diff options
author | Shaohua Li <shaohua.li@intel.com> | 2008-08-27 22:06:16 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-09-23 23:23:00 -0400 |
commit | 1253f7aabfebc51446dbec5c8895c5c8846dfe06 (patch) | |
tree | dd365b884581931ab01473307d519d277cbffaa4 | |
parent | f730ae1838635a02aa60834762c61566911d004c (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.c | 22 | ||||
-rw-r--r-- | drivers/ata/libata-acpi.c | 44 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 6 | ||||
-rw-r--r-- | include/acpi/acpi_drivers.h | 9 |
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 | */ |
598 | int | 606 | int |
599 | register_hotplug_dock_device(acpi_handle handle, acpi_notify_handler handler, | 607 | register_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 | ||
212 | static 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 | |||
231 | static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data) | ||
232 | { | ||
233 | ata_acpi_uevent(data, NULL, event); | ||
234 | } | ||
235 | |||
236 | static 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 | |||
242 | static struct acpi_dock_ops ata_acpi_dev_dock_ops = { | ||
243 | .handler = ata_acpi_dev_notify_dock, | ||
244 | .uevent = ata_acpi_dev_uevent, | ||
245 | }; | ||
246 | |||
247 | static 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 | 172 | static 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 */ |
175 | static acpi_status | 177 | static 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 | -------------------------------------------------------------------------- */ |
118 | struct 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) |
119 | extern int is_dock_device(acpi_handle handle); | 124 | extern int is_dock_device(acpi_handle handle); |
120 | extern int register_dock_notifier(struct notifier_block *nb); | 125 | extern int register_dock_notifier(struct notifier_block *nb); |
121 | extern void unregister_dock_notifier(struct notifier_block *nb); | 126 | extern void unregister_dock_notifier(struct notifier_block *nb); |
122 | extern int register_hotplug_dock_device(acpi_handle handle, | 127 | extern 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); |
125 | extern void unregister_hotplug_dock_device(acpi_handle handle); | 130 | extern 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 | } |
138 | static inline int register_hotplug_dock_device(acpi_handle handle, | 143 | static 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; |