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.c876
-rw-r--r--drivers/platform/x86/toshiba_acpi.c160
11 files changed, 1466 insertions, 933 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 284ebaca6e45..5613483db141 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 e40c7bd1b87e..641b8bfa5538 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 0f6e43bf4fc2..be2fd6f91639 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 000000000000..bdfee177eefb
--- /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 af9f43021172..74909c4aaeea 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 2fab94162147..0f900cc9fa7a 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 353a898c3693..8153b3e59189 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 50d9019de2be..4ac2311c00af 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 552958545f94..dafaa4a92df5 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 27ca676a7092..a463fd72c495 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -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
@@ -1076,67 +1069,234 @@ static int __init tpacpi_check_std_acpi_brightness_support(void)
1076 return 0; 1069 return 0;
1077} 1070}
1078 1071
1079static int __init tpacpi_new_rfkill(const unsigned int id, 1072static void printk_deprecated_attribute(const char * const what,
1080 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,
1081 const enum rfkill_type rfktype, 1231 const enum rfkill_type rfktype,
1082 const char *name, 1232 const char *name,
1083 const bool set_default, 1233 const bool set_default)
1084 int (*toggle_radio)(void *, enum rfkill_state),
1085 int (*get_state)(void *, enum rfkill_state *))
1086{ 1234{
1235 struct tpacpi_rfk *atp_rfk;
1087 int res; 1236 int res;
1088 enum rfkill_state initial_state = RFKILL_STATE_SOFT_BLOCKED; 1237 bool sw_state = false;
1089 1238 int sw_status;
1090 res = get_state(NULL, &initial_state); 1239
1091 if (res < 0) { 1240 BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
1092 printk(TPACPI_ERR 1241
1093 "failed to read initial state for %s, error %d; " 1242 atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL);
1094 "will turn radio off\n", name, res); 1243 if (atp_rfk)
1095 } else if (set_default) { 1244 atp_rfk->rfkill = rfkill_alloc(name,
1096 /* try to set the initial state as the default for the rfkill 1245 &tpacpi_pdev->dev,
1097 * type, since we ask the firmware to preserve it across S5 in 1246 rfktype,
1098 * NVRAM */ 1247 &tpacpi_rfk_rfkill_ops,
1099 if (rfkill_set_default(rfktype, 1248 atp_rfk);
1100 (initial_state == RFKILL_STATE_UNBLOCKED) ? 1249 if (!atp_rfk || !atp_rfk->rfkill) {
1101 RFKILL_STATE_UNBLOCKED :
1102 RFKILL_STATE_SOFT_BLOCKED) == -EPERM)
1103 vdbg_printk(TPACPI_DBG_RFKILL,
1104 "Default state for %s cannot be changed\n",
1105 name);
1106 }
1107
1108 *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
1109 if (!*rfk) {
1110 printk(TPACPI_ERR 1250 printk(TPACPI_ERR
1111 "failed to allocate memory for rfkill class\n"); 1251 "failed to allocate memory for rfkill class\n");
1252 kfree(atp_rfk);
1112 return -ENOMEM; 1253 return -ENOMEM;
1113 } 1254 }
1114 1255
1115 (*rfk)->name = name; 1256 atp_rfk->id = id;
1116 (*rfk)->get_state = get_state; 1257 atp_rfk->ops = tp_rfkops;
1117 (*rfk)->toggle_radio = toggle_radio; 1258
1118 (*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());
1119 1273
1120 res = rfkill_register(*rfk); 1274 res = rfkill_register(atp_rfk->rfkill);
1121 if (res < 0) { 1275 if (res < 0) {
1122 printk(TPACPI_ERR 1276 printk(TPACPI_ERR
1123 "failed to register %s rfkill switch: %d\n", 1277 "failed to register %s rfkill switch: %d\n",
1124 name, res); 1278 name, res);
1125 rfkill_free(*rfk); 1279 rfkill_destroy(atp_rfk->rfkill);
1126 *rfk = NULL; 1280 kfree(atp_rfk);
1127 return res; 1281 return res;
1128 } 1282 }
1129 1283
1284 tpacpi_rfkill_switches[id] = atp_rfk;
1130 return 0; 1285 return 0;
1131} 1286}
1132 1287
1133static void printk_deprecated_attribute(const char * const what, 1288static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id)
1134 const char * const details)
1135{ 1289{
1136 tpacpi_log_usertask("deprecated sysfs attribute"); 1290 struct tpacpi_rfk *tp_rfk;
1137 printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " 1291
1138 "will be removed. %s\n", 1292 BUG_ON(id >= TPACPI_RFK_SW_MAX);
1139 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 }
1140} 1300}
1141 1301
1142static void printk_deprecated_rfkill_attribute(const char * const what) 1302static void printk_deprecated_rfkill_attribute(const char * const what)
@@ -1145,6 +1305,112 @@ static void printk_deprecated_rfkill_attribute(const char * const what)
1145 "Please switch to generic rfkill before year 2010"); 1305 "Please switch to generic rfkill before year 2010");
1146} 1306}
1147 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
1148/************************************************************************* 1414/*************************************************************************
1149 * thinkpad-acpi driver attributes 1415 * thinkpad-acpi driver attributes
1150 */ 1416 */
@@ -1198,8 +1464,6 @@ static DRIVER_ATTR(version, S_IRUGO,
1198 1464
1199#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1465#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1200 1466
1201static void tpacpi_send_radiosw_update(void);
1202
1203/* wlsw_emulstate ------------------------------------------------------ */ 1467/* wlsw_emulstate ------------------------------------------------------ */
1204static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv, 1468static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv,
1205 char *buf) 1469 char *buf)
@@ -1215,11 +1479,10 @@ static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv,
1215 if (parse_strtoul(buf, 1, &t)) 1479 if (parse_strtoul(buf, 1, &t))
1216 return -EINVAL; 1480 return -EINVAL;
1217 1481
1218 if (tpacpi_wlsw_emulstate != t) { 1482 if (tpacpi_wlsw_emulstate != !!t) {
1219 tpacpi_wlsw_emulstate = !!t;
1220 tpacpi_send_radiosw_update();
1221 } else
1222 tpacpi_wlsw_emulstate = !!t; 1483 tpacpi_wlsw_emulstate = !!t;
1484 tpacpi_rfk_update_hwblock_state(!t); /* negative logic */
1485 }
1223 1486
1224 return count; 1487 return count;
1225} 1488}
@@ -1534,17 +1797,23 @@ static struct attribute_set *hotkey_dev_attributes;
1534/* HKEY.MHKG() return bits */ 1797/* HKEY.MHKG() return bits */
1535#define TP_HOTKEY_TABLET_MASK (1 << 3) 1798#define TP_HOTKEY_TABLET_MASK (1 << 3)
1536 1799
1537static int hotkey_get_wlsw(int *status) 1800static int hotkey_get_wlsw(void)
1538{ 1801{
1802 int status;
1803
1804 if (!tp_features.hotkey_wlsw)
1805 return -ENODEV;
1806
1539#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1807#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1540 if (dbg_wlswemul) { 1808 if (dbg_wlswemul)
1541 *status = !!tpacpi_wlsw_emulstate; 1809 return (tpacpi_wlsw_emulstate) ?
1542 return 0; 1810 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
1543 }
1544#endif 1811#endif
1545 if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) 1812
1813 if (!acpi_evalf(hkey_handle, &status, "WLSW", "d"))
1546 return -EIO; 1814 return -EIO;
1547 return 0; 1815
1816 return (status) ? TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
1548} 1817}
1549 1818
1550static int hotkey_get_tablet_mode(int *status) 1819static int hotkey_get_tablet_mode(int *status)
@@ -2178,12 +2447,16 @@ static ssize_t hotkey_radio_sw_show(struct device *dev,
2178 struct device_attribute *attr, 2447 struct device_attribute *attr,
2179 char *buf) 2448 char *buf)
2180{ 2449{
2181 int res, s; 2450 int res;
2182 res = hotkey_get_wlsw(&s); 2451 res = hotkey_get_wlsw();
2183 if (res < 0) 2452 if (res < 0)
2184 return res; 2453 return res;
2185 2454
2186 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);
2187} 2460}
2188 2461
2189static struct device_attribute dev_attr_hotkey_radio_sw = 2462static struct device_attribute dev_attr_hotkey_radio_sw =
@@ -2294,30 +2567,52 @@ static struct attribute *hotkey_mask_attributes[] __initdata = {
2294 &dev_attr_hotkey_wakeup_hotunplug_complete.attr, 2567 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2295}; 2568};
2296 2569
2297static void bluetooth_update_rfk(void); 2570/*
2298static void wan_update_rfk(void); 2571 * Sync both the hw and sw blocking state of all switches
2299static void uwb_update_rfk(void); 2572 */
2300static void tpacpi_send_radiosw_update(void) 2573static void tpacpi_send_radiosw_update(void)
2301{ 2574{
2302 int wlsw; 2575 int wlsw;
2303 2576
2304 /* Sync these BEFORE sending any rfkill events */ 2577 /*
2305 if (tp_features.bluetooth) 2578 * We must sync all rfkill controllers *before* issuing any
2306 bluetooth_update_rfk(); 2579 * rfkill input events, or we will race the rfkill core input
2307 if (tp_features.wan) 2580 * handler.
2308 wan_update_rfk(); 2581 *
2309 if (tp_features.uwb) 2582 * tpacpi_inputdev_send_mutex works as a syncronization point
2310 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);
2311 2593
2312 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { 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);
2600
2601 /* Issue rfkill input event for WLSW switch */
2602 if (!(wlsw < 0)) {
2313 mutex_lock(&tpacpi_inputdev_send_mutex); 2603 mutex_lock(&tpacpi_inputdev_send_mutex);
2314 2604
2315 input_report_switch(tpacpi_inputdev, 2605 input_report_switch(tpacpi_inputdev,
2316 SW_RFKILL_ALL, !!wlsw); 2606 SW_RFKILL_ALL, (wlsw > 0));
2317 input_sync(tpacpi_inputdev); 2607 input_sync(tpacpi_inputdev);
2318 2608
2319 mutex_unlock(&tpacpi_inputdev_send_mutex); 2609 mutex_unlock(&tpacpi_inputdev_send_mutex);
2320 } 2610 }
2611
2612 /*
2613 * this can be unconditional, as we will poll state again
2614 * if userspace uses the notify to read data
2615 */
2321 hotkey_radio_sw_notify_change(); 2616 hotkey_radio_sw_notify_change();
2322} 2617}
2323 2618
@@ -3127,8 +3422,6 @@ enum {
3127 3422
3128#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" 3423#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
3129 3424
3130static struct rfkill *tpacpi_bluetooth_rfkill;
3131
3132static void bluetooth_suspend(pm_message_t state) 3425static void bluetooth_suspend(pm_message_t state)
3133{ 3426{
3134 /* Try to make sure radio will resume powered off */ 3427 /* Try to make sure radio will resume powered off */
@@ -3138,83 +3431,47 @@ static void bluetooth_suspend(pm_message_t state)
3138 "bluetooth power down on resume request failed\n"); 3431 "bluetooth power down on resume request failed\n");
3139} 3432}
3140 3433
3141static int bluetooth_get_radiosw(void) 3434static int bluetooth_get_status(void)
3142{ 3435{
3143 int status; 3436 int status;
3144 3437
3145 if (!tp_features.bluetooth)
3146 return -ENODEV;
3147
3148 /* WLSW overrides bluetooth in firmware/hardware, reflect that */
3149 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3150 return RFKILL_STATE_HARD_BLOCKED;
3151
3152#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3438#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3153 if (dbg_bluetoothemul) 3439 if (dbg_bluetoothemul)
3154 return (tpacpi_bluetooth_emulstate) ? 3440 return (tpacpi_bluetooth_emulstate) ?
3155 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3441 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3156#endif 3442#endif
3157 3443
3158 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 3444 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
3159 return -EIO; 3445 return -EIO;
3160 3446
3161 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ? 3447 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ?
3162 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3448 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3163}
3164
3165static void bluetooth_update_rfk(void)
3166{
3167 int status;
3168
3169 if (!tpacpi_bluetooth_rfkill)
3170 return;
3171
3172 status = bluetooth_get_radiosw();
3173 if (status < 0)
3174 return;
3175 rfkill_force_state(tpacpi_bluetooth_rfkill, status);
3176
3177 vdbg_printk(TPACPI_DBG_RFKILL,
3178 "forced rfkill state to %d\n",
3179 status);
3180} 3449}
3181 3450
3182static int bluetooth_set_radiosw(int radio_on, int update_rfk) 3451static int bluetooth_set_status(enum tpacpi_rfkill_state state)
3183{ 3452{
3184 int status; 3453 int status;
3185 3454
3186 if (!tp_features.bluetooth)
3187 return -ENODEV;
3188
3189 /* WLSW overrides bluetooth in firmware/hardware, but there is no
3190 * reason to risk weird behaviour. */
3191 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3192 && radio_on)
3193 return -EPERM;
3194
3195 vdbg_printk(TPACPI_DBG_RFKILL, 3455 vdbg_printk(TPACPI_DBG_RFKILL,
3196 "will %s bluetooth\n", radio_on ? "enable" : "disable"); 3456 "will attempt to %s bluetooth\n",
3457 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3197 3458
3198#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3459#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3199 if (dbg_bluetoothemul) { 3460 if (dbg_bluetoothemul) {
3200 tpacpi_bluetooth_emulstate = !!radio_on; 3461 tpacpi_bluetooth_emulstate = (state == TPACPI_RFK_RADIO_ON);
3201 if (update_rfk)
3202 bluetooth_update_rfk();
3203 return 0; 3462 return 0;
3204 } 3463 }
3205#endif 3464#endif
3206 3465
3207 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ 3466 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
3208 if (radio_on) 3467 if (state == TPACPI_RFK_RADIO_ON)
3209 status = TP_ACPI_BLUETOOTH_RADIOSSW; 3468 status = TP_ACPI_BLUETOOTH_RADIOSSW;
3210 else 3469 else
3211 status = 0; 3470 status = 0;
3471
3212 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) 3472 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
3213 return -EIO; 3473 return -EIO;
3214 3474
3215 if (update_rfk)
3216 bluetooth_update_rfk();
3217
3218 return 0; 3475 return 0;
3219} 3476}
3220 3477
@@ -3223,35 +3480,16 @@ static ssize_t bluetooth_enable_show(struct device *dev,
3223 struct device_attribute *attr, 3480 struct device_attribute *attr,
3224 char *buf) 3481 char *buf)
3225{ 3482{
3226 int status; 3483 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_BLUETOOTH_SW_ID,
3227 3484 attr, buf);
3228 printk_deprecated_rfkill_attribute("bluetooth_enable");
3229
3230 status = bluetooth_get_radiosw();
3231 if (status < 0)
3232 return status;
3233
3234 return snprintf(buf, PAGE_SIZE, "%d\n",
3235 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
3236} 3485}
3237 3486
3238static ssize_t bluetooth_enable_store(struct device *dev, 3487static ssize_t bluetooth_enable_store(struct device *dev,
3239 struct device_attribute *attr, 3488 struct device_attribute *attr,
3240 const char *buf, size_t count) 3489 const char *buf, size_t count)
3241{ 3490{
3242 unsigned long t; 3491 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_BLUETOOTH_SW_ID,
3243 int res; 3492 attr, buf, count);
3244
3245 printk_deprecated_rfkill_attribute("bluetooth_enable");
3246
3247 if (parse_strtoul(buf, 1, &t))
3248 return -EINVAL;
3249
3250 tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
3251
3252 res = bluetooth_set_radiosw(t, 1);
3253
3254 return (res) ? res : count;
3255} 3493}
3256 3494
3257static struct device_attribute dev_attr_bluetooth_enable = 3495static struct device_attribute dev_attr_bluetooth_enable =
@@ -3269,23 +3507,10 @@ static const struct attribute_group bluetooth_attr_group = {
3269 .attrs = bluetooth_attributes, 3507 .attrs = bluetooth_attributes,
3270}; 3508};
3271 3509
3272static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state) 3510static const struct tpacpi_rfk_ops bluetooth_tprfk_ops = {
3273{ 3511 .get_status = bluetooth_get_status,
3274 int bts = bluetooth_get_radiosw(); 3512 .set_status = bluetooth_set_status,
3275 3513};
3276 if (bts < 0)
3277 return bts;
3278
3279 *state = bts;
3280 return 0;
3281}
3282
3283static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
3284{
3285 dbg_printk(TPACPI_DBG_RFKILL,
3286 "request to change radio state to %d\n", state);
3287 return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3288}
3289 3514
3290static void bluetooth_shutdown(void) 3515static void bluetooth_shutdown(void)
3291{ 3516{
@@ -3301,13 +3526,12 @@ static void bluetooth_shutdown(void)
3301 3526
3302static void bluetooth_exit(void) 3527static void bluetooth_exit(void)
3303{ 3528{
3304 bluetooth_shutdown();
3305
3306 if (tpacpi_bluetooth_rfkill)
3307 rfkill_unregister(tpacpi_bluetooth_rfkill);
3308
3309 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3529 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3310 &bluetooth_attr_group); 3530 &bluetooth_attr_group);
3531
3532 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
3533
3534 bluetooth_shutdown();
3311} 3535}
3312 3536
3313static int __init bluetooth_init(struct ibm_init_struct *iibm) 3537static int __init bluetooth_init(struct ibm_init_struct *iibm)
@@ -3348,20 +3572,18 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3348 if (!tp_features.bluetooth) 3572 if (!tp_features.bluetooth)
3349 return 1; 3573 return 1;
3350 3574
3351 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3352 &bluetooth_attr_group);
3353 if (res)
3354 return res;
3355
3356 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, 3575 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
3357 &tpacpi_bluetooth_rfkill, 3576 &bluetooth_tprfk_ops,
3358 RFKILL_TYPE_BLUETOOTH, 3577 RFKILL_TYPE_BLUETOOTH,
3359 TPACPI_RFK_BLUETOOTH_SW_NAME, 3578 TPACPI_RFK_BLUETOOTH_SW_NAME,
3360 true, 3579 true);
3361 tpacpi_bluetooth_rfk_set, 3580 if (res)
3362 tpacpi_bluetooth_rfk_get); 3581 return res;
3582
3583 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3584 &bluetooth_attr_group);
3363 if (res) { 3585 if (res) {
3364 bluetooth_exit(); 3586 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
3365 return res; 3587 return res;
3366 } 3588 }
3367 3589
@@ -3371,46 +3593,12 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3371/* procfs -------------------------------------------------------------- */ 3593/* procfs -------------------------------------------------------------- */
3372static int bluetooth_read(char *p) 3594static int bluetooth_read(char *p)
3373{ 3595{
3374 int len = 0; 3596 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, p);
3375 int status = bluetooth_get_radiosw();
3376
3377 if (!tp_features.bluetooth)
3378 len += sprintf(p + len, "status:\t\tnot supported\n");
3379 else {
3380 len += sprintf(p + len, "status:\t\t%s\n",
3381 (status == RFKILL_STATE_UNBLOCKED) ?
3382 "enabled" : "disabled");
3383 len += sprintf(p + len, "commands:\tenable, disable\n");
3384 }
3385
3386 return len;
3387} 3597}
3388 3598
3389static int bluetooth_write(char *buf) 3599static int bluetooth_write(char *buf)
3390{ 3600{
3391 char *cmd; 3601 return tpacpi_rfk_procfs_write(TPACPI_RFK_BLUETOOTH_SW_ID, buf);
3392 int state = -1;
3393
3394 if (!tp_features.bluetooth)
3395 return -ENODEV;
3396
3397 while ((cmd = next_cmd(&buf))) {
3398 if (strlencmp(cmd, "enable") == 0) {
3399 state = 1;
3400 } else if (strlencmp(cmd, "disable") == 0) {
3401 state = 0;
3402 } else
3403 return -EINVAL;
3404 }
3405
3406 if (state != -1) {
3407 tpacpi_disclose_usertask("procfs bluetooth",
3408 "attempt to %s\n",
3409 state ? "enable" : "disable");
3410 bluetooth_set_radiosw(state, 1);
3411 }
3412
3413 return 0;
3414} 3602}
3415 3603
3416static struct ibm_struct bluetooth_driver_data = { 3604static struct ibm_struct bluetooth_driver_data = {
@@ -3436,8 +3624,6 @@ enum {
3436 3624
3437#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" 3625#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
3438 3626
3439static struct rfkill *tpacpi_wan_rfkill;
3440
3441static void wan_suspend(pm_message_t state) 3627static void wan_suspend(pm_message_t state)
3442{ 3628{
3443 /* Try to make sure radio will resume powered off */ 3629 /* Try to make sure radio will resume powered off */
@@ -3447,83 +3633,47 @@ static void wan_suspend(pm_message_t state)
3447 "WWAN power down on resume request failed\n"); 3633 "WWAN power down on resume request failed\n");
3448} 3634}
3449 3635
3450static int wan_get_radiosw(void) 3636static int wan_get_status(void)
3451{ 3637{
3452 int status; 3638 int status;
3453 3639
3454 if (!tp_features.wan)
3455 return -ENODEV;
3456
3457 /* WLSW overrides WWAN in firmware/hardware, reflect that */
3458 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3459 return RFKILL_STATE_HARD_BLOCKED;
3460
3461#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3640#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3462 if (dbg_wwanemul) 3641 if (dbg_wwanemul)
3463 return (tpacpi_wwan_emulstate) ? 3642 return (tpacpi_wwan_emulstate) ?
3464 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3643 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3465#endif 3644#endif
3466 3645
3467 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 3646 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
3468 return -EIO; 3647 return -EIO;
3469 3648
3470 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ? 3649 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ?
3471 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3650 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3472}
3473
3474static void wan_update_rfk(void)
3475{
3476 int status;
3477
3478 if (!tpacpi_wan_rfkill)
3479 return;
3480
3481 status = wan_get_radiosw();
3482 if (status < 0)
3483 return;
3484 rfkill_force_state(tpacpi_wan_rfkill, status);
3485
3486 vdbg_printk(TPACPI_DBG_RFKILL,
3487 "forced rfkill state to %d\n",
3488 status);
3489} 3651}
3490 3652
3491static int wan_set_radiosw(int radio_on, int update_rfk) 3653static int wan_set_status(enum tpacpi_rfkill_state state)
3492{ 3654{
3493 int status; 3655 int status;
3494 3656
3495 if (!tp_features.wan)
3496 return -ENODEV;
3497
3498 /* WLSW overrides bluetooth in firmware/hardware, but there is no
3499 * reason to risk weird behaviour. */
3500 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3501 && radio_on)
3502 return -EPERM;
3503
3504 vdbg_printk(TPACPI_DBG_RFKILL, 3657 vdbg_printk(TPACPI_DBG_RFKILL,
3505 "will %s WWAN\n", radio_on ? "enable" : "disable"); 3658 "will attempt to %s wwan\n",
3659 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3506 3660
3507#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3661#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3508 if (dbg_wwanemul) { 3662 if (dbg_wwanemul) {
3509 tpacpi_wwan_emulstate = !!radio_on; 3663 tpacpi_wwan_emulstate = (state == TPACPI_RFK_RADIO_ON);
3510 if (update_rfk)
3511 wan_update_rfk();
3512 return 0; 3664 return 0;
3513 } 3665 }
3514#endif 3666#endif
3515 3667
3516 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ 3668 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */
3517 if (radio_on) 3669 if (state == TPACPI_RFK_RADIO_ON)
3518 status = TP_ACPI_WANCARD_RADIOSSW; 3670 status = TP_ACPI_WANCARD_RADIOSSW;
3519 else 3671 else
3520 status = 0; 3672 status = 0;
3673
3521 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) 3674 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
3522 return -EIO; 3675 return -EIO;
3523 3676
3524 if (update_rfk)
3525 wan_update_rfk();
3526
3527 return 0; 3677 return 0;
3528} 3678}
3529 3679
@@ -3532,35 +3682,16 @@ static ssize_t wan_enable_show(struct device *dev,
3532 struct device_attribute *attr, 3682 struct device_attribute *attr,
3533 char *buf) 3683 char *buf)
3534{ 3684{
3535 int status; 3685 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_WWAN_SW_ID,
3536 3686 attr, buf);
3537 printk_deprecated_rfkill_attribute("wwan_enable");
3538
3539 status = wan_get_radiosw();
3540 if (status < 0)
3541 return status;
3542
3543 return snprintf(buf, PAGE_SIZE, "%d\n",
3544 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
3545} 3687}
3546 3688
3547static ssize_t wan_enable_store(struct device *dev, 3689static ssize_t wan_enable_store(struct device *dev,
3548 struct device_attribute *attr, 3690 struct device_attribute *attr,
3549 const char *buf, size_t count) 3691 const char *buf, size_t count)
3550{ 3692{
3551 unsigned long t; 3693 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_WWAN_SW_ID,
3552 int res; 3694 attr, buf, count);
3553
3554 printk_deprecated_rfkill_attribute("wwan_enable");
3555
3556 if (parse_strtoul(buf, 1, &t))
3557 return -EINVAL;
3558
3559 tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
3560
3561 res = wan_set_radiosw(t, 1);
3562
3563 return (res) ? res : count;
3564} 3695}
3565 3696
3566static struct device_attribute dev_attr_wan_enable = 3697static struct device_attribute dev_attr_wan_enable =
@@ -3578,23 +3709,10 @@ static const struct attribute_group wan_attr_group = {
3578 .attrs = wan_attributes, 3709 .attrs = wan_attributes,
3579}; 3710};
3580 3711
3581static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state) 3712static const struct tpacpi_rfk_ops wan_tprfk_ops = {
3582{ 3713 .get_status = wan_get_status,
3583 int wans = wan_get_radiosw(); 3714 .set_status = wan_set_status,
3584 3715};
3585 if (wans < 0)
3586 return wans;
3587
3588 *state = wans;
3589 return 0;
3590}
3591
3592static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
3593{
3594 dbg_printk(TPACPI_DBG_RFKILL,
3595 "request to change radio state to %d\n", state);
3596 return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3597}
3598 3716
3599static void wan_shutdown(void) 3717static void wan_shutdown(void)
3600{ 3718{
@@ -3610,13 +3728,12 @@ static void wan_shutdown(void)
3610 3728
3611static void wan_exit(void) 3729static void wan_exit(void)
3612{ 3730{
3613 wan_shutdown();
3614
3615 if (tpacpi_wan_rfkill)
3616 rfkill_unregister(tpacpi_wan_rfkill);
3617
3618 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3731 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3619 &wan_attr_group); 3732 &wan_attr_group);
3733
3734 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
3735
3736 wan_shutdown();
3620} 3737}
3621 3738
3622static int __init wan_init(struct ibm_init_struct *iibm) 3739static int __init wan_init(struct ibm_init_struct *iibm)
@@ -3655,20 +3772,19 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3655 if (!tp_features.wan) 3772 if (!tp_features.wan)
3656 return 1; 3773 return 1;
3657 3774
3658 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3659 &wan_attr_group);
3660 if (res)
3661 return res;
3662
3663 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, 3775 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
3664 &tpacpi_wan_rfkill, 3776 &wan_tprfk_ops,
3665 RFKILL_TYPE_WWAN, 3777 RFKILL_TYPE_WWAN,
3666 TPACPI_RFK_WWAN_SW_NAME, 3778 TPACPI_RFK_WWAN_SW_NAME,
3667 true, 3779 true);
3668 tpacpi_wan_rfk_set, 3780 if (res)
3669 tpacpi_wan_rfk_get); 3781 return res;
3782
3783 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3784 &wan_attr_group);
3785
3670 if (res) { 3786 if (res) {
3671 wan_exit(); 3787 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
3672 return res; 3788 return res;
3673 } 3789 }
3674 3790
@@ -3678,48 +3794,12 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3678/* procfs -------------------------------------------------------------- */ 3794/* procfs -------------------------------------------------------------- */
3679static int wan_read(char *p) 3795static int wan_read(char *p)
3680{ 3796{
3681 int len = 0; 3797 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, p);
3682 int status = wan_get_radiosw();
3683
3684 tpacpi_disclose_usertask("procfs wan", "read");
3685
3686 if (!tp_features.wan)
3687 len += sprintf(p + len, "status:\t\tnot supported\n");
3688 else {
3689 len += sprintf(p + len, "status:\t\t%s\n",
3690 (status == RFKILL_STATE_UNBLOCKED) ?
3691 "enabled" : "disabled");
3692 len += sprintf(p + len, "commands:\tenable, disable\n");
3693 }
3694
3695 return len;
3696} 3798}
3697 3799
3698static int wan_write(char *buf) 3800static int wan_write(char *buf)
3699{ 3801{
3700 char *cmd; 3802 return tpacpi_rfk_procfs_write(TPACPI_RFK_WWAN_SW_ID, buf);
3701 int state = -1;
3702
3703 if (!tp_features.wan)
3704 return -ENODEV;
3705
3706 while ((cmd = next_cmd(&buf))) {
3707 if (strlencmp(cmd, "enable") == 0) {
3708 state = 1;
3709 } else if (strlencmp(cmd, "disable") == 0) {
3710 state = 0;
3711 } else
3712 return -EINVAL;
3713 }
3714
3715 if (state != -1) {
3716 tpacpi_disclose_usertask("procfs wan",
3717 "attempt to %s\n",
3718 state ? "enable" : "disable");
3719 wan_set_radiosw(state, 1);
3720 }
3721
3722 return 0;
3723} 3803}
3724 3804
3725static struct ibm_struct wan_driver_data = { 3805static struct ibm_struct wan_driver_data = {
@@ -3743,108 +3823,59 @@ enum {
3743 3823
3744#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw" 3824#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
3745 3825
3746static struct rfkill *tpacpi_uwb_rfkill; 3826static int uwb_get_status(void)
3747
3748static int uwb_get_radiosw(void)
3749{ 3827{
3750 int status; 3828 int status;
3751 3829
3752 if (!tp_features.uwb)
3753 return -ENODEV;
3754
3755 /* WLSW overrides UWB in firmware/hardware, reflect that */
3756 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3757 return RFKILL_STATE_HARD_BLOCKED;
3758
3759#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3830#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3760 if (dbg_uwbemul) 3831 if (dbg_uwbemul)
3761 return (tpacpi_uwb_emulstate) ? 3832 return (tpacpi_uwb_emulstate) ?
3762 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3833 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3763#endif 3834#endif
3764 3835
3765 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d")) 3836 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d"))
3766 return -EIO; 3837 return -EIO;
3767 3838
3768 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ? 3839 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ?
3769 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3840 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3770} 3841}
3771 3842
3772static void uwb_update_rfk(void) 3843static int uwb_set_status(enum tpacpi_rfkill_state state)
3773{ 3844{
3774 int status; 3845 int status;
3775 3846
3776 if (!tpacpi_uwb_rfkill)
3777 return;
3778
3779 status = uwb_get_radiosw();
3780 if (status < 0)
3781 return;
3782 rfkill_force_state(tpacpi_uwb_rfkill, status);
3783
3784 vdbg_printk(TPACPI_DBG_RFKILL, 3847 vdbg_printk(TPACPI_DBG_RFKILL,
3785 "forced rfkill state to %d\n", 3848 "will attempt to %s UWB\n",
3786 status); 3849 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3787}
3788
3789static int uwb_set_radiosw(int radio_on, int update_rfk)
3790{
3791 int status;
3792
3793 if (!tp_features.uwb)
3794 return -ENODEV;
3795
3796 /* WLSW overrides UWB in firmware/hardware, but there is no
3797 * reason to risk weird behaviour. */
3798 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3799 && radio_on)
3800 return -EPERM;
3801
3802 vdbg_printk(TPACPI_DBG_RFKILL,
3803 "will %s UWB\n", radio_on ? "enable" : "disable");
3804 3850
3805#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3851#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3806 if (dbg_uwbemul) { 3852 if (dbg_uwbemul) {
3807 tpacpi_uwb_emulstate = !!radio_on; 3853 tpacpi_uwb_emulstate = (state == TPACPI_RFK_RADIO_ON);
3808 if (update_rfk)
3809 uwb_update_rfk();
3810 return 0; 3854 return 0;
3811 } 3855 }
3812#endif 3856#endif
3813 3857
3814 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
3815 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status)) 3863 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status))
3816 return -EIO; 3864 return -EIO;
3817 3865
3818 if (update_rfk)
3819 uwb_update_rfk();
3820
3821 return 0; 3866 return 0;
3822} 3867}
3823 3868
3824/* --------------------------------------------------------------------- */ 3869/* --------------------------------------------------------------------- */
3825 3870
3826static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state) 3871static const struct tpacpi_rfk_ops uwb_tprfk_ops = {
3827{ 3872 .get_status = uwb_get_status,
3828 int uwbs = uwb_get_radiosw(); 3873 .set_status = uwb_set_status,
3829 3874};
3830 if (uwbs < 0)
3831 return uwbs;
3832
3833 *state = uwbs;
3834 return 0;
3835}
3836
3837static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
3838{
3839 dbg_printk(TPACPI_DBG_RFKILL,
3840 "request to change radio state to %d\n", state);
3841 return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3842}
3843 3875
3844static void uwb_exit(void) 3876static void uwb_exit(void)
3845{ 3877{
3846 if (tpacpi_uwb_rfkill) 3878 tpacpi_destroy_rfkill(TPACPI_RFK_UWB_SW_ID);
3847 rfkill_unregister(tpacpi_uwb_rfkill);
3848} 3879}
3849 3880
3850static int __init uwb_init(struct ibm_init_struct *iibm) 3881static int __init uwb_init(struct ibm_init_struct *iibm)
@@ -3884,13 +3915,10 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
3884 return 1; 3915 return 1;
3885 3916
3886 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, 3917 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
3887 &tpacpi_uwb_rfkill, 3918 &uwb_tprfk_ops,
3888 RFKILL_TYPE_UWB, 3919 RFKILL_TYPE_UWB,
3889 TPACPI_RFK_UWB_SW_NAME, 3920 TPACPI_RFK_UWB_SW_NAME,
3890 false, 3921 false);
3891 tpacpi_uwb_rfk_set,
3892 tpacpi_uwb_rfk_get);
3893
3894 return res; 3922 return res;
3895} 3923}
3896 3924
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 9f187265db8e..81d31ea507d1 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 }