aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/ibm_acpi.c147
1 files changed, 125 insertions, 22 deletions
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 9275dfc130f2..187af1bfcb9d 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1843,40 +1843,143 @@ static int fan_read(char *p)
1843 return len; 1843 return len;
1844} 1844}
1845 1845
1846static int fan_write(char *buf) 1846static int fan_set_level(int level)
1847{ 1847{
1848 char *cmd; 1848 switch (fan_control_access_mode) {
1849 int level, speed; 1849 case IBMACPI_FAN_WR_ACPI_SFAN:
1850 1850 if (level >= 0 && level <= 7) {
1851 while ((cmd = next_cmd(&buf))) {
1852 if (sfan_handle &&
1853 sscanf(cmd, "level %d", &level) == 1 &&
1854 level >= 0 && level <= 7) {
1855 /* 570, 770x-JL */
1856 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level)) 1851 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
1857 return -EIO; 1852 return -EIO;
1858 } else if (!gfan_handle && strlencmp(cmd, "enable") == 0) { 1853 } else
1859 /* all except 570, 600e/x, 770e, 770x */ 1854 return -EINVAL;
1860 if (!acpi_ec_write(fan_status_offset, 0x80)) 1855 break;
1861 return -EIO; 1856
1862 } else if (!gfan_handle && strlencmp(cmd, "disable") == 0) { 1857 default:
1863 /* all except 570, 600e/x, 770e, 770x */ 1858 return -ENXIO;
1864 if (!acpi_ec_write(fan_status_offset, 0x00)) 1859 }
1865 return -EIO; 1860 return 0;
1866 } else if (fans_handle && 1861}
1867 sscanf(cmd, "speed %d", &speed) == 1 && 1862
1868 speed >= 0 && speed <= 65535) { 1863static int fan_set_enable(void)
1869 /* X31, X40 */ 1864{
1865 switch (fan_control_access_mode) {
1866 case IBMACPI_FAN_WR_ACPI_FANS:
1867 case IBMACPI_FAN_WR_TPEC:
1868 if (!acpi_ec_write(fan_status_offset, 0x80))
1869 return -EIO;
1870 break;
1871
1872 default:
1873 return -ENXIO;
1874 }
1875 return 0;
1876}
1877
1878static int fan_set_disable(void)
1879{
1880 switch (fan_control_access_mode) {
1881 case IBMACPI_FAN_WR_ACPI_FANS:
1882 case IBMACPI_FAN_WR_TPEC:
1883 if (!acpi_ec_write(fan_status_offset, 0x00))
1884 return -EIO;
1885 break;
1886
1887 default:
1888 return -ENXIO;
1889 }
1890 return 0;
1891}
1892
1893static int fan_set_speed(int speed)
1894{
1895 switch (fan_control_access_mode) {
1896 case IBMACPI_FAN_WR_ACPI_FANS:
1897 if (speed >= 0 && speed <= 65535) {
1870 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd", 1898 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
1871 speed, speed, speed)) 1899 speed, speed, speed))
1872 return -EIO; 1900 return -EIO;
1873 } else 1901 } else
1874 return -EINVAL; 1902 return -EINVAL;
1875 } 1903 break;
1876 1904
1905 default:
1906 return -ENXIO;
1907 }
1877 return 0; 1908 return 0;
1878} 1909}
1879 1910
1911static int fan_write_cmd_level(const char *cmd, int *rc)
1912{
1913 int level;
1914
1915 if (sscanf(cmd, "level %d", &level) != 1)
1916 return 0;
1917
1918 if ((*rc = fan_set_level(level)) == -ENXIO)
1919 printk(IBM_ERR "level command accepted for unsupported "
1920 "access mode %d", fan_control_access_mode);
1921
1922 return 1;
1923}
1924
1925static int fan_write_cmd_enable(const char *cmd, int *rc)
1926{
1927 if (strlencmp(cmd, "enable") != 0)
1928 return 0;
1929
1930 if ((*rc = fan_set_enable()) == -ENXIO)
1931 printk(IBM_ERR "enable command accepted for unsupported "
1932 "access mode %d", fan_control_access_mode);
1933
1934 return 1;
1935}
1936
1937static int fan_write_cmd_disable(const char *cmd, int *rc)
1938{
1939 if (strlencmp(cmd, "disable") != 0)
1940 return 0;
1941
1942 if ((*rc = fan_set_disable()) == -ENXIO)
1943 printk(IBM_ERR "disable command accepted for unsupported "
1944 "access mode %d", fan_control_access_mode);
1945
1946 return 1;
1947}
1948
1949static int fan_write_cmd_speed(const char *cmd, int *rc)
1950{
1951 int speed;
1952
1953 if (sscanf(cmd, "speed %d", &speed) != 1)
1954 return 0;
1955
1956 if ((*rc = fan_set_speed(speed)) == -ENXIO)
1957 printk(IBM_ERR "speed command accepted for unsupported "
1958 "access mode %d", fan_control_access_mode);
1959
1960 return 1;
1961}
1962
1963static int fan_write(char *buf)
1964{
1965 char *cmd;
1966 int rc = 0;
1967
1968 while (!rc && (cmd = next_cmd(&buf))) {
1969 if (!((fan_control_commands & IBMACPI_FAN_CMD_LEVEL) &&
1970 fan_write_cmd_level(cmd, &rc)) &&
1971 !((fan_control_commands & IBMACPI_FAN_CMD_ENABLE) &&
1972 (fan_write_cmd_enable(cmd, &rc) ||
1973 fan_write_cmd_disable(cmd, &rc))) &&
1974 !((fan_control_commands & IBMACPI_FAN_CMD_SPEED) &&
1975 fan_write_cmd_speed(cmd, &rc))
1976 )
1977 rc = -EINVAL;
1978 }
1979
1980 return rc;
1981}
1982
1880static struct ibm_struct ibms[] = { 1983static struct ibm_struct ibms[] = {
1881 { 1984 {
1882 .name = "driver", 1985 .name = "driver",