diff options
author | Len Brown <len.brown@intel.com> | 2008-10-22 23:57:26 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-10-23 00:11:07 -0400 |
commit | 057316cc6a5b521b332a1d7ccc871cd60c904c74 (patch) | |
tree | 4333e608da237c73ff69b10878025cca96dcb4c8 /drivers/acpi | |
parent | 3e2dab9a1c2deb03c311eb3f83466009147ed4d3 (diff) | |
parent | 2515ddc6db8eb49a79f0fe5e67ff09ac7c81eab4 (diff) |
Merge branch 'linus' into test
Conflicts:
MAINTAINERS
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/acpi/sleep.c
drivers/acpi/Kconfig
drivers/pnp/Makefile
drivers/pnp/quirks.c
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/Kconfig | 3 | ||||
-rw-r--r-- | drivers/acpi/battery.c | 2 | ||||
-rw-r--r-- | drivers/acpi/glue.c | 113 | ||||
-rw-r--r-- | drivers/acpi/sbs.c | 2 | ||||
-rw-r--r-- | drivers/acpi/sleep/proc.c | 18 | ||||
-rw-r--r-- | drivers/acpi/system.c | 1 | ||||
-rw-r--r-- | drivers/acpi/toshiba_acpi.c | 261 |
7 files changed, 267 insertions, 133 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index cbfc58d60236..dc1de7224426 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -253,6 +253,9 @@ config ACPI_ASUS | |||
253 | config ACPI_TOSHIBA | 253 | config ACPI_TOSHIBA |
254 | tristate "Toshiba Laptop Extras" | 254 | tristate "Toshiba Laptop Extras" |
255 | depends on X86 && INPUT | 255 | depends on X86 && INPUT |
256 | select INPUT_POLLDEV | ||
257 | select NET | ||
258 | select RFKILL | ||
256 | select BACKLIGHT_CLASS_DEVICE | 259 | select BACKLIGHT_CLASS_DEVICE |
257 | ---help--- | 260 | ---help--- |
258 | This driver adds support for access to certain system settings | 261 | This driver adds support for access to certain system settings |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index de8046933bce..b2133e89ad9a 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -431,7 +431,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, | |||
431 | } | 431 | } |
432 | 432 | ||
433 | static struct device_attribute alarm_attr = { | 433 | static struct device_attribute alarm_attr = { |
434 | .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE}, | 434 | .attr = {.name = "alarm", .mode = 0644}, |
435 | .show = acpi_battery_alarm_show, | 435 | .show = acpi_battery_alarm_show, |
436 | .store = acpi_battery_alarm_store, | 436 | .store = acpi_battery_alarm_store, |
437 | }; | 437 | }; |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 8dd3336efd7e..24649ada08df 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -260,116 +260,3 @@ static int __init init_acpi_device_notify(void) | |||
260 | } | 260 | } |
261 | 261 | ||
262 | arch_initcall(init_acpi_device_notify); | 262 | arch_initcall(init_acpi_device_notify); |
263 | |||
264 | |||
265 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) | ||
266 | |||
267 | #ifdef CONFIG_PM | ||
268 | static u32 rtc_handler(void *context) | ||
269 | { | ||
270 | acpi_clear_event(ACPI_EVENT_RTC); | ||
271 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
272 | return ACPI_INTERRUPT_HANDLED; | ||
273 | } | ||
274 | |||
275 | static inline void rtc_wake_setup(void) | ||
276 | { | ||
277 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | ||
278 | /* | ||
279 | * After the RTC handler is installed, the Fixed_RTC event should | ||
280 | * be disabled. Only when the RTC alarm is set will it be enabled. | ||
281 | */ | ||
282 | acpi_clear_event(ACPI_EVENT_RTC); | ||
283 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
284 | } | ||
285 | |||
286 | static void rtc_wake_on(struct device *dev) | ||
287 | { | ||
288 | acpi_clear_event(ACPI_EVENT_RTC); | ||
289 | acpi_enable_event(ACPI_EVENT_RTC, 0); | ||
290 | } | ||
291 | |||
292 | static void rtc_wake_off(struct device *dev) | ||
293 | { | ||
294 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
295 | } | ||
296 | #else | ||
297 | #define rtc_wake_setup() do{}while(0) | ||
298 | #define rtc_wake_on NULL | ||
299 | #define rtc_wake_off NULL | ||
300 | #endif | ||
301 | |||
302 | /* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find | ||
303 | * its device node and pass extra config data. This helps its driver use | ||
304 | * capabilities that the now-obsolete mc146818 didn't have, and informs it | ||
305 | * that this board's RTC is wakeup-capable (per ACPI spec). | ||
306 | */ | ||
307 | #include <linux/mc146818rtc.h> | ||
308 | |||
309 | static struct cmos_rtc_board_info rtc_info; | ||
310 | |||
311 | |||
312 | /* PNP devices are registered in a subsys_initcall(); | ||
313 | * ACPI specifies the PNP IDs to use. | ||
314 | */ | ||
315 | #include <linux/pnp.h> | ||
316 | |||
317 | static int __init pnp_match(struct device *dev, void *data) | ||
318 | { | ||
319 | static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", }; | ||
320 | struct pnp_dev *pnp = to_pnp_dev(dev); | ||
321 | int i; | ||
322 | |||
323 | for (i = 0; i < ARRAY_SIZE(ids); i++) { | ||
324 | if (compare_pnp_id(pnp->id, ids[i]) != 0) | ||
325 | return 1; | ||
326 | } | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static struct device *__init get_rtc_dev(void) | ||
331 | { | ||
332 | return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match); | ||
333 | } | ||
334 | |||
335 | static int __init acpi_rtc_init(void) | ||
336 | { | ||
337 | struct device *dev = get_rtc_dev(); | ||
338 | |||
339 | if (acpi_disabled) | ||
340 | return 0; | ||
341 | |||
342 | if (dev) { | ||
343 | rtc_wake_setup(); | ||
344 | rtc_info.wake_on = rtc_wake_on; | ||
345 | rtc_info.wake_off = rtc_wake_off; | ||
346 | |||
347 | /* workaround bug in some ACPI tables */ | ||
348 | if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) { | ||
349 | DBG("bogus FADT month_alarm\n"); | ||
350 | acpi_gbl_FADT.month_alarm = 0; | ||
351 | } | ||
352 | |||
353 | rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; | ||
354 | rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; | ||
355 | rtc_info.rtc_century = acpi_gbl_FADT.century; | ||
356 | |||
357 | /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */ | ||
358 | if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE) | ||
359 | printk(PREFIX "RTC can wake from S4\n"); | ||
360 | |||
361 | |||
362 | dev->platform_data = &rtc_info; | ||
363 | |||
364 | /* RTC always wakes from S1/S2/S3, and often S4/STD */ | ||
365 | device_init_wakeup(dev, 1); | ||
366 | |||
367 | put_device(dev); | ||
368 | } else | ||
369 | DBG("RTC unavailable?\n"); | ||
370 | return 0; | ||
371 | } | ||
372 | /* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */ | ||
373 | fs_initcall(acpi_rtc_init); | ||
374 | |||
375 | #endif | ||
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index d0033250b5a9..6050ce481873 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -463,7 +463,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, | |||
463 | } | 463 | } |
464 | 464 | ||
465 | static struct device_attribute alarm_attr = { | 465 | static struct device_attribute alarm_attr = { |
466 | .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE}, | 466 | .attr = {.name = "alarm", .mode = 0644}, |
467 | .show = acpi_battery_alarm_show, | 467 | .show = acpi_battery_alarm_show, |
468 | .store = acpi_battery_alarm_store, | 468 | .store = acpi_battery_alarm_store, |
469 | }; | 469 | }; |
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index bf5b04de02d1..631ee2ee2ca0 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
@@ -120,13 +120,13 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | |||
120 | spin_unlock_irqrestore(&rtc_lock, flags); | 120 | spin_unlock_irqrestore(&rtc_lock, flags); |
121 | 121 | ||
122 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | 122 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
123 | BCD_TO_BIN(sec); | 123 | sec = bcd2bin(sec); |
124 | BCD_TO_BIN(min); | 124 | min = bcd2bin(min); |
125 | BCD_TO_BIN(hr); | 125 | hr = bcd2bin(hr); |
126 | BCD_TO_BIN(day); | 126 | day = bcd2bin(day); |
127 | BCD_TO_BIN(mo); | 127 | mo = bcd2bin(mo); |
128 | BCD_TO_BIN(yr); | 128 | yr = bcd2bin(yr); |
129 | BCD_TO_BIN(cent); | 129 | cent = bcd2bin(cent); |
130 | } | 130 | } |
131 | 131 | ||
132 | /* we're trusting the FADT (see above) */ | 132 | /* we're trusting the FADT (see above) */ |
@@ -204,7 +204,7 @@ static u32 cmos_bcd_read(int offset, int rtc_control) | |||
204 | { | 204 | { |
205 | u32 val = CMOS_READ(offset); | 205 | u32 val = CMOS_READ(offset); |
206 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 206 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) |
207 | BCD_TO_BIN(val); | 207 | val = bcd2bin(val); |
208 | return val; | 208 | return val; |
209 | } | 209 | } |
210 | 210 | ||
@@ -212,7 +212,7 @@ static u32 cmos_bcd_read(int offset, int rtc_control) | |||
212 | static void cmos_bcd_write(u32 val, int offset, int rtc_control) | 212 | static void cmos_bcd_write(u32 val, int offset, int rtc_control) |
213 | { | 213 | { |
214 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 214 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) |
215 | BIN_TO_BCD(val); | 215 | val = bin2bcd(val); |
216 | CMOS_WRITE(val, offset); | 216 | CMOS_WRITE(val, offset); |
217 | } | 217 | } |
218 | 218 | ||
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 3eefd6d029f9..1d74171b7940 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -115,7 +115,6 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | |||
115 | table_attr->attr.read = acpi_table_show; | 115 | table_attr->attr.read = acpi_table_show; |
116 | table_attr->attr.attr.name = table_attr->name; | 116 | table_attr->attr.attr.name = table_attr->name; |
117 | table_attr->attr.attr.mode = 0444; | 117 | table_attr->attr.attr.mode = 0444; |
118 | table_attr->attr.attr.owner = THIS_MODULE; | ||
119 | 118 | ||
120 | return; | 119 | return; |
121 | } | 120 | } |
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index 4172d290f275..2a632f8b7a05 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * | 4 | * |
5 | * Copyright (C) 2002-2004 John Belmonte | 5 | * Copyright (C) 2002-2004 John Belmonte |
6 | * Copyright (C) 2008 Philip Langdale | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -33,7 +34,7 @@ | |||
33 | * | 34 | * |
34 | */ | 35 | */ |
35 | 36 | ||
36 | #define TOSHIBA_ACPI_VERSION "0.18" | 37 | #define TOSHIBA_ACPI_VERSION "0.19" |
37 | #define PROC_INTERFACE_VERSION 1 | 38 | #define PROC_INTERFACE_VERSION 1 |
38 | 39 | ||
39 | #include <linux/kernel.h> | 40 | #include <linux/kernel.h> |
@@ -42,6 +43,9 @@ | |||
42 | #include <linux/types.h> | 43 | #include <linux/types.h> |
43 | #include <linux/proc_fs.h> | 44 | #include <linux/proc_fs.h> |
44 | #include <linux/backlight.h> | 45 | #include <linux/backlight.h> |
46 | #include <linux/platform_device.h> | ||
47 | #include <linux/rfkill.h> | ||
48 | #include <linux/input-polldev.h> | ||
45 | 49 | ||
46 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
47 | 51 | ||
@@ -90,6 +94,7 @@ MODULE_LICENSE("GPL"); | |||
90 | #define HCI_VIDEO_OUT 0x001c | 94 | #define HCI_VIDEO_OUT 0x001c |
91 | #define HCI_HOTKEY_EVENT 0x001e | 95 | #define HCI_HOTKEY_EVENT 0x001e |
92 | #define HCI_LCD_BRIGHTNESS 0x002a | 96 | #define HCI_LCD_BRIGHTNESS 0x002a |
97 | #define HCI_WIRELESS 0x0056 | ||
93 | 98 | ||
94 | /* field definitions */ | 99 | /* field definitions */ |
95 | #define HCI_LCD_BRIGHTNESS_BITS 3 | 100 | #define HCI_LCD_BRIGHTNESS_BITS 3 |
@@ -98,9 +103,14 @@ MODULE_LICENSE("GPL"); | |||
98 | #define HCI_VIDEO_OUT_LCD 0x1 | 103 | #define HCI_VIDEO_OUT_LCD 0x1 |
99 | #define HCI_VIDEO_OUT_CRT 0x2 | 104 | #define HCI_VIDEO_OUT_CRT 0x2 |
100 | #define HCI_VIDEO_OUT_TV 0x4 | 105 | #define HCI_VIDEO_OUT_TV 0x4 |
106 | #define HCI_WIRELESS_KILL_SWITCH 0x01 | ||
107 | #define HCI_WIRELESS_BT_PRESENT 0x0f | ||
108 | #define HCI_WIRELESS_BT_ATTACH 0x40 | ||
109 | #define HCI_WIRELESS_BT_POWER 0x80 | ||
101 | 110 | ||
102 | static const struct acpi_device_id toshiba_device_ids[] = { | 111 | static const struct acpi_device_id toshiba_device_ids[] = { |
103 | {"TOS6200", 0}, | 112 | {"TOS6200", 0}, |
113 | {"TOS6208", 0}, | ||
104 | {"TOS1900", 0}, | 114 | {"TOS1900", 0}, |
105 | {"", 0}, | 115 | {"", 0}, |
106 | }; | 116 | }; |
@@ -193,7 +203,7 @@ static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS]) | |||
193 | return status; | 203 | return status; |
194 | } | 204 | } |
195 | 205 | ||
196 | /* common hci tasks (get or set one value) | 206 | /* common hci tasks (get or set one or two value) |
197 | * | 207 | * |
198 | * In addition to the ACPI status, the HCI system returns a result which | 208 | * In addition to the ACPI status, the HCI system returns a result which |
199 | * may be useful (such as "not supported"). | 209 | * may be useful (such as "not supported"). |
@@ -218,6 +228,152 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result) | |||
218 | return status; | 228 | return status; |
219 | } | 229 | } |
220 | 230 | ||
231 | static acpi_status hci_write2(u32 reg, u32 in1, u32 in2, u32 *result) | ||
232 | { | ||
233 | u32 in[HCI_WORDS] = { HCI_SET, reg, in1, in2, 0, 0 }; | ||
234 | u32 out[HCI_WORDS]; | ||
235 | acpi_status status = hci_raw(in, out); | ||
236 | *result = (status == AE_OK) ? out[0] : HCI_FAILURE; | ||
237 | return status; | ||
238 | } | ||
239 | |||
240 | static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result) | ||
241 | { | ||
242 | u32 in[HCI_WORDS] = { HCI_GET, reg, *out1, *out2, 0, 0 }; | ||
243 | u32 out[HCI_WORDS]; | ||
244 | acpi_status status = hci_raw(in, out); | ||
245 | *out1 = out[2]; | ||
246 | *out2 = out[3]; | ||
247 | *result = (status == AE_OK) ? out[0] : HCI_FAILURE; | ||
248 | return status; | ||
249 | } | ||
250 | |||
251 | struct toshiba_acpi_dev { | ||
252 | struct platform_device *p_dev; | ||
253 | struct rfkill *rfk_dev; | ||
254 | struct input_polled_dev *poll_dev; | ||
255 | |||
256 | const char *bt_name; | ||
257 | const char *rfk_name; | ||
258 | |||
259 | bool last_rfk_state; | ||
260 | |||
261 | struct mutex mutex; | ||
262 | }; | ||
263 | |||
264 | static struct toshiba_acpi_dev toshiba_acpi = { | ||
265 | .bt_name = "Toshiba Bluetooth", | ||
266 | .rfk_name = "Toshiba RFKill Switch", | ||
267 | .last_rfk_state = false, | ||
268 | }; | ||
269 | |||
270 | /* Bluetooth rfkill handlers */ | ||
271 | |||
272 | static u32 hci_get_bt_present(bool *present) | ||
273 | { | ||
274 | u32 hci_result; | ||
275 | u32 value, value2; | ||
276 | |||
277 | value = 0; | ||
278 | value2 = 0; | ||
279 | hci_read2(HCI_WIRELESS, &value, &value2, &hci_result); | ||
280 | if (hci_result == HCI_SUCCESS) | ||
281 | *present = (value & HCI_WIRELESS_BT_PRESENT) ? true : false; | ||
282 | |||
283 | return hci_result; | ||
284 | } | ||
285 | |||
286 | static 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 | |||
301 | static u32 hci_get_radio_state(bool *radio_state) | ||
302 | { | ||
303 | u32 hci_result; | ||
304 | u32 value, value2; | ||
305 | |||
306 | value = 0; | ||
307 | value2 = 0x0001; | ||
308 | hci_read2(HCI_WIRELESS, &value, &value2, &hci_result); | ||
309 | |||
310 | *radio_state = value & HCI_WIRELESS_KILL_SWITCH; | ||
311 | return hci_result; | ||
312 | } | ||
313 | |||
314 | static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state) | ||
315 | { | ||
316 | u32 result1, result2; | ||
317 | u32 value; | ||
318 | bool radio_state; | ||
319 | struct toshiba_acpi_dev *dev = data; | ||
320 | |||
321 | value = (state == RFKILL_STATE_UNBLOCKED); | ||
322 | |||
323 | if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) | ||
324 | return -EFAULT; | ||
325 | |||
326 | switch (state) { | ||
327 | case RFKILL_STATE_UNBLOCKED: | ||
328 | if (!radio_state) | ||
329 | return -EPERM; | ||
330 | break; | ||
331 | case RFKILL_STATE_SOFT_BLOCKED: | ||
332 | break; | ||
333 | default: | ||
334 | return -EINVAL; | ||
335 | } | ||
336 | |||
337 | mutex_lock(&dev->mutex); | ||
338 | hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1); | ||
339 | hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2); | ||
340 | mutex_unlock(&dev->mutex); | ||
341 | |||
342 | if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS) | ||
343 | return -EFAULT; | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static void bt_poll_rfkill(struct input_polled_dev *poll_dev) | ||
349 | { | ||
350 | bool state_changed; | ||
351 | bool new_rfk_state; | ||
352 | bool value; | ||
353 | u32 hci_result; | ||
354 | struct toshiba_acpi_dev *dev = poll_dev->private; | ||
355 | |||
356 | hci_result = hci_get_radio_state(&value); | ||
357 | if (hci_result != HCI_SUCCESS) | ||
358 | return; /* Can't do anything useful */ | ||
359 | |||
360 | new_rfk_state = value; | ||
361 | |||
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); | ||
366 | |||
367 | if (unlikely(state_changed)) { | ||
368 | rfkill_force_state(dev->rfk_dev, | ||
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 | } | ||
375 | } | ||
376 | |||
221 | static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; | 377 | static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; |
222 | static struct backlight_device *toshiba_backlight_device; | 378 | static struct backlight_device *toshiba_backlight_device; |
223 | static int force_fan; | 379 | static int force_fan; |
@@ -547,6 +703,14 @@ static struct backlight_ops toshiba_backlight_data = { | |||
547 | 703 | ||
548 | static void toshiba_acpi_exit(void) | 704 | static void toshiba_acpi_exit(void) |
549 | { | 705 | { |
706 | if (toshiba_acpi.poll_dev) { | ||
707 | input_unregister_polled_device(toshiba_acpi.poll_dev); | ||
708 | input_free_polled_device(toshiba_acpi.poll_dev); | ||
709 | } | ||
710 | |||
711 | if (toshiba_acpi.rfk_dev) | ||
712 | rfkill_unregister(toshiba_acpi.rfk_dev); | ||
713 | |||
550 | if (toshiba_backlight_device) | 714 | if (toshiba_backlight_device) |
551 | backlight_device_unregister(toshiba_backlight_device); | 715 | backlight_device_unregister(toshiba_backlight_device); |
552 | 716 | ||
@@ -555,6 +719,8 @@ static void toshiba_acpi_exit(void) | |||
555 | if (toshiba_proc_dir) | 719 | if (toshiba_proc_dir) |
556 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); | 720 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); |
557 | 721 | ||
722 | platform_device_unregister(toshiba_acpi.p_dev); | ||
723 | |||
558 | return; | 724 | return; |
559 | } | 725 | } |
560 | 726 | ||
@@ -562,6 +728,10 @@ static int __init toshiba_acpi_init(void) | |||
562 | { | 728 | { |
563 | acpi_status status = AE_OK; | 729 | acpi_status status = AE_OK; |
564 | u32 hci_result; | 730 | u32 hci_result; |
731 | bool bt_present; | ||
732 | bool bt_on; | ||
733 | bool radio_on; | ||
734 | int ret = 0; | ||
565 | 735 | ||
566 | if (acpi_disabled) | 736 | if (acpi_disabled) |
567 | return -ENODEV; | 737 | return -ENODEV; |
@@ -578,6 +748,18 @@ static int __init toshiba_acpi_init(void) | |||
578 | TOSHIBA_ACPI_VERSION); | 748 | TOSHIBA_ACPI_VERSION); |
579 | printk(MY_INFO " HCI method: %s\n", method_hci); | 749 | printk(MY_INFO " HCI method: %s\n", method_hci); |
580 | 750 | ||
751 | mutex_init(&toshiba_acpi.mutex); | ||
752 | |||
753 | toshiba_acpi.p_dev = platform_device_register_simple("toshiba_acpi", | ||
754 | -1, NULL, 0); | ||
755 | if (IS_ERR(toshiba_acpi.p_dev)) { | ||
756 | ret = PTR_ERR(toshiba_acpi.p_dev); | ||
757 | printk(MY_ERR "unable to register platform device\n"); | ||
758 | toshiba_acpi.p_dev = NULL; | ||
759 | toshiba_acpi_exit(); | ||
760 | return ret; | ||
761 | } | ||
762 | |||
581 | force_fan = 0; | 763 | force_fan = 0; |
582 | key_event_valid = 0; | 764 | key_event_valid = 0; |
583 | 765 | ||
@@ -586,19 +768,23 @@ static int __init toshiba_acpi_init(void) | |||
586 | 768 | ||
587 | toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); | 769 | toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); |
588 | if (!toshiba_proc_dir) { | 770 | if (!toshiba_proc_dir) { |
589 | status = AE_ERROR; | 771 | toshiba_acpi_exit(); |
772 | return -ENODEV; | ||
590 | } else { | 773 | } else { |
591 | toshiba_proc_dir->owner = THIS_MODULE; | 774 | toshiba_proc_dir->owner = THIS_MODULE; |
592 | status = add_device(); | 775 | status = add_device(); |
593 | if (ACPI_FAILURE(status)) | 776 | if (ACPI_FAILURE(status)) { |
594 | remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); | 777 | toshiba_acpi_exit(); |
778 | return -ENODEV; | ||
779 | } | ||
595 | } | 780 | } |
596 | 781 | ||
597 | toshiba_backlight_device = backlight_device_register("toshiba",NULL, | 782 | toshiba_backlight_device = backlight_device_register("toshiba", |
783 | &toshiba_acpi.p_dev->dev, | ||
598 | NULL, | 784 | NULL, |
599 | &toshiba_backlight_data); | 785 | &toshiba_backlight_data); |
600 | if (IS_ERR(toshiba_backlight_device)) { | 786 | if (IS_ERR(toshiba_backlight_device)) { |
601 | int ret = PTR_ERR(toshiba_backlight_device); | 787 | ret = PTR_ERR(toshiba_backlight_device); |
602 | 788 | ||
603 | printk(KERN_ERR "Could not register toshiba backlight device\n"); | 789 | printk(KERN_ERR "Could not register toshiba backlight device\n"); |
604 | toshiba_backlight_device = NULL; | 790 | toshiba_backlight_device = NULL; |
@@ -607,7 +793,66 @@ static int __init toshiba_acpi_init(void) | |||
607 | } | 793 | } |
608 | toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; | 794 | toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; |
609 | 795 | ||
610 | return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; | 796 | /* Register rfkill switch for Bluetooth */ |
797 | if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { | ||
798 | toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev, | ||
799 | RFKILL_TYPE_BLUETOOTH); | ||
800 | if (!toshiba_acpi.rfk_dev) { | ||
801 | printk(MY_ERR "unable to allocate rfkill device\n"); | ||
802 | toshiba_acpi_exit(); | ||
803 | return -ENOMEM; | ||
804 | } | ||
805 | |||
806 | toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name; | ||
807 | toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio; | ||
808 | toshiba_acpi.rfk_dev->user_claim_unsupported = 1; | ||
809 | toshiba_acpi.rfk_dev->data = &toshiba_acpi; | ||
810 | |||
811 | if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) { | ||
812 | toshiba_acpi.rfk_dev->state = RFKILL_STATE_UNBLOCKED; | ||
813 | } else if (hci_get_radio_state(&radio_on) == HCI_SUCCESS && | ||
814 | radio_on) { | ||
815 | toshiba_acpi.rfk_dev->state = RFKILL_STATE_SOFT_BLOCKED; | ||
816 | } else { | ||
817 | toshiba_acpi.rfk_dev->state = RFKILL_STATE_HARD_BLOCKED; | ||
818 | } | ||
819 | |||
820 | ret = rfkill_register(toshiba_acpi.rfk_dev); | ||
821 | if (ret) { | ||
822 | printk(MY_ERR "unable to register rfkill device\n"); | ||
823 | toshiba_acpi_exit(); | ||
824 | return -ENOMEM; | ||
825 | } | ||
826 | } | ||
827 | |||
828 | /* Register input device for kill switch */ | ||
829 | toshiba_acpi.poll_dev = input_allocate_polled_device(); | ||
830 | if (!toshiba_acpi.poll_dev) { | ||
831 | printk(MY_ERR "unable to allocate kill-switch input device\n"); | ||
832 | toshiba_acpi_exit(); | ||
833 | return -ENOMEM; | ||
834 | } | ||
835 | toshiba_acpi.poll_dev->private = &toshiba_acpi; | ||
836 | toshiba_acpi.poll_dev->poll = bt_poll_rfkill; | ||
837 | toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */ | ||
838 | |||
839 | toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name; | ||
840 | toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST; | ||
841 | toshiba_acpi.poll_dev->input->id.vendor = 0x0930; /* Toshiba USB ID */ | ||
842 | set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit); | ||
843 | set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit); | ||
844 | input_report_switch(toshiba_acpi.poll_dev->input, SW_RFKILL_ALL, TRUE); | ||
845 | |||
846 | ret = input_register_polled_device(toshiba_acpi.poll_dev); | ||
847 | if (ret) { | ||
848 | printk(MY_ERR "unable to register kill-switch input device\n"); | ||
849 | rfkill_free(toshiba_acpi.rfk_dev); | ||
850 | toshiba_acpi.rfk_dev = NULL; | ||
851 | toshiba_acpi_exit(); | ||
852 | return ret; | ||
853 | } | ||
854 | |||
855 | return 0; | ||
611 | } | 856 | } |
612 | 857 | ||
613 | module_init(toshiba_acpi_init); | 858 | module_init(toshiba_acpi_init); |