aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/thinkpad_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/thinkpad_acpi.c')
-rw-r--r--drivers/misc/thinkpad_acpi.c86
1 files changed, 64 insertions, 22 deletions
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 4db1cf9078d9..899766e16fa8 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -4932,16 +4932,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
4932 */ 4932 */
4933 b = tpacpi_check_std_acpi_brightness_support(); 4933 b = tpacpi_check_std_acpi_brightness_support();
4934 if (b > 0) { 4934 if (b > 0) {
4935 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { 4935
4936 printk(TPACPI_NOTICE 4936 if (acpi_video_backlight_support()) {
4937 "Lenovo BIOS switched to ACPI backlight " 4937 if (brightness_enable > 1) {
4938 "control mode\n"); 4938 printk(TPACPI_NOTICE
4939 } 4939 "Standard ACPI backlight interface "
4940 if (brightness_enable > 1) { 4940 "available, not loading native one.\n");
4941 printk(TPACPI_NOTICE 4941 return 1;
4942 "standard ACPI backlight interface " 4942 } else if (brightness_enable == 1) {
4943 "available, not loading native one...\n"); 4943 printk(TPACPI_NOTICE
4944 return 1; 4944 "Backlight control force enabled, even if standard "
4945 "ACPI backlight interface is available\n");
4946 }
4947 } else {
4948 if (brightness_enable > 1) {
4949 printk(TPACPI_NOTICE
4950 "Standard ACPI backlight interface not "
4951 "available, thinkpad_acpi native "
4952 "brightness control enabled\n");
4953 }
4945 } 4954 }
4946 } 4955 }
4947 4956
@@ -5309,6 +5318,7 @@ static enum fan_control_commands fan_control_commands;
5309 5318
5310static u8 fan_control_initial_status; 5319static u8 fan_control_initial_status;
5311static u8 fan_control_desired_level; 5320static u8 fan_control_desired_level;
5321static u8 fan_control_resume_level;
5312static int fan_watchdog_maxinterval; 5322static int fan_watchdog_maxinterval;
5313 5323
5314static struct mutex fan_mutex; 5324static struct mutex fan_mutex;
@@ -5431,8 +5441,8 @@ static int fan_set_level(int level)
5431 5441
5432 case TPACPI_FAN_WR_ACPI_FANS: 5442 case TPACPI_FAN_WR_ACPI_FANS:
5433 case TPACPI_FAN_WR_TPEC: 5443 case TPACPI_FAN_WR_TPEC:
5434 if ((level != TP_EC_FAN_AUTO) && 5444 if (!(level & TP_EC_FAN_AUTO) &&
5435 (level != TP_EC_FAN_FULLSPEED) && 5445 !(level & TP_EC_FAN_FULLSPEED) &&
5436 ((level < 0) || (level > 7))) 5446 ((level < 0) || (level > 7)))
5437 return -EINVAL; 5447 return -EINVAL;
5438 5448
@@ -5996,38 +6006,67 @@ static void fan_exit(void)
5996 6006
5997static void fan_suspend(pm_message_t state) 6007static void fan_suspend(pm_message_t state)
5998{ 6008{
6009 int rc;
6010
5999 if (!fan_control_allowed) 6011 if (!fan_control_allowed)
6000 return; 6012 return;
6001 6013
6002 /* Store fan status in cache */ 6014 /* Store fan status in cache */
6003 fan_get_status_safe(NULL); 6015 fan_control_resume_level = 0;
6016 rc = fan_get_status_safe(&fan_control_resume_level);
6017 if (rc < 0)
6018 printk(TPACPI_NOTICE
6019 "failed to read fan level for later "
6020 "restore during resume: %d\n", rc);
6021
6022 /* if it is undefined, don't attempt to restore it.
6023 * KEEP THIS LAST */
6004 if (tp_features.fan_ctrl_status_undef) 6024 if (tp_features.fan_ctrl_status_undef)
6005 fan_control_desired_level = TP_EC_FAN_AUTO; 6025 fan_control_resume_level = 0;
6006} 6026}
6007 6027
6008static void fan_resume(void) 6028static void fan_resume(void)
6009{ 6029{
6010 u8 saved_fan_level;
6011 u8 current_level = 7; 6030 u8 current_level = 7;
6012 bool do_set = false; 6031 bool do_set = false;
6032 int rc;
6013 6033
6014 /* DSDT *always* updates status on resume */ 6034 /* DSDT *always* updates status on resume */
6015 tp_features.fan_ctrl_status_undef = 0; 6035 tp_features.fan_ctrl_status_undef = 0;
6016 6036
6017 saved_fan_level = fan_control_desired_level;
6018 if (!fan_control_allowed || 6037 if (!fan_control_allowed ||
6038 !fan_control_resume_level ||
6019 (fan_get_status_safe(&current_level) < 0)) 6039 (fan_get_status_safe(&current_level) < 0))
6020 return; 6040 return;
6021 6041
6022 switch (fan_control_access_mode) { 6042 switch (fan_control_access_mode) {
6023 case TPACPI_FAN_WR_ACPI_SFAN: 6043 case TPACPI_FAN_WR_ACPI_SFAN:
6024 do_set = (saved_fan_level > current_level); 6044 /* never decrease fan level */
6045 do_set = (fan_control_resume_level > current_level);
6025 break; 6046 break;
6026 case TPACPI_FAN_WR_ACPI_FANS: 6047 case TPACPI_FAN_WR_ACPI_FANS:
6027 case TPACPI_FAN_WR_TPEC: 6048 case TPACPI_FAN_WR_TPEC:
6028 do_set = ((saved_fan_level & TP_EC_FAN_FULLSPEED) || 6049 /* never decrease fan level, scale is:
6029 (saved_fan_level == 7 && 6050 * TP_EC_FAN_FULLSPEED > 7 >= TP_EC_FAN_AUTO
6030 !(current_level & TP_EC_FAN_FULLSPEED))); 6051 *
6052 * We expect the firmware to set either 7 or AUTO, but we
6053 * handle FULLSPEED out of paranoia.
6054 *
6055 * So, we can safely only restore FULLSPEED or 7, anything
6056 * else could slow the fan. Restoring AUTO is useless, at
6057 * best that's exactly what the DSDT already set (it is the
6058 * slower it uses).
6059 *
6060 * Always keep in mind that the DSDT *will* have set the
6061 * fans to what the vendor supposes is the best level. We
6062 * muck with it only to speed the fan up.
6063 */
6064 if (fan_control_resume_level != 7 &&
6065 !(fan_control_resume_level & TP_EC_FAN_FULLSPEED))
6066 return;
6067 else
6068 do_set = !(current_level & TP_EC_FAN_FULLSPEED) &&
6069 (current_level != fan_control_resume_level);
6031 break; 6070 break;
6032 default: 6071 default:
6033 return; 6072 return;
@@ -6035,8 +6074,11 @@ static void fan_resume(void)
6035 if (do_set) { 6074 if (do_set) {
6036 printk(TPACPI_NOTICE 6075 printk(TPACPI_NOTICE
6037 "restoring fan level to 0x%02x\n", 6076 "restoring fan level to 0x%02x\n",
6038 saved_fan_level); 6077 fan_control_resume_level);
6039 fan_set_level_safe(saved_fan_level); 6078 rc = fan_set_level_safe(fan_control_resume_level);
6079 if (rc < 0)
6080 printk(TPACPI_NOTICE
6081 "failed to restore fan level: %d\n", rc);
6040 } 6082 }
6041} 6083}
6042 6084