ftrace: cleanups
[safe/jmp/linux-2.6] / drivers / hwmon / w83793.c
index 99e603a..ed3c019 100644 (file)
@@ -37,7 +37,8 @@
 #include <linux/mutex.h>
 
 /* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
+                                               I2C_CLIENT_END };
 
 /* Insmod parameters */
 I2C_CLIENT_INSMOD_1(w83793);
@@ -131,6 +132,7 @@ static u8 scale_in_add[] = { 0, 0, 0, 0, 0, 0, 0, 150, 150, 0 };
 #define PWM_DUTY                       0
 #define PWM_START                      1
 #define PWM_NONSTOP                    2
+#define PWM_STOP_TIME                  3
 #define W83793_REG_PWM(index, nr)      (((nr) == 0 ? 0xb3 : \
                                         (nr) == 1 ? 0x220 : 0x218) + (index))
 
@@ -179,7 +181,7 @@ static inline s8 TEMP_TO_REG(long val, s8 min, s8 max)
 struct w83793_data {
        struct i2c_client client;
        struct i2c_client *lm75[2];
-       struct class_device *class_dev;
+       struct device *hwmon_dev;
        struct mutex update_lock;
        char valid;                     /* !=0 if following fields are valid */
        unsigned long last_updated;     /* In jiffies */
@@ -204,6 +206,8 @@ struct w83793_data {
        u8 temp_fan_map[6];     /* Temp controls which pwm fan, bit field */
 
        u8 has_pwm;
+       u8 has_temp;
+       u8 has_vid;
        u8 pwm_enable;          /* Register value, each Temp has 1 bit */
        u8 pwm_uptime;          /* Register value */
        u8 pwm_downtime;        /* Register value */
@@ -240,9 +244,7 @@ static struct i2c_driver w83793_driver = {
 static ssize_t
 show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct w83793_data *data = i2c_get_clientdata(client);
-
+       struct w83793_data *data = dev_get_drvdata(dev);
        return sprintf(buf, "%d\n", data->vrm);
 }
 
@@ -261,9 +263,7 @@ static ssize_t
 store_vrm(struct device *dev, struct device_attribute *attr,
          const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct w83793_data *data = i2c_get_clientdata(client);
-
+       struct w83793_data *data = dev_get_drvdata(dev);
        data->vrm = simple_strtoul(buf, NULL, 10);
        return count;
 }
@@ -405,10 +405,6 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-#define PWM_DUTY                       0
-#define PWM_START                      1
-#define PWM_NONSTOP                    2
-#define PWM_STOP_TIME                  3
 static ssize_t
 show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -554,8 +550,7 @@ store_temp_mode(struct device *dev, struct device_attribute *attr,
        if ((val == 6) && (index < 4)) {
                val -= 3;
        } else if ((val == 3 && index < 4)
-               || (val == 4 && index >= 4)
-               || val == 0) {
+               || (val == 4 && index >= 4)) {
                /* transform diode or thermistor into internal enable */
                val = !!val;
        } else {
@@ -986,12 +981,6 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = {
        SENSOR_ATTR_IN(7),
        SENSOR_ATTR_IN(8),
        SENSOR_ATTR_IN(9),
-       SENSOR_ATTR_TEMP(1),
-       SENSOR_ATTR_TEMP(2),
-       SENSOR_ATTR_TEMP(3),
-       SENSOR_ATTR_TEMP(4),
-       SENSOR_ATTR_TEMP(5),
-       SENSOR_ATTR_TEMP(6),
        SENSOR_ATTR_FAN(1),
        SENSOR_ATTR_FAN(2),
        SENSOR_ATTR_FAN(3),
@@ -1002,6 +991,15 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = {
        SENSOR_ATTR_PWM(3),
 };
 
+static struct sensor_device_attribute_2 w83793_temp[] = {
+       SENSOR_ATTR_TEMP(1),
+       SENSOR_ATTR_TEMP(2),
+       SENSOR_ATTR_TEMP(3),
+       SENSOR_ATTR_TEMP(4),
+       SENSOR_ATTR_TEMP(5),
+       SENSOR_ATTR_TEMP(6),
+};
+
 /* Fan6-Fan12 */
 static struct sensor_device_attribute_2 w83793_left_fan[] = {
        SENSOR_ATTR_FAN(6),
@@ -1022,11 +1020,13 @@ static struct sensor_device_attribute_2 w83793_left_pwm[] = {
        SENSOR_ATTR_PWM(8),
 };
 
-static struct sensor_device_attribute_2 sda_single_files[] = {
+static struct sensor_device_attribute_2 w83793_vid[] = {
        SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0),
        SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1),
-       SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm,
-                     NOT_USED, NOT_USED),
+};
+static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm);
+
+static struct sensor_device_attribute_2 sda_single_files[] = {
        SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep,
                      store_chassis_clear, ALARM_STATUS, 30),
        SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable,
@@ -1068,7 +1068,7 @@ static int w83793_detach_client(struct i2c_client *client)
 
        /* main client */
        if (data) {
-               hwmon_device_unregister(data->class_dev);
+               hwmon_device_unregister(data->hwmon_dev);
 
                for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++)
                        device_remove_file(dev,
@@ -1077,11 +1077,18 @@ static int w83793_detach_client(struct i2c_client *client)
                for (i = 0; i < ARRAY_SIZE(sda_single_files); i++)
                        device_remove_file(dev, &sda_single_files[i].dev_attr);
 
+               for (i = 0; i < ARRAY_SIZE(w83793_vid); i++)
+                       device_remove_file(dev, &w83793_vid[i].dev_attr);
+               device_remove_file(dev, &dev_attr_vrm);
+
                for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
                        device_remove_file(dev, &w83793_left_fan[i].dev_attr);
 
                for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++)
                        device_remove_file(dev, &w83793_left_pwm[i].dev_attr);
+
+               for (i = 0; i < ARRAY_SIZE(w83793_temp); i++)
+                       device_remove_file(dev, &w83793_temp[i].dev_attr);
        }
 
        if ((err = i2c_detach_client(client)))
@@ -1194,6 +1201,7 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
        struct w83793_data *data;
        int files_fan = ARRAY_SIZE(w83793_left_fan) / 7;
        int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5;
+       int files_temp = ARRAY_SIZE(w83793_temp) / 6;
        int err = 0;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -1274,7 +1282,6 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
        /* Initialize the chip */
        w83793_init_client(client);
 
-       data->vrm = vid_which_vrm();
        /*
           Only fan 1-5 has their own input pins,
           Pwm 1-3 has their own pins
@@ -1285,7 +1292,9 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
        val = w83793_read_value(client, W83793_REG_FANIN_CTRL);
 
        /* check the function of pins 49-56 */
-       if (!(tmp & 0x80)) {
+       if (tmp & 0x80) {
+               data->has_vid |= 0x2;   /* has VIDB */
+       } else {
                data->has_pwm |= 0x18;  /* pwm 4,5 */
                if (val & 0x01) {       /* fan 6 */
                        data->has_fan |= 0x20;
@@ -1301,13 +1310,15 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
                }
        }
 
+       /* check the function of pins 37-40 */
+       if (!(tmp & 0x29))
+               data->has_vid |= 0x1;   /* has VIDA */
        if (0x08 == (tmp & 0x0c)) {
                if (val & 0x08) /* fan 9 */
                        data->has_fan |= 0x100;
                if (val & 0x10) /* fan 10 */
                        data->has_fan |= 0x200;
        }
-
        if (0x20 == (tmp & 0x30)) {
                if (val & 0x20) /* fan 11 */
                        data->has_fan |= 0x400;
@@ -1320,6 +1331,37 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
                data->has_pwm |= 0x80;
        }
 
+       tmp = w83793_read_value(client, W83793_REG_FANIN_SEL);
+       if ((tmp & 0x01) && (val & 0x08)) {     /* fan 9, second location */
+               data->has_fan |= 0x100;
+       }
+       if ((tmp & 0x02) && (val & 0x10)) {     /* fan 10, second location */
+               data->has_fan |= 0x200;
+       }
+       if ((tmp & 0x04) && (val & 0x20)) {     /* fan 11, second location */
+               data->has_fan |= 0x400;
+       }
+       if ((tmp & 0x08) && (val & 0x40)) {     /* fan 12, second location */
+               data->has_fan |= 0x800;
+       }
+
+       /* check the temp1-6 mode, ignore former AMDSI selected inputs */
+       tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[0]);
+       if (tmp & 0x01)
+               data->has_temp |= 0x01;
+       if (tmp & 0x04)
+               data->has_temp |= 0x02;
+       if (tmp & 0x10)
+               data->has_temp |= 0x04;
+       if (tmp & 0x40)
+               data->has_temp |= 0x08;
+
+       tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[1]);
+       if (tmp & 0x01)
+               data->has_temp |= 0x10;
+       if (tmp & 0x02)
+               data->has_temp |= 0x20;
+
        /* Register sysfs hooks */
        for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) {
                err = device_create_file(dev,
@@ -1328,6 +1370,20 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
                        goto exit_remove;
        }
 
+       for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) {
+               if (!(data->has_vid & (1 << i)))
+                       continue;
+               err = device_create_file(dev, &w83793_vid[i].dev_attr);
+               if (err)
+                       goto exit_remove;
+       }
+       if (data->has_vid) {
+               data->vrm = vid_which_vrm();
+               err = device_create_file(dev, &dev_attr_vrm);
+               if (err)
+                       goto exit_remove;
+       }
+
        for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) {
                err = device_create_file(dev, &sda_single_files[i].dev_attr);
                if (err)
@@ -1335,6 +1391,19 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
 
        }
 
