aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2009-01-11 00:01:08 -0500
committerLen Brown <len.brown@intel.com>2009-01-15 13:47:14 -0500
commit1c2ece758a36b48133717e4db060fbe8fa52c5cd (patch)
treec0ab4d86ba1726eafee6a713d24ee89e572db8ad /drivers/platform
parentcb4293589855714b6d5079336019bf2af5fc41f8 (diff)
ACPI: thinkpad-acpi: clean-up fan subdriver quirk
Better document the Unitialized HFSP quirk, and modularize it a bit. This makes the code flow easier to read and reduces LOC. Apply the Unitialized HFSP closer to the source (i.e. inside the get_fan_status()), this fixes a harmless buglet where at driver init with the quirk active, the user could set the hwmon pwm1 attribute and switch out of pwm1_mode=2 to pwm1_mode=0 without changing pwm1_mode directly. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Cc: Tino Keitel <tino.keitel@tikei.de> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c109
1 files changed, 58 insertions, 51 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index d7d41ae2f299..213219d938e8 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -5897,6 +5897,60 @@ TPACPI_HANDLE(sfan, ec, "SFAN", /* 570 */
5897 ); /* all others */ 5897 ); /* all others */
5898 5898
5899/* 5899/*
5900 * Unitialized HFSP quirk: ACPI DSDT and EC fail to initialize the
5901 * HFSP register at boot, so it contains 0x07 but the Thinkpad could
5902 * be in auto mode (0x80).
5903 *
5904 * This is corrected by any write to HFSP either by the driver, or
5905 * by the firmware.
5906 *
5907 * We assume 0x07 really means auto mode while this quirk is active,
5908 * as this is far more likely than the ThinkPad being in level 7,
5909 * which is only used by the firmware during thermal emergencies.
5910 */
5911
5912static void fan_quirk1_detect(void)
5913{
5914 /* In some ThinkPads, neither the EC nor the ACPI
5915 * DSDT initialize the HFSP register, and it ends up
5916 * being initially set to 0x07 when it *could* be
5917 * either 0x07 or 0x80.
5918 *
5919 * Enable for TP-1Y (T43), TP-78 (R51e),
5920 * TP-76 (R52), TP-70 (T43, R52), which are known
5921 * to be buggy. */
5922 if (fan_control_initial_status == 0x07) {
5923 switch (thinkpad_id.ec_model) {
5924 case 0x5931: /* TP-1Y */
5925 case 0x3837: /* TP-78 */
5926 case 0x3637: /* TP-76 */
5927 case 0x3037: /* TP-70 */
5928 printk(TPACPI_NOTICE
5929 "fan_init: initial fan status is unknown, "
5930 "assuming it is in auto mode\n");
5931 tp_features.fan_ctrl_status_undef = 1;
5932 ;;
5933 }
5934 }
5935}
5936
5937static void fan_quirk1_handle(u8 *fan_status)
5938{
5939 if (unlikely(tp_features.fan_ctrl_status_undef)) {
5940 if (*fan_status != fan_control_initial_status) {
5941 /* something changed the HFSP regisnter since
5942 * driver init time, so it is not undefined
5943 * anymore */
5944 tp_features.fan_ctrl_status_undef = 0;
5945 } else {
5946 /* Return most likely status. In fact, it
5947 * might be the only possible status */
5948 *fan_status = TP_EC_FAN_AUTO;
5949 }
5950 }
5951}
5952
5953/*
5900 * Call with fan_mutex held 5954 * Call with fan_mutex held
5901 */ 5955 */
5902static void fan_update_desired_level(u8 status) 5956static void fan_update_desired_level(u8 status)
@@ -5934,8 +5988,10 @@ static int fan_get_status(u8 *status)
5934 if (unlikely(!acpi_ec_read(fan_status_offset, &s))) 5988 if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
5935 return -EIO; 5989 return -EIO;
5936 5990
5937 if (likely(status)) 5991 if (likely(status)) {
5938 *status = s; 5992 *status = s;
5993 fan_quirk1_handle(status);
5994 }
5939 5995
5940 break; 5996 break;
5941 5997
@@ -6245,16 +6301,6 @@ static ssize_t fan_pwm1_enable_show(struct device *dev,
6245 if (res) 6301 if (res)
6246 return res; 6302 return res;
6247 6303
6248 if (unlikely(tp_features.fan_ctrl_status_undef)) {
6249 if (status != fan_control_initial_status) {
6250 tp_features.fan_ctrl_status_undef = 0;
6251 } else {
6252 /* Return most likely status. In fact, it
6253 * might be the only possible status */
6254 status = TP_EC_FAN_AUTO;
6255 }
6256 }
6257
6258 if (status & TP_EC_FAN_FULLSPEED) { 6304 if (status & TP_EC_FAN_FULLSPEED) {
6259 mode = 0; 6305 mode = 0;
6260 } else if (status & TP_EC_FAN_AUTO) { 6306 } else if (status & TP_EC_FAN_AUTO) {
@@ -6319,14 +6365,6 @@ static ssize_t fan_pwm1_show(struct device *dev,
6319 if (res) 6365 if (res)
6320 return res; 6366 return res;
6321 6367
6322 if (unlikely(tp_features.fan_ctrl_status_undef)) {
6323 if (status != fan_control_initial_status) {
6324 tp_features.fan_ctrl_status_undef = 0;
6325 } else {
6326 status = TP_EC_FAN_AUTO;
6327 }
6328 }
6329
6330 if ((status & 6368 if ((status &
6331 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0) 6369 (TP_EC_FAN_AUTO | TP_EC_FAN_FULLSPEED)) != 0)
6332 status = fan_control_desired_level; 6370 status = fan_control_desired_level;
@@ -6458,29 +6496,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
6458 if (likely(acpi_ec_read(fan_status_offset, 6496 if (likely(acpi_ec_read(fan_status_offset,
6459 &fan_control_initial_status))) { 6497 &fan_control_initial_status))) {
6460 fan_status_access_mode = TPACPI_FAN_RD_TPEC; 6498 fan_status_access_mode = TPACPI_FAN_RD_TPEC;
6461 6499 fan_quirk1_detect();
6462 /* In some ThinkPads, neither the EC nor the ACPI
6463 * DSDT initialize the fan status, and it ends up
6464 * being set to 0x07 when it *could* be either
6465 * 0x07 or 0x80.
6466 *
6467 * Enable for TP-1Y (T43), TP-78 (R51e),
6468 * TP-76 (R52), TP-70 (T43, R52), which are known
6469 * to be buggy. */
6470 if (fan_control_initial_status == 0x07) {
6471 switch (thinkpad_id.ec_model) {
6472 case 0x5931: /* TP-1Y */
6473 case 0x3837: /* TP-78 */
6474 case 0x3637: /* TP-76 */
6475 case 0x3037: /* TP-70 */
6476 printk(TPACPI_NOTICE
6477 "fan_init: initial fan status "
6478 "is unknown, assuming it is "
6479 "in auto mode\n");
6480 tp_features.fan_ctrl_status_undef = 1;
6481 ;;
6482 }
6483 }
6484 } else { 6500 } else {
6485 printk(TPACPI_ERR 6501 printk(TPACPI_ERR
6486 "ThinkPad ACPI EC access misbehaving, " 6502 "ThinkPad ACPI EC access misbehaving, "
@@ -6669,15 +6685,6 @@ static int fan_read(char *p)
6669 if (rc < 0) 6685 if (rc < 0)
6670 return rc; 6686 return rc;
6671 6687
6672 if (unlikely(tp_features.fan_ctrl_status_undef)) {
6673 if (status != fan_control_initial_status)
6674 tp_features.fan_ctrl_status_undef = 0;
6675 else
6676 /* Return most likely status. In fact, it
6677 * might be the only possible status */
6678 status = TP_EC_FAN_AUTO;
6679 }
6680
6681 len += sprintf(p + len, "status:\t\t%s\n", 6688 len += sprintf(p + len, "status:\t\t%s\n",
6682 (status != 0) ? "enabled" : "disabled"); 6689 (status != 0) ? "enabled" : "disabled");
6683 6690