Skip to content

Commit

Permalink
thinkpad-acpi: fix bluetooth/wwan resume
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Henrique de Moraes Holschuh committed Feb 26, 2010
1 parent 7f0cf71 commit 08fedfc
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions drivers/platform/x86/thinkpad_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 08fedfc

Please sign in to comment.