[PATCH]

From: Jiang Liu
Date: Tue Jun 18 2013 - 10:22:23 EST


---
drivers/acpi/dock.c | 108 +++++++++++++++----------------------
drivers/pci/hotplug/acpiphp_glue.c | 32 ++++++-----
2 files changed, 62 insertions(+), 78 deletions(-)

diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 469ef56..fd8830a 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -58,10 +58,7 @@ struct dock_station {
unsigned long last_dock_time;
u32 flags;
spinlock_t dd_lock;
- struct mutex hp_lock;
struct list_head dependent_devices;
- struct list_head hotplug_devices;
-
struct list_head sibling;
struct platform_device *dock_device;
};
@@ -70,7 +67,6 @@ static int dock_station_count;

struct dock_dependent_device {
struct list_head list;
- struct list_head hotplug_list;
acpi_handle handle;
const struct acpi_dock_ops *ops;
void *context;
@@ -105,7 +101,6 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)

dd->handle = handle;
INIT_LIST_HEAD(&dd->list);
- INIT_LIST_HEAD(&dd->hotplug_list);

spin_lock(&ds->dd_lock);
list_add_tail(&dd->list, &ds->dependent_devices);
@@ -115,38 +110,6 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
}

/**
- * dock_add_hotplug_device - associate a hotplug handler with the dock station
- * @ds: The dock station
- * @dd: The dependent device struct
- *
- * Add the dependent device to the dock's hotplug device list
- */
-static void
-dock_add_hotplug_device(struct dock_station *ds,
- struct dock_dependent_device *dd)
-{
- mutex_lock(&ds->hp_lock);
- list_add_tail(&dd->hotplug_list, &ds->hotplug_devices);
- mutex_unlock(&ds->hp_lock);
-}
-
-/**
- * dock_del_hotplug_device - remove a hotplug handler from the dock station
- * @ds: The dock station
- * @dd: the dependent device struct
- *
- * Delete the dependent device from the dock's hotplug device list
- */
-static void
-dock_del_hotplug_device(struct dock_station *ds,
- struct dock_dependent_device *dd)
-{
- mutex_lock(&ds->hp_lock);
- list_del(&dd->hotplug_list);
- mutex_unlock(&ds->hp_lock);
-}
-
-/**
* find_dock_dependent_device - get a device dependent on this dock
* @ds: the dock station
* @handle: the acpi_handle of the device we want
@@ -349,12 +312,10 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
{
struct dock_dependent_device *dd;

- mutex_lock(&ds->hp_lock);
-
/*
* First call driver specific hotplug functions
*/
- list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
+ list_for_each_entry(dd, &ds->dependent_devices, list)
if (dd->ops && dd->ops->handler)
dd->ops->handler(dd->handle, event, dd->context);

@@ -370,7 +331,6 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
else
dock_create_acpi_device(dd->handle);
}
- mutex_unlock(&ds->hp_lock);
}

static void dock_event(struct dock_station *ds, u32 event, int num)
@@ -392,7 +352,7 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
if (num == DOCK_EVENT)
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);

- list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
+ list_for_each_entry(dd, &ds->dependent_devices, list)
if (dd->ops && dd->ops->uevent)
dd->ops->uevent(dd->handle, event, dd->context);

@@ -559,19 +519,9 @@ void unregister_dock_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(unregister_dock_notifier);

-/**
- * register_hotplug_dock_device - register a hotplug function
- * @handle: the handle of the device
- * @ops: handlers to call after docking
- * @context: device specific data
- *
- * If a driver would like to perform a hotplug operation after a dock
- * event, they can register an acpi_notifiy_handler to be called by
- * the dock driver after _DCK is executed.
- */
-int
-register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops,
- void *context)
+/* must be called with ACPI scan lock held */
+int __register_hotplug_dock_device(acpi_handle handle,
+ const struct acpi_dock_ops *ops, void *context)
{
struct dock_dependent_device *dd;
struct dock_station *dock_station;
@@ -594,20 +544,39 @@ register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops
if (dd) {
dd->ops = ops;
dd->context = context;
- dock_add_hotplug_device(dock_station, dd);
ret = 0;
}
}

return ret;
}
-EXPORT_SYMBOL_GPL(register_hotplug_dock_device);

