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) static int superio_inw(int base, int reg) { int val; - outb(reg++, base); - val = inb(base + 1) << 8; - outb(reg, base); - val |= inb(base + 1); + val = superio_inb(base, reg) << 8; + val |= superio_inb(base, reg + 1); return val; } static inline void superio_enter(int base) { /* according to the datasheet the key must be send twice! */ - outb( SIO_UNLOCK_KEY, base); - outb( SIO_UNLOCK_KEY, base); + outb(SIO_UNLOCK_KEY, base); + outb(SIO_UNLOCK_KEY, base); } -static inline void superio_select( int base, int ld) +static inline void superio_select(int base, int ld) { outb(SIO_REG_LDSEL, base); outb(ld, base + 1); @@ -905,10 +903,8 @@ static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg) { u16 val; - outb(reg++, data->addr + ADDR_REG_OFFSET); - val = inb(data->addr + DATA_REG_OFFSET) << 8; - outb(reg, data->addr + ADDR_REG_OFFSET); - val |= inb(data->addr + DATA_REG_OFFSET); + val = f71882fg_read8(data, reg) << 8; + val |= f71882fg_read8(data, reg + 1); return val; } @@ -921,10 +917,8 @@ static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val) static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val) { - outb(reg++, data->addr + ADDR_REG_OFFSET); - outb(val >> 8, data->addr + DATA_REG_OFFSET); - outb(reg, data->addr + ADDR_REG_OFFSET); - outb(val & 255, data->addr + DATA_REG_OFFSET); + f71882fg_write8(data, reg, val >> 8); + f71882fg_write8(data, reg + 1, val & 0xff); } 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) mutex_lock(&data->update_lock); /* Update once every 60 seconds */ - if ( time_after(jiffies, data->last_limits + 60 * HZ ) || + if (time_after(jiffies, data->last_limits + 60 * HZ) || !data->valid) { if (data->type == f71882fg || data->type == f71889fg) { data->in1_max = @@ -1127,8 +1121,12 @@ static ssize_t store_fan_full_speed(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; val = SENSORS_LIMIT(val, 23, 1500000); val = fan_to_reg(val); @@ -1157,8 +1155,12 @@ static ssize_t store_fan_beep(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + unsigned long val; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); 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 *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - long val = simple_strtol(buf, NULL, 10) / 8; + int err; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 8; val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); @@ -1233,8 +1242,12 @@ static ssize_t store_in_beep(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + unsigned long val; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); 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 *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10) / 1000; + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 1000; val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); @@ -1333,10 +1352,16 @@ static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10) / 1000; + int err, nr = to_sensor_dev_attr_2(devattr)->index; ssize_t ret = count; u8 reg; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 1000; mutex_lock(&data->update_lock); @@ -1372,8 +1397,14 @@ static ssize_t store_temp_crit(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10) / 1000; + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 1000; val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); @@ -1427,8 +1458,12 @@ static ssize_t store_temp_beep(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + unsigned long val; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); @@ -1490,8 +1525,13 @@ static ssize_t store_pwm(struct device *dev, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); @@ -1551,8 +1591,12 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; /* Special case for F8000 pwm channel 3 which only does auto mode */ if (data->type == f8000 && nr == 2 && val != 2) @@ -1626,9 +1670,14 @@ static ssize_t store_pwm_auto_point_pwm(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int pwm = to_sensor_dev_attr_2(devattr)->index; + int err, pwm = to_sensor_dev_attr_2(devattr)->index; int point = to_sensor_dev_attr_2(devattr)->nr; - long val = simple_strtol(buf, NULL, 10); + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + val = SENSORS_LIMIT(val, 0, 255); mutex_lock(&data->update_lock); @@ -1674,10 +1723,16 @@ static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; + int err, nr = to_sensor_dev_attr_2(devattr)->index; int point = to_sensor_dev_attr_2(devattr)->nr; - long val = simple_strtol(buf, NULL, 10) / 1000; u8 reg; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 1000; mutex_lock(&data->update_lock); data->pwm_auto_point_temp[nr][point] = @@ -1716,8 +1771,12 @@ static ssize_t store_pwm_interpolate(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - unsigned long val = simple_strtoul(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + unsigned long val; + + err = strict_strtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); data->pwm_auto_point_mapping[nr] = @@ -1752,8 +1811,12 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int nr = to_sensor_dev_attr_2(devattr)->index; - long val = simple_strtol(buf, NULL, 10); + int err, nr = to_sensor_dev_attr_2(devattr)->index; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; switch (val) { case 1: @@ -1798,9 +1861,15 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev, const char *buf, size_t count) { struct f71882fg_data *data = dev_get_drvdata(dev); - int pwm = to_sensor_dev_attr_2(devattr)->index; + int err, pwm = to_sensor_dev_attr_2(devattr)->index; int point = to_sensor_dev_attr_2(devattr)->nr; - long val = simple_strtol(buf, NULL, 10) / 1000; + long val; + + err = strict_strtol(buf, 10, &val); + if (err) + return err; + + val /= 1000; if (data->type == f71889fg) val = SENSORS_LIMIT(val, -128, 127); @@ -2109,6 +2178,13 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, int err = -ENODEV; u16 devid; + /* Don't step on other drivers' I/O space by accident */ + if (!request_region(sioaddr, 2, DRVNAME)) { + printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", + (int)sioaddr); + return -EBUSY; + } + superio_enter(sioaddr); devid = superio_inw(sioaddr, SIO_REG_MANID); @@ -2151,8 +2227,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, } *address = superio_inw(sioaddr, SIO_REG_ADDR); - if (*address == 0) - { + if (*address == 0) { printk(KERN_WARNING DRVNAME ": Base address not set\n"); goto exit; } @@ -2164,6 +2239,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, (int)superio_inb(sioaddr, SIO_REG_DEVREV)); exit: superio_exit(sioaddr); + release_region(sioaddr, 2); return err; } |