diff options
author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2009-01-11 00:01:01 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-01-15 13:30:29 -0500 |
commit | 153f82207c51193e4d6a7e6f0e3f9442eabeba1c (patch) | |
tree | b6143c9f393b55f6bdb219730dd1151eb1253c15 /drivers | |
parent | a73f30916ee524437253739eacc682f6fb0f3ea8 (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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 66 |
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 */ | ||
126 | enum { | ||
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 */ | ||
134 | enum { | ||
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 | |||
2794 | enum { | ||
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 | ||
2772 | static struct rfkill *tpacpi_bluetooth_rfkill; | 2803 | static struct rfkill *tpacpi_bluetooth_rfkill; |
2773 | 2804 | ||
2805 | static 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 | |||
2774 | static int bluetooth_get_radiosw(void) | 2812 | static 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 | ||
3028 | static struct rfkill *tpacpi_wan_rfkill; | 3067 | static struct rfkill *tpacpi_wan_rfkill; |
3029 | 3068 | ||
3069 | static 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 | |||
3030 | static int wan_get_radiosw(void) | 3076 | static 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 | /************************************************************************* |