aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-11-06 19:41:39 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-11-06 19:41:39 -0500
commit5add99cfef416487d32b4b7075fe1a409f3a5e82 (patch)
tree29553178aac29acea786fa36576c8b6e0f536623 /drivers/acpi
parent2441191a19039002b2c454a261fb45986df15184 (diff)
ACPI / hotplug: Simplify device ejection routines
Simplify handle_root_bridge_removal() and acpi_eject_store() by getting rid of struct acpi_eject_event and passing device objects directly to async routines executed via acpi_os_hotplug_execute(). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Toshi Kani <toshi.kani@hp.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/pci_root.c20
-rw-r--r--drivers/acpi/scan.c46
2 files changed, 20 insertions, 46 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index d7e53ea53d6c..2c03aaee1006 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -593,27 +593,11 @@ static void handle_root_bridge_insertion(acpi_handle handle)
593static void handle_root_bridge_removal(struct acpi_device *device) 593static void handle_root_bridge_removal(struct acpi_device *device)
594{ 594{
595 acpi_status status; 595 acpi_status status;
596 struct acpi_eject_event *ej_event;
597
598 ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
599 if (!ej_event) {
600 /* Inform firmware the hot-remove operation has error */
601 (void) acpi_evaluate_hotplug_ost(device->handle,
602 ACPI_NOTIFY_EJECT_REQUEST,
603 ACPI_OST_SC_NON_SPECIFIC_FAILURE,
604 NULL);
605 return;
606 }
607
608 ej_event->device = device;
609 ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
610 596
611 get_device(&device->dev); 597 get_device(&device->dev);
612 status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); 598 status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, device);
613 if (ACPI_FAILURE(status)) { 599 if (ACPI_FAILURE(status))
614 put_device(&device->dev); 600 put_device(&device->dev);
615 kfree(ej_event);
616 }
617} 601}
618 602
619static void _handle_hotplug_event_root(struct work_struct *work) 603static void _handle_hotplug_event_root(struct work_struct *work)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 9bdcc187bf4b..cc19d623a18f 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -441,18 +441,8 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data)
441 NULL); 441 NULL);
442} 442}
443 443
444/** 444void __acpi_bus_hot_remove_device(struct acpi_device *device, u32 ost_src)
445 * acpi_bus_hot_remove_device: hot-remove a device and its children
446 * @context: struct acpi_eject_event pointer (freed in this func)
447 *
448 * Hot-remove a device and its children. This function frees up the
449 * memory space passed by arg context, so that the caller may call
450 * this function asynchronously through acpi_os_hotplug_execute().
451 */
452void acpi_bus_hot_remove_device(void *context)
453{ 445{
454 struct acpi_eject_event *ej_event = context;
455 struct acpi_device *device = ej_event->device;
456 acpi_handle handle = device->handle; 446 acpi_handle handle = device->handle;
457 int error; 447 int error;
458 448
@@ -461,13 +451,21 @@ void acpi_bus_hot_remove_device(void *context)
461 451
462 error = acpi_scan_hot_remove(device); 452 error = acpi_scan_hot_remove(device);
463 if (error && handle) 453 if (error && handle)
464 acpi_evaluate_hotplug_ost(handle, ej_event->event, 454 acpi_evaluate_hotplug_ost(handle, ost_src,
465 ACPI_OST_SC_NON_SPECIFIC_FAILURE, 455 ACPI_OST_SC_NON_SPECIFIC_FAILURE,
466 NULL); 456 NULL);
467 457
468 mutex_unlock(&acpi_scan_lock); 458 mutex_unlock(&acpi_scan_lock);
469 unlock_device_hotplug(); 459 unlock_device_hotplug();
470 kfree(context); 460}
461
462/**
463 * acpi_bus_hot_remove_device: Hot-remove a device and its children.
464 * @context: Address of the ACPI device object to hot-remove.
465 */
466void acpi_bus_hot_remove_device(void *context)
467{
468 __acpi_bus_hot_remove_device(context, ACPI_NOTIFY_EJECT_REQUEST);
471} 469}
472EXPORT_SYMBOL(acpi_bus_hot_remove_device); 470EXPORT_SYMBOL(acpi_bus_hot_remove_device);
473 471
@@ -497,15 +495,18 @@ static ssize_t power_state_show(struct device *dev,
497 495
498static DEVICE_ATTR(power_state, 0444, power_state_show, NULL); 496static DEVICE_ATTR(power_state, 0444, power_state_show, NULL);
499 497
498static void acpi_eject_store_work(void *context)
499{
500 __acpi_bus_hot_remove_device(context, ACPI_OST_EC_OSPM_EJECT);
501}
502
500static ssize_t 503static ssize_t
501acpi_eject_store(struct device *d, struct device_attribute *attr, 504acpi_eject_store(struct device *d, struct device_attribute *attr,
502 const char *buf, size_t count) 505 const char *buf, size_t count)
503{ 506{
504 struct acpi_device *acpi_device = to_acpi_device(d); 507 struct acpi_device *acpi_device = to_acpi_device(d);
505 struct acpi_eject_event *ej_event;
506 acpi_object_type not_used; 508 acpi_object_type not_used;
507 acpi_status status; 509 acpi_status status;
508 int ret;
509 510
510 if (!count || buf[0] != '1') 511 if (!count || buf[0] != '1')
511 return -EINVAL; 512 return -EINVAL;
@@ -518,28 +519,17 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
518 if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) 519 if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable)
519 return -ENODEV; 520 return -ENODEV;
520 521
521 ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
522 if (!ej_event) {
523 ret = -ENOMEM;
524 goto err_out;
525 }
526 acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, 522 acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
527 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); 523 ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
528 ej_event->device = acpi_device;
529 ej_event->event = ACPI_OST_EC_OSPM_EJECT;
530 get_device(&acpi_device->dev); 524 get_device(&acpi_device->dev);
531 status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); 525 status = acpi_os_hotplug_execute(acpi_eject_store_work, acpi_device);
532 if (ACPI_SUCCESS(status)) 526 if (ACPI_SUCCESS(status))
533 return count; 527 return count;
534 528
535 put_device(&acpi_device->dev); 529 put_device(&acpi_device->dev);
536 kfree(ej_event);
537 ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN;
538
539 err_out:
540 acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, 530 acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT,
541 ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); 531 ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL);
542 return ret; 532 return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN;
543} 533}
544 534
545static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); 535static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store);