/**
- * unregister_hotplug_dock_device - remove yourself from the hotplug list
- * @handle: the acpi handle of the device
+ * register_hotplug_dock_device - register a hotplug function
+ * @handle: the handle of the device
+ * @ops: handlers to call after docking
+ * @context: device specific data
+ *
+ * If a driver would like to perform a hotplug operation after a dock
+ * event, they can register an acpi_notifiy_handler to be called by
+ * the dock driver after _DCK is executed.
*/
-void unregister_hotplug_dock_device(acpi_handle handle)
+int
+register_hotplug_dock_device(acpi_handle handle,
+ const struct acpi_dock_ops *ops, void *context)
+{
+ int ret;
+
+ acpi_scan_lock_acquire();
+ ret = __register_hotplug_dock_device(handle, ops, context);
+ acpi_scan_lock_release();
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
+
+/* must be called with ACPI scan lock held */
+void __unregister_hotplug_dock_device(acpi_handle handle)
{
struct dock_dependent_device *dd;
struct dock_station *dock_station;
@@ -617,10 +586,23 @@ void unregister_hotplug_dock_device(acpi_handle handle)

list_for_each_entry(dock_station, &dock_stations, sibling) {
dd = find_dock_dependent_device(dock_station, handle);
- if (dd)
- dock_del_hotplug_device(dock_station, dd);
+ if (dd) {
+ dd->ops = NULL;
+ dd->context = NULL;
+ }
}
}
+
+/**
+ * unregister_hotplug_dock_device - remove yourself from the hotplug list
+ * @handle: the acpi handle of the device
+ */
+void unregister_hotplug_dock_device(acpi_handle handle)
+{
+ acpi_scan_lock_acquire();
+ __unregister_hotplug_dock_device(handle);
+ acpi_scan_lock_release();
+}
EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);

/**
@@ -945,10 +927,8 @@ static int __init dock_add(acpi_handle handle)
dock_station->dock_device = dd;
dock_station->last_dock_time = jiffies - HZ;

- mutex_init(&dock_station->hp_lock);
spin_lock_init(&dock_station->dd_lock);
INIT_LIST_HEAD(&dock_station->sibling);
- INIT_LIST_HEAD(&dock_station->hotplug_devices);
ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
INIT_LIST_HEAD(&dock_station->dependent_devices);

diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 716aa93..699b8ca 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -61,6 +61,8 @@ static DEFINE_MUTEX(bridge_mutex);
static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
static void acpiphp_sanitize_bus(struct pci_bus *bus);
static void acpiphp_set_hpp_values(struct pci_bus *bus);
+static void _handle_hotplug_event_func(acpi_handle handle, u32 type,
+ void *context);
static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context);
static void free_bridge(struct kref *kref);

@@ -147,7 +149,7 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,


static const struct acpi_dock_ops acpiphp_dock_ops = {
- .handler = handle_hotplug_event_func,
+ .handler = _handle_hotplug_event_func,
};

/* Check whether the PCI device is managed by native PCIe hotplug driver */
@@ -1065,22 +1067,13 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type,
alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge);
}

-static void _handle_hotplug_event_func(struct work_struct *work)
+static void _handle_hotplug_event_func(acpi_handle handle, u32 type,
+ void *context)
{
- struct acpiphp_func *func;
+ struct acpiphp_func *func = context;
char objname[64];
struct acpi_buffer buffer = { .length = sizeof(objname),
.pointer = objname };
- struct acpi_hp_work *hp_work;
- acpi_handle handle;
- u32 type;
-
- hp_work = container_of(work, struct acpi_hp_work, work);
- handle = hp_work->handle;
- type = hp_work->type;
- func = (struct acpiphp_func *)hp_work->context;
-
- acpi_scan_lock_acquire();

acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);

@@ -1113,7 +1106,18 @@ static void _handle_hotplug_event_func(struct work_struct *work)
warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
break;
}
+}
+
+static void _handle_hotplug_event_cb(struct work_struct *work)
+{
+ struct acpiphp_func *func;
+ struct acpi_hp_work *hp_work;

+ hp_work = container_of(work, struct acpi_hp_work, work);
+ func = (struct acpiphp_func *)hp_work->context;
+ acpi_scan_lock_acquire();
+ _handle_hotplug_event_func(hp_work->handle, hp_work->type,
+ hp_work->context);
acpi_scan_lock_release();
kfree(hp_work); /* allocated in handle_hotplug_event_func */
put_bridge(func->slot->bridge);
@@ -1141,7 +1145,7 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type,
* don't deadlock on hotplug actions.
*/
get_bridge(func->slot->bridge);
- alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func);
+ alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_cb);
}

/*
--
1.8.1.2


--------------000700010704030103000407--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/