team: fix memory leaks
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / acpi / resource.c
index a3868f6c222abfc65541a5a599035e18145108f9..b9cfaf1d94d81aad1ecb6972c070e7bd73b1a469 100644 (file)
@@ -77,18 +77,24 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
        switch (ares->type) {
        case ACPI_RESOURCE_TYPE_MEMORY24:
                memory24 = &ares->data.memory24;
+               if (!memory24->minimum && !memory24->address_length)
+                       return false;
                acpi_dev_get_memresource(res, memory24->minimum,
                                         memory24->address_length,
                                         memory24->write_protect);
                break;
        case ACPI_RESOURCE_TYPE_MEMORY32:
                memory32 = &ares->data.memory32;
+               if (!memory32->minimum && !memory32->address_length)
+                       return false;
                acpi_dev_get_memresource(res, memory32->minimum,
                                         memory32->address_length,
                                         memory32->write_protect);
                break;
        case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
                fixed_memory32 = &ares->data.fixed_memory32;
+               if (!fixed_memory32->address && !fixed_memory32->address_length)
+                       return false;
                acpi_dev_get_memresource(res, fixed_memory32->address,
                                         fixed_memory32->address_length,
                                         fixed_memory32->write_protect);
@@ -144,12 +150,16 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
        switch (ares->type) {
        case ACPI_RESOURCE_TYPE_IO:
                io = &ares->data.io;
+               if (!io->minimum && !io->address_length)
+                       return false;
                acpi_dev_get_ioresource(res, io->minimum,
                                        io->address_length,
                                        io->io_decode);
                break;
        case ACPI_RESOURCE_TYPE_FIXED_IO:
                fixed_io = &ares->data.fixed_io;
+               if (!fixed_io->address && !fixed_io->address_length)
+                       return false;
                acpi_dev_get_ioresource(res, fixed_io->address,
                                        fixed_io->address_length,
                                        ACPI_DECODE_10);
@@ -304,7 +314,8 @@ static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
 }
 
 static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
-                                    u8 triggering, u8 polarity, u8 shareable)
+                                    u8 triggering, u8 polarity, u8 shareable,
+                                    bool legacy)
 {
        int irq, p, t;
 
@@ -317,14 +328,19 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
         * In IO-APIC mode, use overrided attribute. Two reasons:
         * 1. BIOS bug in DSDT
         * 2. BIOS uses IO-APIC mode Interrupt Source Override
+        *
+        * We do this only if we are dealing with IRQ() or IRQNoFlags()
+        * resource (the legacy ISA resources). With modern ACPI 5 devices
+        * using extended IRQ descriptors we take the IRQ configuration
+        * from _CRS directly.
         */
-       if (!acpi_get_override_irq(gsi, &t, &p)) {
+       if (legacy && !acpi_get_override_irq(gsi, &t, &p)) {
                u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
                u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
 
                if (triggering != trig || polarity != pol) {
                        pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
-                                  t ? "edge" : "level", p ? "low" : "high");
+                                  t ? "level" : "edge", p ? "low" : "high");
                        triggering = trig;
                        polarity = pol;
                }
@@ -373,7 +389,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
                }
                acpi_dev_get_irqresource(res, irq->interrupts[index],
                                         irq->triggering, irq->polarity,
-                                        irq->sharable);
+                                        irq->sharable, true);
                break;
        case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
                ext_irq = &ares->data.extended_irq;
@@ -383,7 +399,7 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
                }
                acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
                                         ext_irq->triggering, ext_irq->polarity,
-                                        ext_irq->sharable);
+                                        ext_irq->sharable, false);
                break;
        default:
                return false;