aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ibm_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/ibm_acpi.c')
-rw-r--r--drivers/acpi/ibm_acpi.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 3c091c4b461f..56743c5a0439 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -362,7 +362,7 @@ enum { /* Fan control constants */
362 * control */ 362 * control */
363}; 363};
364 364
365static char* ibm_thinkpad_ec_found = NULL; 365static char *ibm_thinkpad_ec_found = NULL;
366 366
367struct ibm_struct { 367struct ibm_struct {
368 char *name; 368 char *name;
@@ -1794,13 +1794,15 @@ static enum fan_status_access_mode fan_status_access_mode;
1794static enum fan_control_access_mode fan_control_access_mode; 1794static enum fan_control_access_mode fan_control_access_mode;
1795static enum fan_control_commands fan_control_commands; 1795static enum fan_control_commands fan_control_commands;
1796 1796
1797static int fan_control_status_known;
1798static u8 fan_control_initial_status;
1799
1797static int fan_init(void) 1800static int fan_init(void)
1798{ 1801{
1799 u8 status;
1800
1801 fan_status_access_mode = IBMACPI_FAN_NONE; 1802 fan_status_access_mode = IBMACPI_FAN_NONE;
1802 fan_control_access_mode = IBMACPI_FAN_WR_NONE; 1803 fan_control_access_mode = IBMACPI_FAN_WR_NONE;
1803 fan_control_commands = 0; 1804 fan_control_commands = 0;
1805 fan_control_status_known = 1;
1804 1806
1805 if (gfan_handle) { 1807 if (gfan_handle) {
1806 /* 570, 600e/x, 770e, 770x */ 1808 /* 570, 600e/x, 770e, 770x */
@@ -1808,8 +1810,33 @@ static int fan_init(void)
1808 } else { 1810 } else {
1809 /* all other ThinkPads: note that even old-style 1811 /* all other ThinkPads: note that even old-style
1810 * ThinkPad ECs supports the fan control register */ 1812 * ThinkPad ECs supports the fan control register */
1811 if (likely(acpi_ec_read(fan_status_offset, &status))) { 1813 if (likely(acpi_ec_read(fan_status_offset,
1814 &fan_control_initial_status))) {
1812 fan_status_access_mode = IBMACPI_FAN_RD_TPEC; 1815 fan_status_access_mode = IBMACPI_FAN_RD_TPEC;
1816
1817 /* In some ThinkPads, neither the EC nor the ACPI
1818 * DSDT initialize the fan status, and it ends up
1819 * being set to 0x07 when it *could* be either
1820 * 0x07 or 0x80.
1821 *
1822 * Enable for TP-1Y (T43), TP-78 (R51e),
1823 * TP-76 (R52), TP-70 (T43, R52), which are known
1824 * to be buggy. */
1825 if (fan_control_initial_status == 0x07 &&
1826 ibm_thinkpad_ec_found &&
1827 ((ibm_thinkpad_ec_found[0] == '1' &&
1828 ibm_thinkpad_ec_found[1] == 'Y') ||
1829 (ibm_thinkpad_ec_found[0] == '7' &&
1830 (ibm_thinkpad_ec_found[1] == '6' ||
1831 ibm_thinkpad_ec_found[1] == '8' ||
1832 ibm_thinkpad_ec_found[1] == '0'))
1833 )) {
1834 printk(IBM_NOTICE
1835 "fan_init: initial fan status is "
1836 "unknown, assuming it is in auto "
1837 "mode\n");
1838 fan_control_status_known = 0;
1839 }
1813 } else { 1840 } else {
1814 printk(IBM_ERR 1841 printk(IBM_ERR
1815 "ThinkPad ACPI EC access misbehaving, " 1842 "ThinkPad ACPI EC access misbehaving, "
@@ -1930,9 +1957,21 @@ static int fan_read(char *p)
1930 if ((rc = fan_get_status(&status)) < 0) 1957 if ((rc = fan_get_status(&status)) < 0)
1931 return rc; 1958 return rc;
1932 1959
1960 if (unlikely(!fan_control_status_known)) {
1961 if (status != fan_control_initial_status)
1962 fan_control_status_known = 1;
1963 else
1964 /* Return most likely status. In fact, it
1965 * might be the only possible status */
1966 status = IBMACPI_FAN_EC_AUTO;
1967 }
1968
1933 len += sprintf(p + len, "status:\t\t%s\n", 1969 len += sprintf(p + len, "status:\t\t%s\n",
1934 (status != 0) ? "enabled" : "disabled"); 1970 (status != 0) ? "enabled" : "disabled");
1935 1971
1972 /* No ThinkPad boots on disengaged mode, we can safely
1973 * assume the tachometer is online if fan control status
1974 * was unknown */
1936 if ((rc = fan_get_speed(&speed)) < 0) 1975 if ((rc = fan_get_speed(&speed)) < 0)
1937 return rc; 1976 return rc;
1938 1977
@@ -1997,6 +2036,8 @@ static int fan_set_level(int level)
1997 2036
1998 if (!acpi_ec_write(fan_status_offset, level)) 2037 if (!acpi_ec_write(fan_status_offset, level))
1999 return -EIO; 2038 return -EIO;
2039 else
2040 fan_control_status_known = 1;
2000 break; 2041 break;
2001 2042
2002 default: 2043 default:
@@ -2022,6 +2063,8 @@ static int fan_set_enable(void)
2022 2063
2023 if (!acpi_ec_write(fan_status_offset, s)) 2064 if (!acpi_ec_write(fan_status_offset, s))
2024 return -EIO; 2065 return -EIO;
2066 else
2067 fan_control_status_known = 1;
2025 break; 2068 break;
2026 2069
2027 case IBMACPI_FAN_WR_ACPI_SFAN: 2070 case IBMACPI_FAN_WR_ACPI_SFAN:
@@ -2051,6 +2094,8 @@ static int fan_set_disable(void)
2051 case IBMACPI_FAN_WR_TPEC: 2094 case IBMACPI_FAN_WR_TPEC:
2052 if (!acpi_ec_write(fan_status_offset, 0x00)) 2095 if (!acpi_ec_write(fan_status_offset, 0x00))
2053 return -EIO; 2096 return -EIO;
2097 else
2098 fan_control_status_known = 1;
2054 break; 2099 break;
2055 2100
2056 case IBMACPI_FAN_WR_ACPI_SFAN: 2101 case IBMACPI_FAN_WR_ACPI_SFAN: