dock.c (d4263348f796f29546f90802177865dd4379dd0a) dock.c (3b52b21fa1f44c8956e21dfba645eda959111b5e)
1/*
2 * dock.c - ACPI dock station driver
3 *
4 * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 58 unchanged lines hidden (view full) ---

67 struct platform_device *dock_device;
68};
69static LIST_HEAD(dock_stations);
70static int dock_station_count;
71static DEFINE_MUTEX(hotplug_lock);
72
73struct dock_dependent_device {
74 struct list_head list;
1/*
2 * dock.c - ACPI dock station driver
3 *
4 * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 58 unchanged lines hidden (view full) ---

67 struct platform_device *dock_device;
68};
69static LIST_HEAD(dock_stations);
70static int dock_station_count;
71static DEFINE_MUTEX(hotplug_lock);
72
73struct dock_dependent_device {
74 struct list_head list;
75 acpi_handle handle;
75 struct acpi_device *adev;
76 const struct acpi_dock_ops *hp_ops;
77 void *hp_context;
78 unsigned int hp_refcount;
79 void (*hp_release)(void *);
80};
81
82#define DOCK_DOCKING 0x00000001
83#define DOCK_UNDOCKING 0x00000002

--- 9 unchanged lines hidden (view full) ---

93 DOCK_CALL_UEVENT,
94};
95
96/*****************************************************************************
97 * Dock Dependent device functions *
98 *****************************************************************************/
99/**
100 * add_dock_dependent_device - associate a device with the dock station
76 const struct acpi_dock_ops *hp_ops;
77 void *hp_context;
78 unsigned int hp_refcount;
79 void (*hp_release)(void *);
80};
81
82#define DOCK_DOCKING 0x00000001
83#define DOCK_UNDOCKING 0x00000002

--- 9 unchanged lines hidden (view full) ---

93 DOCK_CALL_UEVENT,
94};
95
96/*****************************************************************************
97 * Dock Dependent device functions *
98 *****************************************************************************/
99/**
100 * add_dock_dependent_device - associate a device with the dock station
101 * @ds: The dock station
102 * @handle: handle of the dependent device
101 * @ds: Dock station.
102 * @adev: Dependent ACPI device object.
103 *
104 * Add the dependent device to the dock's dependent device list.
105 */
103 *
104 * Add the dependent device to the dock's dependent device list.
105 */
106static int __init
107add_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)
108{
109 struct dock_dependent_device *dd;
110
111 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
112 if (!dd)
113 return -ENOMEM;
114
108{
109 struct dock_dependent_device *dd;
110
111 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
112 if (!dd)
113 return -ENOMEM;
114
115 dd->handle = handle;
115 dd->adev = adev;
116 INIT_LIST_HEAD(&dd->list);
117 list_add_tail(&dd->list, &ds->dependent_devices);
118
119 return 0;
120}
121
122static void remove_dock_dependent_devices(struct dock_station *ds)
123{

--- 84 unchanged lines hidden (view full) ---

208 }
209
210 mutex_unlock(&hotplug_lock);
211
212 if (!run)
213 return;
214
215 if (cb)
116 INIT_LIST_HEAD(&dd->list);
117 list_add_tail(&dd->list, &ds->dependent_devices);
118
119 return 0;
120}
121
122static void remove_dock_dependent_devices(struct dock_station *ds)
123{

--- 84 unchanged lines hidden (view full) ---

208 }
209
210 mutex_unlock(&hotplug_lock);
211
212 if (!run)
213 return;
214
215 if (cb)
216 cb(dd->handle, event, dd->hp_context);
216 cb(dd->adev->handle, event, dd->hp_context);
217
218 dock_release_hotplug(dd);
219}
220
217
218 dock_release_hotplug(dd);
219}
220
221static struct dock_station *find_dock_station(acpi_handle handle)
222{
223 struct dock_station *ds;
224
225 list_for_each_entry(ds, &dock_stations, sibling)
226 if (ds->handle == handle)
227 return ds;
228
229 return NULL;
230}
231
221/**
222 * find_dock_dependent_device - get a device dependent on this dock
223 * @ds: the dock station
232/**
233 * find_dock_dependent_device - get a device dependent on this dock
234 * @ds: the dock station
224 * @handle: the acpi_handle of the device we want
235 * @adev: ACPI device object to find.
225 *
226 * iterate over the dependent device list for this dock. If the
227 * dependent device matches the handle, return.
228 */
229static struct dock_dependent_device *
236 *
237 * iterate over the dependent device list for this dock. If the
238 * dependent device matches the handle, return.
239 */
240static struct dock_dependent_device *
230find_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
241find_dock_dependent_device(struct dock_station *ds, struct acpi_device *adev)
231{
232 struct dock_dependent_device *dd;
233
234 list_for_each_entry(dd, &ds->dependent_devices, list)
242{
243 struct dock_dependent_device *dd;
244
245 list_for_each_entry(dd, &ds->dependent_devices, list)
235 if (handle == dd->handle)
246 if (adev == dd->adev)
236 return dd;
237
238 return NULL;
239}
240
247 return dd;
248
249 return NULL;
250}
251
241/*****************************************************************************
242 * Dock functions *
243 *****************************************************************************/
244static int __init is_battery(acpi_handle handle)
252void register_dock_dependent_device(struct acpi_device *adev,
253 acpi_handle dshandle)
245{
254{
246 struct acpi_device_info *info;
247 int ret = 1;
255 struct dock_station *ds = find_dock_station(dshandle);
248
256
249 if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info)))
250 return 0;
251 if (!(info->valid & ACPI_VALID_HID))
252 ret = 0;
253 else
254 ret = !strcmp("PNP0C0A", info->hardware_id.string);
255
256 kfree(info);
257 return ret;
257 if (ds && !find_dock_dependent_device(ds, adev))
258 add_dock_dependent_device(ds, adev);
258}
259
259}
260
260/* Check whether ACPI object is an ejectable battery or disk bay */
261static bool __init is_ejectable_bay(acpi_handle handle)
262{
263 if (acpi_has_method(handle, "_EJ0") && is_battery(handle))
264 return true;
261/*****************************************************************************
262 * Dock functions *
263 *****************************************************************************/
265
264
266 return acpi_bay_match(handle);
267}
268
269/**
270 * is_dock_device - see if a device is on a dock station
265/**
266 * is_dock_device - see if a device is on a dock station
271 * @handle: acpi handle of the device
267 * @adev: ACPI device object to check.
272 *
273 * If this device is either the dock station itself,
274 * or is a device dependent on the dock station, then it
275 * is a dock device
276 */
268 *
269 * If this device is either the dock station itself,
270 * or is a device dependent on the dock station, then it
271 * is a dock device
272 */
277int is_dock_device(acpi_handle handle)
273int is_dock_device(struct acpi_device *adev)
278{
279 struct dock_station *dock_station;
280
281 if (!dock_station_count)
282 return 0;
283
274{
275 struct dock_station *dock_station;
276
277 if (!dock_station_count)
278 return 0;
279
284 if (acpi_dock_match(handle))
280 if (acpi_dock_match(adev->handle))
285 return 1;
286
287 list_for_each_entry(dock_station, &dock_stations, sibling)
281 return 1;
282
283 list_for_each_entry(dock_station, &dock_stations, sibling)
288 if (find_dock_dependent_device(dock_station, handle))
284 if (find_dock_dependent_device(dock_station, adev))
289 return 1;
290
291 return 0;
292}
293EXPORT_SYMBOL_GPL(is_dock_device);
294
295/**
296 * dock_present - see if the dock station is present.

--- 11 unchanged lines hidden (view full) ---

308 status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta);
309 if (ACPI_SUCCESS(status) && sta)
310 return 1;
311 }
312 return 0;
313}
314
315/**
285 return 1;
286
287 return 0;
288}
289EXPORT_SYMBOL_GPL(is_dock_device);
290
291/**
292 * dock_present - see if the dock station is present.

--- 11 unchanged lines hidden (view full) ---

304 status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta);
305 if (ACPI_SUCCESS(status) && sta)
306 return 1;
307 }
308 return 0;
309}
310
311/**
316 * dock_create_acpi_device - add new devices to acpi
317 * @handle - handle of the device to add
318 *
319 * This function will create a new acpi_device for the given
320 * handle if one does not exist already. This should cause
321 * acpi to scan for drivers for the given devices, and call
322 * matching driver's add routine.
323 */
324static void dock_create_acpi_device(acpi_handle handle)
325{
326 struct acpi_device *device = NULL;
327 int ret;
328
329 acpi_bus_get_device(handle, &device);
330 if (!acpi_device_enumerated(device)) {
331 ret = acpi_bus_scan(handle);
332 if (ret)
333 pr_debug("error adding bus, %x\n", -ret);
334 }
335}
336
337/**
338 * dock_remove_acpi_device - remove the acpi_device struct from acpi
339 * @handle - the handle of the device to remove
340 *
341 * Tell acpi to remove the acpi_device. This should cause any loaded
342 * driver to have it's remove routine called.
343 */
344static void dock_remove_acpi_device(acpi_handle handle)
345{
346 struct acpi_device *device;
347
348 if (!acpi_bus_get_device(handle, &device))
349 acpi_bus_trim(device);
350}
351
352/**
353 * hot_remove_dock_devices - Remove dock station devices.
354 * @ds: Dock station.
355 */
356static void hot_remove_dock_devices(struct dock_station *ds)
357{
358 struct dock_dependent_device *dd;
359
360 /*
361 * Walk the list in reverse order so that devices that have been added
362 * last are removed first (in case there are some indirect dependencies
363 * between them).
364 */
365 list_for_each_entry_reverse(dd, &ds->dependent_devices, list)
366 dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false);
367
368 list_for_each_entry_reverse(dd, &ds->dependent_devices, list)
312 * hot_remove_dock_devices - Remove dock station devices.
313 * @ds: Dock station.
314 */
315static void hot_remove_dock_devices(struct dock_station *ds)
316{
317 struct dock_dependent_device *dd;
318
319 /*
320 * Walk the list in reverse order so that devices that have been added
321 * last are removed first (in case there are some indirect dependencies
322 * between them).
323 */
324 list_for_each_entry_reverse(dd, &ds->dependent_devices, list)
325 dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false);
326
327 list_for_each_entry_reverse(dd, &ds->dependent_devices, list)
369 dock_remove_acpi_device(dd->handle);
328 acpi_bus_trim(dd->adev);
370}
371
372/**
373 * hotplug_dock_devices - Insert devices on a dock station.
374 * @ds: the dock station
375 * @event: either bus check or device check request
376 *
377 * Some devices on the dock station need to have drivers called

--- 9 unchanged lines hidden (view full) ---

387 list_for_each_entry(dd, &ds->dependent_devices, list)
388 dock_hotplug_event(dd, event, DOCK_CALL_FIXUP);
389
390 /* Call driver specific hotplug functions. */
391 list_for_each_entry(dd, &ds->dependent_devices, list)
392 dock_hotplug_event(dd, event, DOCK_CALL_HANDLER);
393
394 /*
329}
330
331/**
332 * hotplug_dock_devices - Insert devices on a dock station.
333 * @ds: the dock station
334 * @event: either bus check or device check request
335 *
336 * Some devices on the dock station need to have drivers called

--- 9 unchanged lines hidden (view full) ---

346 list_for_each_entry(dd, &ds->dependent_devices, list)
347 dock_hotplug_event(dd, event, DOCK_CALL_FIXUP);
348
349 /* Call driver specific hotplug functions. */
350 list_for_each_entry(dd, &ds->dependent_devices, list)
351 dock_hotplug_event(dd, event, DOCK_CALL_HANDLER);
352
353 /*
395 * Now make sure that an acpi_device is created for each dependent
396 * device. That will cause scan handlers to be attached to device
397 * objects or acpi_drivers to be stopped/started if they are present.
354 * Check if all devices have been enumerated already. If not, run
355 * acpi_bus_scan() for them and that will cause scan handlers to be
356 * attached to device objects or acpi_drivers to be stopped/started if
357 * they are present.
398 */
358 */
399 list_for_each_entry(dd, &ds->dependent_devices, list)
400 dock_create_acpi_device(dd->handle);
359 list_for_each_entry(dd, &ds->dependent_devices, list) {
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 }
401}
402
403static void dock_event(struct dock_station *ds, u32 event, int num)
404{
405 struct device *dev = &ds->dock_device->dev;
406 char event_string[13];
407 char *envp[] = { event_string, NULL };
408 struct dock_dependent_device *dd;

--- 104 unchanged lines hidden (view full) ---

513 * the dock driver after _DCK is executed.
514 */
515int register_hotplug_dock_device(acpi_handle handle,
516 const struct acpi_dock_ops *ops, void *context,
517 void (*init)(void *), void (*release)(void *))
518{
519 struct dock_dependent_device *dd;
520 struct dock_station *dock_station;
368}
369
370static void dock_event(struct dock_station *ds, u32 event, int num)
371{
372 struct device *dev = &ds->dock_device->dev;
373 char event_string[13];
374 char *envp[] = { event_string, NULL };
375 struct dock_dependent_device *dd;

--- 104 unchanged lines hidden (view full) ---

480 * the dock driver after _DCK is executed.
481 */
482int register_hotplug_dock_device(acpi_handle handle,
483 const struct acpi_dock_ops *ops, void *context,
484 void (*init)(void *), void (*release)(void *))
485{
486 struct dock_dependent_device *dd;
487 struct dock_station *dock_station;
488 struct acpi_device *adev;
521 int ret = -EINVAL;
522
523 if (WARN_ON(!context))
524 return -EINVAL;
525
526 if (!dock_station_count)
527 return -ENODEV;
528
489 int ret = -EINVAL;
490
491 if (WARN_ON(!context))
492 return -EINVAL;
493
494 if (!dock_station_count)
495 return -ENODEV;
496
497 ret = acpi_bus_get_device(handle, &adev);
498 if (ret)
499 return ret;
500
529 /*
530 * make sure this handle is for a device dependent on the dock,
531 * this would include the dock station itself
532 */
533 list_for_each_entry(dock_station, &dock_stations, sibling) {
534 /*
535 * An ATA bay can be in a dock and itself can be ejected
536 * separately, so there are two 'dock stations' which need the
537 * ops
538 */
501 /*
502 * make sure this handle is for a device dependent on the dock,
503 * this would include the dock station itself
504 */
505 list_for_each_entry(dock_station, &dock_stations, sibling) {
506 /*
507 * An ATA bay can be in a dock and itself can be ejected
508 * separately, so there are two 'dock stations' which need the
509 * ops
510 */
539 dd = find_dock_dependent_device(dock_station, handle);
511 dd = find_dock_dependent_device(dock_station, adev);
540 if (dd && !dock_init_hotplug(dd, ops, context, init, release))
541 ret = 0;
542 }
543
544 return ret;
545}
546EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
547
548/**
549 * unregister_hotplug_dock_device - remove yourself from the hotplug list
550 * @handle: the acpi handle of the device
551 */
552void unregister_hotplug_dock_device(acpi_handle handle)
553{
554 struct dock_dependent_device *dd;
555 struct dock_station *dock_station;
512 if (dd && !dock_init_hotplug(dd, ops, context, init, release))
513 ret = 0;
514 }
515
516 return ret;
517}
518EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
519
520/**
521 * unregister_hotplug_dock_device - remove yourself from the hotplug list
522 * @handle: the acpi handle of the device
523 */
524void unregister_hotplug_dock_device(acpi_handle handle)
525{
526 struct dock_dependent_device *dd;
527 struct dock_station *dock_station;
528 struct acpi_device *adev;
556
557 if (!dock_station_count)
558 return;
559
529
530 if (!dock_station_count)
531 return;
532
533 if (acpi_bus_get_device(handle, &adev))
534 return;
535
560 list_for_each_entry(dock_station, &dock_stations, sibling) {
536 list_for_each_entry(dock_station, &dock_stations, sibling) {
561 dd = find_dock_dependent_device(dock_station, handle);
537 dd = find_dock_dependent_device(dock_station, adev);
562 if (dd)
563 dock_release_hotplug(dd);
564 }
565}
566EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
567
568/**
569 * handle_eject_request - handle an undock request checking for error conditions

--- 23 unchanged lines hidden (view full) ---

593 acpi_handle_err(ds->handle, "Unable to undock!\n");
594 return -EBUSY;
595 }
596 complete_undock(ds);
597 return 0;
598}
599
600/**
538 if (dd)
539 dock_release_hotplug(dd);
540 }
541}
542EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
543
544/**
545 * handle_eject_request - handle an undock request checking for error conditions

--- 23 unchanged lines hidden (view full) ---

569 acpi_handle_err(ds->handle, "Unable to undock!\n");
570 return -EBUSY;
571 }
572 complete_undock(ds);
573 return 0;
574}
575
576/**
601 * dock_notify - act upon an acpi dock notification
602 * @ds: dock station
603 * @event: the acpi event
577 * dock_notify - Handle ACPI dock notification.
578 * @adev: Dock station's ACPI device object.
579 * @event: Event code.
604 *
605 * If we are notified to dock, then check to see if the dock is
606 * present and then dock. Notify all drivers of the dock event,
607 * and then hotplug and devices that may need hotplugging.
608 */
580 *
581 * If we are notified to dock, then check to see if the dock is
582 * present and then dock. Notify all drivers of the dock event,
583 * and then hotplug and devices that may need hotplugging.
584 */
609static void dock_notify(struct dock_station *ds, u32 event)
585int dock_notify(struct acpi_device *adev, u32 event)
610{
586{
611 acpi_handle handle = ds->handle;
612 struct acpi_device *adev = NULL;
587 acpi_handle handle = adev->handle;
588 struct dock_station *ds = find_dock_station(handle);
613 int surprise_removal = 0;
614
589 int surprise_removal = 0;
590
591 if (!ds)
592 return -ENODEV;
593
615 /*
616 * According to acpi spec 3.0a, if a DEVICE_CHECK notification
617 * is sent and _DCK is present, it is assumed to mean an undock
618 * request.
619 */
620 if ((ds->flags & DOCK_IS_DOCK) && event == ACPI_NOTIFY_DEVICE_CHECK)
621 event = ACPI_NOTIFY_EJECT_REQUEST;
622

--- 4 unchanged lines hidden (view full) ---

627 *
628 * To simplify event handling, dock dependent device handler always
629 * get ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and
630 * ACPI_NOTIFY_EJECT_REQUEST for removal
631 */
632 switch (event) {
633 case ACPI_NOTIFY_BUS_CHECK:
634 case ACPI_NOTIFY_DEVICE_CHECK:
594 /*
595 * According to acpi spec 3.0a, if a DEVICE_CHECK notification
596 * is sent and _DCK is present, it is assumed to mean an undock
597 * request.
598 */
599 if ((ds->flags & DOCK_IS_DOCK) && event == ACPI_NOTIFY_DEVICE_CHECK)
600 event = ACPI_NOTIFY_EJECT_REQUEST;
601

--- 4 unchanged lines hidden (view full) ---

606 *
607 * To simplify event handling, dock dependent device handler always
608 * get ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and
609 * ACPI_NOTIFY_EJECT_REQUEST for removal
610 */
611 switch (event) {
612 case ACPI_NOTIFY_BUS_CHECK:
613 case ACPI_NOTIFY_DEVICE_CHECK:
635 acpi_bus_get_device(handle, &adev);
636 if (!dock_in_progress(ds) && !acpi_device_enumerated(adev)) {
637 begin_dock(ds);
638 dock(ds);
639 if (!dock_present(ds)) {
640 acpi_handle_err(handle, "Unable to dock!\n");
641 complete_dock(ds);
642 break;
643 }

--- 13 unchanged lines hidden (view full) ---

657 case ACPI_NOTIFY_EJECT_REQUEST:
658 begin_undock(ds);
659 if ((immediate_undock && !(ds->flags & DOCK_IS_ATA))
660 || surprise_removal)
661 handle_eject_request(ds, event);
662 else
663 dock_event(ds, event, UNDOCK_EVENT);
664 break;
614 if (!dock_in_progress(ds) && !acpi_device_enumerated(adev)) {
615 begin_dock(ds);
616 dock(ds);
617 if (!dock_present(ds)) {
618 acpi_handle_err(handle, "Unable to dock!\n");
619 complete_dock(ds);
620 break;
621 }

--- 13 unchanged lines hidden (view full) ---

635 case ACPI_NOTIFY_EJECT_REQUEST:
636 begin_undock(ds);
637 if ((immediate_undock && !(ds->flags & DOCK_IS_ATA))
638 || surprise_removal)
639 handle_eject_request(ds, event);
640 else
641 dock_event(ds, event, UNDOCK_EVENT);
642 break;
665 default:
666 acpi_handle_err(handle, "Unknown dock event %d\n", event);
667 }
643 }
644 return 0;
668}
669
645}
646
670static void acpi_dock_deferred_cb(void *data, u32 event)
671{
672 acpi_scan_lock_acquire();
673 dock_notify(data, event);
674 acpi_scan_lock_release();
675}
676
677static void dock_notify_handler(acpi_handle handle, u32 event, void *data)
678{
679 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
680 && event != ACPI_NOTIFY_EJECT_REQUEST)
681 return;
682
683 acpi_hotplug_execute(acpi_dock_deferred_cb, data, event);
684}
685
686/**
687 * find_dock_devices - find devices on the dock station
688 * @handle: the handle of the device we are examining
689 * @lvl: unused
690 * @context: the dock station private data
691 * @rv: unused
692 *
693 * This function is called by acpi_walk_namespace. It will
694 * check to see if an object has an _EJD method. If it does, then it
695 * will see if it is dependent on the dock station.
696 */
697static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl,
698 void *context, void **rv)
699{
700 struct dock_station *ds = context;
701 acpi_handle ejd = NULL;
702
703 acpi_bus_get_ejd(handle, &ejd);
704 if (ejd == ds->handle)
705 add_dock_dependent_device(ds, handle);
706
707 return AE_OK;
708}
709
710/*
711 * show_docked - read method for "docked" file in sysfs
712 */
713static ssize_t show_docked(struct device *dev,
714 struct device_attribute *attr, char *buf)
715{
647/*
648 * show_docked - read method for "docked" file in sysfs
649 */
650static ssize_t show_docked(struct device *dev,
651 struct device_attribute *attr, char *buf)
652{
716 struct acpi_device *tmp;
717
718 struct dock_station *dock_station = dev->platform_data;
653 struct dock_station *dock_station = dev->platform_data;
654 struct acpi_device *adev = NULL;
719
655
720 if (!acpi_bus_get_device(dock_station->handle, &tmp))
721 return snprintf(buf, PAGE_SIZE, "1\n");
722 return snprintf(buf, PAGE_SIZE, "0\n");
656 acpi_bus_get_device(dock_station->handle, &adev);
657 return snprintf(buf, PAGE_SIZE, "%u\n", acpi_device_enumerated(adev));
723}
724static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
725
726/*
727 * show_flags - read method for flags file in sysfs
728 */
729static ssize_t show_flags(struct device *dev,
730 struct device_attribute *attr, char *buf)

--- 69 unchanged lines hidden (view full) ---

800 NULL
801};
802
803static struct attribute_group dock_attribute_group = {
804 .attrs = dock_attributes
805};
806
807/**
658}
659static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
660
661/*
662 * show_flags - read method for flags file in sysfs
663 */
664static ssize_t show_flags(struct device *dev,
665 struct device_attribute *attr, char *buf)

--- 69 unchanged lines hidden (view full) ---

735 NULL
736};
737
738static struct attribute_group dock_attribute_group = {
739 .attrs = dock_attributes
740};
741
742/**
808 * dock_add - add a new dock station
809 * @handle: the dock station handle
743 * acpi_dock_add - Add a new dock station
744 * @adev: Dock station ACPI device object.
810 *
745 *
811 * allocated and initialize a new dock station device. Find all devices
812 * that are on the dock station, and register for dock event notifications.
746 * allocated and initialize a new dock station device.
813 */
747 */
814static int __init dock_add(acpi_handle handle)
748void acpi_dock_add(struct acpi_device *adev)
815{
816 struct dock_station *dock_station, ds = { NULL, };
749{
750 struct dock_station *dock_station, ds = { NULL, };
751 struct platform_device_info pdevinfo;
752 acpi_handle handle = adev->handle;
817 struct platform_device *dd;
753 struct platform_device *dd;
818 acpi_status status;
819 int ret;
820
754 int ret;
755
821 dd = platform_device_register_data(NULL, "dock", dock_station_count,
822 &ds, sizeof(ds));
756 memset(&pdevinfo, 0, sizeof(pdevinfo));
757 pdevinfo.name = "dock";
758 pdevinfo.id = dock_station_count;
759 pdevinfo.acpi_node.companion = adev;
760 pdevinfo.data = &ds;
761 pdevinfo.size_data = sizeof(ds);
762 dd = platform_device_register_full(&pdevinfo);
823 if (IS_ERR(dd))
763 if (IS_ERR(dd))
824 return PTR_ERR(dd);
764 return;
825
826 dock_station = dd->dev.platform_data;
827
828 dock_station->handle = handle;
829 dock_station->dock_device = dd;
830 dock_station->last_dock_time = jiffies - HZ;
831
832 INIT_LIST_HEAD(&dock_station->sibling);
833 INIT_LIST_HEAD(&dock_station->dependent_devices);
834
835 /* we want the dock device to send uevents */
836 dev_set_uevent_suppress(&dd->dev, 0);
837
838 if (acpi_dock_match(handle))
839 dock_station->flags |= DOCK_IS_DOCK;
840 if (acpi_ata_match(handle))
841 dock_station->flags |= DOCK_IS_ATA;
765
766 dock_station = dd->dev.platform_data;
767
768 dock_station->handle = handle;
769 dock_station->dock_device = dd;
770 dock_station->last_dock_time = jiffies - HZ;
771
772 INIT_LIST_HEAD(&dock_station->sibling);
773 INIT_LIST_HEAD(&dock_station->dependent_devices);
774
775 /* we want the dock device to send uevents */
776 dev_set_uevent_suppress(&dd->dev, 0);
777
778 if (acpi_dock_match(handle))
779 dock_station->flags |= DOCK_IS_DOCK;
780 if (acpi_ata_match(handle))
781 dock_station->flags |= DOCK_IS_ATA;
842 if (is_battery(handle))
782 if (acpi_device_is_battery(adev))
843 dock_station->flags |= DOCK_IS_BAT;
844
845 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group);
846 if (ret)
847 goto err_unregister;
848
783 dock_station->flags |= DOCK_IS_BAT;
784
785 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group);
786 if (ret)
787 goto err_unregister;
788
849 /* Find dependent devices */
850 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
851 ACPI_UINT32_MAX, find_dock_devices, NULL,
852 dock_station, NULL);
853
854 /* add the dock station as a device dependent on itself */
789 /* add the dock station as a device dependent on itself */
855 ret = add_dock_dependent_device(dock_station, handle);
790 ret = add_dock_dependent_device(dock_station, adev);
856 if (ret)
857 goto err_rmgroup;
858
791 if (ret)
792 goto err_rmgroup;
793
859 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
860 dock_notify_handler, dock_station);
861 if (ACPI_FAILURE(status)) {
862 ret = -ENODEV;
863 goto err_rmgroup;
864 }
865
866 dock_station_count++;
867 list_add(&dock_station->sibling, &dock_stations);
794 dock_station_count++;
795 list_add(&dock_station->sibling, &dock_stations);
868 return 0;
796 adev->flags.is_dock_station = true;
797 dev_info(&adev->dev, "ACPI dock station (docks/bays count: %d)\n",
798 dock_station_count);
799 return;
869
870err_rmgroup:
871 remove_dock_dependent_devices(dock_station);
872 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group);
873err_unregister:
874 platform_device_unregister(dd);
875 acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret);
800
801err_rmgroup:
802 remove_dock_dependent_devices(dock_station);
803 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group);
804err_unregister:
805 platform_device_unregister(dd);
806 acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret);
876 return ret;
877}
807}
878
879/**
880 * find_dock_and_bay - look for dock stations and bays
881 * @handle: acpi handle of a device
882 * @lvl: unused
883 * @context: unused
884 * @rv: unused
885 *
886 * This is called by acpi_walk_namespace to look for dock stations and bays.
887 */
888static acpi_status __init
889find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
890{
891 if (acpi_dock_match(handle) || is_ejectable_bay(handle))
892 dock_add(handle);
893
894 return AE_OK;
895}
896
897void __init acpi_dock_init(void)
898{
899 /* look for dock stations and bays */
900 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
901 ACPI_UINT32_MAX, find_dock_and_bay, NULL, NULL, NULL);
902
903 if (!dock_station_count) {
904 pr_info(PREFIX "No dock devices found.\n");
905 return;
906 }
907
908 pr_info(PREFIX "%s: %d docks/bays found\n",
909 ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
910}