diff options
| author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-04-23 20:18:01 -0400 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-04-23 20:18:01 -0400 |
| commit | 7d284352f9cbc032f2294024b1a6b5c06765c246 (patch) | |
| tree | e972852cb7a632f230e05bba3eb1eabfa399c431 | |
| parent | 4c533c801d1c9b5c38458a0e7516e0cf50643782 (diff) | |
ACPI / scan: Add a scan handler for PRP0001
If the special PRP0001 device ID is present in the given device's list
of ACPI/PNP IDs and the device has a valid "compatible" property in
the _DSD, it should be enumerated using the default mechanism,
unless some scan handlers match the IDs preceding PRP0001 in the
device's list of ACPI/PNP IDs. In addition to that, no scan handlers
matching the IDs following PRP0001 in that list should be attached
to the device.
To make that happen, define a scan handler that will match PRP0001
and trigger the default enumeration for the matching devices if the
"compatible" property is present for them.
Since that requires the check for platform_id and device->handler
to be removed from acpi_default_enumeration(), move the fallback
invocation of acpi_default_enumeration() to acpi_bus_attach()
(after it's checked if there's a matching ACPI driver for the
device), which is a better place to call it, and do the platform_id
check in there too (device->handler is guaranteed to be unset at
the point where the function is looking for a matching ACPI driver).
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Darren Hart <dvhart@linux.intel.com>
| -rw-r--r-- | drivers/acpi/scan.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 8d40467d37f9..03141aa4ea95 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -2392,9 +2392,6 @@ static void acpi_default_enumeration(struct acpi_device *device) | |||
| 2392 | struct list_head resource_list; | 2392 | struct list_head resource_list; |
| 2393 | bool is_spi_i2c_slave = false; | 2393 | bool is_spi_i2c_slave = false; |
| 2394 | 2394 | ||
| 2395 | if (!device->pnp.type.platform_id || device->handler) | ||
| 2396 | return; | ||
| 2397 | |||
| 2398 | /* | 2395 | /* |
| 2399 | * Do not enemerate SPI/I2C slaves as they will be enuerated by their | 2396 | * Do not enemerate SPI/I2C slaves as they will be enuerated by their |
| 2400 | * respective parents. | 2397 | * respective parents. |
| @@ -2407,6 +2404,29 @@ static void acpi_default_enumeration(struct acpi_device *device) | |||
| 2407 | acpi_create_platform_device(device); | 2404 | acpi_create_platform_device(device); |
| 2408 | } | 2405 | } |
| 2409 | 2406 | ||
| 2407 | static const struct acpi_device_id generic_device_ids[] = { | ||
| 2408 | {"PRP0001", }, | ||
| 2409 | {"", }, | ||
| 2410 | }; | ||
| 2411 | |||
| 2412 | static int acpi_generic_device_attach(struct acpi_device *adev, | ||
| 2413 | const struct acpi_device_id *not_used) | ||
| 2414 | { | ||
| 2415 | /* | ||
| 2416 | * Since PRP0001 is the only ID handled here, the test below can be | ||
| 2417 | * unconditional. | ||
| 2418 | */ | ||
| 2419 | if (adev->data.of_compatible) | ||
| 2420 | acpi_default_enumeration(adev); | ||
| 2421 | |||
| 2422 | return 1; | ||
| 2423 | } | ||
| 2424 | |||
| 2425 | static struct acpi_scan_handler generic_device_handler = { | ||
| 2426 | .ids = generic_device_ids, | ||
| 2427 | .attach = acpi_generic_device_attach, | ||
| 2428 | }; | ||
| 2429 | |||
| 2410 | static int acpi_scan_attach_handler(struct acpi_device *device) | 2430 | static int acpi_scan_attach_handler(struct acpi_device *device) |
| 2411 | { | 2431 | { |
| 2412 | struct acpi_hardware_id *hwid; | 2432 | struct acpi_hardware_id *hwid; |
| @@ -2432,8 +2452,6 @@ static int acpi_scan_attach_handler(struct acpi_device *device) | |||
| 2432 | break; | 2452 | break; |
| 2433 | } | 2453 | } |
| 2434 | } | 2454 | } |
| 2435 | if (!ret) | ||
| 2436 | acpi_default_enumeration(device); | ||
| 2437 | 2455 | ||
| 2438 | return ret; | 2456 | return ret; |
| 2439 | } | 2457 | } |
| @@ -2475,6 +2493,9 @@ static void acpi_bus_attach(struct acpi_device *device) | |||
| 2475 | ret = device_attach(&device->dev); | 2493 | ret = device_attach(&device->dev); |
| 2476 | if (ret < 0) | 2494 | if (ret < 0) |
| 2477 | return; | 2495 | return; |
| 2496 | |||
| 2497 | if (!ret && device->pnp.type.platform_id) | ||
| 2498 | acpi_default_enumeration(device); | ||
| 2478 | } | 2499 | } |
| 2479 | device->flags.visited = true; | 2500 | device->flags.visited = true; |
| 2480 | 2501 | ||
| @@ -2633,6 +2654,8 @@ int __init acpi_scan_init(void) | |||
| 2633 | acpi_pnp_init(); | 2654 | acpi_pnp_init(); |
| 2634 | acpi_int340x_thermal_init(); | 2655 | acpi_int340x_thermal_init(); |
| 2635 | 2656 | ||
| 2657 | acpi_scan_add_handler(&generic_device_handler); | ||
| 2658 | |||
| 2636 | mutex_lock(&acpi_scan_lock); | 2659 | mutex_lock(&acpi_scan_lock); |
| 2637 | /* | 2660 | /* |
| 2638 | * Enumerate devices in the ACPI namespace. | 2661 | * Enumerate devices in the ACPI namespace. |
