ACPI / hotplug: Carry out PCI root eject directly
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 7 Nov 2013 00:42:09 +0000 (01:42 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 7 Nov 2013 00:42:09 +0000 (01:42 +0100)
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>
drivers/acpi/internal.h
drivers/acpi/pci_root.c
drivers/acpi/scan.c

index 6c79ae69d3449789b9d073d2f8fe6059c93e97ae..80cd1a10c4c3b22263b6d59ab2376a9996512efd 100644 (file)
@@ -87,7 +87,7 @@ void acpi_device_add_finalize(struct acpi_device *device);
 void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
 int acpi_bind_one(struct device *dev, acpi_handle handle);
 int acpi_unbind_one(struct device *dev);
-void acpi_bus_hot_remove_device(void *context);
+void acpi_bus_device_eject(struct acpi_device *device, u32 ost_src);
 
 /* --------------------------------------------------------------------------
                                   Power Resource
index add408b07c934c0c68011f459f6ab7e3a68274b5..d77f0bf7eda09790b42df7205c3de076e0f7e65a 100644 (file)
@@ -592,16 +592,6 @@ static void handle_root_bridge_insertion(acpi_handle handle)
                acpi_handle_err(handle, "cannot add bridge to acpi list\n");
 }
 
-static void handle_root_bridge_removal(struct acpi_device *device)
-{
-       acpi_status status;
-
-       get_device(&device->dev);
-       status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, device);
-       if (ACPI_FAILURE(status))
-               put_device(&device->dev);
-}
-
 static void _handle_hotplug_event_root(struct work_struct *work)
 {
        struct acpi_pci_root *root;
@@ -612,6 +602,7 @@ static void _handle_hotplug_event_root(struct work_struct *work)
        hp_work = container_of(work, struct acpi_hp_work, work);
        handle = hp_work->handle;
        type = hp_work->type;
+       kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
 
        acpi_scan_lock_acquire();
 
@@ -641,9 +632,15 @@ static void _handle_hotplug_event_root(struct work_struct *work)
                /* request device eject */
                acpi_handle_printk(KERN_DEBUG, handle,
                                   "Device eject notify on %s\n", __func__);
-               if (root)
-                       handle_root_bridge_removal(root->device);
-               break;
+               if (!root)
+                       break;
+
+               get_device(&root->device->dev);
+
+               acpi_scan_lock_release();
+
+               acpi_bus_device_eject(root->device, ACPI_NOTIFY_EJECT_REQUEST);
+               return;
        default:
                acpi_handle_warn(handle,
                                 "notify_handler: unknown event type 0x%x\n",
@@ -652,7 +649,6 @@ static void _handle_hotplug_event_root(struct work_struct *work)
        }
 
        acpi_scan_lock_release();
-       kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
 }
 
 static void handle_hotplug_event_root(acpi_handle handle, u32 type,
index 4a0a591feed32fe42361153dabd06e9fd0de7fde..c7317fe213bfc34e814f226cf60c5a948b1ec35b 100644 (file)
@@ -285,7 +285,7 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
        return 0;
 }
 
-static void acpi_bus_device_eject(struct acpi_device *device, u32 ost_src)
+void acpi_bus_device_eject(struct acpi_device *device, u32 ost_src)
 {
        acpi_handle handle = device->handle;
        struct acpi_scan_handler *handler;
@@ -409,7 +409,7 @@ static void acpi_hotplug_unsupported(acpi_handle handle, u32 type)
  * acpi_bus_hot_remove_device: Hot-remove a device and its children.
  * @context: Address of the ACPI device object to hot-remove.
  */
-void acpi_bus_hot_remove_device(void *context)
+static void acpi_bus_hot_remove_device(void *context)
 {
        acpi_bus_device_eject(context, ACPI_NOTIFY_EJECT_REQUEST);
 }