aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2007-07-18 22:45:29 -0400
committerLen Brown <len.brown@intel.com>2007-07-21 23:37:50 -0400
commitae92bd17ff703b3703562148c73b4d6833e6a326 (patch)
tree8e987e553f7c4d4a54be326e2b5310c32a6c1faf /drivers/misc
parentb8b26402cb711de5d3bbd4515b91b6d863fea259 (diff)
ACPI: thinkpad-acpi: enable more hotkeys
Revise ACPI HKEY functionality to better interface with the firmware, and enable up to 32 regular hotkeys, instead of just 16 of them. Ouch. This takes care of most keys one used to have to do CMOS NVRAM polling on, and should drop the need for tpb, thinkpad-keys, and other such 5Hz NVRAM polling power vampires on most modern ThinkPads ;-) And, just to add insult to injury, this was sort of working since forever through the procfs interface, but nobody noticed or tried an echo 0xffffffff > /proc/acpi/ibm/hotkey and told me it would generate weird events. ARGH! Thanks to Richard Hughes for kicking off the work that ended up with this discovery, and to Matthew Garret for calling my attention to the fact that newer ThinkPads were indeed generating ACPI GPEs when such hot keys were pressed. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Cc: Richard Hughes <hughsient@gmail.com> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/thinkpad_acpi.c38
-rw-r--r--drivers/misc/thinkpad_acpi.h6
2 files changed, 25 insertions, 19 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 9f10b4694eda..450b1e5cd681 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -727,7 +727,7 @@ static struct ibm_struct thinkpad_acpi_driver_data = {
727 */ 727 */
728 728
729static int hotkey_orig_status; 729static int hotkey_orig_status;
730static int hotkey_orig_mask; 730static u32 hotkey_orig_mask;
731 731
732static struct attribute_set *hotkey_dev_attributes; 732static struct attribute_set *hotkey_dev_attributes;
733 733
@@ -736,7 +736,8 @@ static ssize_t hotkey_enable_show(struct device *dev,
736 struct device_attribute *attr, 736 struct device_attribute *attr,
737 char *buf) 737 char *buf)
738{ 738{
739 int res, status, mask; 739 int res, status;
740 u32 mask;
740 741
741 res = hotkey_get(&status, &mask); 742 res = hotkey_get(&status, &mask);
742 if (res) 743 if (res)
@@ -750,7 +751,8 @@ static ssize_t hotkey_enable_store(struct device *dev,
750 const char *buf, size_t count) 751 const char *buf, size_t count)
751{ 752{
752 unsigned long t; 753 unsigned long t;
753 int res, status, mask; 754 int res, status;
755 u32 mask;
754 756
755 if (parse_strtoul(buf, 1, &t)) 757 if (parse_strtoul(buf, 1, &t))
756 return -EINVAL; 758 return -EINVAL;
@@ -771,13 +773,14 @@ static ssize_t hotkey_mask_show(struct device *dev,
771 struct device_attribute *attr, 773 struct device_attribute *attr,
772 char *buf) 774 char *buf)
773{ 775{
774 int res, status, mask; 776 int res, status;
777 u32 mask;
775 778
776 res = hotkey_get(&status, &mask); 779 res = hotkey_get(&status, &mask);
777 if (res) 780 if (res)
778 return res; 781 return res;
779 782
780 return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask); 783 return snprintf(buf, PAGE_SIZE, "0x%08x\n", mask);
781} 784}
782 785
783static ssize_t hotkey_mask_store(struct device *dev, 786static ssize_t hotkey_mask_store(struct device *dev,
@@ -785,9 +788,10 @@ static ssize_t hotkey_mask_store(struct device *dev,
785 const char *buf, size_t count) 788 const char *buf, size_t count)
786{ 789{
787 unsigned long t; 790 unsigned long t;
788 int res, status, mask; 791 int res, status;
792 u32 mask;
789 793
790 if (parse_strtoul(buf, 0xffff, &t)) 794 if (parse_strtoul(buf, 0xffffffffUL, &t))
791 return -EINVAL; 795 return -EINVAL;
792 796
793 res = hotkey_get(&status, &mask); 797 res = hotkey_get(&status, &mask);
@@ -817,7 +821,7 @@ static ssize_t hotkey_bios_mask_show(struct device *dev,
817 struct device_attribute *attr, 821 struct device_attribute *attr,
818 char *buf) 822 char *buf)
819{ 823{
820 return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask); 824 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
821} 825}
822 826
823static struct device_attribute dev_attr_hotkey_bios_mask = 827static struct device_attribute dev_attr_hotkey_bios_mask =
@@ -902,10 +906,10 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
902{ 906{
903 int hkey; 907 int hkey;
904 908
905 if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) 909 if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
906 acpi_bus_generate_event(ibm->acpi->device, event, hkey); 910 acpi_bus_generate_event(ibm->acpi->device, event, hkey);
907 else { 911 } else {
908 printk(IBM_ERR "unknown hotkey event %d\n", event); 912 printk(IBM_ERR "unknown hotkey notification event %d\n", event);
909 acpi_bus_generate_event(ibm->acpi->device, event, 0); 913 acpi_bus_generate_event(ibm->acpi->device, event, 0);
910 } 914 }
911} 915}
@@ -913,7 +917,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
913/* 917/*
914 * Call with hotkey_mutex held 918 * Call with hotkey_mutex held
915 */ 919 */
916static int hotkey_get(int *status, int *mask) 920static int hotkey_get(int *status, u32 *mask)
917{ 921{
918 if (!acpi_evalf(hkey_handle, status, "DHKC", "d")) 922 if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
919 return -EIO; 923 return -EIO;
@@ -928,7 +932,7 @@ static int hotkey_get(int *status, int *mask)
928/* 932/*
929 * Call with hotkey_mutex held 933 * Call with hotkey_mutex held
930 */ 934 */
931static int hotkey_set(int status, int mask) 935static int hotkey_set(int status, u32 mask)
932{ 936{
933 int i; 937 int i;
934 938
@@ -949,7 +953,8 @@ static int hotkey_set(int status, int mask)
949/* procfs -------------------------------------------------------------- */ 953/* procfs -------------------------------------------------------------- */
950static int hotkey_read(char *p) 954static int hotkey_read(char *p)
951{ 955{
952 int res, status, mask; 956 int res, status;
957 u32 mask;
953 int len = 0; 958 int len = 0;
954 959
955 if (!tp_features.hotkey) { 960 if (!tp_features.hotkey) {
@@ -967,7 +972,7 @@ static int hotkey_read(char *p)
967 972
968 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); 973 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
969 if (tp_features.hotkey_mask) { 974 if (tp_features.hotkey_mask) {
970 len += sprintf(p + len, "mask:\t\t0x%04x\n", mask); 975 len += sprintf(p + len, "mask:\t\t0x%08x\n", mask);
971 len += sprintf(p + len, 976 len += sprintf(p + len,
972 "commands:\tenable, disable, reset, <mask>\n"); 977 "commands:\tenable, disable, reset, <mask>\n");
973 } else { 978 } else {
@@ -980,7 +985,8 @@ static int hotkey_read(char *p)
980 985
981static int hotkey_write(char *buf) 986static int hotkey_write(char *buf)
982{ 987{
983 int res, status, mask; 988 int res, status;
989 u32 mask;
984 char *cmd; 990 char *cmd;
985 int do_cmd = 0; 991 int do_cmd = 0;
986 992
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 72d62f2dabb9..e1a64f0aada9 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -415,14 +415,14 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc);
415 */ 415 */
416 416
417static int hotkey_orig_status; 417static int hotkey_orig_status;
418static int hotkey_orig_mask; 418static u32 hotkey_orig_mask;
419 419
420static struct mutex hotkey_mutex; 420static struct mutex hotkey_mutex;
421 421
422static int hotkey_init(struct ibm_init_struct *iibm); 422static int hotkey_init(struct ibm_init_struct *iibm);
423static void hotkey_exit(void); 423static void hotkey_exit(void);
424static int hotkey_get(int *status, int *mask); 424static int hotkey_get(int *status, u32 *mask);
425static int hotkey_set(int status, int mask); 425static int hotkey_set(int status, u32 mask);
426static void hotkey_notify(struct ibm_struct *ibm, u32 event); 426static void hotkey_notify(struct ibm_struct *ibm, u32 event);
427static int hotkey_read(char *p); 427static int hotkey_read(char *p);
428static int hotkey_write(char *buf); 428static int hotkey_write(char *buf);