diff options
-rw-r--r-- | drivers/acpi/ibm_acpi.c | 147 |
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 | ||
1846 | static int fan_write(char *buf) | 1846 | static 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) { | 1863 | static 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 | |||
1878 | static 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 | |||
1893 | static 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 | ||
1911 | static 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 | |||
1925 | static 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 | |||
1937 | static 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 | |||
1949 | static 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 | |||
1963 | static 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 | |||
1880 | static struct ibm_struct ibms[] = { | 1983 | static struct ibm_struct ibms[] = { |
1881 | { | 1984 | { |
1882 | .name = "driver", | 1985 | .name = "driver", |