+       for (i = 0; i < 6; i++) {
+               int j;
+               if (!(data->has_temp & (1 << i)))
+                       continue;
+               for (j = 0; j < files_temp; j++) {
+                       err = device_create_file(dev,
+                                               &w83793_temp[(i) * files_temp
+                                                               + j].dev_attr);
+                       if (err)
+                               goto exit_remove;
+               }
+       }
+
        for (i = 5; i < 12; i++) {
                int j;
                if (!(data->has_fan & (1 << i)))
@@ -1361,9 +1430,9 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind)
                }
        }
 
-       data->class_dev = hwmon_device_register(dev);
-       if (IS_ERR(data->class_dev)) {
-               err = PTR_ERR(data->class_dev);
+       data->hwmon_dev = hwmon_device_register(dev);
+       if (IS_ERR(data->hwmon_dev)) {
+               err = PTR_ERR(data->hwmon_dev);
                goto exit_remove;
        }
 
@@ -1378,12 +1447,18 @@ exit_remove:
        for (i = 0; i < ARRAY_SIZE(sda_single_files); i++)
                device_remove_file(dev, &sda_single_files[i].dev_attr);
 
+       for (i = 0; i < ARRAY_SIZE(w83793_vid); i++)
+               device_remove_file(dev, &w83793_vid[i].dev_attr);
+
        for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++)
                device_remove_file(dev, &w83793_left_fan[i].dev_attr);
 
        for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++)
                device_remove_file(dev, &w83793_left_pwm[i].dev_attr);
 
