aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristen Carlson Accardi <kristen.c.accardi@intel.com>2007-05-09 18:08:15 -0400
committerLen Brown <len.brown@intel.com>2007-05-10 03:30:41 -0400
commita0cd35fdca0bb711854edeaf016cec6cdf82eeca (patch)
treee732a7047f4d2a24476e7e9faa63573353e45b3a
parent0f6f2804563eee64f0fc7cbcb009b98b6f332af6 (diff)
ACPI: dock: add immediate_undock option
Allow the driver to be loaded with an option that will allow userspace to control whether the laptop is ejected immediately when the user presses the button, or only when the syfs undock file is written. if immediate_undock == 1, then when the user presses the undock button, the laptop will send an event to userspace to notify userspace of the undock, but then immediately undock without waiting for userspace. This is the current behavior, and I set this to be the default. if immediate_undock == 0, then when the user presses the undock button, the laptop will send an event to userspace and do nothing. User space can query the "flags" sysfs entry to determine if an undock request has been made by the user (if bit 1 is set). User space will then need to write the undock sysfs entry to complete the undocking process. Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/acpi/dock.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index b5addd411b55..98ec717b14cf 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -40,6 +40,13 @@ MODULE_AUTHOR("Kristen Carlson Accardi");
40MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION); 40MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION);
41MODULE_LICENSE("GPL"); 41MODULE_LICENSE("GPL");
42 42
43static int immediate_undock = 1;
44module_param(immediate_undock, bool, 0644);
45MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
46 "undock immediately when the undock button is pressed, 0 will cause"
47 " the driver to wait for userspace to write the undock sysfs file "
48 " before undocking");
49
43static struct atomic_notifier_head dock_notifier_list; 50static struct atomic_notifier_head dock_notifier_list;
44static struct platform_device *dock_device; 51static struct platform_device *dock_device;
45static char dock_device_name[] = "dock"; 52static char dock_device_name[] = "dock";
@@ -63,6 +70,7 @@ struct dock_dependent_device {
63}; 70};
64 71
65#define DOCK_DOCKING 0x00000001 72#define DOCK_DOCKING 0x00000001
73#define DOCK_UNDOCKING 0x00000002
66#define DOCK_EVENT 3 74#define DOCK_EVENT 3
67#define UNDOCK_EVENT 2 75#define UNDOCK_EVENT 2
68 76
@@ -420,6 +428,16 @@ static inline void complete_dock(struct dock_station *ds)
420 ds->last_dock_time = jiffies; 428 ds->last_dock_time = jiffies;
421} 429}
422 430
431static inline void begin_undock(struct dock_station *ds)
432{
433 ds->flags |= DOCK_UNDOCKING;
434}
435
436static inline void complete_undock(struct dock_station *ds)
437{
438 ds->flags &= ~(DOCK_UNDOCKING);
439}
440
423/** 441/**
424 * dock_in_progress - see if we are in the middle of handling a dock event 442 * dock_in_progress - see if we are in the middle of handling a dock event
425 * @ds: the dock station 443 * @ds: the dock station
@@ -550,7 +568,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
550 printk(KERN_ERR PREFIX "Unable to undock!\n"); 568 printk(KERN_ERR PREFIX "Unable to undock!\n");
551 return -EBUSY; 569 return -EBUSY;
552 } 570 }
553 571 complete_undock(ds);
554 return 0; 572 return 0;
555} 573}
556 574
@@ -594,7 +612,11 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
594 * to the driver who wish to hotplug. 612 * to the driver who wish to hotplug.
595 */ 613 */
596 case ACPI_NOTIFY_EJECT_REQUEST: 614 case ACPI_NOTIFY_EJECT_REQUEST:
597 handle_eject_request(ds, event); 615 begin_undock(ds);
616 if (immediate_undock)
617 handle_eject_request(ds, event);
618 else
619 dock_event(ds, event, UNDOCK_EVENT);
598 break; 620 break;
599 default: 621 default:
600 printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); 622 printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
@@ -653,6 +675,17 @@ static ssize_t show_docked(struct device *dev,
653DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); 675DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
654 676
655/* 677/*
678 * show_flags - read method for flags file in sysfs
679 */
680static ssize_t show_flags(struct device *dev,
681 struct device_attribute *attr, char *buf)
682{
683 return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags);
684
685}
686DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL);
687
688/*
656 * write_undock - write method for "undock" file in sysfs 689 * write_undock - write method for "undock" file in sysfs
657 */ 690 */
658static ssize_t write_undock(struct device *dev, struct device_attribute *attr, 691static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
@@ -717,6 +750,7 @@ static int dock_add(acpi_handle handle)
717 dock_station = NULL; 750 dock_station = NULL;
718 return PTR_ERR(dock_device); 751 return PTR_ERR(dock_device);
719 } 752 }
753
720 ret = device_create_file(&dock_device->dev, &dev_attr_docked); 754 ret = device_create_file(&dock_device->dev, &dev_attr_docked);
721 if (ret) { 755 if (ret) {
722 printk("Error %d adding sysfs file\n", ret); 756 printk("Error %d adding sysfs file\n", ret);
@@ -744,6 +778,17 @@ static int dock_add(acpi_handle handle)
744 dock_station = NULL; 778 dock_station = NULL;
745 return ret; 779 return ret;
746 } 780 }
781 ret = device_create_file(&dock_device->dev, &dev_attr_flags);
782 if (ret) {
783 printk("Error %d adding sysfs file\n", ret);
784 device_remove_file(&dock_device->dev, &dev_attr_docked);
785 device_remove_file(&dock_device->dev, &dev_attr_undock);
786 device_remove_file(&dock_device->dev, &dev_attr_uid);
787 platform_device_unregister(dock_device);
788 kfree(dock_station);
789 dock_station = NULL;
790 return ret;
791 }
747 792
748 /* Find dependent devices */ 793 /* Find dependent devices */
749 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 794 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
@@ -781,6 +826,7 @@ dock_add_err_unregister:
781 device_remove_file(&dock_device->dev, &dev_attr_docked); 826 device_remove_file(&dock_device->dev, &dev_attr_docked);
782 device_remove_file(&dock_device->dev, &dev_attr_undock); 827 device_remove_file(&dock_device->dev, &dev_attr_undock);
783 device_remove_file(&dock_device->dev, &dev_attr_uid); 828 device_remove_file(&dock_device->dev, &dev_attr_uid);
829 device_remove_file(&dock_device->dev, &dev_attr_flags);
784 platform_device_unregister(dock_device); 830 platform_device_unregister(dock_device);
785 kfree(dock_station); 831 kfree(dock_station);
786 dock_station = NULL; 832 dock_station = NULL;
@@ -814,6 +860,7 @@ static int dock_remove(void)
814 device_remove_file(&dock_device->dev, &dev_attr_docked); 860 device_remove_file(&dock_device->dev, &dev_attr_docked);
815 device_remove_file(&dock_device->dev, &dev_attr_undock); 861 device_remove_file(&dock_device->dev, &dev_attr_undock);
816 device_remove_file(&dock_device->dev, &dev_attr_uid); 862 device_remove_file(&dock_device->dev, &dev_attr_uid);
863 device_remove_file(&dock_device->dev, &dev_attr_flags);
817 platform_device_unregister(dock_device); 864 platform_device_unregister(dock_device);
818 865
819 /* free dock station memory */ 866 /* free dock station memory */