From 636458de36f1fb4cdd318387d2f45604e451b17a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 21 Dec 2012 00:36:47 +0100 Subject: ACPI: Remove the arguments of acpi_bus_add() that are not used Notice that acpi_bus_add() uses only 2 of its 4 arguments and redefine its header to match the body. Update all of its callers as necessary and observe that this leads to quite a number of removed lines of code (Linus will like that). Add a kerneldoc comment documenting acpi_bus_add() and wonder how its callers make wrong assumptions about the second argument (make note to self to take care of that later). Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu Acked-by: Toshi Kani --- drivers/acpi/acpi_memhotplug.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'drivers/acpi/acpi_memhotplug.c') diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index eb30e5ab4cab..d0a7da704d49 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -157,34 +157,17 @@ static int acpi_memory_get_device(acpi_handle handle, struct acpi_memory_device **mem_device) { - acpi_status status; - acpi_handle phandle; struct acpi_device *device = NULL; - struct acpi_device *pdevice = NULL; int result; - if (!acpi_bus_get_device(handle, &device) && device) goto end; - status = acpi_get_parent(handle, &phandle); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Cannot find acpi parent")); - return -EINVAL; - } - - /* Get the parent device */ - result = acpi_bus_get_device(phandle, &pdevice); - if (result) { - acpi_handle_warn(phandle, "Cannot get acpi bus device\n"); - return -EINVAL; - } - /* * Now add the notified device. This creates the acpi_device * and invokes .add function */ - result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); + result = acpi_bus_add(handle, &device); if (result) { acpi_handle_warn(handle, "Cannot add acpi bus\n"); return -EINVAL; -- cgit v1.2.3 From 0cd6ac52b333f66ee64e50ed216ec99231092dcd Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 21 Dec 2012 00:36:49 +0100 Subject: ACPI: Make acpi_bus_scan() and acpi_bus_add() take only one argument The callers of acpi_bus_add() usually assume that if it has succeeded, then a struct acpi_device object has been attached to the handle passed as the first argument. Unfortunately, however, this assumption is wrong, because acpi_bus_scan(), and acpi_bus_add() too as a result, may return a pointer to a different struct acpi_device object on success (it may be an object corresponding to one of the descendant ACPI nodes in the namespace scope below that handle). For this reason, the callers of acpi_bus_add() who care about whether or not a struct acpi_device object has been created for its first argument need to check that using acpi_bus_get_device() anyway, so the second argument of acpi_bus_add() is not really useful for them. The same observation applies to acpi_bus_scan() executed directly from acpi_scan_init(). Therefore modify the relevant callers of acpi_bus_add() to check the existence of the struct acpi_device in question with the help of acpi_bus_get_device() and drop the no longer necessary second argument of acpi_bus_add(). Accordingly, modify acpi_scan_init() to use acpi_bus_get_device() to get acpi_root and drop the no longer needed second argument of acpi_bus_scan(). Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu Acked-by: Toshi Kani --- drivers/acpi/acpi_memhotplug.c | 7 ++++++- drivers/acpi/container.c | 7 ++++++- drivers/acpi/dock.c | 4 +++- drivers/acpi/processor_driver.c | 8 ++++++-- drivers/acpi/scan.c | 38 +++++++++++--------------------------- drivers/pci/hotplug/acpiphp_glue.c | 19 +++++++++++-------- drivers/pci/hotplug/sgi_hotplug.c | 3 +-- include/acpi/acpi_bus.h | 2 +- 8 files changed, 45 insertions(+), 43 deletions(-) (limited to 'drivers/acpi/acpi_memhotplug.c') diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index d0a7da704d49..327ab4459558 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -167,11 +167,16 @@ acpi_memory_get_device(acpi_handle handle, * Now add the notified device. This creates the acpi_device * and invokes .add function */ - result = acpi_bus_add(handle, &device); + result = acpi_bus_add(handle); if (result) { acpi_handle_warn(handle, "Cannot add acpi bus\n"); return -EINVAL; } + result = acpi_bus_get_device(handle, &device); + if (result) { + acpi_handle_warn(handle, "Missing device object\n"); + return -EINVAL; + } end: *mem_device = acpi_driver_data(device); diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 0688f83bc436..f8fb2281f34a 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -166,11 +166,16 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) if (!ACPI_FAILURE(status) || device) break; - result = acpi_bus_add(handle, &device); + result = acpi_bus_add(handle); if (result) { acpi_handle_warn(handle, "Failed to add container\n"); break; } + result = acpi_bus_get_device(handle, &device); + if (result) { + acpi_handle_warn(handle, "Missing device object\n"); + break; + } kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); ost_code = ACPI_OST_SC_SUCCESS; diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index ff30582d2e1d..9e31b2bd93d3 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -317,9 +317,11 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle) * no device created for this object, * so we should create one. */ - ret = acpi_bus_add(handle, &device); + ret = acpi_bus_add(handle); if (ret) pr_debug("error adding bus, %x\n", -ret); + + acpi_bus_get_device(handle, &device); } return device; } diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 18b292e12b38..0777663f443e 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -699,12 +699,16 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, if (!acpi_bus_get_device(handle, &device)) break; - result = acpi_bus_add(handle, &device); + result = acpi_bus_add(handle); if (result) { acpi_handle_err(handle, "Unable to add the device\n"); break; } - + result = acpi_bus_get_device(handle, &device); + if (result) { + acpi_handle_err(handle, "Missing device object\n"); + break; + } ost_code = ACPI_OST_SC_SUCCESS; break; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e3aed481aed2..3d44c705a3a2 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1620,37 +1620,27 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, return status; } -static int acpi_bus_scan(acpi_handle handle, struct acpi_device **child) +static int acpi_bus_scan(acpi_handle handle) { void *device = NULL; - acpi_status status; - int ret = -ENODEV; - status = acpi_bus_check_add(handle, 0, NULL, &device); - if (ACPI_SUCCESS(status)) + if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, acpi_bus_check_add, NULL, NULL, &device); if (!device) - goto out; + return -ENODEV; - ret = 0; - status = acpi_bus_device_attach(handle, 0, NULL, NULL); - if (ACPI_SUCCESS(status)) + if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL))) acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, acpi_bus_device_attach, NULL, NULL, NULL); - out: - if (child) - *child = device; - - return ret; + return 0; } /** * acpi_bus_add - Add ACPI device node objects in a given namespace scope. * @handle: Root of the namespace scope to scan. - * @ret: Location to store a return struct acpi_device pointer. * * Scan a given ACPI tree (probably recently hot-plugged) and create and add * found devices. @@ -1659,21 +1649,12 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_device **child) * 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. - * - * If 0 is returned, the memory location pointed to by @ret will be populated - * with a pointer to a struct acpi_device created while scanning the namespace. - * If @handle corresponds to a device node, that will be a pointer to the struct - * acpi_device object corresponding to @handle. Otherwise, it will be a pointer - * to a struct acpi_device corresponding to one of its descendants. - * - * If an error code is returned, NULL will be stored in the memory location - * pointed to by @ret. */ -int acpi_bus_add(acpi_handle handle, struct acpi_device **ret) +int acpi_bus_add(acpi_handle handle) { int err; - err = acpi_bus_scan(handle, ret); + err = acpi_bus_scan(handle); if (err) return err; @@ -1777,8 +1758,11 @@ int __init acpi_scan_init(void) /* * Enumerate devices in the ACPI namespace. */ - result = acpi_bus_scan(ACPI_ROOT_OBJECT, &acpi_root); + result = acpi_bus_scan(ACPI_ROOT_OBJECT); + if (result) + return result; + result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); if (!result) result = acpi_bus_scan_fixed(); diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index dfc2df54b93a..91b5ad875c53 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -746,14 +746,13 @@ static int acpiphp_bus_add(struct acpiphp_func *func) dbg("acpi_bus_trim return %x\n", ret_val); } - ret_val = acpi_bus_add(func->handle, &device); - if (ret_val) { - dbg("error adding bus, %x\n", - -ret_val); - goto acpiphp_bus_add_out; - } + ret_val = acpi_bus_add(func->handle); + if (!ret_val) + ret_val = acpi_bus_get_device(func->handle, &device); + + if (ret_val) + dbg("error adding bus, %x\n", -ret_val); -acpiphp_bus_add_out: return ret_val; } @@ -1130,10 +1129,14 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type) return; } - if (acpi_bus_add(handle, &device)) { + if (acpi_bus_add(handle)) { err("cannot add bridge to acpi list\n"); return; } + if (acpi_bus_get_device(handle, &device)) { + err("ACPI device object missing\n"); + return; + } if (!acpiphp_configure_bridge(handle)) add_bridge(handle); else diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 801b58d1f78e..f3c419256d2a 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -412,7 +412,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) if (SN_ACPI_BASE_SUPPORT() && ssdt) { unsigned long long adr; struct acpi_device *pdevice; - struct acpi_device *device; acpi_handle phandle; acpi_handle chandle = NULL; acpi_handle rethandle; @@ -448,7 +447,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) if (ACPI_SUCCESS(ret) && (adr>>16) == (slot->device_num + 1)) { - ret = acpi_bus_add(chandle, &device); + ret = acpi_bus_add(chandle); if (ACPI_FAILURE(ret)) { printk(KERN_ERR "%s: acpi_bus_add " "failed (0x%x) for slot %d " diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 056cb0cd8eff..5e1d5a1b477f 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -351,7 +351,7 @@ static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 ty #endif int acpi_bus_register_driver(struct acpi_driver *driver); void acpi_bus_unregister_driver(struct acpi_driver *driver); -int acpi_bus_add(acpi_handle handle, struct acpi_device **ret); +int acpi_bus_add(acpi_handle handle); void acpi_bus_hot_remove_device(void *context); int acpi_bus_trim(struct acpi_device *start, int rmdevice); acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd); -- cgit v1.2.3 From 5993c4670ea2453ef5abb45b312f150e994e6eb9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 11 Jan 2013 22:40:41 +0000 Subject: ACPI: update ej_event interface to take acpi_device Should use acpi_device pointer directly instead of use handle and get the device pointer again later. Signed-off-by: Yinghai Lu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_memhotplug.c | 2 +- drivers/acpi/processor_driver.c | 2 +- drivers/acpi/scan.c | 14 ++++---------- include/acpi/acpi_bus.h | 2 +- 4 files changed, 7 insertions(+), 13 deletions(-) (limited to 'drivers/acpi/acpi_memhotplug.c') diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 327ab4459558..eaddb7a89c70 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -361,7 +361,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) break; } - ej_event->handle = handle; + ej_event->device = device; ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; acpi_os_hotplug_execute(acpi_bus_hot_remove_device, (void *)ej_event); diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 0777663f443e..a24ee43e06e4 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -733,7 +733,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, break; } - ej_event->handle = handle; + ej_event->device = device; ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; acpi_os_hotplug_execute(acpi_bus_hot_remove_device, (void *)ej_event); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index d04d0b33656c..388b59c096dc 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -116,20 +116,14 @@ 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))); @@ -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); } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 566f1fdabbd2..567851b4f043 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -306,7 +306,7 @@ struct acpi_bus_event { }; struct acpi_eject_event { - acpi_handle handle; + struct acpi_device *device; u32 event; }; -- cgit v1.2.3 From b8bd759acd05281abf88cddef30c57313c109697 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 19 Jan 2013 01:27:35 +0100 Subject: ACPI / scan: Drop acpi_bus_add() and use acpi_bus_scan() instead The only difference between acpi_bus_scan() and acpi_bus_add() is the invocation of acpi_update_all_gpes() in the latter which in fact is unnecessary, because acpi_update_all_gpes() has already been called by acpi_scan_init() and the way it is implemented guarantees the next invocations of it to do nothing. For this reason, drop acpi_bus_add() and make all its callers use acpi_bus_scan() directly instead of it. Additionally, rearrange the code in acpi_scan_init() slightly to improve the visibility of the acpi_update_all_gpes() call in there. Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu --- drivers/acpi/acpi_memhotplug.c | 2 +- drivers/acpi/container.c | 2 +- drivers/acpi/dock.c | 2 +- drivers/acpi/processor_driver.c | 2 +- drivers/acpi/scan.c | 54 ++++++++++++++++---------------------- drivers/pci/hotplug/acpiphp_glue.c | 4 +-- drivers/pci/hotplug/sgi_hotplug.c | 4 +-- include/acpi/acpi_bus.h | 2 +- 8 files changed, 31 insertions(+), 41 deletions(-) (limited to 'drivers/acpi/acpi_memhotplug.c') diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index eaddb7a89c70..15ea22fc1f5e 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -167,7 +167,7 @@ acpi_memory_get_device(acpi_handle handle, * Now add the notified device. This creates the acpi_device * and invokes .add function */ - result = acpi_bus_add(handle); + result = acpi_bus_scan(handle); if (result) { acpi_handle_warn(handle, "Cannot add acpi bus\n"); return -EINVAL; diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index f8fb2281f34a..cc79d3e53a39 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -166,7 +166,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) if (!ACPI_FAILURE(status) || device) break; - result = acpi_bus_add(handle); + result = acpi_bus_scan(handle); if (result) { acpi_handle_warn(handle, "Failed to add container\n"); break; diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 4a56a8b2e51e..420d24fc9388 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -317,7 +317,7 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle) * no device created for this object, * so we should create one. */ - ret = acpi_bus_add(handle); + ret = acpi_bus_scan(handle); if (ret) pr_debug("error adding bus, %x\n", -ret); diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index a24ee43e06e4..9c5929a17d3a 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -699,7 +699,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, if (!acpi_bus_get_device(handle, &device)) break; - result = acpi_bus_add(handle); + result = acpi_bus_scan(handle); if (result) { acpi_handle_err(handle, "Unable to add the device\n"); break; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 388b59c096dc..7c43bdc36abc 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1577,26 +1577,8 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, return status; } -static int acpi_bus_scan(acpi_handle handle) -{ - void *device = NULL; - - if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) - acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, - acpi_bus_check_add, NULL, NULL, &device); - - if (!device) - return -ENODEV; - - if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL))) - acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, - acpi_bus_device_attach, NULL, NULL, NULL); - - return 0; -} - /** - * acpi_bus_add - Add ACPI device node objects in a given namespace scope. + * 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 @@ -1607,18 +1589,24 @@ static int acpi_bus_scan(acpi_handle handle) * in the table trunk from which the kernel could create a device and add an * appropriate driver. */ -int acpi_bus_add(acpi_handle handle) +int acpi_bus_scan(acpi_handle handle) { - int err; + void *device = NULL; - err = acpi_bus_scan(handle); - if (err) - return err; + if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) + acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, + acpi_bus_check_add, NULL, NULL, &device); + + if (!device) + return -ENODEV; + + if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL))) + acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, + acpi_bus_device_attach, NULL, NULL, NULL); - acpi_update_all_gpes(); return 0; } -EXPORT_SYMBOL(acpi_bus_add); +EXPORT_SYMBOL(acpi_bus_scan); static acpi_status acpi_bus_device_detach(acpi_handle handle, u32 lvl_not_used, void *not_used, void **ret_not_used) @@ -1708,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) + 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; } diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 22006f2d9dd5..9e2b1f6dbe41 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -746,7 +746,7 @@ static int acpiphp_bus_add(struct acpiphp_func *func) dbg("acpi_bus_trim return %x\n", ret_val); } - ret_val = acpi_bus_add(func->handle); + ret_val = acpi_bus_scan(func->handle); if (!ret_val) ret_val = acpi_bus_get_device(func->handle, &device); @@ -1129,7 +1129,7 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type) return; } - if (acpi_bus_add(handle)) { + if (acpi_bus_scan(handle)) { err("cannot add bridge to acpi list\n"); return; } diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 2e006ee5738b..ae606b3e991e 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -447,9 +447,9 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) if (ACPI_SUCCESS(ret) && (adr>>16) == (slot->device_num + 1)) { - ret = acpi_bus_add(chandle); + ret = acpi_bus_scan(chandle); if (ACPI_FAILURE(ret)) { - printk(KERN_ERR "%s: acpi_bus_add " + printk(KERN_ERR "%s: acpi_bus_scan " "failed (0x%x) for slot %d " "func %d\n", __func__, ret, (int)(adr>>16), diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 567851b4f043..2c722deb2490 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -346,7 +346,7 @@ static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 ty #endif int acpi_bus_register_driver(struct acpi_driver *driver); void acpi_bus_unregister_driver(struct acpi_driver *driver); -int acpi_bus_add(acpi_handle handle); +int acpi_bus_scan(acpi_handle handle); void acpi_bus_hot_remove_device(void *context); int acpi_bus_trim(struct acpi_device *start); acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd); -- cgit v1.2.3 From 51fac8388a0325a43f0ae67453ece2c373e2ec28 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 24 Jan 2013 00:24:48 +0100 Subject: ACPI: Remove useless type argument of driver .remove() operation The second argument of ACPI driver .remove() operation is only used by the ACPI processor driver and the value passed to that driver through it is always available from the given struct acpi_device object's removal_type field. For this reason, the second ACPI driver .remove() argument is in fact useless, so drop it. Signed-off-by: Rafael J. Wysocki Reviewed-by: Jiang Liu Acked-by: Toshi Kani Acked-by: Yinghai Lu --- arch/ia64/hp/common/aml_nfw.c | 2 +- arch/x86/platform/olpc/olpc-xo15-sci.c | 2 +- drivers/acpi/ac.c | 4 ++-- drivers/acpi/acpi_memhotplug.c | 4 ++-- drivers/acpi/acpi_pad.c | 3 +-- drivers/acpi/battery.c | 2 +- drivers/acpi/button.c | 4 ++-- drivers/acpi/container.c | 4 ++-- drivers/acpi/ec.c | 2 +- drivers/acpi/fan.c | 4 ++-- drivers/acpi/hed.c | 2 +- drivers/acpi/pci_link.c | 4 ++-- drivers/acpi/pci_root.c | 4 ++-- drivers/acpi/processor_driver.c | 6 +++--- drivers/acpi/sbs.c | 6 +++--- drivers/acpi/sbshc.c | 4 ++-- drivers/acpi/scan.c | 5 ++--- drivers/acpi/thermal.c | 4 ++-- drivers/acpi/video.c | 4 ++-- drivers/char/hpet.c | 2 +- drivers/char/sonypi.c | 2 +- drivers/hwmon/acpi_power_meter.c | 2 +- drivers/hwmon/asus_atk0110.c | 4 ++-- drivers/i2c/busses/i2c-scmi.c | 2 +- drivers/input/misc/atlas_btns.c | 2 +- drivers/platform/x86/asus-laptop.c | 2 +- drivers/platform/x86/classmate-laptop.c | 10 +++++----- drivers/platform/x86/eeepc-laptop.c | 2 +- drivers/platform/x86/fujitsu-laptop.c | 4 ++-- drivers/platform/x86/fujitsu-tablet.c | 2 +- drivers/platform/x86/hp_accel.c | 2 +- drivers/platform/x86/ideapad-laptop.c | 2 +- drivers/platform/x86/intel_menlow.c | 2 +- drivers/platform/x86/panasonic-laptop.c | 4 ++-- drivers/platform/x86/sony-laptop.c | 4 ++-- drivers/platform/x86/topstar-laptop.c | 2 +- drivers/platform/x86/toshiba_acpi.c | 4 ++-- drivers/platform/x86/toshiba_bluetooth.c | 4 ++-- drivers/platform/x86/wmi.c | 4 ++-- drivers/platform/x86/xo15-ebook.c | 2 +- drivers/staging/quickstart/quickstart.c | 2 +- drivers/video/backlight/apple_bl.c | 2 +- drivers/xen/xen-acpi-pad.c | 3 +-- include/acpi/acpi_bus.h | 2 +- 44 files changed, 70 insertions(+), 73 deletions(-) (limited to 'drivers/acpi/acpi_memhotplug.c') diff --git a/arch/ia64/hp/common/aml_nfw.c b/arch/ia64/hp/common/aml_nfw.c index 6192f7188654..916ffe770bcf 100644 --- a/arch/ia64/hp/common/aml_nfw.c +++ b/arch/ia64/hp/common/aml_nfw.c @@ -191,7 +191,7 @@ static int aml_nfw_add(struct acpi_device *device) return aml_nfw_add_global_handler(); } -static int aml_nfw_remove(struct acpi_device *device, int type) +static int aml_nfw_remove(struct acpi_device *device) { return aml_nfw_remove_global_handler(); } diff --git a/arch/x86/platform/olpc/olpc-xo15-sci.c b/arch/x86/platform/olpc/olpc-xo15-sci.c index 2fdca25905ae..fef7d0ba7e3a 100644 --- a/arch/x86/platform/olpc/olpc-xo15-sci.c +++ b/arch/x86/platform/olpc/olpc-xo15-sci.c @@ -195,7 +195,7 @@ err_sysfs: return r; } -static int xo15_sci_remove(struct acpi_device *device, int type) +static int xo15_sci_remove(struct acpi_device *device) { acpi_disable_gpe(NULL, xo15_sci_gpe); acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler); diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index d5fdd36190cc..6d5bf649196d 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -60,7 +60,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file); #endif static int acpi_ac_add(struct acpi_device *device); -static int acpi_ac_remove(struct acpi_device *device, int type); +static int acpi_ac_remove(struct acpi_device *device); static void acpi_ac_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id ac_device_ids[] = { @@ -337,7 +337,7 @@ static int acpi_ac_resume(struct device *dev) } #endif -static int acpi_ac_remove(struct acpi_device *device, int type) +static int acpi_ac_remove(struct acpi_device *device) { struct acpi_ac *ac = NULL; diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 03d18f290118..94c823b25138 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); #define MEMORY_POWER_OFF_STATE 2 static int acpi_memory_device_add(struct acpi_device *device); -static int acpi_memory_device_remove(struct acpi_device *device, int type); +static int acpi_memory_device_remove(struct acpi_device *device); static const struct acpi_device_id memory_device_ids[] = { {ACPI_MEMORY_DEVICE_HID, 0}, @@ -415,7 +415,7 @@ static int acpi_memory_device_add(struct acpi_device *device) return result; } -static int acpi_memory_device_remove(struct acpi_device *device, int type) +static int acpi_memory_device_remove(struct acpi_device *device) { struct acpi_memory_device *mem_device = NULL; int result; diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 16fa979f7180..31de1043eea0 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -482,8 +482,7 @@ static int acpi_pad_add(struct acpi_device *device) return 0; } -static int acpi_pad_remove(struct acpi_device *device, - int type) +static int acpi_pad_remove(struct acpi_device *device) { mutex_lock(&isolated_cpus_lock); acpi_pad_idle_cpus(0); diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 7efaeaa53b88..c5cd5b5513e6 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1111,7 +1111,7 @@ fail: return result; } -static int acpi_battery_remove(struct acpi_device *device, int type) +static int acpi_battery_remove(struct acpi_device *device) { struct acpi_battery *battery = NULL; diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index f0d936b65e37..86c7d5445c38 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -75,7 +75,7 @@ static const struct acpi_device_id button_device_ids[] = { MODULE_DEVICE_TABLE(acpi, button_device_ids); static int acpi_button_add(struct acpi_device *device); -static int acpi_button_remove(struct acpi_device *device, int type); +static int acpi_button_remove(struct acpi_device *device); static void acpi_button_notify(struct acpi_device *device, u32 event); #ifdef CONFIG_PM_SLEEP @@ -433,7 +433,7 @@ static int acpi_button_add(struct acpi_device *device) return error; } -static int acpi_button_remove(struct acpi_device *device, int type) +static int acpi_button_remove(struct acpi_device *device) { struct acpi_button *button = acpi_driver_data(device); diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index cc79d3e53a39..cc0bf4613e0d 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -52,7 +52,7 @@ MODULE_DESCRIPTION("ACPI container driver"); MODULE_LICENSE("GPL"); static int acpi_container_add(struct acpi_device *device); -static int acpi_container_remove(struct acpi_device *device, int type); +static int acpi_container_remove(struct acpi_device *device); static const struct acpi_device_id container_device_ids[] = { {"ACPI0004", 0}, @@ -125,7 +125,7 @@ static int acpi_container_add(struct acpi_device *device) return 0; } -static int acpi_container_remove(struct acpi_device *device, int type) +static int acpi_container_remove(struct acpi_device *device) { acpi_status status = AE_OK; struct acpi_container *pc = NULL; diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 354007d490d1..d45b2871d33b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -852,7 +852,7 @@ static int acpi_ec_add(struct acpi_device *device) return ret; } -static int acpi_ec_remove(struct acpi_device *device, int type) +static int acpi_ec_remove(struct acpi_device *device) { struct acpi_ec *ec; struct acpi_ec_query_handler *handler, *tmp; diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 3bd6a54702d6..f815da82c765 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -45,7 +45,7 @@ MODULE_DESCRIPTION("ACPI Fan Driver"); MODULE_LICENSE("GPL"); static int acpi_fan_add(struct acpi_device *device); -static int acpi_fan_remove(struct acpi_device *device, int type); +static int acpi_fan_remove(struct acpi_device *device); static const struct acpi_device_id fan_device_ids[] = { {"PNP0C0B", 0}, @@ -172,7 +172,7 @@ static int acpi_fan_add(struct acpi_device *device) return result; } -static int acpi_fan_remove(struct acpi_device *device, int type) +static int acpi_fan_remove(struct acpi_device *device) { struct thermal_cooling_device *cdev = acpi_driver_data(device); diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c index a0cc796932f7..13b1d39d7cdf 100644 --- a/drivers/acpi/hed.c +++ b/drivers/acpi/hed.c @@ -70,7 +70,7 @@ static int acpi_hed_add(struct acpi_device *device) return 0; } -static int acpi_hed_remove(struct acpi_device *device, int type) +static int acpi_hed_remove(struct acpi_device *device) { hed_handle = NULL; return 0; diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index a12808259dfb..b6592797f5b2 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -54,7 +54,7 @@ ACPI_MODULE_NAME("pci_link"); #define ACPI_PCI_LINK_MAX_POSSIBLE 16 static int acpi_pci_link_add(struct acpi_device *device); -static int acpi_pci_link_remove(struct acpi_device *device, int type); +static int acpi_pci_link_remove(struct acpi_device *device); static const struct acpi_device_id link_device_ids[] = { {"PNP0C0F", 0}, @@ -766,7 +766,7 @@ static void irqrouter_resume(void) } } -static int acpi_pci_link_remove(struct acpi_device *device, int type) +static int acpi_pci_link_remove(struct acpi_device *device) { struct acpi_pci_link *link; diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 22a8458b4ec9..8890775e8b25 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -46,7 +46,7 @@ ACPI_MODULE_NAME("pci_root"); #define ACPI_PCI_ROOT_CLASS "pci_bridge" #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" static int acpi_pci_root_add(struct acpi_device *device); -static int acpi_pci_root_remove(struct acpi_device *device, int type); +static int acpi_pci_root_remove(struct acpi_device *device); #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ | OSC_ACTIVE_STATE_PWR_SUPPORT \ @@ -627,7 +627,7 @@ end: return result; } -static int acpi_pci_root_remove(struct acpi_device *device, int type) +static int acpi_pci_root_remove(struct acpi_device *device) { acpi_status status; acpi_handle handle; diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 9c5929a17d3a..c5d2fd85dbe0 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -81,7 +81,7 @@ MODULE_DESCRIPTION("ACPI Processor Driver"); MODULE_LICENSE("GPL"); static int acpi_processor_add(struct acpi_device *device); -static int acpi_processor_remove(struct acpi_device *device, int type); +static int acpi_processor_remove(struct acpi_device *device); static void acpi_processor_notify(struct acpi_device *device, u32 event); static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr); static int acpi_processor_handle_eject(struct acpi_processor *pr); @@ -610,7 +610,7 @@ err_free_pr: return result; } -static int acpi_processor_remove(struct acpi_device *device, int type) +static int acpi_processor_remove(struct acpi_device *device) { struct acpi_processor *pr = NULL; @@ -623,7 +623,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type) if (pr->id >= nr_cpu_ids) goto free; - if (type == ACPI_BUS_REMOVAL_EJECT) { + if (device->removal_type == ACPI_BUS_REMOVAL_EJECT) { if (acpi_processor_handle_eject(pr)) return -EINVAL; } diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index ff0740e0a9c2..e523245643ac 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -130,7 +130,7 @@ struct acpi_sbs { #define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) -static int acpi_sbs_remove(struct acpi_device *device, int type); +static int acpi_sbs_remove(struct acpi_device *device); static int acpi_battery_get_state(struct acpi_battery *battery); static inline int battery_scale(int log) @@ -949,11 +949,11 @@ static int acpi_sbs_add(struct acpi_device *device) acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs); end: if (result) - acpi_sbs_remove(device, 0); + acpi_sbs_remove(device); return result; } -static int acpi_sbs_remove(struct acpi_device *device, int type) +static int acpi_sbs_remove(struct acpi_device *device) { struct acpi_sbs *sbs; int id; diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index cf6129a8af7c..b78bc605837e 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -33,7 +33,7 @@ struct acpi_smb_hc { }; static int acpi_smbus_hc_add(struct acpi_device *device); -static int acpi_smbus_hc_remove(struct acpi_device *device, int type); +static int acpi_smbus_hc_remove(struct acpi_device *device); static const struct acpi_device_id sbs_device_ids[] = { {"ACPI0001", 0}, @@ -296,7 +296,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device) extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); -static int acpi_smbus_hc_remove(struct acpi_device *device, int type) +static int acpi_smbus_hc_remove(struct acpi_device *device) { struct acpi_smb_hc *hc; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index bc8077f173da..0989b323e65f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -577,8 +577,7 @@ static int acpi_device_probe(struct device * dev) 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; } } @@ -600,7 +599,7 @@ static int acpi_device_remove(struct device * dev) 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; diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 506fbd4b5733..da079d4e0baa 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -97,7 +97,7 @@ module_param(psv, int, 0644); MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); static int acpi_thermal_add(struct acpi_device *device); -static int acpi_thermal_remove(struct acpi_device *device, int type); +static int acpi_thermal_remove(struct acpi_device *device); static void acpi_thermal_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id thermal_device_ids[] = { @@ -1111,7 +1111,7 @@ end: return result; } -static int acpi_thermal_remove(struct acpi_device *device, int type) +static int acpi_thermal_remove(struct acpi_device *device) { struct acpi_thermal *tz = NULL; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index ac9a69cd45f5..5be60ad8381f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -88,7 +88,7 @@ module_param(use_bios_initial_backlight, bool, 0644); static int register_count = 0; static int acpi_video_bus_add(struct acpi_device *device); -static int acpi_video_bus_remove(struct acpi_device *device, int type); +static int acpi_video_bus_remove(struct acpi_device *device); static void acpi_video_bus_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id video_device_ids[] = { @@ -1740,7 +1740,7 @@ static int acpi_video_bus_add(struct acpi_device *device) return error; } -static int acpi_video_bus_remove(struct acpi_device *device, int type) +static int acpi_video_bus_remove(struct acpi_device *device) { struct acpi_video_bus *video = NULL; diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index fe6d4be48296..e3f9a99b8522 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -1041,7 +1041,7 @@ static int hpet_acpi_add(struct acpi_device *device) return hpet_alloc(&data); } -static int hpet_acpi_remove(struct acpi_device *device, int type) +static int hpet_acpi_remove(struct acpi_device *device) { /* XXX need to unregister clocksource, dealloc mem, etc */ return -EINVAL; diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index d780295a1473..6386a98e43c1 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1142,7 +1142,7 @@ static int sonypi_acpi_add(struct acpi_device *device) return 0; } -static int sonypi_acpi_remove(struct acpi_device *device, int type) +static int sonypi_acpi_remove(struct acpi_device *device) { sonypi_acpi_device = NULL; return 0; diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 1672e2a5db46..6351aba8819c 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -911,7 +911,7 @@ exit: return res; } -static int acpi_power_meter_remove(struct acpi_device *device, int type) +static int acpi_power_meter_remove(struct acpi_device *device) { struct acpi_power_meter_resource *resource; diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 56dbcfb3e301..b25c64302cbc 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c @@ -190,7 +190,7 @@ struct atk_acpi_input_buf { }; static int atk_add(struct acpi_device *device); -static int atk_remove(struct acpi_device *device, int type); +static int atk_remove(struct acpi_device *device); static void atk_print_sensor(struct atk_data *data, union acpi_object *obj); static int atk_read_value(struct atk_sensor_data *sensor, u64 *value); static void atk_free_sensors(struct atk_data *data); @@ -1416,7 +1416,7 @@ out: return err; } -static int atk_remove(struct acpi_device *device, int type) +static int atk_remove(struct acpi_device *device) { struct atk_data *data = device->driver_data; dev_dbg(&device->dev, "removing...\n"); diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index 6aafa3d88ff0..c447e8d40b78 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c @@ -406,7 +406,7 @@ err: return -EIO; } -static int acpi_smbus_cmi_remove(struct acpi_device *device, int type) +static int acpi_smbus_cmi_remove(struct acpi_device *device) { struct acpi_smbus_cmi *smbus_cmi = acpi_driver_data(device); diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 26f13131639a..5d4402365a52 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c @@ -121,7 +121,7 @@ static int atlas_acpi_button_add(struct acpi_device *device) return err; } -static int atlas_acpi_button_remove(struct acpi_device *device, int type) +static int atlas_acpi_button_remove(struct acpi_device *device) { acpi_status status; diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index fcde4e528819..d9f9a0dbc6f3 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1910,7 +1910,7 @@ fail_platform: return result; } -static int asus_acpi_remove(struct acpi_device *device, int type) +static int asus_acpi_remove(struct acpi_device *device) { struct asus_laptop *asus = acpi_driver_data(device); diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index c87ff16873f9..36e5e6c13db4 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -432,7 +432,7 @@ failed_sensitivity: return error; } -static int cmpc_accel_remove_v4(struct acpi_device *acpi, int type) +static int cmpc_accel_remove_v4(struct acpi_device *acpi) { struct input_dev *inputdev; struct cmpc_accel *accel; @@ -668,7 +668,7 @@ failed_file: return error; } -static int cmpc_accel_remove(struct acpi_device *acpi, int type) +static int cmpc_accel_remove(struct acpi_device *acpi) { struct input_dev *inputdev; struct cmpc_accel *accel; @@ -753,7 +753,7 @@ static int cmpc_tablet_add(struct acpi_device *acpi) cmpc_tablet_idev_init); } -static int cmpc_tablet_remove(struct acpi_device *acpi, int type) +static int cmpc_tablet_remove(struct acpi_device *acpi) { return cmpc_remove_acpi_notify_device(acpi); } @@ -1000,7 +1000,7 @@ out_bd: return retval; } -static int cmpc_ipml_remove(struct acpi_device *acpi, int type) +static int cmpc_ipml_remove(struct acpi_device *acpi) { struct ipml200_dev *ipml; @@ -1079,7 +1079,7 @@ static int cmpc_keys_add(struct acpi_device *acpi) cmpc_keys_idev_init); } -static int cmpc_keys_remove(struct acpi_device *acpi, int type) +static int cmpc_keys_remove(struct acpi_device *acpi) { return cmpc_remove_acpi_notify_device(acpi); } diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 528e9495458d..98935f945f53 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1501,7 +1501,7 @@ fail_platform: return result; } -static int eeepc_acpi_remove(struct acpi_device *device, int type) +static int eeepc_acpi_remove(struct acpi_device *device) { struct eeepc_laptop *eeepc = acpi_driver_data(device); diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index c4c1a5444b38..1c9386e7c58c 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -733,7 +733,7 @@ err_stop: return result; } -static int acpi_fujitsu_remove(struct acpi_device *device, int type) +static int acpi_fujitsu_remove(struct acpi_device *device) { struct fujitsu_t *fujitsu = acpi_driver_data(device); struct input_dev *input = fujitsu->input; @@ -938,7 +938,7 @@ err_stop: return result; } -static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) +static int acpi_fujitsu_hotkey_remove(struct acpi_device *device) { struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device); struct input_dev *input = fujitsu_hotkey->input; diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c index 174ca01c4aa7..570926c10014 100644 --- a/drivers/platform/x86/fujitsu-tablet.c +++ b/drivers/platform/x86/fujitsu-tablet.c @@ -431,7 +431,7 @@ static int acpi_fujitsu_add(struct acpi_device *adev) return 0; } -static int acpi_fujitsu_remove(struct acpi_device *adev, int type) +static int acpi_fujitsu_remove(struct acpi_device *adev) { free_irq(fujitsu.irq, fujitsu_interrupt); release_region(fujitsu.io_base, fujitsu.io_length); diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 18d74f29dcb2..e64a7a870d42 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -337,7 +337,7 @@ static int lis3lv02d_add(struct acpi_device *device) return ret; } -static int lis3lv02d_remove(struct acpi_device *device, int type) +static int lis3lv02d_remove(struct acpi_device *device) { if (!device) return -EINVAL; diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 64bfb30a52e9..17f00b8dc5cb 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -834,7 +834,7 @@ platform_failed: return ret; } -static int ideapad_acpi_remove(struct acpi_device *adevice, int type) +static int ideapad_acpi_remove(struct acpi_device *adevice) { struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); int i; diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index 3271ac85115e..d6cfc1558c2f 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c @@ -200,7 +200,7 @@ static int intel_menlow_memory_add(struct acpi_device *device) } -static int intel_menlow_memory_remove(struct acpi_device *device, int type) +static int intel_menlow_memory_remove(struct acpi_device *device) { struct thermal_cooling_device *cdev = acpi_driver_data(device); diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 8e8caa767d6a..4add9a31bf60 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -176,7 +176,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0, /* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */ static int acpi_pcc_hotkey_add(struct acpi_device *device); -static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type); +static int acpi_pcc_hotkey_remove(struct acpi_device *device); static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id pcc_device_ids[] = { @@ -663,7 +663,7 @@ static int __init acpi_pcc_init(void) return 0; } -static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type) +static int acpi_pcc_hotkey_remove(struct acpi_device *device) { struct pcc_acpi *pcc = acpi_driver_data(device); diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index b8ad71f7863f..ceb41eff4230 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -2740,7 +2740,7 @@ outwalk: return result; } -static int sony_nc_remove(struct acpi_device *device, int type) +static int sony_nc_remove(struct acpi_device *device) { struct sony_nc_value *item; @@ -4111,7 +4111,7 @@ found: * ACPI driver * *****************/ -static int sony_pic_remove(struct acpi_device *device, int type) +static int sony_pic_remove(struct acpi_device *device) { struct sony_pic_ioport *io, *tmp_io; struct sony_pic_irq *irq, *tmp_irq; diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index d727bfee89a6..4ab618c63b45 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -157,7 +157,7 @@ add_err: return -ENODEV; } -static int acpi_topstar_remove(struct acpi_device *device, int type) +static int acpi_topstar_remove(struct acpi_device *device) { struct topstar_hkey *tps_hkey = acpi_driver_data(device); diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index c2727895794c..904476b2fa8f 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -1118,7 +1118,7 @@ static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev) return 0; } -static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type) +static int toshiba_acpi_remove(struct acpi_device *acpi_dev) { struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); @@ -1250,7 +1250,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) return 0; error: - toshiba_acpi_remove(acpi_dev, 0); + toshiba_acpi_remove(acpi_dev); return ret; } diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index e95be0b74859..74dd01ae343b 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c @@ -32,7 +32,7 @@ MODULE_LICENSE("GPL"); static int toshiba_bt_rfkill_add(struct acpi_device *device); -static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type); +static int toshiba_bt_rfkill_remove(struct acpi_device *device); static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id bt_device_ids[] = { @@ -122,7 +122,7 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) return result; } -static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type) +static int toshiba_bt_rfkill_remove(struct acpi_device *device) { /* clean up */ return 0; diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 42a4dcc25f92..e4ac38aca580 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -92,7 +92,7 @@ module_param(debug_dump_wdg, bool, 0444); MODULE_PARM_DESC(debug_dump_wdg, "Dump available WMI interfaces [0/1]"); -static int acpi_wmi_remove(struct acpi_device *device, int type); +static int acpi_wmi_remove(struct acpi_device *device); static int acpi_wmi_add(struct acpi_device *device); static void acpi_wmi_notify(struct acpi_device *device, u32 event); @@ -917,7 +917,7 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event) } } -static int acpi_wmi_remove(struct acpi_device *device, int type) +static int acpi_wmi_remove(struct acpi_device *device) { acpi_remove_address_space_handler(device->handle, ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler); diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index 16d340c3b852..4b1377bd5944 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c @@ -150,7 +150,7 @@ static int ebook_switch_add(struct acpi_device *device) return error; } -static int ebook_switch_remove(struct acpi_device *device, int type) +static int ebook_switch_remove(struct acpi_device *device) { struct ebook_switch *button = acpi_driver_data(device); diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index cac320738142..adb8da564cf6 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c @@ -296,7 +296,7 @@ fail_config: return ret; } -static int quickstart_acpi_remove(struct acpi_device *device, int type) +static int quickstart_acpi_remove(struct acpi_device *device) { acpi_status status; struct quickstart_acpi *quickstart; diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c index f088d4c07381..d84329676689 100644 --- a/drivers/video/backlight/apple_bl.c +++ b/drivers/video/backlight/apple_bl.c @@ -196,7 +196,7 @@ static int apple_bl_add(struct acpi_device *dev) return 0; } -static int apple_bl_remove(struct acpi_device *dev, int type) +static int apple_bl_remove(struct acpi_device *dev) { backlight_device_unregister(apple_backlight_device); diff --git a/drivers/xen/xen-acpi-pad.c b/drivers/xen/xen-acpi-pad.c index da39191e7278..c763479ed85e 100644 --- a/drivers/xen/xen-acpi-pad.c +++ b/drivers/xen/xen-acpi-pad.c @@ -140,8 +140,7 @@ static int acpi_pad_add(struct acpi_device *device) return 0; } -static int acpi_pad_remove(struct acpi_device *device, - int type) +static int acpi_pad_remove(struct acpi_device *device) { mutex_lock(&xen_cpu_lock); xen_acpi_pad_idle_cpus(0); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 2c722deb2490..7714a1c2bbc5 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -89,7 +89,7 @@ struct acpi_device; */ typedef int (*acpi_op_add) (struct acpi_device * device); -typedef int (*acpi_op_remove) (struct acpi_device * device, int type); +typedef int (*acpi_op_remove) (struct acpi_device * device); typedef int (*acpi_op_start) (struct acpi_device * device); typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event); -- cgit v1.2.3 From 3757b94802fb65d8f696597a74053cf21738da0b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 13 Feb 2013 14:36:47 +0100 Subject: ACPI / hotplug: Fix concurrency issues and memory leaks This changeset is aimed at fixing a few different but related problems in the ACPI hotplug infrastructure. First of all, since notify handlers may be run in parallel with acpi_bus_scan(), acpi_bus_trim() and acpi_bus_hot_remove_device() and some of them are installed for ACPI handles that have no struct acpi_device objects attached (i.e. before those objects are created), those notify handlers have to take acpi_scan_lock to prevent races from taking place (e.g. a struct acpi_device is found to be present for the given ACPI handle, but right after that it is removed by acpi_bus_trim() running in parallel to the given notify handler). Moreover, since some of them call acpi_bus_scan() and acpi_bus_trim(), this leads to the conclusion that acpi_scan_lock should be acquired by the callers of these two funtions rather by these functions themselves. For these reasons, make all notify handlers that can handle device addition and eject events take acpi_scan_lock and remove the acpi_scan_lock locking from acpi_bus_scan() and acpi_bus_trim(). Accordingly, update all of their users to make sure that they are always called under acpi_scan_lock. Furthermore, since eject operations are carried out asynchronously with respect to the notify events that trigger them, with the help of acpi_bus_hot_remove_device(), even if notify handlers take the ACPI scan lock, it still is possible that, for example, acpi_bus_trim() will run between acpi_bus_hot_remove_device() and the notify handler that scheduled its execution and that acpi_bus_trim() will remove the device node passed to acpi_bus_hot_remove_device() for ejection. In that case, the struct acpi_device object obtained by acpi_bus_hot_remove_device() will be invalid and not-so-funny things will ensue. To protect agaist that, make the users of acpi_bus_hot_remove_device() run get_device() on ACPI device node objects that are about to be passed to it and make acpi_bus_hot_remove_device() run put_device() on them and check if their ACPI handles are not NULL (make acpi_device_unregister() clear the device nodes' ACPI handles for that check to work). Finally, observe that acpi_os_hotplug_execute() actually can fail, in which case its caller ought to free memory allocated for the context object to prevent leaks from happening. It also needs to run put_device() on the device node that it ran get_device() on previously in that case. Modify the code accordingly. Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu --- drivers/acpi/acpi_memhotplug.c | 56 ++++++++++++++++++++----------- drivers/acpi/container.c | 12 ++++--- drivers/acpi/dock.c | 19 +++++++++-- drivers/acpi/processor_driver.c | 24 +++++++++---- drivers/acpi/scan.c | 69 ++++++++++++++++++++++++++------------ drivers/pci/hotplug/acpiphp_glue.c | 6 ++++ drivers/pci/hotplug/sgi_hotplug.c | 5 ++- include/acpi/acpi_bus.h | 3 ++ 8 files changed, 139 insertions(+), 55 deletions(-) (limited to 'drivers/acpi/acpi_memhotplug.c') diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 94c823b25138..034d3e72aa92 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -153,14 +153,16 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) return 0; } -static int -acpi_memory_get_device(acpi_handle handle, - struct acpi_memory_device **mem_device) +static int acpi_memory_get_device(acpi_handle handle, + struct acpi_memory_device **mem_device) { struct acpi_device *device = NULL; - int result; + int result = 0; - if (!acpi_bus_get_device(handle, &device) && device) + acpi_scan_lock_acquire(); + + acpi_bus_get_device(handle, &device); + if (device) goto end; /* @@ -169,23 +171,28 @@ acpi_memory_get_device(acpi_handle handle, */ result = acpi_bus_scan(handle); if (result) { - acpi_handle_warn(handle, "Cannot add acpi bus\n"); - return -EINVAL; + acpi_handle_warn(handle, "ACPI namespace scan failed\n"); + result = -EINVAL; + goto out; } result = acpi_bus_get_device(handle, &device); if (result) { acpi_handle_warn(handle, "Missing device object\n"); - return -EINVAL; + result = -EINVAL; + goto out; } - end: + end: *mem_device = acpi_driver_data(device); if (!(*mem_device)) { dev_err(&device->dev, "driver data not found\n"); - return -ENODEV; + result = -ENODEV; + goto out; } - return 0; + out: + acpi_scan_lock_release(); + return result; } static int acpi_memory_check_device(struct acpi_memory_device *mem_device) @@ -305,6 +312,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) struct acpi_device *device; struct acpi_eject_event *ej_event = NULL; u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ + acpi_status status; switch (event) { case ACPI_NOTIFY_BUS_CHECK: @@ -327,29 +335,40 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "\nReceived EJECT REQUEST notification for device\n")); + status = AE_ERROR; + acpi_scan_lock_acquire(); + if (acpi_bus_get_device(handle, &device)) { acpi_handle_err(handle, "Device doesn't exist\n"); - break; + goto unlock; } mem_device = acpi_driver_data(device); if (!mem_device) { acpi_handle_err(handle, "Driver Data is NULL\n"); - break; + goto unlock; } ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); if (!ej_event) { pr_err(PREFIX "No memory, dropping EJECT\n"); - break; + goto unlock; } + get_device(&device->dev); ej_event->device = device; ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; - acpi_os_hotplug_execute(acpi_bus_hot_remove_device, - (void *)ej_event); + /* The eject is carried out asynchronously. */ + status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, + ej_event); + if (ACPI_FAILURE(status)) { + put_device(&device->dev); + kfree(ej_event); + } - /* eject is performed asynchronously */ - return; + unlock: + acpi_scan_lock_release(); + if (ACPI_SUCCESS(status)) + return; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); @@ -360,7 +379,6 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) /* Inform firmware that the hotplug operation has completed */ (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); - return; } static void acpi_memory_device_free(struct acpi_memory_device *mem_device) diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 4cc2937cc022..5523ba7d764d 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -88,6 +88,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) acpi_status status; u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ + acpi_scan_lock_acquire(); + switch (type) { case ACPI_NOTIFY_BUS_CHECK: /* Fall through */ @@ -103,7 +105,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) /* device exist and this is a remove request */ device->flags.eject_pending = 1; kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); - return; + goto out; } break; } @@ -130,18 +132,20 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) if (!acpi_bus_get_device(handle, &device) && device) { device->flags.eject_pending = 1; kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); - return; + goto out; } break; default: /* non-hotplug event; possibly handled by other handler */ - return; + goto out; } /* Inform firmware that the hotplug operation has completed */ (void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); - return; + + out: + acpi_scan_lock_release(); } static bool is_container(acpi_handle handle) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 68d720af71ed..4fdea381ef21 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -744,7 +744,9 @@ static void acpi_dock_deferred_cb(void *context) { struct dock_data *data = context; + acpi_scan_lock_acquire(); dock_notify(data->handle, data->event, data->ds); + acpi_scan_lock_release(); kfree(data); } @@ -757,20 +759,31 @@ static int acpi_dock_notifier_call(struct notifier_block *this, if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK && event != ACPI_NOTIFY_EJECT_REQUEST) return 0; + + acpi_scan_lock_acquire(); + list_for_each_entry(dock_station, &dock_stations, sibling) { if (dock_station->handle == handle) { struct dock_data *dd; + acpi_status status; dd = kmalloc(sizeof(*dd), GFP_KERNEL); if (!dd) - return 0; + break; + dd->handle = handle; dd->event = event; dd->ds = dock_station; - acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd); - return 0 ; + status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, + dd); + if (ACPI_FAILURE(status)) + kfree(dd); + + break; } } + + acpi_scan_lock_release(); return 0; } diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index c5d2fd85dbe0..cbf1f122666b 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -683,8 +683,11 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, struct acpi_device *device = NULL; struct acpi_eject_event *ej_event = NULL; u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ + acpi_status status; int result; + acpi_scan_lock_acquire(); + switch (event) { case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: @@ -733,25 +736,32 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, break; } + get_device(&device->dev); ej_event->device = device; ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; - acpi_os_hotplug_execute(acpi_bus_hot_remove_device, - (void *)ej_event); - - /* eject is performed asynchronously */ - return; + /* The eject is carried out asynchronously. */ + status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, + ej_event); + if (ACPI_FAILURE(status)) { + put_device(&device->dev); + kfree(ej_event); + break; + } + goto out; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); /* non-hotplug event; possibly handled by other handler */ - return; + goto out; } /* Inform firmware that the hotplug operation has completed */ (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); - return; + + out: + acpi_scan_lock_release(); } static acpi_status is_processor_device(acpi_handle handle) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c7676ee8eca4..d16a94ef0baf 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -42,6 +42,18 @@ struct acpi_device_bus_id{ struct list_head node; }; +void acpi_scan_lock_acquire(void) +{ + mutex_lock(&acpi_scan_lock); +} +EXPORT_SYMBOL_GPL(acpi_scan_lock_acquire); + +void acpi_scan_lock_release(void) +{ + mutex_unlock(&acpi_scan_lock); +} +EXPORT_SYMBOL_GPL(acpi_scan_lock_release); + int acpi_scan_add_handler(struct acpi_scan_handler *handler) { if (!handler || !handler->attach) @@ -95,8 +107,6 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha } static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); -static void __acpi_bus_trim(struct acpi_device *start); - /** * acpi_bus_hot_remove_device: hot-remove a device and its children * @context: struct acpi_eject_event pointer (freed in this func) @@ -107,7 +117,7 @@ static void __acpi_bus_trim(struct acpi_device *start); */ void acpi_bus_hot_remove_device(void *context) { - struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; + struct acpi_eject_event *ej_event = context; struct acpi_device *device = ej_event->device; acpi_handle handle = device->handle; acpi_handle temp; @@ -118,11 +128,19 @@ void acpi_bus_hot_remove_device(void *context) mutex_lock(&acpi_scan_lock); + /* If there is no handle, the device node has been unregistered. */ + if (!device->handle) { + dev_dbg(&device->dev, "ACPI handle missing\n"); + put_device(&device->dev); + goto out; + } + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Hot-removing device %s...\n", dev_name(&device->dev))); - __acpi_bus_trim(device); - /* Device node has been released. */ + acpi_bus_trim(device); + /* Device node has been unregistered. */ + put_device(&device->dev); device = NULL; if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) { @@ -151,6 +169,7 @@ void acpi_bus_hot_remove_device(void *context) ost_code, NULL); } + out: mutex_unlock(&acpi_scan_lock); kfree(context); return; @@ -212,6 +231,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, goto err; } + get_device(&acpi_device->dev); ej_event->device = acpi_device; if (acpi_device->flags.eject_pending) { /* event originated from ACPI eject notification */ @@ -224,7 +244,11 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); } - acpi_os_hotplug_execute(acpi_bus_hot_remove_device, (void *)ej_event); + status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); + if (ACPI_FAILURE(status)) { + put_device(&acpi_device->dev); + kfree(ej_event); + } err: return ret; } @@ -779,6 +803,7 @@ static void acpi_device_unregister(struct acpi_device *device) * no more references. */ acpi_device_set_power(device, ACPI_STATE_D3_COLD); + device->handle = NULL; put_device(&device->dev); } @@ -1623,14 +1648,14 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, * 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. + * + * Must be called under acpi_scan_lock. */ int acpi_bus_scan(acpi_handle handle) { void *device = NULL; int error = 0; - mutex_lock(&acpi_scan_lock); - if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, acpi_bus_check_add, NULL, NULL, &device); @@ -1641,7 +1666,6 @@ int acpi_bus_scan(acpi_handle handle) acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, acpi_bus_device_attach, NULL, NULL, NULL); - mutex_unlock(&acpi_scan_lock); return error; } EXPORT_SYMBOL(acpi_bus_scan); @@ -1678,7 +1702,13 @@ static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used, return AE_OK; } -static void __acpi_bus_trim(struct acpi_device *start) +/** + * acpi_bus_trim - Remove ACPI device node and all of its descendants + * @start: Root of the ACPI device nodes subtree to remove. + * + * Must be called under acpi_scan_lock. + */ +void acpi_bus_trim(struct acpi_device *start) { /* * Execute acpi_bus_device_detach() as a post-order callback to detach @@ -1695,13 +1725,6 @@ static void __acpi_bus_trim(struct acpi_device *start) acpi_bus_remove, NULL, NULL); acpi_bus_remove(start->handle, 0, NULL, NULL); } - -void acpi_bus_trim(struct acpi_device *start) -{ - mutex_lock(&acpi_scan_lock); - __acpi_bus_trim(start); - mutex_unlock(&acpi_scan_lock); -} EXPORT_SYMBOL_GPL(acpi_bus_trim); static int acpi_bus_scan_fixed(void) @@ -1758,23 +1781,27 @@ int __init acpi_scan_init(void) acpi_csrt_init(); acpi_container_init(); + mutex_lock(&acpi_scan_lock); /* * Enumerate devices in the ACPI namespace. */ result = acpi_bus_scan(ACPI_ROOT_OBJECT); if (result) - return result; + goto out; result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); if (result) - return result; + goto out; result = acpi_bus_scan_fixed(); if (result) { acpi_device_unregister(acpi_root); - return result; + goto out; } acpi_update_all_gpes(); - return 0; + + out: + mutex_unlock(&acpi_scan_lock); + return result; } diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index d1a6f4a25da8..a951c22921d1 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -1218,6 +1218,8 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) handle = hp_work->handle; type = hp_work->type; + acpi_scan_lock_acquire(); + if (acpi_bus_get_device(handle, &device)) { /* This bridge must have just been physically inserted */ handle_bridge_insertion(handle, type); @@ -1295,6 +1297,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) } out: + acpi_scan_lock_release(); kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ } @@ -1341,6 +1344,8 @@ static void _handle_hotplug_event_func(struct work_struct *work) func = (struct acpiphp_func *)context; + acpi_scan_lock_acquire(); + switch (type) { case ACPI_NOTIFY_BUS_CHECK: /* bus re-enumerate */ @@ -1371,6 +1376,7 @@ static void _handle_hotplug_event_func(struct work_struct *work) break; } + acpi_scan_lock_release(); kfree(hp_work); /* allocated in handle_hotplug_event_func */ } diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index ae606b3e991e..574421bc2fa6 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -425,6 +425,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) pdevice = NULL; } + acpi_scan_lock_acquire(); /* * Walk the rootbus node's immediate children looking for * the slot's device node(s). There can be more than @@ -458,6 +459,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) } } } + acpi_scan_lock_release(); } /* Call the driver for the new device */ @@ -508,6 +510,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) /* Get the rootbus node pointer */ phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; + acpi_scan_lock_acquire(); /* * Walk the rootbus node's immediate children looking for * the slot's device node(s). There can be more than @@ -538,7 +541,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) acpi_bus_trim(device); } } - + acpi_scan_lock_release(); } /* Free the SN resources assigned to the Linux device.*/ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 41850cb21730..227ba7dc293d 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -395,6 +395,9 @@ int acpi_bus_receive_event(struct acpi_bus_event *event); static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) { return 0; } #endif + +void acpi_scan_lock_acquire(void); +void acpi_scan_lock_release(void); int acpi_scan_add_handler(struct acpi_scan_handler *handler); int acpi_bus_register_driver(struct acpi_driver *driver); void acpi_bus_unregister_driver(struct acpi_driver *driver); -- cgit v1.2.3 From 60a5a19e7419ba0bc22ed01b3285e8940b42944c Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Fri, 22 Feb 2013 16:33:14 -0800 Subject: memory-hotplug: remove sysfs file of node Introduce a new function try_offline_node() to remove sysfs file of node when all memory sections of this node are removed. If some memory sections of this node are not removed, this function does nothing. Signed-off-by: Wen Congyang Signed-off-by: Tang Chen Cc: KOSAKI Motohiro Cc: Jiang Liu Cc: Jianguo Wu Cc: Kamezawa Hiroyuki Cc: Lai Jiangshan Cc: Wu Jianguo Cc: Yasuaki Ishimatsu Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "H. Peter Anvin" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/acpi/acpi_memhotplug.c | 8 ++++-- include/linux/memory_hotplug.h | 2 +- mm/memory_hotplug.c | 58 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 5 deletions(-) (limited to 'drivers/acpi/acpi_memhotplug.c') diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 034d3e72aa92..da1f82b445e0 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -280,9 +280,11 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) { - int result = 0; + int result = 0, nid; struct acpi_memory_info *info, *n; + nid = acpi_get_node(mem_device->device->handle); + list_for_each_entry_safe(info, n, &mem_device->res_list, list) { if (info->failed) /* The kernel does not use this memory block */ @@ -295,7 +297,9 @@ static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) */ return -EBUSY; - result = remove_memory(info->start_addr, info->length); + if (nid < 0) + nid = memory_add_physaddr_to_nid(info->start_addr); + result = remove_memory(nid, info->start_addr, info->length); if (result) return result; diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 4d523fe75ba1..69903ccf549e 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -248,7 +248,7 @@ extern int arch_add_memory(int nid, u64 start, u64 size); extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); extern int offline_memory_block(struct memory_block *mem); extern bool is_memblock_offlined(struct memory_block *mem); -extern int remove_memory(u64 start, u64 size); +extern int remove_memory(int nid, u64 start, u64 size); extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn, int nr_pages); extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 3f792375f326..aea6374f435a 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -1679,7 +1680,58 @@ static int is_memblock_offlined_cb(struct memory_block *mem, void *arg) return ret; } -int __ref remove_memory(u64 start, u64 size) +static int check_cpu_on_node(void *data) +{ + struct pglist_data *pgdat = data; + int cpu; + + for_each_present_cpu(cpu) { + if (cpu_to_node(cpu) == pgdat->node_id) + /* + * the cpu on this node isn't removed, and we can't + * offline this node. + */ + return -EBUSY; + } + + return 0; +} + +/* offline the node if all memory sections of this node are removed */ +static void try_offline_node(int nid) +{ + unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; + unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages; + unsigned long pfn; + + for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { + unsigned long section_nr = pfn_to_section_nr(pfn); + + if (!present_section_nr(section_nr)) + continue; + + if (pfn_to_nid(pfn) != nid) + continue; + + /* + * some memory sections of this node are not removed, and we + * can't offline node now. + */ + return; + } + + if (stop_machine(check_cpu_on_node, NODE_DATA(nid), NULL)) + return; + + /* + * all memory/cpu of this node are removed, we can offline this + * node now. + */ + node_set_offline(nid); + unregister_one_node(nid); +} + +int __ref remove_memory(int nid, u64 start, u64 size) { unsigned long start_pfn, end_pfn; int ret = 0; @@ -1734,6 +1786,8 @@ repeat: arch_remove_memory(start, size); + try_offline_node(nid); + unlock_memory_hotplug(); return 0; @@ -1743,7 +1797,7 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages) { return -EINVAL; } -int remove_memory(u64 start, u64 size) +int remove_memory(int nid, u64 start, u64 size) { return -EINVAL; } -- cgit v1.2.3