aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
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);