diff options
| author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-11-06 19:42:09 -0500 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-11-06 19:42:09 -0500 |
| commit | 43d388832bd3e413e9b5e6f3caef4b0844b901af (patch) | |
| tree | 0a95011781ad5a4286761fd17ed2f5c285b5e02a | |
| parent | a3b1b1ef78cd2ffb5d3a223465064dee05929dc3 (diff) | |
ACPI / hotplug: Carry out PCI root eject directly
Since _handle_hotplug_event_root() is run from the ACPI hotplug
workqueue, it doesn't need to queue up a work item to eject a PCI
host bridge on the same workqueue. Instead, it can just carry out
the eject by calling acpi_bus_device_eject() directly, so make that
happen.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
| -rw-r--r-- | drivers/acpi/internal.h | 2 | ||||
| -rw-r--r-- | drivers/acpi/pci_root.c | 24 | ||||
| -rw-r--r-- | drivers/acpi/scan.c | 4 |
3 files changed, 13 insertions, 17 deletions
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 6c79ae69d344..80cd1a10c4c3 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
| @@ -87,7 +87,7 @@ void acpi_device_add_finalize(struct acpi_device *device); | |||
| 87 | void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); | 87 | void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); |
| 88 | int acpi_bind_one(struct device *dev, acpi_handle handle); | 88 | int acpi_bind_one(struct device *dev, acpi_handle handle); |
| 89 | int acpi_unbind_one(struct device *dev); | 89 | int acpi_unbind_one(struct device *dev); |
| 90 | void acpi_bus_hot_remove_device(void *context); | 90 | void acpi_bus_device_eject(struct acpi_device *device, u32 ost_src); |
| 91 | 91 | ||
| 92 | /* -------------------------------------------------------------------------- | 92 | /* -------------------------------------------------------------------------- |
| 93 | Power Resource | 93 | Power Resource |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index add408b07c93..d77f0bf7eda0 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -592,16 +592,6 @@ static void handle_root_bridge_insertion(acpi_handle handle) | |||
| 592 | acpi_handle_err(handle, "cannot add bridge to acpi list\n"); | 592 | acpi_handle_err(handle, "cannot add bridge to acpi list\n"); |
| 593 | } | 593 | } |
| 594 | 594 | ||
| 595 | static void handle_root_bridge_removal(struct acpi_device *device) | ||
| 596 | { | ||
| 597 | acpi_status status; | ||
| 598 | |||
| 599 | get_device(&device->dev); | ||
| 600 | status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, device); | ||
| 601 | if (ACPI_FAILURE(status)) | ||
| 602 | put_device(&device->dev); | ||
| 603 | } | ||
| 604 | |||
| 605 | static void _handle_hotplug_event_root(struct work_struct *work) | 595 | static void _handle_hotplug_event_root(struct work_struct *work) |
| 606 | { | 596 | { |
| 607 | struct acpi_pci_root *root; | 597 | struct acpi_pci_root *root; |
| @@ -612,6 +602,7 @@ static void _handle_hotplug_event_root(struct work_struct *work) | |||
| 612 | hp_work = container_of(work, struct acpi_hp_work, work); | 602 | hp_work = container_of(work, struct acpi_hp_work, work); |
| 613 | handle = hp_work->handle; | 603 | handle = hp_work->handle; |
| 614 | type = hp_work->type; | 604 | type = hp_work->type; |
| 605 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | ||
| 615 | 606 | ||
| 616 | acpi_scan_lock_acquire(); | 607 | acpi_scan_lock_acquire(); |
| 617 | 608 | ||
| @@ -641,9 +632,15 @@ static void _handle_hotplug_event_root(struct work_struct *work) | |||
| 641 | /* request device eject */ | 632 | /* request device eject */ |
| 642 | acpi_handle_printk(KERN_DEBUG, handle, | 633 | acpi_handle_printk(KERN_DEBUG, handle, |
| 643 | "Device eject notify on %s\n", __func__); | 634 | "Device eject notify on %s\n", __func__); |
| 644 | if (root) | 635 | if (!root) |
| 645 | handle_root_bridge_removal(root->device); | 636 | break; |
| 646 | break; | 637 | |
| 638 | get_device(&root->device->dev); | ||
| 639 | |||
| 640 | acpi_scan_lock_release(); | ||
| 641 | |||
| 642 | acpi_bus_device_eject(root->device, ACPI_NOTIFY_EJECT_REQUEST); | ||
| 643 | return; | ||
| 647 | default: | 644 | default: |
| 648 | acpi_handle_warn(handle, | 645 | acpi_handle_warn(handle, |
| 649 | "notify_handler: unknown event type 0x%x\n", | 646 | "notify_handler: unknown event type 0x%x\n", |
| @@ -652,7 +649,6 @@ static void _handle_hotplug_event_root(struct work_struct *work) | |||
| 652 | } | 649 | } |
| 653 | 650 | ||
| 654 | acpi_scan_lock_release(); | 651 | acpi_scan_lock_release(); |
| 655 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | ||
| 656 | } | 652 | } |
| 657 | 653 | ||
| 658 | static void handle_hotplug_event_root(acpi_handle handle, u32 type, | 654 | static void handle_hotplug_event_root(acpi_handle handle, u32 type, |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 4a0a591feed3..c7317fe213bf 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -285,7 +285,7 @@ static int acpi_scan_hot_remove(struct acpi_device *device) | |||
| 285 | return 0; | 285 | return 0; |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | static void acpi_bus_device_eject(struct acpi_device *device, u32 ost_src) | 288 | void acpi_bus_device_eject(struct acpi_device *device, u32 ost_src) |
| 289 | { | 289 | { |
| 290 | acpi_handle handle = device->handle; | 290 | acpi_handle handle = device->handle; |
| 291 | struct acpi_scan_handler *handler; | 291 | struct acpi_scan_handler *handler; |
| @@ -409,7 +409,7 @@ static void acpi_hotplug_unsupported(acpi_handle handle, u32 type) | |||
| 409 | * acpi_bus_hot_remove_device: Hot-remove a device and its children. | 409 | * acpi_bus_hot_remove_device: Hot-remove a device and its children. |
| 410 | * @context: Address of the ACPI device object to hot-remove. | 410 | * @context: Address of the ACPI device object to hot-remove. |
| 411 | */ | 411 | */ |
| 412 | void acpi_bus_hot_remove_device(void *context) | 412 | static void acpi_bus_hot_remove_device(void *context) |
| 413 | { | 413 | { |
| 414 | acpi_bus_device_eject(context, ACPI_NOTIFY_EJECT_REQUEST); | 414 | acpi_bus_device_eject(context, ACPI_NOTIFY_EJECT_REQUEST); |
| 415 | } | 415 | } |
