diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-07-04 21:03:25 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-07-14 19:33:12 -0400 |
commit | f09ce741a03ad7de591aa47e760fbeee28567b63 (patch) | |
tree | 2cbbd5f36902f161102ca5e9348bb6bdae62600f | |
parent | e6c215f15a1cbf4cdd6996d95fba0c0d6c0f3ccc (diff) |
ACPI / dock / PCI: Drop ACPI dock notifier chain
The only user of the ACPI dock notifier chain is the ACPI-based PCI
hotplug (acpiphp) driver that uses it to carry out post-dock fixups
needed by some systems with broken _DCK. However, it is not
necessary to use a separate notifier chain for that, as it can be
simply replaced with a new callback in struct acpi_dock_ops.
For this reason, add a new .fixup() callback to struct acpi_dock_ops
and make hotplug_dock_devices() execute it for all dock devices with
hotplug operations registered. Accordingly, make acpiphp point that
callback to the function carrying out the post-dock fixups and
do not register a separate dock notifier for each device
registering dock operations. Finally, drop the ACPI dock notifier
chain that has no more users.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/acpi/dock.c | 66 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 18 | ||||
-rw-r--r-- | include/acpi/acpi_drivers.h | 10 |
4 files changed, 30 insertions, 65 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 3e20b13fa272..c89a9c3b48b4 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -51,8 +51,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " | |||
51 | " the driver to wait for userspace to write the undock sysfs file " | 51 | " the driver to wait for userspace to write the undock sysfs file " |
52 | " before undocking"); | 52 | " before undocking"); |
53 | 53 | ||
54 | static struct atomic_notifier_head dock_notifier_list; | ||
55 | |||
56 | static const struct acpi_device_id dock_device_ids[] = { | 54 | static const struct acpi_device_id dock_device_ids[] = { |
57 | {"LNXDOCK", 0}, | 55 | {"LNXDOCK", 0}, |
58 | {"", 0}, | 56 | {"", 0}, |
@@ -89,6 +87,12 @@ struct dock_dependent_device { | |||
89 | #define DOCK_EVENT 3 | 87 | #define DOCK_EVENT 3 |
90 | #define UNDOCK_EVENT 2 | 88 | #define UNDOCK_EVENT 2 |
91 | 89 | ||
90 | enum dock_callback_type { | ||
91 | DOCK_CALL_HANDLER, | ||
92 | DOCK_CALL_FIXUP, | ||
93 | DOCK_CALL_UEVENT, | ||
94 | }; | ||
95 | |||
92 | /***************************************************************************** | 96 | /***************************************************************************** |
93 | * Dock Dependent device functions * | 97 | * Dock Dependent device functions * |
94 | *****************************************************************************/ | 98 | *****************************************************************************/ |
@@ -179,7 +183,7 @@ static void dock_release_hotplug(struct dock_dependent_device *dd) | |||
179 | } | 183 | } |
180 | 184 | ||
181 | static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, | 185 | static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, |
182 | bool uevent) | 186 | enum dock_callback_type cb_type) |
183 | { | 187 | { |
184 | acpi_notify_handler cb = NULL; | 188 | acpi_notify_handler cb = NULL; |
185 | bool run = false; | 189 | bool run = false; |
@@ -189,8 +193,18 @@ static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, | |||
189 | if (dd->hp_context) { | 193 | if (dd->hp_context) { |
190 | run = true; | 194 | run = true; |
191 | dd->hp_refcount++; | 195 | dd->hp_refcount++; |
192 | if (dd->hp_ops) | 196 | if (dd->hp_ops) { |
193 | cb = uevent ? dd->hp_ops->uevent : dd->hp_ops->handler; | 197 | switch (cb_type) { |
198 | case DOCK_CALL_FIXUP: | ||
199 | cb = dd->hp_ops->fixup; | ||
200 | break; | ||
201 | case DOCK_CALL_UEVENT: | ||
202 | cb = dd->hp_ops->uevent; | ||
203 | break; | ||
204 | default: | ||
205 | cb = dd->hp_ops->handler; | ||
206 | } | ||
207 | } | ||
194 | } | 208 | } |
195 | 209 | ||
196 | mutex_unlock(&hotplug_lock); | 210 | mutex_unlock(&hotplug_lock); |
@@ -372,9 +386,13 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
372 | { | 386 | { |
373 | struct dock_dependent_device *dd; | 387 | struct dock_dependent_device *dd; |
374 | 388 | ||
389 | /* Call driver specific post-dock fixups. */ | ||
390 | list_for_each_entry(dd, &ds->dependent_devices, list) | ||
391 | dock_hotplug_event(dd, event, DOCK_CALL_FIXUP); | ||
392 | |||
375 | /* Call driver specific hotplug functions. */ | 393 | /* Call driver specific hotplug functions. */ |
376 | list_for_each_entry(dd, &ds->dependent_devices, list) | 394 | list_for_each_entry(dd, &ds->dependent_devices, list) |
377 | dock_hotplug_event(dd, event, false); | 395 | dock_hotplug_event(dd, event, DOCK_CALL_HANDLER); |
378 | 396 | ||
379 | /* | 397 | /* |
380 | * Now make sure that an acpi_device is created for each dependent | 398 | * Now make sure that an acpi_device is created for each dependent |
@@ -405,7 +423,7 @@ static void dock_event(struct dock_station *ds, u32 event, int num) | |||
405 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); | 423 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); |
406 | 424 | ||
407 | list_for_each_entry(dd, &ds->dependent_devices, list) | 425 | list_for_each_entry(dd, &ds->dependent_devices, list) |
408 | dock_hotplug_event(dd, event, true); | 426 | dock_hotplug_event(dd, event, DOCK_CALL_UEVENT); |
409 | 427 | ||
410 | if (num != DOCK_EVENT) | 428 | if (num != DOCK_EVENT) |
411 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); | 429 | kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); |
@@ -488,37 +506,6 @@ static int dock_in_progress(struct dock_station *ds) | |||
488 | } | 506 | } |
489 | 507 | ||
490 | /** | 508 | /** |
491 | * register_dock_notifier - add yourself to the dock notifier list | ||
492 | * @nb: the callers notifier block | ||
493 | * | ||
494 | * If a driver wishes to be notified about dock events, they can | ||
495 | * use this function to put a notifier block on the dock notifier list. | ||
496 | * this notifier call chain will be called after a dock event, but | ||
497 | * before hotplugging any new devices. | ||
498 | */ | ||
499 | int register_dock_notifier(struct notifier_block *nb) | ||
500 | { | ||
501 | if (!dock_station_count) | ||
502 | return -ENODEV; | ||
503 | |||
504 | return atomic_notifier_chain_register(&dock_notifier_list, nb); | ||
505 | } | ||
506 | EXPORT_SYMBOL_GPL(register_dock_notifier); | ||
507 | |||
508 | /** | ||
509 | * unregister_dock_notifier - remove yourself from the dock notifier list | ||
510 | * @nb: the callers notifier block | ||
511 | */ | ||
512 | void unregister_dock_notifier(struct notifier_block *nb) | ||
513 | { | ||
514 | if (!dock_station_count) | ||
515 | return; | ||
516 | |||
517 | atomic_notifier_chain_unregister(&dock_notifier_list, nb); | ||
518 | } | ||
519 | EXPORT_SYMBOL_GPL(unregister_dock_notifier); | ||
520 | |||
521 | /** | ||
522 | * register_hotplug_dock_device - register a hotplug function | 509 | * register_hotplug_dock_device - register a hotplug function |
523 | * @handle: the handle of the device | 510 | * @handle: the handle of the device |
524 | * @ops: handlers to call after docking | 511 | * @ops: handlers to call after docking |
@@ -658,8 +645,6 @@ static void dock_notify(struct dock_station *ds, u32 event) | |||
658 | complete_dock(ds); | 645 | complete_dock(ds); |
659 | break; | 646 | break; |
660 | } | 647 | } |
661 | atomic_notifier_call_chain(&dock_notifier_list, | ||
662 | event, NULL); | ||
663 | hotplug_dock_devices(ds, event); | 648 | hotplug_dock_devices(ds, event); |
664 | complete_dock(ds); | 649 | complete_dock(ds); |
665 | dock_event(ds, event, DOCK_EVENT); | 650 | dock_event(ds, event, DOCK_EVENT); |
@@ -945,7 +930,6 @@ void __init acpi_dock_init(void) | |||
945 | return; | 930 | return; |
946 | } | 931 | } |
947 | 932 | ||
948 | ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); | ||
949 | pr_info(PREFIX "%s: %d docks/bays found\n", | 933 | pr_info(PREFIX "%s: %d docks/bays found\n", |
950 | ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); | 934 | ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); |
951 | } | 935 | } |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 6fdd49c6f0b9..6c781edabcc6 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -122,7 +122,6 @@ struct acpiphp_func { | |||
122 | struct acpiphp_slot *slot; /* parent */ | 122 | struct acpiphp_slot *slot; /* parent */ |
123 | 123 | ||
124 | struct list_head sibling; | 124 | struct list_head sibling; |
125 | struct notifier_block nb; | ||
126 | acpi_handle handle; | 125 | acpi_handle handle; |
127 | 126 | ||
128 | u8 function; /* pci function# */ | 127 | u8 function; /* pci function# */ |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index a0a7133a1d12..8bfad0dc29ab 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -119,15 +119,14 @@ static void free_bridge(struct kref *kref) | |||
119 | * TBD - figure out a way to only call fixups for | 119 | * TBD - figure out a way to only call fixups for |
120 | * systems that require them. | 120 | * systems that require them. |
121 | */ | 121 | */ |
122 | static int post_dock_fixups(struct notifier_block *nb, unsigned long val, | 122 | static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) |
123 | void *v) | ||
124 | { | 123 | { |
125 | struct acpiphp_func *func = container_of(nb, struct acpiphp_func, nb); | 124 | struct acpiphp_func *func = data; |
126 | struct pci_bus *bus = func->slot->bridge->pci_bus; | 125 | struct pci_bus *bus = func->slot->bridge->pci_bus; |
127 | u32 buses; | 126 | u32 buses; |
128 | 127 | ||
129 | if (!bus->self) | 128 | if (!bus->self) |
130 | return NOTIFY_OK; | 129 | return; |
131 | 130 | ||
132 | /* fixup bad _DCK function that rewrites | 131 | /* fixup bad _DCK function that rewrites |
133 | * secondary bridge on slot | 132 | * secondary bridge on slot |
@@ -143,11 +142,11 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, | |||
143 | | ((unsigned int)(bus->busn_res.end) << 16); | 142 | | ((unsigned int)(bus->busn_res.end) << 16); |
144 | pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); | 143 | pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); |
145 | } | 144 | } |
146 | return NOTIFY_OK; | ||
147 | } | 145 | } |
148 | 146 | ||
149 | 147 | ||
150 | static const struct acpi_dock_ops acpiphp_dock_ops = { | 148 | static const struct acpi_dock_ops acpiphp_dock_ops = { |
149 | .fixup = post_dock_fixups, | ||
151 | .handler = hotplug_event_func, | 150 | .handler = hotplug_event_func, |
152 | }; | 151 | }; |
153 | 152 | ||
@@ -315,14 +314,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
315 | &acpiphp_dock_ops, newfunc, | 314 | &acpiphp_dock_ops, newfunc, |
316 | acpiphp_dock_init, acpiphp_dock_release)) | 315 | acpiphp_dock_init, acpiphp_dock_release)) |
317 | dbg("failed to register dock device\n"); | 316 | dbg("failed to register dock device\n"); |
318 | |||
319 | /* we need to be notified when dock events happen | ||
320 | * outside of the hotplug operation, since we may | ||
321 | * need to do fixups before we can hotplug. | ||
322 | */ | ||
323 | newfunc->nb.notifier_call = post_dock_fixups; | ||
324 | if (register_dock_notifier(&newfunc->nb)) | ||
325 | dbg("failed to register a dock notifier"); | ||
326 | } | 317 | } |
327 | 318 | ||
328 | /* install notify handler */ | 319 | /* install notify handler */ |
@@ -472,7 +463,6 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
472 | list_for_each_entry(func, &slot->funcs, sibling) { | 463 | list_for_each_entry(func, &slot->funcs, sibling) { |
473 | if (is_dock_device(func->handle)) { | 464 | if (is_dock_device(func->handle)) { |
474 | unregister_hotplug_dock_device(func->handle); | 465 | unregister_hotplug_dock_device(func->handle); |
475 | unregister_dock_notifier(&func->nb); | ||
476 | } | 466 | } |
477 | if (!(func->flags & FUNC_HAS_DCK)) { | 467 | if (!(func->flags & FUNC_HAS_DCK)) { |
478 | status = acpi_remove_notify_handler(func->handle, | 468 | status = acpi_remove_notify_handler(func->handle, |
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 0cf85786ed21..1cedfcb1bd88 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h | |||
@@ -113,14 +113,13 @@ void pci_acpi_crs_quirks(void); | |||
113 | Dock Station | 113 | Dock Station |
114 | -------------------------------------------------------------------------- */ | 114 | -------------------------------------------------------------------------- */ |
115 | struct acpi_dock_ops { | 115 | struct acpi_dock_ops { |
116 | acpi_notify_handler fixup; | ||
116 | acpi_notify_handler handler; | 117 | acpi_notify_handler handler; |
117 | acpi_notify_handler uevent; | 118 | acpi_notify_handler uevent; |
118 | }; | 119 | }; |
119 | 120 | ||
120 | #ifdef CONFIG_ACPI_DOCK | 121 | #ifdef CONFIG_ACPI_DOCK |
121 | extern int is_dock_device(acpi_handle handle); | 122 | extern int is_dock_device(acpi_handle handle); |
122 | extern int register_dock_notifier(struct notifier_block *nb); | ||
123 | extern void unregister_dock_notifier(struct notifier_block *nb); | ||
124 | extern int register_hotplug_dock_device(acpi_handle handle, | 123 | extern int register_hotplug_dock_device(acpi_handle handle, |
125 | const struct acpi_dock_ops *ops, | 124 | const struct acpi_dock_ops *ops, |
126 | void *context, | 125 | void *context, |
@@ -132,13 +131,6 @@ static inline int is_dock_device(acpi_handle handle) | |||
132 | { | 131 | { |
133 | return 0; | 132 | return 0; |
134 | } | 133 | } |
135 | static inline int register_dock_notifier(struct notifier_block *nb) | ||
136 | { | ||
137 | return -ENODEV; | ||
138 | } | ||
139 | static inline void unregister_dock_notifier(struct notifier_block *nb) | ||
140 | { | ||
141 | } | ||
142 | static inline int register_hotplug_dock_device(acpi_handle handle, | 134 | static inline int register_hotplug_dock_device(acpi_handle handle, |
143 | const struct acpi_dock_ops *ops, | 135 | const struct acpi_dock_ops *ops, |
144 | void *context, | 136 | void *context, |