25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/slab.h>
29 #include <linux/types.h>
33 #include <linux/stddef.h>
37 #define PREFIX "ACPI: "
39 #define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver"
46 static bool immediate_undock = 1;
49 "undock immediately when the undock button is pressed, 0 will cause"
50 " the driver to wait for userspace to write the undock sysfs file "
74 static int dock_station_count;
84 #define DOCK_DOCKING 0x00000001
85 #define DOCK_UNDOCKING 0x00000002
86 #define DOCK_IS_DOCK 0x00000010
87 #define DOCK_IS_ATA 0x00000020
88 #define DOCK_IS_BAT 0x00000040
90 #define UNDOCK_EVENT 2
112 INIT_LIST_HEAD(&dd->
list);
169 if (handle == dd->
handle) {
243 if (!is_ejectable(handle))
245 if (is_battery(handle) || is_ata(handle))
264 if (!dock_station_count)
271 if (find_dock_dependent_device(dock_station, handle))
287 unsigned long long sta;
309 static struct acpi_device * dock_create_acpi_device(
acpi_handle handle)
311 struct acpi_device *
device;
312 struct acpi_device *parent_device;
323 parent_device =
NULL;
326 ACPI_BUS_TYPE_DEVICE);
328 pr_debug(
"error adding bus, %x\n", -ret);
342 static void dock_remove_acpi_device(
acpi_handle handle)
344 struct acpi_device *device;
350 pr_debug(
"error removing bus, %x\n", -ret);
375 dd->
ops->handler(dd->handle, event, dd->
context);
385 dock_remove_acpi_device(dd->handle);
387 dock_create_acpi_device(dd->handle);
395 char event_string[13];
396 char *envp[] = { event_string,
NULL };
400 sprintf(event_string,
"EVENT=undock");
402 sprintf(event_string,
"EVENT=dock");
413 dd->
ops->uevent(dd->handle, event, dd->
context);
436 pr_debug(
"No _EJ0 support for dock device\n");
441 arg_list.pointer = &
arg;
443 arg.integer.value = 1;
447 pr_debug(
"Failed to evaluate _EJ0!\n");
457 static void handle_dock(
struct dock_station *ds,
int dock)
468 (
char *)name_buffer.
pointer, dock ?
"docking" :
"undocking");
472 arg_list.pointer = &
arg;
474 arg.integer.value = dock;
478 " _DCK\n", (
char *)name_buffer.
pointer));
499 static inline void complete_dock(
struct dock_station *ds)
505 static inline void begin_undock(
struct dock_station *ds)
510 static inline void complete_undock(
struct dock_station *ds)
515 static void dock_lock(
struct dock_station *ds,
int lock)
522 arg_list.pointer = &
arg;
524 arg.integer.value = !!lock;
561 if (!dock_station_count)
574 if (!dock_station_count)
599 if (!dock_station_count)
612 dd = find_dock_dependent_device(dock_station, handle);
616 dock_add_hotplug_device(dock_station, dd);
634 if (!dock_station_count)
638 dd = find_dock_dependent_device(dock_station, handle);
640 dock_del_hotplug_device(dock_station, dd);
653 if (dock_in_progress(ds))
669 if (dock_present(ds)) {
690 struct acpi_device *
tmp;
691 int surprise_removal = 0;
717 if (!dock_present(ds)) {
724 hotplug_dock_devices(ds, event);
731 if (dock_present(ds) || dock_in_progress(ds))
734 surprise_removal = 1;
741 handle_eject_request(ds, event);
756 static void acpi_dock_deferred_cb(
void *context)
765 unsigned long event,
void *data)
774 if (dock_station->
handle == handle) {
782 dd->
ds = dock_station;
791 .notifier_call = acpi_dock_notifier_call,
806 find_dock_devices(
acpi_handle handle,
u32 lvl,
void *context,
void **rv)
810 struct dock_station *ds =
context;
825 add_dock_dependent_device(ds, handle);
834 static ssize_t show_docked(
struct device *dev,
837 struct acpi_device *
tmp;
850 static ssize_t show_flags(
struct device *dev,
863 const char *buf,
size_t count)
871 begin_undock(dock_station);
873 return ret ? ret:
count;
880 static ssize_t show_dock_uid(
struct device *dev,
883 unsigned long long lbuf;
886 "_UID",
NULL, &lbuf);
894 static ssize_t show_dock_type(
struct device *dev,
901 type =
"dock_station";
905 type =
"battery_bay";
913 static struct attribute *dock_attributes[] = {
914 &dev_attr_docked.attr,
915 &dev_attr_flags.attr,
916 &dev_attr_undock.attr,
923 .attrs = dock_attributes
936 struct dock_station ds, *dock_station;
939 id = dock_station_count;
940 memset(&ds, 0,
sizeof(ds));
941 dd = platform_device_register_data(
NULL,
"dock",
id, &ds,
sizeof(ds));
945 dock_station = dd->
dev.platform_data;
953 INIT_LIST_HEAD(&dock_station->
sibling);
959 dev_set_uevent_suppress(&dd->
dev, 0);
965 if (is_battery(handle))
978 ret = add_dock_dependent_device(dock_station, handle);
982 dock_station_count++;
983 list_add(&dock_station->
sibling, &dock_stations);
997 static int dock_remove(
struct dock_station *ds)
1002 if (!dock_station_count)
1030 if (is_dock(handle))
1040 if (is_ejectable_bay(handle) && !is_dock(handle))
1045 static int __init dock_init(
void)
1057 if (!dock_station_count) {
1068 static void __exit dock_exit(
void)
1070 struct dock_station *
tmp, *dock_station;
1074 dock_remove(dock_station);