aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-27 15:17:29 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-27 15:17:29 -0500
commitc511cc1990bbc263c3f8a2ef4d7d613a3b40ffe2 (patch)
tree4919ff638fa0606267deec1d225fed199afb11e5 /drivers
parentbfee26dba0f373ebe4e6f0b293d078b02f9f7f69 (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')
-rw-r--r--drivers/acpi/scan.c16
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
53static LIST_HEAD(acpi_device_list); 53static LIST_HEAD(acpi_device_list);
54static LIST_HEAD(acpi_bus_id_list); 54static LIST_HEAD(acpi_bus_id_list);
55static DEFINE_MUTEX(acpi_scan_lock);
55DEFINE_MUTEX(acpi_device_lock); 56DEFINE_MUTEX(acpi_device_lock);
56LIST_HEAD(acpi_wakeup_device_list); 57LIST_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,
1587int acpi_bus_scan(acpi_handle handle) 1588int 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}
1604EXPORT_SYMBOL(acpi_bus_scan); 1608EXPORT_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
1629void acpi_bus_trim(struct acpi_device *start) 1633void 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}
1646EXPORT_SYMBOL_GPL(acpi_bus_trim); 1654EXPORT_SYMBOL_GPL(acpi_bus_trim);
1647 1655