aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-11-06 19:41:58 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-11-06 19:41:58 -0500
commita3b1b1ef78cd2ffb5d3a223465064dee05929dc3 (patch)
tree4562daf8598ad8ed1538f61895e9c874780690f2 /drivers
parentace8238b00eafd493b8dbcc7db813ed72b8b6e87 (diff)
ACPI / hotplug: Merge device hot-removal routines
There is no real reasn why acpi_bus_device_eject() and acpi_bus_hot_remove_device() should work differently, so rework acpi_bus_device_eject() so that it can be called internally by both acpi_bus_hot_remove_device() and acpi_eject_store_work(). Accordingly, rework acpi_hotplug_notify_cb() to queue up the execution of acpi_bus_hot_remove_device() through acpi_os_hotplug_execute() on eject request notifications. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/scan.c84
1 files changed, 38 insertions, 46 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 1217ba33f8bf..4a0a591feed3 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -285,10 +285,9 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
285 return 0; 285 return 0;
286} 286}
287 287
288static void acpi_bus_device_eject(void *context) 288static void acpi_bus_device_eject(struct acpi_device *device, u32 ost_src)
289{ 289{
290 acpi_handle handle = context; 290 acpi_handle handle = device->handle;
291 struct acpi_device *device = NULL;
292 struct acpi_scan_handler *handler; 291 struct acpi_scan_handler *handler;
293 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 292 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
294 int error; 293 int error;
@@ -296,20 +295,19 @@ static void acpi_bus_device_eject(void *context)
296 lock_device_hotplug(); 295 lock_device_hotplug();
297 mutex_lock(&acpi_scan_lock); 296 mutex_lock(&acpi_scan_lock);
298 297
299 acpi_bus_get_device(handle, &device);
300 if (!device)
301 goto err_out;
302
303 handler = device->handler; 298 handler = device->handler;
304 if (!handler || !handler->hotplug.enabled) 299 if (!handler || !handler->hotplug.enabled) {
300 put_device(&device->dev);
305 goto err_support; 301 goto err_support;
302 }
303
304 if (ost_src == ACPI_NOTIFY_EJECT_REQUEST)
305 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
306 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
306 307
307 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST,
308 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
309 if (handler->hotplug.mode == AHM_CONTAINER) 308 if (handler->hotplug.mode == AHM_CONTAINER)
310 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); 309 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
311 310
312 get_device(&device->dev);
313 error = acpi_scan_hot_remove(device); 311 error = acpi_scan_hot_remove(device);
314 if (error == -EPERM) { 312 if (error == -EPERM) {
315 goto err_support; 313 goto err_support;
@@ -325,8 +323,7 @@ static void acpi_bus_device_eject(void *context)
325 err_support: 323 err_support:
326 ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; 324 ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
327 err_out: 325 err_out:
328 acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, ost_code, 326 acpi_evaluate_hotplug_ost(handle, ost_src, ost_code, NULL);
329 NULL);
330 goto out; 327 goto out;
331} 328}
332 329
@@ -408,10 +405,20 @@ static void acpi_hotplug_unsupported(acpi_handle handle, u32 type)
408 acpi_evaluate_hotplug_ost(handle, type, ost_status, NULL); 405 acpi_evaluate_hotplug_ost(handle, type, ost_status, NULL);
409} 406}
410 407
408/**
409 * acpi_bus_hot_remove_device: Hot-remove a device and its children.
410 * @context: Address of the ACPI device object to hot-remove.
411 */
412void acpi_bus_hot_remove_device(void *context)
413{
414 acpi_bus_device_eject(context, ACPI_NOTIFY_EJECT_REQUEST);
415}
416
411static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) 417static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
412{ 418{
413 acpi_osd_exec_callback callback; 419 acpi_osd_exec_callback callback;
414 struct acpi_scan_handler *handler = data; 420 struct acpi_scan_handler *handler = data;
421 struct acpi_device *adev;
415 acpi_status status; 422 acpi_status status;
416 423
417 if (!handler->hotplug.enabled) 424 if (!handler->hotplug.enabled)
@@ -428,44 +435,29 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
428 break; 435 break;
429 case ACPI_NOTIFY_EJECT_REQUEST: 436 case ACPI_NOTIFY_EJECT_REQUEST:
430 acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); 437 acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n");
431 callback = acpi_bus_device_eject; 438 status = acpi_bus_get_device(handle, &adev);
432 break; 439 if (ACPI_FAILURE(status))
440 goto err_out;
441
442 get_device(&adev->dev);
443 callback = acpi_bus_hot_remove_device;
444 status = acpi_os_hotplug_execute(callback, adev);
445 if (ACPI_SUCCESS(status))
446 return;
447
448 put_device(&adev->dev);
449 goto err_out;
433 default: 450 default:
434 /* non-hotplug event; possibly handled by other handler */ 451 /* non-hotplug event; possibly handled by other handler */
435 return; 452 return;
436 } 453 }
437 status = acpi_os_hotplug_execute(callback, handle); 454 status = acpi_os_hotplug_execute(callback, handle);
438 if (ACPI_FAILURE(status)) 455 if (ACPI_SUCCESS(status))
439 acpi_evaluate_hotplug_ost(handle, type, 456 return;
440 ACPI_OST_SC_NON_SPECIFIC_FAILURE,
441 NULL);
442}
443
444void __acpi_bus_hot_remove_device(struct acpi_device *device, u32 ost_src)
445{
446 acpi_handle handle = device->handle;
447 int error;
448
449 lock_device_hotplug();
450 mutex_lock(&acpi_scan_lock);
451
452 error = acpi_scan_hot_remove(device);
453 if (error && handle)
454 acpi_evaluate_hotplug_ost(handle, ost_src,
455 ACPI_OST_SC_NON_SPECIFIC_FAILURE,
456 NULL);
457
458 mutex_unlock(&acpi_scan_lock);
459 unlock_device_hotplug();
460}
461 457
462/** 458 err_out:
463 * acpi_bus_hot_remove_device: Hot-remove a device and its children. 459 acpi_evaluate_hotplug_ost(handle, type,
464 * @context: Address of the ACPI device object to hot-remove. 460 ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
465 */
466void acpi_bus_hot_remove_device(void *context)
467{
468 __acpi_bus_hot_remove_device(context, ACPI_NOTIFY_EJECT_REQUEST);
469} 461}
470 462
471static ssize_t real_power_state_show(struct device *dev, 463static ssize_t real_power_state_show(struct device *dev,
@@ -496,7 +488,7 @@ static DEVICE_ATTR(power_state, 0444, power_state_show, NULL);
496 488
497static void acpi_eject_store_work(void *context) 489static void acpi_eject_store_work(void *context)
498{ 490{
499 __acpi_bus_hot_remove_device(context, ACPI_OST_EC_OSPM_EJECT); 491 acpi_bus_device_eject(context, ACPI_OST_EC_OSPM_EJECT);
500} 492}
501 493
502static ssize_t 494static ssize_t