diff options
Diffstat (limited to 'drivers/hwmon/f71882fg.c')
-rw-r--r-- | drivers/hwmon/f71882fg.c | 170 |
1 files changed, 123 insertions, 47 deletions
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index a95fa4256caa..537841ef44b9 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -856,21 +856,19 @@ static inline int superio_inb(int base, int reg) | |||
856 | static int superio_inw(int base, int reg) | 856 | static int superio_inw(int base, int reg) |
857 | { | 857 | { |
858 | int val; | 858 | int val; |
859 | outb(reg++, base); | 859 | val = superio_inb(base, reg) << 8; |
860 | val = inb(base + 1) << 8; | 860 | val |= superio_inb(base, reg + 1); |
861 | outb(reg, base); | ||
862 | val |= inb(base + 1); | ||
863 | return val; | 861 | return val; |
864 | } | 862 | } |
865 | 863 | ||
866 | static inline void superio_enter(int base) | 864 | static inline void superio_enter(int base) |
867 | { | 865 | { |
868 | /* according to the datasheet the key must be send twice! */ | 866 | /* according to the datasheet the key must be send twice! */ |
869 | outb( SIO_UNLOCK_KEY, base); | 867 | outb(SIO_UNLOCK_KEY, base); |
870 | outb( SIO_UNLOCK_KEY, base); | 868 | outb(SIO_UNLOCK_KEY, base); |
871 | } | 869 | } |
872 | 870 | ||
873 | static inline void superio_select( int base, int ld) | 871 | static inline void superio_select(int base, int ld) |
874 | { | 872 | { |
875 | outb(SIO_REG_LDSEL, base); | 873 | outb(SIO_REG_LDSEL, base); |
876 | outb(ld, base + 1); | 874 | outb(ld, base + 1); |
@@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg) | |||
905 | { | 903 | { |
906 | u16 val; | 904 | u16 val; |
907 | 905 | ||
908 | outb(reg++, data->addr + ADDR_REG_OFFSET); | 906 | val = f71882fg_read8(data, reg) << 8; |
909 | val = inb(data->addr + DATA_REG_OFFSET) << 8; | 907 | val |= f71882fg_read8(data, reg + 1); |
910 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
911 | val |= inb(data->addr + DATA_REG_OFFSET); | ||
912 | 908 | ||
913 | return val; | 909 | return val; |
914 | } | 910 | } |
@@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val) | |||
921 | 917 | ||
922 | static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val) | 918 | static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val) |
923 | { | 919 | { |
924 | outb(reg++, data->addr + ADDR_REG_OFFSET); | 920 | f71882fg_write8(data, reg, val >> 8); |
925 | outb(val >> 8, data->addr + DATA_REG_OFFSET); | 921 | f71882fg_write8(data, reg + 1, val & 0xff); |
926 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
927 | outb(val & 255, data->addr + DATA_REG_OFFSET); | ||
928 | } | 922 | } |
929 | 923 | ||
930 | static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr) | 924 | static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr) |
@@ -945,7 +939,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
945 | mutex_lock(&data->update_lock); | 939 | mutex_lock(&data->update_lock); |
946 | 940 | ||
947 | /* Update once every 60 seconds */ | 941 | /* Update once every 60 seconds */ |
948 | if ( time_after(jiffies, data->last_limits + 60 * HZ ) || | 942 | if (time_after(jiffies, data->last_limits + 60 * HZ) || |
949 | !data->valid) { | 943 | !data->valid) { |
950 | if (data->type == f71882fg || data->type == f71889fg) { | 944 | if (data->type == f71882fg || data->type == f71889fg) { |
951 | data->in1_max = | 945 | data->in1_max = |
@@ -1127,8 +1121,12 @@ static ssize_t store_fan_full_speed(struct device *dev, | |||
1127 | const char *buf, size_t count) | 1121 | const char *buf, size_t count) |
1128 | { | 1122 | { |
1129 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1123 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1130 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1124 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1131 | long val = simple_strtol(buf, NULL, 10); | 1125 | long val; |
1126 | |||
1127 | err = strict_strtol(buf, 10, &val); | ||
1128 | if (err) | ||
1129 | return err; | ||
1132 | 1130 | ||
1133 | val = SENSORS_LIMIT(val, 23, 1500000); | 1131 | val = SENSORS_LIMIT(val, 23, 1500000); |
1134 | val = fan_to_reg(val); | 1132 | val = fan_to_reg(val); |
@@ -1157,8 +1155,12 @@ static ssize_t store_fan_beep(struct device *dev, struct device_attribute | |||
1157 | *devattr, const char *buf, size_t count) | 1155 | *devattr, const char *buf, size_t count) |
1158 | { | 1156 | { |
1159 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1157 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1160 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1158 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1161 | unsigned long val = simple_strtoul(buf, NULL, 10); | 1159 | unsigned long val; |
1160 | |||
1161 | err = strict_strtoul(buf, 10, &val); | ||
1162 | if (err) | ||
1163 | return err; | ||
1162 | 1164 | ||
1163 | mutex_lock(&data->update_lock); | 1165 | mutex_lock(&data->update_lock); |
1164 | data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); | 1166 | data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); |
@@ -1206,7 +1208,14 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute | |||
1206 | *devattr, const char *buf, size_t count) | 1208 | *devattr, const char *buf, size_t count) |
1207 | { | 1209 | { |
1208 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1210 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1209 | long val = simple_strtol(buf, NULL, 10) / 8; | 1211 | int err; |
1212 | long val; | ||
1213 | |||
1214 | err = strict_strtol(buf, 10, &val); | ||
1215 | if (err) | ||
1216 | return err; | ||
1217 | |||
1218 | val /= 8; | ||
1210 | val = SENSORS_LIMIT(val, 0, 255); | 1219 | val = SENSORS_LIMIT(val, 0, 255); |
1211 | 1220 | ||
1212 | mutex_lock(&data->update_lock); | 1221 | mutex_lock(&data->update_lock); |
@@ -1233,8 +1242,12 @@ static ssize_t store_in_beep(struct device *dev, struct device_attribute | |||
1233 | *devattr, const char *buf, size_t count) | 1242 | *devattr, const char *buf, size_t count) |
1234 | { | 1243 | { |
1235 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1244 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1236 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1245 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1237 | unsigned long val = simple_strtoul(buf, NULL, 10); | 1246 | unsigned long val; |
1247 | |||
1248 | err = strict_strtoul(buf, 10, &val); | ||
1249 | if (err) | ||
1250 | return err; | ||
1238 | 1251 | ||
1239 | mutex_lock(&data->update_lock); | 1252 | mutex_lock(&data->update_lock); |
1240 | data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); | 1253 | data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); |
@@ -1299,8 +1312,14 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute | |||
1299 | *devattr, const char *buf, size_t count) | 1312 | *devattr, const char *buf, size_t count) |
1300 | { | 1313 | { |
1301 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1314 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1302 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1315 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1303 | long val = simple_strtol(buf, NULL, 10) / 1000; | 1316 | long val; |
1317 | |||
1318 | err = strict_strtol(buf, 10, &val); | ||
1319 | if (err) | ||
1320 | return err; | ||
1321 | |||
1322 | val /= 1000; | ||
1304 | val = SENSORS_LIMIT(val, 0, 255); | 1323 | val = SENSORS_LIMIT(val, 0, 255); |
1305 | 1324 | ||
1306 | mutex_lock(&data->update_lock); | 1325 | mutex_lock(&data->update_lock); |
@@ -1333,10 +1352,16 @@ static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute | |||
1333 | *devattr, const char *buf, size_t count) | 1352 | *devattr, const char *buf, size_t count) |
1334 | { | 1353 | { |
1335 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1354 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1336 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1355 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1337 | long val = simple_strtol(buf, NULL, 10) / 1000; | ||
1338 | ssize_t ret = count; | 1356 | ssize_t ret = count; |
1339 | u8 reg; | 1357 | u8 reg; |
1358 | long val; | ||
1359 | |||
1360 | err = strict_strtol(buf, 10, &val); | ||
1361 | if (err) | ||
1362 | return err; | ||
1363 | |||
1364 | val /= 1000; | ||
1340 | 1365 | ||
1341 | mutex_lock(&data->update_lock); | 1366 | mutex_lock(&data->update_lock); |
1342 | 1367 | ||
@@ -1372,8 +1397,14 @@ static ssize_t store_temp_crit(struct device *dev, struct device_attribute | |||
1372 | *devattr, const char *buf, size_t count) | 1397 | *devattr, const char *buf, size_t count) |
1373 | { | 1398 | { |
1374 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1399 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1375 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1400 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1376 | long val = simple_strtol(buf, NULL, 10) / 1000; | 1401 | long val; |
1402 | |||
1403 | err = strict_strtol(buf, 10, &val); | ||
1404 | if (err) | ||
1405 | return err; | ||
1406 | |||
1407 | val /= 1000; | ||
1377 | val = SENSORS_LIMIT(val, 0, 255); | 1408 | val = SENSORS_LIMIT(val, 0, 255); |
1378 | 1409 | ||
1379 | mutex_lock(&data->update_lock); | 1410 | mutex_lock(&data->update_lock); |
@@ -1427,8 +1458,12 @@ static ssize_t store_temp_beep(struct device *dev, struct device_attribute | |||
1427 | *devattr, const char *buf, size_t count) | 1458 | *devattr, const char *buf, size_t count) |
1428 | { | 1459 | { |
1429 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1460 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1430 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1461 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1431 | unsigned long val = simple_strtoul(buf, NULL, 10); | 1462 | unsigned long val; |
1463 | |||
1464 | err = strict_strtoul(buf, 10, &val); | ||
1465 | if (err) | ||
1466 | return err; | ||
1432 | 1467 | ||
1433 | mutex_lock(&data->update_lock); | 1468 | mutex_lock(&data->update_lock); |
1434 | data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); | 1469 | data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); |
@@ -1490,8 +1525,13 @@ static ssize_t store_pwm(struct device *dev, | |||
1490 | size_t count) | 1525 | size_t count) |
1491 | { | 1526 | { |
1492 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1527 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1493 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1528 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1494 | long val = simple_strtol(buf, NULL, 10); | 1529 | long val; |
1530 | |||
1531 | err = strict_strtol(buf, 10, &val); | ||
1532 | if (err) | ||
1533 | return err; | ||
1534 | |||
1495 | val = SENSORS_LIMIT(val, 0, 255); | 1535 | val = SENSORS_LIMIT(val, 0, 255); |
1496 | 1536 | ||
1497 | mutex_lock(&data->update_lock); | 1537 | mutex_lock(&data->update_lock); |
@@ -1551,8 +1591,12 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute | |||
1551 | *devattr, const char *buf, size_t count) | 1591 | *devattr, const char *buf, size_t count) |
1552 | { | 1592 | { |
1553 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1593 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1554 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1594 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1555 | long val = simple_strtol(buf, NULL, 10); | 1595 | long val; |
1596 | |||
1597 | err = strict_strtol(buf, 10, &val); | ||
1598 | if (err) | ||
1599 | return err; | ||
1556 | 1600 | ||
1557 | /* Special case for F8000 pwm channel 3 which only does auto mode */ | 1601 | /* Special case for F8000 pwm channel 3 which only does auto mode */ |
1558 | if (data->type == f8000 && nr == 2 && val != 2) | 1602 | if (data->type == f8000 && nr == 2 && val != 2) |
@@ -1626,9 +1670,14 @@ static ssize_t store_pwm_auto_point_pwm(struct device *dev, | |||
1626 | const char *buf, size_t count) | 1670 | const char *buf, size_t count) |
1627 | { | 1671 | { |
1628 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1672 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1629 | int pwm = to_sensor_dev_attr_2(devattr)->index; | 1673 | int err, pwm = to_sensor_dev_attr_2(devattr)->index; |
1630 | int point = to_sensor_dev_attr_2(devattr)->nr; | 1674 | int point = to_sensor_dev_attr_2(devattr)->nr; |
1631 | long val = simple_strtol(buf, NULL, 10); | 1675 | long val; |
1676 | |||
1677 | err = strict_strtol(buf, 10, &val); | ||
1678 | if (err) | ||
1679 | return err; | ||
1680 | |||
1632 | val = SENSORS_LIMIT(val, 0, 255); | 1681 | val = SENSORS_LIMIT(val, 0, 255); |
1633 | 1682 | ||
1634 | mutex_lock(&data->update_lock); | 1683 | mutex_lock(&data->update_lock); |
@@ -1674,10 +1723,16 @@ static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev, | |||
1674 | const char *buf, size_t count) | 1723 | const char *buf, size_t count) |
1675 | { | 1724 | { |
1676 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1725 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1677 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1726 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1678 | int point = to_sensor_dev_attr_2(devattr)->nr; | 1727 | int point = to_sensor_dev_attr_2(devattr)->nr; |
1679 | long val = simple_strtol(buf, NULL, 10) / 1000; | ||
1680 | u8 reg; | 1728 | u8 reg; |
1729 | long val; | ||
1730 | |||
1731 | err = strict_strtol(buf, 10, &val); | ||
1732 | if (err) | ||
1733 | return err; | ||
1734 | |||
1735 | val /= 1000; | ||
1681 | 1736 | ||
1682 | mutex_lock(&data->update_lock); | 1737 | mutex_lock(&data->update_lock); |
1683 | data->pwm_auto_point_temp[nr][point] = | 1738 | data->pwm_auto_point_temp[nr][point] = |
@@ -1716,8 +1771,12 @@ static ssize_t store_pwm_interpolate(struct device *dev, | |||
1716 | const char *buf, size_t count) | 1771 | const char *buf, size_t count) |
1717 | { | 1772 | { |
1718 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1773 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1719 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1774 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1720 | unsigned long val = simple_strtoul(buf, NULL, 10); | 1775 | unsigned long val; |
1776 | |||
1777 | err = strict_strtoul(buf, 10, &val); | ||
1778 | if (err) | ||
1779 | return err; | ||
1721 | 1780 | ||
1722 | mutex_lock(&data->update_lock); | 1781 | mutex_lock(&data->update_lock); |
1723 | data->pwm_auto_point_mapping[nr] = | 1782 | data->pwm_auto_point_mapping[nr] = |
@@ -1752,8 +1811,12 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev, | |||
1752 | const char *buf, size_t count) | 1811 | const char *buf, size_t count) |
1753 | { | 1812 | { |
1754 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1813 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1755 | int nr = to_sensor_dev_attr_2(devattr)->index; | 1814 | int err, nr = to_sensor_dev_attr_2(devattr)->index; |
1756 | long val = simple_strtol(buf, NULL, 10); | 1815 | long val; |
1816 | |||
1817 | err = strict_strtol(buf, 10, &val); | ||
1818 | if (err) | ||
1819 | return err; | ||
1757 | 1820 | ||
1758 | switch (val) { | 1821 | switch (val) { |
1759 | case 1: | 1822 | case 1: |
@@ -1798,9 +1861,15 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev, | |||
1798 | const char *buf, size_t count) | 1861 | const char *buf, size_t count) |
1799 | { | 1862 | { |
1800 | struct f71882fg_data *data = dev_get_drvdata(dev); | 1863 | struct f71882fg_data *data = dev_get_drvdata(dev); |
1801 | int pwm = to_sensor_dev_attr_2(devattr)->index; | 1864 | int err, pwm = to_sensor_dev_attr_2(devattr)->index; |
1802 | int point = to_sensor_dev_attr_2(devattr)->nr; | 1865 | int point = to_sensor_dev_attr_2(devattr)->nr; |
1803 | long val = simple_strtol(buf, NULL, 10) / 1000; | 1866 | long val; |
1867 | |||
1868 | err = strict_strtol(buf, 10, &val); | ||
1869 | if (err) | ||
1870 | return err; | ||
1871 | |||
1872 | val /= 1000; | ||
1804 | 1873 | ||
1805 | if (data->type == f71889fg) | 1874 | if (data->type == f71889fg) |
1806 | val = SENSORS_LIMIT(val, -128, 127); | 1875 | val = SENSORS_LIMIT(val, -128, 127); |
@@ -2109,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2109 | int err = -ENODEV; | 2178 | int err = -ENODEV; |
2110 | u16 devid; | 2179 | u16 devid; |
2111 | 2180 | ||
2181 | /* Don't step on other drivers' I/O space by accident */ | ||
2182 | if (!request_region(sioaddr, 2, DRVNAME)) { | ||
2183 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
2184 | (int)sioaddr); | ||
2185 | return -EBUSY; | ||
2186 | } | ||
2187 | |||
2112 | superio_enter(sioaddr); | 2188 | superio_enter(sioaddr); |
2113 | 2189 | ||
2114 | devid = superio_inw(sioaddr, SIO_REG_MANID); | 2190 | devid = superio_inw(sioaddr, SIO_REG_MANID); |
@@ -2151,8 +2227,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2151 | } | 2227 | } |
2152 | 2228 | ||
2153 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | 2229 | *address = superio_inw(sioaddr, SIO_REG_ADDR); |
2154 | if (*address == 0) | 2230 | if (*address == 0) { |
2155 | { | ||
2156 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); | 2231 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); |
2157 | goto exit; | 2232 | goto exit; |
2158 | } | 2233 | } |
@@ -2164,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2164 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); | 2239 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); |
2165 | exit: | 2240 | exit: |
2166 | superio_exit(sioaddr); | 2241 | superio_exit(sioaddr); |
2242 | release_region(sioaddr, 2); | ||
2167 | return err; | 2243 | return err; |
2168 | } | 2244 | } |
2169 | 2245 | ||