diff options
-rw-r--r-- | drivers/acpi/scan.c | 64 |
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) return -ENODEV; } -static int acpi_bus_remove(struct acpi_device *dev) +static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used, + void *not_used, void **ret_not_used) { - if (!dev) - return -EINVAL; + struct acpi_device *dev = NULL; + + if (acpi_bus_get_device(handle, &dev)) + return AE_OK; dev->removal_type = ACPI_BUS_REMOVAL_EJECT; device_release_driver(&dev->dev); acpi_device_unregister(dev); - return 0; + return AE_OK; } static int acpi_add_single_object(struct acpi_device **child, @@ -1641,51 +1644,14 @@ EXPORT_SYMBOL(acpi_bus_add); int acpi_bus_trim(struct acpi_device *start) { - acpi_status status; - struct acpi_device *parent, *child; - acpi_handle phandle, chandle; - acpi_object_type type; - u32 level = 1; - int err = 0; - - parent = start; - phandle = start->handle; - child = chandle = NULL; - - while ((level > 0) && parent && (!err)) { - status = acpi_get_next_object(ACPI_TYPE_ANY, phandle, - chandle, &chandle); - - /* - * If this scope is exhausted then move our way back up. - */ - if (ACPI_FAILURE(status)) { - level--; - chandle = phandle; - acpi_get_parent(phandle, &phandle); - child = parent; - parent = parent->parent; - err = acpi_bus_remove(child); - continue; - } - - status = acpi_get_type(chandle, &type); - if (ACPI_FAILURE(status)) { - continue; - } - /* - * If there is a device corresponding to chandle then - * parse it (depth-first). - */ - if (acpi_bus_get_device(chandle, &child) == 0) { - level++; - phandle = chandle; - chandle = NULL; - parent = child; - } - continue; - } - return err; + /* + * Execute acpi_bus_remove() as a post-order callback to remove device + * nodes in the given namespace scope. + */ + acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, + acpi_bus_remove, NULL, NULL); + acpi_bus_remove(start->handle, 0, NULL, NULL); + return 0; } EXPORT_SYMBOL_GPL(acpi_bus_trim); |