diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/misc/thinkpad_acpi.c | 127 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.h | 2 |
2 files changed, 129 insertions, 0 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index a56526500c18..83a8d984e709 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -706,6 +706,108 @@ static struct ibm_struct thinkpad_acpi_driver_data = { | |||
706 | static int hotkey_orig_status; | 706 | static int hotkey_orig_status; |
707 | static int hotkey_orig_mask; | 707 | static int hotkey_orig_mask; |
708 | 708 | ||
709 | static struct attribute_set *hotkey_dev_attributes = NULL; | ||
710 | |||
711 | /* sysfs hotkey enable ------------------------------------------------- */ | ||
712 | static ssize_t hotkey_enable_show(struct device *dev, | ||
713 | struct device_attribute *attr, | ||
714 | char *buf) | ||
715 | { | ||
716 | int res, status, mask; | ||
717 | |||
718 | res = hotkey_get(&status, &mask); | ||
719 | if (res) | ||
720 | return res; | ||
721 | |||
722 | return snprintf(buf, PAGE_SIZE, "%d\n", status); | ||
723 | } | ||
724 | |||
725 | static ssize_t hotkey_enable_store(struct device *dev, | ||
726 | struct device_attribute *attr, | ||
727 | const char *buf, size_t count) | ||
728 | { | ||
729 | unsigned long t; | ||
730 | int res, status, mask; | ||
731 | |||
732 | if (parse_strtoul(buf, 1, &t)) | ||
733 | return -EINVAL; | ||
734 | |||
735 | res = hotkey_get(&status, &mask); | ||
736 | if (!res) | ||
737 | res = hotkey_set(t, mask); | ||
738 | |||
739 | return (res) ? res : count; | ||
740 | } | ||
741 | |||
742 | static struct device_attribute dev_attr_hotkey_enable = | ||
743 | __ATTR(enable, S_IWUSR | S_IRUGO, | ||
744 | hotkey_enable_show, hotkey_enable_store); | ||
745 | |||
746 | /* sysfs hotkey mask --------------------------------------------------- */ | ||
747 | static ssize_t hotkey_mask_show(struct device *dev, | ||
748 | struct device_attribute *attr, | ||
749 | char *buf) | ||
750 | { | ||
751 | int res, status, mask; | ||
752 | |||
753 | res = hotkey_get(&status, &mask); | ||
754 | if (res) | ||
755 | return res; | ||
756 | |||
757 | return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask); | ||
758 | } | ||
759 | |||
760 | static ssize_t hotkey_mask_store(struct device *dev, | ||
761 | struct device_attribute *attr, | ||
762 | const char *buf, size_t count) | ||
763 | { | ||
764 | unsigned long t; | ||
765 | int res, status, mask; | ||
766 | |||
767 | if (parse_strtoul(buf, 0xffff, &t)) | ||
768 | return -EINVAL; | ||
769 | |||
770 | res = hotkey_get(&status, &mask); | ||
771 | if (!res) | ||
772 | hotkey_set(status, t); | ||
773 | |||
774 | return (res) ? res : count; | ||
775 | } | ||
776 | |||
777 | static struct device_attribute dev_attr_hotkey_mask = | ||
778 | __ATTR(mask, S_IWUSR | S_IRUGO, | ||
779 | hotkey_mask_show, hotkey_mask_store); | ||
780 | |||
781 | /* sysfs hotkey bios_enabled ------------------------------------------- */ | ||
782 | static ssize_t hotkey_bios_enabled_show(struct device *dev, | ||
783 | struct device_attribute *attr, | ||
784 | char *buf) | ||
785 | { | ||
786 | return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status); | ||
787 | } | ||
788 | |||
789 | static struct device_attribute dev_attr_hotkey_bios_enabled = | ||
790 | __ATTR(bios_enabled, S_IRUGO, hotkey_bios_enabled_show, NULL); | ||
791 | |||
792 | /* sysfs hotkey bios_mask ---------------------------------------------- */ | ||
793 | static ssize_t hotkey_bios_mask_show(struct device *dev, | ||
794 | struct device_attribute *attr, | ||
795 | char *buf) | ||
796 | { | ||
797 | return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask); | ||
798 | } | ||
799 | |||
800 | static struct device_attribute dev_attr_hotkey_bios_mask = | ||
801 | __ATTR(bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); | ||
802 | |||
803 | /* --------------------------------------------------------------------- */ | ||
804 | |||
805 | static struct attribute *hotkey_mask_attributes[] = { | ||
806 | &dev_attr_hotkey_mask.attr, | ||
807 | &dev_attr_hotkey_bios_enabled.attr, | ||
808 | &dev_attr_hotkey_bios_mask.attr, | ||
809 | }; | ||
810 | |||
709 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 811 | static int __init hotkey_init(struct ibm_init_struct *iibm) |
710 | { | 812 | { |
711 | int res; | 813 | int res; |
@@ -722,6 +824,15 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
722 | str_supported(tp_features.hotkey)); | 824 | str_supported(tp_features.hotkey)); |
723 | 825 | ||
724 | if (tp_features.hotkey) { | 826 | if (tp_features.hotkey) { |
827 | hotkey_dev_attributes = create_attr_set(4, | ||
828 | TPACPI_HOTKEY_SYSFS_GROUP); | ||
829 | if (!hotkey_dev_attributes) | ||
830 | return -ENOMEM; | ||
831 | res = add_to_attr_set(hotkey_dev_attributes, | ||
832 | &dev_attr_hotkey_enable.attr); | ||
833 | if (res) | ||
834 | return res; | ||
835 | |||
725 | /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, | 836 | /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, |
726 | A30, R30, R31, T20-22, X20-21, X22-24 */ | 837 | A30, R30, R31, T20-22, X20-21, X22-24 */ |
727 | tp_features.hotkey_mask = | 838 | tp_features.hotkey_mask = |
@@ -731,6 +842,16 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
731 | str_supported(tp_features.hotkey_mask)); | 842 | str_supported(tp_features.hotkey_mask)); |
732 | 843 | ||
733 | res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask); | 844 | res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask); |
845 | if (!res && tp_features.hotkey_mask) { | ||
846 | res = add_many_to_attr_set(hotkey_dev_attributes, | ||
847 | hotkey_mask_attributes, | ||
848 | ARRAY_SIZE(hotkey_mask_attributes)); | ||
849 | } | ||
850 | if (!res) | ||
851 | res = register_attr_set_with_sysfs( | ||
852 | hotkey_dev_attributes, | ||
853 | &tpacpi_pdev->dev.kobj); | ||
854 | |||
734 | if (res) | 855 | if (res) |
735 | return res; | 856 | return res; |
736 | } | 857 | } |
@@ -748,6 +869,11 @@ static void hotkey_exit(void) | |||
748 | if (res) | 869 | if (res) |
749 | printk(IBM_ERR "failed to restore hotkey to BIOS defaults\n"); | 870 | printk(IBM_ERR "failed to restore hotkey to BIOS defaults\n"); |
750 | } | 871 | } |
872 | |||
873 | if (hotkey_dev_attributes) { | ||
874 | delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); | ||
875 | hotkey_dev_attributes = NULL; | ||
876 | } | ||
751 | } | 877 | } |
752 | 878 | ||
753 | static void hotkey_notify(struct ibm_struct *ibm, u32 event) | 879 | static void hotkey_notify(struct ibm_struct *ibm, u32 event) |
@@ -798,6 +924,7 @@ static int hotkey_set(int status, int mask) | |||
798 | return 0; | 924 | return 0; |
799 | } | 925 | } |
800 | 926 | ||
927 | /* procfs -------------------------------------------------------------- */ | ||
801 | static int hotkey_read(char *p) | 928 | static int hotkey_read(char *p) |
802 | { | 929 | { |
803 | int res, status, mask; | 930 | int res, status, mask; |
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index a9e709368256..7615adb381c8 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h | |||
@@ -414,6 +414,8 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc); | |||
414 | * Hotkey subdriver | 414 | * Hotkey subdriver |
415 | */ | 415 | */ |
416 | 416 | ||
417 | #define TPACPI_HOTKEY_SYSFS_GROUP "hotkey" | ||
418 | |||
417 | static int hotkey_orig_status; | 419 | static int hotkey_orig_status; |
418 | static int hotkey_orig_mask; | 420 | static int hotkey_orig_mask; |
419 | 421 | ||