aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2010-02-25 20:22:07 -0500
committerHenrique de Moraes Holschuh <hmh@hmh.eng.br>2010-02-25 20:22:07 -0500
commit08fedfc903c78e380b0baa7b57c52d367794d0a5 (patch)
treeec7631cf63d947f5b6ce7dc98cb52c8e568701f7 /drivers
parent7f0cf712a74fcc3ad21f0bde95bd32c2f2cc3888 (diff)
thinkpad-acpi: fix bluetooth/wwan resume
Studying the DSDTs of various thinkpads, it looks like bit 3 of the argument to SBDC and SWAN is not "set radio to last state on resume". Rather, it seems to be "if this bit is set, enable radio on resume, otherwise disable it on resume". So, the proper way to prepare the radios for S3 suspend is: disable radio and clear bit 3 on the SBDC/SWAN call to to resume with radio disabled, and enable radio and set bit 3 on the SBDC/SWAN call to resume with the radio enabled. Also, for persistent devices, the rfkill core does not restore state, so we really need to get the firmware to do the right thing. We don't sync the radio state on suspend, instead we trust the BIOS to not do anything weird if we never touched the radio state since boot. Time will tell if that's a wise way of doing things... Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Cc: stable@kernel.org
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 5f450831e5f0..3af4628d7dd1 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -3878,7 +3878,7 @@ enum {
3878 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ 3878 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */
3879 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ 3879 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */
3880 TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume: 3880 TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume:
3881 off / last state */ 3881 0 = disable, 1 = enable */
3882}; 3882};
3883 3883
3884enum { 3884enum {
@@ -3924,10 +3924,11 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state)
3924 } 3924 }
3925#endif 3925#endif
3926 3926
3927 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
3928 status = TP_ACPI_BLUETOOTH_RESUMECTRL;
3929 if (state == TPACPI_RFK_RADIO_ON) 3927 if (state == TPACPI_RFK_RADIO_ON)
3930 status |= TP_ACPI_BLUETOOTH_RADIOSSW; 3928 status = TP_ACPI_BLUETOOTH_RADIOSSW
3929 | TP_ACPI_BLUETOOTH_RESUMECTRL;
3930 else
3931 status = 0;
3931 3932
3932 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) 3933 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
3933 return -EIO; 3934 return -EIO;
@@ -4078,7 +4079,7 @@ enum {
4078 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ 4079 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */
4079 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ 4080 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */
4080 TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume: 4081 TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume:
4081 off / last state */ 4082 0 = disable, 1 = enable */
4082}; 4083};
4083 4084
4084#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" 4085#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
@@ -4115,10 +4116,11 @@ static int wan_set_status(enum tpacpi_rfkill_state state)
4115 } 4116 }
4116#endif 4117#endif
4117 4118
4118 /* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */
4119 status = TP_ACPI_WANCARD_RESUMECTRL;
4120 if (state == TPACPI_RFK_RADIO_ON) 4119 if (state == TPACPI_RFK_RADIO_ON)
4121 status |= TP_ACPI_WANCARD_RADIOSSW; 4120 status = TP_ACPI_WANCARD_RADIOSSW
4121 | TP_ACPI_WANCARD_RESUMECTRL;
4122 else
4123 status = 0;
4122 4124
4123 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) 4125 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
4124 return -EIO; 4126 return -EIO;