aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/Kconfig31
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/acer-wmi.c52
-rw-r--r--drivers/platform/x86/acerhdf.c602
-rw-r--r--drivers/platform/x86/dell-laptop.c101
-rw-r--r--drivers/platform/x86/dell-wmi.c56
-rw-r--r--drivers/platform/x86/eeepc-laptop.c141
-rw-r--r--drivers/platform/x86/hp-wmi.c185
-rw-r--r--drivers/platform/x86/sony-laptop.c194
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c1287
-rw-r--r--drivers/platform/x86/toshiba_acpi.c160
11 files changed, 1837 insertions, 973 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 284ebaca6e4..5613483db14 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -21,7 +21,7 @@ config ACER_WMI
21 depends on NEW_LEDS 21 depends on NEW_LEDS
22 depends on BACKLIGHT_CLASS_DEVICE 22 depends on BACKLIGHT_CLASS_DEVICE
23 depends on SERIO_I8042 23 depends on SERIO_I8042
24 depends on RFKILL 24 depends on RFKILL || RFKILL = n
25 select ACPI_WMI 25 select ACPI_WMI
26 ---help--- 26 ---help---
27 This is a driver for newer Acer (and Wistron) laptops. It adds 27 This is a driver for newer Acer (and Wistron) laptops. It adds
@@ -34,6 +34,23 @@ config ACER_WMI
34 If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M 34 If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M
35 here. 35 here.
36 36
37config ACERHDF
38 tristate "Acer Aspire One temperature and fan driver"
39 depends on THERMAL && THERMAL_HWMON && ACPI
40 ---help---
41 This is a driver for Acer Aspire One netbooks. It allows to access
42 the temperature sensor and to control the fan.
43
44 After loading this driver the BIOS is still in control of the fan.
45 To let the kernel handle the fan, do:
46 echo -n enabled > /sys/class/thermal/thermal_zone0/mode
47
48 For more information about this driver see
49 <http://piie.net/files/acerhdf_README.txt>
50
51 If you have an Acer Aspire One netbook, say Y or M
52 here.
53
37config ASUS_LAPTOP 54config ASUS_LAPTOP
38 tristate "Asus Laptop Extras (EXPERIMENTAL)" 55 tristate "Asus Laptop Extras (EXPERIMENTAL)"
39 depends on ACPI 56 depends on ACPI
@@ -60,7 +77,7 @@ config DELL_LAPTOP
60 depends on DCDBAS 77 depends on DCDBAS
61 depends on EXPERIMENTAL 78 depends on EXPERIMENTAL
62 depends on BACKLIGHT_CLASS_DEVICE 79 depends on BACKLIGHT_CLASS_DEVICE
63 depends on RFKILL 80 depends on RFKILL || RFKILL = n
64 depends on POWER_SUPPLY 81 depends on POWER_SUPPLY
65 default n 82 default n
66 ---help--- 83 ---help---
@@ -117,7 +134,7 @@ config HP_WMI
117 tristate "HP WMI extras" 134 tristate "HP WMI extras"
118 depends on ACPI_WMI 135 depends on ACPI_WMI
119 depends on INPUT 136 depends on INPUT
120 depends on RFKILL 137 depends on RFKILL || RFKILL = n
121 help 138 help
122 Say Y here if you want to support WMI-based hotkeys on HP laptops and 139 Say Y here if you want to support WMI-based hotkeys on HP laptops and
123 to read data from WMI such as docking or ambient light sensor state. 140 to read data from WMI such as docking or ambient light sensor state.
@@ -196,14 +213,13 @@ config THINKPAD_ACPI
196 tristate "ThinkPad ACPI Laptop Extras" 213 tristate "ThinkPad ACPI Laptop Extras"
197 depends on ACPI 214 depends on ACPI
198 depends on INPUT 215 depends on INPUT
216 depends on RFKILL || RFKILL = n
199 select BACKLIGHT_LCD_SUPPORT 217 select BACKLIGHT_LCD_SUPPORT
200 select BACKLIGHT_CLASS_DEVICE 218 select BACKLIGHT_CLASS_DEVICE
201 select HWMON 219 select HWMON
202 select NVRAM 220 select NVRAM
203 select NEW_LEDS 221 select NEW_LEDS
204 select LEDS_CLASS 222 select LEDS_CLASS
205 select NET
206 select RFKILL
207 ---help--- 223 ---help---
208 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds 224 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
209 support for Fn-Fx key combinations, Bluetooth control, video 225 support for Fn-Fx key combinations, Bluetooth control, video
@@ -338,9 +354,9 @@ config EEEPC_LAPTOP
338 depends on ACPI 354 depends on ACPI
339 depends on INPUT 355 depends on INPUT
340 depends on EXPERIMENTAL 356 depends on EXPERIMENTAL
357 depends on RFKILL || RFKILL = n
341 select BACKLIGHT_CLASS_DEVICE 358 select BACKLIGHT_CLASS_DEVICE
342 select HWMON 359 select HWMON
343 select RFKILL
344 ---help--- 360 ---help---
345 This driver supports the Fn-Fx keys on Eee PC laptops. 361 This driver supports the Fn-Fx keys on Eee PC laptops.
346 It also adds the ability to switch camera/wlan on/off. 362 It also adds the ability to switch camera/wlan on/off.
@@ -405,9 +421,8 @@ config ACPI_TOSHIBA
405 tristate "Toshiba Laptop Extras" 421 tristate "Toshiba Laptop Extras"
406 depends on ACPI 422 depends on ACPI
407 depends on INPUT 423 depends on INPUT
424 depends on RFKILL || RFKILL = n
408 select INPUT_POLLDEV 425 select INPUT_POLLDEV
409 select NET
410 select RFKILL
411 select BACKLIGHT_CLASS_DEVICE 426 select BACKLIGHT_CLASS_DEVICE
412 ---help--- 427 ---help---
413 This driver adds support for access to certain system settings 428 This driver adds support for access to certain system settings
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index e40c7bd1b87..641b8bfa553 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
9obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o 9obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
10obj-$(CONFIG_DELL_WMI) += dell-wmi.o 10obj-$(CONFIG_DELL_WMI) += dell-wmi.o
11obj-$(CONFIG_ACER_WMI) += acer-wmi.o 11obj-$(CONFIG_ACER_WMI) += acer-wmi.o
12obj-$(CONFIG_ACERHDF) += acerhdf.o
12obj-$(CONFIG_HP_WMI) += hp-wmi.o 13obj-$(CONFIG_HP_WMI) += hp-wmi.o
13obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o 14obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
14obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o 15obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 0f6e43bf4fc..be2fd6f9163 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -958,59 +958,47 @@ static void acer_rfkill_update(struct work_struct *ignored)
958 958
959 status = get_u32(&state, ACER_CAP_WIRELESS); 959 status = get_u32(&state, ACER_CAP_WIRELESS);
960 if (ACPI_SUCCESS(status)) 960 if (ACPI_SUCCESS(status))
961 rfkill_force_state(wireless_rfkill, state ? 961 rfkill_set_sw_state(wireless_rfkill, !state);
962 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED);
963 962
964 if (has_cap(ACER_CAP_BLUETOOTH)) { 963 if (has_cap(ACER_CAP_BLUETOOTH)) {
965 status = get_u32(&state, ACER_CAP_BLUETOOTH); 964 status = get_u32(&state, ACER_CAP_BLUETOOTH);
966 if (ACPI_SUCCESS(status)) 965 if (ACPI_SUCCESS(status))
967 rfkill_force_state(bluetooth_rfkill, state ? 966 rfkill_set_sw_state(bluetooth_rfkill, !state);
968 RFKILL_STATE_UNBLOCKED :
969 RFKILL_STATE_SOFT_BLOCKED);
970 } 967 }
971 968
972 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); 969 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
973} 970}
974 971
975static int acer_rfkill_set(void *data, enum rfkill_state state) 972static int acer_rfkill_set(void *data, bool blocked)
976{ 973{
977 acpi_status status; 974 acpi_status status;
978 u32 *cap = data; 975 u32 cap = (unsigned long)data;
979 status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap); 976 status = set_u32(!!blocked, cap);
980 if (ACPI_FAILURE(status)) 977 if (ACPI_FAILURE(status))
981 return -ENODEV; 978 return -ENODEV;
982 return 0; 979 return 0;
983} 980}
984 981
985static struct rfkill * acer_rfkill_register(struct device *dev, 982static const struct rfkill_ops acer_rfkill_ops = {
986enum rfkill_type type, char *name, u32 cap) 983 .set_block = acer_rfkill_set,
984};
985
986static struct rfkill *acer_rfkill_register(struct device *dev,
987 enum rfkill_type type,
988 char *name, u32 cap)
987{ 989{
988 int err; 990 int err;
989 u32 state;
990 u32 *data;
991 struct rfkill *rfkill_dev; 991 struct rfkill *rfkill_dev;
992 992
993 rfkill_dev = rfkill_allocate(dev, type); 993 rfkill_dev = rfkill_alloc(name, dev, type,
994 &acer_rfkill_ops,
995 (void *)(unsigned long)cap);
994 if (!rfkill_dev) 996 if (!rfkill_dev)
995 return ERR_PTR(-ENOMEM); 997 return ERR_PTR(-ENOMEM);
996 rfkill_dev->name = name;
997 get_u32(&state, cap);
998 rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED :
999 RFKILL_STATE_SOFT_BLOCKED;
1000 data = kzalloc(sizeof(u32), GFP_KERNEL);
1001 if (!data) {
1002 rfkill_free(rfkill_dev);
1003 return ERR_PTR(-ENOMEM);
1004 }
1005 *data = cap;
1006 rfkill_dev->data = data;
1007 rfkill_dev->toggle_radio = acer_rfkill_set;
1008 rfkill_dev->user_claim_unsupported = 1;
1009 998
1010 err = rfkill_register(rfkill_dev); 999 err = rfkill_register(rfkill_dev);
1011 if (err) { 1000 if (err) {
1012 kfree(rfkill_dev->data); 1001 rfkill_destroy(rfkill_dev);
1013 rfkill_free(rfkill_dev);
1014 return ERR_PTR(err); 1002 return ERR_PTR(err);
1015 } 1003 }
1016 return rfkill_dev; 1004 return rfkill_dev;
@@ -1028,8 +1016,8 @@ static int acer_rfkill_init(struct device *dev)
1028 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", 1016 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
1029 ACER_CAP_BLUETOOTH); 1017 ACER_CAP_BLUETOOTH);
1030 if (IS_ERR(bluetooth_rfkill)) { 1018 if (IS_ERR(bluetooth_rfkill)) {
1031 kfree(wireless_rfkill->data);
1032 rfkill_unregister(wireless_rfkill); 1019 rfkill_unregister(wireless_rfkill);
1020 rfkill_destroy(wireless_rfkill);
1033 return PTR_ERR(bluetooth_rfkill); 1021 return PTR_ERR(bluetooth_rfkill);
1034 } 1022 }
1035 } 1023 }
@@ -1042,11 +1030,13 @@ static int acer_rfkill_init(struct device *dev)
1042static void acer_rfkill_exit(void) 1030static void acer_rfkill_exit(void)
1043{ 1031{
1044 cancel_delayed_work_sync(&acer_rfkill_work); 1032 cancel_delayed_work_sync(&acer_rfkill_work);
1045 kfree(wireless_rfkill->data); 1033
1046 rfkill_unregister(wireless_rfkill); 1034 rfkill_unregister(wireless_rfkill);
1035 rfkill_destroy(wireless_rfkill);
1036
1047 if (has_cap(ACER_CAP_BLUETOOTH)) { 1037 if (has_cap(ACER_CAP_BLUETOOTH)) {
1048 kfree(bluetooth_rfkill->data);
1049 rfkill_unregister(bluetooth_rfkill); 1038 rfkill_unregister(bluetooth_rfkill);
1039 rfkill_destroy(bluetooth_rfkill);
1050 } 1040 }
1051 return; 1041 return;
1052} 1042}
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
new file mode 100644
index 00000000000..bdfee177eef
--- /dev/null
+++ b/drivers/platform/x86/acerhdf.c
@@ -0,0 +1,602 @@
1/*
2 * acerhdf - A driver which monitors the temperature
3 * of the aspire one netbook, turns on/off the fan
4 * as soon as the upper/lower threshold is reached.
5 *
6 * (C) 2009 - Peter Feuerer peter (a) piie.net
7 * http://piie.net
8 * 2009 Borislav Petkov <petkovbb@gmail.com>
9 *
10 * Inspired by and many thanks to:
11 * o acerfand - Rachel Greenham
12 * o acer_ec.pl - Michael Kurz michi.kurz (at) googlemail.com
13 * - Petr Tomasek tomasek (#) etf,cuni,cz
14 * - Carlos Corbacho cathectic (at) gmail.com
15 * o lkml - Matthew Garrett
16 * - Borislav Petkov
17 * - Andreas Mohr
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34#define pr_fmt(fmt) "acerhdf: " fmt
35
36#include <linux/kernel.h>
37#include <linux/module.h>
38#include <linux/fs.h>
39#include <linux/dmi.h>
40#include <acpi/acpi_drivers.h>
41#include <linux/sched.h>
42#include <linux/thermal.h>
43#include <linux/platform_device.h>
44
45/*
46 * The driver is started with "kernel mode off" by default. That means, the BIOS
47 * is still in control of the fan. In this mode the driver allows to read the
48 * temperature of the cpu and a userspace tool may take over control of the fan.
49 * If the driver is switched to "kernel mode" (e.g. via module parameter) the
50 * driver is in full control of the fan. If you want the module to be started in
51 * kernel mode by default, define the following:
52 */
53#undef START_IN_KERNEL_MODE
54
55#define DRV_VER "0.5.13"
56
57/*
58 * According to the Atom N270 datasheet,
59 * (http://download.intel.com/design/processor/datashts/320032.pdf) the
60 * CPU's optimal operating limits denoted in junction temperature as
61 * measured by the on-die thermal monitor are within 0 <= Tj <= 90. So,
62 * assume 89°C is critical temperature.
63 */
64#define ACERHDF_TEMP_CRIT 89
65#define ACERHDF_FAN_OFF 0
66#define ACERHDF_FAN_AUTO 1
67
68/*
69 * No matter what value the user puts into the fanon variable, turn on the fan
70 * at 80 degree Celsius to prevent hardware damage
71 */
72#define ACERHDF_MAX_FANON 80
73
74/*
75 * Maximum interval between two temperature checks is 15 seconds, as the die
76 * can get hot really fast under heavy load (plus we shouldn't forget about
77 * possible impact of _external_ aggressive sources such as heaters, sun etc.)
78 */
79#define ACERHDF_MAX_INTERVAL 15
80
81#ifdef START_IN_KERNEL_MODE
82static int kernelmode = 1;
83#else
84static int kernelmode;
85#endif
86
87static unsigned int interval = 10;
88static unsigned int fanon = 63;
89static unsigned int fanoff = 58;
90static unsigned int verbose;
91static unsigned int fanstate = ACERHDF_FAN_AUTO;
92static char force_bios[16];
93static unsigned int prev_interval;
94struct thermal_zone_device *thz_dev;
95struct thermal_cooling_device *cl_dev;
96struct platform_device *acerhdf_dev;
97
98module_param(kernelmode, uint, 0);
99MODULE_PARM_DESC(kernelmode, "Kernel mode fan control on / off");
100module_param(interval, uint, 0600);
101MODULE_PARM_DESC(interval, "Polling interval of temperature check");
102module_param(fanon, uint, 0600);
103MODULE_PARM_DESC(fanon, "Turn the fan on above this temperature");
104module_param(fanoff, uint, 0600);
105MODULE_PARM_DESC(fanoff, "Turn the fan off below this temperature");
106module_param(verbose, uint, 0600);
107MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");
108module_param_string(force_bios, force_bios, 16, 0);
109MODULE_PARM_DESC(force_bios, "Force BIOS version and omit BIOS check");
110
111/* BIOS settings */
112struct bios_settings_t {
113 const char *vendor;
114 const char *version;
115 unsigned char fanreg;
116 unsigned char tempreg;
117 unsigned char fancmd[2]; /* fan off and auto commands */
118};
119
120/* Register addresses and values for different BIOS versions */
121static const struct bios_settings_t bios_tbl[] = {
122 {"Acer", "v0.3109", 0x55, 0x58, {0x1f, 0x00} },
123 {"Acer", "v0.3114", 0x55, 0x58, {0x1f, 0x00} },
124 {"Acer", "v0.3301", 0x55, 0x58, {0xaf, 0x00} },
125 {"Acer", "v0.3304", 0x55, 0x58, {0xaf, 0x00} },
126 {"Acer", "v0.3305", 0x55, 0x58, {0xaf, 0x00} },
127 {"Acer", "v0.3308", 0x55, 0x58, {0x21, 0x00} },
128 {"Acer", "v0.3309", 0x55, 0x58, {0x21, 0x00} },
129 {"Acer", "v0.3310", 0x55, 0x58, {0x21, 0x00} },
130 {"Gateway", "v0.3103", 0x55, 0x58, {0x21, 0x00} },
131 {"Packard Bell", "v0.3105", 0x55, 0x58, {0x21, 0x00} },
132 {"", "", 0, 0, {0, 0} }
133};
134
135static const struct bios_settings_t *bios_cfg __read_mostly;
136
137
138static int acerhdf_get_temp(int *temp)
139{
140 u8 read_temp;
141
142 if (ec_read(bios_cfg->tempreg, &read_temp))
143 return -EINVAL;
144
145 *temp = read_temp;
146
147 return 0;
148}
149
150static int acerhdf_get_fanstate(int *state)
151{
152 u8 fan;
153 bool tmp;
154
155 if (ec_read(bios_cfg->fanreg, &fan))
156 return -EINVAL;
157
158 tmp = (fan == bios_cfg->fancmd[ACERHDF_FAN_OFF]);
159 *state = tmp ? ACERHDF_FAN_OFF : ACERHDF_FAN_AUTO;
160
161 return 0;
162}
163
164static void acerhdf_change_fanstate(int state)
165{
166 unsigned char cmd;
167
168 if (verbose)
169 pr_notice("fan %s\n", (state == ACERHDF_FAN_OFF) ?
170 "OFF" : "ON");
171
172 if ((state != ACERHDF_FAN_OFF) && (state != ACERHDF_FAN_AUTO)) {
173 pr_err("invalid fan state %d requested, setting to auto!\n",
174 state);
175 state = ACERHDF_FAN_AUTO;
176 }
177
178 cmd = bios_cfg->fancmd[state];
179 fanstate = state;
180
181 ec_write(bios_cfg->fanreg, cmd);
182}
183
184static void acerhdf_check_param(struct thermal_zone_device *thermal)
185{
186 if (fanon > ACERHDF_MAX_FANON) {
187 pr_err("fanon temperature too high, set to %d\n",
188 ACERHDF_MAX_FANON);
189 fanon = ACERHDF_MAX_FANON;
190 }
191
192 if (kernelmode && prev_interval != interval) {
193 if (interval > ACERHDF_MAX_INTERVAL) {
194 pr_err("interval too high, set to %d\n",
195 ACERHDF_MAX_INTERVAL);
196 interval = ACERHDF_MAX_INTERVAL;
197 }
198 if (verbose)
199 pr_notice("interval changed to: %d\n",
200 interval);
201 thermal->polling_delay = interval*1000;
202 prev_interval = interval;
203 }
204}
205
206/*
207 * This is the thermal zone callback which does the delayed polling of the fan
208 * state. We do check /sysfs-originating settings here in acerhdf_check_param()
209 * as late as the polling interval is since we can't do that in the respective
210 * accessors of the module parameters.
211 */
212static int acerhdf_get_ec_temp(struct thermal_zone_device *thermal,
213 unsigned long *t)
214{
215 int temp, err = 0;
216
217 acerhdf_check_param(thermal);
218
219 err = acerhdf_get_temp(&temp);
220 if (err)
221 return err;
222
223 if (verbose)
224 pr_notice("temp %d\n", temp);
225
226 *t = temp;
227 return 0;
228}
229
230static int acerhdf_bind(struct thermal_zone_device *thermal,
231 struct thermal_cooling_device *cdev)
232{
233 /* if the cooling device is the one from acerhdf bind it */
234 if (cdev != cl_dev)
235 return 0;
236
237 if (thermal_zone_bind_cooling_device(thermal, 0, cdev)) {
238 pr_err("error binding cooling dev\n");
239 return -EINVAL;
240 }
241 return 0;
242}
243
244static int acerhdf_unbind(struct thermal_zone_device *thermal,
245 struct thermal_cooling_device *cdev)
246{
247 if (cdev != cl_dev)
248 return 0;
249
250 if (thermal_zone_unbind_cooling_device(thermal, 0, cdev)) {
251 pr_err("error unbinding cooling dev\n");
252 return -EINVAL;
253 }
254 return 0;
255}
256
257static inline void acerhdf_revert_to_bios_mode(void)
258{
259 acerhdf_change_fanstate(ACERHDF_FAN_AUTO);
260 kernelmode = 0;
261 if (thz_dev)
262 thz_dev->polling_delay = 0;
263 pr_notice("kernel mode fan control OFF\n");
264}
265static inline void acerhdf_enable_kernelmode(void)
266{
267 kernelmode = 1;
268
269 thz_dev->polling_delay = interval*1000;
270 thermal_zone_device_update(thz_dev);
271 pr_notice("kernel mode fan control ON\n");
272}
273
274static int acerhdf_get_mode(struct thermal_zone_device *thermal,
275 enum thermal_device_mode *mode)
276{
277 if (verbose)
278 pr_notice("kernel mode fan control %d\n", kernelmode);
279
280 *mode = (kernelmode) ? THERMAL_DEVICE_ENABLED
281 : THERMAL_DEVICE_DISABLED;
282
283 return 0;
284}
285
286/*
287 * set operation mode;
288 * enabled: the thermal layer of the kernel takes care about
289 * the temperature and the fan.
290 * disabled: the BIOS takes control of the fan.
291 */
292static int acerhdf_set_mode(struct thermal_zone_device *thermal,
293 enum thermal_device_mode mode)
294{
295 if (mode == THERMAL_DEVICE_DISABLED && kernelmode)
296 acerhdf_revert_to_bios_mode();
297 else if (mode == THERMAL_DEVICE_ENABLED && !kernelmode)
298 acerhdf_enable_kernelmode();
299
300 return 0;
301}
302
303static int acerhdf_get_trip_type(struct thermal_zone_device *thermal, int trip,
304 enum thermal_trip_type *type)
305{
306 if (trip == 0)
307 *type = THERMAL_TRIP_ACTIVE;
308
309 return 0;
310}
311
312static int acerhdf_get_trip_temp(struct thermal_zone_device *thermal, int trip,
313 unsigned long *temp)
314{
315 if (trip == 0)
316 *temp = fanon;
317
318 return 0;
319}
320
321static int acerhdf_get_crit_temp(struct thermal_zone_device *thermal,
322 unsigned long *temperature)
323{
324 *temperature = ACERHDF_TEMP_CRIT;
325 return 0;
326}
327
328/* bind callback functions to thermalzone */
329struct thermal_zone_device_ops acerhdf_dev_ops = {
330 .bind = acerhdf_bind,
331 .unbind = acerhdf_unbind,
332 .get_temp = acerhdf_get_ec_temp,
333 .get_mode = acerhdf_get_mode,
334 .set_mode = acerhdf_set_mode,
335 .get_trip_type = acerhdf_get_trip_type,
336 .get_trip_temp = acerhdf_get_trip_temp,
337 .get_crit_temp = acerhdf_get_crit_temp,
338};
339
340
341/*
342 * cooling device callback functions
343 * get maximal fan cooling state
344 */
345static int acerhdf_get_max_state(struct thermal_cooling_device *cdev,
346 unsigned long *state)
347{
348 *state = 1;
349
350 return 0;
351}
352
353static int acerhdf_get_cur_state(struct thermal_cooling_device *cdev,
354 unsigned long *state)
355{
356 int err = 0, tmp;
357
358 err = acerhdf_get_fanstate(&tmp);
359 if (err)
360 return err;
361
362 *state = (tmp == ACERHDF_FAN_AUTO) ? 1 : 0;
363 return 0;
364}
365
366/* change current fan state - is overwritten when running in kernel mode */
367static int acerhdf_set_cur_state(struct thermal_cooling_device *cdev,
368 unsigned long state)
369{
370 int cur_temp, cur_state, err = 0;
371
372 if (!kernelmode)
373 return 0;
374
375 err = acerhdf_get_temp(&cur_temp);
376 if (err) {
377 pr_err("error reading temperature, hand off control to BIOS\n");
378 goto err_out;
379 }
380
381 err = acerhdf_get_fanstate(&cur_state);
382 if (err) {
383 pr_err("error reading fan state, hand off control to BIOS\n");
384 goto err_out;
385 }
386
387 if (state == 0) {
388 /* turn fan off only if below fanoff temperature */
389 if ((cur_state == ACERHDF_FAN_AUTO) &&
390 (cur_temp < fanoff))
391 acerhdf_change_fanstate(ACERHDF_FAN_OFF);
392 } else {
393 if (cur_state == ACERHDF_FAN_OFF)
394 acerhdf_change_fanstate(ACERHDF_FAN_AUTO);
395 }
396 return 0;
397
398err_out:
399 acerhdf_revert_to_bios_mode();
400 return -EINVAL;
401}
402
403/* bind fan callbacks to fan device */
404struct thermal_cooling_device_ops acerhdf_cooling_ops = {
405 .get_max_state = acerhdf_get_max_state,
406 .get_cur_state = acerhdf_get_cur_state,
407 .set_cur_state = acerhdf_set_cur_state,
408};
409
410/* suspend / resume functionality */
411static int acerhdf_suspend(struct platform_device *dev, pm_message_t state)
412{
413 if (kernelmode)
414 acerhdf_change_fanstate(ACERHDF_FAN_AUTO);
415
416 if (verbose)
417 pr_notice("going suspend\n");
418
419 return 0;
420}
421
422static int acerhdf_resume(struct platform_device *device)
423{
424 if (verbose)
425 pr_notice("resuming\n");
426
427 return 0;
428}
429
430static int __devinit acerhdf_probe(struct platform_device *device)
431{
432 return 0;
433}
434
435static int acerhdf_remove(struct platform_device *device)
436{
437 return 0;
438}
439
440struct platform_driver acerhdf_drv = {
441 .driver = {
442 .name = "acerhdf",
443 .owner = THIS_MODULE,
444 },
445 .probe = acerhdf_probe,
446 .remove = acerhdf_remove,
447 .suspend = acerhdf_suspend,
448 .resume = acerhdf_resume,
449};
450
451
452/* check hardware */
453static int acerhdf_check_hardware(void)
454{
455 char const *vendor, *version, *product;
456 int i;
457
458 /* get BIOS data */
459 vendor = dmi_get_system_info(DMI_SYS_VENDOR);
460 version = dmi_get_system_info(DMI_BIOS_VERSION);
461 product = dmi_get_system_info(DMI_PRODUCT_NAME);
462
463 pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER);
464
465 if (!force_bios[0]) {
466 if (strncmp(product, "AO", 2)) {
467 pr_err("no Aspire One hardware found\n");
468 return -EINVAL;
469 }
470 } else {
471 pr_info("forcing BIOS version: %s\n", version);
472 version = force_bios;
473 kernelmode = 0;
474 }
475
476 if (verbose)
477 pr_info("BIOS info: %s %s, product: %s\n",
478 vendor, version, product);
479
480 /* search BIOS version and vendor in BIOS settings table */
481 for (i = 0; bios_tbl[i].version[0]; i++) {
482 if (!strcmp(bios_tbl[i].vendor, vendor) &&
483 !strcmp(bios_tbl[i].version, version)) {
484 bios_cfg = &bios_tbl[i];
485 break;
486 }
487 }
488
489 if (!bios_cfg) {
490 pr_err("unknown (unsupported) BIOS version %s/%s, "
491 "please report, aborting!\n", vendor, version);
492 return -EINVAL;
493 }
494
495 /*
496 * if started with kernel mode off, prevent the kernel from switching
497 * off the fan
498 */
499 if (!kernelmode) {
500 pr_notice("Fan control off, to enable do:\n");
501 pr_notice("echo -n \"enabled\" > "
502 "/sys/class/thermal/thermal_zone0/mode\n");
503 }
504
505 return 0;
506}
507
508static int acerhdf_register_platform(void)
509{
510 int err = 0;
511
512 err = platform_driver_register(&acerhdf_drv);
513 if (err)
514 return err;
515
516 acerhdf_dev = platform_device_alloc("acerhdf", -1);
517 platform_device_add(acerhdf_dev);
518
519 return 0;
520}
521
522static void acerhdf_unregister_platform(void)
523{
524 if (!acerhdf_dev)
525 return;
526
527 platform_device_del(acerhdf_dev);
528 platform_driver_unregister(&acerhdf_drv);
529}
530
531static int acerhdf_register_thermal(void)
532{
533 cl_dev = thermal_cooling_device_register("acerhdf-fan", NULL,
534 &acerhdf_cooling_ops);
535
536 if (IS_ERR(cl_dev))
537 return -EINVAL;
538
539 thz_dev = thermal_zone_device_register("acerhdf", 1, NULL,
540 &acerhdf_dev_ops, 0, 0, 0,
541 (kernelmode) ? interval*1000 : 0);
542 if (IS_ERR(thz_dev))
543 return -EINVAL;
544
545 return 0;
546}
547
548static void acerhdf_unregister_thermal(void)
549{
550 if (cl_dev) {
551 thermal_cooling_device_unregister(cl_dev);
552 cl_dev = NULL;
553 }
554
555 if (thz_dev) {
556 thermal_zone_device_unregister(thz_dev);
557 thz_dev = NULL;
558 }
559}
560
561static int __init acerhdf_init(void)
562{
563 int err = 0;
564
565 err = acerhdf_check_hardware();
566 if (err)
567 goto out_err;
568
569 err = acerhdf_register_platform();
570 if (err)
571 goto err_unreg;
572
573 err = acerhdf_register_thermal();
574 if (err)
575 goto err_unreg;
576
577 return 0;
578
579err_unreg:
580 acerhdf_unregister_thermal();
581 acerhdf_unregister_platform();
582
583out_err:
584 return -ENODEV;
585}
586
587static void __exit acerhdf_exit(void)
588{
589 acerhdf_change_fanstate(ACERHDF_FAN_AUTO);
590 acerhdf_unregister_thermal();
591 acerhdf_unregister_platform();
592}
593
594MODULE_LICENSE("GPL");
595MODULE_AUTHOR("Peter Feuerer");
596MODULE_DESCRIPTION("Aspire One temperature and fan driver");
597MODULE_ALIAS("dmi:*:*Acer*:*:");
598MODULE_ALIAS("dmi:*:*Gateway*:*:");
599MODULE_ALIAS("dmi:*:*Packard Bell*:*:");
600
601module_init(acerhdf_init);
602module_exit(acerhdf_exit);
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index af9f4302117..74909c4aaee 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -174,10 +174,11 @@ dell_send_request(struct calling_interface_buffer *buffer, int class,
174 result[3]: NVRAM format version number 174 result[3]: NVRAM format version number
175*/ 175*/
176 176
177static int dell_rfkill_set(int radio, enum rfkill_state state) 177static int dell_rfkill_set(void *data, bool blocked)
178{ 178{
179 struct calling_interface_buffer buffer; 179 struct calling_interface_buffer buffer;
180 int disable = (state == RFKILL_STATE_UNBLOCKED) ? 0 : 1; 180 int disable = blocked ? 1 : 0;
181 unsigned long radio = (unsigned long)data;
181 182
182 memset(&buffer, 0, sizeof(struct calling_interface_buffer)); 183 memset(&buffer, 0, sizeof(struct calling_interface_buffer));
183 buffer.input[0] = (1 | (radio<<8) | (disable << 16)); 184 buffer.input[0] = (1 | (radio<<8) | (disable << 16));
@@ -186,56 +187,24 @@ static int dell_rfkill_set(int radio, enum rfkill_state state)
186 return 0; 187 return 0;
187} 188}
188 189
189static int dell_wifi_set(void *data, enum rfkill_state state) 190static void dell_rfkill_query(struct rfkill *rfkill, void *data)
190{
191 return dell_rfkill_set(1, state);
192}
193
194static int dell_bluetooth_set(void *data, enum rfkill_state state)
195{
196 return dell_rfkill_set(2, state);
197}
198
199static int dell_wwan_set(void *data, enum rfkill_state state)
200{
201 return dell_rfkill_set(3, state);
202}
203
204static int dell_rfkill_get(int bit, enum rfkill_state *state)
205{ 191{
206 struct calling_interface_buffer buffer; 192 struct calling_interface_buffer buffer;
207 int status; 193 int status;
208 int new_state = RFKILL_STATE_HARD_BLOCKED; 194 int bit = (unsigned long)data + 16;
209 195
210 memset(&buffer, 0, sizeof(struct calling_interface_buffer)); 196 memset(&buffer, 0, sizeof(struct calling_interface_buffer));
211 dell_send_request(&buffer, 17, 11); 197 dell_send_request(&buffer, 17, 11);
212 status = buffer.output[1]; 198 status = buffer.output[1];
213 199
214 if (status & (1<<16)) 200 if (status & BIT(bit))
215 new_state = RFKILL_STATE_SOFT_BLOCKED; 201 rfkill_set_hw_state(rfkill, !!(status & BIT(16)));
216
217 if (status & (1<<bit))
218 *state = new_state;
219 else
220 *state = RFKILL_STATE_UNBLOCKED;
221
222 return 0;
223}
224
225static int dell_wifi_get(void *data, enum rfkill_state *state)
226{
227 return dell_rfkill_get(17, state);
228}
229
230static int dell_bluetooth_get(void *data, enum rfkill_state *state)
231{
232 return dell_rfkill_get(18, state);
233} 202}
234 203
235static int dell_wwan_get(void *data, enum rfkill_state *state) 204static const struct rfkill_ops dell_rfkill_ops = {
236{ 205 .set_block = dell_rfkill_set,
237 return dell_rfkill_get(19, state); 206 .query = dell_rfkill_query,
238} 207};
239 208
240static int dell_setup_rfkill(void) 209static int dell_setup_rfkill(void)
241{ 210{
@@ -248,36 +217,37 @@ static int dell_setup_rfkill(void)
248 status = buffer.output[1]; 217 status = buffer.output[1];
249 218
250 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { 219 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
251 wifi_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WLAN); 220 wifi_rfkill = rfkill_alloc("dell-wifi", NULL, RFKILL_TYPE_WLAN,
252 if (!wifi_rfkill) 221 &dell_rfkill_ops, (void *) 1);
222 if (!wifi_rfkill) {
223 ret = -ENOMEM;
253 goto err_wifi; 224 goto err_wifi;
254 wifi_rfkill->name = "dell-wifi"; 225 }
255 wifi_rfkill->toggle_radio = dell_wifi_set;
256 wifi_rfkill->get_state = dell_wifi_get;
257 ret = rfkill_register(wifi_rfkill); 226 ret = rfkill_register(wifi_rfkill);
258 if (ret) 227 if (ret)
259 goto err_wifi; 228 goto err_wifi;
260 } 229 }
261 230
262 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { 231 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {
263 bluetooth_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_BLUETOOTH); 232 bluetooth_rfkill = rfkill_alloc("dell-bluetooth", NULL,
264 if (!bluetooth_rfkill) 233 RFKILL_TYPE_BLUETOOTH,
234 &dell_rfkill_ops, (void *) 2);
235 if (!bluetooth_rfkill) {
236 ret = -ENOMEM;
265 goto err_bluetooth; 237 goto err_bluetooth;
266 bluetooth_rfkill->name = "dell-bluetooth"; 238 }
267 bluetooth_rfkill->toggle_radio = dell_bluetooth_set;
268 bluetooth_rfkill->get_state = dell_bluetooth_get;
269 ret = rfkill_register(bluetooth_rfkill); 239 ret = rfkill_register(bluetooth_rfkill);
270 if (ret) 240 if (ret)
271 goto err_bluetooth; 241 goto err_bluetooth;
272 } 242 }
273 243
274 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { 244 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {
275 wwan_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WWAN); 245 wwan_rfkill = rfkill_alloc("dell-wwan", NULL, RFKILL_TYPE_WWAN,
276 if (!wwan_rfkill) 246 &dell_rfkill_ops, (void *) 3);
247 if (!wwan_rfkill) {
248 ret = -ENOMEM;
277 goto err_wwan; 249 goto err_wwan;
278 wwan_rfkill->name = "dell-wwan"; 250 }
279 wwan_rfkill->toggle_radio = dell_wwan_set;
280 wwan_rfkill->get_state = dell_wwan_get;
281 ret = rfkill_register(wwan_rfkill); 251 ret = rfkill_register(wwan_rfkill);
282 if (ret) 252 if (ret)
283 goto err_wwan; 253 goto err_wwan;
@@ -285,22 +255,15 @@ static int dell_setup_rfkill(void)
285 255
286 return 0; 256 return 0;
287err_wwan: 257err_wwan:
288 if (wwan_rfkill) 258 rfkill_destroy(wwan_rfkill);
289 rfkill_free(wwan_rfkill); 259 if (bluetooth_rfkill)
290 if (bluetooth_rfkill) {
291 rfkill_unregister(bluetooth_rfkill); 260 rfkill_unregister(bluetooth_rfkill);
292 bluetooth_rfkill = NULL;
293 }
294err_bluetooth: 261err_bluetooth:
295 if (bluetooth_rfkill) 262 rfkill_destroy(bluetooth_rfkill);
296 rfkill_free(bluetooth_rfkill); 263 if (wifi_rfkill)
297 if (wifi_rfkill) {
298 rfkill_unregister(wifi_rfkill); 264 rfkill_unregister(wifi_rfkill);
299 wifi_rfkill = NULL;
300 }
301err_wifi: 265err_wifi:
302 if (wifi_rfkill) 266 rfkill_destroy(wifi_rfkill);
303 rfkill_free(wifi_rfkill);
304 267
305 return ret; 268 return ret;
306} 269}
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
index 2fab9416214..0f900cc9fa7 100644
--- a/drivers/platform/x86/dell-wmi.c
+++ b/drivers/platform/x86/dell-wmi.c
@@ -46,10 +46,53 @@ struct key_entry {
46 u16 keycode; 46 u16 keycode;
47}; 47};
48 48
49enum { KE_KEY, KE_SW, KE_END }; 49enum { KE_KEY, KE_SW, KE_IGNORE, KE_END };
50
51/*
52 * Certain keys are flagged as KE_IGNORE. All of these are either
53 * notifications (rather than requests for change) or are also sent
54 * via the keyboard controller so should not be sent again.
55 */
50 56
51static struct key_entry dell_wmi_keymap[] = { 57static struct key_entry dell_wmi_keymap[] = {
52 {KE_KEY, 0xe045, KEY_PROG1}, 58 {KE_KEY, 0xe045, KEY_PROG1},
59 {KE_KEY, 0xe009, KEY_EJECTCD},
60
61 /* These also contain the brightness level at offset 6 */
62 {KE_KEY, 0xe006, KEY_BRIGHTNESSUP},
63 {KE_KEY, 0xe005, KEY_BRIGHTNESSDOWN},
64
65 /* Battery health status button */
66 {KE_KEY, 0xe007, KEY_BATTERY},
67
68 /* This is actually for all radios. Although physically a
69 * switch, the notification does not provide an indication of
70 * state and so it should be reported as a key */
71 {KE_KEY, 0xe008, KEY_WLAN},
72
73 /* The next device is at offset 6, the active devices are at
74 offset 8 and the attached devices at offset 10 */
75 {KE_KEY, 0xe00b, KEY_DISPLAYTOGGLE},
76
77 {KE_IGNORE, 0xe00c, KEY_KBDILLUMTOGGLE},
78
79 /* BIOS error detected */
80 {KE_IGNORE, 0xe00d, KEY_RESERVED},
81
82 /* Wifi Catcher */
83 {KE_KEY, 0xe011, KEY_PROG2},
84
85 /* Ambient light sensor toggle */
86 {KE_IGNORE, 0xe013, KEY_RESERVED},
87
88 {KE_IGNORE, 0xe020, KEY_MUTE},
89 {KE_IGNORE, 0xe02e, KEY_VOLUMEDOWN},
90 {KE_IGNORE, 0xe030, KEY_VOLUMEUP},
91 {KE_IGNORE, 0xe033, KEY_KBDILLUMUP},
92 {KE_IGNORE, 0xe034, KEY_KBDILLUMDOWN},
93 {KE_IGNORE, 0xe03a, KEY_CAPSLOCK},
94 {KE_IGNORE, 0xe045, KEY_NUMLOCK},
95 {KE_IGNORE, 0xe046, KEY_SCROLLLOCK},
53 {KE_END, 0} 96 {KE_END, 0}
54}; 97};
55 98
@@ -122,15 +165,20 @@ static void dell_wmi_notify(u32 value, void *context)
122 165
123 if (obj && obj->type == ACPI_TYPE_BUFFER) { 166 if (obj && obj->type == ACPI_TYPE_BUFFER) {
124 int *buffer = (int *)obj->buffer.pointer; 167 int *buffer = (int *)obj->buffer.pointer;
125 key = dell_wmi_get_entry_by_scancode(buffer[1]); 168 /*
169 * The upper bytes of the event may contain
170 * additional information, so mask them off for the
171 * scancode lookup
172 */
173 key = dell_wmi_get_entry_by_scancode(buffer[1] & 0xFFFF);
126 if (key) { 174 if (key) {
127 input_report_key(dell_wmi_input_dev, key->keycode, 1); 175 input_report_key(dell_wmi_input_dev, key->keycode, 1);
128 input_sync(dell_wmi_input_dev); 176 input_sync(dell_wmi_input_dev);
129 input_report_key(dell_wmi_input_dev, key->keycode, 0); 177 input_report_key(dell_wmi_input_dev, key->keycode, 0);
130 input_sync(dell_wmi_input_dev); 178 input_sync(dell_wmi_input_dev);
131 } else 179 } else if (buffer[1] & 0xFFFF)
132 printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n", 180 printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
133 buffer[1]); 181 buffer[1] & 0xFFFF);
134 } 182 }
135} 183}
136 184
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 353a898c369..8153b3e5918 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -180,6 +180,7 @@ static struct key_entry eeepc_keymap[] = {
180 */ 180 */
181static int eeepc_hotk_add(struct acpi_device *device); 181static int eeepc_hotk_add(struct acpi_device *device);
182static int eeepc_hotk_remove(struct acpi_device *device, int type); 182static int eeepc_hotk_remove(struct acpi_device *device, int type);
183static int eeepc_hotk_resume(struct acpi_device *device);
183 184
184static const struct acpi_device_id eeepc_device_ids[] = { 185static const struct acpi_device_id eeepc_device_ids[] = {
185 {EEEPC_HOTK_HID, 0}, 186 {EEEPC_HOTK_HID, 0},
@@ -194,6 +195,7 @@ static struct acpi_driver eeepc_hotk_driver = {
194 .ops = { 195 .ops = {
195 .add = eeepc_hotk_add, 196 .add = eeepc_hotk_add,
196 .remove = eeepc_hotk_remove, 197 .remove = eeepc_hotk_remove,
198 .resume = eeepc_hotk_resume,
197 }, 199 },
198}; 200};
199 201
@@ -299,39 +301,22 @@ static int update_bl_status(struct backlight_device *bd)
299 * Rfkill helpers 301 * Rfkill helpers
300 */ 302 */
301 303
302static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state) 304static bool eeepc_wlan_rfkill_blocked(void)
303{
304 if (state == RFKILL_STATE_SOFT_BLOCKED)
305 return set_acpi(CM_ASL_WLAN, 0);
306 else
307 return set_acpi(CM_ASL_WLAN, 1);
308}
309
310static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state)
311{ 305{
312 if (get_acpi(CM_ASL_WLAN) == 1) 306 if (get_acpi(CM_ASL_WLAN) == 1)
313 *state = RFKILL_STATE_UNBLOCKED; 307 return false;
314 else 308 return true;
315 *state = RFKILL_STATE_SOFT_BLOCKED;
316 return 0;
317} 309}
318 310
319static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state) 311static int eeepc_rfkill_set(void *data, bool blocked)
320{ 312{
321 if (state == RFKILL_STATE_SOFT_BLOCKED) 313 unsigned long asl = (unsigned long)data;
322 return set_acpi(CM_ASL_BLUETOOTH, 0); 314 return set_acpi(asl, !blocked);
323 else
324 return set_acpi(CM_ASL_BLUETOOTH, 1);
325} 315}
326 316
327static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state) 317static const struct rfkill_ops eeepc_rfkill_ops = {
328{ 318 .set_block = eeepc_rfkill_set,
329 if (get_acpi(CM_ASL_BLUETOOTH) == 1) 319};
330 *state = RFKILL_STATE_UNBLOCKED;
331 else
332 *state = RFKILL_STATE_SOFT_BLOCKED;
333 return 0;
334}
335 320
336/* 321/*
337 * Sys helpers 322 * Sys helpers
@@ -529,23 +514,19 @@ static int notify_brn(void)
529 return -1; 514 return -1;
530} 515}
531 516
532static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) 517static void eeepc_rfkill_hotplug(void)
533{ 518{
534 enum rfkill_state state;
535 struct pci_dev *dev; 519 struct pci_dev *dev;
536 struct pci_bus *bus = pci_find_bus(0, 1); 520 struct pci_bus *bus = pci_find_bus(0, 1);
537 521 bool blocked;
538 if (event != ACPI_NOTIFY_BUS_CHECK)
539 return;
540 522
541 if (!bus) { 523 if (!bus) {
542 printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); 524 printk(EEEPC_WARNING "Unable to find PCI bus 1?\n");
543 return; 525 return;
544 } 526 }
545 527
546 eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state); 528 blocked = eeepc_wlan_rfkill_blocked();
547 529 if (!blocked) {
548 if (state == RFKILL_STATE_UNBLOCKED) {
549 dev = pci_get_slot(bus, 0); 530 dev = pci_get_slot(bus, 0);
550 if (dev) { 531 if (dev) {
551 /* Device already present */ 532 /* Device already present */
@@ -566,7 +547,15 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
566 } 547 }
567 } 548 }
568 549
569 rfkill_force_state(ehotk->eeepc_wlan_rfkill, state); 550 rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked);
551}
552
553static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
554{
555 if (event != ACPI_NOTIFY_BUS_CHECK)
556 return;
557
558 eeepc_rfkill_hotplug();
570} 559}
571 560
572static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) 561static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
@@ -684,26 +673,17 @@ static int eeepc_hotk_add(struct acpi_device *device)
684 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); 673 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
685 674
686 if (get_acpi(CM_ASL_WLAN) != -1) { 675 if (get_acpi(CM_ASL_WLAN) != -1) {
687 ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, 676 ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan",
688 RFKILL_TYPE_WLAN); 677 &device->dev,
678 RFKILL_TYPE_WLAN,
679 &eeepc_rfkill_ops,
680 (void *)CM_ASL_WLAN);
689 681
690 if (!ehotk->eeepc_wlan_rfkill) 682 if (!ehotk->eeepc_wlan_rfkill)
691 goto wlan_fail; 683 goto wlan_fail;
692 684
693 ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; 685 rfkill_init_sw_state(ehotk->eeepc_wlan_rfkill,
694 ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; 686 get_acpi(CM_ASL_WLAN) != 1);
695 ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
696 if (get_acpi(CM_ASL_WLAN) == 1) {
697 ehotk->eeepc_wlan_rfkill->state =
698 RFKILL_STATE_UNBLOCKED;
699 rfkill_set_default(RFKILL_TYPE_WLAN,
700 RFKILL_STATE_UNBLOCKED);
701 } else {
702 ehotk->eeepc_wlan_rfkill->state =
703 RFKILL_STATE_SOFT_BLOCKED;
704 rfkill_set_default(RFKILL_TYPE_WLAN,
705 RFKILL_STATE_SOFT_BLOCKED);
706 }
707 result = rfkill_register(ehotk->eeepc_wlan_rfkill); 687 result = rfkill_register(ehotk->eeepc_wlan_rfkill);
708 if (result) 688 if (result)
709 goto wlan_fail; 689 goto wlan_fail;
@@ -711,28 +691,17 @@ static int eeepc_hotk_add(struct acpi_device *device)
711 691
712 if (get_acpi(CM_ASL_BLUETOOTH) != -1) { 692 if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
713 ehotk->eeepc_bluetooth_rfkill = 693 ehotk->eeepc_bluetooth_rfkill =
714 rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); 694 rfkill_alloc("eeepc-bluetooth",
695 &device->dev,
696 RFKILL_TYPE_BLUETOOTH,
697 &eeepc_rfkill_ops,
698 (void *)CM_ASL_BLUETOOTH);
715 699
716 if (!ehotk->eeepc_bluetooth_rfkill) 700 if (!ehotk->eeepc_bluetooth_rfkill)
717 goto bluetooth_fail; 701 goto bluetooth_fail;
718 702
719 ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; 703 rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill,
720 ehotk->eeepc_bluetooth_rfkill->toggle_radio = 704 get_acpi(CM_ASL_BLUETOOTH) != 1);
721 eeepc_bluetooth_rfkill_set;
722 ehotk->eeepc_bluetooth_rfkill->get_state =
723 eeepc_bluetooth_rfkill_state;
724 if (get_acpi(CM_ASL_BLUETOOTH) == 1) {
725 ehotk->eeepc_bluetooth_rfkill->state =
726 RFKILL_STATE_UNBLOCKED;
727 rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
728 RFKILL_STATE_UNBLOCKED);
729 } else {
730 ehotk->eeepc_bluetooth_rfkill->state =
731 RFKILL_STATE_SOFT_BLOCKED;
732 rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
733 RFKILL_STATE_SOFT_BLOCKED);
734 }
735
736 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); 705 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
737 if (result) 706 if (result)
738 goto bluetooth_fail; 707 goto bluetooth_fail;
@@ -741,13 +710,10 @@ static int eeepc_hotk_add(struct acpi_device *device)
741 return 0; 710 return 0;
742 711
743 bluetooth_fail: 712 bluetooth_fail:
744 if (ehotk->eeepc_bluetooth_rfkill) 713 rfkill_destroy(ehotk->eeepc_bluetooth_rfkill);
745 rfkill_free(ehotk->eeepc_bluetooth_rfkill);
746 rfkill_unregister(ehotk->eeepc_wlan_rfkill); 714 rfkill_unregister(ehotk->eeepc_wlan_rfkill);
747 ehotk->eeepc_wlan_rfkill = NULL;
748 wlan_fail: 715 wlan_fail:
749 if (ehotk->eeepc_wlan_rfkill) 716 rfkill_destroy(ehotk->eeepc_wlan_rfkill);
750 rfkill_free(ehotk->eeepc_wlan_rfkill);
751 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); 717 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
752 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); 718 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
753 ehotk_fail: 719 ehotk_fail:
@@ -775,6 +741,33 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type)
775 return 0; 741 return 0;
776} 742}
777 743
744static int eeepc_hotk_resume(struct acpi_device *device)
745{
746 if (ehotk->eeepc_wlan_rfkill) {
747 bool wlan;
748
749 /* Workaround - it seems that _PTS disables the wireless
750 without notification or changing the value read by WLAN.
751 Normally this is fine because the correct value is restored
752 from the non-volatile storage on resume, but we need to do
753 it ourself if case suspend is aborted, or we lose wireless.
754 */
755 wlan = get_acpi(CM_ASL_WLAN);
756 set_acpi(CM_ASL_WLAN, wlan);
757
758 rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill,
759 wlan != 1);
760
761 eeepc_rfkill_hotplug();
762 }
763
764 if (ehotk->eeepc_bluetooth_rfkill)
765 rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill,
766 get_acpi(CM_ASL_BLUETOOTH) != 1);
767
768 return 0;
769}
770
778/* 771/*
779 * Hwmon 772 * Hwmon
780 */ 773 */
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 50d9019de2b..4ac2311c00a 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -47,7 +47,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
47#define HPWMI_DISPLAY_QUERY 0x1 47#define HPWMI_DISPLAY_QUERY 0x1
48#define HPWMI_HDDTEMP_QUERY 0x2 48#define HPWMI_HDDTEMP_QUERY 0x2
49#define HPWMI_ALS_QUERY 0x3 49#define HPWMI_ALS_QUERY 0x3
50#define HPWMI_DOCK_QUERY 0x4 50#define HPWMI_HARDWARE_QUERY 0x4
51#define HPWMI_WIRELESS_QUERY 0x5 51#define HPWMI_WIRELESS_QUERY 0x5
52#define HPWMI_HOTKEY_QUERY 0xc 52#define HPWMI_HOTKEY_QUERY 0xc
53 53
@@ -75,10 +75,9 @@ struct key_entry {
75 u16 keycode; 75 u16 keycode;
76}; 76};
77 77
78enum { KE_KEY, KE_SW, KE_END }; 78enum { KE_KEY, KE_END };
79 79
80static struct key_entry hp_wmi_keymap[] = { 80static struct key_entry hp_wmi_keymap[] = {
81 {KE_SW, 0x01, SW_DOCK},
82 {KE_KEY, 0x02, KEY_BRIGHTNESSUP}, 81 {KE_KEY, 0x02, KEY_BRIGHTNESSUP},
83 {KE_KEY, 0x03, KEY_BRIGHTNESSDOWN}, 82 {KE_KEY, 0x03, KEY_BRIGHTNESSDOWN},
84 {KE_KEY, 0x20e6, KEY_PROG1}, 83 {KE_KEY, 0x20e6, KEY_PROG1},
@@ -151,61 +150,64 @@ static int hp_wmi_als_state(void)
151 150
152static int hp_wmi_dock_state(void) 151static int hp_wmi_dock_state(void)
153{ 152{
154 return hp_wmi_perform_query(HPWMI_DOCK_QUERY, 0, 0); 153 int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, 0);
155}
156 154
157static int hp_wmi_wifi_set(void *data, enum rfkill_state state) 155 if (ret < 0)
158{ 156 return ret;
159 if (state) 157
160 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x101); 158 return ret & 0x1;
161 else
162 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x100);
163} 159}
164 160
165static int hp_wmi_bluetooth_set(void *data, enum rfkill_state state) 161static int hp_wmi_tablet_state(void)
166{ 162{
167 if (state) 163 int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, 0);
168 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x202); 164
169 else 165 if (ret < 0)
170 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x200); 166 return ret;
167
168 return (ret & 0x4) ? 1 : 0;
171} 169}
172 170
173static int hp_wmi_wwan_set(void *data, enum rfkill_state state) 171static int hp_wmi_set_block(void *data, bool blocked)
174{ 172{
175 if (state) 173 unsigned long b = (unsigned long) data;
176 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x404); 174 int query = BIT(b + 8) | ((!!blocked) << b);
177 else 175
178 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x400); 176 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query);
179} 177}
180 178
181static int hp_wmi_wifi_state(void) 179static const struct rfkill_ops hp_wmi_rfkill_ops = {
180 .set_block = hp_wmi_set_block,
181};
182
183static bool hp_wmi_wifi_state(void)
182{ 184{
183 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 185 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
184 186
185 if (wireless & 0x100) 187 if (wireless & 0x100)
186 return RFKILL_STATE_UNBLOCKED; 188 return false;
187 else 189 else
188 return RFKILL_STATE_SOFT_BLOCKED; 190 return true;
189} 191}
190 192
191static int hp_wmi_bluetooth_state(void) 193static bool hp_wmi_bluetooth_state(void)
192{ 194{
193 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 195 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
194 196
195 if (wireless & 0x10000) 197 if (wireless & 0x10000)
196 return RFKILL_STATE_UNBLOCKED; 198 return false;
197 else 199 else
198 return RFKILL_STATE_SOFT_BLOCKED; 200 return true;
199} 201}
200 202
201static int hp_wmi_wwan_state(void) 203static bool hp_wmi_wwan_state(void)
202{ 204{
203 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 205 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
204 206
205 if (wireless & 0x1000000) 207 if (wireless & 0x1000000)
206 return RFKILL_STATE_UNBLOCKED; 208 return false;
207 else 209 else
208 return RFKILL_STATE_SOFT_BLOCKED; 210 return true;
209} 211}
210 212
211static ssize_t show_display(struct device *dev, struct device_attribute *attr, 213static ssize_t show_display(struct device *dev, struct device_attribute *attr,
@@ -244,6 +246,15 @@ static ssize_t show_dock(struct device *dev, struct device_attribute *attr,
244 return sprintf(buf, "%d\n", value); 246 return sprintf(buf, "%d\n", value);
245} 247}
246 248
249static ssize_t show_tablet(struct device *dev, struct device_attribute *attr,
250 char *buf)
251{
252 int value = hp_wmi_tablet_state();
253 if (value < 0)
254 return -EINVAL;
255 return sprintf(buf, "%d\n", value);
256}
257
247static ssize_t set_als(struct device *dev, struct device_attribute *attr, 258static ssize_t set_als(struct device *dev, struct device_attribute *attr,
248 const char *buf, size_t count) 259 const char *buf, size_t count)
249{ 260{
@@ -256,6 +267,7 @@ static DEVICE_ATTR(display, S_IRUGO, show_display, NULL);
256static DEVICE_ATTR(hddtemp, S_IRUGO, show_hddtemp, NULL); 267static DEVICE_ATTR(hddtemp, S_IRUGO, show_hddtemp, NULL);
257static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als); 268static DEVICE_ATTR(als, S_IRUGO | S_IWUSR, show_als, set_als);
258static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL); 269static DEVICE_ATTR(dock, S_IRUGO, show_dock, NULL);
270static DEVICE_ATTR(tablet, S_IRUGO, show_tablet, NULL);
259 271
260static struct key_entry *hp_wmi_get_entry_by_scancode(int code) 272static struct key_entry *hp_wmi_get_entry_by_scancode(int code)
261{ 273{
@@ -338,23 +350,23 @@ static void hp_wmi_notify(u32 value, void *context)
338 key->keycode, 0); 350 key->keycode, 0);
339 input_sync(hp_wmi_input_dev); 351 input_sync(hp_wmi_input_dev);
340 break; 352 break;
341 case KE_SW:
342 input_report_switch(hp_wmi_input_dev,
343 key->keycode,
344 hp_wmi_dock_state());
345 input_sync(hp_wmi_input_dev);
346 break;
347 } 353 }
354 } else if (eventcode == 0x1) {
355 input_report_switch(hp_wmi_input_dev, SW_DOCK,
356 hp_wmi_dock_state());
357 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
358 hp_wmi_tablet_state());
359 input_sync(hp_wmi_input_dev);
348 } else if (eventcode == 0x5) { 360 } else if (eventcode == 0x5) {
349 if (wifi_rfkill) 361 if (wifi_rfkill)
350 rfkill_force_state(wifi_rfkill, 362 rfkill_set_sw_state(wifi_rfkill,
351 hp_wmi_wifi_state()); 363 hp_wmi_wifi_state());
352 if (bluetooth_rfkill) 364 if (bluetooth_rfkill)
353 rfkill_force_state(bluetooth_rfkill, 365 rfkill_set_sw_state(bluetooth_rfkill,
354 hp_wmi_bluetooth_state()); 366 hp_wmi_bluetooth_state());
355 if (wwan_rfkill) 367 if (wwan_rfkill)
356 rfkill_force_state(wwan_rfkill, 368 rfkill_set_sw_state(wwan_rfkill,
357 hp_wmi_wwan_state()); 369 hp_wmi_wwan_state());
358 } else 370 } else
359 printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", 371 printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n",
360 eventcode); 372 eventcode);
@@ -381,18 +393,19 @@ static int __init hp_wmi_input_setup(void)
381 set_bit(EV_KEY, hp_wmi_input_dev->evbit); 393 set_bit(EV_KEY, hp_wmi_input_dev->evbit);
382 set_bit(key->keycode, hp_wmi_input_dev->keybit); 394 set_bit(key->keycode, hp_wmi_input_dev->keybit);
383 break; 395 break;
384 case KE_SW:
385 set_bit(EV_SW, hp_wmi_input_dev->evbit);
386 set_bit(key->keycode, hp_wmi_input_dev->swbit);
387
388 /* Set initial dock state */
389 input_report_switch(hp_wmi_input_dev, key->keycode,
390 hp_wmi_dock_state());
391 input_sync(hp_wmi_input_dev);
392 break;
393 } 396 }
394 } 397 }
395 398
399 set_bit(EV_SW, hp_wmi_input_dev->evbit);
400 set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
401 set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
402
403 /* Set initial hardware state */
404 input_report_switch(hp_wmi_input_dev, SW_DOCK, hp_wmi_dock_state());
405 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
406 hp_wmi_tablet_state());
407 input_sync(hp_wmi_input_dev);
408
396 err = input_register_device(hp_wmi_input_dev); 409 err = input_register_device(hp_wmi_input_dev);
397 410
398 if (err) { 411 if (err) {
@@ -409,6 +422,7 @@ static void cleanup_sysfs(struct platform_device *device)
409 device_remove_file(&device->dev, &dev_attr_hddtemp); 422 device_remove_file(&device->dev, &dev_attr_hddtemp);
410 device_remove_file(&device->dev, &dev_attr_als); 423 device_remove_file(&device->dev, &dev_attr_als);
411 device_remove_file(&device->dev, &dev_attr_dock); 424 device_remove_file(&device->dev, &dev_attr_dock);
425 device_remove_file(&device->dev, &dev_attr_tablet);
412} 426}
413 427
414static int __init hp_wmi_bios_setup(struct platform_device *device) 428static int __init hp_wmi_bios_setup(struct platform_device *device)
@@ -428,36 +442,35 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
428 err = device_create_file(&device->dev, &dev_attr_dock); 442 err = device_create_file(&device->dev, &dev_attr_dock);
429 if (err) 443 if (err)
430 goto add_sysfs_error; 444 goto add_sysfs_error;
445 err = device_create_file(&device->dev, &dev_attr_tablet);
446 if (err)
447 goto add_sysfs_error;
431 448
432 if (wireless & 0x1) { 449 if (wireless & 0x1) {
433 wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN); 450 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
434 wifi_rfkill->name = "hp-wifi"; 451 RFKILL_TYPE_WLAN,
435 wifi_rfkill->state = hp_wmi_wifi_state(); 452 &hp_wmi_rfkill_ops,
436 wifi_rfkill->toggle_radio = hp_wmi_wifi_set; 453 (void *) 0);
437 wifi_rfkill->user_claim_unsupported = 1;
438 err = rfkill_register(wifi_rfkill); 454 err = rfkill_register(wifi_rfkill);
439 if (err) 455 if (err)
440 goto add_sysfs_error; 456 goto register_wifi_error;
441 } 457 }
442 458
443 if (wireless & 0x2) { 459 if (wireless & 0x2) {
444 bluetooth_rfkill = rfkill_allocate(&device->dev, 460 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
445 RFKILL_TYPE_BLUETOOTH); 461 RFKILL_TYPE_BLUETOOTH,
446 bluetooth_rfkill->name = "hp-bluetooth"; 462 &hp_wmi_rfkill_ops,
447 bluetooth_rfkill->state = hp_wmi_bluetooth_state(); 463 (void *) 1);
448 bluetooth_rfkill->toggle_radio = hp_wmi_bluetooth_set;
449 bluetooth_rfkill->user_claim_unsupported = 1;
450 err = rfkill_register(bluetooth_rfkill); 464 err = rfkill_register(bluetooth_rfkill);
451 if (err) 465 if (err)
452 goto register_bluetooth_error; 466 goto register_bluetooth_error;
453 } 467 }
454 468
455 if (wireless & 0x4) { 469 if (wireless & 0x4) {
456 wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN); 470 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
457 wwan_rfkill->name = "hp-wwan"; 471 RFKILL_TYPE_WWAN,
458 wwan_rfkill->state = hp_wmi_wwan_state(); 472 &hp_wmi_rfkill_ops,
459 wwan_rfkill->toggle_radio = hp_wmi_wwan_set; 473 (void *) 2);
460 wwan_rfkill->user_claim_unsupported = 1;
461 err = rfkill_register(wwan_rfkill); 474 err = rfkill_register(wwan_rfkill);
462 if (err) 475 if (err)
463 goto register_wwan_err; 476 goto register_wwan_err;
@@ -465,11 +478,15 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
465 478
466 return 0; 479 return 0;
467register_wwan_err: 480register_wwan_err:
481 rfkill_destroy(wwan_rfkill);
468 if (bluetooth_rfkill) 482 if (bluetooth_rfkill)
469 rfkill_unregister(bluetooth_rfkill); 483 rfkill_unregister(bluetooth_rfkill);
470register_bluetooth_error: 484register_bluetooth_error:
485 rfkill_destroy(bluetooth_rfkill);
471 if (wifi_rfkill) 486 if (wifi_rfkill)
472 rfkill_unregister(wifi_rfkill); 487 rfkill_unregister(wifi_rfkill);
488register_wifi_error:
489 rfkill_destroy(wifi_rfkill);
473add_sysfs_error: 490add_sysfs_error:
474 cleanup_sysfs(device); 491 cleanup_sysfs(device);
475 return err; 492 return err;
@@ -479,35 +496,35 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
479{ 496{
480 cleanup_sysfs(device); 497 cleanup_sysfs(device);
481 498
482 if (wifi_rfkill) 499 if (wifi_rfkill) {
483 rfkill_unregister(wifi_rfkill); 500 rfkill_unregister(wifi_rfkill);
484 if (bluetooth_rfkill) 501 rfkill_destroy(wifi_rfkill);
502 }
503 if (bluetooth_rfkill) {
485 rfkill_unregister(bluetooth_rfkill); 504 rfkill_unregister(bluetooth_rfkill);
486 if (wwan_rfkill) 505 rfkill_destroy(wifi_rfkill);
506 }
507 if (wwan_rfkill) {
487 rfkill_unregister(wwan_rfkill); 508 rfkill_unregister(wwan_rfkill);
509 rfkill_destroy(wwan_rfkill);
510 }
488 511
489 return 0; 512 return 0;
490} 513}
491 514
492static int hp_wmi_resume_handler(struct platform_device *device) 515static int hp_wmi_resume_handler(struct platform_device *device)
493{ 516{
494 struct key_entry *key;
495
496 /* 517 /*
497 * Docking state may have changed while suspended, so trigger 518 * Hardware state may have changed while suspended, so trigger
498 * an input event for the current state. As this is a switch, 519 * input events for the current state. As this is a switch,
499 * the input layer will only actually pass it on if the state 520 * the input layer will only actually pass it on if the state
500 * changed. 521 * changed.
501 */ 522 */
502 for (key = hp_wmi_keymap; key->type != KE_END; key++) { 523
503 switch (key->type) { 524 input_report_switch(hp_wmi_input_dev, SW_DOCK, hp_wmi_dock_state());
504 case KE_SW: 525 input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
505 input_report_switch(hp_wmi_input_dev, key->keycode, 526 hp_wmi_tablet_state());
506 hp_wmi_dock_state()); 527 input_sync(hp_wmi_input_dev);
507 input_sync(hp_wmi_input_dev);
508 break;
509 }
510 }
511 528
512 return 0; 529 return 0;
513} 530}
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 552958545f9..dafaa4a92df 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -128,11 +128,11 @@ enum sony_nc_rfkill {
128 SONY_BLUETOOTH, 128 SONY_BLUETOOTH,
129 SONY_WWAN, 129 SONY_WWAN,
130 SONY_WIMAX, 130 SONY_WIMAX,
131 SONY_RFKILL_MAX, 131 N_SONY_RFKILL,
132}; 132};
133 133
134static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX]; 134static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL];
135static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900}; 135static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900};
136static void sony_nc_rfkill_update(void); 136static void sony_nc_rfkill_update(void);
137 137
138/*********** Input Devices ***********/ 138/*********** Input Devices ***********/
@@ -1051,151 +1051,97 @@ static void sony_nc_rfkill_cleanup(void)
1051{ 1051{
1052 int i; 1052 int i;
1053 1053
1054 for (i = 0; i < SONY_RFKILL_MAX; i++) { 1054 for (i = 0; i < N_SONY_RFKILL; i++) {
1055 if (sony_rfkill_devices[i]) 1055 if (sony_rfkill_devices[i]) {
1056 rfkill_unregister(sony_rfkill_devices[i]); 1056 rfkill_unregister(sony_rfkill_devices[i]);
1057 rfkill_destroy(sony_rfkill_devices[i]);
1058 }
1057 } 1059 }
1058} 1060}
1059 1061
1060static int sony_nc_rfkill_get(void *data, enum rfkill_state *state) 1062static int sony_nc_rfkill_set(void *data, bool blocked)
1061{
1062 int result;
1063 int argument = sony_rfkill_address[(long) data];
1064
1065 sony_call_snc_handle(0x124, 0x200, &result);
1066 if (result & 0x1) {
1067 sony_call_snc_handle(0x124, argument, &result);
1068 if (result & 0xf)
1069 *state = RFKILL_STATE_UNBLOCKED;
1070 else
1071 *state = RFKILL_STATE_SOFT_BLOCKED;
1072 } else {
1073 *state = RFKILL_STATE_HARD_BLOCKED;
1074 }
1075
1076 return 0;
1077}
1078
1079static int sony_nc_rfkill_set(void *data, enum rfkill_state state)
1080{ 1063{
1081 int result; 1064 int result;
1082 int argument = sony_rfkill_address[(long) data] + 0x100; 1065 int argument = sony_rfkill_address[(long) data] + 0x100;
1083 1066
1084 if (state == RFKILL_STATE_UNBLOCKED) 1067 if (!blocked)
1085 argument |= 0xff0000; 1068 argument |= 0xff0000;
1086 1069
1087 return sony_call_snc_handle(0x124, argument, &result); 1070 return sony_call_snc_handle(0x124, argument, &result);
1088} 1071}
1089 1072
1090static int sony_nc_setup_wifi_rfkill(struct acpi_device *device) 1073static const struct rfkill_ops sony_rfkill_ops = {
1091{ 1074 .set_block = sony_nc_rfkill_set,
1092 int err = 0; 1075};
1093 struct rfkill *sony_wifi_rfkill;
1094
1095 sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
1096 if (!sony_wifi_rfkill)
1097 return -1;
1098 sony_wifi_rfkill->name = "sony-wifi";
1099 sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set;
1100 sony_wifi_rfkill->get_state = sony_nc_rfkill_get;
1101 sony_wifi_rfkill->user_claim_unsupported = 1;
1102 sony_wifi_rfkill->data = (void *)SONY_WIFI;
1103 err = rfkill_register(sony_wifi_rfkill);
1104 if (err)
1105 rfkill_free(sony_wifi_rfkill);
1106 else {
1107 sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
1108 sony_nc_rfkill_set(sony_wifi_rfkill->data,
1109 RFKILL_STATE_UNBLOCKED);
1110 }
1111 return err;
1112}
1113 1076
1114static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device) 1077static int sony_nc_setup_rfkill(struct acpi_device *device,
1078 enum sony_nc_rfkill nc_type)
1115{ 1079{
1116 int err = 0; 1080 int err = 0;
1117 struct rfkill *sony_bluetooth_rfkill; 1081 struct rfkill *rfk;
1118 1082 enum rfkill_type type;
1119 sony_bluetooth_rfkill = rfkill_allocate(&device->dev, 1083 const char *name;
1120 RFKILL_TYPE_BLUETOOTH); 1084
1121 if (!sony_bluetooth_rfkill) 1085 switch (nc_type) {
1122 return -1; 1086 case SONY_WIFI:
1123 sony_bluetooth_rfkill->name = "sony-bluetooth"; 1087 type = RFKILL_TYPE_WLAN;
1124 sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set; 1088 name = "sony-wifi";
1125 sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get; 1089 break;
1126 sony_bluetooth_rfkill->user_claim_unsupported = 1; 1090 case SONY_BLUETOOTH:
1127 sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH; 1091 type = RFKILL_TYPE_BLUETOOTH;
1128 err = rfkill_register(sony_bluetooth_rfkill); 1092 name = "sony-bluetooth";
1129 if (err) 1093 break;
1130 rfkill_free(sony_bluetooth_rfkill); 1094 case SONY_WWAN:
1131 else { 1095 type = RFKILL_TYPE_WWAN;
1132 sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill; 1096 name = "sony-wwan";
1133 sony_nc_rfkill_set(sony_bluetooth_rfkill->data, 1097 break;
1134 RFKILL_STATE_UNBLOCKED); 1098 case SONY_WIMAX:
1099 type = RFKILL_TYPE_WIMAX;
1100 name = "sony-wimax";
1101 break;
1102 default:
1103 return -EINVAL;
1135 } 1104 }
1136 return err;
1137}
1138 1105
1139static int sony_nc_setup_wwan_rfkill(struct acpi_device *device) 1106 rfk = rfkill_alloc(name, &device->dev, type,
1140{ 1107 &sony_rfkill_ops, (void *)nc_type);
1141 int err = 0; 1108 if (!rfk)
1142 struct rfkill *sony_wwan_rfkill; 1109 return -ENOMEM;
1143 1110
1144 sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN); 1111 err = rfkill_register(rfk);
1145 if (!sony_wwan_rfkill) 1112 if (err) {
1146 return -1; 1113 rfkill_destroy(rfk);
1147 sony_wwan_rfkill->name = "sony-wwan"; 1114 return err;
1148 sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set;
1149 sony_wwan_rfkill->get_state = sony_nc_rfkill_get;
1150 sony_wwan_rfkill->user_claim_unsupported = 1;
1151 sony_wwan_rfkill->data = (void *)SONY_WWAN;
1152 err = rfkill_register(sony_wwan_rfkill);
1153 if (err)
1154 rfkill_free(sony_wwan_rfkill);
1155 else {
1156 sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
1157 sony_nc_rfkill_set(sony_wwan_rfkill->data,
1158 RFKILL_STATE_UNBLOCKED);
1159 } 1115 }
1116 sony_rfkill_devices[nc_type] = rfk;
1160 return err; 1117 return err;
1161} 1118}
1162 1119
1163static int sony_nc_setup_wimax_rfkill(struct acpi_device *device) 1120static void sony_nc_rfkill_update()
1164{ 1121{
1165 int err = 0; 1122 enum sony_nc_rfkill i;
1166 struct rfkill *sony_wimax_rfkill; 1123 int result;
1124 bool hwblock;
1167 1125
1168 sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX); 1126 sony_call_snc_handle(0x124, 0x200, &result);
1169 if (!sony_wimax_rfkill) 1127 hwblock = !(result & 0x1);
1170 return -1;
1171 sony_wimax_rfkill->name = "sony-wimax";
1172 sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set;
1173 sony_wimax_rfkill->get_state = sony_nc_rfkill_get;
1174 sony_wimax_rfkill->user_claim_unsupported = 1;
1175 sony_wimax_rfkill->data = (void *)SONY_WIMAX;
1176 err = rfkill_register(sony_wimax_rfkill);
1177 if (err)
1178 rfkill_free(sony_wimax_rfkill);
1179 else {
1180 sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
1181 sony_nc_rfkill_set(sony_wimax_rfkill->data,
1182 RFKILL_STATE_UNBLOCKED);
1183 }
1184 return err;
1185}
1186 1128
1187static void sony_nc_rfkill_update() 1129 for (i = 0; i < N_SONY_RFKILL; i++) {
1188{ 1130 int argument = sony_rfkill_address[i];
1189 int i;
1190 enum rfkill_state state;
1191 1131
1192 for (i = 0; i < SONY_RFKILL_MAX; i++) { 1132 if (!sony_rfkill_devices[i])
1193 if (sony_rfkill_devices[i]) { 1133 continue;
1194 sony_rfkill_devices[i]-> 1134
1195 get_state(sony_rfkill_devices[i]->data, 1135 if (hwblock) {
1196 &state); 1136 if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) {
1197 rfkill_force_state(sony_rfkill_devices[i], state); 1137 /* we already know we're blocked */
1138 }
1139 continue;
1198 } 1140 }
1141
1142 sony_call_snc_handle(0x124, argument, &result);
1143 rfkill_set_states(sony_rfkill_devices[i],
1144 !(result & 0xf), false);
1199 } 1145 }
1200} 1146}
1201 1147
@@ -1214,13 +1160,13 @@ static int sony_nc_rfkill_setup(struct acpi_device *device)
1214 } 1160 }
1215 1161
1216 if (result & 0x1) 1162 if (result & 0x1)
1217 sony_nc_setup_wifi_rfkill(device); 1163 sony_nc_setup_rfkill(device, SONY_WIFI);
1218 if (result & 0x2) 1164 if (result & 0x2)
1219 sony_nc_setup_bluetooth_rfkill(device); 1165 sony_nc_setup_rfkill(device, SONY_BLUETOOTH);
1220 if (result & 0x1c) 1166 if (result & 0x1c)
1221 sony_nc_setup_wwan_rfkill(device); 1167 sony_nc_setup_rfkill(device, SONY_WWAN);
1222 if (result & 0x20) 1168 if (result & 0x20)
1223 sony_nc_setup_wimax_rfkill(device); 1169 sony_nc_setup_rfkill(device, SONY_WIMAX);
1224 1170
1225 return 0; 1171 return 0;
1226} 1172}
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 912be65b626..a463fd72c49 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -22,7 +22,7 @@
22 */ 22 */
23 23
24#define TPACPI_VERSION "0.23" 24#define TPACPI_VERSION "0.23"
25#define TPACPI_SYSFS_VERSION 0x020300 25#define TPACPI_SYSFS_VERSION 0x020400
26 26
27/* 27/*
28 * Changelog: 28 * Changelog:
@@ -166,13 +166,6 @@ enum {
166 166
167#define TPACPI_MAX_ACPI_ARGS 3 167#define TPACPI_MAX_ACPI_ARGS 3
168 168
169/* rfkill switches */
170enum {
171 TPACPI_RFK_BLUETOOTH_SW_ID = 0,
172 TPACPI_RFK_WWAN_SW_ID,
173 TPACPI_RFK_UWB_SW_ID,
174};
175
176/* printk headers */ 169/* printk headers */
177#define TPACPI_LOG TPACPI_FILE ": " 170#define TPACPI_LOG TPACPI_FILE ": "
178#define TPACPI_EMERG KERN_EMERG TPACPI_LOG 171#define TPACPI_EMERG KERN_EMERG TPACPI_LOG
@@ -264,6 +257,8 @@ static struct {
264 u32 wan:1; 257 u32 wan:1;
265 u32 uwb:1; 258 u32 uwb:1;
266 u32 fan_ctrl_status_undef:1; 259 u32 fan_ctrl_status_undef:1;
260 u32 second_fan:1;
261 u32 beep_needs_two_args:1;
267 u32 input_device_registered:1; 262 u32 input_device_registered:1;
268 u32 platform_drv_registered:1; 263 u32 platform_drv_registered:1;
269 u32 platform_drv_attrs_registered:1; 264 u32 platform_drv_attrs_registered:1;
@@ -284,8 +279,10 @@ struct thinkpad_id_data {
284 char *bios_version_str; /* Something like 1ZET51WW (1.03z) */ 279 char *bios_version_str; /* Something like 1ZET51WW (1.03z) */
285 char *ec_version_str; /* Something like 1ZHT51WW-1.04a */ 280 char *ec_version_str; /* Something like 1ZHT51WW-1.04a */
286 281
287 u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */ 282 u16 bios_model; /* 1Y = 0x5931, 0 = unknown */
288 u16 ec_model; 283 u16 ec_model;
284 u16 bios_release; /* 1ZETK1WW = 0x314b, 0 = unknown */
285 u16 ec_release;
289 286
290 char *model_str; /* ThinkPad T43 */ 287 char *model_str; /* ThinkPad T43 */
291 char *nummodel_str; /* 9384A9C for a 9384-A9C model */ 288 char *nummodel_str; /* 9384A9C for a 9384-A9C model */
@@ -362,6 +359,73 @@ static void tpacpi_log_usertask(const char * const what)
362 } \ 359 } \
363 } while (0) 360 } while (0)
364 361
362/*
363 * Quirk handling helpers
364 *
365 * ThinkPad IDs and versions seen in the field so far
366 * are two-characters from the set [0-9A-Z], i.e. base 36.
367 *
368 * We use values well outside that range as specials.
369 */
370
371#define TPACPI_MATCH_ANY 0xffffU
372#define TPACPI_MATCH_UNKNOWN 0U
373
374/* TPID('1', 'Y') == 0x5931 */
375#define TPID(__c1, __c2) (((__c2) << 8) | (__c1))
376
377#define TPACPI_Q_IBM(__id1, __id2, __quirk) \
378 { .vendor = PCI_VENDOR_ID_IBM, \
379 .bios = TPID(__id1, __id2), \
380 .ec = TPACPI_MATCH_ANY, \
381 .quirks = (__quirk) }
382
383#define TPACPI_Q_LNV(__id1, __id2, __quirk) \
384 { .vendor = PCI_VENDOR_ID_LENOVO, \
385 .bios = TPID(__id1, __id2), \
386 .ec = TPACPI_MATCH_ANY, \
387 .quirks = (__quirk) }
388
389struct tpacpi_quirk {
390 unsigned int vendor;
391 u16 bios;
392 u16 ec;
393 unsigned long quirks;
394};
395
396/**
397 * tpacpi_check_quirks() - search BIOS/EC version on a list
398 * @qlist: array of &struct tpacpi_quirk
399 * @qlist_size: number of elements in @qlist
400 *
401 * Iterates over a quirks list until one is found that matches the
402 * ThinkPad's vendor, BIOS and EC model.
403 *
404 * Returns 0 if nothing matches, otherwise returns the quirks field of
405 * the matching &struct tpacpi_quirk entry.
406 *
407 * The match criteria is: vendor, ec and bios much match.
408 */
409static unsigned long __init tpacpi_check_quirks(
410 const struct tpacpi_quirk *qlist,
411 unsigned int qlist_size)
412{
413 while (qlist_size) {
414 if ((qlist->vendor == thinkpad_id.vendor ||
415 qlist->vendor == TPACPI_MATCH_ANY) &&
416 (qlist->bios == thinkpad_id.bios_model ||
417 qlist->bios == TPACPI_MATCH_ANY) &&
418 (qlist->ec == thinkpad_id.ec_model ||
419 qlist->ec == TPACPI_MATCH_ANY))
420 return qlist->quirks;
421
422 qlist_size--;
423 qlist++;
424 }
425 return 0;
426}
427
428
365/**************************************************************************** 429/****************************************************************************
366 **************************************************************************** 430 ****************************************************************************
367 * 431 *
@@ -1005,67 +1069,234 @@ static int __init tpacpi_check_std_acpi_brightness_support(void)
1005 return 0; 1069 return 0;
1006} 1070}
1007 1071
1008static int __init tpacpi_new_rfkill(const unsigned int id, 1072static void printk_deprecated_attribute(const char * const what,
1009 struct rfkill **rfk, 1073 const char * const details)
1074{
1075 tpacpi_log_usertask("deprecated sysfs attribute");
1076 printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
1077 "will be removed. %s\n",
1078 what, details);
1079}
1080
1081/*************************************************************************
1082 * rfkill and radio control support helpers
1083 */
1084
1085/*
1086 * ThinkPad-ACPI firmware handling model:
1087 *
1088 * WLSW (master wireless switch) is event-driven, and is common to all
1089 * firmware-controlled radios. It cannot be controlled, just monitored,
1090 * as expected. It overrides all radio state in firmware
1091 *
1092 * The kernel, a masked-off hotkey, and WLSW can change the radio state
1093 * (TODO: verify how WLSW interacts with the returned radio state).
1094 *
1095 * The only time there are shadow radio state changes, is when
1096 * masked-off hotkeys are used.
1097 */
1098
1099/*
1100 * Internal driver API for radio state:
1101 *
1102 * int: < 0 = error, otherwise enum tpacpi_rfkill_state
1103 * bool: true means radio blocked (off)
1104 */
1105enum tpacpi_rfkill_state {
1106 TPACPI_RFK_RADIO_OFF = 0,
1107 TPACPI_RFK_RADIO_ON
1108};
1109
1110/* rfkill switches */
1111enum tpacpi_rfk_id {
1112 TPACPI_RFK_BLUETOOTH_SW_ID = 0,
1113 TPACPI_RFK_WWAN_SW_ID,
1114 TPACPI_RFK_UWB_SW_ID,
1115 TPACPI_RFK_SW_MAX
1116};
1117
1118static const char *tpacpi_rfkill_names[] = {
1119 [TPACPI_RFK_BLUETOOTH_SW_ID] = "bluetooth",
1120 [TPACPI_RFK_WWAN_SW_ID] = "wwan",
1121 [TPACPI_RFK_UWB_SW_ID] = "uwb",
1122 [TPACPI_RFK_SW_MAX] = NULL
1123};
1124
1125/* ThinkPad-ACPI rfkill subdriver */
1126struct tpacpi_rfk {
1127 struct rfkill *rfkill;
1128 enum tpacpi_rfk_id id;
1129 const struct tpacpi_rfk_ops *ops;
1130};
1131
1132struct tpacpi_rfk_ops {
1133 /* firmware interface */
1134 int (*get_status)(void);
1135 int (*set_status)(const enum tpacpi_rfkill_state);
1136};
1137
1138static struct tpacpi_rfk *tpacpi_rfkill_switches[TPACPI_RFK_SW_MAX];
1139
1140/* Query FW and update rfkill sw state for a given rfkill switch */
1141static int tpacpi_rfk_update_swstate(const struct tpacpi_rfk *tp_rfk)
1142{
1143 int status;
1144
1145 if (!tp_rfk)
1146 return -ENODEV;
1147
1148 status = (tp_rfk->ops->get_status)();
1149 if (status < 0)
1150 return status;
1151
1152 rfkill_set_sw_state(tp_rfk->rfkill,
1153 (status == TPACPI_RFK_RADIO_OFF));
1154
1155 return status;
1156}
1157
1158/* Query FW and update rfkill sw state for all rfkill switches */
1159static void tpacpi_rfk_update_swstate_all(void)
1160{
1161 unsigned int i;
1162
1163 for (i = 0; i < TPACPI_RFK_SW_MAX; i++)
1164 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[i]);
1165}
1166
1167/*
1168 * Sync the HW-blocking state of all rfkill switches,
1169 * do notice it causes the rfkill core to schedule uevents
1170 */
1171static void tpacpi_rfk_update_hwblock_state(bool blocked)
1172{
1173 unsigned int i;
1174 struct tpacpi_rfk *tp_rfk;
1175
1176 for (i = 0; i < TPACPI_RFK_SW_MAX; i++) {
1177 tp_rfk = tpacpi_rfkill_switches[i];
1178 if (tp_rfk) {
1179 if (rfkill_set_hw_state(tp_rfk->rfkill,
1180 blocked)) {
1181 /* ignore -- we track sw block */
1182 }
1183 }
1184 }
1185}
1186
1187/* Call to get the WLSW state from the firmware */
1188static int hotkey_get_wlsw(void);
1189
1190/* Call to query WLSW state and update all rfkill switches */
1191static bool tpacpi_rfk_check_hwblock_state(void)
1192{
1193 int res = hotkey_get_wlsw();
1194 int hw_blocked;
1195
1196 /* When unknown or unsupported, we have to assume it is unblocked */
1197 if (res < 0)
1198 return false;
1199
1200 hw_blocked = (res == TPACPI_RFK_RADIO_OFF);
1201 tpacpi_rfk_update_hwblock_state(hw_blocked);
1202
1203 return hw_blocked;
1204}
1205
1206static int tpacpi_rfk_hook_set_block(void *data, bool blocked)
1207{
1208 struct tpacpi_rfk *tp_rfk = data;
1209 int res;
1210
1211 dbg_printk(TPACPI_DBG_RFKILL,
1212 "request to change radio state to %s\n",
1213 blocked ? "blocked" : "unblocked");
1214
1215 /* try to set radio state */
1216 res = (tp_rfk->ops->set_status)(blocked ?
1217 TPACPI_RFK_RADIO_OFF : TPACPI_RFK_RADIO_ON);
1218
1219 /* and update the rfkill core with whatever the FW really did */
1220 tpacpi_rfk_update_swstate(tp_rfk);
1221
1222 return (res < 0) ? res : 0;
1223}
1224
1225static const struct rfkill_ops tpacpi_rfk_rfkill_ops = {
1226 .set_block = tpacpi_rfk_hook_set_block,
1227};
1228
1229static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
1230 const struct tpacpi_rfk_ops *tp_rfkops,
1010 const enum rfkill_type rfktype, 1231 const enum rfkill_type rfktype,
1011 const char *name, 1232 const char *name,
1012 const bool set_default, 1233 const bool set_default)
1013 int (*toggle_radio)(void *, enum rfkill_state),
1014 int (*get_state)(void *, enum rfkill_state *))
1015{ 1234{
1235 struct tpacpi_rfk *atp_rfk;
1016 int res; 1236 int res;
1017 enum rfkill_state initial_state = RFKILL_STATE_SOFT_BLOCKED; 1237 bool sw_state = false;
1018 1238 int sw_status;
1019 res = get_state(NULL, &initial_state); 1239
1020 if (res < 0) { 1240 BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
1021 printk(TPACPI_ERR 1241
1022 "failed to read initial state for %s, error %d; " 1242 atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL);
1023 "will turn radio off\n", name, res); 1243 if (atp_rfk)
1024 } else if (set_default) { 1244 atp_rfk->rfkill = rfkill_alloc(name,
1025 /* try to set the initial state as the default for the rfkill 1245 &tpacpi_pdev->dev,
1026 * type, since we ask the firmware to preserve it across S5 in 1246 rfktype,
1027 * NVRAM */ 1247 &tpacpi_rfk_rfkill_ops,
1028 if (rfkill_set_default(rfktype, 1248 atp_rfk);
1029 (initial_state == RFKILL_STATE_UNBLOCKED) ? 1249 if (!atp_rfk || !atp_rfk->rfkill) {
1030 RFKILL_STATE_UNBLOCKED :
1031 RFKILL_STATE_SOFT_BLOCKED) == -EPERM)
1032 vdbg_printk(TPACPI_DBG_RFKILL,
1033 "Default state for %s cannot be changed\n",
1034 name);
1035 }
1036
1037 *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
1038 if (!*rfk) {
1039 printk(TPACPI_ERR 1250 printk(TPACPI_ERR
1040 "failed to allocate memory for rfkill class\n"); 1251 "failed to allocate memory for rfkill class\n");
1252 kfree(atp_rfk);
1041 return -ENOMEM; 1253 return -ENOMEM;
1042 } 1254 }
1043 1255
1044 (*rfk)->name = name; 1256 atp_rfk->id = id;
1045 (*rfk)->get_state = get_state; 1257 atp_rfk->ops = tp_rfkops;
1046 (*rfk)->toggle_radio = toggle_radio; 1258
1047 (*rfk)->state = initial_state; 1259 sw_status = (tp_rfkops->get_status)();
1260 if (sw_status < 0) {
1261 printk(TPACPI_ERR
1262 "failed to read initial state for %s, error %d\n",
1263 name, sw_status);
1264 } else {
1265 sw_state = (sw_status == TPACPI_RFK_RADIO_OFF);
1266 if (set_default) {
1267 /* try to keep the initial state, since we ask the
1268 * firmware to preserve it across S5 in NVRAM */
1269 rfkill_init_sw_state(atp_rfk->rfkill, sw_state);
1270 }
1271 }
1272 rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state());
1048 1273
1049 res = rfkill_register(*rfk); 1274 res = rfkill_register(atp_rfk->rfkill);
1050 if (res < 0) { 1275 if (res < 0) {
1051 printk(TPACPI_ERR 1276 printk(TPACPI_ERR
1052 "failed to register %s rfkill switch: %d\n", 1277 "failed to register %s rfkill switch: %d\n",
1053 name, res); 1278 name, res);
1054 rfkill_free(*rfk); 1279 rfkill_destroy(atp_rfk->rfkill);
1055 *rfk = NULL; 1280 kfree(atp_rfk);
1056 return res; 1281 return res;
1057 } 1282 }
1058 1283
1284 tpacpi_rfkill_switches[id] = atp_rfk;
1059 return 0; 1285 return 0;
1060} 1286}
1061 1287
1062static void printk_deprecated_attribute(const char * const what, 1288static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id)
1063 const char * const details)
1064{ 1289{
1065 tpacpi_log_usertask("deprecated sysfs attribute"); 1290 struct tpacpi_rfk *tp_rfk;
1066 printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " 1291
1067 "will be removed. %s\n", 1292 BUG_ON(id >= TPACPI_RFK_SW_MAX);
1068 what, details); 1293
1294 tp_rfk = tpacpi_rfkill_switches[id];
1295 if (tp_rfk) {
1296 rfkill_unregister(tp_rfk->rfkill);
1297 tpacpi_rfkill_switches[id] = NULL;
1298 kfree(tp_rfk);
1299 }
1069} 1300}
1070 1301
1071static void printk_deprecated_rfkill_attribute(const char * const what) 1302static void printk_deprecated_rfkill_attribute(const char * const what)
@@ -1074,6 +1305,112 @@ static void printk_deprecated_rfkill_attribute(const char * const what)
1074 "Please switch to generic rfkill before year 2010"); 1305 "Please switch to generic rfkill before year 2010");
1075} 1306}
1076 1307
1308/* sysfs <radio> enable ------------------------------------------------ */
1309static ssize_t tpacpi_rfk_sysfs_enable_show(const enum tpacpi_rfk_id id,
1310 struct device_attribute *attr,
1311 char *buf)
1312{
1313 int status;
1314
1315 printk_deprecated_rfkill_attribute(attr->attr.name);
1316
1317 /* This is in the ABI... */
1318 if (tpacpi_rfk_check_hwblock_state()) {
1319 status = TPACPI_RFK_RADIO_OFF;
1320 } else {
1321 status = tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1322 if (status < 0)
1323 return status;
1324 }
1325
1326 return snprintf(buf, PAGE_SIZE, "%d\n",
1327 (status == TPACPI_RFK_RADIO_ON) ? 1 : 0);
1328}
1329
1330static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id,
1331 struct device_attribute *attr,
1332 const char *buf, size_t count)
1333{
1334 unsigned long t;
1335 int res;
1336
1337 printk_deprecated_rfkill_attribute(attr->attr.name);
1338
1339 if (parse_strtoul(buf, 1, &t))
1340 return -EINVAL;
1341
1342 tpacpi_disclose_usertask(attr->attr.name, "set to %ld\n", t);
1343
1344 /* This is in the ABI... */
1345 if (tpacpi_rfk_check_hwblock_state() && !!t)
1346 return -EPERM;
1347
1348 res = tpacpi_rfkill_switches[id]->ops->set_status((!!t) ?
1349 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF);
1350 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1351
1352 return (res < 0) ? res : count;
1353}
1354
1355/* procfs -------------------------------------------------------------- */
1356static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p)
1357{
1358 int len = 0;
1359
1360 if (id >= TPACPI_RFK_SW_MAX)
1361 len += sprintf(p + len, "status:\t\tnot supported\n");
1362 else {
1363 int status;
1364
1365 /* This is in the ABI... */
1366 if (tpacpi_rfk_check_hwblock_state()) {
1367 status = TPACPI_RFK_RADIO_OFF;
1368 } else {
1369 status = tpacpi_rfk_update_swstate(
1370 tpacpi_rfkill_switches[id]);
1371 if (status < 0)
1372 return status;
1373 }
1374
1375 len += sprintf(p + len, "status:\t\t%s\n",
1376 (status == TPACPI_RFK_RADIO_ON) ?
1377 "enabled" : "disabled");
1378 len += sprintf(p + len, "commands:\tenable, disable\n");
1379 }
1380
1381 return len;
1382}
1383
1384static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)
1385{
1386 char *cmd;
1387 int status = -1;
1388 int res = 0;
1389
1390 if (id >= TPACPI_RFK_SW_MAX)
1391 return -ENODEV;
1392
1393 while ((cmd = next_cmd(&buf))) {
1394 if (strlencmp(cmd, "enable") == 0)
1395 status = TPACPI_RFK_RADIO_ON;
1396 else if (strlencmp(cmd, "disable") == 0)
1397 status = TPACPI_RFK_RADIO_OFF;
1398 else
1399 return -EINVAL;
1400 }
1401
1402 if (status != -1) {
1403 tpacpi_disclose_usertask("procfs", "attempt to %s %s\n",
1404 (status == TPACPI_RFK_RADIO_ON) ?
1405 "enable" : "disable",
1406 tpacpi_rfkill_names[id]);
1407 res = (tpacpi_rfkill_switches[id]->ops->set_status)(status);
1408 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1409 }
1410
1411 return res;
1412}
1413
1077/************************************************************************* 1414/*************************************************************************
1078 * thinkpad-acpi driver attributes 1415 * thinkpad-acpi driver attributes
1079 */ 1416 */
@@ -1127,8 +1464,6 @@ static DRIVER_ATTR(version, S_IRUGO,
1127 1464
1128#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1465#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1129 1466
1130static void tpacpi_send_radiosw_update(void);
1131
1132/* wlsw_emulstate ------------------------------------------------------ */ 1467/* wlsw_emulstate ------------------------------------------------------ */
1133static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv, 1468static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv,
1134 char *buf) 1469 char *buf)
@@ -1144,11 +1479,10 @@ static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv,
1144 if (parse_strtoul(buf, 1, &t)) 1479 if (parse_strtoul(buf, 1, &t))
1145 return -EINVAL; 1480 return -EINVAL;
1146 1481
1147 if (tpacpi_wlsw_emulstate != t) { 1482 if (tpacpi_wlsw_emulstate != !!t) {
1148 tpacpi_wlsw_emulstate = !!t;
1149 tpacpi_send_radiosw_update();
1150 } else
1151 tpacpi_wlsw_emulstate = !!t; 1483 tpacpi_wlsw_emulstate = !!t;
1484 tpacpi_rfk_update_hwblock_state(!t); /* negative logic */
1485 }
1152 1486
1153 return count; 1487 return count;
1154} 1488}
@@ -1463,17 +1797,23 @@ static struct attribute_set *hotkey_dev_attributes;
1463/* HKEY.MHKG() return bits */ 1797/* HKEY.MHKG() return bits */
1464#define TP_HOTKEY_TABLET_MASK (1 << 3) 1798#define TP_HOTKEY_TABLET_MASK (1 << 3)
1465 1799
1466static int hotkey_get_wlsw(int *status) 1800static int hotkey_get_wlsw(void)
1467{ 1801{
1802 int status;
1803
1804 if (!tp_features.hotkey_wlsw)
1805 return -ENODEV;
1806
1468#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1807#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1469 if (dbg_wlswemul) { 1808 if (dbg_wlswemul)
1470 *status = !!tpacpi_wlsw_emulstate; 1809 return (tpacpi_wlsw_emulstate) ?
1471 return 0; 1810 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
1472 }
1473#endif 1811#endif
1474 if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) 1812
1813 if (!acpi_evalf(hkey_handle, &status, "WLSW", "d"))
1475 return -EIO; 1814 return -EIO;
1476 return 0; 1815
1816 return (status) ? TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
1477} 1817}
1478 1818
1479static int hotkey_get_tablet_mode(int *status) 1819static int hotkey_get_tablet_mode(int *status)
@@ -2107,12 +2447,16 @@ static ssize_t hotkey_radio_sw_show(struct device *dev,
2107 struct device_attribute *attr, 2447 struct device_attribute *attr,
2108 char *buf) 2448 char *buf)
2109{ 2449{
2110 int res, s; 2450 int res;
2111 res = hotkey_get_wlsw(&s); 2451 res = hotkey_get_wlsw();
2112 if (res < 0) 2452 if (res < 0)
2113 return res; 2453 return res;
2114 2454
2115 return snprintf(buf, PAGE_SIZE, "%d\n", !!s); 2455 /* Opportunistic update */
2456 tpacpi_rfk_update_hwblock_state((res == TPACPI_RFK_RADIO_OFF));
2457
2458 return snprintf(buf, PAGE_SIZE, "%d\n",
2459 (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1);
2116} 2460}
2117 2461
2118static struct device_attribute dev_attr_hotkey_radio_sw = 2462static struct device_attribute dev_attr_hotkey_radio_sw =
@@ -2223,30 +2567,52 @@ static struct attribute *hotkey_mask_attributes[] __initdata = {
2223 &dev_attr_hotkey_wakeup_hotunplug_complete.attr, 2567 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2224}; 2568};
2225 2569
2226static void bluetooth_update_rfk(void); 2570/*
2227static void wan_update_rfk(void); 2571 * Sync both the hw and sw blocking state of all switches
2228static void uwb_update_rfk(void); 2572 */
2229static void tpacpi_send_radiosw_update(void) 2573static void tpacpi_send_radiosw_update(void)
2230{ 2574{
2231 int wlsw; 2575 int wlsw;
2232 2576
2233 /* Sync these BEFORE sending any rfkill events */ 2577 /*
2234 if (tp_features.bluetooth) 2578 * We must sync all rfkill controllers *before* issuing any
2235 bluetooth_update_rfk(); 2579 * rfkill input events, or we will race the rfkill core input
2236 if (tp_features.wan) 2580 * handler.
2237 wan_update_rfk(); 2581 *
2238 if (tp_features.uwb) 2582 * tpacpi_inputdev_send_mutex works as a syncronization point
2239 uwb_update_rfk(); 2583 * for the above.
2584 *
2585 * We optimize to avoid numerous calls to hotkey_get_wlsw.
2586 */
2587
2588 wlsw = hotkey_get_wlsw();
2589
2590 /* Sync hw blocking state first if it is hw-blocked */
2591 if (wlsw == TPACPI_RFK_RADIO_OFF)
2592 tpacpi_rfk_update_hwblock_state(true);
2593
2594 /* Sync sw blocking state */
2595 tpacpi_rfk_update_swstate_all();
2596
2597 /* Sync hw blocking state last if it is hw-unblocked */
2598 if (wlsw == TPACPI_RFK_RADIO_ON)
2599 tpacpi_rfk_update_hwblock_state(false);
2240 2600
2241 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { 2601 /* Issue rfkill input event for WLSW switch */
2602 if (!(wlsw < 0)) {
2242 mutex_lock(&tpacpi_inputdev_send_mutex); 2603 mutex_lock(&tpacpi_inputdev_send_mutex);
2243 2604
2244 input_report_switch(tpacpi_inputdev, 2605 input_report_switch(tpacpi_inputdev,
2245 SW_RFKILL_ALL, !!wlsw); 2606 SW_RFKILL_ALL, (wlsw > 0));
2246 input_sync(tpacpi_inputdev); 2607 input_sync(tpacpi_inputdev);
2247 2608
2248 mutex_unlock(&tpacpi_inputdev_send_mutex); 2609 mutex_unlock(&tpacpi_inputdev_send_mutex);
2249 } 2610 }
2611
2612 /*
2613 * this can be unconditional, as we will poll state again
2614 * if userspace uses the notify to read data
2615 */
2250 hotkey_radio_sw_notify_change(); 2616 hotkey_radio_sw_notify_change();
2251} 2617}
2252 2618
@@ -2585,7 +2951,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2585 /* update bright_acpimode... */ 2951 /* update bright_acpimode... */
2586 tpacpi_check_std_acpi_brightness_support(); 2952 tpacpi_check_std_acpi_brightness_support();
2587 2953
2588 if (tp_features.bright_acpimode) { 2954 if (tp_features.bright_acpimode && acpi_video_backlight_support()) {
2589 printk(TPACPI_INFO 2955 printk(TPACPI_INFO
2590 "This ThinkPad has standard ACPI backlight " 2956 "This ThinkPad has standard ACPI backlight "
2591 "brightness control, supported by the ACPI " 2957 "brightness control, supported by the ACPI "
@@ -3056,8 +3422,6 @@ enum {
3056 3422
3057#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" 3423#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
3058 3424
3059static struct rfkill *tpacpi_bluetooth_rfkill;
3060
3061static void bluetooth_suspend(pm_message_t state) 3425static void bluetooth_suspend(pm_message_t state)
3062{ 3426{
3063 /* Try to make sure radio will resume powered off */ 3427 /* Try to make sure radio will resume powered off */
@@ -3067,83 +3431,47 @@ static void bluetooth_suspend(pm_message_t state)
3067 "bluetooth power down on resume request failed\n"); 3431 "bluetooth power down on resume request failed\n");
3068} 3432}
3069 3433
3070static int bluetooth_get_radiosw(void) 3434static int bluetooth_get_status(void)
3071{ 3435{
3072 int status; 3436 int status;
3073 3437
3074 if (!tp_features.bluetooth)
3075 return -ENODEV;
3076
3077 /* WLSW overrides bluetooth in firmware/hardware, reflect that */
3078 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3079 return RFKILL_STATE_HARD_BLOCKED;
3080
3081#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3438#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3082 if (dbg_bluetoothemul) 3439 if (dbg_bluetoothemul)
3083 return (tpacpi_bluetooth_emulstate) ? 3440 return (tpacpi_bluetooth_emulstate) ?
3084 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3441 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3085#endif 3442#endif
3086 3443
3087 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 3444 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
3088 return -EIO; 3445 return -EIO;
3089 3446
3090 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ? 3447 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ?
3091 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3448 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3092} 3449}
3093 3450
3094static void bluetooth_update_rfk(void) 3451static int bluetooth_set_status(enum tpacpi_rfkill_state state)
3095{ 3452{
3096 int status; 3453 int status;
3097 3454
3098 if (!tpacpi_bluetooth_rfkill)
3099 return;
3100
3101 status = bluetooth_get_radiosw();
3102 if (status < 0)
3103 return;
3104 rfkill_force_state(tpacpi_bluetooth_rfkill, status);
3105
3106 vdbg_printk(TPACPI_DBG_RFKILL, 3455 vdbg_printk(TPACPI_DBG_RFKILL,
3107 "forced rfkill state to %d\n", 3456 "will attempt to %s bluetooth\n",
3108 status); 3457 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3109}
3110
3111static int bluetooth_set_radiosw(int radio_on, int update_rfk)
3112{
3113 int status;
3114
3115 if (!tp_features.bluetooth)
3116 return -ENODEV;
3117
3118 /* WLSW overrides bluetooth in firmware/hardware, but there is no
3119 * reason to risk weird behaviour. */
3120 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3121 && radio_on)
3122 return -EPERM;
3123
3124 vdbg_printk(TPACPI_DBG_RFKILL,
3125 "will %s bluetooth\n", radio_on ? "enable" : "disable");
3126 3458
3127#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3459#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3128 if (dbg_bluetoothemul) { 3460 if (dbg_bluetoothemul) {
3129 tpacpi_bluetooth_emulstate = !!radio_on; 3461 tpacpi_bluetooth_emulstate = (state == TPACPI_RFK_RADIO_ON);
3130 if (update_rfk)
3131 bluetooth_update_rfk();
3132 return 0; 3462 return 0;
3133 } 3463 }
3134#endif 3464#endif
3135 3465
3136 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ 3466 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
3137 if (radio_on) 3467 if (state == TPACPI_RFK_RADIO_ON)
3138 status = TP_ACPI_BLUETOOTH_RADIOSSW; 3468 status = TP_ACPI_BLUETOOTH_RADIOSSW;
3139 else 3469 else
3140 status = 0; 3470 status = 0;
3471
3141 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) 3472 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
3142 return -EIO; 3473 return -EIO;
3143 3474
3144 if (update_rfk)
3145 bluetooth_update_rfk();
3146
3147 return 0; 3475 return 0;
3148} 3476}
3149 3477
@@ -3152,35 +3480,16 @@ static ssize_t bluetooth_enable_show(struct device *dev,
3152 struct device_attribute *attr, 3480 struct device_attribute *attr,
3153 char *buf) 3481 char *buf)
3154{ 3482{
3155 int status; 3483 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_BLUETOOTH_SW_ID,
3156 3484 attr, buf);
3157 printk_deprecated_rfkill_attribute("bluetooth_enable");
3158
3159 status = bluetooth_get_radiosw();
3160 if (status < 0)
3161 return status;
3162
3163 return snprintf(buf, PAGE_SIZE, "%d\n",
3164 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
3165} 3485}
3166 3486
3167static ssize_t bluetooth_enable_store(struct device *dev, 3487static ssize_t bluetooth_enable_store(struct device *dev,
3168 struct device_attribute *attr, 3488 struct device_attribute *attr,
3169 const char *buf, size_t count) 3489 const char *buf, size_t count)
3170{ 3490{
3171 unsigned long t; 3491 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_BLUETOOTH_SW_ID,
3172 int res; 3492 attr, buf, count);
3173
3174 printk_deprecated_rfkill_attribute("bluetooth_enable");
3175
3176 if (parse_strtoul(buf, 1, &t))
3177 return -EINVAL;
3178
3179 tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
3180
3181 res = bluetooth_set_radiosw(t, 1);
3182
3183 return (res) ? res : count;
3184} 3493}
3185 3494
3186static struct device_attribute dev_attr_bluetooth_enable = 3495static struct device_attribute dev_attr_bluetooth_enable =
@@ -3198,23 +3507,10 @@ static const struct attribute_group bluetooth_attr_group = {
3198 .attrs = bluetooth_attributes, 3507 .attrs = bluetooth_attributes,
3199}; 3508};
3200 3509
3201static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state) 3510static const struct tpacpi_rfk_ops bluetooth_tprfk_ops = {
3202{ 3511 .get_status = bluetooth_get_status,
3203 int bts = bluetooth_get_radiosw(); 3512 .set_status = bluetooth_set_status,
3204 3513};
3205 if (bts < 0)
3206 return bts;
3207
3208 *state = bts;
3209 return 0;
3210}
3211
3212static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
3213{
3214 dbg_printk(TPACPI_DBG_RFKILL,
3215 "request to change radio state to %d\n", state);
3216 return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3217}
3218 3514
3219static void bluetooth_shutdown(void) 3515static void bluetooth_shutdown(void)
3220{ 3516{
@@ -3230,13 +3526,12 @@ static void bluetooth_shutdown(void)
3230 3526
3231static void bluetooth_exit(void) 3527static void bluetooth_exit(void)
3232{ 3528{
3233 bluetooth_shutdown();
3234
3235 if (tpacpi_bluetooth_rfkill)
3236 rfkill_unregister(tpacpi_bluetooth_rfkill);
3237
3238 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3529 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3239 &bluetooth_attr_group); 3530 &bluetooth_attr_group);
3531
3532 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
3533
3534 bluetooth_shutdown();
3240} 3535}
3241 3536
3242static int __init bluetooth_init(struct ibm_init_struct *iibm) 3537static int __init bluetooth_init(struct ibm_init_struct *iibm)
@@ -3277,20 +3572,18 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3277 if (!tp_features.bluetooth) 3572 if (!tp_features.bluetooth)
3278 return 1; 3573 return 1;
3279 3574
3280 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3281 &bluetooth_attr_group);
3282 if (res)
3283 return res;
3284
3285 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, 3575 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
3286 &tpacpi_bluetooth_rfkill, 3576 &bluetooth_tprfk_ops,
3287 RFKILL_TYPE_BLUETOOTH, 3577 RFKILL_TYPE_BLUETOOTH,
3288 TPACPI_RFK_BLUETOOTH_SW_NAME, 3578 TPACPI_RFK_BLUETOOTH_SW_NAME,
3289 true, 3579 true);
3290 tpacpi_bluetooth_rfk_set, 3580 if (res)
3291 tpacpi_bluetooth_rfk_get); 3581 return res;
3582
3583 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3584 &bluetooth_attr_group);
3292 if (res) { 3585 if (res) {
3293 bluetooth_exit(); 3586 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
3294 return res; 3587 return res;
3295 } 3588 }
3296 3589
@@ -3300,46 +3593,12 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3300/* procfs -------------------------------------------------------------- */ 3593/* procfs -------------------------------------------------------------- */
3301static int bluetooth_read(char *p) 3594static int bluetooth_read(char *p)
3302{ 3595{
3303 int len = 0; 3596 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, p);
3304 int status = bluetooth_get_radiosw();
3305
3306 if (!tp_features.bluetooth)
3307 len += sprintf(p + len, "status:\t\tnot supported\n");
3308 else {
3309 len += sprintf(p + len, "status:\t\t%s\n",
3310 (status == RFKILL_STATE_UNBLOCKED) ?
3311 "enabled" : "disabled");
3312 len += sprintf(p + len, "commands:\tenable, disable\n");
3313 }
3314
3315 return len;
3316} 3597}
3317 3598
3318static int bluetooth_write(char *buf) 3599static int bluetooth_write(char *buf)
3319{ 3600{
3320 char *cmd; 3601 return tpacpi_rfk_procfs_write(TPACPI_RFK_BLUETOOTH_SW_ID, buf);
3321 int state = -1;
3322
3323 if (!tp_features.bluetooth)
3324 return -ENODEV;
3325
3326 while ((cmd = next_cmd(&buf))) {
3327 if (strlencmp(cmd, "enable") == 0) {
3328 state = 1;
3329 } else if (strlencmp(cmd, "disable") == 0) {
3330 state = 0;
3331 } else
3332 return -EINVAL;
3333 }
3334
3335 if (state != -1) {
3336 tpacpi_disclose_usertask("procfs bluetooth",
3337 "attempt to %s\n",
3338 state ? "enable" : "disable");
3339 bluetooth_set_radiosw(state, 1);
3340 }
3341
3342 return 0;
3343} 3602}
3344 3603
3345static struct ibm_struct bluetooth_driver_data = { 3604static struct ibm_struct bluetooth_driver_data = {
@@ -3365,8 +3624,6 @@ enum {
3365 3624
3366#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" 3625#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
3367 3626
3368static struct rfkill *tpacpi_wan_rfkill;
3369
3370static void wan_suspend(pm_message_t state) 3627static void wan_suspend(pm_message_t state)
3371{ 3628{
3372 /* Try to make sure radio will resume powered off */ 3629 /* Try to make sure radio will resume powered off */
@@ -3376,83 +3633,47 @@ static void wan_suspend(pm_message_t state)
3376 "WWAN power down on resume request failed\n"); 3633 "WWAN power down on resume request failed\n");
3377} 3634}
3378 3635
3379static int wan_get_radiosw(void) 3636static int wan_get_status(void)
3380{ 3637{
3381 int status; 3638 int status;
3382 3639
3383 if (!tp_features.wan)
3384 return -ENODEV;
3385
3386 /* WLSW overrides WWAN in firmware/hardware, reflect that */
3387 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3388 return RFKILL_STATE_HARD_BLOCKED;
3389
3390#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3640#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3391 if (dbg_wwanemul) 3641 if (dbg_wwanemul)
3392 return (tpacpi_wwan_emulstate) ? 3642 return (tpacpi_wwan_emulstate) ?
3393 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3643 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3394#endif 3644#endif
3395 3645
3396 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 3646 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
3397 return -EIO; 3647 return -EIO;
3398 3648
3399 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ? 3649 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ?
3400 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3650 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3401}
3402
3403static void wan_update_rfk(void)
3404{
3405 int status;
3406
3407 if (!tpacpi_wan_rfkill)
3408 return;
3409
3410 status = wan_get_radiosw();
3411 if (status < 0)
3412 return;
3413 rfkill_force_state(tpacpi_wan_rfkill, status);
3414
3415 vdbg_printk(TPACPI_DBG_RFKILL,
3416 "forced rfkill state to %d\n",
3417 status);
3418} 3651}
3419 3652
3420static int wan_set_radiosw(int radio_on, int update_rfk) 3653static int wan_set_status(enum tpacpi_rfkill_state state)
3421{ 3654{
3422 int status; 3655 int status;
3423 3656
3424 if (!tp_features.wan)
3425 return -ENODEV;
3426
3427 /* WLSW overrides bluetooth in firmware/hardware, but there is no
3428 * reason to risk weird behaviour. */
3429 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3430 && radio_on)
3431 return -EPERM;
3432
3433 vdbg_printk(TPACPI_DBG_RFKILL, 3657 vdbg_printk(TPACPI_DBG_RFKILL,
3434 "will %s WWAN\n", radio_on ? "enable" : "disable"); 3658 "will attempt to %s wwan\n",
3659 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3435 3660
3436#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3661#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3437 if (dbg_wwanemul) { 3662 if (dbg_wwanemul) {
3438 tpacpi_wwan_emulstate = !!radio_on; 3663 tpacpi_wwan_emulstate = (state == TPACPI_RFK_RADIO_ON);
3439 if (update_rfk)
3440 wan_update_rfk();
3441 return 0; 3664 return 0;
3442 } 3665 }
3443#endif 3666#endif
3444 3667
3445 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ 3668 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */
3446 if (radio_on) 3669 if (state == TPACPI_RFK_RADIO_ON)
3447 status = TP_ACPI_WANCARD_RADIOSSW; 3670 status = TP_ACPI_WANCARD_RADIOSSW;
3448 else 3671 else
3449 status = 0; 3672 status = 0;
3673
3450 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) 3674 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
3451 return -EIO; 3675 return -EIO;
3452 3676
3453 if (update_rfk)
3454 wan_update_rfk();
3455
3456 return 0; 3677 return 0;
3457} 3678}
3458 3679
@@ -3461,35 +3682,16 @@ static ssize_t wan_enable_show(struct device *dev,
3461 struct device_attribute *attr, 3682 struct device_attribute *attr,
3462 char *buf) 3683 char *buf)
3463{ 3684{
3464 int status; 3685 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_WWAN_SW_ID,
3465 3686 attr, buf);
3466 printk_deprecated_rfkill_attribute("wwan_enable");
3467
3468 status = wan_get_radiosw();
3469 if (status < 0)
3470 return status;
3471
3472 return snprintf(buf, PAGE_SIZE, "%d\n",
3473 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
3474} 3687}
3475 3688
3476static ssize_t wan_enable_store(struct device *dev, 3689static ssize_t wan_enable_store(struct device *dev,
3477 struct device_attribute *attr, 3690 struct device_attribute *attr,
3478 const char *buf, size_t count) 3691 const char *buf, size_t count)
3479{ 3692{
3480 unsigned long t; 3693 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_WWAN_SW_ID,
3481 int res; 3694 attr, buf, count);
3482
3483 printk_deprecated_rfkill_attribute("wwan_enable");
3484
3485 if (parse_strtoul(buf, 1, &t))
3486 return -EINVAL;
3487
3488 tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
3489
3490 res = wan_set_radiosw(t, 1);
3491
3492 return (res) ? res : count;
3493} 3695}
3494 3696
3495static struct device_attribute dev_attr_wan_enable = 3697static struct device_attribute dev_attr_wan_enable =
@@ -3507,23 +3709,10 @@ static const struct attribute_group wan_attr_group = {
3507 .attrs = wan_attributes, 3709 .attrs = wan_attributes,
3508}; 3710};
3509 3711
3510static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state) 3712static const struct tpacpi_rfk_ops wan_tprfk_ops = {
3511{ 3713 .get_status = wan_get_status,
3512 int wans = wan_get_radiosw(); 3714 .set_status = wan_set_status,
3513 3715};
3514 if (wans < 0)
3515 return wans;
3516
3517 *state = wans;
3518 return 0;
3519}
3520
3521static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
3522{
3523 dbg_printk(TPACPI_DBG_RFKILL,
3524 "request to change radio state to %d\n", state);
3525 return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3526}
3527 3716
3528static void wan_shutdown(void) 3717static void wan_shutdown(void)
3529{ 3718{
@@ -3539,13 +3728,12 @@ static void wan_shutdown(void)
3539 3728
3540static void wan_exit(void) 3729static void wan_exit(void)
3541{ 3730{
3542 wan_shutdown();
3543
3544 if (tpacpi_wan_rfkill)
3545 rfkill_unregister(tpacpi_wan_rfkill);
3546
3547 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3731 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3548 &wan_attr_group); 3732 &wan_attr_group);
3733
3734 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
3735
3736 wan_shutdown();
3549} 3737}
3550 3738
3551static int __init wan_init(struct ibm_init_struct *iibm) 3739static int __init wan_init(struct ibm_init_struct *iibm)
@@ -3584,20 +3772,19 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3584 if (!tp_features.wan) 3772 if (!tp_features.wan)
3585 return 1; 3773 return 1;
3586 3774
3587 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3588 &wan_attr_group);
3589 if (res)
3590 return res;
3591
3592 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, 3775 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
3593 &tpacpi_wan_rfkill, 3776 &wan_tprfk_ops,
3594 RFKILL_TYPE_WWAN, 3777 RFKILL_TYPE_WWAN,
3595 TPACPI_RFK_WWAN_SW_NAME, 3778 TPACPI_RFK_WWAN_SW_NAME,
3596 true, 3779 true);
3597 tpacpi_wan_rfk_set, 3780 if (res)
3598 tpacpi_wan_rfk_get); 3781 return res;
3782
3783 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3784 &wan_attr_group);
3785
3599 if (res) { 3786 if (res) {
3600 wan_exit(); 3787 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
3601 return res; 3788 return res;
3602 } 3789 }
3603 3790
@@ -3607,48 +3794,12 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3607/* procfs -------------------------------------------------------------- */ 3794/* procfs -------------------------------------------------------------- */
3608static int wan_read(char *p) 3795static int wan_read(char *p)
3609{ 3796{
3610 int len = 0; 3797 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, p);
3611 int status = wan_get_radiosw();
3612
3613 tpacpi_disclose_usertask("procfs wan", "read");
3614
3615 if (!tp_features.wan)
3616 len += sprintf(p + len, "status:\t\tnot supported\n");
3617 else {
3618 len += sprintf(p + len, "status:\t\t%s\n",
3619 (status == RFKILL_STATE_UNBLOCKED) ?
3620 "enabled" : "disabled");
3621 len += sprintf(p + len, "commands:\tenable, disable\n");
3622 }
3623
3624 return len;
3625} 3798}
3626 3799
3627static int wan_write(char *buf) 3800static int wan_write(char *buf)
3628{ 3801{
3629 char *cmd; 3802 return tpacpi_rfk_procfs_write(TPACPI_RFK_WWAN_SW_ID, buf);
3630 int state = -1;
3631
3632 if (!tp_features.wan)
3633 return -ENODEV;
3634
3635 while ((cmd = next_cmd(&buf))) {
3636 if (strlencmp(cmd, "enable") == 0) {
3637 state = 1;
3638 } else if (strlencmp(cmd, "disable") == 0) {
3639 state = 0;
3640 } else
3641 return -EINVAL;
3642 }
3643
3644 if (state != -1) {
3645 tpacpi_disclose_usertask("procfs wan",
3646 "attempt to %s\n",
3647 state ? "enable" : "disable");
3648 wan_set_radiosw(state, 1);
3649 }
3650
3651 return 0;
3652} 3803}
3653 3804
3654static struct ibm_struct wan_driver_data = { 3805static struct ibm_struct wan_driver_data = {
@@ -3672,108 +3823,59 @@ enum {
3672 3823
3673#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw" 3824#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
3674 3825
3675static struct rfkill *tpacpi_uwb_rfkill; 3826static int uwb_get_status(void)
3676
3677static int uwb_get_radiosw(void)
3678{ 3827{
3679 int status; 3828 int status;
3680 3829
3681 if (!tp_features.uwb)
3682 return -ENODEV;
3683
3684 /* WLSW overrides UWB in firmware/hardware, reflect that */
3685 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3686 return RFKILL_STATE_HARD_BLOCKED;
3687
3688#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3830#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3689 if (dbg_uwbemul) 3831 if (dbg_uwbemul)
3690 return (tpacpi_uwb_emulstate) ? 3832 return (tpacpi_uwb_emulstate) ?
3691 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3833 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3692#endif 3834#endif
3693 3835
3694 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d")) 3836 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d"))
3695 return -EIO; 3837 return -EIO;
3696 3838
3697 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ? 3839 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ?
3698 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3840 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3699} 3841}
3700 3842
3701static void uwb_update_rfk(void) 3843static int uwb_set_status(enum tpacpi_rfkill_state state)
3702{ 3844{
3703 int status; 3845 int status;
3704 3846
3705 if (!tpacpi_uwb_rfkill)
3706 return;
3707
3708 status = uwb_get_radiosw();
3709 if (status < 0)
3710 return;
3711 rfkill_force_state(tpacpi_uwb_rfkill, status);
3712
3713 vdbg_printk(TPACPI_DBG_RFKILL,
3714 "forced rfkill state to %d\n",
3715 status);
3716}
3717
3718static int uwb_set_radiosw(int radio_on, int update_rfk)
3719{
3720 int status;
3721
3722 if (!tp_features.uwb)
3723 return -ENODEV;
3724
3725 /* WLSW overrides UWB in firmware/hardware, but there is no
3726 * reason to risk weird behaviour. */
3727 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3728 && radio_on)
3729 return -EPERM;
3730
3731 vdbg_printk(TPACPI_DBG_RFKILL, 3847 vdbg_printk(TPACPI_DBG_RFKILL,
3732 "will %s UWB\n", radio_on ? "enable" : "disable"); 3848 "will attempt to %s UWB\n",
3849 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3733 3850
3734#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3851#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3735 if (dbg_uwbemul) { 3852 if (dbg_uwbemul) {
3736 tpacpi_uwb_emulstate = !!radio_on; 3853 tpacpi_uwb_emulstate = (state == TPACPI_RFK_RADIO_ON);
3737 if (update_rfk)
3738 uwb_update_rfk();
3739 return 0; 3854 return 0;
3740 } 3855 }
3741#endif 3856#endif
3742 3857
3743 status = (radio_on) ? TP_ACPI_UWB_RADIOSSW : 0; 3858 if (state == TPACPI_RFK_RADIO_ON)
3859 status = TP_ACPI_UWB_RADIOSSW;
3860 else
3861 status = 0;
3862
3744 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status)) 3863 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status))
3745 return -EIO; 3864 return -EIO;
3746 3865
3747 if (update_rfk)
3748 uwb_update_rfk();
3749
3750 return 0; 3866 return 0;
3751} 3867}
3752 3868
3753/* --------------------------------------------------------------------- */ 3869/* --------------------------------------------------------------------- */
3754 3870
3755static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state) 3871static const struct tpacpi_rfk_ops uwb_tprfk_ops = {
3756{ 3872 .get_status = uwb_get_status,
3757 int uwbs = uwb_get_radiosw(); 3873 .set_status = uwb_set_status,
3758 3874};
3759 if (uwbs < 0)
3760 return uwbs;
3761
3762 *state = uwbs;
3763 return 0;
3764}
3765
3766static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
3767{
3768 dbg_printk(TPACPI_DBG_RFKILL,
3769 "request to change radio state to %d\n", state);
3770 return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3771}
3772 3875
3773static void uwb_exit(void) 3876static void uwb_exit(void)
3774{ 3877{
3775 if (tpacpi_uwb_rfkill) 3878 tpacpi_destroy_rfkill(TPACPI_RFK_UWB_SW_ID);
3776 rfkill_unregister(tpacpi_uwb_rfkill);
3777} 3879}
3778 3880
3779static int __init uwb_init(struct ibm_init_struct *iibm) 3881static int __init uwb_init(struct ibm_init_struct *iibm)
@@ -3813,13 +3915,10 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
3813 return 1; 3915 return 1;
3814 3916
3815 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, 3917 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
3816 &tpacpi_uwb_rfkill, 3918 &uwb_tprfk_ops,
3817 RFKILL_TYPE_UWB, 3919 RFKILL_TYPE_UWB,
3818 TPACPI_RFK_UWB_SW_NAME, 3920 TPACPI_RFK_UWB_SW_NAME,
3819 false, 3921 false);
3820 tpacpi_uwb_rfk_set,
3821 tpacpi_uwb_rfk_get);
3822
3823 return res; 3922 return res;
3824} 3923}
3825 3924
@@ -4745,7 +4844,7 @@ TPACPI_HANDLE(led, ec, "SLED", /* 570 */
4745 "LED", /* all others */ 4844 "LED", /* all others */
4746 ); /* R30, R31 */ 4845 ); /* R30, R31 */
4747 4846
4748#define TPACPI_LED_NUMLEDS 8 4847#define TPACPI_LED_NUMLEDS 16
4749static struct tpacpi_led_classdev *tpacpi_leds; 4848static struct tpacpi_led_classdev *tpacpi_leds;
4750static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS]; 4849static enum led_status_t tpacpi_led_state_cache[TPACPI_LED_NUMLEDS];
4751static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { 4850static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
@@ -4758,15 +4857,20 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
4758 "tpacpi::dock_batt", 4857 "tpacpi::dock_batt",
4759 "tpacpi::unknown_led", 4858 "tpacpi::unknown_led",
4760 "tpacpi::standby", 4859 "tpacpi::standby",
4860 "tpacpi::dock_status1",
4861 "tpacpi::dock_status2",
4862 "tpacpi::unknown_led2",
4863 "tpacpi::unknown_led3",
4864 "tpacpi::thinkvantage",
4761}; 4865};
4762#define TPACPI_SAFE_LEDS 0x0081U 4866#define TPACPI_SAFE_LEDS 0x1081U
4763 4867
4764static inline bool tpacpi_is_led_restricted(const unsigned int led) 4868static inline bool tpacpi_is_led_restricted(const unsigned int led)
4765{ 4869{
4766#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS 4870#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
4767 return false; 4871 return false;
4768#else 4872#else
4769 return (TPACPI_SAFE_LEDS & (1 << led)) == 0; 4873 return (1U & (TPACPI_SAFE_LEDS >> led)) == 0;
4770#endif 4874#endif
4771} 4875}
4772 4876
@@ -4928,6 +5032,10 @@ static int __init tpacpi_init_led(unsigned int led)
4928 5032
4929 tpacpi_leds[led].led = led; 5033 tpacpi_leds[led].led = led;
4930 5034
5035 /* LEDs with no name don't get registered */
5036 if (!tpacpi_led_names[led])
5037 return 0;
5038
4931 tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set; 5039 tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set;
4932 tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set; 5040 tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;
4933 if (led_supported == TPACPI_LED_570) 5041 if (led_supported == TPACPI_LED_570)
@@ -4946,10 +5054,59 @@ static int __init tpacpi_init_led(unsigned int led)
4946 return rc; 5054 return rc;
4947} 5055}
4948 5056
5057static const struct tpacpi_quirk led_useful_qtable[] __initconst = {
5058 TPACPI_Q_IBM('1', 'E', 0x009f), /* A30 */
5059 TPACPI_Q_IBM('1', 'N', 0x009f), /* A31 */
5060 TPACPI_Q_IBM('1', 'G', 0x009f), /* A31 */
5061
5062 TPACPI_Q_IBM('1', 'I', 0x0097), /* T30 */
5063 TPACPI_Q_IBM('1', 'R', 0x0097), /* T40, T41, T42, R50, R51 */
5064 TPACPI_Q_IBM('7', '0', 0x0097), /* T43, R52 */
5065 TPACPI_Q_IBM('1', 'Y', 0x0097), /* T43 */
5066 TPACPI_Q_IBM('1', 'W', 0x0097), /* R50e */
5067 TPACPI_Q_IBM('1', 'V', 0x0097), /* R51 */
5068 TPACPI_Q_IBM('7', '8', 0x0097), /* R51e */
5069 TPACPI_Q_IBM('7', '6', 0x0097), /* R52 */
5070
5071 TPACPI_Q_IBM('1', 'K', 0x00bf), /* X30 */
5072 TPACPI_Q_IBM('1', 'Q', 0x00bf), /* X31, X32 */
5073 TPACPI_Q_IBM('1', 'U', 0x00bf), /* X40 */
5074 TPACPI_Q_IBM('7', '4', 0x00bf), /* X41 */
5075 TPACPI_Q_IBM('7', '5', 0x00bf), /* X41t */
5076
5077 TPACPI_Q_IBM('7', '9', 0x1f97), /* T60 (1) */
5078 TPACPI_Q_IBM('7', '7', 0x1f97), /* Z60* (1) */
5079 TPACPI_Q_IBM('7', 'F', 0x1f97), /* Z61* (1) */
5080 TPACPI_Q_IBM('7', 'B', 0x1fb7), /* X60 (1) */
5081
5082 /* (1) - may have excess leds enabled on MSB */
5083
5084 /* Defaults (order matters, keep last, don't reorder!) */
5085 { /* Lenovo */
5086 .vendor = PCI_VENDOR_ID_LENOVO,
5087 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
5088 .quirks = 0x1fffU,
5089 },
5090 { /* IBM ThinkPads with no EC version string */
5091 .vendor = PCI_VENDOR_ID_IBM,
5092 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_UNKNOWN,
5093 .quirks = 0x00ffU,
5094 },
5095 { /* IBM ThinkPads with EC version string */
5096 .vendor = PCI_VENDOR_ID_IBM,
5097 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
5098 .quirks = 0x00bfU,
5099 },
5100};
5101
5102#undef TPACPI_LEDQ_IBM
5103#undef TPACPI_LEDQ_LNV
5104
4949static int __init led_init(struct ibm_init_struct *iibm) 5105static int __init led_init(struct ibm_init_struct *iibm)
4950{ 5106{
4951 unsigned int i; 5107 unsigned int i;
4952 int rc; 5108 int rc;
5109 unsigned long useful_leds;
4953 5110
4954 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n"); 5111 vdbg_printk(TPACPI_DBG_INIT, "initializing LED subdriver\n");
4955 5112
@@ -4971,6 +5128,9 @@ static int __init led_init(struct ibm_init_struct *iibm)
4971 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n", 5128 vdbg_printk(TPACPI_DBG_INIT, "LED commands are %s, mode %d\n",
4972 str_supported(led_supported), led_supported); 5129 str_supported(led_supported), led_supported);
4973 5130
5131 if (led_supported == TPACPI_LED_NONE)
5132 return 1;
5133
4974 tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS, 5134 tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS,
4975 GFP_KERNEL); 5135 GFP_KERNEL);
4976 if (!tpacpi_leds) { 5136 if (!tpacpi_leds) {
@@ -4978,8 +5138,12 @@ static int __init led_init(struct ibm_init_struct *iibm)
4978 return -ENOMEM; 5138 return -ENOMEM;
4979 } 5139 }
4980 5140
5141 useful_leds = tpacpi_check_quirks(led_useful_qtable,
5142 ARRAY_SIZE(led_useful_qtable));
5143
4981 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { 5144 for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
4982 if (!tpacpi_is_led_restricted(i)) { 5145 if (!tpacpi_is_led_restricted(i) &&
5146 test_bit(i, &useful_leds)) {
4983 rc = tpacpi_init_led(i); 5147 rc = tpacpi_init_led(i);
4984 if (rc < 0) { 5148 if (rc < 0) {
4985 led_exit(); 5149 led_exit();
@@ -4989,12 +5153,11 @@ static int __init led_init(struct ibm_init_struct *iibm)
4989 } 5153 }
4990 5154
4991#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS 5155#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
4992 if (led_supported != TPACPI_LED_NONE) 5156 printk(TPACPI_NOTICE
4993 printk(TPACPI_NOTICE 5157 "warning: userspace override of important "
4994 "warning: userspace override of important " 5158 "firmware LEDs is enabled\n");
4995 "firmware LEDs is enabled\n");
4996#endif 5159#endif
4997 return (led_supported != TPACPI_LED_NONE)? 0 : 1; 5160 return 0;
4998} 5161}
4999 5162
5000#define str_led_status(s) \ 5163#define str_led_status(s) \
@@ -5024,7 +5187,7 @@ static int led_read(char *p)
5024 } 5187 }
5025 5188
5026 len += sprintf(p + len, "commands:\t" 5189 len += sprintf(p + len, "commands:\t"
5027 "<led> on, <led> off, <led> blink (<led> is 0-7)\n"); 5190 "<led> on, <led> off, <led> blink (<led> is 0-15)\n");
5028 5191
5029 return len; 5192 return len;
5030} 5193}
@@ -5039,7 +5202,7 @@ static int led_write(char *buf)
5039 return -ENODEV; 5202 return -ENODEV;
5040 5203
5041 while ((cmd = next_cmd(&buf))) { 5204 while ((cmd = next_cmd(&buf))) {
5042 if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 7) 5205 if (sscanf(cmd, "%d", &led) != 1 || led < 0 || led > 15)
5043 return -EINVAL; 5206 return -EINVAL;
5044 5207
5045 if (strstr(cmd, "off")) { 5208 if (strstr(cmd, "off")) {
@@ -5073,8 +5236,17 @@ static struct ibm_struct led_driver_data = {
5073 5236
5074TPACPI_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ 5237TPACPI_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */
5075 5238
5239#define TPACPI_BEEP_Q1 0x0001
5240
5241static const struct tpacpi_quirk beep_quirk_table[] __initconst = {
5242 TPACPI_Q_IBM('I', 'M', TPACPI_BEEP_Q1), /* 570 */
5243 TPACPI_Q_IBM('I', 'U', TPACPI_BEEP_Q1), /* 570E - unverified */
5244};
5245
5076static int __init beep_init(struct ibm_init_struct *iibm) 5246static int __init beep_init(struct ibm_init_struct *iibm)
5077{ 5247{
5248 unsigned long quirks;
5249
5078 vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n"); 5250 vdbg_printk(TPACPI_DBG_INIT, "initializing beep subdriver\n");
5079 5251
5080 TPACPI_ACPIHANDLE_INIT(beep); 5252 TPACPI_ACPIHANDLE_INIT(beep);
@@ -5082,6 +5254,11 @@ static int __init beep_init(struct ibm_init_struct *iibm)
5082 vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n", 5254 vdbg_printk(TPACPI_DBG_INIT, "beep is %s\n",
5083 str_supported(beep_handle != NULL)); 5255 str_supported(beep_handle != NULL));
5084 5256
5257 quirks = tpacpi_check_quirks(beep_quirk_table,
5258 ARRAY_SIZE(beep_quirk_table));
5259
5260 tp_features.beep_needs_two_args = !!(quirks & TPACPI_BEEP_Q1);
5261
5085 return (beep_handle)? 0 : 1; 5262 return (beep_handle)? 0 : 1;
5086} 5263}
5087 5264
@@ -5113,8 +5290,15 @@ static int beep_write(char *buf)
5113 /* beep_cmd set */ 5290 /* beep_cmd set */
5114 } else 5291 } else
5115 return -EINVAL; 5292 return -EINVAL;
5116 if (!acpi_evalf(beep_handle, NULL, NULL, "vdd", beep_cmd, 0)) 5293 if (tp_features.beep_needs_two_args) {
5117 return -EIO; 5294 if (!acpi_evalf(beep_handle, NULL, NULL, "vdd",
5295 beep_cmd, 0))
5296 return -EIO;
5297 } else {
5298 if (!acpi_evalf(beep_handle, NULL, NULL, "vd",
5299 beep_cmd))
5300 return -EIO;
5301 }
5118 } 5302 }
5119 5303
5120 return 0; 5304 return 0;
@@ -5541,6 +5725,10 @@ static struct ibm_struct ecdump_driver_data = {
5541 * Bit 3-0: backlight brightness level 5725 * Bit 3-0: backlight brightness level
5542 * 5726 *
5543 * brightness_get_raw returns status data in the HBRV layout 5727 * brightness_get_raw returns status data in the HBRV layout
5728 *
5729 * WARNING: The X61 has been verified to use HBRV for something else, so
5730 * this should be used _only_ on IBM ThinkPads, and maybe with some careful
5731 * testing on the very early *60 Lenovo models...
5544 */ 5732 */
5545 5733
5546enum { 5734enum {
@@ -5841,6 +6029,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
5841 brightness_mode); 6029 brightness_mode);
5842 } 6030 }
5843 6031
6032 /* Safety */
6033 if (thinkpad_id.vendor != PCI_VENDOR_ID_IBM &&
6034 (brightness_mode == TPACPI_BRGHT_MODE_ECNVRAM ||
6035 brightness_mode == TPACPI_BRGHT_MODE_EC))
6036 return -EINVAL;
6037
5844 if (tpacpi_brightness_get_raw(&b) < 0) 6038 if (tpacpi_brightness_get_raw(&b) < 0)
5845 return 1; 6039 return 1;
5846 6040
@@ -6133,6 +6327,21 @@ static struct ibm_struct volume_driver_data = {
6133 * For firmware bugs, refer to: 6327 * For firmware bugs, refer to:
6134 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues 6328 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
6135 * 6329 *
6330 * ----
6331 *
6332 * ThinkPad EC register 0x31 bit 0 (only on select models)
6333 *
6334 * When bit 0 of EC register 0x31 is zero, the tachometer registers
6335 * show the speed of the main fan. When bit 0 of EC register 0x31
6336 * is one, the tachometer registers show the speed of the auxiliary
6337 * fan.
6338 *
6339 * Fan control seems to affect both fans, regardless of the state
6340 * of this bit.
6341 *
6342 * So far, only the firmware for the X60/X61 non-tablet versions
6343 * seem to support this (firmware TP-7M).
6344 *
6136 * TPACPI_FAN_WR_ACPI_FANS: 6345 * TPACPI_FAN_WR_ACPI_FANS:
6137 * ThinkPad X31, X40, X41. Not available in the X60. 6346 * ThinkPad X31, X40, X41. Not available in the X60.
6138 * 6347 *
@@ -6159,6 +6368,8 @@ enum { /* Fan control constants */
6159 fan_status_offset = 0x2f, /* EC register 0x2f */ 6368 fan_status_offset = 0x2f, /* EC register 0x2f */
6160 fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM) 6369 fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM)
6161 * 0x84 must be read before 0x85 */ 6370 * 0x84 must be read before 0x85 */
6371 fan_select_offset = 0x31, /* EC register 0x31 (Firmware 7M)
6372 bit 0 selects which fan is active */
6162 6373
6163 TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */ 6374 TP_EC_FAN_FULLSPEED = 0x40, /* EC fan mode: full speed */
6164 TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */ 6375 TP_EC_FAN_AUTO = 0x80, /* EC fan mode: auto fan control */
@@ -6221,30 +6432,18 @@ TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */
6221 * We assume 0x07 really means auto mode while this quirk is active, 6432 * We assume 0x07 really means auto mode while this quirk is active,
6222 * as this is far more likely than the ThinkPad being in level 7, 6433 * as this is far more likely than the ThinkPad being in level 7,
6223 * which is only used by the firmware during thermal emergencies. 6434 * which is only used by the firmware during thermal emergencies.
6435 *
6436 * Enable for TP-1Y (T43), TP-78 (R51e), TP-76 (R52),
6437 * TP-70 (T43, R52), which are known to be buggy.
6224 */ 6438 */
6225 6439
6226static void fan_quirk1_detect(void) 6440static void fan_quirk1_setup(void)
6227{ 6441{
6228 /* In some ThinkPads, neither the EC nor the ACPI
6229 * DSDT initialize the HFSP register, and it ends up
6230 * being initially set to 0x07 when it *could* be
6231 * either 0x07 or 0x80.
6232 *
6233 * Enable for TP-1Y (T43), TP-78 (R51e),
6234 * TP-76 (R52), TP-70 (T43, R52), which are known
6235 * to be buggy. */
6236 if (fan_control_initial_status == 0x07) { 6442 if (fan_control_initial_status == 0x07) {
6237 switch (thinkpad_id.ec_model) { 6443 printk(TPACPI_NOTICE
6238 case 0x5931: /* TP-1Y */ 6444 "fan_init: initial fan status is unknown, "
6239 case 0x3837: /* TP-78 */ 6445 "assuming it is in auto mode\n");
6240 case 0x3637: /* TP-76 */ 6446 tp_features.fan_ctrl_status_undef = 1;
6241 case 0x3037: /* TP-70 */
6242 printk(TPACPI_NOTICE
6243 "fan_init: initial fan status is unknown, "
6244 "assuming it is in auto mode\n");
6245 tp_features.fan_ctrl_status_undef = 1;
6246 ;;
6247 }
6248 } 6447 }
6249} 6448}
6250 6449
@@ -6264,6 +6463,38 @@ static void fan_quirk1_handle(u8 *fan_status)
6264 } 6463 }
6265} 6464}
6266 6465
6466/* Select main fan on X60/X61, NOOP on others */
6467static bool fan_select_fan1(void)
6468{
6469 if (tp_features.second_fan) {
6470 u8 val;
6471
6472 if (ec_read(fan_select_offset, &val) < 0)
6473 return false;
6474 val &= 0xFEU;
6475 if (ec_write(fan_select_offset, val) < 0)
6476 return false;
6477 }
6478 return true;
6479}
6480
6481/* Select secondary fan on X60/X61 */
6482static bool fan_select_fan2(void)
6483{
6484 u8 val;
6485
6486 if (!tp_features.second_fan)
6487 return false;
6488
6489 if (ec_read(fan_select_offset, &val) < 0)
6490 return false;
6491 val |= 0x01U;
6492 if (ec_write(fan_select_offset, val) < 0)
6493 return false;
6494
6495 return true;
6496}
6497
6267/* 6498/*
6268 * Call with fan_mutex held 6499 * Call with fan_mutex held
6269 */ 6500 */
@@ -6341,6 +6572,8 @@ static int fan_get_speed(unsigned int *speed)
6341 switch (fan_status_access_mode) { 6572 switch (fan_status_access_mode) {
6342 case TPACPI_FAN_RD_TPEC: 6573 case TPACPI_FAN_RD_TPEC:
6343 /* all except 570, 600e/x, 770e, 770x */ 6574 /* all except 570, 600e/x, 770e, 770x */
6575 if (unlikely(!fan_select_fan1()))
6576 return -EIO;
6344 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) || 6577 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
6345 !acpi_ec_read(fan_rpm_offset + 1, &hi))) 6578 !acpi_ec_read(fan_rpm_offset + 1, &hi)))
6346 return -EIO; 6579 return -EIO;
@@ -6357,6 +6590,34 @@ static int fan_get_speed(unsigned int *speed)
6357 return 0; 6590 return 0;
6358} 6591}
6359 6592
6593static int fan2_get_speed(unsigned int *speed)
6594{
6595 u8 hi, lo;
6596 bool rc;
6597
6598 switch (fan_status_access_mode) {
6599 case TPACPI_FAN_RD_TPEC:
6600 /* all except 570, 600e/x, 770e, 770x */
6601 if (unlikely(!fan_select_fan2()))
6602 return -EIO;
6603 rc = !acpi_ec_read(fan_rpm_offset, &lo) ||
6604 !acpi_ec_read(fan_rpm_offset + 1, &hi);
6605 fan_select_fan1(); /* play it safe */
6606 if (rc)
6607 return -EIO;
6608
6609 if (likely(speed))
6610 *speed = (hi << 8) | lo;
6611
6612 break;
6613
6614 default:
6615 return -ENXIO;
6616 }
6617
6618 return 0;
6619}
6620
6360static int fan_set_level(int level) 6621static int fan_set_level(int level)
6361{ 6622{
6362 if (!fan_control_allowed) 6623 if (!fan_control_allowed)
@@ -6762,6 +7023,25 @@ static struct device_attribute dev_attr_fan_fan1_input =
6762 __ATTR(fan1_input, S_IRUGO, 7023 __ATTR(fan1_input, S_IRUGO,
6763 fan_fan1_input_show, NULL); 7024 fan_fan1_input_show, NULL);
6764 7025
7026/* sysfs fan fan2_input ------------------------------------------------ */
7027static ssize_t fan_fan2_input_show(struct device *dev,
7028 struct device_attribute *attr,
7029 char *buf)
7030{
7031 int res;
7032 unsigned int speed;
7033
7034 res = fan2_get_speed(&speed);
7035 if (res < 0)
7036 return res;
7037
7038 return snprintf(buf, PAGE_SIZE, "%u\n", speed);
7039}
7040
7041static struct device_attribute dev_attr_fan_fan2_input =
7042 __ATTR(fan2_input, S_IRUGO,
7043 fan_fan2_input_show, NULL);
7044
6765/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ 7045/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
6766static ssize_t fan_fan_watchdog_show(struct device_driver *drv, 7046static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
6767 char *buf) 7047 char *buf)
@@ -6795,6 +7075,7 @@ static DRIVER_ATTR(fan_watchdog, S_IWUSR | S_IRUGO,
6795static struct attribute *fan_attributes[] = { 7075static struct attribute *fan_attributes[] = {
6796 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr, 7076 &dev_attr_fan_pwm1_enable.attr, &dev_attr_fan_pwm1.attr,
6797 &dev_attr_fan_fan1_input.attr, 7077 &dev_attr_fan_fan1_input.attr,
7078 NULL, /* for fan2_input */
6798 NULL 7079 NULL
6799}; 7080};
6800 7081
@@ -6802,9 +7083,36 @@ static const struct attribute_group fan_attr_group = {
6802 .attrs = fan_attributes, 7083 .attrs = fan_attributes,
6803}; 7084};
6804 7085
7086#define TPACPI_FAN_Q1 0x0001 /* Unitialized HFSP */
7087#define TPACPI_FAN_2FAN 0x0002 /* EC 0x31 bit 0 selects fan2 */
7088
7089#define TPACPI_FAN_QI(__id1, __id2, __quirks) \
7090 { .vendor = PCI_VENDOR_ID_IBM, \
7091 .bios = TPACPI_MATCH_ANY, \
7092 .ec = TPID(__id1, __id2), \
7093 .quirks = __quirks }
7094
7095#define TPACPI_FAN_QL(__id1, __id2, __quirks) \
7096 { .vendor = PCI_VENDOR_ID_LENOVO, \
7097 .bios = TPACPI_MATCH_ANY, \
7098 .ec = TPID(__id1, __id2), \
7099 .quirks = __quirks }
7100
7101static const struct tpacpi_quirk fan_quirk_table[] __initconst = {
7102 TPACPI_FAN_QI('1', 'Y', TPACPI_FAN_Q1),
7103 TPACPI_FAN_QI('7', '8', TPACPI_FAN_Q1),
7104 TPACPI_FAN_QI('7', '6', TPACPI_FAN_Q1),
7105 TPACPI_FAN_QI('7', '0', TPACPI_FAN_Q1),
7106 TPACPI_FAN_QL('7', 'M', TPACPI_FAN_2FAN),
7107};
7108
7109#undef TPACPI_FAN_QL
7110#undef TPACPI_FAN_QI
7111
6805static int __init fan_init(struct ibm_init_struct *iibm) 7112static int __init fan_init(struct ibm_init_struct *iibm)
6806{ 7113{
6807 int rc; 7114 int rc;
7115 unsigned long quirks;
6808 7116
6809 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN, 7117 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
6810 "initializing fan subdriver\n"); 7118 "initializing fan subdriver\n");
@@ -6815,12 +7123,16 @@ static int __init fan_init(struct ibm_init_struct *iibm)
6815 fan_control_commands = 0; 7123 fan_control_commands = 0;
6816 fan_watchdog_maxinterval = 0; 7124 fan_watchdog_maxinterval = 0;
6817 tp_features.fan_ctrl_status_undef = 0; 7125 tp_features.fan_ctrl_status_undef = 0;
7126 tp_features.second_fan = 0;
6818 fan_control_desired_level = 7; 7127 fan_control_desired_level = 7;
6819 7128
6820 TPACPI_ACPIHANDLE_INIT(fans); 7129 TPACPI_ACPIHANDLE_INIT(fans);
6821 TPACPI_ACPIHANDLE_INIT(gfan); 7130 TPACPI_ACPIHANDLE_INIT(gfan);
6822 TPACPI_ACPIHANDLE_INIT(sfan); 7131 TPACPI_ACPIHANDLE_INIT(sfan);
6823 7132
7133 quirks = tpacpi_check_quirks(fan_quirk_table,
7134 ARRAY_SIZE(fan_quirk_table));
7135
6824 if (gfan_handle) { 7136 if (gfan_handle) {
6825 /* 570, 600e/x, 770e, 770x */ 7137 /* 570, 600e/x, 770e, 770x */
6826 fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN; 7138 fan_status_access_mode = TPACPI_FAN_RD_ACPI_GFAN;
@@ -6830,7 +7142,13 @@ static int __init fan_init(struct ibm_init_struct *iibm)
6830 if (likely(acpi_ec_read(fan_status_offset, 7142 if (likely(acpi_ec_read(fan_status_offset,
6831 &fan_control_initial_status))) { 7143 &fan_control_initial_status))) {
6832 fan_status_access_mode = TPACPI_FAN_RD_TPEC; 7144 fan_status_access_mode = TPACPI_FAN_RD_TPEC;
6833 fan_quirk1_detect(); 7145 if (quirks & TPACPI_FAN_Q1)
7146 fan_quirk1_setup();
7147 if (quirks & TPACPI_FAN_2FAN) {
7148 tp_features.second_fan = 1;
7149 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
7150 "secondary fan support enabled\n");
7151 }
6834 } else { 7152 } else {
6835 printk(TPACPI_ERR 7153 printk(TPACPI_ERR
6836 "ThinkPad ACPI EC access misbehaving, " 7154 "ThinkPad ACPI EC access misbehaving, "
@@ -6886,6 +7204,11 @@ static int __init fan_init(struct ibm_init_struct *iibm)
6886 7204
6887 if (fan_status_access_mode != TPACPI_FAN_NONE || 7205 if (fan_status_access_mode != TPACPI_FAN_NONE ||
6888 fan_control_access_mode != TPACPI_FAN_WR_NONE) { 7206 fan_control_access_mode != TPACPI_FAN_WR_NONE) {
7207 if (tp_features.second_fan) {
7208 /* attach second fan tachometer */
7209 fan_attributes[ARRAY_SIZE(fan_attributes)-2] =
7210 &dev_attr_fan_fan2_input.attr;
7211 }
6889 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, 7212 rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
6890 &fan_attr_group); 7213 &fan_attr_group);
6891 if (rc < 0) 7214 if (rc < 0)
@@ -7357,6 +7680,24 @@ err_out:
7357 7680
7358/* Probing */ 7681/* Probing */
7359 7682
7683static bool __pure __init tpacpi_is_fw_digit(const char c)
7684{
7685 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z');
7686}
7687
7688/* Most models: xxyTkkWW (#.##c); Ancient 570/600 and -SL lacks (#.##c) */
7689static bool __pure __init tpacpi_is_valid_fw_id(const char* const s,
7690 const char t)
7691{
7692 return s && strlen(s) >= 8 &&
7693 tpacpi_is_fw_digit(s[0]) &&
7694 tpacpi_is_fw_digit(s[1]) &&
7695 s[2] == t && s[3] == 'T' &&
7696 tpacpi_is_fw_digit(s[4]) &&
7697 tpacpi_is_fw_digit(s[5]) &&
7698 s[6] == 'W' && s[7] == 'W';
7699}
7700
7360/* returns 0 - probe ok, or < 0 - probe error. 7701/* returns 0 - probe ok, or < 0 - probe error.
7361 * Probe ok doesn't mean thinkpad found. 7702 * Probe ok doesn't mean thinkpad found.
7362 * On error, kfree() cleanup on tp->* is not performed, caller must do it */ 7703 * On error, kfree() cleanup on tp->* is not performed, caller must do it */
@@ -7383,10 +7724,15 @@ static int __must_check __init get_thinkpad_model_data(
7383 tp->bios_version_str = kstrdup(s, GFP_KERNEL); 7724 tp->bios_version_str = kstrdup(s, GFP_KERNEL);
7384 if (s && !tp->bios_version_str) 7725 if (s && !tp->bios_version_str)
7385 return -ENOMEM; 7726 return -ENOMEM;
7386 if (!tp->bios_version_str) 7727
7728 /* Really ancient ThinkPad 240X will fail this, which is fine */
7729 if (!tpacpi_is_valid_fw_id(tp->bios_version_str, 'E'))
7387 return 0; 7730 return 0;
7731
7388 tp->bios_model = tp->bios_version_str[0] 7732 tp->bios_model = tp->bios_version_str[0]
7389 | (tp->bios_version_str[1] << 8); 7733 | (tp->bios_version_str[1] << 8);
7734 tp->bios_release = (tp->bios_version_str[4] << 8)
7735 | tp->bios_version_str[5];
7390 7736
7391 /* 7737 /*
7392 * ThinkPad T23 or newer, A31 or newer, R50e or newer, 7738 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
@@ -7405,8 +7751,21 @@ static int __must_check __init get_thinkpad_model_data(
7405 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL); 7751 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
7406 if (!tp->ec_version_str) 7752 if (!tp->ec_version_str)
7407 return -ENOMEM; 7753 return -ENOMEM;
7408 tp->ec_model = ec_fw_string[0] 7754
7409 | (ec_fw_string[1] << 8); 7755 if (tpacpi_is_valid_fw_id(ec_fw_string, 'H')) {
7756 tp->ec_model = ec_fw_string[0]
7757 | (ec_fw_string[1] << 8);
7758 tp->ec_release = (ec_fw_string[4] << 8)
7759 | ec_fw_string[5];
7760 } else {
7761 printk(TPACPI_NOTICE
7762 "ThinkPad firmware release %s "
7763 "doesn't match the known patterns\n",
7764 ec_fw_string);
7765 printk(TPACPI_NOTICE
7766 "please report this to %s\n",
7767 TPACPI_MAIL);
7768 }
7410 break; 7769 break;
7411 } 7770 }
7412 } 7771 }
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 9f187265db8..81d31ea507d 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -45,7 +45,6 @@
45#include <linux/backlight.h> 45#include <linux/backlight.h>
46#include <linux/platform_device.h> 46#include <linux/platform_device.h>
47#include <linux/rfkill.h> 47#include <linux/rfkill.h>
48#include <linux/input-polldev.h>
49 48
50#include <asm/uaccess.h> 49#include <asm/uaccess.h>
51 50
@@ -250,21 +249,15 @@ static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result)
250 249
251struct toshiba_acpi_dev { 250struct toshiba_acpi_dev {
252 struct platform_device *p_dev; 251 struct platform_device *p_dev;
253 struct rfkill *rfk_dev; 252 struct rfkill *bt_rfk;
254 struct input_polled_dev *poll_dev;
255 253
256 const char *bt_name; 254 const char *bt_name;
257 const char *rfk_name;
258
259 bool last_rfk_state;
260 255
261 struct mutex mutex; 256 struct mutex mutex;
262}; 257};
263 258
264static struct toshiba_acpi_dev toshiba_acpi = { 259static struct toshiba_acpi_dev toshiba_acpi = {
265 .bt_name = "Toshiba Bluetooth", 260 .bt_name = "Toshiba Bluetooth",
266 .rfk_name = "Toshiba RFKill Switch",
267 .last_rfk_state = false,
268}; 261};
269 262
270/* Bluetooth rfkill handlers */ 263/* Bluetooth rfkill handlers */
@@ -283,21 +276,6 @@ static u32 hci_get_bt_present(bool *present)
283 return hci_result; 276 return hci_result;
284} 277}
285 278
286static u32 hci_get_bt_on(bool *on)
287{
288 u32 hci_result;
289 u32 value, value2;
290
291 value = 0;
292 value2 = 0x0001;
293 hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
294 if (hci_result == HCI_SUCCESS)
295 *on = (value & HCI_WIRELESS_BT_POWER) &&
296 (value & HCI_WIRELESS_BT_ATTACH);
297
298 return hci_result;
299}
300
301static u32 hci_get_radio_state(bool *radio_state) 279static u32 hci_get_radio_state(bool *radio_state)
302{ 280{
303 u32 hci_result; 281 u32 hci_result;
@@ -311,70 +289,67 @@ static u32 hci_get_radio_state(bool *radio_state)
311 return hci_result; 289 return hci_result;
312} 290}
313 291
314static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state) 292static int bt_rfkill_set_block(void *data, bool blocked)
315{ 293{
294 struct toshiba_acpi_dev *dev = data;
316 u32 result1, result2; 295 u32 result1, result2;
317 u32 value; 296 u32 value;
297 int err;
318 bool radio_state; 298 bool radio_state;
319 struct toshiba_acpi_dev *dev = data;
320 299
321 value = (state == RFKILL_STATE_UNBLOCKED); 300 value = (blocked == false);
322 301
323 if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) 302 mutex_lock(&dev->mutex);
324 return -EFAULT; 303 if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) {
304 err = -EBUSY;
305 goto out;
306 }
325 307
326 switch (state) { 308 if (!radio_state) {
327 case RFKILL_STATE_UNBLOCKED: 309 err = 0;
328 if (!radio_state) 310 goto out;
329 return -EPERM;
330 break;
331 case RFKILL_STATE_SOFT_BLOCKED:
332 break;
333 default:
334 return -EINVAL;
335 } 311 }
336 312
337 mutex_lock(&dev->mutex);
338 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1); 313 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1);
339 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2); 314 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2);
340 mutex_unlock(&dev->mutex);
341 315
342 if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS) 316 if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS)
343 return -EFAULT; 317 err = -EBUSY;
344 318 else
345 return 0; 319 err = 0;
320 out:
321 mutex_unlock(&dev->mutex);
322 return err;
346} 323}
347 324
348static void bt_poll_rfkill(struct input_polled_dev *poll_dev) 325static void bt_rfkill_poll(struct rfkill *rfkill, void *data)
349{ 326{
350 bool state_changed;
351 bool new_rfk_state; 327 bool new_rfk_state;
352 bool value; 328 bool value;
353 u32 hci_result; 329 u32 hci_result;
354 struct toshiba_acpi_dev *dev = poll_dev->private; 330 struct toshiba_acpi_dev *dev = data;
331
332 mutex_lock(&dev->mutex);
355 333
356 hci_result = hci_get_radio_state(&value); 334 hci_result = hci_get_radio_state(&value);
357 if (hci_result != HCI_SUCCESS) 335 if (hci_result != HCI_SUCCESS) {
358 return; /* Can't do anything useful */ 336 /* Can't do anything useful */
337 mutex_unlock(&dev->mutex);
338 }
359 339
360 new_rfk_state = value; 340 new_rfk_state = value;
361 341
362 mutex_lock(&dev->mutex);
363 state_changed = new_rfk_state != dev->last_rfk_state;
364 dev->last_rfk_state = new_rfk_state;
365 mutex_unlock(&dev->mutex); 342 mutex_unlock(&dev->mutex);
366 343
367 if (unlikely(state_changed)) { 344 if (rfkill_set_hw_state(rfkill, !new_rfk_state))
368 rfkill_force_state(dev->rfk_dev, 345 bt_rfkill_set_block(data, true);
369 new_rfk_state ?
370 RFKILL_STATE_SOFT_BLOCKED :
371 RFKILL_STATE_HARD_BLOCKED);
372 input_report_switch(poll_dev->input, SW_RFKILL_ALL,
373 new_rfk_state);
374 input_sync(poll_dev->input);
375 }
376} 346}
377 347
348static const struct rfkill_ops toshiba_rfk_ops = {
349 .set_block = bt_rfkill_set_block,
350 .poll = bt_rfkill_poll,
351};
352
378static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; 353static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
379static struct backlight_device *toshiba_backlight_device; 354static struct backlight_device *toshiba_backlight_device;
380static int force_fan; 355static int force_fan;
@@ -702,14 +677,11 @@ static struct backlight_ops toshiba_backlight_data = {
702 677
703static void toshiba_acpi_exit(void) 678static void toshiba_acpi_exit(void)
704{ 679{
705 if (toshiba_acpi.poll_dev) { 680 if (toshiba_acpi.bt_rfk) {
706 input_unregister_polled_device(toshiba_acpi.poll_dev); 681 rfkill_unregister(toshiba_acpi.bt_rfk);
707 input_free_polled_device(toshiba_acpi.poll_dev); 682 rfkill_destroy(toshiba_acpi.bt_rfk);
708 } 683 }
709 684
710 if (toshiba_acpi.rfk_dev)
711 rfkill_unregister(toshiba_acpi.rfk_dev);
712
713 if (toshiba_backlight_device) 685 if (toshiba_backlight_device)
714 backlight_device_unregister(toshiba_backlight_device); 686 backlight_device_unregister(toshiba_backlight_device);
715 687
@@ -728,8 +700,6 @@ static int __init toshiba_acpi_init(void)
728 acpi_status status = AE_OK; 700 acpi_status status = AE_OK;
729 u32 hci_result; 701 u32 hci_result;
730 bool bt_present; 702 bool bt_present;
731 bool bt_on;
732 bool radio_on;
733 int ret = 0; 703 int ret = 0;
734 704
735 if (acpi_disabled) 705 if (acpi_disabled)
@@ -793,61 +763,21 @@ static int __init toshiba_acpi_init(void)
793 763
794 /* Register rfkill switch for Bluetooth */ 764 /* Register rfkill switch for Bluetooth */
795 if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { 765 if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
796 toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev, 766 toshiba_acpi.bt_rfk = rfkill_alloc(toshiba_acpi.bt_name,
797 RFKILL_TYPE_BLUETOOTH); 767 &toshiba_acpi.p_dev->dev,
798 if (!toshiba_acpi.rfk_dev) { 768 RFKILL_TYPE_BLUETOOTH,
769 &toshiba_rfk_ops,
770 &toshiba_acpi);
771 if (!toshiba_acpi.bt_rfk) {
799 printk(MY_ERR "unable to allocate rfkill device\n"); 772 printk(MY_ERR "unable to allocate rfkill device\n");
800 toshiba_acpi_exit(); 773 toshiba_acpi_exit();
801 return -ENOMEM; 774 return -ENOMEM;
802 } 775 }
803 776
804 toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name; 777 ret = rfkill_register(toshiba_acpi.bt_rfk);
805 toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio;
806 toshiba_acpi.rfk_dev->user_claim_unsupported = 1;
807 toshiba_acpi.rfk_dev->data = &toshiba_acpi;
808
809 if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) {
810 toshiba_acpi.rfk_dev->state = RFKILL_STATE_UNBLOCKED;
811 } else if (hci_get_radio_state(&radio_on) == HCI_SUCCESS &&
812 radio_on) {
813 toshiba_acpi.rfk_dev->state = RFKILL_STATE_SOFT_BLOCKED;
814 } else {
815 toshiba_acpi.rfk_dev->state = RFKILL_STATE_HARD_BLOCKED;
816 }
817
818 ret = rfkill_register(toshiba_acpi.rfk_dev);
819 if (ret) { 778 if (ret) {
820 printk(MY_ERR "unable to register rfkill device\n"); 779 printk(MY_ERR "unable to register rfkill device\n");
821 toshiba_acpi_exit(); 780 rfkill_destroy(toshiba_acpi.bt_rfk);
822 return -ENOMEM;
823 }
824
825 /* Register input device for kill switch */
826 toshiba_acpi.poll_dev = input_allocate_polled_device();
827 if (!toshiba_acpi.poll_dev) {
828 printk(MY_ERR
829 "unable to allocate kill-switch input device\n");
830 toshiba_acpi_exit();
831 return -ENOMEM;
832 }
833 toshiba_acpi.poll_dev->private = &toshiba_acpi;
834 toshiba_acpi.poll_dev->poll = bt_poll_rfkill;
835 toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */
836
837 toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name;
838 toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST;
839 /* Toshiba USB ID */
840 toshiba_acpi.poll_dev->input->id.vendor = 0x0930;
841 set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit);
842 set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit);
843 input_report_switch(toshiba_acpi.poll_dev->input,
844 SW_RFKILL_ALL, TRUE);
845 input_sync(toshiba_acpi.poll_dev->input);
846
847 ret = input_register_polled_device(toshiba_acpi.poll_dev);
848 if (ret) {
849 printk(MY_ERR
850 "unable to register kill-switch input device\n");
851 toshiba_acpi_exit(); 781 toshiba_acpi_exit();
852 return ret; 782 return ret;
853 } 783 }