aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-15 07:24:02 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-15 07:24:02 -0500
commitcecdb193c8d91a42d9489d00618cc3dfff92e55a (patch)
tree7d7e16d389efab64ff2c0799de50e0b19ab20077 /drivers/acpi/scan.c
parentae281795ec92d35dd1631401829124acab965b1f (diff)
ACPI / scan: Change the implementation of acpi_bus_trim()
The current acpi_bus_trim() implementation is not really straightforward and may be simplified significantly by using acpi_walk_namespace() with acpi_bus_remove() as a post-order callback. Observe that acpi_bus_remove(), as called by acpi_bus_trim(), cannot actually fail, because its first argument is guaranteed not to be NULL thanks to the acpi_bus_get_device() check in acpi_bus_trim(), so simply move the acpi_bus_get_device() check to acpi_bus_remove() and use acpi_walk_namespace() to execute it for every device under start->handle as a post-order callback. The, run it directly for start->handle itself. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com> Acked-by: Yinghai Lu <yinghai@kernel.org> Acked-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c64
1 files changed, 15 insertions, 49 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d14ce446b469..1ee62bd25828 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1374,17 +1374,20 @@ static int acpi_device_set_context(struct acpi_device *device)
1374 return -ENODEV; 1374 return -ENODEV;
1375} 1375}
1376 1376
1377static int acpi_bus_remove(struct acpi_device *dev) 1377static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used,
1378 void *not_used, void **ret_not_used)
1378{ 1379{
1379 if (!dev) 1380 struct acpi_device *dev = NULL;
1380 return -EINVAL; 1381
1382 if (acpi_bus_get_device(handle, &dev))
1383 return AE_OK;
1381 1384
1382 dev->removal_type = ACPI_BUS_REMOVAL_EJECT; 1385 dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
1383 device_release_driver(&dev->dev); 1386 device_release_driver(&dev->dev);
1384 1387
1385 acpi_device_unregister(dev); 1388 acpi_device_unregister(dev);
1386 1389
1387 return 0; 1390 return AE_OK;
1388} 1391}
1389 1392
1390static int acpi_add_single_object(struct acpi_device **child, 1393static int acpi_add_single_object(struct acpi_device **child,
@@ -1641,51 +1644,14 @@ EXPORT_SYMBOL(acpi_bus_add);
1641 1644
1642int acpi_bus_trim(struct acpi_device *start) 1645int acpi_bus_trim(struct acpi_device *start)
1643{ 1646{
1644 acpi_status status; 1647 /*
1645 struct acpi_device *parent, *child; 1648 * Execute acpi_bus_remove() as a post-order callback to remove device
1646 acpi_handle phandle, chandle; 1649 * nodes in the given namespace scope.
1647 acpi_object_type type; 1650 */
1648 u32 level = 1; 1651 acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
1649 int err = 0; 1652 acpi_bus_remove, NULL, NULL);
1650 1653 acpi_bus_remove(start->handle, 0, NULL, NULL);
1651 parent = start; 1654 return 0;
1652 phandle = start->handle;
1653 child = chandle = NULL;
1654
1655 while ((level > 0) && parent && (!err)) {
1656 status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
1657 chandle, &chandle);
1658
1659 /*
1660 * If this scope is exhausted then move our way back up.
1661 */
1662 if (ACPI_FAILURE(status)) {
1663 level--;
1664 chandle = phandle;
1665 acpi_get_parent(phandle, &phandle);
1666 child = parent;
1667 parent = parent->parent;
1668 err = acpi_bus_remove(child);
1669 continue;
1670 }
1671
1672 status = acpi_get_type(chandle, &type);
1673 if (ACPI_FAILURE(status)) {
1674 continue;
1675 }
1676 /*
1677 * If there is a device corresponding to chandle then
1678 * parse it (depth-first).
1679 */
1680 if (acpi_bus_get_device(chandle, &child) == 0) {
1681 level++;
1682 phandle = chandle;
1683 chandle = NULL;
1684 parent = child;
1685 }
1686 continue;
1687 }
1688 return err;
1689} 1655}
1690EXPORT_SYMBOL_GPL(acpi_bus_trim); 1656EXPORT_SYMBOL_GPL(acpi_bus_trim);
1691 1657