diff options
-rw-r--r-- | drivers/acpi/dock.c | 104 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 6 | ||||
-rw-r--r-- | include/acpi/acpi_drivers.h | 4 |
3 files changed, 47 insertions, 67 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 3199ce950e05..8c3967cb4830 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -72,7 +72,7 @@ static DEFINE_MUTEX(hotplug_lock); | |||
72 | 72 | ||
73 | struct dock_dependent_device { | 73 | struct dock_dependent_device { |
74 | struct list_head list; | 74 | struct list_head list; |
75 | acpi_handle handle; | 75 | struct acpi_device *adev; |
76 | const struct acpi_dock_ops *hp_ops; | 76 | const struct acpi_dock_ops *hp_ops; |
77 | void *hp_context; | 77 | void *hp_context; |
78 | unsigned int hp_refcount; | 78 | unsigned int hp_refcount; |
@@ -98,12 +98,13 @@ enum dock_callback_type { | |||
98 | *****************************************************************************/ | 98 | *****************************************************************************/ |
99 | /** | 99 | /** |
100 | * add_dock_dependent_device - associate a device with the dock station | 100 | * add_dock_dependent_device - associate a device with the dock station |
101 | * @ds: The dock station | 101 | * @ds: Dock station. |
102 | * @handle: handle of the dependent device | 102 | * @adev: Dependent ACPI device object. |
103 | * | 103 | * |
104 | * Add the dependent device to the dock's dependent device list. | 104 | * Add the dependent device to the dock's dependent device list. |
105 | */ | 105 | */ |
106 | static int add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | 106 | static int add_dock_dependent_device(struct dock_station *ds, |
107 | struct acpi_device *adev) | ||
107 | { | 108 | { |
108 | struct dock_dependent_device *dd; | 109 | struct dock_dependent_device *dd; |
109 | 110 | ||
@@ -111,7 +112,7 @@ static int add_dock_dependent_device(struct dock_station *ds, acpi_handle handle | |||
111 | if (!dd) | 112 | if (!dd) |
112 | return -ENOMEM; | 113 | return -ENOMEM; |
113 | 114 | ||
114 | dd->handle = handle; | 115 | dd->adev = adev; |
115 | INIT_LIST_HEAD(&dd->list); | 116 | INIT_LIST_HEAD(&dd->list); |
116 | list_add_tail(&dd->list, &ds->dependent_devices); | 117 | list_add_tail(&dd->list, &ds->dependent_devices); |
117 | 118 | ||
@@ -212,7 +213,7 @@ static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, | |||
212 | return; | 213 | return; |
213 | 214 | ||
214 | if (cb) | 215 | if (cb) |
215 | cb(dd->handle, event, dd->hp_context); | 216 | cb(dd->adev->handle, event, dd->hp_context); |
216 | 217 | ||
217 | dock_release_hotplug(dd); | 218 | dock_release_hotplug(dd); |
218 | } | 219 | } |
@@ -231,18 +232,18 @@ static struct dock_station *find_dock_station(acpi_handle handle) | |||
231 | /** | 232 | /** |
232 | * find_dock_dependent_device - get a device dependent on this dock | 233 | * find_dock_dependent_device - get a device dependent on this dock |
233 | * @ds: the dock station | 234 | * @ds: the dock station |
234 | * @handle: the acpi_handle of the device we want | 235 | * @adev: ACPI device object to find. |
235 | * | 236 | * |
236 | * iterate over the dependent device list for this dock. If the | 237 | * iterate over the dependent device list for this dock. If the |
237 | * dependent device matches the handle, return. | 238 | * dependent device matches the handle, return. |
238 | */ | 239 | */ |
239 | static struct dock_dependent_device * | 240 | static struct dock_dependent_device * |
240 | find_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | 241 | find_dock_dependent_device(struct dock_station *ds, struct acpi_device *adev) |
241 | { | 242 | { |
242 | struct dock_dependent_device *dd; | 243 | struct dock_dependent_device *dd; |
243 | 244 | ||
244 | list_for_each_entry(dd, &ds->dependent_devices, list) | 245 | list_for_each_entry(dd, &ds->dependent_devices, list) |
245 | if (handle == dd->handle) | 246 | if (adev == dd->adev) |
246 | return dd; | 247 | return dd; |
247 | 248 | ||
248 | return NULL; | 249 | return NULL; |
@@ -252,10 +253,9 @@ void register_dock_dependent_device(struct acpi_device *adev, | |||
252 | acpi_handle dshandle) | 253 | acpi_handle dshandle) |
253 | { | 254 | { |
254 | struct dock_station *ds = find_dock_station(dshandle); | 255 | struct dock_station *ds = find_dock_station(dshandle); |
255 | acpi_handle handle = adev->handle; | ||
256 | 256 | ||
257 | if (ds && !find_dock_dependent_device(ds, handle)) | 257 | if (ds && !find_dock_dependent_device(ds, adev)) |
258 | add_dock_dependent_device(ds, handle); | 258 | add_dock_dependent_device(ds, adev); |
259 | } | 259 | } |
260 | 260 | ||
261 | /***************************************************************************** | 261 | /***************************************************************************** |
@@ -264,24 +264,24 @@ void register_dock_dependent_device(struct acpi_device *adev, | |||
264 | 264 | ||
265 | /** | 265 | /** |
266 | * is_dock_device - see if a device is on a dock station | 266 | * is_dock_device - see if a device is on a dock station |
267 | * @handle: acpi handle of the device | 267 | * @adev: ACPI device object to check. |
268 | * | 268 | * |
269 | * If this device is either the dock station itself, | 269 | * If this device is either the dock station itself, |
270 | * or is a device dependent on the dock station, then it | 270 | * or is a device dependent on the dock station, then it |
271 | * is a dock device | 271 | * is a dock device |
272 | */ | 272 | */ |
273 | int is_dock_device(acpi_handle handle) | 273 | int is_dock_device(struct acpi_device *adev) |
274 | { | 274 | { |
275 | struct dock_station *dock_station; | 275 | struct dock_station *dock_station; |
276 | 276 | ||
277 | if (!dock_station_count) | 277 | if (!dock_station_count) |
278 | return 0; | 278 | return 0; |
279 | 279 | ||
280 | if (acpi_dock_match(handle)) | 280 | if (acpi_dock_match(adev->handle)) |
281 | return 1; | 281 | return 1; |
282 | 282 | ||
283 | list_for_each_entry(dock_station, &dock_stations, sibling) | 283 | list_for_each_entry(dock_station, &dock_stations, sibling) |
284 | if (find_dock_dependent_device(dock_station, handle)) | 284 | if (find_dock_dependent_device(dock_station, adev)) |
285 | return 1; | 285 | return 1; |
286 | 286 | ||
287 | return 0; | 287 | return 0; |
@@ -309,43 +309,6 @@ static int dock_present(struct dock_station *ds) | |||
309 | } | 309 | } |
310 | 310 | ||
311 | /** | 311 | /** |
312 | * dock_create_acpi_device - add new devices to acpi | ||
313 | * @handle - handle of the device to add | ||
314 | * | ||
315 | * This function will create a new acpi_device for the given | ||
316 | * handle if one does not exist already. This should cause | ||
317 | * acpi to scan for drivers for the given devices, and call | ||
318 | * matching driver's add routine. | ||
319 | */ | ||
320 | static void dock_create_acpi_device(acpi_handle handle) | ||
321 | { | ||
322 | struct acpi_device *device = NULL; | ||
323 | int ret; | ||
324 | |||
325 | acpi_bus_get_device(handle, &device); | ||
326 | if (!acpi_device_enumerated(device)) { | ||
327 | ret = acpi_bus_scan(handle); | ||
328 | if (ret) | ||
329 | pr_debug("error adding bus, %x\n", -ret); | ||
330 | } | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * dock_remove_acpi_device - remove the acpi_device struct from acpi | ||
335 | * @handle - the handle of the device to remove | ||
336 | * | ||
337 | * Tell acpi to remove the acpi_device. This should cause any loaded | ||
338 | * driver to have it's remove routine called. | ||
339 | */ | ||
340 | static void dock_remove_acpi_device(acpi_handle handle) | ||
341 | { | ||
342 | struct acpi_device *device; | ||
343 | |||
344 | if (!acpi_bus_get_device(handle, &device)) | ||
345 | acpi_bus_trim(device); | ||
346 | } | ||
347 | |||
348 | /** | ||
349 | * hot_remove_dock_devices - Remove dock station devices. | 312 | * hot_remove_dock_devices - Remove dock station devices. |
350 | * @ds: Dock station. | 313 | * @ds: Dock station. |
351 | */ | 314 | */ |
@@ -362,7 +325,7 @@ static void hot_remove_dock_devices(struct dock_station *ds) | |||
362 | dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false); | 325 | dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false); |
363 | 326 | ||
364 | list_for_each_entry_reverse(dd, &ds->dependent_devices, list) | 327 | list_for_each_entry_reverse(dd, &ds->dependent_devices, list) |
365 | dock_remove_acpi_device(dd->handle); | 328 | acpi_bus_trim(dd->adev); |
366 | } | 329 | } |
367 | 330 | ||
368 | /** | 331 | /** |
@@ -388,12 +351,20 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) | |||
388 | dock_hotplug_event(dd, event, DOCK_CALL_HANDLER); | 351 | dock_hotplug_event(dd, event, DOCK_CALL_HANDLER); |
389 | 352 | ||
390 | /* | 353 | /* |
391 | * Now make sure that an acpi_device is created for each dependent | 354 | * Check if all devices have been enumerated already. If not, run |
392 | * device. That will cause scan handlers to be attached to device | 355 | * acpi_bus_scan() for them and that will cause scan handlers to be |
393 | * objects or acpi_drivers to be stopped/started if they are present. | 356 | * attached to device objects or acpi_drivers to be stopped/started if |
357 | * they are present. | ||
394 | */ | 358 | */ |
395 | list_for_each_entry(dd, &ds->dependent_devices, list) | 359 | list_for_each_entry(dd, &ds->dependent_devices, list) { |
396 | dock_create_acpi_device(dd->handle); | 360 | struct acpi_device *adev = dd->adev; |
361 | |||
362 | if (!acpi_device_enumerated(adev)) { | ||
363 | int ret = acpi_bus_scan(adev->handle); | ||
364 | if (ret) | ||
365 | dev_dbg(&adev->dev, "scan error %d\n", -ret); | ||
366 | } | ||
367 | } | ||
397 | } | 368 | } |
398 | 369 | ||
399 | static void dock_event(struct dock_station *ds, u32 event, int num) | 370 | static void dock_event(struct dock_station *ds, u32 event, int num) |
@@ -514,6 +485,7 @@ int register_hotplug_dock_device(acpi_handle handle, | |||
514 | { | 485 | { |
515 | struct dock_dependent_device *dd; | 486 | struct dock_dependent_device *dd; |
516 | struct dock_station *dock_station; | 487 | struct dock_station *dock_station; |
488 | struct acpi_device *adev; | ||
517 | int ret = -EINVAL; | 489 | int ret = -EINVAL; |
518 | 490 | ||
519 | if (WARN_ON(!context)) | 491 | if (WARN_ON(!context)) |
@@ -522,6 +494,10 @@ int register_hotplug_dock_device(acpi_handle handle, | |||
522 | if (!dock_station_count) | 494 | if (!dock_station_count) |
523 | return -ENODEV; | 495 | return -ENODEV; |
524 | 496 | ||
497 | ret = acpi_bus_get_device(handle, &adev); | ||
498 | if (ret) | ||
499 | return ret; | ||
500 | |||
525 | /* | 501 | /* |
526 | * make sure this handle is for a device dependent on the dock, | 502 | * make sure this handle is for a device dependent on the dock, |
527 | * this would include the dock station itself | 503 | * this would include the dock station itself |
@@ -532,7 +508,7 @@ int register_hotplug_dock_device(acpi_handle handle, | |||
532 | * separately, so there are two 'dock stations' which need the | 508 | * separately, so there are two 'dock stations' which need the |
533 | * ops | 509 | * ops |
534 | */ | 510 | */ |
535 | dd = find_dock_dependent_device(dock_station, handle); | 511 | dd = find_dock_dependent_device(dock_station, adev); |
536 | if (dd && !dock_init_hotplug(dd, ops, context, init, release)) | 512 | if (dd && !dock_init_hotplug(dd, ops, context, init, release)) |
537 | ret = 0; | 513 | ret = 0; |
538 | } | 514 | } |
@@ -549,12 +525,16 @@ void unregister_hotplug_dock_device(acpi_handle handle) | |||
549 | { | 525 | { |
550 | struct dock_dependent_device *dd; | 526 | struct dock_dependent_device *dd; |
551 | struct dock_station *dock_station; | 527 | struct dock_station *dock_station; |
528 | struct acpi_device *adev; | ||
552 | 529 | ||
553 | if (!dock_station_count) | 530 | if (!dock_station_count) |
554 | return; | 531 | return; |
555 | 532 | ||
533 | if (acpi_bus_get_device(handle, &adev)) | ||
534 | return; | ||
535 | |||
556 | list_for_each_entry(dock_station, &dock_stations, sibling) { | 536 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
557 | dd = find_dock_dependent_device(dock_station, handle); | 537 | dd = find_dock_dependent_device(dock_station, adev); |
558 | if (dd) | 538 | if (dd) |
559 | dock_release_hotplug(dd); | 539 | dock_release_hotplug(dd); |
560 | } | 540 | } |
@@ -807,7 +787,7 @@ void acpi_dock_add(struct acpi_device *adev) | |||
807 | goto err_unregister; | 787 | goto err_unregister; |
808 | 788 | ||
809 | /* add the dock station as a device dependent on itself */ | 789 | /* add the dock station as a device dependent on itself */ |
810 | ret = add_dock_dependent_device(dock_station, handle); | 790 | ret = add_dock_dependent_device(dock_station, adev); |
811 | if (ret) | 791 | if (ret) |
812 | goto err_rmgroup; | 792 | goto err_rmgroup; |
813 | 793 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index d3d2cc6bb40a..cd886725c42e 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -334,7 +334,7 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, | |||
334 | * by the native PCIe hotplug (PCIeHP), becuase that code is supposed to | 334 | * by the native PCIe hotplug (PCIeHP), becuase that code is supposed to |
335 | * expose slots to user space in those cases. | 335 | * expose slots to user space in those cases. |
336 | */ | 336 | */ |
337 | if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(handle)) | 337 | if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev)) |
338 | && !(pdev && device_is_managed_by_native_pciehp(pdev))) { | 338 | && !(pdev && device_is_managed_by_native_pciehp(pdev))) { |
339 | unsigned long long sun; | 339 | unsigned long long sun; |
340 | int retval; | 340 | int retval; |
@@ -369,7 +369,7 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, | |||
369 | &val, 60*1000)) | 369 | &val, 60*1000)) |
370 | slot->flags |= SLOT_ENABLED; | 370 | slot->flags |= SLOT_ENABLED; |
371 | 371 | ||
372 | if (is_dock_device(handle)) { | 372 | if (is_dock_device(adev)) { |
373 | /* we don't want to call this device's _EJ0 | 373 | /* we don't want to call this device's _EJ0 |
374 | * because we want the dock notify handler | 374 | * because we want the dock notify handler |
375 | * to call it after it calls _DCK | 375 | * to call it after it calls _DCK |
@@ -411,7 +411,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
411 | list_for_each_entry(func, &slot->funcs, sibling) { | 411 | list_for_each_entry(func, &slot->funcs, sibling) { |
412 | struct acpi_device *adev = func_to_acpi_device(func); | 412 | struct acpi_device *adev = func_to_acpi_device(func); |
413 | 413 | ||
414 | if (is_dock_device(adev->handle)) | 414 | if (is_dock_device(adev)) |
415 | unregister_hotplug_dock_device(adev->handle); | 415 | unregister_hotplug_dock_device(adev->handle); |
416 | 416 | ||
417 | acpi_lock_hp_context(); | 417 | acpi_lock_hp_context(); |
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index b124fdb26046..d6c98b9cbe38 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h | |||
@@ -116,7 +116,7 @@ struct acpi_dock_ops { | |||
116 | }; | 116 | }; |
117 | 117 | ||
118 | #ifdef CONFIG_ACPI_DOCK | 118 | #ifdef CONFIG_ACPI_DOCK |
119 | extern int is_dock_device(acpi_handle handle); | 119 | extern int is_dock_device(struct acpi_device *adev); |
120 | extern int register_hotplug_dock_device(acpi_handle handle, | 120 | extern int register_hotplug_dock_device(acpi_handle handle, |
121 | const struct acpi_dock_ops *ops, | 121 | const struct acpi_dock_ops *ops, |
122 | void *context, | 122 | void *context, |
@@ -124,7 +124,7 @@ extern int register_hotplug_dock_device(acpi_handle handle, | |||
124 | void (*release)(void *)); | 124 | void (*release)(void *)); |
125 | extern void unregister_hotplug_dock_device(acpi_handle handle); | 125 | extern void unregister_hotplug_dock_device(acpi_handle handle); |
126 | #else | 126 | #else |
127 | static inline int is_dock_device(acpi_handle handle) | 127 | static inline int is_dock_device(struct acpi_device *adev) |
128 | { | 128 | { |
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |