isofs: Fix unchecked printing of ER records
[pandora-kernel.git] / drivers / hwmon / w83627ehf.c
index 483cb26..b6a3ce3 100644 (file)
@@ -39,7 +39,7 @@
                                               0x8860 0xa1
     w83627dhg    9      5       4       3      0xa020 0xc1    0x5ca3
     w83627dhg-p  9      5       4       3      0xb070 0xc1    0x5ca3
-    w83627uhg    8      2       2       2      0xa230 0xc1    0x5ca3
+    w83627uhg    8      2       2       3      0xa230 0xc1    0x5ca3
     w83667hg     9      5       3       3      0xa510 0xc1    0x5ca3
     w83667hg-b   9      5       3       4      0xb350 0xc1    0x5ca3
     nct6775f     9      4       3       9      0xb470 0xc1    0x5ca3
@@ -1319,6 +1319,7 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
 {
        struct w83627ehf_data *data = dev_get_drvdata(dev);
        struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+       struct w83627ehf_sio_data *sio_data = dev->platform_data;
        int nr = sensor_attr->index;
        unsigned long val;
        int err;
@@ -1330,6 +1331,11 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
 
        if (val > 1)
                return -EINVAL;
+
+       /* On NCT67766F, DC mode is only supported for pwm1 */
+       if (sio_data->kind == nct6776 && nr && val != 1)
+               return -EINVAL;
+
        mutex_lock(&data->update_lock);
        reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]);
        data->pwm_mode[nr] = val;
@@ -1601,7 +1607,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \
        val = step_time_to_reg(val, data->pwm_mode[nr]); \
        mutex_lock(&data->update_lock); \
        data->reg[nr] = val; \
-       w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \
+       w83627ehf_write_value(data, data->REG_##REG[nr], val); \
        mutex_unlock(&data->update_lock); \
        return count; \
 } \
@@ -1835,12 +1841,15 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data,
                diode = 0x70;
        }
        for (i = 0; i < 3; i++) {
-               const char *label = data->temp_label[data->temp_src[i]];
+               const char *label = NULL;
+
+               if (data->temp_label)
+                       label = data->temp_label[data->temp_src[i]];
 
                /* Digital source overrides analog type */
-               if (strncmp(label, "PECI", 4) == 0)
+               if (label && strncmp(label, "PECI", 4) == 0)
                        data->temp_type[i] = 6;
-               else if (strncmp(label, "AMD", 3) == 0)
+               else if (label && strncmp(label, "AMD", 3) == 0)
                        data->temp_type[i] = 5;
                else if ((tmp & (0x02 << i)))
                        data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3;
@@ -1911,9 +1920,26 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
                fan4min = 0;
                fan5pin = 0;
        } else if (sio_data->kind == nct6776) {
-               fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
-               fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01);
-               fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02);
+               bool gpok = superio_inb(sio_data->sioreg, 0x27) & 0x80;
+
+               superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
+               regval = superio_inb(sio_data->sioreg, SIO_REG_ENABLE);
+
+               if (regval & 0x80)
+                       fan3pin = gpok;
+               else
+                       fan3pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x40);
+
+               if (regval & 0x40)
+                       fan4pin = gpok;
+               else
+                       fan4pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x01);
+
+               if (regval & 0x20)
+                       fan5pin = gpok;
+               else
+                       fan5pin = !!(superio_inb(sio_data->sioreg, 0x1C) & 0x02);
+
                fan4min = fan4pin;
        } else if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) {
                fan3pin = 1;
@@ -1978,7 +2004,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
                goto exit;
        }
 
-       data = kzalloc(sizeof(struct w83627ehf_data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(struct w83627ehf_data),
+                           GFP_KERNEL);
        if (!data) {
                err = -ENOMEM;
                goto exit_release;
@@ -1988,6 +2015,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
        mutex_init(&data->lock);
        mutex_init(&data->update_lock);
        data->name = w83627ehf_device_names[sio_data->kind];
+       data->bank = 0xff;              /* Force initial bank selection */
        platform_set_drvdata(pdev, data);
 
        /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
@@ -2131,16 +2159,16 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
                w83627ehf_set_temp_reg_ehf(data, 3);
 
                /*
-                * Temperature sources for temp1 and temp2 are selected with
+                * Temperature sources for temp2 and temp3 are selected with
                 * bank 0, registers 0x49 and 0x4a.
                 */
                data->temp_src[0] = 0;  /* SYSTIN */
                reg = w83627ehf_read_value(data, 0x49) & 0x07;
                /* Adjust to have the same mapping as other source registers */
                if (reg == 0)
-                       data->temp_src[1]++;
+                       data->temp_src[1] = 1;
                else if (reg >= 2 && reg <= 5)
-                       data->temp_src[1] += 2;
+                       data->temp_src[1] = reg + 2;
                else    /* should never happen */
                        data->have_temp &= ~(1 << 1);
                reg = w83627ehf_read_value(data, 0x4a);
@@ -2472,9 +2500,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
 
 exit_remove:
        w83627ehf_device_remove_files(dev);
-       kfree(data);
-       platform_set_drvdata(pdev, NULL);
 exit_release:
+       platform_set_drvdata(pdev, NULL);
        release_region(res->start, IOREGION_LENGTH);
 exit:
        return err;
@@ -2488,7 +2515,6 @@ static int __devexit w83627ehf_remove(struct platform_device *pdev)
        w83627ehf_device_remove_files(&pdev->dev);
        release_region(data->addr, IOREGION_LENGTH);
        platform_set_drvdata(pdev, NULL);
-       kfree(data);
 
        return 0;
 }