void acpi_bus_hot_remove_device(void *context)
{
struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context;
- struct acpi_device *device;
- acpi_handle handle = ej_event->handle;
+ struct acpi_device *device = ej_event->device;
+ acpi_handle handle = device->handle;
acpi_handle temp;
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status = AE_OK;
u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
- if (acpi_bus_get_device(handle, &device))
- goto err_out;
-
- if (!device)
- goto err_out;
-
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Hot-removing device %s...\n", dev_name(&device->dev)));
goto err;
}
- ej_event->handle = acpi_device->handle;
+ ej_event->device = acpi_device;
if (acpi_device->flags.eject_pending) {
/* event originated from ACPI eject notification */
ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
} else {
/* event originated from user */
ej_event->event = ACPI_OST_EC_OSPM_EJECT;
- (void) acpi_evaluate_hotplug_ost(ej_event->handle,
+ (void) acpi_evaluate_hotplug_ost(acpi_device->handle,
ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
}
ret = acpi_device_install_notify_handler(acpi_dev);
if (ret) {
if (acpi_drv->ops.remove)
- acpi_drv->ops.remove(acpi_dev,
- acpi_dev->removal_type);
+ acpi_drv->ops.remove(acpi_dev);
return ret;
}
}
if (acpi_drv->ops.notify)
acpi_device_remove_notify_handler(acpi_dev);
if (acpi_drv->ops.remove)
- acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type);
+ acpi_drv->ops.remove(acpi_dev);
}
acpi_dev->driver = NULL;
acpi_dev->driver_data = NULL;
acpi_add_id(device, ACPI_DOCK_HID);
else if (!acpi_ibm_smbus_match(device))
acpi_add_id(device, ACPI_SMBUS_IBM_HID);
- else if (!acpi_device_hid(device) &&
+ else if (list_empty(&device->pnp.ids) &&
ACPI_IS_ROOT_DEVICE(device->parent)) {
acpi_add_id(device, ACPI_BUS_HID); /* \_SB, LNXSYBUS */
strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
return -ENODEV;
}
-static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used,
- void *not_used, void **ret_not_used)
-{
- 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 AE_OK;
-}
-
static int acpi_add_single_object(struct acpi_device **child,
acpi_handle handle, int type,
unsigned long long sta, bool match_driver)
return status;
}
-static int acpi_bus_scan(acpi_handle handle)
+/**
+ * acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
+ * @handle: Root of the namespace scope to scan.
+ *
+ * Scan a given ACPI tree (probably recently hot-plugged) and create and add
+ * found devices.
+ *
+ * If no devices were found, -ENODEV is returned, but it does not mean that
+ * there has been a real error. There just have been no suitable ACPI objects
+ * in the table trunk from which the kernel could create a device and add an
+ * appropriate driver.
+ */
+int acpi_bus_scan(acpi_handle handle)
{
void *device = NULL;
return 0;
}
+EXPORT_SYMBOL(acpi_bus_scan);
-/**
- * acpi_bus_add - Add ACPI device node objects in a given namespace scope.
- * @handle: Root of the namespace scope to scan.
- *
- * Scan a given ACPI tree (probably recently hot-plugged) and create and add
- * found devices.
- *
- * If no devices were found, -ENODEV is returned, but it does not mean that
- * there has been a real error. There just have been no suitable ACPI objects
- * in the table trunk from which the kernel could create a device and add an
- * appropriate driver.
- */
-int acpi_bus_add(acpi_handle handle)
+static acpi_status acpi_bus_device_detach(acpi_handle handle, u32 lvl_not_used,
+ void *not_used, void **ret_not_used)
{
- int err;
+ struct acpi_device *device = NULL;
- err = acpi_bus_scan(handle);
- if (err)
- return err;
+ if (!acpi_bus_get_device(handle, &device)) {
+ device->removal_type = ACPI_BUS_REMOVAL_EJECT;
+ device_release_driver(&device->dev);
+ }
+ return AE_OK;
+}
- acpi_update_all_gpes();
- return 0;
+static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used,
+ void *not_used, void **ret_not_used)
+{
+ struct acpi_device *device = NULL;
+
+ if (!acpi_bus_get_device(handle, &device))
+ acpi_device_unregister(device);
+
+ return AE_OK;
}
-EXPORT_SYMBOL(acpi_bus_add);
int acpi_bus_trim(struct acpi_device *start)
{
+ /*
+ * Execute acpi_bus_device_detach() as a post-order callback to detach
+ * all ACPI drivers from the device nodes being removed.
+ */
+ acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL,
+ acpi_bus_device_detach, NULL, NULL);
+ acpi_bus_device_detach(start->handle, 0, NULL, NULL);
/*
* Execute acpi_bus_remove() as a post-order callback to remove device
* nodes in the given namespace scope.
return result;
result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root);
- if (!result)
- result = acpi_bus_scan_fixed();
-
if (result)
+ return result;
+
+ result = acpi_bus_scan_fixed();
+ if (result) {
acpi_device_unregister(acpi_root);
- else
- acpi_update_all_gpes();
+ return result;
+ }
- return result;
+ acpi_update_all_gpes();
+ return 0;
}