aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2010-02-25 22:22:07 -0300
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-15 09:06:47 -0700
commit6f4698f6c3846c4ddccaacee85aec17599dabcff (patch)
tree0378280ad26494c6e788c3fe27021ebe281ecf35
parent6a79a0708eecc65ade97a09ec4c11488374e1bbc (diff)
thinkpad-acpi: fix bluetooth/wwan resume
commit 08fedfc903c78e380b0baa7b57c52d367794d0a5 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-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 20b0345933f1..4ab5382ca4ed 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -3878,7 +3878,7 @@ enum {
TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */
TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */
TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume:
- off / last state */
+ 0 = disable, 1 = enable */
};
enum {
@@ -3924,10 +3924,11 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state)
}
#endif
- /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
- status = TP_ACPI_BLUETOOTH_RESUMECTRL;
if (state == TPACPI_RFK_RADIO_ON)
- status |= TP_ACPI_BLUETOOTH_RADIOSSW;
+ status = TP_ACPI_BLUETOOTH_RADIOSSW
+ | TP_ACPI_BLUETOOTH_RESUMECTRL;
+ else
+ status = 0;
if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
return -EIO;
@@ -4078,7 +4079,7 @@ enum {
TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */
TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */
TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume:
- off / last state */
+ 0 = disable, 1 = enable */
};
#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
@@ -4115,10 +4116,11 @@ static int wan_set_status(enum tpacpi_rfkill_state state)
}
#endif
- /* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */
- status = TP_ACPI_WANCARD_RESUMECTRL;
if (state == TPACPI_RFK_RADIO_ON)
- status |= TP_ACPI_WANCARD_RADIOSSW;
+ status = TP_ACPI_WANCARD_RADIOSSW
+ | TP_ACPI_WANCARD_RESUMECTRL;
+ else
+ status = 0;
if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
return -EIO;