ACPI / scan: do not match drivers against objects having scan handlers
authorAaron Lu <aaron.lu@intel.com>
Tue, 4 Jun 2013 21:02:58 +0000 (23:02 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 5 Jun 2013 11:11:47 +0000 (13:11 +0200)
With the introduction of ACPI scan handlers, an ACPI device object
with an ACPI scan handler attached to it must not be bound to an ACPI
driver any more.  Therefore it doesn't make sense to match those
ACPI device objects against a newly registered ACPI driver in
acpi_bus_match(), so make that function return 0 if the device
object passed to it has an ACPI scan handler attached.

This also addresses a regression related to a broken ACPI table in
the BIOS, where it has defined a _ROM method under the PCI root
bridge object.  This causes the video module to treat that object
as a display controller device (since only display devices are
supposed to have a _ROM method defined according to the ACPI spec).
As a result, the ACPI video driver binds to the PCI root bridge
object and overwrites the previously assigned driver_data field of
it, causing subsequent calls to acpi_get_pci_dev() to fail.

[rjw: Subject and changelog]
References: https://bugzilla.kernel.org/show_bug.cgi?id=58091
Reported-by: Jason Cassell <bluesloth600@gmail.com>
Reported-and-bisected-by: Dmitry S. Demin <dmitryy.demin@gmail.com>
Cc: 3.9+ <stable@kernel.org>
Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/scan.c

index 44225cb15f3a248fb842c6e3b3d3f188f47aa99d..90c5759e1355e667ac34839720149da8bda701e8 100644 (file)
@@ -740,6 +740,10 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
        struct acpi_device *acpi_dev = to_acpi_device(dev);
        struct acpi_driver *acpi_drv = to_acpi_driver(drv);
 
+       /* Skip ACPI device objects with scan handlers attached. */
+       if (acpi_dev->handler)
+               return 0;
+
        return acpi_dev->flags.match_driver
                && !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
 }