aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dock.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-20 19:10:09 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-20 19:10:09 -0500
commit3b52b21fa1f44c8956e21dfba645eda959111b5e (patch)
tree8c6ac7f521467f66dbf55249beb25d0446ac6957 /drivers/acpi/dock.c
parent96075315c5e7077fc5a3ac54c9b9e97e376e66ed (diff)
ACPI / dock: Use ACPI device object pointers instead of ACPI handles
Rework the ACPI dock station driver to store ACPI device object pointers instead of ACPI handles in its internal data structures. The purpose is moslty to make subsequent simplifications possible, but also this allows the overall code size to be reduced slightly. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/dock.c')
-rw-r--r--drivers/acpi/dock.c104
1 files changed, 42 insertions, 62 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