diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-02-20 19:10:09 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-02-20 19:10:09 -0500 |
commit | 3b52b21fa1f44c8956e21dfba645eda959111b5e (patch) | |
tree | 8c6ac7f521467f66dbf55249beb25d0446ac6957 /drivers/acpi/dock.c | |
parent | 96075315c5e7077fc5a3ac54c9b9e97e376e66ed (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.c | 104 |
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 | ||
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 | ||