diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-11-06 19:41:39 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-11-06 19:41:39 -0500 |
commit | 5add99cfef416487d32b4b7075fe1a409f3a5e82 (patch) | |
tree | 29553178aac29acea786fa36576c8b6e0f536623 /drivers/acpi | |
parent | 2441191a19039002b2c454a261fb45986df15184 (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.c | 20 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 46 |
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) | |||
593 | static void handle_root_bridge_removal(struct acpi_device *device) | 593 | static 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 | ||
619 | static void _handle_hotplug_event_root(struct work_struct *work) | 603 | static 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 | /** | 444 | void __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 | */ | ||
452 | void 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 | */ | ||
466 | void acpi_bus_hot_remove_device(void *context) | ||
467 | { | ||
468 | __acpi_bus_hot_remove_device(context, ACPI_NOTIFY_EJECT_REQUEST); | ||
471 | } | 469 | } |
472 | EXPORT_SYMBOL(acpi_bus_hot_remove_device); | 470 | EXPORT_SYMBOL(acpi_bus_hot_remove_device); |
473 | 471 | ||
@@ -497,15 +495,18 @@ static ssize_t power_state_show(struct device *dev, | |||
497 | 495 | ||
498 | static DEVICE_ATTR(power_state, 0444, power_state_show, NULL); | 496 | static DEVICE_ATTR(power_state, 0444, power_state_show, NULL); |
499 | 497 | ||
498 | static void acpi_eject_store_work(void *context) | ||
499 | { | ||
500 | __acpi_bus_hot_remove_device(context, ACPI_OST_EC_OSPM_EJECT); | ||
501 | } | ||
502 | |||
500 | static ssize_t | 503 | static ssize_t |
501 | acpi_eject_store(struct device *d, struct device_attribute *attr, | 504 | acpi_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 | ||
545 | static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); | 535 | static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); |