aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShaohua Li <shaohua.li@intel.com>2008-08-27 22:06:16 -0400
committerLen Brown <len.brown@intel.com>2008-09-23 23:23:00 -0400
commit1253f7aabfebc51446dbec5c8895c5c8846dfe06 (patch)
treedd365b884581931ab01473307d519d277cbffaa4
parentf730ae1838635a02aa60834762c61566911d004c (diff)
dock: introduce .uevent for devices in dock, eg libata
dock's uevent reported itself, not ata. It might be difficult to find an ata device just according to a dock. This patch introduces docking ops for each device in a dock. when docking, dock driver can send device specific uevent. This should help dock station too (not just bay) Signed-off-by: Shaohua Li <shaohua.li@intel.com> Acked-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/acpi/dock.c22
-rw-r--r--drivers/ata/libata-acpi.c44
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c6
-rw-r--r--include/acpi/acpi_drivers.h9
4 files changed, 68 insertions, 13 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index f19f643fb362..ac7dfefcb50b 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -75,7 +75,7 @@ struct dock_dependent_device {
75 struct list_head list; 75 struct list_head list;
76 struct list_head hotplug_list; 76 struct list_head hotplug_list;
77 acpi_handle handle; 77 acpi_handle handle;
78 acpi_notify_handler handler; 78 struct acpi_dock_ops *ops;
79 void *context; 79 void *context;
80}; 80};
81 81
@@ -385,8 +385,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
385 * First call driver specific hotplug functions 385 * First call driver specific hotplug functions
386 */ 386 */
387 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) { 387 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) {
388 if (dd->handler) 388 if (dd->ops && dd->ops->handler)
389 dd->handler(dd->handle, event, dd->context); 389 dd->ops->handler(dd->handle, event, dd->context);
390 } 390 }
391 391
392 /* 392 /*
@@ -409,6 +409,7 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
409 struct device *dev = &ds->dock_device->dev; 409 struct device *dev = &ds->dock_device->dev;
410 char event_string[13]; 410 char event_string[13];
411 char *envp[] = { event_string, NULL }; 411 char *envp[] = { event_string, NULL };
412 struct dock_dependent_device *dd;
412 413
413 if (num == UNDOCK_EVENT) 414 if (num == UNDOCK_EVENT)
414 sprintf(event_string, "EVENT=undock"); 415 sprintf(event_string, "EVENT=undock");
@@ -419,7 +420,14 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
419 * Indicate that the status of the dock station has 420 * Indicate that the status of the dock station has
420 * changed. 421 * changed.
421 */ 422 */
422 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 423 if (num == DOCK_EVENT)
424 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
425
426 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
427 if (dd->ops && dd->ops->uevent)
428 dd->ops->uevent(dd->handle, event, dd->context);
429 if (num != DOCK_EVENT)
430 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
423} 431}
424 432
425/** 433/**
@@ -588,7 +596,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
588/** 596/**
589 * register_hotplug_dock_device - register a hotplug function 597 * register_hotplug_dock_device - register a hotplug function
590 * @handle: the handle of the device 598 * @handle: the handle of the device
591 * @handler: the acpi_notifier_handler to call after docking 599 * @ops: handlers to call after docking
592 * @context: device specific data 600 * @context: device specific data
593 * 601 *
594 * If a driver would like to perform a hotplug operation after a dock 602 * If a driver would like to perform a hotplug operation after a dock
@@ -596,7 +604,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
596 * the dock driver after _DCK is executed. 604 * the dock driver after _DCK is executed.
597 */ 605 */
598int 606int
599register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler, 607register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
600 void *context) 608 void *context)
601{ 609{
602 struct dock_dependent_device *dd; 610 struct dock_dependent_device *dd;
@@ -612,7 +620,7 @@ register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler,
612 list_for_each_entry(dock_station, &dock_stations, sibiling) { 620 list_for_each_entry(dock_station, &dock_stations, sibiling) {
613 dd = find_dock_dependent_device(dock_station, handle); 621 dd = find_dock_dependent_device(dock_station, handle);
614 if (dd) { 622 if (dd) {
615 dd->handler = handler; 623 dd->ops = ops;
616 dd->context = context; 624 dd->context = context;
617 dock_add_hotplug_device(dock_station, dd); 625 dock_add_hotplug_device(dock_station, dd);
618 return 0; 626 return 0;
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 97727be7e158..c012307d0ba6 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -209,6 +209,46 @@ static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data)
209 ata_acpi_handle_hotplug(ap, NULL, event); 209 ata_acpi_handle_hotplug(ap, NULL, event);
210} 210}
211 211
212static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
213 u32 event)
214{
215 struct kobject *kobj = NULL;
216 char event_string[20];
217 char *envp[] = { event_string, NULL };
218
219 if (dev) {
220 if (dev->sdev)
221 kobj = &dev->sdev->sdev_gendev.kobj;
222 } else
223 kobj = &ap->dev->kobj;
224
225 if (kobj) {
226 snprintf(event_string, 20, "BAY_EVENT=%d", event);
227 kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
228 }
229}
230
231static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data)
232{
233 ata_acpi_uevent(data, NULL, event);
234}
235
236static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data)
237{
238 struct ata_device *dev = data;
239 ata_acpi_uevent(dev->link->ap, dev, event);
240}
241
242static struct acpi_dock_ops ata_acpi_dev_dock_ops = {
243 .handler = ata_acpi_dev_notify_dock,
244 .uevent = ata_acpi_dev_uevent,
245};
246
247static struct acpi_dock_ops ata_acpi_ap_dock_ops = {
248 .handler = ata_acpi_ap_notify_dock,
249 .uevent = ata_acpi_ap_uevent,
250};
251
212/** 252/**
213 * ata_acpi_associate - associate ATA host with ACPI objects 253 * ata_acpi_associate - associate ATA host with ACPI objects
214 * @host: target ATA host 254 * @host: target ATA host
@@ -244,7 +284,7 @@ void ata_acpi_associate(struct ata_host *host)
244 if (ap->acpi_handle) { 284 if (ap->acpi_handle) {
245 /* we might be on a docking station */ 285 /* we might be on a docking station */
246 register_hotplug_dock_device(ap->acpi_handle, 286 register_hotplug_dock_device(ap->acpi_handle,
247 ata_acpi_ap_notify_dock, ap); 287 &ata_acpi_ap_dock_ops, ap);
248 } 288 }
249 289
250 for (j = 0; j < ata_link_max_devices(&ap->link); j++) { 290 for (j = 0; j < ata_link_max_devices(&ap->link); j++) {
@@ -253,7 +293,7 @@ void ata_acpi_associate(struct ata_host *host)
253 if (dev->acpi_handle) { 293 if (dev->acpi_handle) {
254 /* we might be on a docking station */ 294 /* we might be on a docking station */
255 register_hotplug_dock_device(dev->acpi_handle, 295 register_hotplug_dock_device(dev->acpi_handle,
256 ata_acpi_dev_notify_dock, dev); 296 &ata_acpi_dev_dock_ops, dev);
257 } 297 }
258 } 298 }
259 } 299 }
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index a3e4705dd8f0..db54c5ef2aa5 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -169,7 +169,9 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
169} 169}
170 170
171 171
172 172static struct acpi_dock_ops acpiphp_dock_ops = {
173 .handler = handle_hotplug_event_func,
174};
173 175
174/* callback routine to register each ACPI PCI slot object */ 176/* callback routine to register each ACPI PCI slot object */
175static acpi_status 177static acpi_status
@@ -285,7 +287,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
285 */ 287 */
286 newfunc->flags &= ~FUNC_HAS_EJ0; 288 newfunc->flags &= ~FUNC_HAS_EJ0;
287 if (register_hotplug_dock_device(handle, 289 if (register_hotplug_dock_device(handle,
288 handle_hotplug_event_func, newfunc)) 290 &acpiphp_dock_ops, newfunc))
289 dbg("failed to register dock device\n"); 291 dbg("failed to register dock device\n");
290 292
291 /* we need to be notified when dock events happen 293 /* we need to be notified when dock events happen
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index e5f38e5ce86f..4f5042a0ef80 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -115,12 +115,17 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
115/*-------------------------------------------------------------------------- 115/*--------------------------------------------------------------------------
116 Dock Station 116 Dock Station
117 -------------------------------------------------------------------------- */ 117 -------------------------------------------------------------------------- */
118struct acpi_dock_ops {
119 acpi_notify_handler handler;
120 acpi_notify_handler uevent;
121};
122
118#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE) 123#if defined(CONFIG_ACPI_DOCK) || defined(CONFIG_ACPI_DOCK_MODULE)
119extern int is_dock_device(acpi_handle handle); 124extern int is_dock_device(acpi_handle handle);
120extern int register_dock_notifier(struct notifier_block *nb); 125extern int register_dock_notifier(struct notifier_block *nb);
121extern void unregister_dock_notifier(struct notifier_block *nb); 126extern void unregister_dock_notifier(struct notifier_block *nb);
122extern int register_hotplug_dock_device(acpi_handle handle, 127extern int register_hotplug_dock_device(acpi_handle handle,
123 acpi_notify_handler handler, 128 struct acpi_dock_ops *ops,
124 void *context); 129 void *context);
125extern void unregister_hotplug_dock_device(acpi_handle handle); 130extern void unregister_hotplug_dock_device(acpi_handle handle);
126#else 131#else
@@ -136,7 +141,7 @@ static inline void unregister_dock_notifier(struct notifier_block *nb)
136{ 141{
137} 142}
138static inline int register_hotplug_dock_device(acpi_handle handle, 143static inline int register_hotplug_dock_device(acpi_handle handle,
139 acpi_notify_handler handler, 144 struct acpi_dock_ops *ops,
140 void *context) 145 void *context)
141{ 146{
142 return -ENODEV; 147 return -ENODEV;