aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/thinkpad_acpi.c
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2007-09-04 10:13:15 -0400
committerLen Brown <len.brown@intel.com>2007-09-17 00:58:19 -0400
commitff80f1370f2eff7dd7a828cf2416bf7be697247e (patch)
tree752fbf04cfc7f347e26a16050cb554051bc13dc6 /drivers/misc/thinkpad_acpi.c
parent0d4cbb5e7f60b2f1a4d8b7f6ea4cc264262c7a01 (diff)
ACPI: thinkpad-acpi: revert new 2.6.23 CONFIG_THINKPAD_ACPI_INPUT_ENABLED option
Revert new 2.6.23 CONFIG_THINKPAD_ACPI_INPUT_ENABLED Kconfig option because it would create a legacy we don't want to support. CONFIG_THINKPAD_ACPI_INPUT_ENABLED was added to try to fix an issue that is now moot with the addition of the netlink ACPI event report interface to the ACPI core. Now that ACPI core can send events over netlink, we can use a different strategy to keep backwards compatibility with older userspace, without the need for the CONFIG_THINKPAD_ACPI_INPUT_ENABLED games. And it arrived before CONFIG_THINKPAD_ACPI_INPUT_ENABLED made it to a stable mainline kernel, even, which is Good. This patch is in sync with some changes to thinkpad-acpi backports, that will keep things sane for userspace across different combinations of kernel versions, thinkpad-acpi backports (or the lack thereof), and userspace capabilities: Unless a module parameter is used, thinkpad-acpi will now behave in such a way that it will work well (by default) with userspace that still uses only the old ACPI procfs event interface and doesn't care for thinkpad-acpi input devices. It will also always work well with userspace that has been updated to use both the thinkpad-acpi input devices, and ACPI core netlink event interface, regardless of any module parameter. The module parameter was added to allow thinkpad-acpi to work with userspace that has been partially updated to use thinkpad-acpi input devices, but not the new ACPI core netlink event interface. To use this mode of hot key reporting, one has to specify the hotkey_report_mode=2 module parameter. The thinkpad-acpi driver exports the value of hotkey_report_mode through sysfs, as well. thinkpad-acpi backports to older kernels, that do not support the new ACPI core netlink interface, have code to allow userspace to switch hotkey_report_mode at runtime through sysfs. This capability will not be provided in mainline thinkpad-acpi as it is not needed there. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Cc: Michael S. Tsirkin <mst@dev.mellanox.co.il> Cc: Hugh Dickins <hugh@veritas.com> Cc: Richard Hughes <hughsient@gmail.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/misc/thinkpad_acpi.c')
-rw-r--r--drivers/misc/thinkpad_acpi.c142
1 files changed, 86 insertions, 56 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index bb8956d0c104..3d849d13657d 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -906,9 +906,26 @@ static ssize_t hotkey_radio_sw_show(struct device *dev,
906static struct device_attribute dev_attr_hotkey_radio_sw = 906static struct device_attribute dev_attr_hotkey_radio_sw =
907 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); 907 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
908 908
909/* sysfs hotkey report_mode -------------------------------------------- */
910static ssize_t hotkey_report_mode_show(struct device *dev,
911 struct device_attribute *attr,
912 char *buf)
913{
914 return snprintf(buf, PAGE_SIZE, "%d\n",
915 (hotkey_report_mode != 0) ? hotkey_report_mode : 1);
916}
917
918static struct device_attribute dev_attr_hotkey_report_mode =
919 __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL);
920
909/* --------------------------------------------------------------------- */ 921/* --------------------------------------------------------------------- */
910 922
911static struct attribute *hotkey_mask_attributes[] = { 923static struct attribute *hotkey_attributes[] __initdata = {
924 &dev_attr_hotkey_enable.attr,
925 &dev_attr_hotkey_report_mode.attr,
926};
927
928static struct attribute *hotkey_mask_attributes[] __initdata = {
912 &dev_attr_hotkey_mask.attr, 929 &dev_attr_hotkey_mask.attr,
913 &dev_attr_hotkey_bios_enabled.attr, 930 &dev_attr_hotkey_bios_enabled.attr,
914 &dev_attr_hotkey_bios_mask.attr, 931 &dev_attr_hotkey_bios_mask.attr,
@@ -987,11 +1004,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
987 str_supported(tp_features.hotkey)); 1004 str_supported(tp_features.hotkey));
988 1005
989 if (tp_features.hotkey) { 1006 if (tp_features.hotkey) {
990 hotkey_dev_attributes = create_attr_set(7, NULL); 1007 hotkey_dev_attributes = create_attr_set(8, NULL);
991 if (!hotkey_dev_attributes) 1008 if (!hotkey_dev_attributes)
992 return -ENOMEM; 1009 return -ENOMEM;
993 res = add_to_attr_set(hotkey_dev_attributes, 1010 res = add_many_to_attr_set(hotkey_dev_attributes,
994 &dev_attr_hotkey_enable.attr); 1011 hotkey_attributes,
1012 ARRAY_SIZE(hotkey_attributes));
995 if (res) 1013 if (res)
996 return res; 1014 return res;
997 1015
@@ -1055,11 +1073,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
1055 TPACPI_HOTKEY_MAP_SIZE); 1073 TPACPI_HOTKEY_MAP_SIZE);
1056 } 1074 }
1057 1075
1058#ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
1059 for (i = 0; i < 12; i++)
1060 hotkey_keycode_map[i] = KEY_UNKNOWN;
1061#endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */
1062
1063 set_bit(EV_KEY, tpacpi_inputdev->evbit); 1076 set_bit(EV_KEY, tpacpi_inputdev->evbit);
1064 set_bit(EV_MSC, tpacpi_inputdev->evbit); 1077 set_bit(EV_MSC, tpacpi_inputdev->evbit);
1065 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); 1078 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
@@ -1081,14 +1094,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
1081 set_bit(SW_RADIO, tpacpi_inputdev->swbit); 1094 set_bit(SW_RADIO, tpacpi_inputdev->swbit);
1082 } 1095 }
1083 1096
1084#ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
1085 dbg_printk(TPACPI_DBG_INIT, 1097 dbg_printk(TPACPI_DBG_INIT,
1086 "enabling hot key handling\n"); 1098 "enabling hot key handling\n");
1087 res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask) 1099 res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask)
1088 | hotkey_orig_mask); 1100 | hotkey_orig_mask);
1089 if (res) 1101 if (res)
1090 return res; 1102 return res;
1091#endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */ 1103
1104 dbg_printk(TPACPI_DBG_INIT,
1105 "legacy hot key reporting over procfs %s\n",
1106 (hotkey_report_mode < 2) ?
1107 "enabled" : "disabled");
1092 } 1108 }
1093 1109
1094 return (tp_features.hotkey)? 0 : 1; 1110 return (tp_features.hotkey)? 0 : 1;
@@ -1142,58 +1158,65 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
1142{ 1158{
1143 u32 hkey; 1159 u32 hkey;
1144 unsigned int keycode, scancode; 1160 unsigned int keycode, scancode;
1145 int sendacpi = 1; 1161 int send_acpi_ev = 0;
1146 1162
1147 if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { 1163 if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
1148 if (tpacpi_inputdev->users > 0) { 1164 switch (hkey >> 12) {
1149 switch (hkey >> 12) { 1165 case 1:
1150 case 1: 1166 /* 0x1000-0x1FFF: key presses */
1151 /* 0x1000-0x1FFF: key presses */ 1167 scancode = hkey & 0xfff;
1152 scancode = hkey & 0xfff; 1168 if (scancode > 0 && scancode < 0x21) {
1153 if (scancode > 0 && scancode < 0x21) { 1169 scancode--;
1154 scancode--; 1170 keycode = hotkey_keycode_map[scancode];
1155 keycode = hotkey_keycode_map[scancode]; 1171 tpacpi_input_send_key(scancode, keycode);
1156 tpacpi_input_send_key(scancode, keycode); 1172 } else {
1157 sendacpi = (keycode == KEY_RESERVED 1173 printk(IBM_ERR
1158 || keycode == KEY_UNKNOWN); 1174 "hotkey 0x%04x out of range for keyboard map\n",
1159 } else { 1175 hkey);
1160 printk(IBM_ERR 1176 send_acpi_ev = 1;
1161 "hotkey 0x%04x out of range for keyboard map\n", 1177 }
1162 hkey); 1178 break;
1163 } 1179 case 5:
1164 break; 1180 /* 0x5000-0x5FFF: LID */
1165 case 5: 1181 /* we don't handle it through this path, just
1166 /* 0x5000-0x5FFF: LID */ 1182 * eat up known LID events */
1167 /* we don't handle it through this path, just 1183 if (hkey != 0x5001 && hkey != 0x5002) {
1168 * eat up known LID events */ 1184 printk(IBM_ERR
1169 if (hkey != 0x5001 && hkey != 0x5002) { 1185 "unknown LID-related hotkey event: 0x%04x\n",
1170 printk(IBM_ERR 1186 hkey);
1171 "unknown LID-related hotkey event: 0x%04x\n", 1187 send_acpi_ev = 1;
1172 hkey); 1188 }
1173 } 1189 break;
1190 case 7:
1191 /* 0x7000-0x7FFF: misc */
1192 if (tp_features.hotkey_wlsw && hkey == 0x7000) {
1193 tpacpi_input_send_radiosw();
1174 break; 1194 break;
1175 case 7:
1176 /* 0x7000-0x7FFF: misc */
1177 if (tp_features.hotkey_wlsw && hkey == 0x7000) {
1178 tpacpi_input_send_radiosw();
1179 sendacpi = 0;
1180 break;
1181 }
1182 /* fallthrough to default */
1183 default:
1184 /* case 2: dock-related */
1185 /* 0x2305 - T43 waking up due to bay lever eject while aslept */
1186 /* case 3: ultra-bay related. maybe bay in dock? */
1187 /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */
1188 printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey);
1189 } 1195 }
1196 /* fallthrough to default */
1197 default:
1198 /* case 2: dock-related */
1199 /* 0x2305 - T43 waking up due to bay lever eject while aslept */
1200 /* case 3: ultra-bay related. maybe bay in dock? */
1201 /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */
1202 printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey);
1203 send_acpi_ev = 1;
1190 } 1204 }
1191
1192 if (sendacpi)
1193 acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
1194 } else { 1205 } else {
1195 printk(IBM_ERR "unknown hotkey notification event %d\n", event); 1206 printk(IBM_ERR "unknown hotkey notification event %d\n", event);
1196 acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); 1207 hkey = 0;
1208 send_acpi_ev = 1;
1209 }
1210
1211 /* Legacy events */
1212 if (send_acpi_ev || hotkey_report_mode < 2)
1213 acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
1214
1215 /* netlink events */
1216 if (send_acpi_ev) {
1217 acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
1218 ibm->acpi->device->dev.bus_id,
1219 event, hkey);
1197 } 1220 }
1198} 1221}
1199 1222
@@ -4623,6 +4646,9 @@ module_param_named(fan_control, fan_control_allowed, bool, 0);
4623static int brightness_mode; 4646static int brightness_mode;
4624module_param_named(brightness_mode, brightness_mode, int, 0); 4647module_param_named(brightness_mode, brightness_mode, int, 0);
4625 4648
4649static unsigned int hotkey_report_mode;
4650module_param(hotkey_report_mode, uint, 0);
4651
4626#define IBM_PARAM(feature) \ 4652#define IBM_PARAM(feature) \
4627 module_param_call(feature, set_ibm_param, NULL, NULL, 0) 4653 module_param_call(feature, set_ibm_param, NULL, NULL, 0)
4628 4654
@@ -4648,6 +4674,10 @@ static int __init thinkpad_acpi_module_init(void)
4648{ 4674{
4649 int ret, i; 4675 int ret, i;
4650 4676
4677 /* Parameter checking */
4678 if (hotkey_report_mode > 2)
4679 return -EINVAL;
4680
4651 /* Driver-level probe */ 4681 /* Driver-level probe */
4652 4682
4653 get_thinkpad_model_data(&thinkpad_id); 4683 get_thinkpad_model_data(&thinkpad_id);