aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2009-01-11 00:01:01 -0500
committerLen Brown <len.brown@intel.com>2009-01-15 13:30:29 -0500
commit153f82207c51193e4d6a7e6f0e3f9442eabeba1c (patch)
treeb6143c9f393b55f6bdb219730dd1151eb1253c15
parenta73f30916ee524437253739eacc682f6fb0f3ea8 (diff)
ACPI: thinkpad-acpi: resume with radios disabled
Instruct the firmware to not enable the radios when resuming. This is safer, and the rfkill core will take care to manually enable any radios that need to be enabled. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c66
1 files changed, 56 insertions, 10 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index a086ce8ed4eb..b2c5913ff72e 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -122,6 +122,27 @@ enum {
122#define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */ 122#define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */
123#define TPACPI_HKEY_INPUT_VERSION 0x4101 123#define TPACPI_HKEY_INPUT_VERSION 0x4101
124 124
125/* ACPI \WGSV commands */
126enum {
127 TP_ACPI_WGSV_GET_STATE = 0x01, /* Get state information */
128 TP_ACPI_WGSV_PWR_ON_ON_RESUME = 0x02, /* Resume WWAN powered on */
129 TP_ACPI_WGSV_PWR_OFF_ON_RESUME = 0x03, /* Resume WWAN powered off */
130 TP_ACPI_WGSV_SAVE_STATE = 0x04, /* Save state for S4/S5 */
131};
132
133/* TP_ACPI_WGSV_GET_STATE bits */
134enum {
135 TP_ACPI_WGSV_STATE_WWANEXIST = 0x0001, /* WWAN hw available */
136 TP_ACPI_WGSV_STATE_WWANPWR = 0x0002, /* WWAN radio enabled */
137 TP_ACPI_WGSV_STATE_WWANPWRRES = 0x0004, /* WWAN state at resume */
138 TP_ACPI_WGSV_STATE_WWANBIOSOFF = 0x0008, /* WWAN disabled in BIOS */
139 TP_ACPI_WGSV_STATE_BLTHEXIST = 0x0001, /* BLTH hw available */
140 TP_ACPI_WGSV_STATE_BLTHPWR = 0x0002, /* BLTH radio enabled */
141 TP_ACPI_WGSV_STATE_BLTHPWRRES = 0x0004, /* BLTH state at resume */
142 TP_ACPI_WGSV_STATE_BLTHBIOSOFF = 0x0008, /* BLTH disabled in BIOS */
143 TP_ACPI_WGSV_STATE_UWBEXIST = 0x0010, /* UWB hw available */
144 TP_ACPI_WGSV_STATE_UWBPWR = 0x0020, /* UWB radio enabled */
145};
125 146
126/**************************************************************************** 147/****************************************************************************
127 * Main driver 148 * Main driver
@@ -2766,11 +2787,28 @@ enum {
2766 /* ACPI GBDC/SBDC bits */ 2787 /* ACPI GBDC/SBDC bits */
2767 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ 2788 TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */
2768 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ 2789 TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */
2769 TP_ACPI_BLUETOOTH_UNK = 0x04, /* unknown function */ 2790 TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume:
2791 off / last state */
2792};
2793
2794enum {
2795 /* ACPI \BLTH commands */
2796 TP_ACPI_BLTH_GET_ULTRAPORT_ID = 0x00, /* Get Ultraport BT ID */
2797 TP_ACPI_BLTH_GET_PWR_ON_RESUME = 0x01, /* Get power-on-resume state */
2798 TP_ACPI_BLTH_PWR_ON_ON_RESUME = 0x02, /* Resume powered on */
2799 TP_ACPI_BLTH_PWR_OFF_ON_RESUME = 0x03, /* Resume powered off */
2800 TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */
2770}; 2801};
2771 2802
2772static struct rfkill *tpacpi_bluetooth_rfkill; 2803static struct rfkill *tpacpi_bluetooth_rfkill;
2773 2804
2805static void bluetooth_suspend(pm_message_t state)
2806{
2807 /* Try to make sure radio will resume powered off */
2808 acpi_evalf(NULL, NULL, "\\BLTH", "vd",
2809 TP_ACPI_BLTH_PWR_OFF_ON_RESUME);
2810}
2811
2774static int bluetooth_get_radiosw(void) 2812static int bluetooth_get_radiosw(void)
2775{ 2813{
2776 int status; 2814 int status;
@@ -2830,12 +2868,11 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk)
2830 } 2868 }
2831#endif 2869#endif
2832 2870
2833 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 2871 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
2834 return -EIO;
2835 if (radio_on) 2872 if (radio_on)
2836 status |= TP_ACPI_BLUETOOTH_RADIOSSW; 2873 status = TP_ACPI_BLUETOOTH_RADIOSSW;
2837 else 2874 else
2838 status &= ~TP_ACPI_BLUETOOTH_RADIOSSW; 2875 status = 0;
2839 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) 2876 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
2840 return -EIO; 2877 return -EIO;
2841 2878
@@ -3012,6 +3049,7 @@ static struct ibm_struct bluetooth_driver_data = {
3012 .read = bluetooth_read, 3049 .read = bluetooth_read,
3013 .write = bluetooth_write, 3050 .write = bluetooth_write,
3014 .exit = bluetooth_exit, 3051 .exit = bluetooth_exit,
3052 .suspend = bluetooth_suspend,
3015}; 3053};
3016 3054
3017/************************************************************************* 3055/*************************************************************************
@@ -3022,11 +3060,19 @@ enum {
3022 /* ACPI GWAN/SWAN bits */ 3060 /* ACPI GWAN/SWAN bits */
3023 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ 3061 TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */
3024 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ 3062 TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */
3025 TP_ACPI_WANCARD_UNK = 0x04, /* unknown function */ 3063 TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume:
3064 off / last state */
3026}; 3065};
3027 3066
3028static struct rfkill *tpacpi_wan_rfkill; 3067static struct rfkill *tpacpi_wan_rfkill;
3029 3068
3069static void wan_suspend(pm_message_t state)
3070{
3071 /* Try to make sure radio will resume powered off */
3072 acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
3073 TP_ACPI_WGSV_PWR_OFF_ON_RESUME);
3074}
3075
3030static int wan_get_radiosw(void) 3076static int wan_get_radiosw(void)
3031{ 3077{
3032 int status; 3078 int status;
@@ -3086,12 +3132,11 @@ static int wan_set_radiosw(int radio_on, int update_rfk)
3086 } 3132 }
3087#endif 3133#endif
3088 3134
3089 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 3135 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */
3090 return -EIO;
3091 if (radio_on) 3136 if (radio_on)
3092 status |= TP_ACPI_WANCARD_RADIOSSW; 3137 status = TP_ACPI_WANCARD_RADIOSSW;
3093 else 3138 else
3094 status &= ~TP_ACPI_WANCARD_RADIOSSW; 3139 status = 0;
3095 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) 3140 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
3096 return -EIO; 3141 return -EIO;
3097 3142
@@ -3266,6 +3311,7 @@ static struct ibm_struct wan_driver_data = {
3266 .read = wan_read, 3311 .read = wan_read,
3267 .write = wan_write, 3312 .write = wan_write,
3268 .exit = wan_exit, 3313 .exit = wan_exit,
3314 .suspend = wan_suspend,
3269}; 3315};
3270 3316
3271/************************************************************************* 3317/*************************************************************************