aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/thinkpad_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/thinkpad_acpi.c')
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c632
1 files changed, 426 insertions, 206 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index f78d27503925..3910f2f3eada 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:
@@ -145,6 +145,51 @@ enum {
145 TP_ACPI_WGSV_STATE_UWBPWR = 0x0020, /* UWB radio enabled */ 145 TP_ACPI_WGSV_STATE_UWBPWR = 0x0020, /* UWB radio enabled */
146}; 146};
147 147
148/* HKEY events */
149enum tpacpi_hkey_event_t {
150 /* Hotkey-related */
151 TP_HKEY_EV_HOTKEY_BASE = 0x1001, /* first hotkey (FN+F1) */
152 TP_HKEY_EV_BRGHT_UP = 0x1010, /* Brightness up */
153 TP_HKEY_EV_BRGHT_DOWN = 0x1011, /* Brightness down */
154 TP_HKEY_EV_VOL_UP = 0x1015, /* Volume up or unmute */
155 TP_HKEY_EV_VOL_DOWN = 0x1016, /* Volume down or unmute */
156 TP_HKEY_EV_VOL_MUTE = 0x1017, /* Mixer output mute */
157
158 /* Reasons for waking up from S3/S4 */
159 TP_HKEY_EV_WKUP_S3_UNDOCK = 0x2304, /* undock requested, S3 */
160 TP_HKEY_EV_WKUP_S4_UNDOCK = 0x2404, /* undock requested, S4 */
161 TP_HKEY_EV_WKUP_S3_BAYEJ = 0x2305, /* bay ejection req, S3 */
162 TP_HKEY_EV_WKUP_S4_BAYEJ = 0x2405, /* bay ejection req, S4 */
163 TP_HKEY_EV_WKUP_S3_BATLOW = 0x2313, /* battery empty, S3 */
164 TP_HKEY_EV_WKUP_S4_BATLOW = 0x2413, /* battery empty, S4 */
165
166 /* Auto-sleep after eject request */
167 TP_HKEY_EV_BAYEJ_ACK = 0x3003, /* bay ejection complete */
168 TP_HKEY_EV_UNDOCK_ACK = 0x4003, /* undock complete */
169
170 /* Misc bay events */
171 TP_HKEY_EV_OPTDRV_EJ = 0x3006, /* opt. drive tray ejected */
172
173 /* User-interface events */
174 TP_HKEY_EV_LID_CLOSE = 0x5001, /* laptop lid closed */
175 TP_HKEY_EV_LID_OPEN = 0x5002, /* laptop lid opened */
176 TP_HKEY_EV_TABLET_TABLET = 0x5009, /* tablet swivel up */
177 TP_HKEY_EV_TABLET_NOTEBOOK = 0x500a, /* tablet swivel down */
178 TP_HKEY_EV_PEN_INSERTED = 0x500b, /* tablet pen inserted */
179 TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */
180 TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */
181
182 /* Thermal events */
183 TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */
184 TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */
185 TP_HKEY_EV_ALARM_SENSOR_HOT = 0x6021, /* sensor too hot */
186 TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */
187 TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* thermal table changed */
188
189 /* Misc */
190 TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */
191};
192
148/**************************************************************************** 193/****************************************************************************
149 * Main driver 194 * Main driver
150 */ 195 */
@@ -1848,6 +1893,27 @@ static struct ibm_struct thinkpad_acpi_driver_data = {
1848 * Hotkey subdriver 1893 * Hotkey subdriver
1849 */ 1894 */
1850 1895
1896/*
1897 * ThinkPad firmware event model
1898 *
1899 * The ThinkPad firmware has two main event interfaces: normal ACPI
1900 * notifications (which follow the ACPI standard), and a private event
1901 * interface.
1902 *
1903 * The private event interface also issues events for the hotkeys. As
1904 * the driver gained features, the event handling code ended up being
1905 * built around the hotkey subdriver. This will need to be refactored
1906 * to a more formal event API eventually.
1907 *
1908 * Some "hotkeys" are actually supposed to be used as event reports,
1909 * such as "brightness has changed", "volume has changed", depending on
1910 * the ThinkPad model and how the firmware is operating.
1911 *
1912 * Unlike other classes, hotkey-class events have mask/unmask control on
1913 * non-ancient firmware. However, how it behaves changes a lot with the
1914 * firmware model and version.
1915 */
1916
1851enum { /* hot key scan codes (derived from ACPI DSDT) */ 1917enum { /* hot key scan codes (derived from ACPI DSDT) */
1852 TP_ACPI_HOTKEYSCAN_FNF1 = 0, 1918 TP_ACPI_HOTKEYSCAN_FNF1 = 0,
1853 TP_ACPI_HOTKEYSCAN_FNF2, 1919 TP_ACPI_HOTKEYSCAN_FNF2,
@@ -1875,7 +1941,7 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */
1875 TP_ACPI_HOTKEYSCAN_THINKPAD, 1941 TP_ACPI_HOTKEYSCAN_THINKPAD,
1876}; 1942};
1877 1943
1878enum { /* Keys available through NVRAM polling */ 1944enum { /* Keys/events available through NVRAM polling */
1879 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U, 1945 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U,
1880 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U, 1946 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U,
1881}; 1947};
@@ -1930,8 +1996,11 @@ static struct task_struct *tpacpi_hotkey_task;
1930static struct mutex hotkey_thread_mutex; 1996static struct mutex hotkey_thread_mutex;
1931 1997
1932/* 1998/*
1933 * Acquire mutex to write poller control variables. 1999 * Acquire mutex to write poller control variables as an
1934 * Increment hotkey_config_change when changing them. 2000 * atomic block.
2001 *
2002 * Increment hotkey_config_change when changing them if you
2003 * want the kthread to forget old state.
1935 * 2004 *
1936 * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END 2005 * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END
1937 */ 2006 */
@@ -1942,6 +2011,11 @@ static unsigned int hotkey_config_change;
1942 * hotkey poller control variables 2011 * hotkey poller control variables
1943 * 2012 *
1944 * Must be atomic or readers will also need to acquire mutex 2013 * Must be atomic or readers will also need to acquire mutex
2014 *
2015 * HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END
2016 * should be used only when the changes need to be taken as
2017 * a block, OR when one needs to force the kthread to forget
2018 * old state.
1945 */ 2019 */
1946static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */ 2020static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */
1947static unsigned int hotkey_poll_freq = 10; /* Hz */ 2021static unsigned int hotkey_poll_freq = 10; /* Hz */
@@ -1972,10 +2046,12 @@ static enum { /* Reasons for waking up */
1972 2046
1973static int hotkey_autosleep_ack; 2047static int hotkey_autosleep_ack;
1974 2048
1975static u32 hotkey_orig_mask; 2049static u32 hotkey_orig_mask; /* events the BIOS had enabled */
1976static u32 hotkey_all_mask; 2050static u32 hotkey_all_mask; /* all events supported in fw */
1977static u32 hotkey_reserved_mask; 2051static u32 hotkey_reserved_mask; /* events better left disabled */
1978static u32 hotkey_mask; 2052static u32 hotkey_driver_mask; /* events needed by the driver */
2053static u32 hotkey_user_mask; /* events visible to userspace */
2054static u32 hotkey_acpi_mask; /* events enabled in firmware */
1979 2055
1980static unsigned int hotkey_report_mode; 2056static unsigned int hotkey_report_mode;
1981 2057
@@ -1983,6 +2059,9 @@ static u16 *hotkey_keycode_map;
1983 2059
1984static struct attribute_set *hotkey_dev_attributes; 2060static struct attribute_set *hotkey_dev_attributes;
1985 2061
2062static void tpacpi_driver_event(const unsigned int hkey_event);
2063static void hotkey_driver_event(const unsigned int scancode);
2064
1986/* HKEY.MHKG() return bits */ 2065/* HKEY.MHKG() return bits */
1987#define TP_HOTKEY_TABLET_MASK (1 << 3) 2066#define TP_HOTKEY_TABLET_MASK (1 << 3)
1988 2067
@@ -2017,24 +2096,53 @@ static int hotkey_get_tablet_mode(int *status)
2017} 2096}
2018 2097
2019/* 2098/*
2099 * Reads current event mask from firmware, and updates
2100 * hotkey_acpi_mask accordingly. Also resets any bits
2101 * from hotkey_user_mask that are unavailable to be
2102 * delivered (shadow requirement of the userspace ABI).
2103 *
2020 * Call with hotkey_mutex held 2104 * Call with hotkey_mutex held
2021 */ 2105 */
2022static int hotkey_mask_get(void) 2106static int hotkey_mask_get(void)
2023{ 2107{
2024 u32 m = 0;
2025
2026 if (tp_features.hotkey_mask) { 2108 if (tp_features.hotkey_mask) {
2109 u32 m = 0;
2110
2027 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d")) 2111 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d"))
2028 return -EIO; 2112 return -EIO;
2113
2114 hotkey_acpi_mask = m;
2115 } else {
2116 /* no mask support doesn't mean no event support... */
2117 hotkey_acpi_mask = hotkey_all_mask;
2029 } 2118 }
2030 HOTKEY_CONFIG_CRITICAL_START 2119
2031 hotkey_mask = m | (hotkey_source_mask & hotkey_mask); 2120 /* sync userspace-visible mask */
2032 HOTKEY_CONFIG_CRITICAL_END 2121 hotkey_user_mask &= (hotkey_acpi_mask | hotkey_source_mask);
2033 2122
2034 return 0; 2123 return 0;
2035} 2124}
2036 2125
2126void static hotkey_mask_warn_incomplete_mask(void)
2127{
2128 /* log only what the user can fix... */
2129 const u32 wantedmask = hotkey_driver_mask &
2130 ~(hotkey_acpi_mask | hotkey_source_mask) &
2131 (hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK);
2132
2133 if (wantedmask)
2134 printk(TPACPI_NOTICE
2135 "required events 0x%08x not enabled!\n",
2136 wantedmask);
2137}
2138
2037/* 2139/*
2140 * Set the firmware mask when supported
2141 *
2142 * Also calls hotkey_mask_get to update hotkey_acpi_mask.
2143 *
2144 * NOTE: does not set bits in hotkey_user_mask, but may reset them.
2145 *
2038 * Call with hotkey_mutex held 2146 * Call with hotkey_mutex held
2039 */ 2147 */
2040static int hotkey_mask_set(u32 mask) 2148static int hotkey_mask_set(u32 mask)
@@ -2042,66 +2150,98 @@ static int hotkey_mask_set(u32 mask)
2042 int i; 2150 int i;
2043 int rc = 0; 2151 int rc = 0;
2044 2152
2045 if (tp_features.hotkey_mask) { 2153 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 2154
2059 HOTKEY_CONFIG_CRITICAL_START 2155 if (tp_features.hotkey_mask) {
2060 for (i = 0; i < 32; i++) { 2156 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, 2157 if (!acpi_evalf(hkey_handle,
2067 NULL, "MHKM", "vdd", i + 1, 2158 NULL, "MHKM", "vdd", i + 1,
2068 !!((mask & ~hotkey_source_mask) & m))) { 2159 !!(mask & (1 << i)))) {
2069 rc = -EIO; 2160 rc = -EIO;
2070 break; 2161 break;
2071 } else {
2072 hotkey_mask = (hotkey_mask & ~m) | (mask & m);
2073 } 2162 }
2074 } 2163 }
2075 HOTKEY_CONFIG_CRITICAL_END 2164 }
2076 2165
2077 /* hotkey_mask_get must be called unconditionally below */ 2166 /*
2078 if (!hotkey_mask_get() && !rc && 2167 * We *must* make an inconditional call to hotkey_mask_get to
2079 (hotkey_mask & ~hotkey_source_mask) != 2168 * refresh hotkey_acpi_mask and update hotkey_user_mask
2080 (mask & ~hotkey_source_mask)) { 2169 *
2081 printk(TPACPI_NOTICE 2170 * Take the opportunity to also log when we cannot _enable_
2082 "requested hot key mask 0x%08x, but " 2171 * a given event.
2083 "firmware forced it to 0x%08x\n", 2172 */
2084 mask, hotkey_mask); 2173 if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) {
2085 } 2174 printk(TPACPI_NOTICE
2086 } else { 2175 "asked for hotkey mask 0x%08x, but "
2087#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2176 "firmware forced it to 0x%08x\n",
2088 HOTKEY_CONFIG_CRITICAL_START 2177 fwmask, hotkey_acpi_mask);
2089 hotkey_mask = mask & hotkey_source_mask;
2090 HOTKEY_CONFIG_CRITICAL_END
2091 hotkey_mask_get();
2092 if (hotkey_mask != mask) {
2093 printk(TPACPI_NOTICE
2094 "requested hot key mask 0x%08x, "
2095 "forced to 0x%08x (NVRAM poll mask is "
2096 "0x%08x): no firmware mask support\n",
2097 mask, hotkey_mask, hotkey_source_mask);
2098 }
2099#else
2100 hotkey_mask_get();
2101 rc = -ENXIO;
2102#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
2103 } 2178 }
2104 2179
2180 hotkey_mask_warn_incomplete_mask();
2181
2182 return rc;
2183}
2184
2185/*
2186 * Sets hotkey_user_mask and tries to set the firmware mask
2187 *
2188 * Call with hotkey_mutex held
2189 */
2190static int hotkey_user_mask_set(const u32 mask)
2191{
2192 int rc;
2193
2194 /* Give people a chance to notice they are doing something that
2195 * is bound to go boom on their users sooner or later */
2196 if (!tp_warned.hotkey_mask_ff &&
2197 (mask == 0xffff || mask == 0xffffff ||
2198 mask == 0xffffffff)) {
2199 tp_warned.hotkey_mask_ff = 1;
2200 printk(TPACPI_NOTICE
2201 "setting the hotkey mask to 0x%08x is likely "
2202 "not the best way to go about it\n", mask);
2203 printk(TPACPI_NOTICE
2204 "please consider using the driver defaults, "
2205 "and refer to up-to-date thinkpad-acpi "
2206 "documentation\n");
2207 }
2208
2209 /* Try to enable what the user asked for, plus whatever we need.
2210 * this syncs everything but won't enable bits in hotkey_user_mask */
2211 rc = hotkey_mask_set((mask | hotkey_driver_mask) & ~hotkey_source_mask);
2212
2213 /* Enable the available bits in hotkey_user_mask */
2214 hotkey_user_mask = mask & (hotkey_acpi_mask | hotkey_source_mask);
2215
2216 return rc;
2217}
2218
2219/*
2220 * Sets the driver hotkey mask.
2221 *
2222 * Can be called even if the hotkey subdriver is inactive
2223 */
2224static int tpacpi_hotkey_driver_mask_set(const u32 mask)
2225{
2226 int rc;
2227
2228 /* Do the right thing if hotkey_init has not been called yet */
2229 if (!tp_features.hotkey) {
2230 hotkey_driver_mask = mask;
2231 return 0;
2232 }
2233
2234 mutex_lock(&hotkey_mutex);
2235
2236 HOTKEY_CONFIG_CRITICAL_START
2237 hotkey_driver_mask = mask;
2238 hotkey_source_mask |= (mask & ~hotkey_all_mask);
2239 HOTKEY_CONFIG_CRITICAL_END
2240
2241 rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) &
2242 ~hotkey_source_mask);
2243 mutex_unlock(&hotkey_mutex);
2244
2105 return rc; 2245 return rc;
2106} 2246}
2107 2247
@@ -2137,11 +2277,10 @@ static void tpacpi_input_send_tabletsw(void)
2137 } 2277 }
2138} 2278}
2139 2279
2140static void tpacpi_input_send_key(unsigned int scancode) 2280/* Do NOT call without validating scancode first */
2281static void tpacpi_input_send_key(const unsigned int scancode)
2141{ 2282{
2142 unsigned int keycode; 2283 const unsigned int keycode = hotkey_keycode_map[scancode];
2143
2144 keycode = hotkey_keycode_map[scancode];
2145 2284
2146 if (keycode != KEY_RESERVED) { 2285 if (keycode != KEY_RESERVED) {
2147 mutex_lock(&tpacpi_inputdev_send_mutex); 2286 mutex_lock(&tpacpi_inputdev_send_mutex);
@@ -2162,19 +2301,28 @@ static void tpacpi_input_send_key(unsigned int scancode)
2162 } 2301 }
2163} 2302}
2164 2303
2304/* Do NOT call without validating scancode first */
2305static void tpacpi_input_send_key_masked(const unsigned int scancode)
2306{
2307 hotkey_driver_event(scancode);
2308 if (hotkey_user_mask & (1 << scancode))
2309 tpacpi_input_send_key(scancode);
2310}
2311
2165#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2312#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2166static struct tp_acpi_drv_struct ibm_hotkey_acpidriver; 2313static struct tp_acpi_drv_struct ibm_hotkey_acpidriver;
2167 2314
2315/* Do NOT call without validating scancode first */
2168static void tpacpi_hotkey_send_key(unsigned int scancode) 2316static void tpacpi_hotkey_send_key(unsigned int scancode)
2169{ 2317{
2170 tpacpi_input_send_key(scancode); 2318 tpacpi_input_send_key_masked(scancode);
2171 if (hotkey_report_mode < 2) { 2319 if (hotkey_report_mode < 2) {
2172 acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device, 2320 acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device,
2173 0x80, 0x1001 + scancode); 2321 0x80, TP_HKEY_EV_HOTKEY_BASE + scancode);
2174 } 2322 }
2175} 2323}
2176 2324
2177static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m) 2325static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m)
2178{ 2326{
2179 u8 d; 2327 u8 d;
2180 2328
@@ -2210,21 +2358,24 @@ static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m)
2210 } 2358 }
2211} 2359}
2212 2360
2361static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2362 struct tp_nvram_state *newn,
2363 const u32 event_mask)
2364{
2365
2213#define TPACPI_COMPARE_KEY(__scancode, __member) \ 2366#define TPACPI_COMPARE_KEY(__scancode, __member) \
2214 do { \ 2367 do { \
2215 if ((mask & (1 << __scancode)) && \ 2368 if ((event_mask & (1 << __scancode)) && \
2216 oldn->__member != newn->__member) \ 2369 oldn->__member != newn->__member) \
2217 tpacpi_hotkey_send_key(__scancode); \ 2370 tpacpi_hotkey_send_key(__scancode); \
2218 } while (0) 2371 } while (0)
2219 2372
2220#define TPACPI_MAY_SEND_KEY(__scancode) \ 2373#define TPACPI_MAY_SEND_KEY(__scancode) \
2221 do { if (mask & (1 << __scancode)) \ 2374 do { \
2222 tpacpi_hotkey_send_key(__scancode); } while (0) 2375 if (event_mask & (1 << __scancode)) \
2376 tpacpi_hotkey_send_key(__scancode); \
2377 } while (0)
2223 2378
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); 2379 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle);
2229 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle); 2380 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle);
2230 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle); 2381 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle);
@@ -2270,15 +2421,22 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2270 } 2421 }
2271 } 2422 }
2272 } 2423 }
2273}
2274 2424
2275#undef TPACPI_COMPARE_KEY 2425#undef TPACPI_COMPARE_KEY
2276#undef TPACPI_MAY_SEND_KEY 2426#undef TPACPI_MAY_SEND_KEY
2427}
2277 2428
2429/*
2430 * Polling driver
2431 *
2432 * We track all events in hotkey_source_mask all the time, since
2433 * most of them are edge-based. We only issue those requested by
2434 * hotkey_user_mask or hotkey_driver_mask, though.
2435 */
2278static int hotkey_kthread(void *data) 2436static int hotkey_kthread(void *data)
2279{ 2437{
2280 struct tp_nvram_state s[2]; 2438 struct tp_nvram_state s[2];
2281 u32 mask; 2439 u32 poll_mask, event_mask;
2282 unsigned int si, so; 2440 unsigned int si, so;
2283 unsigned long t; 2441 unsigned long t;
2284 unsigned int change_detector, must_reset; 2442 unsigned int change_detector, must_reset;
@@ -2298,10 +2456,12 @@ static int hotkey_kthread(void *data)
2298 /* Initial state for compares */ 2456 /* Initial state for compares */
2299 mutex_lock(&hotkey_thread_data_mutex); 2457 mutex_lock(&hotkey_thread_data_mutex);
2300 change_detector = hotkey_config_change; 2458 change_detector = hotkey_config_change;
2301 mask = hotkey_source_mask & hotkey_mask; 2459 poll_mask = hotkey_source_mask;
2460 event_mask = hotkey_source_mask &
2461 (hotkey_driver_mask | hotkey_user_mask);
2302 poll_freq = hotkey_poll_freq; 2462 poll_freq = hotkey_poll_freq;
2303 mutex_unlock(&hotkey_thread_data_mutex); 2463 mutex_unlock(&hotkey_thread_data_mutex);
2304 hotkey_read_nvram(&s[so], mask); 2464 hotkey_read_nvram(&s[so], poll_mask);
2305 2465
2306 while (!kthread_should_stop()) { 2466 while (!kthread_should_stop()) {
2307 if (t == 0) { 2467 if (t == 0) {
@@ -2324,15 +2484,17 @@ static int hotkey_kthread(void *data)
2324 t = 0; 2484 t = 0;
2325 change_detector = hotkey_config_change; 2485 change_detector = hotkey_config_change;
2326 } 2486 }
2327 mask = hotkey_source_mask & hotkey_mask; 2487 poll_mask = hotkey_source_mask;
2488 event_mask = hotkey_source_mask &
2489 (hotkey_driver_mask | hotkey_user_mask);
2328 poll_freq = hotkey_poll_freq; 2490 poll_freq = hotkey_poll_freq;
2329 mutex_unlock(&hotkey_thread_data_mutex); 2491 mutex_unlock(&hotkey_thread_data_mutex);
2330 2492
2331 if (likely(mask)) { 2493 if (likely(poll_mask)) {
2332 hotkey_read_nvram(&s[si], mask); 2494 hotkey_read_nvram(&s[si], poll_mask);
2333 if (likely(si != so)) { 2495 if (likely(si != so)) {
2334 hotkey_compare_and_issue_event(&s[so], &s[si], 2496 hotkey_compare_and_issue_event(&s[so], &s[si],
2335 mask); 2497 event_mask);
2336 } 2498 }
2337 } 2499 }
2338 2500
@@ -2364,10 +2526,12 @@ static void hotkey_poll_stop_sync(void)
2364/* call with hotkey_mutex held */ 2526/* call with hotkey_mutex held */
2365static void hotkey_poll_setup(bool may_warn) 2527static void hotkey_poll_setup(bool may_warn)
2366{ 2528{
2367 u32 hotkeys_to_poll = hotkey_source_mask & hotkey_mask; 2529 const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
2530 const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
2368 2531
2369 if (hotkeys_to_poll != 0 && hotkey_poll_freq > 0 && 2532 if (hotkey_poll_freq > 0 &&
2370 (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { 2533 (poll_driver_mask ||
2534 (poll_user_mask && tpacpi_inputdev->users > 0))) {
2371 if (!tpacpi_hotkey_task) { 2535 if (!tpacpi_hotkey_task) {
2372 tpacpi_hotkey_task = kthread_run(hotkey_kthread, 2536 tpacpi_hotkey_task = kthread_run(hotkey_kthread,
2373 NULL, TPACPI_NVRAM_KTHREAD_NAME); 2537 NULL, TPACPI_NVRAM_KTHREAD_NAME);
@@ -2380,12 +2544,13 @@ static void hotkey_poll_setup(bool may_warn)
2380 } 2544 }
2381 } else { 2545 } else {
2382 hotkey_poll_stop_sync(); 2546 hotkey_poll_stop_sync();
2383 if (may_warn && hotkeys_to_poll != 0 && 2547 if (may_warn && (poll_driver_mask || poll_user_mask) &&
2384 hotkey_poll_freq == 0) { 2548 hotkey_poll_freq == 0) {
2385 printk(TPACPI_NOTICE 2549 printk(TPACPI_NOTICE
2386 "hot keys 0x%08x require polling, " 2550 "hot keys 0x%08x and/or events 0x%08x "
2387 "which is currently disabled\n", 2551 "require polling, which is currently "
2388 hotkeys_to_poll); 2552 "disabled\n",
2553 poll_user_mask, poll_driver_mask);
2389 } 2554 }
2390 } 2555 }
2391} 2556}
@@ -2403,9 +2568,7 @@ static void hotkey_poll_set_freq(unsigned int freq)
2403 if (!freq) 2568 if (!freq)
2404 hotkey_poll_stop_sync(); 2569 hotkey_poll_stop_sync();
2405 2570
2406 HOTKEY_CONFIG_CRITICAL_START
2407 hotkey_poll_freq = freq; 2571 hotkey_poll_freq = freq;
2408 HOTKEY_CONFIG_CRITICAL_END
2409} 2572}
2410 2573
2411#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 2574#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
@@ -2440,7 +2603,8 @@ static int hotkey_inputdev_open(struct input_dev *dev)
2440static void hotkey_inputdev_close(struct input_dev *dev) 2603static void hotkey_inputdev_close(struct input_dev *dev)
2441{ 2604{
2442 /* disable hotkey polling when possible */ 2605 /* disable hotkey polling when possible */
2443 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) 2606 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING &&
2607 !(hotkey_source_mask & hotkey_driver_mask))
2444 hotkey_poll_setup_safe(false); 2608 hotkey_poll_setup_safe(false);
2445} 2609}
2446 2610
@@ -2488,15 +2652,7 @@ static ssize_t hotkey_mask_show(struct device *dev,
2488 struct device_attribute *attr, 2652 struct device_attribute *attr,
2489 char *buf) 2653 char *buf)
2490{ 2654{
2491 int res; 2655 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} 2656}
2501 2657
2502static ssize_t hotkey_mask_store(struct device *dev, 2658static ssize_t hotkey_mask_store(struct device *dev,
@@ -2512,7 +2668,7 @@ static ssize_t hotkey_mask_store(struct device *dev,
2512 if (mutex_lock_killable(&hotkey_mutex)) 2668 if (mutex_lock_killable(&hotkey_mutex))
2513 return -ERESTARTSYS; 2669 return -ERESTARTSYS;
2514 2670
2515 res = hotkey_mask_set(t); 2671 res = hotkey_user_mask_set(t);
2516 2672
2517#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2673#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2518 hotkey_poll_setup(true); 2674 hotkey_poll_setup(true);
@@ -2594,6 +2750,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
2594 const char *buf, size_t count) 2750 const char *buf, size_t count)
2595{ 2751{
2596 unsigned long t; 2752 unsigned long t;
2753 u32 r_ev;
2754 int rc;
2597 2755
2598 if (parse_strtoul(buf, 0xffffffffUL, &t) || 2756 if (parse_strtoul(buf, 0xffffffffUL, &t) ||
2599 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0)) 2757 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0))
@@ -2606,14 +2764,28 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
2606 hotkey_source_mask = t; 2764 hotkey_source_mask = t;
2607 HOTKEY_CONFIG_CRITICAL_END 2765 HOTKEY_CONFIG_CRITICAL_END
2608 2766
2767 rc = hotkey_mask_set((hotkey_user_mask | hotkey_driver_mask) &
2768 ~hotkey_source_mask);
2609 hotkey_poll_setup(true); 2769 hotkey_poll_setup(true);
2610 hotkey_mask_set(hotkey_mask); 2770
2771 /* check if events needed by the driver got disabled */
2772 r_ev = hotkey_driver_mask & ~(hotkey_acpi_mask & hotkey_all_mask)
2773 & ~hotkey_source_mask & TPACPI_HKEY_NVRAM_KNOWN_MASK;
2611 2774
2612 mutex_unlock(&hotkey_mutex); 2775 mutex_unlock(&hotkey_mutex);
2613 2776
2777 if (rc < 0)
2778 printk(TPACPI_ERR "hotkey_source_mask: failed to update the"
2779 "firmware event mask!\n");
2780
2781 if (r_ev)
2782 printk(TPACPI_NOTICE "hotkey_source_mask: "
2783 "some important events were disabled: "
2784 "0x%04x\n", r_ev);
2785
2614 tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); 2786 tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
2615 2787
2616 return count; 2788 return (rc < 0) ? rc : count;
2617} 2789}
2618 2790
2619static struct device_attribute dev_attr_hotkey_source_mask = 2791static struct device_attribute dev_attr_hotkey_source_mask =
@@ -2731,9 +2903,8 @@ static struct device_attribute dev_attr_hotkey_wakeup_reason =
2731 2903
2732static void hotkey_wakeup_reason_notify_change(void) 2904static void hotkey_wakeup_reason_notify_change(void)
2733{ 2905{
2734 if (tp_features.hotkey_mask) 2906 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2735 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2907 "wakeup_reason");
2736 "wakeup_reason");
2737} 2908}
2738 2909
2739/* sysfs wakeup hotunplug_complete (pollable) -------------------------- */ 2910/* sysfs wakeup hotunplug_complete (pollable) -------------------------- */
@@ -2750,9 +2921,8 @@ static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete =
2750 2921
2751static void hotkey_wakeup_hotunplug_complete_notify_change(void) 2922static void hotkey_wakeup_hotunplug_complete_notify_change(void)
2752{ 2923{
2753 if (tp_features.hotkey_mask) 2924 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2754 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2925 "wakeup_hotunplug_complete");
2755 "wakeup_hotunplug_complete");
2756} 2926}
2757 2927
2758/* --------------------------------------------------------------------- */ 2928/* --------------------------------------------------------------------- */
@@ -2760,27 +2930,19 @@ static void hotkey_wakeup_hotunplug_complete_notify_change(void)
2760static struct attribute *hotkey_attributes[] __initdata = { 2930static struct attribute *hotkey_attributes[] __initdata = {
2761 &dev_attr_hotkey_enable.attr, 2931 &dev_attr_hotkey_enable.attr,
2762 &dev_attr_hotkey_bios_enabled.attr, 2932 &dev_attr_hotkey_bios_enabled.attr,
2933 &dev_attr_hotkey_bios_mask.attr,
2763 &dev_attr_hotkey_report_mode.attr, 2934 &dev_attr_hotkey_report_mode.attr,
2764#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2935 &dev_attr_hotkey_wakeup_reason.attr,
2936 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2765 &dev_attr_hotkey_mask.attr, 2937 &dev_attr_hotkey_mask.attr,
2766 &dev_attr_hotkey_all_mask.attr, 2938 &dev_attr_hotkey_all_mask.attr,
2767 &dev_attr_hotkey_recommended_mask.attr, 2939 &dev_attr_hotkey_recommended_mask.attr,
2940#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2768 &dev_attr_hotkey_source_mask.attr, 2941 &dev_attr_hotkey_source_mask.attr,
2769 &dev_attr_hotkey_poll_freq.attr, 2942 &dev_attr_hotkey_poll_freq.attr,
2770#endif 2943#endif
2771}; 2944};
2772 2945
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/* 2946/*
2785 * Sync both the hw and sw blocking state of all switches 2947 * Sync both the hw and sw blocking state of all switches
2786 */ 2948 */
@@ -2843,16 +3005,16 @@ static void hotkey_exit(void)
2843 3005
2844 kfree(hotkey_keycode_map); 3006 kfree(hotkey_keycode_map);
2845 3007
2846 if (tp_features.hotkey) { 3008 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
2847 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY, 3009 "restoring original HKEY status and mask\n");
2848 "restoring original hot key mask\n"); 3010 /* yes, there is a bitwise or below, we want the
2849 /* no short-circuit boolean operator below! */ 3011 * functions to be called even if one of them fail */
2850 if ((hotkey_mask_set(hotkey_orig_mask) | 3012 if (((tp_features.hotkey_mask &&
2851 hotkey_status_set(false)) != 0) 3013 hotkey_mask_set(hotkey_orig_mask)) |
2852 printk(TPACPI_ERR 3014 hotkey_status_set(false)) != 0)
2853 "failed to restore hot key mask " 3015 printk(TPACPI_ERR
2854 "to BIOS defaults\n"); 3016 "failed to restore hot key mask "
2855 } 3017 "to BIOS defaults\n");
2856} 3018}
2857 3019
2858static void __init hotkey_unmap(const unsigned int scancode) 3020static void __init hotkey_unmap(const unsigned int scancode)
@@ -2864,6 +3026,35 @@ static void __init hotkey_unmap(const unsigned int scancode)
2864 } 3026 }
2865} 3027}
2866 3028
3029/*
3030 * HKEY quirks:
3031 * TPACPI_HK_Q_INIMASK: Supports FN+F3,FN+F4,FN+F12
3032 */
3033
3034#define TPACPI_HK_Q_INIMASK 0x0001
3035
3036static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
3037 TPACPI_Q_IBM('I', 'H', TPACPI_HK_Q_INIMASK), /* 600E */
3038 TPACPI_Q_IBM('I', 'N', TPACPI_HK_Q_INIMASK), /* 600E */
3039 TPACPI_Q_IBM('I', 'D', TPACPI_HK_Q_INIMASK), /* 770, 770E, 770ED */
3040 TPACPI_Q_IBM('I', 'W', TPACPI_HK_Q_INIMASK), /* A20m */
3041 TPACPI_Q_IBM('I', 'V', TPACPI_HK_Q_INIMASK), /* A20p */
3042 TPACPI_Q_IBM('1', '0', TPACPI_HK_Q_INIMASK), /* A21e, A22e */
3043 TPACPI_Q_IBM('K', 'U', TPACPI_HK_Q_INIMASK), /* A21e */
3044 TPACPI_Q_IBM('K', 'X', TPACPI_HK_Q_INIMASK), /* A21m, A22m */
3045 TPACPI_Q_IBM('K', 'Y', TPACPI_HK_Q_INIMASK), /* A21p, A22p */
3046 TPACPI_Q_IBM('1', 'B', TPACPI_HK_Q_INIMASK), /* A22e */
3047 TPACPI_Q_IBM('1', '3', TPACPI_HK_Q_INIMASK), /* A22m */
3048 TPACPI_Q_IBM('1', 'E', TPACPI_HK_Q_INIMASK), /* A30/p (0) */
3049 TPACPI_Q_IBM('1', 'C', TPACPI_HK_Q_INIMASK), /* R30 */
3050 TPACPI_Q_IBM('1', 'F', TPACPI_HK_Q_INIMASK), /* R31 */
3051 TPACPI_Q_IBM('I', 'Y', TPACPI_HK_Q_INIMASK), /* T20 */
3052 TPACPI_Q_IBM('K', 'Z', TPACPI_HK_Q_INIMASK), /* T21 */
3053 TPACPI_Q_IBM('1', '6', TPACPI_HK_Q_INIMASK), /* T22 */
3054 TPACPI_Q_IBM('I', 'Z', TPACPI_HK_Q_INIMASK), /* X20, X21 */
3055 TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */
3056};
3057
2867static int __init hotkey_init(struct ibm_init_struct *iibm) 3058static int __init hotkey_init(struct ibm_init_struct *iibm)
2868{ 3059{
2869 /* Requirements for changing the default keymaps: 3060 /* Requirements for changing the default keymaps:
@@ -2906,9 +3097,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2906 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 3097 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
2907 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 3098 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
2908 3099
2909 /* brightness: firmware always reacts to them, unless 3100 /* brightness: firmware always reacts to them */
2910 * X.org did some tricks in the radeon BIOS scratch
2911 * registers of *some* models */
2912 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 3101 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
2913 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 3102 KEY_RESERVED, /* 0x10: FN+END (brightness down) */
2914 3103
@@ -2983,6 +3172,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2983 int status; 3172 int status;
2984 int hkeyv; 3173 int hkeyv;
2985 3174
3175 unsigned long quirks;
3176
2986 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3177 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2987 "initializing hotkey subdriver\n"); 3178 "initializing hotkey subdriver\n");
2988 3179
@@ -3008,9 +3199,16 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3008 if (!tp_features.hotkey) 3199 if (!tp_features.hotkey)
3009 return 1; 3200 return 1;
3010 3201
3202 quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable,
3203 ARRAY_SIZE(tpacpi_hotkey_qtable));
3204
3011 tpacpi_disable_brightness_delay(); 3205 tpacpi_disable_brightness_delay();
3012 3206
3013 hotkey_dev_attributes = create_attr_set(13, NULL); 3207 /* MUST have enough space for all attributes to be added to
3208 * hotkey_dev_attributes */
3209 hotkey_dev_attributes = create_attr_set(
3210 ARRAY_SIZE(hotkey_attributes) + 2,
3211 NULL);
3014 if (!hotkey_dev_attributes) 3212 if (!hotkey_dev_attributes)
3015 return -ENOMEM; 3213 return -ENOMEM;
3016 res = add_many_to_attr_set(hotkey_dev_attributes, 3214 res = add_many_to_attr_set(hotkey_dev_attributes,
@@ -3019,7 +3217,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3019 if (res) 3217 if (res)
3020 goto err_exit; 3218 goto err_exit;
3021 3219
3022 /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 3220 /* mask not supported on 600e/x, 770e, 770x, A21e, A2xm/p,
3023 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking 3221 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking
3024 for HKEY interface version 0x100 */ 3222 for HKEY interface version 0x100 */
3025 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { 3223 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
@@ -3033,10 +3231,22 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3033 * MHKV 0x100 in A31, R40, R40e, 3231 * MHKV 0x100 in A31, R40, R40e,
3034 * T4x, X31, and later 3232 * T4x, X31, and later
3035 */ 3233 */
3036 tp_features.hotkey_mask = 1;
3037 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3234 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3038 "firmware HKEY interface version: 0x%x\n", 3235 "firmware HKEY interface version: 0x%x\n",
3039 hkeyv); 3236 hkeyv);
3237
3238 /* Paranoia check AND init hotkey_all_mask */
3239 if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
3240 "MHKA", "qd")) {
3241 printk(TPACPI_ERR
3242 "missing MHKA handler, "
3243 "please report this to %s\n",
3244 TPACPI_MAIL);
3245 /* Fallback: pre-init for FN+F3,F4,F12 */
3246 hotkey_all_mask = 0x080cU;
3247 } else {
3248 tp_features.hotkey_mask = 1;
3249 }
3040 } 3250 }
3041 } 3251 }
3042 3252
@@ -3044,32 +3254,23 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3044 "hotkey masks are %s\n", 3254 "hotkey masks are %s\n",
3045 str_supported(tp_features.hotkey_mask)); 3255 str_supported(tp_features.hotkey_mask));
3046 3256
3047 if (tp_features.hotkey_mask) { 3257 /* Init hotkey_all_mask if not initialized yet */
3048 if (!acpi_evalf(hkey_handle, &hotkey_all_mask, 3258 if (!tp_features.hotkey_mask && !hotkey_all_mask &&
3049 "MHKA", "qd")) { 3259 (quirks & TPACPI_HK_Q_INIMASK))
3050 printk(TPACPI_ERR 3260 hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */
3051 "missing MHKA handler, "
3052 "please report this to %s\n",
3053 TPACPI_MAIL);
3054 /* FN+F12, FN+F4, FN+F3 */
3055 hotkey_all_mask = 0x080cU;
3056 }
3057 }
3058 3261
3059 /* hotkey_source_mask *must* be zero for 3262 /* Init hotkey_acpi_mask and hotkey_orig_mask */
3060 * the first hotkey_mask_get */
3061 if (tp_features.hotkey_mask) { 3263 if (tp_features.hotkey_mask) {
3264 /* hotkey_source_mask *must* be zero for
3265 * the first hotkey_mask_get to return hotkey_orig_mask */
3062 res = hotkey_mask_get(); 3266 res = hotkey_mask_get();
3063 if (res) 3267 if (res)
3064 goto err_exit; 3268 goto err_exit;
3065 3269
3066 hotkey_orig_mask = hotkey_mask; 3270 hotkey_orig_mask = hotkey_acpi_mask;
3067 res = add_many_to_attr_set( 3271 } else {
3068 hotkey_dev_attributes, 3272 hotkey_orig_mask = hotkey_all_mask;
3069 hotkey_mask_attributes, 3273 hotkey_acpi_mask = hotkey_all_mask;
3070 ARRAY_SIZE(hotkey_mask_attributes));
3071 if (res)
3072 goto err_exit;
3073 } 3274 }
3074 3275
3075#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3276#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
@@ -3183,14 +3384,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3183 } 3384 }
3184 3385
3185#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 3386#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
3186 if (tp_features.hotkey_mask) { 3387 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
3187 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK 3388 & ~hotkey_all_mask
3188 & ~hotkey_all_mask 3389 & ~hotkey_reserved_mask;
3189 & ~hotkey_reserved_mask;
3190 } else {
3191 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
3192 & ~hotkey_reserved_mask;
3193 }
3194 3390
3195 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3391 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3196 "hotkey source mask 0x%08x, polling freq %u\n", 3392 "hotkey source mask 0x%08x, polling freq %u\n",
@@ -3204,13 +3400,18 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3204 hotkey_exit(); 3400 hotkey_exit();
3205 return res; 3401 return res;
3206 } 3402 }
3207 res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) 3403 res = hotkey_mask_set(((hotkey_all_mask & ~hotkey_reserved_mask)
3208 & ~hotkey_reserved_mask) 3404 | hotkey_driver_mask)
3209 | hotkey_orig_mask); 3405 & ~hotkey_source_mask);
3210 if (res < 0 && res != -ENXIO) { 3406 if (res < 0 && res != -ENXIO) {
3211 hotkey_exit(); 3407 hotkey_exit();
3212 return res; 3408 return res;
3213 } 3409 }
3410 hotkey_user_mask = (hotkey_acpi_mask | hotkey_source_mask)
3411 & ~hotkey_reserved_mask;
3412 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3413 "initial masks: user=0x%08x, fw=0x%08x, poll=0x%08x\n",
3414 hotkey_user_mask, hotkey_acpi_mask, hotkey_source_mask);
3214 3415
3215 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3416 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3216 "legacy ibm/hotkey event reporting over procfs %s\n", 3417 "legacy ibm/hotkey event reporting over procfs %s\n",
@@ -3245,7 +3446,7 @@ static bool hotkey_notify_hotkey(const u32 hkey,
3245 if (scancode > 0 && scancode < 0x21) { 3446 if (scancode > 0 && scancode < 0x21) {
3246 scancode--; 3447 scancode--;
3247 if (!(hotkey_source_mask & (1 << scancode))) { 3448 if (!(hotkey_source_mask & (1 << scancode))) {
3248 tpacpi_input_send_key(scancode); 3449 tpacpi_input_send_key_masked(scancode);
3249 *send_acpi_ev = false; 3450 *send_acpi_ev = false;
3250 } else { 3451 } else {
3251 *ignore_acpi_ev = true; 3452 *ignore_acpi_ev = true;
@@ -3264,20 +3465,20 @@ static bool hotkey_notify_wakeup(const u32 hkey,
3264 *ignore_acpi_ev = false; 3465 *ignore_acpi_ev = false;
3265 3466
3266 switch (hkey) { 3467 switch (hkey) {
3267 case 0x2304: /* suspend, undock */ 3468 case TP_HKEY_EV_WKUP_S3_UNDOCK: /* suspend, undock */
3268 case 0x2404: /* hibernation, undock */ 3469 case TP_HKEY_EV_WKUP_S4_UNDOCK: /* hibernation, undock */
3269 hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK; 3470 hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK;
3270 *ignore_acpi_ev = true; 3471 *ignore_acpi_ev = true;
3271 break; 3472 break;
3272 3473
3273 case 0x2305: /* suspend, bay eject */ 3474 case TP_HKEY_EV_WKUP_S3_BAYEJ: /* suspend, bay eject */
3274 case 0x2405: /* hibernation, bay eject */ 3475 case TP_HKEY_EV_WKUP_S4_BAYEJ: /* hibernation, bay eject */
3275 hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ; 3476 hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ;
3276 *ignore_acpi_ev = true; 3477 *ignore_acpi_ev = true;
3277 break; 3478 break;
3278 3479
3279 case 0x2313: /* Battery on critical low level (S3) */ 3480 case TP_HKEY_EV_WKUP_S3_BATLOW: /* Battery on critical low level/S3 */
3280 case 0x2413: /* Battery on critical low level (S4) */ 3481 case TP_HKEY_EV_WKUP_S4_BATLOW: /* Battery on critical low level/S4 */
3281 printk(TPACPI_ALERT 3482 printk(TPACPI_ALERT
3282 "EMERGENCY WAKEUP: battery almost empty\n"); 3483 "EMERGENCY WAKEUP: battery almost empty\n");
3283 /* how to auto-heal: */ 3484 /* how to auto-heal: */
@@ -3307,21 +3508,21 @@ static bool hotkey_notify_usrevent(const u32 hkey,
3307 *ignore_acpi_ev = false; 3508 *ignore_acpi_ev = false;
3308 3509
3309 switch (hkey) { 3510 switch (hkey) {
3310 case 0x5010: /* Lenovo new BIOS: brightness changed */ 3511 case TP_HKEY_EV_PEN_INSERTED: /* X61t: tablet pen inserted into bay */
3311 case 0x500b: /* X61t: tablet pen inserted into bay */ 3512 case TP_HKEY_EV_PEN_REMOVED: /* X61t: tablet pen removed from bay */
3312 case 0x500c: /* X61t: tablet pen removed from bay */
3313 return true; 3513 return true;
3314 3514
3315 case 0x5009: /* X41t-X61t: swivel up (tablet mode) */ 3515 case TP_HKEY_EV_TABLET_TABLET: /* X41t-X61t: tablet mode */
3316 case 0x500a: /* X41t-X61t: swivel down (normal mode) */ 3516 case TP_HKEY_EV_TABLET_NOTEBOOK: /* X41t-X61t: normal mode */
3317 tpacpi_input_send_tabletsw(); 3517 tpacpi_input_send_tabletsw();
3318 hotkey_tablet_mode_notify_change(); 3518 hotkey_tablet_mode_notify_change();
3319 *send_acpi_ev = false; 3519 *send_acpi_ev = false;
3320 return true; 3520 return true;
3321 3521
3322 case 0x5001: 3522 case TP_HKEY_EV_LID_CLOSE: /* Lid closed */
3323 case 0x5002: 3523 case TP_HKEY_EV_LID_OPEN: /* Lid opened */
3324 /* LID switch events. Do not propagate */ 3524 case TP_HKEY_EV_BRGHT_CHANGED: /* brightness changed */
3525 /* do not propagate these events */
3325 *ignore_acpi_ev = true; 3526 *ignore_acpi_ev = true;
3326 return true; 3527 return true;
3327 3528
@@ -3339,30 +3540,30 @@ static bool hotkey_notify_thermal(const u32 hkey,
3339 *ignore_acpi_ev = false; 3540 *ignore_acpi_ev = false;
3340 3541
3341 switch (hkey) { 3542 switch (hkey) {
3342 case 0x6011: 3543 case TP_HKEY_EV_ALARM_BAT_HOT:
3343 printk(TPACPI_CRIT 3544 printk(TPACPI_CRIT
3344 "THERMAL ALARM: battery is too hot!\n"); 3545 "THERMAL ALARM: battery is too hot!\n");
3345 /* recommended action: warn user through gui */ 3546 /* recommended action: warn user through gui */
3346 return true; 3547 return true;
3347 case 0x6012: 3548 case TP_HKEY_EV_ALARM_BAT_XHOT:
3348 printk(TPACPI_ALERT 3549 printk(TPACPI_ALERT
3349 "THERMAL EMERGENCY: battery is extremely hot!\n"); 3550 "THERMAL EMERGENCY: battery is extremely hot!\n");
3350 /* recommended action: immediate sleep/hibernate */ 3551 /* recommended action: immediate sleep/hibernate */
3351 return true; 3552 return true;
3352 case 0x6021: 3553 case TP_HKEY_EV_ALARM_SENSOR_HOT:
3353 printk(TPACPI_CRIT 3554 printk(TPACPI_CRIT
3354 "THERMAL ALARM: " 3555 "THERMAL ALARM: "
3355 "a sensor reports something is too hot!\n"); 3556 "a sensor reports something is too hot!\n");
3356 /* recommended action: warn user through gui, that */ 3557 /* recommended action: warn user through gui, that */
3357 /* some internal component is too hot */ 3558 /* some internal component is too hot */
3358 return true; 3559 return true;
3359 case 0x6022: 3560 case TP_HKEY_EV_ALARM_SENSOR_XHOT:
3360 printk(TPACPI_ALERT 3561 printk(TPACPI_ALERT
3361 "THERMAL EMERGENCY: " 3562 "THERMAL EMERGENCY: "
3362 "a sensor reports something is extremely hot!\n"); 3563 "a sensor reports something is extremely hot!\n");
3363 /* recommended action: immediate sleep/hibernate */ 3564 /* recommended action: immediate sleep/hibernate */
3364 return true; 3565 return true;
3365 case 0x6030: 3566 case TP_HKEY_EV_THM_TABLE_CHANGED:
3366 printk(TPACPI_INFO 3567 printk(TPACPI_INFO
3367 "EC reports that Thermal Table has changed\n"); 3568 "EC reports that Thermal Table has changed\n");
3368 /* recommended action: do nothing, we don't have 3569 /* recommended action: do nothing, we don't have
@@ -3420,7 +3621,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
3420 break; 3621 break;
3421 case 3: 3622 case 3:
3422 /* 0x3000-0x3FFF: bay-related wakeups */ 3623 /* 0x3000-0x3FFF: bay-related wakeups */
3423 if (hkey == 0x3003) { 3624 if (hkey == TP_HKEY_EV_BAYEJ_ACK) {
3424 hotkey_autosleep_ack = 1; 3625 hotkey_autosleep_ack = 1;
3425 printk(TPACPI_INFO 3626 printk(TPACPI_INFO
3426 "bay ejected\n"); 3627 "bay ejected\n");
@@ -3432,7 +3633,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
3432 break; 3633 break;
3433 case 4: 3634 case 4:
3434 /* 0x4000-0x4FFF: dock-related wakeups */ 3635 /* 0x4000-0x4FFF: dock-related wakeups */
3435 if (hkey == 0x4003) { 3636 if (hkey == TP_HKEY_EV_UNDOCK_ACK) {
3436 hotkey_autosleep_ack = 1; 3637 hotkey_autosleep_ack = 1;
3437 printk(TPACPI_INFO 3638 printk(TPACPI_INFO
3438 "undocked\n"); 3639 "undocked\n");
@@ -3454,7 +3655,8 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
3454 break; 3655 break;
3455 case 7: 3656 case 7:
3456 /* 0x7000-0x7FFF: misc */ 3657 /* 0x7000-0x7FFF: misc */
3457 if (tp_features.hotkey_wlsw && hkey == 0x7000) { 3658 if (tp_features.hotkey_wlsw &&
3659 hkey == TP_HKEY_EV_RFKILL_CHANGED) {
3458 tpacpi_send_radiosw_update(); 3660 tpacpi_send_radiosw_update();
3459 send_acpi_ev = 0; 3661 send_acpi_ev = 0;
3460 known_ev = true; 3662 known_ev = true;
@@ -3500,10 +3702,12 @@ static void hotkey_resume(void)
3500{ 3702{
3501 tpacpi_disable_brightness_delay(); 3703 tpacpi_disable_brightness_delay();
3502 3704
3503 if (hotkey_mask_get()) 3705 if (hotkey_status_set(true) < 0 ||
3706 hotkey_mask_set(hotkey_acpi_mask) < 0)
3504 printk(TPACPI_ERR 3707 printk(TPACPI_ERR
3505 "error while trying to read hot key mask " 3708 "error while attempting to reset the event "
3506 "from firmware\n"); 3709 "firmware interface\n");
3710
3507 tpacpi_send_radiosw_update(); 3711 tpacpi_send_radiosw_update();
3508 hotkey_tablet_mode_notify_change(); 3712 hotkey_tablet_mode_notify_change();
3509 hotkey_wakeup_reason_notify_change(); 3713 hotkey_wakeup_reason_notify_change();
@@ -3532,8 +3736,8 @@ static int hotkey_read(char *p)
3532 return res; 3736 return res;
3533 3737
3534 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); 3738 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
3535 if (tp_features.hotkey_mask) { 3739 if (hotkey_all_mask) {
3536 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_mask); 3740 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_user_mask);
3537 len += sprintf(p + len, 3741 len += sprintf(p + len,
3538 "commands:\tenable, disable, reset, <mask>\n"); 3742 "commands:\tenable, disable, reset, <mask>\n");
3539 } else { 3743 } else {
@@ -3570,7 +3774,7 @@ static int hotkey_write(char *buf)
3570 if (mutex_lock_killable(&hotkey_mutex)) 3774 if (mutex_lock_killable(&hotkey_mutex))
3571 return -ERESTARTSYS; 3775 return -ERESTARTSYS;
3572 3776
3573 mask = hotkey_mask; 3777 mask = hotkey_user_mask;
3574 3778
3575 res = 0; 3779 res = 0;
3576 while ((cmd = next_cmd(&buf))) { 3780 while ((cmd = next_cmd(&buf))) {
@@ -3592,12 +3796,11 @@ static int hotkey_write(char *buf)
3592 } 3796 }
3593 } 3797 }
3594 3798
3595 if (!res) 3799 if (!res) {
3596 tpacpi_disclose_usertask("procfs hotkey", 3800 tpacpi_disclose_usertask("procfs hotkey",
3597 "set mask to 0x%08x\n", mask); 3801 "set mask to 0x%08x\n", mask);
3598 3802 res = hotkey_user_mask_set(mask);
3599 if (!res && mask != hotkey_mask) 3803 }
3600 res = hotkey_mask_set(mask);
3601 3804
3602errexit: 3805errexit:
3603 mutex_unlock(&hotkey_mutex); 3806 mutex_unlock(&hotkey_mutex);
@@ -6010,8 +6213,10 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6010 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, 6213 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
6011 &ibm_backlight_data); 6214 &ibm_backlight_data);
6012 if (IS_ERR(ibm_backlight_device)) { 6215 if (IS_ERR(ibm_backlight_device)) {
6216 int rc = PTR_ERR(ibm_backlight_device);
6217 ibm_backlight_device = NULL;
6013 printk(TPACPI_ERR "Could not register backlight device\n"); 6218 printk(TPACPI_ERR "Could not register backlight device\n");
6014 return PTR_ERR(ibm_backlight_device); 6219 return rc;
6015 } 6220 }
6016 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, 6221 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6017 "brightness is supported\n"); 6222 "brightness is supported\n");
@@ -7499,6 +7704,21 @@ static struct ibm_struct fan_driver_data = {
7499 **************************************************************************** 7704 ****************************************************************************
7500 ****************************************************************************/ 7705 ****************************************************************************/
7501 7706
7707/*
7708 * HKEY event callout for other subdrivers go here
7709 * (yes, it is ugly, but it is quick, safe, and gets the job done
7710 */
7711static void tpacpi_driver_event(const unsigned int hkey_event)
7712{
7713}
7714
7715
7716
7717static void hotkey_driver_event(const unsigned int scancode)
7718{
7719 tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode);
7720}
7721
7502/* sysfs name ---------------------------------------------------------- */ 7722/* sysfs name ---------------------------------------------------------- */
7503static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, 7723static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
7504 struct device_attribute *attr, 7724 struct device_attribute *attr,