aboutsummaryrefslogtreecommitdiffstats
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
parent07290bed7968c0e08fb3efe193fb148f1fea5e08 (diff)
parent0e501834f8c2ba7de2a56e332d346dcf4ac0b593 (diff)
Merge branch 'thinkpad-acpi' into release
-rw-r--r--Documentation/laptops/thinkpad-acpi.txt144
-rw-r--r--drivers/platform/x86/Kconfig24
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c735
3 files changed, 657 insertions, 246 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 41bc99fa1884..3d7650768bb5 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -20,7 +20,8 @@ moved to the drivers/misc tree and renamed to thinkpad-acpi for kernel
20kernel 2.6.29 and release 0.22. 20kernel 2.6.29 and release 0.22.
21 21
22The driver is named "thinkpad-acpi". In some places, like module 22The driver is named "thinkpad-acpi". In some places, like module
23names, "thinkpad_acpi" is used because of userspace issues. 23names and log messages, "thinkpad_acpi" is used because of userspace
24issues.
24 25
25"tpacpi" is used as a shorthand where "thinkpad-acpi" would be too 26"tpacpi" is used as a shorthand where "thinkpad-acpi" would be too
26long due to length limitations on some Linux kernel versions. 27long due to length limitations on some Linux kernel versions.
@@ -37,7 +38,7 @@ detailed description):
37 - ThinkLight on and off 38 - ThinkLight on and off
38 - limited docking and undocking 39 - limited docking and undocking
39 - UltraBay eject 40 - UltraBay eject
40 - CMOS control 41 - CMOS/UCMS control
41 - LED control 42 - LED control
42 - ACPI sounds 43 - ACPI sounds
43 - temperature sensors 44 - temperature sensors
@@ -46,6 +47,7 @@ detailed description):
46 - Volume control 47 - Volume control
47 - Fan control and monitoring: fan speed, fan enable/disable 48 - Fan control and monitoring: fan speed, fan enable/disable
48 - WAN enable and disable 49 - WAN enable and disable
50 - UWB enable and disable
49 51
50A compatibility table by model and feature is maintained on the web 52A compatibility table by model and feature is maintained on the web
51site, http://ibm-acpi.sf.net/. I appreciate any success or failure 53site, http://ibm-acpi.sf.net/. I appreciate any success or failure
@@ -53,7 +55,7 @@ reports, especially if they add to or correct the compatibility table.
53Please include the following information in your report: 55Please include the following information in your report:
54 56
55 - ThinkPad model name 57 - ThinkPad model name
56 - a copy of your DSDT, from /proc/acpi/dsdt 58 - a copy of your ACPI tables, using the "acpidump" utility
57 - a copy of the output of dmidecode, with serial numbers 59 - a copy of the output of dmidecode, with serial numbers
58 and UUIDs masked off 60 and UUIDs masked off
59 - which driver features work and which don't 61 - which driver features work and which don't
@@ -66,17 +68,18 @@ Installation
66------------ 68------------
67 69
68If you are compiling this driver as included in the Linux kernel 70If you are compiling this driver as included in the Linux kernel
69sources, simply enable the CONFIG_THINKPAD_ACPI option, and optionally 71sources, look for the CONFIG_THINKPAD_ACPI Kconfig option.
70enable the CONFIG_THINKPAD_ACPI_BAY option if you want the 72It is located on the menu path: "Device Drivers" -> "X86 Platform
71thinkpad-specific bay functionality. 73Specific Device Drivers" -> "ThinkPad ACPI Laptop Extras".
74
72 75
73Features 76Features
74-------- 77--------
75 78
76The driver exports two different interfaces to userspace, which can be 79The driver exports two different interfaces to userspace, which can be
77used to access the features it provides. One is a legacy procfs-based 80used to access the features it provides. One is a legacy procfs-based
78interface, which will be removed at some time in the distant future. 81interface, which will be removed at some time in the future. The other
79The other is a new sysfs-based interface which is not complete yet. 82is a new sysfs-based interface which is not complete yet.
80 83
81The procfs interface creates the /proc/acpi/ibm directory. There is a 84The procfs interface creates the /proc/acpi/ibm directory. There is a
82file under that directory for each feature it supports. The procfs 85file under that directory for each feature it supports. The procfs
@@ -111,15 +114,17 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver
111as a driver attribute (see below). 114as a driver attribute (see below).
112 115
113Sysfs driver attributes are on the driver's sysfs attribute space, 116Sysfs driver attributes are on the driver's sysfs attribute space,
114for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and 117for 2.6.23+ this is /sys/bus/platform/drivers/thinkpad_acpi/ and
115/sys/bus/platform/drivers/thinkpad_hwmon/ 118/sys/bus/platform/drivers/thinkpad_hwmon/
116 119
117Sysfs device attributes are on the thinkpad_acpi device sysfs attribute 120Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
118space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/. 121space, for 2.6.23+ this is /sys/devices/platform/thinkpad_acpi/.
119 122
120Sysfs device attributes for the sensors and fan are on the 123Sysfs device attributes for the sensors and fan are on the
121thinkpad_hwmon device's sysfs attribute space, but you should locate it 124thinkpad_hwmon device's sysfs attribute space, but you should locate it
122looking for a hwmon device with the name attribute of "thinkpad". 125looking for a hwmon device with the name attribute of "thinkpad", or
126better yet, through libsensors.
127
123 128
124Driver version 129Driver version
125-------------- 130--------------
@@ -129,6 +134,7 @@ sysfs driver attribute: version
129 134
130The driver name and version. No commands can be written to this file. 135The driver name and version. No commands can be written to this file.
131 136
137
132Sysfs interface version 138Sysfs interface version
133----------------------- 139-----------------------
134 140
@@ -160,6 +166,7 @@ expect that an attribute might not be there, and deal with it properly
160(an attribute not being there *is* a valid way to make it clear that a 166(an attribute not being there *is* a valid way to make it clear that a
161feature is not available in sysfs). 167feature is not available in sysfs).
162 168
169
163Hot keys 170Hot keys
164-------- 171--------
165 172
@@ -172,17 +179,14 @@ system. Enabling the hotkey functionality of thinkpad-acpi signals the
172firmware that such a driver is present, and modifies how the ThinkPad 179firmware that such a driver is present, and modifies how the ThinkPad
173firmware will behave in many situations. 180firmware will behave in many situations.
174 181
175The driver enables the hot key feature automatically when loaded. The 182The driver enables the HKEY ("hot key") event reporting automatically
176feature can later be disabled and enabled back at runtime. The driver 183when loaded, and disables it when it is removed.
177will also restore the hot key feature to its previous state and mask
178when it is unloaded.
179 184
180When the hotkey feature is enabled and the hot key mask is set (see 185The driver will report HKEY events in the following format:
181below), the driver will report HKEY events in the following format:
182 186
183 ibm/hotkey HKEY 00000080 0000xxxx 187 ibm/hotkey HKEY 00000080 0000xxxx
184 188
185Some of these events refer to hot key presses, but not all. 189Some of these events refer to hot key presses, but not all of them.
186 190
187The driver will generate events over the input layer for hot keys and 191The driver will generate events over the input layer for hot keys and
188radio switches, and over the ACPI netlink layer for other events. The 192radio switches, and over the ACPI netlink layer for other events. The
@@ -214,13 +218,17 @@ procfs notes:
214 218
215The following commands can be written to the /proc/acpi/ibm/hotkey file: 219The following commands can be written to the /proc/acpi/ibm/hotkey file:
216 220
217 echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
218 echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
219 echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys 221 echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys
220 echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys 222 echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
221 ... any other 8-hex-digit mask ... 223 ... any other 8-hex-digit mask ...
222 echo reset > /proc/acpi/ibm/hotkey -- restore the original mask 224 echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
223 225
226The following commands have been deprecated and will cause the kernel
227to log a warning:
228
229 echo enable > /proc/acpi/ibm/hotkey -- does nothing
230 echo disable > /proc/acpi/ibm/hotkey -- returns an error
231
224The procfs interface does not support NVRAM polling control. So as to 232The procfs interface does not support NVRAM polling control. So as to
225maintain maximum bug-to-bug compatibility, it does not report any masks, 233maintain maximum bug-to-bug compatibility, it does not report any masks,
226nor does it allow one to manipulate the hot key mask when the firmware 234nor does it allow one to manipulate the hot key mask when the firmware
@@ -229,12 +237,9 @@ does not support masks at all, even if NVRAM polling is in use.
229sysfs notes: 237sysfs notes:
230 238
231 hotkey_bios_enabled: 239 hotkey_bios_enabled:
232 Returns the status of the hot keys feature when 240 DEPRECATED, WILL BE REMOVED SOON.
233 thinkpad-acpi was loaded. Upon module unload, the hot
234 key feature status will be restored to this value.
235 241
236 0: hot keys were disabled 242 Returns 0.
237 1: hot keys were enabled (unusual)
238 243
239 hotkey_bios_mask: 244 hotkey_bios_mask:
240 Returns the hot keys mask when thinkpad-acpi was loaded. 245 Returns the hot keys mask when thinkpad-acpi was loaded.
@@ -242,13 +247,10 @@ sysfs notes:
242 to this value. 247 to this value.
243 248
244 hotkey_enable: 249 hotkey_enable:
245 Enables/disables the hot keys feature in the ACPI 250 DEPRECATED, WILL BE REMOVED SOON.
246 firmware, and reports current status of the hot keys
247 feature. Has no effect on the NVRAM hot key polling
248 functionality.
249 251
250 0: disables the hot keys feature / feature disabled 252 0: returns -EPERM
251 1: enables the hot keys feature / feature enabled 253 1: does nothing
252 254
253 hotkey_mask: 255 hotkey_mask:
254 bit mask to enable driver-handling (and depending on 256 bit mask to enable driver-handling (and depending on
@@ -618,6 +620,7 @@ For Lenovo models *with* ACPI backlight control:
618 and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process 620 and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process
619 these keys on userspace somehow (e.g. by calling xbacklight). 621 these keys on userspace somehow (e.g. by calling xbacklight).
620 622
623
621Bluetooth 624Bluetooth
622--------- 625---------
623 626
@@ -628,6 +631,9 @@ sysfs rfkill class: switch "tpacpi_bluetooth_sw"
628This feature shows the presence and current state of a ThinkPad 631This feature shows the presence and current state of a ThinkPad
629Bluetooth device in the internal ThinkPad CDC slot. 632Bluetooth device in the internal ThinkPad CDC slot.
630 633
634If the ThinkPad supports it, the Bluetooth state is stored in NVRAM,
635so it is kept across reboots and power-off.
636
631Procfs notes: 637Procfs notes:
632 638
633If Bluetooth is installed, the following commands can be used: 639If Bluetooth is installed, the following commands can be used:
@@ -652,6 +658,7 @@ Sysfs notes:
652 rfkill controller switch "tpacpi_bluetooth_sw": refer to 658 rfkill controller switch "tpacpi_bluetooth_sw": refer to
653 Documentation/rfkill.txt for details. 659 Documentation/rfkill.txt for details.
654 660
661
655Video output control -- /proc/acpi/ibm/video 662Video output control -- /proc/acpi/ibm/video
656-------------------------------------------- 663--------------------------------------------
657 664
@@ -693,11 +700,8 @@ Fn-F7 from working. This also disables the video output switching
693features of this driver, as it uses the same ACPI methods as 700features of this driver, as it uses the same ACPI methods as
694Fn-F7. Video switching on the console should still work. 701Fn-F7. Video switching on the console should still work.
695 702
696UPDATE: There's now a patch for the X.org Radeon driver which 703UPDATE: refer to https://bugs.freedesktop.org/show_bug.cgi?id=2000
697addresses this issue. Some people are reporting success with the patch
698while others are still having problems. For more information:
699 704
700https://bugs.freedesktop.org/show_bug.cgi?id=2000
701 705
702ThinkLight control 706ThinkLight control
703------------------ 707------------------
@@ -720,10 +724,11 @@ The ThinkLight sysfs interface is documented by the LED class
720documentation, in Documentation/leds-class.txt. The ThinkLight LED name 724documentation, in Documentation/leds-class.txt. The ThinkLight LED name
721is "tpacpi::thinklight". 725is "tpacpi::thinklight".
722 726
723Due to limitations in the sysfs LED class, if the status of the thinklight 727Due to limitations in the sysfs LED class, if the status of the ThinkLight
724cannot be read or if it is unknown, thinkpad-acpi will report it as "off". 728cannot be read or if it is unknown, thinkpad-acpi will report it as "off".
725It is impossible to know if the status returned through sysfs is valid. 729It is impossible to know if the status returned through sysfs is valid.
726 730
731
727Docking / undocking -- /proc/acpi/ibm/dock 732Docking / undocking -- /proc/acpi/ibm/dock
728------------------------------------------ 733------------------------------------------
729 734
@@ -784,6 +789,7 @@ the only docking stations currently supported are the X-series
784UltraBase docks and "dumb" port replicators like the Mini Dock (the 789UltraBase docks and "dumb" port replicators like the Mini Dock (the
785latter don't need any ACPI support, actually). 790latter don't need any ACPI support, actually).
786 791
792
787UltraBay eject -- /proc/acpi/ibm/bay 793UltraBay eject -- /proc/acpi/ibm/bay
788------------------------------------ 794------------------------------------
789 795
@@ -847,8 +853,9 @@ supported. Use "eject2" instead of "eject" for the second bay.
847Note: the UltraBay eject support on the 600e/x, A22p and A3x is 853Note: the UltraBay eject support on the 600e/x, A22p and A3x is
848EXPERIMENTAL and may not work as expected. USE WITH CAUTION! 854EXPERIMENTAL and may not work as expected. USE WITH CAUTION!
849 855
850CMOS control 856
851------------ 857CMOS/UCMS control
858-----------------
852 859
853procfs: /proc/acpi/ibm/cmos 860procfs: /proc/acpi/ibm/cmos
854sysfs device attribute: cmos_command 861sysfs device attribute: cmos_command
@@ -882,6 +889,7 @@ The cmos command interface is prone to firmware split-brain problems, as
882in newer ThinkPads it is just a compatibility layer. Do not use it, it is 889in newer ThinkPads it is just a compatibility layer. Do not use it, it is
883exported just as a debug tool. 890exported just as a debug tool.
884 891
892
885LED control 893LED control
886----------- 894-----------
887 895
@@ -893,6 +901,17 @@ some older ThinkPad models, it is possible to query the status of the
893LED indicators as well. Newer ThinkPads cannot query the real status 901LED indicators as well. Newer ThinkPads cannot query the real status
894of the LED indicators. 902of the LED indicators.
895 903
904Because misuse of the LEDs could induce an unaware user to perform
905dangerous actions (like undocking or ejecting a bay device while the
906buses are still active), or mask an important alarm (such as a nearly
907empty battery, or a broken battery), access to most LEDs is
908restricted.
909
910Unrestricted access to all LEDs requires that thinkpad-acpi be
911compiled with the CONFIG_THINKPAD_ACPI_UNSAFE_LEDS option enabled.
912Distributions must never enable this option. Individual users that
913are aware of the consequences are welcome to enabling it.
914
896procfs notes: 915procfs notes:
897 916
898The available commands are: 917The available commands are:
@@ -939,6 +958,7 @@ ThinkPad indicator LED should blink in hardware accelerated mode, use the
939"timer" trigger, and leave the delay_on and delay_off parameters set to 958"timer" trigger, and leave the delay_on and delay_off parameters set to
940zero (to request hardware acceleration autodetection). 959zero (to request hardware acceleration autodetection).
941 960
961
942ACPI sounds -- /proc/acpi/ibm/beep 962ACPI sounds -- /proc/acpi/ibm/beep
943---------------------------------- 963----------------------------------
944 964
@@ -968,6 +988,7 @@ X40:
968 16 - one medium-pitched beep repeating constantly, stop with 17 988 16 - one medium-pitched beep repeating constantly, stop with 17
969 17 - stop 16 989 17 - stop 16
970 990
991
971Temperature sensors 992Temperature sensors
972------------------- 993-------------------
973 994
@@ -1115,6 +1136,7 @@ registers contain the current battery capacity, etc. If you experiment
1115with this, do send me your results (including some complete dumps with 1136with this, do send me your results (including some complete dumps with
1116a description of the conditions when they were taken.) 1137a description of the conditions when they were taken.)
1117 1138
1139
1118LCD brightness control 1140LCD brightness control
1119---------------------- 1141----------------------
1120 1142
@@ -1124,10 +1146,9 @@ sysfs backlight device "thinkpad_screen"
1124This feature allows software control of the LCD brightness on ThinkPad 1146This feature allows software control of the LCD brightness on ThinkPad
1125models which don't have a hardware brightness slider. 1147models which don't have a hardware brightness slider.
1126 1148
1127It has some limitations: the LCD backlight cannot be actually turned on or 1149It has some limitations: the LCD backlight cannot be actually turned
1128off by this interface, and in many ThinkPad models, the "dim while on 1150on or off by this interface, it just controls the backlight brightness
1129battery" functionality will be enabled by the BIOS when this interface is 1151level.
1130used, and cannot be controlled.
1131 1152
1132On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control 1153On IBM (and some of the earlier Lenovo) ThinkPads, the backlight control
1133has eight brightness levels, ranging from 0 to 7. Some of the levels 1154has eight brightness levels, ranging from 0 to 7. Some of the levels
@@ -1136,10 +1157,15 @@ display backlight brightness control methods have 16 levels, ranging
1136from 0 to 15. 1157from 0 to 15.
1137 1158
1138There are two interfaces to the firmware for direct brightness control, 1159There are two interfaces to the firmware for direct brightness control,
1139EC and CMOS. To select which one should be used, use the 1160EC and UCMS (or CMOS). To select which one should be used, use the
1140brightness_mode module parameter: brightness_mode=1 selects EC mode, 1161brightness_mode module parameter: brightness_mode=1 selects EC mode,
1141brightness_mode=2 selects CMOS mode, brightness_mode=3 selects both EC 1162brightness_mode=2 selects UCMS mode, brightness_mode=3 selects EC
1142and CMOS. The driver tries to auto-detect which interface to use. 1163mode with NVRAM backing (so that brightness changes are remembered
1164across shutdown/reboot).
1165
1166The driver tries to select which interface to use from a table of
1167defaults for each ThinkPad model. If it makes a wrong choice, please
1168report this as a bug, so that we can fix it.
1143 1169
1144When display backlight brightness controls are available through the 1170When display backlight brightness controls are available through the
1145standard ACPI interface, it is best to use it instead of this direct 1171standard ACPI interface, it is best to use it instead of this direct
@@ -1201,6 +1227,7 @@ WARNING:
1201 and maybe reduce the life of the backlight lamps by needlessly kicking 1227 and maybe reduce the life of the backlight lamps by needlessly kicking
1202 its level up and down at every change. 1228 its level up and down at every change.
1203 1229
1230
1204Volume control -- /proc/acpi/ibm/volume 1231Volume control -- /proc/acpi/ibm/volume
1205--------------------------------------- 1232---------------------------------------
1206 1233
@@ -1217,6 +1244,11 @@ distinct. The unmute the volume after the mute command, use either the
1217up or down command (the level command will not unmute the volume). 1244up or down command (the level command will not unmute the volume).
1218The current volume level and mute state is shown in the file. 1245The current volume level and mute state is shown in the file.
1219 1246
1247The ALSA mixer interface to this feature is still missing, but patches
1248to add it exist. That problem should be addressed in the not so
1249distant future.
1250
1251
1220Fan control and monitoring: fan speed, fan enable/disable 1252Fan control and monitoring: fan speed, fan enable/disable
1221--------------------------------------------------------- 1253---------------------------------------------------------
1222 1254
@@ -1383,8 +1415,11 @@ procfs: /proc/acpi/ibm/wan
1383sysfs device attribute: wwan_enable (deprecated) 1415sysfs device attribute: wwan_enable (deprecated)
1384sysfs rfkill class: switch "tpacpi_wwan_sw" 1416sysfs rfkill class: switch "tpacpi_wwan_sw"
1385 1417
1386This feature shows the presence and current state of a W-WAN (Sierra 1418This feature shows the presence and current state of the built-in
1387Wireless EV-DO) device. 1419Wireless WAN device.
1420
1421If the ThinkPad supports it, the WWAN state is stored in NVRAM,
1422so it is kept across reboots and power-off.
1388 1423
1389It was tested on a Lenovo ThinkPad X60. It should probably work on other 1424It was tested on a Lenovo ThinkPad X60. It should probably work on other
1390ThinkPad models which come with this module installed. 1425ThinkPad models which come with this module installed.
@@ -1413,6 +1448,7 @@ Sysfs notes:
1413 rfkill controller switch "tpacpi_wwan_sw": refer to 1448 rfkill controller switch "tpacpi_wwan_sw": refer to
1414 Documentation/rfkill.txt for details. 1449 Documentation/rfkill.txt for details.
1415 1450
1451
1416EXPERIMENTAL: UWB 1452EXPERIMENTAL: UWB
1417----------------- 1453-----------------
1418 1454
@@ -1431,6 +1467,7 @@ Sysfs notes:
1431 rfkill controller switch "tpacpi_uwb_sw": refer to 1467 rfkill controller switch "tpacpi_uwb_sw": refer to
1432 Documentation/rfkill.txt for details. 1468 Documentation/rfkill.txt for details.
1433 1469
1470
1434Multiple Commands, Module Parameters 1471Multiple Commands, Module Parameters
1435------------------------------------ 1472------------------------------------
1436 1473
@@ -1445,6 +1482,7 @@ for example:
1445 1482
1446 modprobe thinkpad_acpi hotkey=enable,0xffff video=auto_disable 1483 modprobe thinkpad_acpi hotkey=enable,0xffff video=auto_disable
1447 1484
1485
1448Enabling debugging output 1486Enabling debugging output
1449------------------------- 1487-------------------------
1450 1488
@@ -1457,8 +1495,15 @@ will enable all debugging output classes. It takes a bitmask, so
1457to enable more than one output class, just add their values. 1495to enable more than one output class, just add their values.
1458 1496
1459 Debug bitmask Description 1497 Debug bitmask Description
1498 0x8000 Disclose PID of userspace programs
1499 accessing some functions of the driver
1460 0x0001 Initialization and probing 1500 0x0001 Initialization and probing
1461 0x0002 Removal 1501 0x0002 Removal
1502 0x0004 RF Transmitter control (RFKILL)
1503 (bluetooth, WWAN, UWB...)
1504 0x0008 HKEY event interface, hotkeys
1505 0x0010 Fan control
1506 0x0020 Backlight brightness
1462 1507
1463There is also a kernel build option to enable more debugging 1508There is also a kernel build option to enable more debugging
1464information, which may be necessary to debug driver problems. 1509information, which may be necessary to debug driver problems.
@@ -1467,6 +1512,7 @@ The level of debugging information output by the driver can be changed
1467at runtime through sysfs, using the driver attribute debug_level. The 1512at runtime through sysfs, using the driver attribute debug_level. The
1468attribute takes the same bitmask as the debug module parameter above. 1513attribute takes the same bitmask as the debug module parameter above.
1469 1514
1515
1470Force loading of module 1516Force loading of module
1471----------------------- 1517-----------------------
1472 1518
@@ -1505,3 +1551,7 @@ Sysfs interface changelog:
1505 1551
15060x020200: Add poll()/select() support to the following attributes: 15520x020200: Add poll()/select() support to the following attributes:
1507 hotkey_radio_sw, wakeup_hotunplug_complete, wakeup_reason 1553 hotkey_radio_sw, wakeup_hotunplug_complete, wakeup_reason
1554
15550x020300: hotkey enable/disable support removed, attributes
1556 hotkey_bios_enabled and hotkey_enable deprecated and
1557 marked for removal.
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/*