summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorBjorn Helgaas2013-01-25 19:26:36 +0100
committerBjorn Helgaas2013-01-25 19:26:36 +0100
commita2766602ac6885f9514abd97821984cd152cdad3 (patch)
tree8932650a9accababfcc37daf515aa75cb0df7749 /drivers/acpi/scan.c
parentMerge branch 'acpi-scan' of git://git.kernel.org/pub/scm/linux/kernel/git/raf... (diff)
parentACPI / scan: Drop acpi_bus_add() and use acpi_bus_scan() instead (diff)
downloadkernel-qcow2-linux-a2766602ac6885f9514abd97821984cd152cdad3.tar.gz
kernel-qcow2-linux-a2766602ac6885f9514abd97821984cd152cdad3.tar.xz
kernel-qcow2-linux-a2766602ac6885f9514abd97821984cd152cdad3.zip
Merge branch 'acpi-scan' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm into pci/acpi-scan2
* 'acpi-scan' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / scan: Drop acpi_bus_add() and use acpi_bus_scan() instead ACPI: update ej_event interface to take acpi_device ACPI / scan: Add second pass to acpi_bus_trim() ACPI / scan: Change the implementation of acpi_bus_trim() ACPI / scan: Drop the second argument of acpi_bus_trim() ACPI / scan: Drop the second argument of acpi_device_unregister() ACPI: Remove the ops field from struct acpi_device ACPI: remove unused acpi_op_bind and acpi_op_unbind ACPI / scan: Fix check of device_attach() return value.
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c168
1 files changed, 62 insertions, 106 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e380345b643a..7c43bdc36abc 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -116,24 +116,18 @@ static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
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)));
- if (acpi_bus_trim(device, 1)) {
+ if (acpi_bus_trim(device)) {
printk(KERN_ERR PREFIX
"Removing device failed\n");
goto err_out;
@@ -215,7 +209,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
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;
@@ -223,7 +217,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
} 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);
}
@@ -701,7 +695,7 @@ end:
return result;
}
-static void acpi_device_unregister(struct acpi_device *device, int type)
+static void acpi_device_unregister(struct acpi_device *device)
{
mutex_lock(&acpi_device_lock);
if (device->parent)
@@ -1374,22 +1368,6 @@ static int acpi_device_set_context(struct acpi_device *device)
return -ENODEV;
}
-static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
-{
- if (!dev)
- return -EINVAL;
-
- dev->removal_type = ACPI_BUS_REMOVAL_EJECT;
- device_release_driver(&dev->dev);
-
- if (!rmdevice)
- return 0;
-
- acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT);
-
- return 0;
-}
-
static int acpi_add_single_object(struct acpi_device **child,
acpi_handle handle, int type,
unsigned long long sta, bool match_driver)
@@ -1593,13 +1571,25 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
if (!acpi_match_device_ids(device, acpi_platform_device_ids)) {
/* This is a known good platform device. */
acpi_create_platform_device(device);
- } else if (device_attach(&device->dev)) {
+ } else if (device_attach(&device->dev) < 0) {
status = AE_CTRL_DEPTH;
}
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;
@@ -1616,84 +1606,48 @@ static int acpi_bus_scan(acpi_handle handle)
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;
-
- err = acpi_bus_scan(handle);
- if (err)
- return err;
+ struct acpi_device *device = NULL;
- acpi_update_all_gpes();
- return 0;
+ if (!acpi_bus_get_device(handle, &device)) {
+ device->removal_type = ACPI_BUS_REMOVAL_EJECT;
+ device_release_driver(&device->dev);
+ }
+ return AE_OK;
}
-EXPORT_SYMBOL(acpi_bus_add);
-int acpi_bus_trim(struct acpi_device *start, int rmdevice)
+static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used,
+ void *not_used, void **ret_not_used)
{
- 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);
+ struct acpi_device *device = NULL;
- /*
- * 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;
-
- if (level == 0)
- err = acpi_bus_remove(child, rmdevice);
- else
- err = acpi_bus_remove(child, 1);
+ if (!acpi_bus_get_device(handle, &device))
+ acpi_device_unregister(device);
- continue;
- }
+ return AE_OK;
+}
- 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;
+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.
+ */
+ 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);
@@ -1742,13 +1696,15 @@ int __init acpi_scan_init(void)
return result;
result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root);
- if (!result)
- result = acpi_bus_scan_fixed();
-
if (result)
- acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
- else
- acpi_update_all_gpes();
+ return result;
- return result;
+ result = acpi_bus_scan_fixed();
+ if (result) {
+ acpi_device_unregister(acpi_root);
+ return result;
+ }
+
+ acpi_update_all_gpes();
+ return 0;
}