aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-04-05 01:42:09 -0400
committerLen Brown <len.brown@intel.com>2009-04-05 01:42:09 -0400
commit336d63b8a3cadc1c678f4b16d6105633c7f6af75 (patch)
treed8d713eb39500139ec637c55cc38e62d863d1845 /drivers/platform
parent07290bed7968c0e08fb3efe193fb148f1fea5e08 (diff)
parent0e501834f8c2ba7de2a56e332d346dcf4ac0b593 (diff)
Merge branch 'thinkpad-acpi' into release
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/Kconfig24
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c735
2 files changed, 560 insertions, 199 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 3608081bc3e0..d45c6ab729f8 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -226,6 +226,30 @@ config THINKPAD_ACPI_DEBUG
226 226
227 If you are not sure, say N here. 227 If you are not sure, say N here.
228 228
229config THINKPAD_ACPI_UNSAFE_LEDS
230 bool "Allow control of important LEDs (unsafe)"
231 depends on THINKPAD_ACPI
232 default n
233 ---help---
234 Overriding LED state on ThinkPads can mask important
235 firmware alerts (like critical battery condition), or misled
236 the user into damaging the hardware (undocking or ejecting
237 the bay while buses are still active), etc.
238
239 LED control on the ThinkPad is write-only (with very few
240 exceptions on very ancient models), which makes it
241 impossible to know beforehand if important information will
242 be lost when one changes LED state.
243
244 Users that know what they are doing can enable this option
245 and the driver will allow control of every LED, including
246 the ones on the dock stations.
247
248 Never enable this option on a distribution kernel.
249
250 Say N here, unless you are building a kernel for your own
251 use, and need to control the important firmware LEDs.
252
229config THINKPAD_ACPI_DOCK 253config THINKPAD_ACPI_DOCK
230 bool "Legacy Docking Station Support" 254 bool "Legacy Docking Station Support"
231 depends on THINKPAD_ACPI 255 depends on THINKPAD_ACPI
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index d2433204a40c..ba3682c5cde0 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * 4 *
5 * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net> 5 * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
6 * Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br> 6 * Copyright (C) 2006-2009 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
22 */ 22 */
23 23
24#define TPACPI_VERSION "0.22" 24#define TPACPI_VERSION "0.22"
25#define TPACPI_SYSFS_VERSION 0x020200 25#define TPACPI_SYSFS_VERSION 0x020300
26 26
27/* 27/*
28 * Changelog: 28 * Changelog:
@@ -54,6 +54,7 @@
54#include <linux/string.h> 54#include <linux/string.h>
55#include <linux/list.h> 55#include <linux/list.h>
56#include <linux/mutex.h> 56#include <linux/mutex.h>
57#include <linux/sched.h>
57#include <linux/kthread.h> 58#include <linux/kthread.h>
58#include <linux/freezer.h> 59#include <linux/freezer.h>
59#include <linux/delay.h> 60#include <linux/delay.h>
@@ -172,29 +173,26 @@ enum {
172 TPACPI_RFK_UWB_SW_ID, 173 TPACPI_RFK_UWB_SW_ID,
173}; 174};
174 175
175/* Debugging */ 176/* printk headers */
176#define TPACPI_LOG TPACPI_FILE ": " 177#define TPACPI_LOG TPACPI_FILE ": "
177#define TPACPI_ALERT KERN_ALERT TPACPI_LOG 178#define TPACPI_EMERG KERN_EMERG TPACPI_LOG
178#define TPACPI_CRIT KERN_CRIT TPACPI_LOG 179#define TPACPI_ALERT KERN_ALERT TPACPI_LOG
179#define TPACPI_ERR KERN_ERR TPACPI_LOG 180#define TPACPI_CRIT KERN_CRIT TPACPI_LOG
180#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG 181#define TPACPI_ERR KERN_ERR TPACPI_LOG
181#define TPACPI_INFO KERN_INFO TPACPI_LOG 182#define TPACPI_WARN KERN_WARNING TPACPI_LOG
182#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG 183#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
183 184#define TPACPI_INFO KERN_INFO TPACPI_LOG
185#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG
186
187/* Debugging printk groups */
184#define TPACPI_DBG_ALL 0xffff 188#define TPACPI_DBG_ALL 0xffff
189#define TPACPI_DBG_DISCLOSETASK 0x8000
185#define TPACPI_DBG_INIT 0x0001 190#define TPACPI_DBG_INIT 0x0001
186#define TPACPI_DBG_EXIT 0x0002 191#define TPACPI_DBG_EXIT 0x0002
187#define dbg_printk(a_dbg_level, format, arg...) \ 192#define TPACPI_DBG_RFKILL 0x0004
188 do { if (dbg_level & a_dbg_level) \ 193#define TPACPI_DBG_HKEY 0x0008
189 printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \ 194#define TPACPI_DBG_FAN 0x0010
190 } while (0) 195#define TPACPI_DBG_BRGHT 0x0020
191#ifdef CONFIG_THINKPAD_ACPI_DEBUG
192#define vdbg_printk(a_dbg_level, format, arg...) \
193 dbg_printk(a_dbg_level, format, ## arg)
194static const char *str_supported(int is_supported);
195#else
196#define vdbg_printk(a_dbg_level, format, arg...)
197#endif
198 196
199#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") 197#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
200#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") 198#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -277,7 +275,6 @@ static struct {
277 275
278static struct { 276static struct {
279 u16 hotkey_mask_ff:1; 277 u16 hotkey_mask_ff:1;
280 u16 bright_cmos_ec_unsync:1;
281} tp_warned; 278} tp_warned;
282 279
283struct thinkpad_id_data { 280struct thinkpad_id_data {
@@ -326,6 +323,39 @@ static int tpacpi_uwb_emulstate;
326#endif 323#endif
327 324
328 325
326/*************************************************************************
327 * Debugging helpers
328 */
329
330#define dbg_printk(a_dbg_level, format, arg...) \
331 do { if (dbg_level & (a_dbg_level)) \
332 printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
333 } while (0)
334
335#ifdef CONFIG_THINKPAD_ACPI_DEBUG
336#define vdbg_printk dbg_printk
337static const char *str_supported(int is_supported);
338#else
339#define vdbg_printk(a_dbg_level, format, arg...) \
340 do { } while (0)
341#endif
342
343static void tpacpi_log_usertask(const char * const what)
344{
345 printk(TPACPI_DEBUG "%s: access by process with PID %d\n",
346 what, task_tgid_vnr(current));
347}
348
349#define tpacpi_disclose_usertask(what, format, arg...) \
350 do { \
351 if (unlikely( \
352 (dbg_level & TPACPI_DBG_DISCLOSETASK) && \
353 (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \
354 printk(TPACPI_DEBUG "%s: PID %d: " format, \
355 what, task_tgid_vnr(current), ## arg); \
356 } \
357 } while (0)
358
329/**************************************************************************** 359/****************************************************************************
330 **************************************************************************** 360 ****************************************************************************
331 * 361 *
@@ -989,10 +1019,13 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
989 /* try to set the initial state as the default for the rfkill 1019 /* try to set the initial state as the default for the rfkill
990 * type, since we ask the firmware to preserve it across S5 in 1020 * type, since we ask the firmware to preserve it across S5 in
991 * NVRAM */ 1021 * NVRAM */
992 rfkill_set_default(rfktype, 1022 if (rfkill_set_default(rfktype,
993 (initial_state == RFKILL_STATE_UNBLOCKED) ? 1023 (initial_state == RFKILL_STATE_UNBLOCKED) ?
994 RFKILL_STATE_UNBLOCKED : 1024 RFKILL_STATE_UNBLOCKED :
995 RFKILL_STATE_SOFT_BLOCKED); 1025 RFKILL_STATE_SOFT_BLOCKED) == -EPERM)
1026 vdbg_printk(TPACPI_DBG_RFKILL,
1027 "Default state for %s cannot be changed\n",
1028 name);
996 } 1029 }
997 1030
998 *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype); 1031 *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
@@ -1020,6 +1053,21 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
1020 return 0; 1053 return 0;
1021} 1054}
1022 1055
1056static void printk_deprecated_attribute(const char * const what,
1057 const char * const details)
1058{
1059 tpacpi_log_usertask("deprecated sysfs attribute");
1060 printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
1061 "will be removed. %s\n",
1062 what, details);
1063}
1064
1065static void printk_deprecated_rfkill_attribute(const char * const what)
1066{
1067 printk_deprecated_attribute(what,
1068 "Please switch to generic rfkill before year 2010");
1069}
1070
1023/************************************************************************* 1071/*************************************************************************
1024 * thinkpad-acpi driver attributes 1072 * thinkpad-acpi driver attributes
1025 */ 1073 */
@@ -1382,7 +1430,6 @@ static enum { /* Reasons for waking up */
1382 1430
1383static int hotkey_autosleep_ack; 1431static int hotkey_autosleep_ack;
1384 1432
1385static int hotkey_orig_status;
1386static u32 hotkey_orig_mask; 1433static u32 hotkey_orig_mask;
1387static u32 hotkey_all_mask; 1434static u32 hotkey_all_mask;
1388static u32 hotkey_reserved_mask; 1435static u32 hotkey_reserved_mask;
@@ -1529,9 +1576,9 @@ static int hotkey_status_get(int *status)
1529 return 0; 1576 return 0;
1530} 1577}
1531 1578
1532static int hotkey_status_set(int status) 1579static int hotkey_status_set(bool enable)
1533{ 1580{
1534 if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status)) 1581 if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0))
1535 return -EIO; 1582 return -EIO;
1536 1583
1537 return 0; 1584 return 0;
@@ -1847,6 +1894,9 @@ static ssize_t hotkey_enable_show(struct device *dev,
1847{ 1894{
1848 int res, status; 1895 int res, status;
1849 1896
1897 printk_deprecated_attribute("hotkey_enable",
1898 "Hotkey reporting is always enabled");
1899
1850 res = hotkey_status_get(&status); 1900 res = hotkey_status_get(&status);
1851 if (res) 1901 if (res)
1852 return res; 1902 return res;
@@ -1859,14 +1909,17 @@ static ssize_t hotkey_enable_store(struct device *dev,
1859 const char *buf, size_t count) 1909 const char *buf, size_t count)
1860{ 1910{
1861 unsigned long t; 1911 unsigned long t;
1862 int res; 1912
1913 printk_deprecated_attribute("hotkey_enable",
1914 "Hotkeys can be disabled through hotkey_mask");
1863 1915
1864 if (parse_strtoul(buf, 1, &t)) 1916 if (parse_strtoul(buf, 1, &t))
1865 return -EINVAL; 1917 return -EINVAL;
1866 1918
1867 res = hotkey_status_set(t); 1919 if (t == 0)
1920 return -EPERM;
1868 1921
1869 return (res) ? res : count; 1922 return count;
1870} 1923}
1871 1924
1872static struct device_attribute dev_attr_hotkey_enable = 1925static struct device_attribute dev_attr_hotkey_enable =
@@ -1910,6 +1963,8 @@ static ssize_t hotkey_mask_store(struct device *dev,
1910 1963
1911 mutex_unlock(&hotkey_mutex); 1964 mutex_unlock(&hotkey_mutex);
1912 1965
1966 tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t);
1967
1913 return (res) ? res : count; 1968 return (res) ? res : count;
1914} 1969}
1915 1970
@@ -1922,7 +1977,7 @@ static ssize_t hotkey_bios_enabled_show(struct device *dev,
1922 struct device_attribute *attr, 1977 struct device_attribute *attr,
1923 char *buf) 1978 char *buf)
1924{ 1979{
1925 return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status); 1980 return sprintf(buf, "0\n");
1926} 1981}
1927 1982
1928static struct device_attribute dev_attr_hotkey_bios_enabled = 1983static struct device_attribute dev_attr_hotkey_bios_enabled =
@@ -1996,6 +2051,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
1996 2051
1997 mutex_unlock(&hotkey_mutex); 2052 mutex_unlock(&hotkey_mutex);
1998 2053
2054 tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
2055
1999 return count; 2056 return count;
2000} 2057}
2001 2058
@@ -2028,6 +2085,8 @@ static ssize_t hotkey_poll_freq_store(struct device *dev,
2028 hotkey_poll_setup(1); 2085 hotkey_poll_setup(1);
2029 mutex_unlock(&hotkey_mutex); 2086 mutex_unlock(&hotkey_mutex);
2030 2087
2088 tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);
2089
2031 return count; 2090 return count;
2032} 2091}
2033 2092
@@ -2197,11 +2256,11 @@ static void hotkey_exit(void)
2197 kfree(hotkey_keycode_map); 2256 kfree(hotkey_keycode_map);
2198 2257
2199 if (tp_features.hotkey) { 2258 if (tp_features.hotkey) {
2200 dbg_printk(TPACPI_DBG_EXIT, 2259 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
2201 "restoring original hot key mask\n"); 2260 "restoring original hot key mask\n");
2202 /* no short-circuit boolean operator below! */ 2261 /* no short-circuit boolean operator below! */
2203 if ((hotkey_mask_set(hotkey_orig_mask) | 2262 if ((hotkey_mask_set(hotkey_orig_mask) |
2204 hotkey_status_set(hotkey_orig_status)) != 0) 2263 hotkey_status_set(false)) != 0)
2205 printk(TPACPI_ERR 2264 printk(TPACPI_ERR
2206 "failed to restore hot key mask " 2265 "failed to restore hot key mask "
2207 "to BIOS defaults\n"); 2266 "to BIOS defaults\n");
@@ -2327,7 +2386,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2327 int status; 2386 int status;
2328 int hkeyv; 2387 int hkeyv;
2329 2388
2330 vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); 2389 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2390 "initializing hotkey subdriver\n");
2331 2391
2332 BUG_ON(!tpacpi_inputdev); 2392 BUG_ON(!tpacpi_inputdev);
2333 BUG_ON(tpacpi_inputdev->open != NULL || 2393 BUG_ON(tpacpi_inputdev->open != NULL ||
@@ -2344,7 +2404,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2344 /* hotkey not supported on 570 */ 2404 /* hotkey not supported on 570 */
2345 tp_features.hotkey = hkey_handle != NULL; 2405 tp_features.hotkey = hkey_handle != NULL;
2346 2406
2347 vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", 2407 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2408 "hotkeys are %s\n",
2348 str_supported(tp_features.hotkey)); 2409 str_supported(tp_features.hotkey));
2349 2410
2350 if (!tp_features.hotkey) 2411 if (!tp_features.hotkey)
@@ -2376,10 +2437,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2376 * T4x, X31, and later 2437 * T4x, X31, and later
2377 */ 2438 */
2378 tp_features.hotkey_mask = 1; 2439 tp_features.hotkey_mask = 1;
2440 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2441 "firmware HKEY interface version: 0x%x\n",
2442 hkeyv);
2379 } 2443 }
2380 } 2444 }
2381 2445
2382 vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", 2446 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2447 "hotkey masks are %s\n",
2383 str_supported(tp_features.hotkey_mask)); 2448 str_supported(tp_features.hotkey_mask));
2384 2449
2385 if (tp_features.hotkey_mask) { 2450 if (tp_features.hotkey_mask) {
@@ -2396,10 +2461,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2396 2461
2397 /* hotkey_source_mask *must* be zero for 2462 /* hotkey_source_mask *must* be zero for
2398 * the first hotkey_mask_get */ 2463 * the first hotkey_mask_get */
2399 res = hotkey_status_get(&hotkey_orig_status);
2400 if (res)
2401 goto err_exit;
2402
2403 if (tp_features.hotkey_mask) { 2464 if (tp_features.hotkey_mask) {
2404 res = hotkey_mask_get(); 2465 res = hotkey_mask_get();
2405 if (res) 2466 if (res)
@@ -2422,7 +2483,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2422 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; 2483 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
2423 } 2484 }
2424 2485
2425 vdbg_printk(TPACPI_DBG_INIT, 2486 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2426 "hotkey source mask 0x%08x, polling freq %d\n", 2487 "hotkey source mask 0x%08x, polling freq %d\n",
2427 hotkey_source_mask, hotkey_poll_freq); 2488 hotkey_source_mask, hotkey_poll_freq);
2428#endif 2489#endif
@@ -2476,12 +2537,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2476 } 2537 }
2477 2538
2478 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { 2539 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
2479 dbg_printk(TPACPI_DBG_INIT, 2540 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2480 "using Lenovo default hot key map\n"); 2541 "using Lenovo default hot key map\n");
2481 memcpy(hotkey_keycode_map, &lenovo_keycode_map, 2542 memcpy(hotkey_keycode_map, &lenovo_keycode_map,
2482 TPACPI_HOTKEY_MAP_SIZE); 2543 TPACPI_HOTKEY_MAP_SIZE);
2483 } else { 2544 } else {
2484 dbg_printk(TPACPI_DBG_INIT, 2545 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2485 "using IBM default hot key map\n"); 2546 "using IBM default hot key map\n");
2486 memcpy(hotkey_keycode_map, &ibm_keycode_map, 2547 memcpy(hotkey_keycode_map, &ibm_keycode_map,
2487 TPACPI_HOTKEY_MAP_SIZE); 2548 TPACPI_HOTKEY_MAP_SIZE);
@@ -2538,8 +2599,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2538 | (1 << TP_ACPI_HOTKEYSCAN_FNEND); 2599 | (1 << TP_ACPI_HOTKEYSCAN_FNEND);
2539 } 2600 }
2540 2601
2541 dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n"); 2602 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2542 res = hotkey_status_set(1); 2603 "enabling firmware HKEY event interface...\n");
2604 res = hotkey_status_set(true);
2543 if (res) { 2605 if (res) {
2544 hotkey_exit(); 2606 hotkey_exit();
2545 return res; 2607 return res;
@@ -2552,8 +2614,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2552 return res; 2614 return res;
2553 } 2615 }
2554 2616
2555 dbg_printk(TPACPI_DBG_INIT, 2617 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2556 "legacy hot key reporting over procfs %s\n", 2618 "legacy ibm/hotkey event reporting over procfs %s\n",
2557 (hotkey_report_mode < 2) ? 2619 (hotkey_report_mode < 2) ?
2558 "enabled" : "disabled"); 2620 "enabled" : "disabled");
2559 2621
@@ -2884,9 +2946,17 @@ static int hotkey_read(char *p)
2884 return len; 2946 return len;
2885} 2947}
2886 2948
2949static void hotkey_enabledisable_warn(void)
2950{
2951 tpacpi_log_usertask("procfs hotkey enable/disable");
2952 WARN(1, TPACPI_WARN
2953 "hotkey enable/disable functionality has been "
2954 "removed from the driver. Hotkeys are always enabled.\n");
2955}
2956
2887static int hotkey_write(char *buf) 2957static int hotkey_write(char *buf)
2888{ 2958{
2889 int res, status; 2959 int res;
2890 u32 mask; 2960 u32 mask;
2891 char *cmd; 2961 char *cmd;
2892 2962
@@ -2896,17 +2966,16 @@ static int hotkey_write(char *buf)
2896 if (mutex_lock_killable(&hotkey_mutex)) 2966 if (mutex_lock_killable(&hotkey_mutex))
2897 return -ERESTARTSYS; 2967 return -ERESTARTSYS;
2898 2968
2899 status = -1;
2900 mask = hotkey_mask; 2969 mask = hotkey_mask;
2901 2970
2902 res = 0; 2971 res = 0;
2903 while ((cmd = next_cmd(&buf))) { 2972 while ((cmd = next_cmd(&buf))) {
2904 if (strlencmp(cmd, "enable") == 0) { 2973 if (strlencmp(cmd, "enable") == 0) {
2905 status = 1; 2974 hotkey_enabledisable_warn();
2906 } else if (strlencmp(cmd, "disable") == 0) { 2975 } else if (strlencmp(cmd, "disable") == 0) {
2907 status = 0; 2976 hotkey_enabledisable_warn();
2977 res = -EPERM;
2908 } else if (strlencmp(cmd, "reset") == 0) { 2978 } else if (strlencmp(cmd, "reset") == 0) {
2909 status = hotkey_orig_status;
2910 mask = hotkey_orig_mask; 2979 mask = hotkey_orig_mask;
2911 } else if (sscanf(cmd, "0x%x", &mask) == 1) { 2980 } else if (sscanf(cmd, "0x%x", &mask) == 1) {
2912 /* mask set */ 2981 /* mask set */
@@ -2917,8 +2986,10 @@ static int hotkey_write(char *buf)
2917 goto errexit; 2986 goto errexit;
2918 } 2987 }
2919 } 2988 }
2920 if (status != -1) 2989
2921 res = hotkey_status_set(status); 2990 if (!res)
2991 tpacpi_disclose_usertask("procfs hotkey",
2992 "set mask to 0x%08x\n", mask);
2922 2993
2923 if (!res && mask != hotkey_mask) 2994 if (!res && mask != hotkey_mask)
2924 res = hotkey_mask_set(mask); 2995 res = hotkey_mask_set(mask);
@@ -2971,13 +3042,17 @@ enum {
2971 TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */ 3042 TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */
2972}; 3043};
2973 3044
3045#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
3046
2974static struct rfkill *tpacpi_bluetooth_rfkill; 3047static struct rfkill *tpacpi_bluetooth_rfkill;
2975 3048
2976static void bluetooth_suspend(pm_message_t state) 3049static void bluetooth_suspend(pm_message_t state)
2977{ 3050{
2978 /* Try to make sure radio will resume powered off */ 3051 /* Try to make sure radio will resume powered off */
2979 acpi_evalf(NULL, NULL, "\\BLTH", "vd", 3052 if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
2980 TP_ACPI_BLTH_PWR_OFF_ON_RESUME); 3053 TP_ACPI_BLTH_PWR_OFF_ON_RESUME))
3054 vdbg_printk(TPACPI_DBG_RFKILL,
3055 "bluetooth power down on resume request failed\n");
2981} 3056}
2982 3057
2983static int bluetooth_get_radiosw(void) 3058static int bluetooth_get_radiosw(void)
@@ -3015,6 +3090,10 @@ static void bluetooth_update_rfk(void)
3015 if (status < 0) 3090 if (status < 0)
3016 return; 3091 return;
3017 rfkill_force_state(tpacpi_bluetooth_rfkill, status); 3092 rfkill_force_state(tpacpi_bluetooth_rfkill, status);
3093
3094 vdbg_printk(TPACPI_DBG_RFKILL,
3095 "forced rfkill state to %d\n",
3096 status);
3018} 3097}
3019 3098
3020static int bluetooth_set_radiosw(int radio_on, int update_rfk) 3099static int bluetooth_set_radiosw(int radio_on, int update_rfk)
@@ -3030,6 +3109,9 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk)
3030 && radio_on) 3109 && radio_on)
3031 return -EPERM; 3110 return -EPERM;
3032 3111
3112 vdbg_printk(TPACPI_DBG_RFKILL,
3113 "will %s bluetooth\n", radio_on ? "enable" : "disable");
3114
3033#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3115#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3034 if (dbg_bluetoothemul) { 3116 if (dbg_bluetoothemul) {
3035 tpacpi_bluetooth_emulstate = !!radio_on; 3117 tpacpi_bluetooth_emulstate = !!radio_on;
@@ -3060,6 +3142,8 @@ static ssize_t bluetooth_enable_show(struct device *dev,
3060{ 3142{
3061 int status; 3143 int status;
3062 3144
3145 printk_deprecated_rfkill_attribute("bluetooth_enable");
3146
3063 status = bluetooth_get_radiosw(); 3147 status = bluetooth_get_radiosw();
3064 if (status < 0) 3148 if (status < 0)
3065 return status; 3149 return status;
@@ -3075,9 +3159,13 @@ static ssize_t bluetooth_enable_store(struct device *dev,
3075 unsigned long t; 3159 unsigned long t;
3076 int res; 3160 int res;
3077 3161
3162 printk_deprecated_rfkill_attribute("bluetooth_enable");
3163
3078 if (parse_strtoul(buf, 1, &t)) 3164 if (parse_strtoul(buf, 1, &t))
3079 return -EINVAL; 3165 return -EINVAL;
3080 3166
3167 tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
3168
3081 res = bluetooth_set_radiosw(t, 1); 3169 res = bluetooth_set_radiosw(t, 1);
3082 3170
3083 return (res) ? res : count; 3171 return (res) ? res : count;
@@ -3111,6 +3199,8 @@ static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state)
3111 3199
3112static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state) 3200static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
3113{ 3201{
3202 dbg_printk(TPACPI_DBG_RFKILL,
3203 "request to change radio state to %d\n", state);
3114 return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); 3204 return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3115} 3205}
3116 3206
@@ -3121,6 +3211,9 @@ static void bluetooth_shutdown(void)
3121 TP_ACPI_BLTH_SAVE_STATE)) 3211 TP_ACPI_BLTH_SAVE_STATE))
3122 printk(TPACPI_NOTICE 3212 printk(TPACPI_NOTICE
3123 "failed to save bluetooth state to NVRAM\n"); 3213 "failed to save bluetooth state to NVRAM\n");
3214 else
3215 vdbg_printk(TPACPI_DBG_RFKILL,
3216 "bluestooth state saved to NVRAM\n");
3124} 3217}
3125 3218
3126static void bluetooth_exit(void) 3219static void bluetooth_exit(void)
@@ -3139,7 +3232,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3139 int res; 3232 int res;
3140 int status = 0; 3233 int status = 0;
3141 3234
3142 vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n"); 3235 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
3236 "initializing bluetooth subdriver\n");
3143 3237
3144 TPACPI_ACPIHANDLE_INIT(hkey); 3238 TPACPI_ACPIHANDLE_INIT(hkey);
3145 3239
@@ -3148,7 +3242,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3148 tp_features.bluetooth = hkey_handle && 3242 tp_features.bluetooth = hkey_handle &&
3149 acpi_evalf(hkey_handle, &status, "GBDC", "qd"); 3243 acpi_evalf(hkey_handle, &status, "GBDC", "qd");
3150 3244
3151 vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n", 3245 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
3246 "bluetooth is %s, status 0x%02x\n",
3152 str_supported(tp_features.bluetooth), 3247 str_supported(tp_features.bluetooth),
3153 status); 3248 status);
3154 3249
@@ -3163,7 +3258,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3163 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { 3258 !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
3164 /* no bluetooth hardware present in system */ 3259 /* no bluetooth hardware present in system */
3165 tp_features.bluetooth = 0; 3260 tp_features.bluetooth = 0;
3166 dbg_printk(TPACPI_DBG_INIT, 3261 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
3167 "bluetooth hardware not installed\n"); 3262 "bluetooth hardware not installed\n");
3168 } 3263 }
3169 3264
@@ -3178,7 +3273,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3178 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, 3273 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
3179 &tpacpi_bluetooth_rfkill, 3274 &tpacpi_bluetooth_rfkill,
3180 RFKILL_TYPE_BLUETOOTH, 3275 RFKILL_TYPE_BLUETOOTH,
3181 "tpacpi_bluetooth_sw", 3276 TPACPI_RFK_BLUETOOTH_SW_NAME,
3182 true, 3277 true,
3183 tpacpi_bluetooth_rfk_set, 3278 tpacpi_bluetooth_rfk_set,
3184 tpacpi_bluetooth_rfk_get); 3279 tpacpi_bluetooth_rfk_get);
@@ -3211,19 +3306,27 @@ static int bluetooth_read(char *p)
3211static int bluetooth_write(char *buf) 3306static int bluetooth_write(char *buf)
3212{ 3307{
3213 char *cmd; 3308 char *cmd;
3309 int state = -1;
3214 3310
3215 if (!tp_features.bluetooth) 3311 if (!tp_features.bluetooth)
3216 return -ENODEV; 3312 return -ENODEV;
3217 3313
3218 while ((cmd = next_cmd(&buf))) { 3314 while ((cmd = next_cmd(&buf))) {
3219 if (strlencmp(cmd, "enable") == 0) { 3315 if (strlencmp(cmd, "enable") == 0) {
3220 bluetooth_set_radiosw(1, 1); 3316 state = 1;
3221 } else if (strlencmp(cmd, "disable") == 0) { 3317 } else if (strlencmp(cmd, "disable") == 0) {
3222 bluetooth_set_radiosw(0, 1); 3318 state = 0;
3223 } else 3319 } else
3224 return -EINVAL; 3320 return -EINVAL;
3225 } 3321 }
3226 3322
3323 if (state != -1) {
3324 tpacpi_disclose_usertask("procfs bluetooth",
3325 "attempt to %s\n",
3326 state ? "enable" : "disable");
3327 bluetooth_set_radiosw(state, 1);
3328 }
3329
3227 return 0; 3330 return 0;
3228} 3331}
3229 3332
@@ -3248,13 +3351,17 @@ enum {
3248 off / last state */ 3351 off / last state */
3249}; 3352};
3250 3353
3354#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
3355
3251static struct rfkill *tpacpi_wan_rfkill; 3356static struct rfkill *tpacpi_wan_rfkill;
3252 3357
3253static void wan_suspend(pm_message_t state) 3358static void wan_suspend(pm_message_t state)
3254{ 3359{
3255 /* Try to make sure radio will resume powered off */ 3360 /* Try to make sure radio will resume powered off */
3256 acpi_evalf(NULL, NULL, "\\WGSV", "qvd", 3361 if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
3257 TP_ACPI_WGSV_PWR_OFF_ON_RESUME); 3362 TP_ACPI_WGSV_PWR_OFF_ON_RESUME))
3363 vdbg_printk(TPACPI_DBG_RFKILL,
3364 "WWAN power down on resume request failed\n");
3258} 3365}
3259 3366
3260static int wan_get_radiosw(void) 3367static int wan_get_radiosw(void)
@@ -3292,6 +3399,10 @@ static void wan_update_rfk(void)
3292 if (status < 0) 3399 if (status < 0)
3293 return; 3400 return;
3294 rfkill_force_state(tpacpi_wan_rfkill, status); 3401 rfkill_force_state(tpacpi_wan_rfkill, status);
3402
3403 vdbg_printk(TPACPI_DBG_RFKILL,
3404 "forced rfkill state to %d\n",
3405 status);
3295} 3406}
3296 3407
3297static int wan_set_radiosw(int radio_on, int update_rfk) 3408static int wan_set_radiosw(int radio_on, int update_rfk)
@@ -3307,6 +3418,9 @@ static int wan_set_radiosw(int radio_on, int update_rfk)
3307 && radio_on) 3418 && radio_on)
3308 return -EPERM; 3419 return -EPERM;
3309 3420
3421 vdbg_printk(TPACPI_DBG_RFKILL,
3422 "will %s WWAN\n", radio_on ? "enable" : "disable");
3423
3310#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3424#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3311 if (dbg_wwanemul) { 3425 if (dbg_wwanemul) {
3312 tpacpi_wwan_emulstate = !!radio_on; 3426 tpacpi_wwan_emulstate = !!radio_on;
@@ -3337,6 +3451,8 @@ static ssize_t wan_enable_show(struct device *dev,
3337{ 3451{
3338 int status; 3452 int status;
3339 3453
3454 printk_deprecated_rfkill_attribute("wwan_enable");
3455
3340 status = wan_get_radiosw(); 3456 status = wan_get_radiosw();
3341 if (status < 0) 3457 if (status < 0)
3342 return status; 3458 return status;
@@ -3352,9 +3468,13 @@ static ssize_t wan_enable_store(struct device *dev,
3352 unsigned long t; 3468 unsigned long t;
3353 int res; 3469 int res;
3354 3470
3471 printk_deprecated_rfkill_attribute("wwan_enable");
3472
3355 if (parse_strtoul(buf, 1, &t)) 3473 if (parse_strtoul(buf, 1, &t))
3356 return -EINVAL; 3474 return -EINVAL;
3357 3475
3476 tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
3477
3358 res = wan_set_radiosw(t, 1); 3478 res = wan_set_radiosw(t, 1);
3359 3479
3360 return (res) ? res : count; 3480 return (res) ? res : count;
@@ -3388,6 +3508,8 @@ static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state)
3388 3508
3389static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state) 3509static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
3390{ 3510{
3511 dbg_printk(TPACPI_DBG_RFKILL,
3512 "request to change radio state to %d\n", state);
3391 return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); 3513 return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3392} 3514}
3393 3515
@@ -3398,6 +3520,9 @@ static void wan_shutdown(void)
3398 TP_ACPI_WGSV_SAVE_STATE)) 3520 TP_ACPI_WGSV_SAVE_STATE))
3399 printk(TPACPI_NOTICE 3521 printk(TPACPI_NOTICE
3400 "failed to save WWAN state to NVRAM\n"); 3522 "failed to save WWAN state to NVRAM\n");
3523 else
3524 vdbg_printk(TPACPI_DBG_RFKILL,
3525 "WWAN state saved to NVRAM\n");
3401} 3526}
3402 3527
3403static void wan_exit(void) 3528static void wan_exit(void)
@@ -3416,14 +3541,16 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3416 int res; 3541 int res;
3417 int status = 0; 3542 int status = 0;
3418 3543
3419 vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n"); 3544 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
3545 "initializing wan subdriver\n");
3420 3546
3421 TPACPI_ACPIHANDLE_INIT(hkey); 3547 TPACPI_ACPIHANDLE_INIT(hkey);
3422 3548
3423 tp_features.wan = hkey_handle && 3549 tp_features.wan = hkey_handle &&
3424 acpi_evalf(hkey_handle, &status, "GWAN", "qd"); 3550 acpi_evalf(hkey_handle, &status, "GWAN", "qd");
3425 3551
3426 vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n", 3552 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
3553 "wan is %s, status 0x%02x\n",
3427 str_supported(tp_features.wan), 3554 str_supported(tp_features.wan),
3428 status); 3555 status);
3429 3556
@@ -3438,7 +3565,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3438 !(status & TP_ACPI_WANCARD_HWPRESENT)) { 3565 !(status & TP_ACPI_WANCARD_HWPRESENT)) {
3439 /* no wan hardware present in system */ 3566 /* no wan hardware present in system */
3440 tp_features.wan = 0; 3567 tp_features.wan = 0;
3441 dbg_printk(TPACPI_DBG_INIT, 3568 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
3442 "wan hardware not installed\n"); 3569 "wan hardware not installed\n");
3443 } 3570 }
3444 3571
@@ -3453,7 +3580,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3453 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, 3580 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
3454 &tpacpi_wan_rfkill, 3581 &tpacpi_wan_rfkill,
3455 RFKILL_TYPE_WWAN, 3582 RFKILL_TYPE_WWAN,
3456 "tpacpi_wwan_sw", 3583 TPACPI_RFK_WWAN_SW_NAME,
3457 true, 3584 true,
3458 tpacpi_wan_rfk_set, 3585 tpacpi_wan_rfk_set,
3459 tpacpi_wan_rfk_get); 3586 tpacpi_wan_rfk_get);
@@ -3471,6 +3598,8 @@ static int wan_read(char *p)
3471 int len = 0; 3598 int len = 0;
3472 int status = wan_get_radiosw(); 3599 int status = wan_get_radiosw();
3473 3600
3601 tpacpi_disclose_usertask("procfs wan", "read");
3602
3474 if (!tp_features.wan) 3603 if (!tp_features.wan)
3475 len += sprintf(p + len, "status:\t\tnot supported\n"); 3604 len += sprintf(p + len, "status:\t\tnot supported\n");
3476 else { 3605 else {
@@ -3486,19 +3615,27 @@ static int wan_read(char *p)
3486static int wan_write(char *buf) 3615static int wan_write(char *buf)
3487{ 3616{
3488 char *cmd; 3617 char *cmd;
3618 int state = -1;
3489 3619
3490 if (!tp_features.wan) 3620 if (!tp_features.wan)
3491 return -ENODEV; 3621 return -ENODEV;
3492 3622
3493 while ((cmd = next_cmd(&buf))) { 3623 while ((cmd = next_cmd(&buf))) {
3494 if (strlencmp(cmd, "enable") == 0) { 3624 if (strlencmp(cmd, "enable") == 0) {
3495 wan_set_radiosw(1, 1); 3625 state = 1;
3496 } else if (strlencmp(cmd, "disable") == 0) { 3626 } else if (strlencmp(cmd, "disable") == 0) {
3497 wan_set_radiosw(0, 1); 3627 state = 0;
3498 } else 3628 } else
3499 return -EINVAL; 3629 return -EINVAL;
3500 } 3630 }
3501 3631
3632 if (state != -1) {
3633 tpacpi_disclose_usertask("procfs wan",
3634 "attempt to %s\n",
3635 state ? "enable" : "disable");
3636 wan_set_radiosw(state, 1);
3637 }
3638
3502 return 0; 3639 return 0;
3503} 3640}
3504 3641
@@ -3521,6 +3658,8 @@ enum {
3521 TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */ 3658 TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */
3522}; 3659};
3523 3660
3661#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
3662
3524static struct rfkill *tpacpi_uwb_rfkill; 3663static struct rfkill *tpacpi_uwb_rfkill;
3525 3664
3526static int uwb_get_radiosw(void) 3665static int uwb_get_radiosw(void)
@@ -3558,6 +3697,10 @@ static void uwb_update_rfk(void)
3558 if (status < 0) 3697 if (status < 0)
3559 return; 3698 return;
3560 rfkill_force_state(tpacpi_uwb_rfkill, status); 3699 rfkill_force_state(tpacpi_uwb_rfkill, status);
3700
3701 vdbg_printk(TPACPI_DBG_RFKILL,
3702 "forced rfkill state to %d\n",
3703 status);
3561} 3704}
3562 3705
3563static int uwb_set_radiosw(int radio_on, int update_rfk) 3706static int uwb_set_radiosw(int radio_on, int update_rfk)
@@ -3573,6 +3716,9 @@ static int uwb_set_radiosw(int radio_on, int update_rfk)
3573 && radio_on) 3716 && radio_on)
3574 return -EPERM; 3717 return -EPERM;
3575 3718
3719 vdbg_printk(TPACPI_DBG_RFKILL,
3720 "will %s UWB\n", radio_on ? "enable" : "disable");
3721
3576#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3722#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3577 if (dbg_uwbemul) { 3723 if (dbg_uwbemul) {
3578 tpacpi_uwb_emulstate = !!radio_on; 3724 tpacpi_uwb_emulstate = !!radio_on;
@@ -3607,6 +3753,8 @@ static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state)
3607 3753
3608static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state) 3754static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
3609{ 3755{
3756 dbg_printk(TPACPI_DBG_RFKILL,
3757 "request to change radio state to %d\n", state);
3610 return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); 3758 return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3611} 3759}
3612 3760
@@ -3621,14 +3769,16 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
3621 int res; 3769 int res;
3622 int status = 0; 3770 int status = 0;
3623 3771
3624 vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n"); 3772 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
3773 "initializing uwb subdriver\n");
3625 3774
3626 TPACPI_ACPIHANDLE_INIT(hkey); 3775 TPACPI_ACPIHANDLE_INIT(hkey);
3627 3776
3628 tp_features.uwb = hkey_handle && 3777 tp_features.uwb = hkey_handle &&
3629 acpi_evalf(hkey_handle, &status, "GUWB", "qd"); 3778 acpi_evalf(hkey_handle, &status, "GUWB", "qd");
3630 3779
3631 vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n", 3780 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
3781 "uwb is %s, status 0x%02x\n",
3632 str_supported(tp_features.uwb), 3782 str_supported(tp_features.uwb),
3633 status); 3783 status);
3634 3784
@@ -3653,7 +3803,7 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
3653 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, 3803 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
3654 &tpacpi_uwb_rfkill, 3804 &tpacpi_uwb_rfkill,
3655 RFKILL_TYPE_UWB, 3805 RFKILL_TYPE_UWB,
3656 "tpacpi_uwb_sw", 3806 TPACPI_RFK_UWB_SW_NAME,
3657 false, 3807 false,
3658 tpacpi_uwb_rfk_set, 3808 tpacpi_uwb_rfk_set,
3659 tpacpi_uwb_rfk_get); 3809 tpacpi_uwb_rfk_get);
@@ -4602,6 +4752,16 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
4602 "tpacpi::unknown_led", 4752 "tpacpi::unknown_led",
4603 "tpacpi::standby", 4753 "tpacpi::standby",
4604}; 4754};
4755#define TPACPI_SAFE_LEDS 0x0081U
4756
4757static inline bool tpacpi_is_led_restricted(const unsigned int led)
4758{
4759#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
4760 return false;
4761#else
4762 return (TPACPI_SAFE_LEDS & (1 << led)) == 0;
4763#endif
4764}
4605 4765
4606static int led_get_status(const unsigned int led) 4766static int led_get_status(const unsigned int led)
4607{ 4767{
@@ -4639,16 +4799,20 @@ static int led_set_status(const unsigned int led,
4639 switch (led_supported) { 4799 switch (led_supported) {
4640 case TPACPI_LED_570: 4800 case TPACPI_LED_570:
4641 /* 570 */ 4801 /* 570 */
4642 if (led > 7) 4802 if (unlikely(led > 7))
4643 return -EINVAL; 4803 return -EINVAL;
4804 if (unlikely(tpacpi_is_led_restricted(led)))
4805 return -EPERM;
4644 if (!acpi_evalf(led_handle, NULL, NULL, "vdd", 4806 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
4645 (1 << led), led_sled_arg1[ledstatus])) 4807 (1 << led), led_sled_arg1[ledstatus]))
4646 rc = -EIO; 4808 rc = -EIO;
4647 break; 4809 break;
4648 case TPACPI_LED_OLD: 4810 case TPACPI_LED_OLD:
4649 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ 4811 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
4650 if (led > 7) 4812 if (unlikely(led > 7))
4651 return -EINVAL; 4813 return -EINVAL;
4814 if (unlikely(tpacpi_is_led_restricted(led)))
4815 return -EPERM;
4652 rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led)); 4816 rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
4653 if (rc >= 0) 4817 if (rc >= 0)
4654 rc = ec_write(TPACPI_LED_EC_HLBL, 4818 rc = ec_write(TPACPI_LED_EC_HLBL,
@@ -4659,6 +4823,10 @@ static int led_set_status(const unsigned int led,
4659 break; 4823 break;
4660 case TPACPI_LED_NEW: 4824 case TPACPI_LED_NEW:
4661 /* all others */ 4825 /* all others */
4826 if (unlikely(led >= TPACPI_LED_NUMLEDS))
4827 return -EINVAL;
4828 if (unlikely(tpacpi_is_led_restricted(led)))
4829 return -EPERM;
4662 if (!acpi_evalf(led_handle, NULL, NULL, "vdd", 4830 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
4663 led, led_led_arg1[ledstatus])) 4831 led, led_led_arg1[ledstatus]))
4664 rc = -EIO; 4832 rc = -EIO;
@@ -4751,6 +4919,30 @@ static void led_exit(void)
4751 kfree(tpacpi_leds); 4919 kfree(tpacpi_leds);
4752} 4920}
4753 4921
4922static int __init tpacpi_init_led(unsigned int led)
4923{
4924 int rc;
4925
4926 tpacpi_leds[led].led = led;
4927
4928 tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set;
4929 tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;
4930 if (led_supported == TPACPI_LED_570)
4931 tpacpi_leds[led].led_classdev.brightness_get =
4932 &led_sysfs_get;
4933
4934 tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led];
4935
4936 INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker);
4937
4938 rc = led_classdev_register(&tpacpi_pdev->dev,
4939 &tpacpi_leds[led].led_classdev);
4940 if (rc < 0)
4941 tpacpi_leds[led].led_classdev.name = NULL;
4942
4943 return rc;
4944}
4945
4754static int __init led_init(struct ibm_init_struct *iibm) 4946static int __init led_init(struct ibm_init_struct *iibm)
4755{ 4947{
4756 unsigned int i; 4948 unsigned int i;
@@ -4784,27 +4976,21 @@ static int __init led_init(struct ibm_init_struct *iibm)
4784 } 4976 }
4785 4977
4786 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { 4978 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
4787 tpacpi_leds[i].led = i; 4979 if (!tpacpi_is_led_restricted(i)) {
4788 4980 rc = tpacpi_init_led(i);
4789 tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set; 4981 if (rc < 0) {
4790 tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set; 4982 led_exit();
4791 if (led_supported == TPACPI_LED_570) 4983 return rc;
4792 tpacpi_leds[i].led_classdev.brightness_get = 4984 }
4793 &led_sysfs_get;
4794
4795 tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
4796
4797 INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
4798
4799 rc = led_classdev_register(&tpacpi_pdev->dev,
4800 &tpacpi_leds[i].led_classdev);
4801 if (rc < 0) {
4802 tpacpi_leds[i].led_classdev.name = NULL;
4803 led_exit();
4804 return rc;
4805 } 4985 }
4806 } 4986 }
4807 4987
4988#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
4989 if (led_supported != TPACPI_LED_NONE)
4990 printk(TPACPI_NOTICE
4991 "warning: userspace override of important "
4992 "firmware LEDs is enabled\n");
4993#endif
4808 return (led_supported != TPACPI_LED_NONE)? 0 : 1; 4994 return (led_supported != TPACPI_LED_NONE)? 0 : 1;
4809} 4995}
4810 4996
@@ -5340,6 +5526,20 @@ static struct ibm_struct ecdump_driver_data = {
5340 5526
5341#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen" 5527#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
5342 5528
5529/*
5530 * ThinkPads can read brightness from two places: EC HBRV (0x31), or
5531 * CMOS NVRAM byte 0x5E, bits 0-3.
5532 *
5533 * EC HBRV (0x31) has the following layout
5534 * Bit 7: unknown function
5535 * Bit 6: unknown function
5536 * Bit 5: Z: honour scale changes, NZ: ignore scale changes
5537 * Bit 4: must be set to zero to avoid problems
5538 * Bit 3-0: backlight brightness level
5539 *
5540 * brightness_get_raw returns status data in the HBRV layout
5541 */
5542
5343enum { 5543enum {
5344 TP_EC_BACKLIGHT = 0x31, 5544 TP_EC_BACKLIGHT = 0x31,
5345 5545
@@ -5349,108 +5549,164 @@ enum {
5349 TP_EC_BACKLIGHT_MAPSW = 0x20, 5549 TP_EC_BACKLIGHT_MAPSW = 0x20,
5350}; 5550};
5351 5551
5552enum tpacpi_brightness_access_mode {
5553 TPACPI_BRGHT_MODE_AUTO = 0, /* Not implemented yet */
5554 TPACPI_BRGHT_MODE_EC, /* EC control */
5555 TPACPI_BRGHT_MODE_UCMS_STEP, /* UCMS step-based control */
5556 TPACPI_BRGHT_MODE_ECNVRAM, /* EC control w/ NVRAM store */
5557 TPACPI_BRGHT_MODE_MAX
5558};
5559
5352static struct backlight_device *ibm_backlight_device; 5560static struct backlight_device *ibm_backlight_device;
5353static int brightness_mode; 5561
5562static enum tpacpi_brightness_access_mode brightness_mode =
5563 TPACPI_BRGHT_MODE_MAX;
5564
5354static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ 5565static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
5355 5566
5356static struct mutex brightness_mutex; 5567static struct mutex brightness_mutex;
5357 5568
5358/* 5569/* NVRAM brightness access,
5359 * ThinkPads can read brightness from two places: EC 0x31, or 5570 * call with brightness_mutex held! */
5360 * CMOS NVRAM byte 0x5E, bits 0-3. 5571static unsigned int tpacpi_brightness_nvram_get(void)
5361 *
5362 * EC 0x31 has the following layout
5363 * Bit 7: unknown function
5364 * Bit 6: unknown function
5365 * Bit 5: Z: honour scale changes, NZ: ignore scale changes
5366 * Bit 4: must be set to zero to avoid problems
5367 * Bit 3-0: backlight brightness level
5368 *
5369 * brightness_get_raw returns status data in the EC 0x31 layout
5370 */
5371static int brightness_get_raw(int *status)
5372{ 5572{
5373 u8 lec = 0, lcmos = 0, level = 0; 5573 u8 lnvram;
5374 5574
5375 if (brightness_mode & 1) { 5575 lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
5376 if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec)) 5576 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
5377 return -EIO; 5577 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
5378 level = lec & TP_EC_BACKLIGHT_LVLMSK; 5578 lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07;
5379 }; 5579
5380 if (brightness_mode & 2) { 5580 return lnvram;
5381 lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) 5581}
5382 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) 5582
5383 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; 5583static void tpacpi_brightness_checkpoint_nvram(void)
5384 lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07; 5584{
5385 level = lcmos; 5585 u8 lec = 0;
5386 } 5586 u8 b_nvram;
5387 5587
5388 if (brightness_mode == 3) { 5588 if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM)
5389 *status = lec; /* Prefer EC, CMOS is just a backing store */ 5589 return;
5390 lec &= TP_EC_BACKLIGHT_LVLMSK; 5590
5391 if (lec == lcmos) 5591 vdbg_printk(TPACPI_DBG_BRGHT,
5392 tp_warned.bright_cmos_ec_unsync = 0; 5592 "trying to checkpoint backlight level to NVRAM...\n");
5393 else { 5593
5394 if (!tp_warned.bright_cmos_ec_unsync) { 5594 if (mutex_lock_killable(&brightness_mutex) < 0)
5395 printk(TPACPI_ERR 5595 return;
5396 "CMOS NVRAM (%u) and EC (%u) do not " 5596
5397 "agree on display brightness level\n", 5597 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
5398 (unsigned int) lcmos, 5598 goto unlock;
5399 (unsigned int) lec); 5599 lec &= TP_EC_BACKLIGHT_LVLMSK;
5400 tp_warned.bright_cmos_ec_unsync = 1; 5600 b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
5401 } 5601
5602 if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
5603 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
5604 /* NVRAM needs update */
5605 b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
5606 TP_NVRAM_POS_LEVEL_BRIGHTNESS);
5607 b_nvram |= lec;
5608 nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
5609 dbg_printk(TPACPI_DBG_BRGHT,
5610 "updated NVRAM backlight level to %u (0x%02x)\n",
5611 (unsigned int) lec, (unsigned int) b_nvram);
5612 } else
5613 vdbg_printk(TPACPI_DBG_BRGHT,
5614 "NVRAM backlight level already is %u (0x%02x)\n",
5615 (unsigned int) lec, (unsigned int) b_nvram);
5616
5617unlock:
5618 mutex_unlock(&brightness_mutex);
5619}
5620
5621
5622/* call with brightness_mutex held! */
5623static int tpacpi_brightness_get_raw(int *status)
5624{
5625 u8 lec = 0;
5626
5627 switch (brightness_mode) {
5628 case TPACPI_BRGHT_MODE_UCMS_STEP:
5629 *status = tpacpi_brightness_nvram_get();
5630 return 0;
5631 case TPACPI_BRGHT_MODE_EC:
5632 case TPACPI_BRGHT_MODE_ECNVRAM:
5633 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
5402 return -EIO; 5634 return -EIO;
5403 } 5635 *status = lec;
5404 } else { 5636 return 0;
5405 *status = level; 5637 default:
5638 return -ENXIO;
5406 } 5639 }
5640}
5641
5642/* call with brightness_mutex held! */
5643/* do NOT call with illegal backlight level value */
5644static int tpacpi_brightness_set_ec(unsigned int value)
5645{
5646 u8 lec = 0;
5647
5648 if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
5649 return -EIO;
5650
5651 if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT,
5652 (lec & TP_EC_BACKLIGHT_CMDMSK) |
5653 (value & TP_EC_BACKLIGHT_LVLMSK))))
5654 return -EIO;
5655
5656 return 0;
5657}
5658
5659/* call with brightness_mutex held! */
5660static int tpacpi_brightness_set_ucmsstep(unsigned int value)
5661{
5662 int cmos_cmd, inc;
5663 unsigned int current_value, i;
5664
5665 current_value = tpacpi_brightness_nvram_get();
5666
5667 if (value == current_value)
5668 return 0;
5669
5670 cmos_cmd = (value > current_value) ?
5671 TP_CMOS_BRIGHTNESS_UP :
5672 TP_CMOS_BRIGHTNESS_DOWN;
5673 inc = (value > current_value) ? 1 : -1;
5674
5675 for (i = current_value; i != value; i += inc)
5676 if (issue_thinkpad_cmos_command(cmos_cmd))
5677 return -EIO;
5407 5678
5408 return 0; 5679 return 0;
5409} 5680}
5410 5681
5411/* May return EINTR which can always be mapped to ERESTARTSYS */ 5682/* May return EINTR which can always be mapped to ERESTARTSYS */
5412static int brightness_set(int value) 5683static int brightness_set(unsigned int value)
5413{ 5684{
5414 int cmos_cmd, inc, i, res; 5685 int res;
5415 int current_value;
5416 int command_bits;
5417 5686
5418 if (value > ((tp_features.bright_16levels)? 15 : 7) || 5687 if (value > ((tp_features.bright_16levels)? 15 : 7) ||
5419 value < 0) 5688 value < 0)
5420 return -EINVAL; 5689 return -EINVAL;
5421 5690
5691 vdbg_printk(TPACPI_DBG_BRGHT,
5692 "set backlight level to %d\n", value);
5693
5422 res = mutex_lock_killable(&brightness_mutex); 5694 res = mutex_lock_killable(&brightness_mutex);
5423 if (res < 0) 5695 if (res < 0)
5424 return res; 5696 return res;
5425 5697
5426 res = brightness_get_raw(&current_value); 5698 switch (brightness_mode) {
5427 if (res < 0) 5699 case TPACPI_BRGHT_MODE_EC:
5428 goto errout; 5700 case TPACPI_BRGHT_MODE_ECNVRAM:
5429 5701 res = tpacpi_brightness_set_ec(value);
5430 command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK; 5702 break;
5431 current_value &= TP_EC_BACKLIGHT_LVLMSK; 5703 case TPACPI_BRGHT_MODE_UCMS_STEP:
5432 5704 res = tpacpi_brightness_set_ucmsstep(value);
5433 cmos_cmd = value > current_value ? 5705 break;
5434 TP_CMOS_BRIGHTNESS_UP : 5706 default:
5435 TP_CMOS_BRIGHTNESS_DOWN; 5707 res = -ENXIO;
5436 inc = (value > current_value)? 1 : -1;
5437
5438 res = 0;
5439 for (i = current_value; i != value; i += inc) {
5440 if ((brightness_mode & 2) &&
5441 issue_thinkpad_cmos_command(cmos_cmd)) {
5442 res = -EIO;
5443 goto errout;
5444 }
5445 if ((brightness_mode & 1) &&
5446 !acpi_ec_write(TP_EC_BACKLIGHT,
5447 (i + inc) | command_bits)) {
5448 res = -EIO;
5449 goto errout;;
5450 }
5451 } 5708 }
5452 5709
5453errout:
5454 mutex_unlock(&brightness_mutex); 5710 mutex_unlock(&brightness_mutex);
5455 return res; 5711 return res;
5456} 5712}
@@ -5459,21 +5715,34 @@ errout:
5459 5715
5460static int brightness_update_status(struct backlight_device *bd) 5716static int brightness_update_status(struct backlight_device *bd)
5461{ 5717{
5462 /* it is the backlight class's job (caller) to handle 5718 unsigned int level =
5463 * EINTR and other errors properly */
5464 return brightness_set(
5465 (bd->props.fb_blank == FB_BLANK_UNBLANK && 5719 (bd->props.fb_blank == FB_BLANK_UNBLANK &&
5466 bd->props.power == FB_BLANK_UNBLANK) ? 5720 bd->props.power == FB_BLANK_UNBLANK) ?
5467 bd->props.brightness : 0); 5721 bd->props.brightness : 0;
5722
5723 dbg_printk(TPACPI_DBG_BRGHT,
5724 "backlight: attempt to set level to %d\n",
5725 level);
5726
5727 /* it is the backlight class's job (caller) to handle
5728 * EINTR and other errors properly */
5729 return brightness_set(level);
5468} 5730}
5469 5731
5470static int brightness_get(struct backlight_device *bd) 5732static int brightness_get(struct backlight_device *bd)
5471{ 5733{
5472 int status, res; 5734 int status, res;
5473 5735
5474 res = brightness_get_raw(&status); 5736 res = mutex_lock_killable(&brightness_mutex);
5475 if (res < 0) 5737 if (res < 0)
5476 return 0; /* FIXME: teach backlight about error handling */ 5738 return 0;
5739
5740 res = tpacpi_brightness_get_raw(&status);
5741
5742 mutex_unlock(&brightness_mutex);
5743
5744 if (res < 0)
5745 return 0;
5477 5746
5478 return status & TP_EC_BACKLIGHT_LVLMSK; 5747 return status & TP_EC_BACKLIGHT_LVLMSK;
5479} 5748}
@@ -5523,7 +5792,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
5523 } 5792 }
5524 5793
5525 if (!brightness_enable) { 5794 if (!brightness_enable) {
5526 dbg_printk(TPACPI_DBG_INIT, 5795 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
5527 "brightness support disabled by " 5796 "brightness support disabled by "
5528 "module parameter\n"); 5797 "module parameter\n");
5529 return 1; 5798 return 1;
@@ -5538,20 +5807,38 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
5538 if (b == 16) 5807 if (b == 16)
5539 tp_features.bright_16levels = 1; 5808 tp_features.bright_16levels = 1;
5540 5809
5541 if (!brightness_mode) { 5810 /*
5542 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) 5811 * Check for module parameter bogosity, note that we
5543 brightness_mode = 2; 5812 * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
5544 else 5813 * able to detect "unspecified"
5545 brightness_mode = 3; 5814 */
5815 if (brightness_mode > TPACPI_BRGHT_MODE_MAX)
5816 return -EINVAL;
5546 5817
5547 dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n", 5818 /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
5548 brightness_mode); 5819 if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
5549 } 5820 brightness_mode == TPACPI_BRGHT_MODE_MAX) {
5821 if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) {
5822 /*
5823 * IBM models that define HBRV probably have
5824 * EC-based backlight level control
5825 */
5826 if (acpi_evalf(ec_handle, NULL, "HBRV", "qd"))
5827 /* T40-T43, R50-R52, R50e, R51e, X31-X41 */
5828 brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
5829 else
5830 /* all other IBM ThinkPads */
5831 brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
5832 } else
5833 /* All Lenovo ThinkPads */
5834 brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
5550 5835
5551 if (brightness_mode > 3) 5836 dbg_printk(TPACPI_DBG_BRGHT,
5552 return -EINVAL; 5837 "selected brightness_mode=%d\n",
5838 brightness_mode);
5839 }
5553 5840
5554 if (brightness_get_raw(&b) < 0) 5841 if (tpacpi_brightness_get_raw(&b) < 0)
5555 return 1; 5842 return 1;
5556 5843
5557 if (tp_features.bright_16levels) 5844 if (tp_features.bright_16levels)
@@ -5565,7 +5852,8 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
5565 printk(TPACPI_ERR "Could not register backlight device\n"); 5852 printk(TPACPI_ERR "Could not register backlight device\n");
5566 return PTR_ERR(ibm_backlight_device); 5853 return PTR_ERR(ibm_backlight_device);
5567 } 5854 }
5568 vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n"); 5855 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
5856 "brightness is supported\n");
5569 5857
5570 ibm_backlight_device->props.max_brightness = 5858 ibm_backlight_device->props.max_brightness =
5571 (tp_features.bright_16levels)? 15 : 7; 5859 (tp_features.bright_16levels)? 15 : 7;
@@ -5575,13 +5863,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
5575 return 0; 5863 return 0;
5576} 5864}
5577 5865
5866static void brightness_suspend(pm_message_t state)
5867{
5868 tpacpi_brightness_checkpoint_nvram();
5869}
5870
5871static void brightness_shutdown(void)
5872{
5873 tpacpi_brightness_checkpoint_nvram();
5874}
5875
5578static void brightness_exit(void) 5876static void brightness_exit(void)
5579{ 5877{
5580 if (ibm_backlight_device) { 5878 if (ibm_backlight_device) {
5581 vdbg_printk(TPACPI_DBG_EXIT, 5879 vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT,
5582 "calling backlight_device_unregister()\n"); 5880 "calling backlight_device_unregister()\n");
5583 backlight_device_unregister(ibm_backlight_device); 5881 backlight_device_unregister(ibm_backlight_device);
5584 } 5882 }
5883
5884 tpacpi_brightness_checkpoint_nvram();
5585} 5885}
5586 5886
5587static int brightness_read(char *p) 5887static int brightness_read(char *p)
@@ -5628,6 +5928,9 @@ static int brightness_write(char *buf)
5628 return -EINVAL; 5928 return -EINVAL;
5629 } 5929 }
5630 5930
5931 tpacpi_disclose_usertask("procfs brightness",
5932 "set level to %d\n", level);
5933
5631 /* 5934 /*
5632 * Now we know what the final level should be, so we try to set it. 5935 * Now we know what the final level should be, so we try to set it.
5633 * Doing it this way makes the syscall restartable in case of EINTR 5936 * Doing it this way makes the syscall restartable in case of EINTR
@@ -5641,6 +5944,8 @@ static struct ibm_struct brightness_driver_data = {
5641 .read = brightness_read, 5944 .read = brightness_read,
5642 .write = brightness_write, 5945 .write = brightness_write,
5643 .exit = brightness_exit, 5946 .exit = brightness_exit,
5947 .suspend = brightness_suspend,
5948 .shutdown = brightness_shutdown,
5644}; 5949};
5645 5950
5646/************************************************************************* 5951/*************************************************************************
@@ -6086,6 +6391,9 @@ static int fan_set_level(int level)
6086 default: 6391 default:
6087 return -ENXIO; 6392 return -ENXIO;
6088 } 6393 }
6394
6395 vdbg_printk(TPACPI_DBG_FAN,
6396 "fan control: set fan control register to 0x%02x\n", level);
6089 return 0; 6397 return 0;
6090} 6398}
6091 6399
@@ -6163,6 +6471,11 @@ static int fan_set_enable(void)
6163 } 6471 }
6164 6472
6165 mutex_unlock(&fan_mutex); 6473 mutex_unlock(&fan_mutex);
6474
6475 if (!rc)
6476 vdbg_printk(TPACPI_DBG_FAN,
6477 "fan control: set fan control register to 0x%02x\n",
6478 s);
6166 return rc; 6479 return rc;
6167} 6480}
6168 6481
@@ -6199,6 +6512,9 @@ static int fan_set_disable(void)
6199 rc = -ENXIO; 6512 rc = -ENXIO;
6200 } 6513 }
6201 6514
6515 if (!rc)
6516 vdbg_printk(TPACPI_DBG_FAN,
6517 "fan control: set fan control register to 0\n");
6202 6518
6203 mutex_unlock(&fan_mutex); 6519 mutex_unlock(&fan_mutex);
6204 return rc; 6520 return rc;
@@ -6327,6 +6643,9 @@ static ssize_t fan_pwm1_enable_store(struct device *dev,
6327 if (parse_strtoul(buf, 2, &t)) 6643 if (parse_strtoul(buf, 2, &t))
6328 return -EINVAL; 6644 return -EINVAL;
6329 6645
6646 tpacpi_disclose_usertask("hwmon pwm1_enable",
6647 "set fan mode to %lu\n", t);
6648
6330 switch (t) { 6649 switch (t) {
6331 case 0: 6650 case 0:
6332 level = TP_EC_FAN_FULLSPEED; 6651 level = TP_EC_FAN_FULLSPEED;
@@ -6392,6 +6711,9 @@ static ssize_t fan_pwm1_store(struct device *dev,
6392 if (parse_strtoul(buf, 255, &s)) 6711 if (parse_strtoul(buf, 255, &s))
6393 return -EINVAL; 6712 return -EINVAL;
6394 6713
6714 tpacpi_disclose_usertask("hwmon pwm1",
6715 "set fan speed to %lu\n", s);
6716
6395 /* scale down from 0-255 to 0-7 */ 6717 /* scale down from 0-255 to 0-7 */
6396 newlevel = (s >> 5) & 0x07; 6718 newlevel = (s >> 5) & 0x07;
6397 6719
@@ -6458,6 +6780,8 @@ static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
6458 fan_watchdog_maxinterval = t; 6780 fan_watchdog_maxinterval = t;
6459 fan_watchdog_reset(); 6781 fan_watchdog_reset();
6460 6782
6783 tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t);
6784
6461 return count; 6785 return count;
6462} 6786}
6463 6787
@@ -6479,7 +6803,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
6479{ 6803{
6480 int rc; 6804 int rc;
6481 6805
6482 vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n"); 6806 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
6807 "initializing fan subdriver\n");
6483 6808
6484 mutex_init(&fan_mutex); 6809 mutex_init(&fan_mutex);
6485 fan_status_access_mode = TPACPI_FAN_NONE; 6810 fan_status_access_mode = TPACPI_FAN_NONE;
@@ -6538,7 +6863,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
6538 } 6863 }
6539 } 6864 }
6540 6865
6541 vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n", 6866 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
6867 "fan is %s, modes %d, %d\n",
6542 str_supported(fan_status_access_mode != TPACPI_FAN_NONE || 6868 str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
6543 fan_control_access_mode != TPACPI_FAN_WR_NONE), 6869 fan_control_access_mode != TPACPI_FAN_WR_NONE),
6544 fan_status_access_mode, fan_control_access_mode); 6870 fan_status_access_mode, fan_control_access_mode);
@@ -6547,7 +6873,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
6547 if (!fan_control_allowed) { 6873 if (!fan_control_allowed) {
6548 fan_control_access_mode = TPACPI_FAN_WR_NONE; 6874 fan_control_access_mode = TPACPI_FAN_WR_NONE;
6549 fan_control_commands = 0; 6875 fan_control_commands = 0;
6550 dbg_printk(TPACPI_DBG_INIT, 6876 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
6551 "fan control features disabled by parameter\n"); 6877 "fan control features disabled by parameter\n");
6552 } 6878 }
6553 6879
@@ -6576,7 +6902,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
6576 6902
6577static void fan_exit(void) 6903static void fan_exit(void)
6578{ 6904{
6579 vdbg_printk(TPACPI_DBG_EXIT, 6905 vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN,
6580 "cancelling any pending fan watchdog tasks\n"); 6906 "cancelling any pending fan watchdog tasks\n");
6581 6907
6582 /* FIXME: can we really do this unconditionally? */ 6908 /* FIXME: can we really do this unconditionally? */
@@ -6757,6 +7083,9 @@ static int fan_write_cmd_level(const char *cmd, int *rc)
6757 if (*rc == -ENXIO) 7083 if (*rc == -ENXIO)
6758 printk(TPACPI_ERR "level command accepted for unsupported " 7084 printk(TPACPI_ERR "level command accepted for unsupported "
6759 "access mode %d", fan_control_access_mode); 7085 "access mode %d", fan_control_access_mode);
7086 else if (!*rc)
7087 tpacpi_disclose_usertask("procfs fan",
7088 "set level to %d\n", level);
6760 7089
6761 return 1; 7090 return 1;
6762} 7091}
@@ -6770,6 +7099,8 @@ static int fan_write_cmd_enable(const char *cmd, int *rc)
6770 if (*rc == -ENXIO) 7099 if (*rc == -ENXIO)
6771 printk(TPACPI_ERR "enable command accepted for unsupported " 7100 printk(TPACPI_ERR "enable command accepted for unsupported "
6772 "access mode %d", fan_control_access_mode); 7101 "access mode %d", fan_control_access_mode);
7102 else if (!*rc)
7103 tpacpi_disclose_usertask("procfs fan", "enable\n");
6773 7104
6774 return 1; 7105 return 1;
6775} 7106}
@@ -6783,6 +7114,8 @@ static int fan_write_cmd_disable(const char *cmd, int *rc)
6783 if (*rc == -ENXIO) 7114 if (*rc == -ENXIO)
6784 printk(TPACPI_ERR "disable command accepted for unsupported " 7115 printk(TPACPI_ERR "disable command accepted for unsupported "
6785 "access mode %d", fan_control_access_mode); 7116 "access mode %d", fan_control_access_mode);
7117 else if (!*rc)
7118 tpacpi_disclose_usertask("procfs fan", "disable\n");
6786 7119
6787 return 1; 7120 return 1;
6788} 7121}
@@ -6801,6 +7134,9 @@ static int fan_write_cmd_speed(const char *cmd, int *rc)
6801 if (*rc == -ENXIO) 7134 if (*rc == -ENXIO)
6802 printk(TPACPI_ERR "speed command accepted for unsupported " 7135 printk(TPACPI_ERR "speed command accepted for unsupported "
6803 "access mode %d", fan_control_access_mode); 7136 "access mode %d", fan_control_access_mode);
7137 else if (!*rc)
7138 tpacpi_disclose_usertask("procfs fan",
7139 "set speed to %d\n", speed);
6804 7140
6805 return 1; 7141 return 1;
6806} 7142}
@@ -6814,8 +7150,12 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc)
6814 7150
6815 if (interval < 0 || interval > 120) 7151 if (interval < 0 || interval > 120)
6816 *rc = -EINVAL; 7152 *rc = -EINVAL;
6817 else 7153 else {
6818 fan_watchdog_maxinterval = interval; 7154 fan_watchdog_maxinterval = interval;
7155 tpacpi_disclose_usertask("procfs fan",
7156 "set watchdog timer to %d\n",
7157 interval);
7158 }
6819 7159
6820 return 1; 7160 return 1;
6821} 7161}
@@ -7244,10 +7584,10 @@ module_param_named(fan_control, fan_control_allowed, bool, 0);
7244MODULE_PARM_DESC(fan_control, 7584MODULE_PARM_DESC(fan_control,
7245 "Enables setting fan parameters features when true"); 7585 "Enables setting fan parameters features when true");
7246 7586
7247module_param_named(brightness_mode, brightness_mode, int, 0); 7587module_param_named(brightness_mode, brightness_mode, uint, 0);
7248MODULE_PARM_DESC(brightness_mode, 7588MODULE_PARM_DESC(brightness_mode,
7249 "Selects brightness control strategy: " 7589 "Selects brightness control strategy: "
7250 "0=auto, 1=EC, 2=CMOS, 3=both"); 7590 "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
7251 7591
7252module_param(brightness_enable, uint, 0); 7592module_param(brightness_enable, uint, 0);
7253MODULE_PARM_DESC(brightness_enable, 7593MODULE_PARM_DESC(brightness_enable,
@@ -7517,9 +7857,6 @@ static int __init thinkpad_acpi_module_init(void)
7517 return 0; 7857 return 0;
7518} 7858}
7519 7859
7520/* Please remove this in year 2009 */
7521MODULE_ALIAS("ibm_acpi");
7522
7523MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); 7860MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
7524 7861
7525/* 7862/*