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>

authored by Henrique de Moraes Holschuh and committed by Len Brown ff80f137 0d4cbb5e

+163 -94
+75 -17
Documentation/thinkpad-acpi.txt
··· 161 161 firmware that such a driver is present, and modifies how the ThinkPad 162 162 firmware will behave in many situations. 163 163 164 + The driver enables the hot key feature automatically when loaded. The 165 + feature can later be disabled and enabled back at runtime. The driver 166 + will also restore the hot key feature to its previous state and mask 167 + when it is unloaded. 168 + 164 169 When the hotkey feature is enabled and the hot key mask is set (see 165 - below), the various hot keys either generate ACPI events in the 166 - following format: 170 + below), the driver will report HKEY events in the following format: 167 171 168 172 ibm/hotkey HKEY 00000080 0000xxxx 169 173 170 - or events over the input layer. The input layer support accepts the 171 - standard IOCTLs to remap the keycodes assigned to each hotkey. 174 + Some of these events refer to hot key presses, but not all. 172 175 173 - When the input device is open, the driver will suppress any ACPI hot key 174 - events that get translated into a meaningful input layer event, in order 175 - to avoid sending duplicate events to userspace. Hot keys that are 176 - mapped to KEY_RESERVED in the keymap are not translated, and will always 177 - generate an ACPI ibm/hotkey HKEY event, and no input layer events. 176 + The driver will generate events over the input layer for hot keys and 177 + radio switches, and over the ACPI netlink layer for other events. The 178 + input layer support accepts the standard IOCTLs to remap the keycodes 179 + assigned to each hot key. 178 180 179 181 The hot key bit mask allows some control over which hot keys generate 180 182 events. If a key is "masked" (bit set to 0 in the mask), the firmware ··· 257 255 attribute will read 0 if the switch is in the "radios 258 256 disabled" postition, and 1 if the switch is in the 259 257 "radios enabled" position. 258 + 259 + hotkey_report_mode: 260 + Returns the state of the procfs ACPI event report mode 261 + filter for hot keys. If it is set to 1 (the default), 262 + all hot key presses are reported both through the input 263 + layer and also as ACPI events through procfs (but not 264 + through netlink). If it is set to 2, hot key presses 265 + are reported only through the input layer. 266 + 267 + This attribute is read-only in kernels 2.6.23 or later, 268 + and read-write on earlier kernels. 269 + 270 + May return -EPERM (write access locked out by module 271 + parameter) or -EACCES (read-only). 260 272 261 273 input layer notes: 262 274 ··· 409 393 hot key press or release, but the firmware will do it for either one, not 410 394 both. 411 395 412 - If a key is mapped to KEY_RESERVED, it generates no input events at all, 413 - and it may generate a legacy thinkpad-acpi ACPI hotkey event. 414 - 396 + If a key is mapped to KEY_RESERVED, it generates no input events at all. 415 397 If a key is mapped to KEY_UNKNOWN, it generates an input event that 416 - includes an scan code, and it may also generate a legacy thinkpad-acpi 417 - ACPI hotkey event. 418 - 419 - If a key is mapped to anything else, it will only generate legacy 420 - thinkpad-acpi ACPI hotkey events if nobody has opened the input device. 398 + includes an scan code. If a key is mapped to anything else, it will 399 + generate input device EV_KEY events. 421 400 422 401 Non hot-key ACPI HKEY event map: 423 402 0x5001 Lid closed 424 403 0x5002 Lid opened 425 404 0x7000 Radio Switch may have changed state 405 + 406 + The above events are not propagated by the driver, except for legacy 407 + compatibility purposes when hotkey_report_mode is set to 1. 408 + 409 + Compatibility notes: 410 + 411 + ibm-acpi and thinkpad-acpi 0.15 (mainline kernels before 2.6.23) never 412 + supported the input layer, and sent events over the procfs ACPI event 413 + interface. 414 + 415 + To avoid sending duplicate events over the input layer and the ACPI 416 + event interface, thinkpad-acpi 0.16 implements a module parameter 417 + (hotkey_report_mode), and also a sysfs device attribute with the same 418 + name. 419 + 420 + Make no mistake here: userspace is expected to switch to using the input 421 + layer interface of thinkpad-acpi, together with the ACPI netlink event 422 + interface in kernels 2.6.23 and later, or with the ACPI procfs event 423 + interface in kernels 2.6.22 and earlier. 424 + 425 + If no hotkey_report_mode module parameter is specified (or it is set to 426 + zero), the driver defaults to mode 1 (see below), and on kernels 2.6.22 427 + and earlier, also allows one to change the hotkey_report_mode through 428 + sysfs. In kernels 2.6.23 and later, where the netlink ACPI event 429 + interface is available, hotkey_report_mode cannot be changed through 430 + sysfs (it is read-only). 431 + 432 + If the hotkey_report_mode module parameter is set to 1 or 2, it cannot 433 + be changed later through sysfs (any writes will return -EPERM to signal 434 + that hotkey_report_mode was locked. On 2.6.23 and later, where 435 + hotkey_report_mode cannot be changed at all, writes will return -EACES). 436 + 437 + hotkey_report_mode set to 1 makes the driver export through the procfs 438 + ACPI event interface all hot key presses (which are *also* sent to the 439 + input layer). This is a legacy compatibility behaviour, and it is also 440 + the default mode of operation for the driver. 441 + 442 + hotkey_report_mode set to 2 makes the driver filter out the hot key 443 + presses from the procfs ACPI event interface, so these events will only 444 + be sent through the input layer. Userspace that has been updated to use 445 + the thinkpad-acpi input layer interface should set hotkey_report_mode to 446 + 2. 447 + 448 + Hot key press events are never sent to the ACPI netlink event interface. 449 + Really up-to-date userspace under kernel 2.6.23 and later is to use the 450 + netlink interface and the input layer interface, and don't bother at all 451 + with hotkey_report_mode. 426 452 427 453 428 454 Bluetooth
-20
drivers/misc/Kconfig
··· 202 202 203 203 If you are not sure, say Y here. 204 204 205 - config THINKPAD_ACPI_INPUT_ENABLED 206 - bool "Enable input layer support by default" 207 - depends on THINKPAD_ACPI 208 - default n 209 - ---help--- 210 - This option enables thinkpad-acpi hot key handling over the input 211 - layer at driver load time. When it is unset, the driver does not 212 - enable hot key handling by default, and also starts up with a mostly 213 - empty keymap. 214 - 215 - This option should be enabled if you have a new enough HAL or other 216 - userspace support that properly handles the thinkpad-acpi event 217 - device. It auto-tunes the hot key support to those reported by the 218 - firmware and enables it automatically. 219 - 220 - If unsure, say N here to retain the old behaviour of ibm-acpi, and 221 - thinkpad-acpi up to kernel 2.6.21: userspace will have to enable and 222 - set up the thinkpad-acpi hot key handling using the sysfs interace 223 - after loading the driver. 224 - 225 205 226 206 endif # MISC_DEVICES
+87 -57
drivers/misc/thinkpad_acpi.c
··· 906 906 static struct device_attribute dev_attr_hotkey_radio_sw = 907 907 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); 908 908 909 + /* sysfs hotkey report_mode -------------------------------------------- */ 910 + static 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 + 918 + static 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 911 - static struct attribute *hotkey_mask_attributes[] = { 923 + static struct attribute *hotkey_attributes[] __initdata = { 924 + &dev_attr_hotkey_enable.attr, 925 + &dev_attr_hotkey_report_mode.attr, 926 + }; 927 + 928 + static struct attribute *hotkey_mask_attributes[] __initdata = { 912 929 &dev_attr_hotkey_mask.attr, 913 930 &dev_attr_hotkey_bios_enabled.attr, 914 931 &dev_attr_hotkey_bios_mask.attr, ··· 1004 987 str_supported(tp_features.hotkey)); 1005 988 1006 989 if (tp_features.hotkey) { 1007 - hotkey_dev_attributes = create_attr_set(7, NULL); 990 + hotkey_dev_attributes = create_attr_set(8, NULL); 1008 991 if (!hotkey_dev_attributes) 1009 992 return -ENOMEM; 1010 - res = add_to_attr_set(hotkey_dev_attributes, 1011 - &dev_attr_hotkey_enable.attr); 993 + res = add_many_to_attr_set(hotkey_dev_attributes, 994 + hotkey_attributes, 995 + ARRAY_SIZE(hotkey_attributes)); 1012 996 if (res) 1013 997 return res; 1014 998 ··· 1073 1055 TPACPI_HOTKEY_MAP_SIZE); 1074 1056 } 1075 1057 1076 - #ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED 1077 - for (i = 0; i < 12; i++) 1078 - hotkey_keycode_map[i] = KEY_UNKNOWN; 1079 - #endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */ 1080 - 1081 1058 set_bit(EV_KEY, tpacpi_inputdev->evbit); 1082 1059 set_bit(EV_MSC, tpacpi_inputdev->evbit); 1083 1060 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); ··· 1094 1081 set_bit(SW_RADIO, tpacpi_inputdev->swbit); 1095 1082 } 1096 1083 1097 - #ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED 1098 1084 dbg_printk(TPACPI_DBG_INIT, 1099 1085 "enabling hot key handling\n"); 1100 1086 res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask) 1101 1087 | hotkey_orig_mask); 1102 1088 if (res) 1103 1089 return res; 1104 - #endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */ 1090 + 1091 + dbg_printk(TPACPI_DBG_INIT, 1092 + "legacy hot key reporting over procfs %s\n", 1093 + (hotkey_report_mode < 2) ? 1094 + "enabled" : "disabled"); 1105 1095 } 1106 1096 1107 1097 return (tp_features.hotkey)? 0 : 1; ··· 1158 1142 { 1159 1143 u32 hkey; 1160 1144 unsigned int keycode, scancode; 1161 - int sendacpi = 1; 1145 + int send_acpi_ev = 0; 1162 1146 1163 1147 if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { 1164 - if (tpacpi_inputdev->users > 0) { 1165 - switch (hkey >> 12) { 1166 - case 1: 1167 - /* 0x1000-0x1FFF: key presses */ 1168 - scancode = hkey & 0xfff; 1169 - if (scancode > 0 && scancode < 0x21) { 1170 - scancode--; 1171 - keycode = hotkey_keycode_map[scancode]; 1172 - tpacpi_input_send_key(scancode, keycode); 1173 - sendacpi = (keycode == KEY_RESERVED 1174 - || keycode == KEY_UNKNOWN); 1175 - } else { 1176 - printk(IBM_ERR 1177 - "hotkey 0x%04x out of range for keyboard map\n", 1178 - hkey); 1179 - } 1180 - break; 1181 - case 5: 1182 - /* 0x5000-0x5FFF: LID */ 1183 - /* we don't handle it through this path, just 1184 - * eat up known LID events */ 1185 - if (hkey != 0x5001 && hkey != 0x5002) { 1186 - printk(IBM_ERR 1187 - "unknown LID-related hotkey event: 0x%04x\n", 1188 - hkey); 1189 - } 1190 - break; 1191 - case 7: 1192 - /* 0x7000-0x7FFF: misc */ 1193 - if (tp_features.hotkey_wlsw && hkey == 0x7000) { 1194 - tpacpi_input_send_radiosw(); 1195 - sendacpi = 0; 1196 - break; 1197 - } 1198 - /* fallthrough to default */ 1199 - default: 1200 - /* case 2: dock-related */ 1201 - /* 0x2305 - T43 waking up due to bay lever eject while aslept */ 1202 - /* case 3: ultra-bay related. maybe bay in dock? */ 1203 - /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */ 1204 - printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey); 1148 + switch (hkey >> 12) { 1149 + case 1: 1150 + /* 0x1000-0x1FFF: key presses */ 1151 + scancode = hkey & 0xfff; 1152 + if (scancode > 0 && scancode < 0x21) { 1153 + scancode--; 1154 + keycode = hotkey_keycode_map[scancode]; 1155 + tpacpi_input_send_key(scancode, keycode); 1156 + } else { 1157 + printk(IBM_ERR 1158 + "hotkey 0x%04x out of range for keyboard map\n", 1159 + hkey); 1160 + send_acpi_ev = 1; 1205 1161 } 1162 + break; 1163 + case 5: 1164 + /* 0x5000-0x5FFF: LID */ 1165 + /* we don't handle it through this path, just 1166 + * eat up known LID events */ 1167 + if (hkey != 0x5001 && hkey != 0x5002) { 1168 + printk(IBM_ERR 1169 + "unknown LID-related hotkey event: 0x%04x\n", 1170 + hkey); 1171 + send_acpi_ev = 1; 1172 + } 1173 + break; 1174 + case 7: 1175 + /* 0x7000-0x7FFF: misc */ 1176 + if (tp_features.hotkey_wlsw && hkey == 0x7000) { 1177 + tpacpi_input_send_radiosw(); 1178 + break; 1179 + } 1180 + /* fallthrough to default */ 1181 + default: 1182 + /* case 2: dock-related */ 1183 + /* 0x2305 - T43 waking up due to bay lever eject while aslept */ 1184 + /* case 3: ultra-bay related. maybe bay in dock? */ 1185 + /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */ 1186 + printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey); 1187 + send_acpi_ev = 1; 1206 1188 } 1207 - 1208 - if (sendacpi) 1209 - acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); 1210 1189 } else { 1211 1190 printk(IBM_ERR "unknown hotkey notification event %d\n", event); 1212 - acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); 1191 + hkey = 0; 1192 + send_acpi_ev = 1; 1193 + } 1194 + 1195 + /* Legacy events */ 1196 + if (send_acpi_ev || hotkey_report_mode < 2) 1197 + acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); 1198 + 1199 + /* netlink events */ 1200 + if (send_acpi_ev) { 1201 + acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, 1202 + ibm->acpi->device->dev.bus_id, 1203 + event, hkey); 1213 1204 } 1214 1205 } 1215 1206 ··· 4646 4623 static int brightness_mode; 4647 4624 module_param_named(brightness_mode, brightness_mode, int, 0); 4648 4625 4626 + static unsigned int hotkey_report_mode; 4627 + module_param(hotkey_report_mode, uint, 0); 4628 + 4649 4629 #define IBM_PARAM(feature) \ 4650 4630 module_param_call(feature, set_ibm_param, NULL, NULL, 0) 4651 4631 ··· 4673 4647 static int __init thinkpad_acpi_module_init(void) 4674 4648 { 4675 4649 int ret, i; 4650 + 4651 + /* Parameter checking */ 4652 + if (hotkey_report_mode > 2) 4653 + return -EINVAL; 4676 4654 4677 4655 /* Driver-level probe */ 4678 4656
+1
drivers/misc/thinkpad_acpi.h
··· 181 181 static int experimental; 182 182 static u32 dbg_level; 183 183 static int force_load; 184 + static unsigned int hotkey_report_mode; 184 185 185 186 static int thinkpad_acpi_module_init(void); 186 187 static void thinkpad_acpi_module_exit(void);