ACPI / resources: only reject zero length resources based at address zero
authorAndy Whitcroft <apw@canonical.com>
Thu, 19 Jun 2014 10:19:16 +0000 (11:19 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 7 Jul 2014 20:11:09 +0000 (22:11 +0200)
The recently merged change (in v3.14-rc6) to ACPI resource detection
(below) causes all zero length ACPI resources to be elided from the
table:

  commit b355cee88e3b1a193f0e9a81db810f6f83ad728b
  Author: Zhang Rui <rui.zhang@intel.com>
  Date:   Thu Feb 27 11:37:15 2014 +0800

    ACPI / resources: ignore invalid ACPI device resources

This change has caused a regression in (at least) serial port detection
for a number of machines (see LP#1313981 [1]).  These seem to represent
their IO regions (presumably incorrectly) as a zero length region.
Reverting the above commit restores these serial devices.

Only elide zero length resources which lie at address 0.

Fixes: b355cee88e3b (ACPI / resources: ignore invalid ACPI device resources)
Signed-off-by: Andy Whitcroft <apw@canonical.com>
Acked-by: Zhang Rui <rui.zhang@intel.com>
Cc: 3.14+ <stable@vger.kernel.org> # 3.14+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/resource.c

index 0bdacc5e26a3b9411b82a5fe4772c2c9f9b7d490..2ba8f02ced3637e0b1431bb16049b2f238069ee2 100644 (file)
@@ -77,7 +77,7 @@ 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->address_length)
+               if (!memory24->minimum && !memory24->address_length)
                        return false;
                acpi_dev_get_memresource(res, memory24->minimum,
                                         memory24->address_length,
@@ -85,7 +85,7 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
                break;
        case ACPI_RESOURCE_TYPE_MEMORY32:
                memory32 = &ares->data.memory32;
-               if (!memory32->address_length)
+               if (!memory32->minimum && !memory32->address_length)
                        return false;
                acpi_dev_get_memresource(res, memory32->minimum,
                                         memory32->address_length,
@@ -93,7 +93,7 @@ bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
                break;
        case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
                fixed_memory32 = &ares->data.fixed_memory32;
-               if (!fixed_memory32->address_length)
+               if (!fixed_memory32->address && !fixed_memory32->address_length)
                        return false;
                acpi_dev_get_memresource(res, fixed_memory32->address,
                                         fixed_memory32->address_length,
@@ -150,7 +150,7 @@ 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->address_length)
+               if (!io->minimum && !io->address_length)
                        return false;
                acpi_dev_get_ioresource(res, io->minimum,
                                        io->address_length,
@@ -158,7 +158,7 @@ bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
                break;
        case ACPI_RESOURCE_TYPE_FIXED_IO:
                fixed_io = &ares->data.fixed_io;
-               if (!fixed_io->address_length)
+               if (!fixed_io->address && !fixed_io->address_length)
                        return false;
                acpi_dev_get_ioresource(res, fixed_io->address,
                                        fixed_io->address_length,