Add patches accepted for 2.6.29-rc2
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / releases / upstream / 2.6.29-rc2 / 0006-ACPI-thinkpad-acpi-preserve-radio-state-across-shu.patch
blob4897db0d0b3697a3b96d8093dcc0cd1bda23c278
1 From 90d9d3c79c44bcf95bc487e9bbceaff2de370310 Mon Sep 17 00:00:00 2001
2 From: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
3 Date: Sun, 11 Jan 2009 03:01:02 -0200
4 Subject: ACPI: thinkpad-acpi: preserve radio state across shutdown
6 Store in firmware NVRAM the radio state on machine shutdown for WWAN and
7 bluetooth. Also, try to set the initial boot state of these radios as the
8 rfkill default state for their respective classes.
10 Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
11 Cc: Ivo van Doorn <IvDoorn@gmail.com>
12 Signed-off-by: Len Brown <len.brown@intel.com>
13 ---
14 drivers/platform/x86/thinkpad_acpi.c | 59 +++++++++++++++++++++++++++++++--
15 1 files changed, 55 insertions(+), 4 deletions(-)
17 diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
18 index b2c5913..27d709b 100644
19 --- a/drivers/platform/x86/thinkpad_acpi.c
20 +++ b/drivers/platform/x86/thinkpad_acpi.c
21 @@ -222,6 +222,7 @@ struct ibm_struct {
22 void (*exit) (void);
23 void (*resume) (void);
24 void (*suspend) (pm_message_t state);
25 + void (*shutdown) (void);
27 struct list_head all_drivers;
29 @@ -759,6 +760,18 @@ static int tpacpi_resume_handler(struct platform_device *pdev)
30 return 0;
33 +static void tpacpi_shutdown_handler(struct platform_device *pdev)
35 + struct ibm_struct *ibm, *itmp;
37 + list_for_each_entry_safe(ibm, itmp,
38 + &tpacpi_all_drivers,
39 + all_drivers) {
40 + if (ibm->shutdown)
41 + (ibm->shutdown)();
42 + }
45 static struct platform_driver tpacpi_pdriver = {
46 .driver = {
47 .name = TPACPI_DRVR_NAME,
48 @@ -766,6 +779,7 @@ static struct platform_driver tpacpi_pdriver = {
50 .suspend = tpacpi_suspend_handler,
51 .resume = tpacpi_resume_handler,
52 + .shutdown = tpacpi_shutdown_handler,
55 static struct platform_driver tpacpi_hwmon_pdriver = {
56 @@ -957,7 +971,22 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
57 int (*get_state)(void *, enum rfkill_state *))
59 int res;
60 - enum rfkill_state initial_state;
61 + enum rfkill_state initial_state = RFKILL_STATE_SOFT_BLOCKED;
63 + res = get_state(NULL, &initial_state);
64 + if (res < 0) {
65 + printk(TPACPI_ERR
66 + "failed to read initial state for %s, error %d; "
67 + "will turn radio off\n", name, res);
68 + } else {
69 + /* try to set the initial state as the default for the rfkill
70 + * type, since we ask the firmware to preserve it across S5 in
71 + * NVRAM */
72 + rfkill_set_default(rfktype,
73 + (initial_state == RFKILL_STATE_UNBLOCKED) ?
74 + RFKILL_STATE_UNBLOCKED :
75 + RFKILL_STATE_SOFT_BLOCKED);
76 + }
78 *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
79 if (!*rfk) {
80 @@ -969,9 +998,7 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
81 (*rfk)->name = name;
82 (*rfk)->get_state = get_state;
83 (*rfk)->toggle_radio = toggle_radio;
85 - if (!get_state(NULL, &initial_state))
86 - (*rfk)->state = initial_state;
87 + (*rfk)->state = initial_state;
89 res = rfkill_register(*rfk);
90 if (res < 0) {
91 @@ -2943,8 +2970,19 @@ static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
92 return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
95 +static void bluetooth_shutdown(void)
97 + /* Order firmware to save current state to NVRAM */
98 + if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
99 + TP_ACPI_BLTH_SAVE_STATE))
100 + printk(TPACPI_NOTICE
101 + "failed to save bluetooth state to NVRAM\n");
104 static void bluetooth_exit(void)
106 + bluetooth_shutdown();
108 if (tpacpi_bluetooth_rfkill)
109 rfkill_unregister(tpacpi_bluetooth_rfkill);
111 @@ -3050,6 +3088,7 @@ static struct ibm_struct bluetooth_driver_data = {
112 .write = bluetooth_write,
113 .exit = bluetooth_exit,
114 .suspend = bluetooth_suspend,
115 + .shutdown = bluetooth_shutdown,
118 /*************************************************************************
119 @@ -3207,8 +3246,19 @@ static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
120 return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
123 +static void wan_shutdown(void)
125 + /* Order firmware to save current state to NVRAM */
126 + if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd",
127 + TP_ACPI_WGSV_SAVE_STATE))
128 + printk(TPACPI_NOTICE
129 + "failed to save WWAN state to NVRAM\n");
132 static void wan_exit(void)
134 + wan_shutdown();
136 if (tpacpi_wan_rfkill)
137 rfkill_unregister(tpacpi_wan_rfkill);
139 @@ -3312,6 +3362,7 @@ static struct ibm_struct wan_driver_data = {
140 .write = wan_write,
141 .exit = wan_exit,
142 .suspend = wan_suspend,
143 + .shutdown = wan_shutdown,
146 /*************************************************************************
148 1.5.6.5