aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2009-09-20 13:09:25 -0400
committerLen Brown <len.brown@intel.com>2009-09-20 13:48:13 -0400
commit0d922e3b84dc4923fc67901580a3c166006fba7a (patch)
treed7ee9009f4d423cee170fc41471922d1abcfe329 /drivers/platform
parent176dd98523fee4836210bc0834c8e3e6a93247bf (diff)
thinkpad-acpi: hotkey event driver update
Update the HKEY event driver to: 1. Handle better the second-gen firmware, which has no HKEY mask support but does report FN+F3, FN+F4 and FN+F12 without the need for NVRAM polling. a) always make the mask-related attributes available in sysfs; b) use DMI quirks to detect the second-gen firmware; c) properly report that FN+F3, FN+F4 and FN+F12 are enabled, and available even on mask-less second-gen firmware; 2. Decouple the issuing of hotkey events towards userspace from their reception from the firmware. ALSA mixer and brightness event reporting support will need this feature. 3. Clean up the mess in the hotkey driver a great deal. It is still very convoluted, and wants a full refactoring into a proper event API interface, but that is not going to happen today. 4. Fully reset firmware interface on resume (restore hotkey mask and status). 5. Stop losing polled events for no good reason when changing the mask and poll frequencies. We will still lose them when the hotkey_source_mask is changed, as well as any that happened between driver suspend and driver resume. The hotkey subdriver now has the notion of user-space-visible hotkey event mask, as well as of the set of "hotkey" events the driver needs (because brightness/volume change reports are not just keypress reports in most ThinkPad models). With this rewrite, the ABI level is bumped to 0x020500 should userspace need to know it is dealing with the updated hotkey subdriver. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c478
1 files changed, 302 insertions, 176 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 66ba5f57d78..50aa4c112b2 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -22,7 +22,7 @@
22 */ 22 */
23 23
24#define TPACPI_VERSION "0.23" 24#define TPACPI_VERSION "0.23"
25#define TPACPI_SYSFS_VERSION 0x020400 25#define TPACPI_SYSFS_VERSION 0x020500
26 26
27/* 27/*
28 * Changelog: 28 * Changelog:
@@ -1848,6 +1848,27 @@ static struct ibm_struct thinkpad_acpi_driver_data = {
1848 * Hotkey subdriver 1848 * Hotkey subdriver
1849 */ 1849 */
1850 1850
1851/*
1852 * ThinkPad firmware event model
1853 *
1854 * The ThinkPad firmware has two main event interfaces: normal ACPI
1855 * notifications (which follow the ACPI standard), and a private event
1856 * interface.
1857 *
1858 * The private event interface also issues events for the hotkeys. As
1859 * the driver gained features, the event handling code ended up being
1860 * built around the hotkey subdriver. This will need to be refactored
1861 * to a more formal event API eventually.
1862 *
1863 * Some "hotkeys" are actually supposed to be used as event reports,
1864 * such as "brightness has changed", "volume has changed", depending on
1865 * the ThinkPad model and how the firmware is operating.
1866 *
1867 * Unlike other classes, hotkey-class events have mask/unmask control on
1868 * non-ancient firmware. However, how it behaves changes a lot with the
1869 * firmware model and version.
1870 */
1871
1851enum { /* hot key scan codes (derived from ACPI DSDT) */ 1872enum { /* hot key scan codes (derived from ACPI DSDT) */
1852 TP_ACPI_HOTKEYSCAN_FNF1 = 0, 1873 TP_ACPI_HOTKEYSCAN_FNF1 = 0,
1853 TP_ACPI_HOTKEYSCAN_FNF2, 1874 TP_ACPI_HOTKEYSCAN_FNF2,
@@ -1875,7 +1896,7 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */
1875 TP_ACPI_HOTKEYSCAN_THINKPAD, 1896 TP_ACPI_HOTKEYSCAN_THINKPAD,
1876}; 1897};
1877 1898
1878enum { /* Keys available through NVRAM polling */ 1899enum { /* Keys/events available through NVRAM polling */
1879 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U, 1900 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U,
1880 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U, 1901 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U,
1881}; 1902};
@@ -1930,8 +1951,11 @@ static struct task_struct *tpacpi_hotkey_task;
1930static struct mutex hotkey_thread_mutex; 1951static struct mutex hotkey_thread_mutex;
1931 1952
1932/* 1953/*
1933 * Acquire mutex to write poller control variables. 1954 * Acquire mutex to write poller control variables as an
1934 * Increment hotkey_config_change when changing them. 1955 * atomic block.
1956 *
1957 * Increment hotkey_config_change when changing them if you
1958 * want the kthread to forget old state.
1935 * 1959 *
1936 * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END 1960 * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END
1937 */ 1961 */
@@ -1942,6 +1966,11 @@ static unsigned int hotkey_config_change;
1942 * hotkey poller control variables 1966 * hotkey poller control variables
1943 * 1967 *
1944 * Must be atomic or readers will also need to acquire mutex 1968 * Must be atomic or readers will also need to acquire mutex
1969 *
1970 * HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END
1971 * should be used only when the changes need to be taken as
1972 * a block, OR when one needs to force the kthread to forget
1973 * old state.
1945 */ 1974 */
1946static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */ 1975static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */
1947static unsigned int hotkey_poll_freq = 10; /* Hz */ 1976static unsigned int hotkey_poll_freq = 10; /* Hz */
@@ -1972,10 +2001,12 @@ static enum { /* Reasons for waking up */
1972 2001
1973static int hotkey_autosleep_ack; 2002static int hotkey_autosleep_ack;
1974 2003
1975static u32 hotkey_orig_mask; 2004static u32 hotkey_orig_mask; /* events the BIOS had enabled */
1976static u32 hotkey_all_mask; 2005static u32 hotkey_all_mask; /* all events supported in fw */
1977static u32 hotkey_reserved_mask; 2006static u32 hotkey_reserved_mask; /* events better left disabled */
1978static u32 hotkey_mask; 2007static u32 hotkey_driver_mask; /* events needed by the driver */
2008static u32 hotkey_user_mask; /* events visible to userspace */
2009static u32 hotkey_acpi_mask; /* events enabled in firmware */
1979 2010
1980static unsigned int hotkey_report_mode; 2011static unsigned int hotkey_report_mode;
1981 2012
@@ -2017,24 +2048,53 @@ static int hotkey_get_tablet_mode(int *status)
2017} 2048}
2018 2049
2019/* 2050/*
2051 * Reads current event mask from firmware, and updates
2052 * hotkey_acpi_mask accordingly. Also resets any bits
2053 * from hotkey_user_mask that are unavailable to be
2054 * delivered (shadow requirement of the userspace ABI).
2055 *
2020 * Call with hotkey_mutex held 2056 * Call with hotkey_mutex held
2021 */ 2057 */
2022static int hotkey_mask_get(void) 2058static int hotkey_mask_get(void)
2023{ 2059{
2024 u32 m = 0;
2025
2026 if (tp_features.hotkey_mask) { 2060 if (tp_features.hotkey_mask) {
2061 u32 m = 0;
2062
2027 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d")) 2063 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d"))
2028 return -EIO; 2064 return -EIO;
2065
2066 hotkey_acpi_mask = m;
2067 } else {
2068 /* no mask support doesn't mean no event support... */
2069 hotkey_acpi_mask = hotkey_all_mask;
2029 } 2070 }
2030 HOTKEY_CONFIG_CRITICAL_START 2071
2031 hotkey_mask = m | (hotkey_source_mask & hotkey_mask); 2072 /* sync userspace-visible mask */
2032 HOTKEY_CONFIG_CRITICAL_END 2073 hotkey_user_mask &= (hotkey_acpi_mask | hotkey_source_mask);
2033 2074
2034 return 0; 2075 return 0;
2035} 2076}
2036 2077
2078void static hotkey_mask_warn_incomplete_mask(void)
2079{
2080 /* log only what the user can fix... */
2081 const u32 wantedmask = hotkey_driver_mask &
2082 ~(hotkey_acpi_mask | hotkey_source_mask) &
2083 (hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK);
2084
2085 if (wantedmask)
2086 printk(TPACPI_NOTICE
2087 "required events 0x%08x not enabled!\n",
2088 wantedmask);
2089}
2090
2037/* 2091/*
2092 * Set the firmware mask when supported
2093 *
2094 * Also calls hotkey_mask_get to update hotkey_acpi_mask.
2095 *
2096 * NOTE: does not set bits in hotkey_user_mask, but may reset them.
2097 *
2038 * Call with hotkey_mutex held 2098 * Call with hotkey_mutex held
2039 */ 2099 */
2040static int hotkey_mask_set(u32 mask) 2100static int hotkey_mask_set(u32 mask)
@@ -2042,66 +2102,69 @@ static int hotkey_mask_set(u32 mask)
2042 int i; 2102 int i;
2043 int rc = 0; 2103 int rc = 0;
2044 2104
2045 if (tp_features.hotkey_mask) { 2105 const u32 fwmask = mask & ~hotkey_source_mask;
2046 if (!tp_warned.hotkey_mask_ff &&
2047 (mask == 0xffff || mask == 0xffffff ||
2048 mask == 0xffffffff)) {
2049 tp_warned.hotkey_mask_ff = 1;
2050 printk(TPACPI_NOTICE
2051 "setting the hotkey mask to 0x%08x is likely "
2052 "not the best way to go about it\n", mask);
2053 printk(TPACPI_NOTICE
2054 "please consider using the driver defaults, "
2055 "and refer to up-to-date thinkpad-acpi "
2056 "documentation\n");
2057 }
2058 2106
2059 HOTKEY_CONFIG_CRITICAL_START 2107 if (tp_features.hotkey_mask) {
2060 for (i = 0; i < 32; i++) { 2108 for (i = 0; i < 32; i++) {
2061 u32 m = 1 << i;
2062 /* enable in firmware mask only keys not in NVRAM
2063 * mode, but enable the key in the cached hotkey_mask
2064 * regardless of mode, or the key will end up
2065 * disabled by hotkey_mask_get() */
2066 if (!acpi_evalf(hkey_handle, 2109 if (!acpi_evalf(hkey_handle,
2067 NULL, "MHKM", "vdd", i + 1, 2110 NULL, "MHKM", "vdd", i + 1,
2068 !!((mask & ~hotkey_source_mask) & m))) { 2111 !!(mask & (1 << i)))) {
2069 rc = -EIO; 2112 rc = -EIO;
2070 break; 2113 break;
2071 } else {
2072 hotkey_mask = (hotkey_mask & ~m) | (mask & m);
2073 } 2114 }
2074 } 2115 }
2075 HOTKEY_CONFIG_CRITICAL_END 2116 }
2076 2117
2077 /* hotkey_mask_get must be called unconditionally below */ 2118 /*
2078 if (!hotkey_mask_get() && !rc && 2119 * We *must* make an inconditional call to hotkey_mask_get to
2079 (hotkey_mask & ~hotkey_source_mask) != 2120 * refresh hotkey_acpi_mask and update hotkey_user_mask
2080 (mask & ~hotkey_source_mask)) { 2121 *
2081 printk(TPACPI_NOTICE 2122 * Take the opportunity to also log when we cannot _enable_
2082 "requested hot key mask 0x%08x, but " 2123 * a given event.
2083 "firmware forced it to 0x%08x\n", 2124 */
2084 mask, hotkey_mask); 2125 if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) {
2085 } 2126 printk(TPACPI_NOTICE
2086 } else { 2127 "asked for hotkey mask 0x%08x, but "
2087#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2128 "firmware forced it to 0x%08x\n",
2088 HOTKEY_CONFIG_CRITICAL_START 2129 fwmask, hotkey_acpi_mask);
2089 hotkey_mask = mask & hotkey_source_mask; 2130 }
2090 HOTKEY_CONFIG_CRITICAL_END 2131
2091 hotkey_mask_get(); 2132 hotkey_mask_warn_incomplete_mask();
2092 if (hotkey_mask != mask) { 2133
2093 printk(TPACPI_NOTICE 2134 return rc;
2094 "requested hot key mask 0x%08x, " 2135}
2095 "forced to 0x%08x (NVRAM poll mask is " 2136
2096 "0x%08x): no firmware mask support\n", 2137/*
2097 mask, hotkey_mask, hotkey_source_mask); 2138 * Sets hotkey_user_mask and tries to set the firmware mask
2098 } 2139 *
2099#else 2140 * Call with hotkey_mutex held
2100 hotkey_mask_get(); 2141 */
2101 rc = -ENXIO; 2142static int hotkey_user_mask_set(const u32 mask)
2102#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 2143{
2144 int rc;
2145
2146 /* Give people a chance to notice they are doing something that
2147 * is bound to go boom on their users sooner or later */
2148 if (!tp_warned.hotkey_mask_ff &&
2149 (mask == 0xffff || mask == 0xffffff ||
2150 mask == 0xffffffff)) {
2151 tp_warned.hotkey_mask_ff = 1;
2152 printk(TPACPI_NOTICE
2153 "setting the hotkey mask to 0x%08x is likely "
2154 "not the best way to go about it\n", mask);
2155 printk(TPACPI_NOTICE
2156 "please consider using the driver defaults, "
2157 "and refer to up-to-date thinkpad-acpi "
2158 "documentation\n");
2103 } 2159 }
2104 2160
2161 /* Try to enable what the user asked for, plus whatever we need.
2162 * this syncs everything but won't enable bits in hotkey_user_mask */
2163 rc = hotkey_mask_set((mask | hotkey_driver_mask) & ~hotkey_source_mask);
2164
2165 /* Enable the available bits in hotkey_user_mask */
2166 hotkey_user_mask = mask & (hotkey_acpi_mask | hotkey_source_mask);
2167
2105 return rc; 2168 return rc;
2106} 2169}
2107 2170
@@ -2137,11 +2200,10 @@ static void tpacpi_input_send_tabletsw(void)
2137 } 2200 }
2138} 2201}
2139 2202
2140static void tpacpi_input_send_key(unsigned int scancode) 2203/* Do NOT call without validating scancode first */
2204static void tpacpi_input_send_key(const unsigned int scancode)
2141{ 2205{
2142 unsigned int keycode; 2206 const unsigned int keycode = hotkey_keycode_map[scancode];
2143
2144 keycode = hotkey_keycode_map[scancode];
2145 2207
2146 if (keycode != KEY_RESERVED) { 2208 if (keycode != KEY_RESERVED) {
2147 mutex_lock(&tpacpi_inputdev_send_mutex); 2209 mutex_lock(&tpacpi_inputdev_send_mutex);
@@ -2162,19 +2224,27 @@ static void tpacpi_input_send_key(unsigned int scancode)
2162 } 2224 }
2163} 2225}
2164 2226
2227/* Do NOT call without validating scancode first */
2228static void tpacpi_input_send_key_masked(const unsigned int scancode)
2229{
2230 if (hotkey_user_mask & (1 << scancode))
2231 tpacpi_input_send_key(scancode);
2232}
2233
2165#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2234#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2166static struct tp_acpi_drv_struct ibm_hotkey_acpidriver; 2235static struct tp_acpi_drv_struct ibm_hotkey_acpidriver;
2167 2236
2237/* Do NOT call without validating scancode first */
2168static void tpacpi_hotkey_send_key(unsigned int scancode) 2238static void tpacpi_hotkey_send_key(unsigned int scancode)
2169{ 2239{
2170 tpacpi_input_send_key(scancode); 2240 tpacpi_input_send_key_masked(scancode);
2171 if (hotkey_report_mode < 2) { 2241 if (hotkey_report_mode < 2) {
2172 acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device, 2242 acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device,
2173 0x80, 0x1001 + scancode); 2243 0x80, 0x1001 + scancode);
2174 } 2244 }
2175} 2245}
2176 2246
2177static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m) 2247static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m)
2178{ 2248{
2179 u8 d; 2249 u8 d;
2180 2250
@@ -2210,21 +2280,24 @@ static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m)
2210 } 2280 }
2211} 2281}
2212 2282
2283static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2284 struct tp_nvram_state *newn,
2285 const u32 event_mask)
2286{
2287
2213#define TPACPI_COMPARE_KEY(__scancode, __member) \ 2288#define TPACPI_COMPARE_KEY(__scancode, __member) \
2214 do { \ 2289 do { \
2215 if ((mask & (1 << __scancode)) && \ 2290 if ((event_mask & (1 << __scancode)) && \
2216 oldn->__member != newn->__member) \ 2291 oldn->__member != newn->__member) \
2217 tpacpi_hotkey_send_key(__scancode); \ 2292 tpacpi_hotkey_send_key(__scancode); \
2218 } while (0) 2293 } while (0)
2219 2294
2220#define TPACPI_MAY_SEND_KEY(__scancode) \ 2295#define TPACPI_MAY_SEND_KEY(__scancode) \
2221 do { if (mask & (1 << __scancode)) \ 2296 do { \
2222 tpacpi_hotkey_send_key(__scancode); } while (0) 2297 if (event_mask & (1 << __scancode)) \
2298 tpacpi_hotkey_send_key(__scancode); \
2299 } while (0)
2223 2300
2224static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2225 struct tp_nvram_state *newn,
2226 u32 mask)
2227{
2228 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle); 2301 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle);
2229 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle); 2302 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle);
2230 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle); 2303 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle);
@@ -2270,15 +2343,22 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2270 } 2343 }
2271 } 2344 }
2272 } 2345 }
2273}
2274 2346
2275#undef TPACPI_COMPARE_KEY 2347#undef TPACPI_COMPARE_KEY
2276#undef TPACPI_MAY_SEND_KEY 2348#undef TPACPI_MAY_SEND_KEY
2349}
2277 2350
2351/*
2352 * Polling driver
2353 *
2354 * We track all events in hotkey_source_mask all the time, since
2355 * most of them are edge-based. We only issue those requested by
2356 * hotkey_user_mask or hotkey_driver_mask, though.
2357 */
2278static int hotkey_kthread(void *data) 2358static int hotkey_kthread(void *data)
2279{ 2359{
2280 struct tp_nvram_state s[2]; 2360 struct tp_nvram_state s[2];
2281 u32 mask; 2361 u32 poll_mask, event_mask;
2282 unsigned int si, so; 2362 unsigned int si, so;
2283 unsigned long t; 2363 unsigned long t;
2284 unsigned int change_detector, must_reset; 2364 unsigned int change_detector, must_reset;
@@ -2298,10 +2378,12 @@ static int hotkey_kthread(void *data)
2298 /* Initial state for compares */ 2378 /* Initial state for compares */
2299 mutex_lock(&hotkey_thread_data_mutex); 2379 mutex_lock(&hotkey_thread_data_mutex);
2300 change_detector = hotkey_config_change; 2380 change_detector = hotkey_config_change;
2301 mask = hotkey_source_mask & hotkey_mask; 2381 poll_mask = hotkey_source_mask;
2382 event_mask = hotkey_source_mask &
2383 (hotkey_driver_mask | hotkey_user_mask);
2302 poll_freq = hotkey_poll_freq; 2384 poll_freq = hotkey_poll_freq;
2303 mutex_unlock(&hotkey_thread_data_mutex); 2385 mutex_unlock(&hotkey_thread_data_mutex);
2304 hotkey_read_nvram(&s[so], mask); 2386 hotkey_read_nvram(&s[so], poll_mask);
2305 2387
2306 while (!kthread_should_stop()) { 2388 while (!kthread_should_stop()) {
2307 if (t == 0) { 2389 if (t == 0) {
@@ -2324,15 +2406,17 @@ static int hotkey_kthread(void *data)
2324 t = 0; 2406 t = 0;
2325 change_detector = hotkey_config_change; 2407 change_detector = hotkey_config_change;
2326 } 2408 }
2327 mask = hotkey_source_mask & hotkey_mask; 2409 poll_mask = hotkey_source_mask;
2410 event_mask = hotkey_source_mask &
2411 (hotkey_driver_mask | hotkey_user_mask);
2328 poll_freq = hotkey_poll_freq; 2412 poll_freq = hotkey_poll_freq;
2329 mutex_unlock(&hotkey_thread_data_mutex); 2413 mutex_unlock(&hotkey_thread_data_mutex);
2330 2414
2331 if (likely(mask)) { 2415 if (likely(poll_mask)) {
2332 hotkey_read_nvram(&s[si], mask); 2416 hotkey_read_nvram(&s[si], poll_mask);
2333 if (likely(si != so)) { 2417 if (likely(si != so)) {
2334 hotkey_compare_and_issue_event(&s[so], &s[si], 2418 hotkey_compare_and_issue_event(&s[so], &s[si],
2335 mask); 2419 event_mask);
2336 } 2420 }
2337 } 2421 }
2338 2422
@@ -2364,10 +2448,12 @@ static void hotkey_poll_stop_sync(void)
2364/* call with hotkey_mutex held */ 2448/* call with hotkey_mutex held */
2365static void hotkey_poll_setup(bool may_warn) 2449static void hotkey_poll_setup(bool may_warn)
2366{ 2450{
2367 u32 hotkeys_to_poll = hotkey_source_mask & hotkey_mask; 2451 const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
2452 const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
2368 2453
2369 if (hotkeys_to_poll != 0 && hotkey_poll_freq > 0 && 2454 if (hotkey_poll_freq > 0 &&
2370 (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { 2455 (poll_driver_mask ||
2456 (poll_user_mask && tpacpi_inputdev->users > 0))) {
2371 if (!tpacpi_hotkey_task) { 2457 if (!tpacpi_hotkey_task) {
2372 tpacpi_hotkey_task = kthread_run(hotkey_kthread, 2458 tpacpi_hotkey_task = kthread_run(hotkey_kthread,
2373 NULL, TPACPI_NVRAM_KTHREAD_NAME); 2459 NULL, TPACPI_NVRAM_KTHREAD_NAME);
@@ -2380,12 +2466,13 @@ static void hotkey_poll_setup(bool may_warn)
2380 } 2466 }
2381 } else { 2467 } else {
2382 hotkey_poll_stop_sync(); 2468 hotkey_poll_stop_sync();
2383 if (may_warn && hotkeys_to_poll != 0 && 2469 if (may_warn && (poll_driver_mask || poll_user_mask) &&
2384 hotkey_poll_freq == 0) { 2470 hotkey_poll_freq == 0) {
2385 printk(TPACPI_NOTICE 2471 printk(TPACPI_NOTICE
2386 "hot keys 0x%08x require polling, " 2472 "hot keys 0x%08x and/or events 0x%08x "
2387 "which is currently disabled\n", 2473 "require polling, which is currently "
2388 hotkeys_to_poll); 2474 "disabled\n",
2475 poll_user_mask, poll_driver_mask);
2389 } 2476 }
2390 } 2477 }
2391} 2478}
@@ -2403,9 +2490,7 @@ static void hotkey_poll_set_freq(unsigned int freq)
2403 if (!freq) 2490 if (!freq)
2404 hotkey_poll_stop_sync(); 2491 hotkey_poll_stop_sync();
2405 2492
2406 HOTKEY_CONFIG_CRITICAL_START
2407 hotkey_poll_freq = freq; 2493 hotkey_poll_freq = freq;
2408 HOTKEY_CONFIG_CRITICAL_END
2409} 2494}
2410 2495
2411#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 2496#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
@@ -2440,7 +2525,8 @@ static int hotkey_inputdev_open(struct input_dev *dev)
2440static void hotkey_inputdev_close(struct input_dev *dev) 2525static void hotkey_inputdev_close(struct input_dev *dev)
2441{ 2526{
2442 /* disable hotkey polling when possible */ 2527 /* disable hotkey polling when possible */
2443 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) 2528 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING &&
2529 !(hotkey_source_mask & hotkey_driver_mask))
2444 hotkey_poll_setup_safe(false); 2530 hotkey_poll_setup_safe(false);
2445} 2531}
2446 2532
@@ -2488,15 +2574,7 @@ static ssize_t hotkey_mask_show(struct device *dev,
2488 struct device_attribute *attr, 2574 struct device_attribute *attr,
2489 char *buf) 2575 char *buf)
2490{ 2576{
2491 int res; 2577 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_user_mask);
2492
2493 if (mutex_lock_killable(&hotkey_mutex))
2494 return -ERESTARTSYS;
2495 res = hotkey_mask_get();
2496 mutex_unlock(&hotkey_mutex);
2497
2498 return (res)?
2499 res : snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_mask);
2500} 2578}
2501 2579
2502static ssize_t hotkey_mask_store(struct device *dev, 2580static ssize_t hotkey_mask_store(struct device *dev,
@@ -2512,7 +2590,7 @@ static ssize_t hotkey_mask_store(struct device *dev,
2512 if (mutex_lock_killable(&hotkey_mutex)) 2590 if (mutex_lock_killable(&hotkey_mutex))
2513 return -ERESTARTSYS; 2591 return -ERESTARTSYS;
2514 2592
2515 res = hotkey_mask_set(t); 2593 res = hotkey_user_mask_set(t);
2516 2594
2517#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2595#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2518 hotkey_poll_setup(true); 2596 hotkey_poll_setup(true);
@@ -2594,6 +2672,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
2594 const char *buf, size_t count) 2672 const char *buf, size_t count)
2595{ 2673{
2596 unsigned long t; 2674 unsigned long t;
2675 u32 r_ev;
2676 int rc;
2597 2677
2598 if (parse_strtoul(buf, 0xffffffffUL, &t) || 2678 if (parse_strtoul(buf, 0xffffffffUL, &t) ||
2599 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0)) 2679 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0))
@@ -2606,14 +2686,28 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
2606 hotkey_source_mask = t; 2686 hotkey_source_mask = t;
2607 HOTKEY_CONFIG_CRITICAL_END 2687 HOTKEY_CONFIG_CRITICAL_END
2608 2688
2689 rc = hotkey_mask_set((hotkey_user_mask | hotkey_driver_mask) &
2690 ~hotkey_source_mask);
2609 hotkey_poll_setup(true); 2691 hotkey_poll_setup(true);
2610 hotkey_mask_set(hotkey_mask); 2692
2693 /* check if events needed by the driver got disabled */
2694 r_ev = hotkey_driver_mask & ~(hotkey_acpi_mask & hotkey_all_mask)
2695 & ~hotkey_source_mask & TPACPI_HKEY_NVRAM_KNOWN_MASK;
2611 2696
2612 mutex_unlock(&hotkey_mutex); 2697 mutex_unlock(&hotkey_mutex);
2613 2698
2699 if (rc < 0)
2700 printk(TPACPI_ERR "hotkey_source_mask: failed to update the"
2701 "firmware event mask!\n");
2702
2703 if (r_ev)
2704 printk(TPACPI_NOTICE "hotkey_source_mask: "
2705 "some important events were disabled: "
2706 "0x%04x\n", r_ev);
2707
2614 tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); 2708 tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
2615 2709
2616 return count; 2710 return (rc < 0) ? rc : count;
2617} 2711}
2618 2712
2619static struct device_attribute dev_attr_hotkey_source_mask = 2713static struct device_attribute dev_attr_hotkey_source_mask =
@@ -2731,9 +2825,8 @@ static struct device_attribute dev_attr_hotkey_wakeup_reason =
2731 2825
2732static void hotkey_wakeup_reason_notify_change(void) 2826static void hotkey_wakeup_reason_notify_change(void)
2733{ 2827{
2734 if (tp_features.hotkey_mask) 2828 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2735 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2829 "wakeup_reason");
2736 "wakeup_reason");
2737} 2830}
2738 2831
2739/* sysfs wakeup hotunplug_complete (pollable) -------------------------- */ 2832/* sysfs wakeup hotunplug_complete (pollable) -------------------------- */
@@ -2750,9 +2843,8 @@ static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete =
2750 2843
2751static void hotkey_wakeup_hotunplug_complete_notify_change(void) 2844static void hotkey_wakeup_hotunplug_complete_notify_change(void)
2752{ 2845{
2753 if (tp_features.hotkey_mask) 2846 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2754 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2847 "wakeup_hotunplug_complete");
2755 "wakeup_hotunplug_complete");
2756} 2848}
2757 2849
2758/* --------------------------------------------------------------------- */ 2850/* --------------------------------------------------------------------- */
@@ -2760,27 +2852,19 @@ static void hotkey_wakeup_hotunplug_complete_notify_change(void)
2760static struct attribute *hotkey_attributes[] __initdata = { 2852static struct attribute *hotkey_attributes[] __initdata = {
2761 &dev_attr_hotkey_enable.attr, 2853 &dev_attr_hotkey_enable.attr,
2762 &dev_attr_hotkey_bios_enabled.attr, 2854 &dev_attr_hotkey_bios_enabled.attr,
2855 &dev_attr_hotkey_bios_mask.attr,
2763 &dev_attr_hotkey_report_mode.attr, 2856 &dev_attr_hotkey_report_mode.attr,
2764#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2857 &dev_attr_hotkey_wakeup_reason.attr,
2858 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2765 &dev_attr_hotkey_mask.attr, 2859 &dev_attr_hotkey_mask.attr,
2766 &dev_attr_hotkey_all_mask.attr, 2860 &dev_attr_hotkey_all_mask.attr,
2767 &dev_attr_hotkey_recommended_mask.attr, 2861 &dev_attr_hotkey_recommended_mask.attr,
2862#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2768 &dev_attr_hotkey_source_mask.attr, 2863 &dev_attr_hotkey_source_mask.attr,
2769 &dev_attr_hotkey_poll_freq.attr, 2864 &dev_attr_hotkey_poll_freq.attr,
2770#endif 2865#endif
2771}; 2866};
2772 2867
2773static struct attribute *hotkey_mask_attributes[] __initdata = {
2774 &dev_attr_hotkey_bios_mask.attr,
2775#ifndef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2776 &dev_attr_hotkey_mask.attr,
2777 &dev_attr_hotkey_all_mask.attr,
2778 &dev_attr_hotkey_recommended_mask.attr,
2779#endif
2780 &dev_attr_hotkey_wakeup_reason.attr,
2781 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2782};
2783
2784/* 2868/*
2785 * Sync both the hw and sw blocking state of all switches 2869 * Sync both the hw and sw blocking state of all switches
2786 */ 2870 */
@@ -2844,10 +2928,12 @@ static void hotkey_exit(void)
2844 kfree(hotkey_keycode_map); 2928 kfree(hotkey_keycode_map);
2845 2929
2846 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY, 2930 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
2847 "restoring original hot key mask\n"); 2931 "restoring original HKEY status and mask\n");
2848 /* no short-circuit boolean operator below! */ 2932 /* yes, there is a bitwise or below, we want the
2849 if (((tp_features.hotkey_mask && hotkey_mask_set(hotkey_orig_mask)) 2933 * functions to be called even if one of them fail */
2850 | hotkey_status_set(false)) != 0) 2934 if (((tp_features.hotkey_mask &&
2935 hotkey_mask_set(hotkey_orig_mask)) |
2936 hotkey_status_set(false)) != 0)
2851 printk(TPACPI_ERR 2937 printk(TPACPI_ERR
2852 "failed to restore hot key mask " 2938 "failed to restore hot key mask "
2853 "to BIOS defaults\n"); 2939 "to BIOS defaults\n");
@@ -2862,6 +2948,35 @@ static void __init hotkey_unmap(const unsigned int scancode)
2862 } 2948 }
2863} 2949}
2864 2950
2951/*
2952 * HKEY quirks:
2953 * TPACPI_HK_Q_INIMASK: Supports FN+F3,FN+F4,FN+F12
2954 */
2955
2956#define TPACPI_HK_Q_INIMASK 0x0001
2957
2958static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
2959 TPACPI_Q_IBM('I', 'H', TPACPI_HK_Q_INIMASK), /* 600E */
2960 TPACPI_Q_IBM('I', 'N', TPACPI_HK_Q_INIMASK), /* 600E */
2961 TPACPI_Q_IBM('I', 'D', TPACPI_HK_Q_INIMASK), /* 770, 770E, 770ED */
2962 TPACPI_Q_IBM('I', 'W', TPACPI_HK_Q_INIMASK), /* A20m */
2963 TPACPI_Q_IBM('I', 'V', TPACPI_HK_Q_INIMASK), /* A20p */
2964 TPACPI_Q_IBM('1', '0', TPACPI_HK_Q_INIMASK), /* A21e, A22e */
2965 TPACPI_Q_IBM('K', 'U', TPACPI_HK_Q_INIMASK), /* A21e */
2966 TPACPI_Q_IBM('K', 'X', TPACPI_HK_Q_INIMASK), /* A21m, A22m */
2967 TPACPI_Q_IBM('K', 'Y', TPACPI_HK_Q_INIMASK), /* A21p, A22p */
2968 TPACPI_Q_IBM('1', 'B', TPACPI_HK_Q_INIMASK), /* A22e */
2969 TPACPI_Q_IBM('1', '3', TPACPI_HK_Q_INIMASK), /* A22m */
2970 TPACPI_Q_IBM('1', 'E', TPACPI_HK_Q_INIMASK), /* A30/p (0) */
2971 TPACPI_Q_IBM('1', 'C', TPACPI_HK_Q_INIMASK), /* R30 */
2972 TPACPI_Q_IBM('1', 'F', TPACPI_HK_Q_INIMASK), /* R31 */
2973 TPACPI_Q_IBM('I', 'Y', TPACPI_HK_Q_INIMASK), /* T20 */
2974 TPACPI_Q_IBM('K', 'Z', TPACPI_HK_Q_INIMASK), /* T21 */
2975 TPACPI_Q_IBM('1', '6', TPACPI_HK_Q_INIMASK), /* T22 */
2976 TPACPI_Q_IBM('I', 'Z', TPACPI_HK_Q_INIMASK), /* X20, X21 */
2977 TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */
2978};
2979
2865static int __init hotkey_init(struct ibm_init_struct *iibm) 2980static int __init hotkey_init(struct ibm_init_struct *iibm)
2866{ 2981{
2867 /* Requirements for changing the default keymaps: 2982 /* Requirements for changing the default keymaps:
@@ -2904,9 +3019,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2904 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 3019 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
2905 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 3020 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
2906 3021
2907 /* brightness: firmware always reacts to them, unless 3022 /* brightness: firmware always reacts to them */
2908 * X.org did some tricks in the radeon BIOS scratch
2909 * registers of *some* models */
2910 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 3023 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
2911 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 3024 KEY_RESERVED, /* 0x10: FN+END (brightness down) */
2912 3025
@@ -2981,6 +3094,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2981 int status; 3094 int status;
2982 int hkeyv; 3095 int hkeyv;
2983 3096
3097 unsigned long quirks;
3098
2984 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3099 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2985 "initializing hotkey subdriver\n"); 3100 "initializing hotkey subdriver\n");
2986 3101
@@ -3006,9 +3121,16 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3006 if (!tp_features.hotkey) 3121 if (!tp_features.hotkey)
3007 return 1; 3122 return 1;
3008 3123
3124 quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable,
3125 ARRAY_SIZE(tpacpi_hotkey_qtable));
3126
3009 tpacpi_disable_brightness_delay(); 3127 tpacpi_disable_brightness_delay();
3010 3128
3011 hotkey_dev_attributes = create_attr_set(13, NULL); 3129 /* MUST have enough space for all attributes to be added to
3130 * hotkey_dev_attributes */
3131 hotkey_dev_attributes = create_attr_set(
3132 ARRAY_SIZE(hotkey_attributes) + 2,
3133 NULL);
3012 if (!hotkey_dev_attributes) 3134 if (!hotkey_dev_attributes)
3013 return -ENOMEM; 3135 return -ENOMEM;
3014 res = add_many_to_attr_set(hotkey_dev_attributes, 3136 res = add_many_to_attr_set(hotkey_dev_attributes,
@@ -3017,7 +3139,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3017 if (res) 3139 if (res)
3018 goto err_exit; 3140 goto err_exit;
3019 3141
3020 /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 3142 /* mask not supported on 600e/x, 770e, 770x, A21e, A2xm/p,
3021 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking 3143 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking
3022 for HKEY interface version 0x100 */ 3144 for HKEY interface version 0x100 */
3023 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { 3145 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
@@ -3031,10 +3153,22 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3031 * MHKV 0x100 in A31, R40, R40e, 3153 * MHKV 0x100 in A31, R40, R40e,
3032 * T4x, X31, and later 3154 * T4x, X31, and later
3033 */ 3155 */
3034 tp_features.hotkey_mask = 1;
3035 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3156 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3036 "firmware HKEY interface version: 0x%x\n", 3157 "firmware HKEY interface version: 0x%x\n",
3037 hkeyv); 3158 hkeyv);
3159
3160 /* Paranoia check AND init hotkey_all_mask */
3161 if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
3162 "MHKA", "qd")) {
3163 printk(TPACPI_ERR
3164 "missing MHKA handler, "
3165 "please report this to %s\n",
3166 TPACPI_MAIL);
3167 /* Fallback: pre-init for FN+F3,F4,F12 */
3168 hotkey_all_mask = 0x080cU;
3169 } else {
3170 tp_features.hotkey_mask = 1;
3171 }
3038 } 3172 }
3039 } 3173 }
3040 3174
@@ -3042,32 +3176,23 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3042 "hotkey masks are %s\n", 3176 "hotkey masks are %s\n",
3043 str_supported(tp_features.hotkey_mask)); 3177 str_supported(tp_features.hotkey_mask));
3044 3178
3045 if (tp_features.hotkey_mask) { 3179 /* Init hotkey_all_mask if not initialized yet */
3046 if (!acpi_evalf(hkey_handle, &hotkey_all_mask, 3180 if (!tp_features.hotkey_mask && !hotkey_all_mask &&
3047 "MHKA", "qd")) { 3181 (quirks & TPACPI_HK_Q_INIMASK))
3048 printk(TPACPI_ERR 3182 hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */
3049 "missing MHKA handler, "
3050 "please report this to %s\n",
3051 TPACPI_MAIL);
3052 /* FN+F12, FN+F4, FN+F3 */
3053 hotkey_all_mask = 0x080cU;
3054 }
3055 }
3056 3183
3057 /* hotkey_source_mask *must* be zero for 3184 /* Init hotkey_acpi_mask and hotkey_orig_mask */
3058 * the first hotkey_mask_get */
3059 if (tp_features.hotkey_mask) { 3185 if (tp_features.hotkey_mask) {
3186 /* hotkey_source_mask *must* be zero for
3187 * the first hotkey_mask_get to return hotkey_orig_mask */
3060 res = hotkey_mask_get(); 3188 res = hotkey_mask_get();
3061 if (res) 3189 if (res)
3062 goto err_exit; 3190 goto err_exit;
3063 3191
3064 hotkey_orig_mask = hotkey_mask; 3192 hotkey_orig_mask = hotkey_acpi_mask;
3065 res = add_many_to_attr_set( 3193 } else {
3066 hotkey_dev_attributes, 3194 hotkey_orig_mask = hotkey_all_mask;
3067 hotkey_mask_attributes, 3195 hotkey_acpi_mask = hotkey_all_mask;
3068 ARRAY_SIZE(hotkey_mask_attributes));
3069 if (res)
3070 goto err_exit;
3071 } 3196 }
3072 3197
3073#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3198#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
@@ -3181,14 +3306,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3181 } 3306 }
3182 3307
3183#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 3308#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
3184 if (tp_features.hotkey_mask) { 3309 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
3185 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK 3310 & ~hotkey_all_mask
3186 & ~hotkey_all_mask 3311 & ~hotkey_reserved_mask;
3187 & ~hotkey_reserved_mask;
3188 } else {
3189 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
3190 & ~hotkey_reserved_mask;
3191 }
3192 3312
3193 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3313 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3194 "hotkey source mask 0x%08x, polling freq %u\n", 3314 "hotkey source mask 0x%08x, polling freq %u\n",
@@ -3202,13 +3322,18 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3202 hotkey_exit(); 3322 hotkey_exit();
3203 return res; 3323 return res;
3204 } 3324 }
3205 res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) 3325 res = hotkey_mask_set(((hotkey_all_mask & ~hotkey_reserved_mask)
3206 & ~hotkey_reserved_mask) 3326 | hotkey_driver_mask)
3207 | hotkey_orig_mask); 3327 & ~hotkey_source_mask);
3208 if (res < 0 && res != -ENXIO) { 3328 if (res < 0 && res != -ENXIO) {
3209 hotkey_exit(); 3329 hotkey_exit();
3210 return res; 3330 return res;
3211 } 3331 }
3332 hotkey_user_mask = (hotkey_acpi_mask | hotkey_source_mask)
3333 & ~hotkey_reserved_mask;
3334 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3335 "initial masks: user=0x%08x, fw=0x%08x, poll=0x%08x\n",
3336 hotkey_user_mask, hotkey_acpi_mask, hotkey_source_mask);
3212 3337
3213 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3338 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3214 "legacy ibm/hotkey event reporting over procfs %s\n", 3339 "legacy ibm/hotkey event reporting over procfs %s\n",
@@ -3243,7 +3368,7 @@ static bool hotkey_notify_hotkey(const u32 hkey,
3243 if (scancode > 0 && scancode < 0x21) { 3368 if (scancode > 0 && scancode < 0x21) {
3244 scancode--; 3369 scancode--;
3245 if (!(hotkey_source_mask & (1 << scancode))) { 3370 if (!(hotkey_source_mask & (1 << scancode))) {
3246 tpacpi_input_send_key(scancode); 3371 tpacpi_input_send_key_masked(scancode);
3247 *send_acpi_ev = false; 3372 *send_acpi_ev = false;
3248 } else { 3373 } else {
3249 *ignore_acpi_ev = true; 3374 *ignore_acpi_ev = true;
@@ -3498,10 +3623,12 @@ static void hotkey_resume(void)
3498{ 3623{
3499 tpacpi_disable_brightness_delay(); 3624 tpacpi_disable_brightness_delay();
3500 3625
3501 if (hotkey_mask_get()) 3626 if (hotkey_status_set(true) < 0 ||
3627 hotkey_mask_set(hotkey_acpi_mask) < 0)
3502 printk(TPACPI_ERR 3628 printk(TPACPI_ERR
3503 "error while trying to read hot key mask " 3629 "error while attempting to reset the event "
3504 "from firmware\n"); 3630 "firmware interface\n");
3631
3505 tpacpi_send_radiosw_update(); 3632 tpacpi_send_radiosw_update();
3506 hotkey_tablet_mode_notify_change(); 3633 hotkey_tablet_mode_notify_change();
3507 hotkey_wakeup_reason_notify_change(); 3634 hotkey_wakeup_reason_notify_change();
@@ -3530,8 +3657,8 @@ static int hotkey_read(char *p)
3530 return res; 3657 return res;
3531 3658
3532 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); 3659 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
3533 if (tp_features.hotkey_mask) { 3660 if (hotkey_all_mask) {
3534 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_mask); 3661 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_user_mask);
3535 len += sprintf(p + len, 3662 len += sprintf(p + len,
3536 "commands:\tenable, disable, reset, <mask>\n"); 3663 "commands:\tenable, disable, reset, <mask>\n");
3537 } else { 3664 } else {
@@ -3568,7 +3695,7 @@ static int hotkey_write(char *buf)
3568 if (mutex_lock_killable(&hotkey_mutex)) 3695 if (mutex_lock_killable(&hotkey_mutex))
3569 return -ERESTARTSYS; 3696 return -ERESTARTSYS;
3570 3697
3571 mask = hotkey_mask; 3698 mask = hotkey_user_mask;
3572 3699
3573 res = 0; 3700 res = 0;
3574 while ((cmd = next_cmd(&buf))) { 3701 while ((cmd = next_cmd(&buf))) {
@@ -3590,12 +3717,11 @@ static int hotkey_write(char *buf)
3590 } 3717 }
3591 } 3718 }
3592 3719
3593 if (!res) 3720 if (!res) {
3594 tpacpi_disclose_usertask("procfs hotkey", 3721 tpacpi_disclose_usertask("procfs hotkey",
3595 "set mask to 0x%08x\n", mask); 3722 "set mask to 0x%08x\n", mask);
3596 3723 res = hotkey_user_mask_set(mask);
3597 if (!res && mask != hotkey_mask) 3724 }
3598 res = hotkey_mask_set(mask);
3599 3725
3600errexit: 3726errexit:
3601 mutex_unlock(&hotkey_mutex); 3727 mutex_unlock(&hotkey_mutex);