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 /drivers/acpi/pci_root.c | |
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>
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r-- | drivers/acpi/pci_root.c | 24 |
1 files changed, 10 insertions, 14 deletions
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, |