+       for (i = 0; i < ARRAY_SIZE(w83793_temp); i++)
+               device_remove_file(dev, &w83793_temp[i].dev_attr);
+
        if (data->lm75[0] != NULL) {
                i2c_detach_client(data->lm75[0]);
                kfree(data->lm75[0]);
@@ -1435,6 +1510,8 @@ static void w83793_update_nonvolatile(struct device *dev)
        }
 
        for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) {
+               if (!(data->has_temp & (1 << i)))
+                       continue;
                data->temp_fan_map[i] =
                    w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i));
                for (j = 1; j < 5; j++) {
@@ -1517,9 +1594,12 @@ static struct w83793_data *w83793_update_device(struct device *dev)
                    w83793_read_value(client, W83793_REG_FAN(i) + 1);
        }
 
-       for (i = 0; i < ARRAY_SIZE(data->temp); i++)
+       for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
+               if (!(data->has_temp & (1 << i)))
+                       continue;
                data->temp[i][TEMP_READ] =
                    w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]);
+       }
 
        data->temp_low_bits =
            w83793_read_value(client, W83793_REG_TEMP_LOW_BITS);
@@ -1534,8 +1614,10 @@ static struct w83793_data *w83793_update_device(struct device *dev)
        for (i = 0; i < ARRAY_SIZE(data->alarms); i++)
                data->alarms[i] =
                    w83793_read_value(client, W83793_REG_ALARM(i));
-       data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA);
-       data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB);
+       if (data->has_vid & 0x01)
+               data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA);
+       if (data->has_vid & 0x02)
+               data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB);
        w83793_update_nonvolatile(dev);
        data->last_updated = jiffies;
        data->valid = 1;