diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-01-27 15:17:29 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-01-27 15:17:29 -0500 |
commit | c511cc1990bbc263c3f8a2ef4d7d613a3b40ffe2 (patch) | |
tree | 4919ff638fa0606267deec1d225fed199afb11e5 /drivers/acpi/scan.c | |
parent | bfee26dba0f373ebe4e6f0b293d078b02f9f7f69 (diff) |
ACPI / scan: Make namespace scanning and trimming mutually exclusive
There is no guarantee that acpi_bus_scan() and acpi_bus_trim() will
not be run in parallel for the same scope of the ACPI namespace,
which may lead to a great deal of confusion, so introduce a new mutex
to prevent that from happening.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r-- | drivers/acpi/scan.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index d37f290be44c..43754655c156 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -52,6 +52,7 @@ static const struct acpi_device_id acpi_platform_device_ids[] = { | |||
52 | 52 | ||
53 | static LIST_HEAD(acpi_device_list); | 53 | static LIST_HEAD(acpi_device_list); |
54 | static LIST_HEAD(acpi_bus_id_list); | 54 | static LIST_HEAD(acpi_bus_id_list); |
55 | static DEFINE_MUTEX(acpi_scan_lock); | ||
55 | DEFINE_MUTEX(acpi_device_lock); | 56 | DEFINE_MUTEX(acpi_device_lock); |
56 | LIST_HEAD(acpi_wakeup_device_list); | 57 | LIST_HEAD(acpi_wakeup_device_list); |
57 | 58 | ||
@@ -1587,19 +1588,22 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, | |||
1587 | int acpi_bus_scan(acpi_handle handle) | 1588 | int acpi_bus_scan(acpi_handle handle) |
1588 | { | 1589 | { |
1589 | void *device = NULL; | 1590 | void *device = NULL; |
1591 | int error = 0; | ||
1592 | |||
1593 | mutex_lock(&acpi_scan_lock); | ||
1590 | 1594 | ||
1591 | if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) | 1595 | if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) |
1592 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 1596 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
1593 | acpi_bus_check_add, NULL, NULL, &device); | 1597 | acpi_bus_check_add, NULL, NULL, &device); |
1594 | 1598 | ||
1595 | if (!device) | 1599 | if (!device) |
1596 | return -ENODEV; | 1600 | error = -ENODEV; |
1597 | 1601 | else if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL))) | |
1598 | if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL))) | ||
1599 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 1602 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
1600 | acpi_bus_device_attach, NULL, NULL, NULL); | 1603 | acpi_bus_device_attach, NULL, NULL, NULL); |
1601 | 1604 | ||
1602 | return 0; | 1605 | mutex_unlock(&acpi_scan_lock); |
1606 | return error; | ||
1603 | } | 1607 | } |
1604 | EXPORT_SYMBOL(acpi_bus_scan); | 1608 | EXPORT_SYMBOL(acpi_bus_scan); |
1605 | 1609 | ||
@@ -1628,6 +1632,8 @@ static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used, | |||
1628 | 1632 | ||
1629 | void acpi_bus_trim(struct acpi_device *start) | 1633 | void acpi_bus_trim(struct acpi_device *start) |
1630 | { | 1634 | { |
1635 | mutex_lock(&acpi_scan_lock); | ||
1636 | |||
1631 | /* | 1637 | /* |
1632 | * Execute acpi_bus_device_detach() as a post-order callback to detach | 1638 | * Execute acpi_bus_device_detach() as a post-order callback to detach |
1633 | * all ACPI drivers from the device nodes being removed. | 1639 | * all ACPI drivers from the device nodes being removed. |
@@ -1642,6 +1648,8 @@ void acpi_bus_trim(struct acpi_device *start) | |||
1642 | acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, | 1648 | acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, |
1643 | acpi_bus_remove, NULL, NULL); | 1649 | acpi_bus_remove, NULL, NULL); |
1644 | acpi_bus_remove(start->handle, 0, NULL, NULL); | 1650 | acpi_bus_remove(start->handle, 0, NULL, NULL); |
1651 | |||
1652 | mutex_unlock(&acpi_scan_lock); | ||
1645 | } | 1653 | } |
1646 | EXPORT_SYMBOL_GPL(acpi_bus_trim); | 1654 | EXPORT_SYMBOL_GPL(acpi_bus_trim); |
1647 | 1655 | ||