aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */