aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/dock.c104
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c6
-rw-r--r--include/acpi/acpi_drivers.h4
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
73struct dock_dependent_device { 73struct 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 */
106static int add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) 106static 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 */
239static struct dock_dependent_device * 240static struct dock_dependent_device *
240find_dock_dependent_device(struct dock_station *ds, acpi_handle handle) 241find_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 */
273int is_dock_device(acpi_handle handle) 273int 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 */
320static 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 */
340static 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
399static void dock_event(struct dock_station *ds, u32 event, int num) 370static 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
119extern int is_dock_device(acpi_handle handle); 119extern int is_dock_device(struct acpi_device *adev);
120extern int register_hotplug_dock_device(acpi_handle handle, 120extern 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 *));
125extern void unregister_hotplug_dock_device(acpi_handle handle); 125extern void unregister_hotplug_dock_device(acpi_handle handle);
126#else 126#else
127static inline int is_dock_device(acpi_handle handle) 127static inline int is_dock_device(struct acpi_device *adev)
128{ 128{
129 return 0; 129 return 0;
130} 130}