]> git.sur5r.net Git - groeck-nct6775/commitdiff
sync with latest upstream version
authorGuenter Roeck <linux@roeck-us.net>
Thu, 26 Dec 2013 13:06:27 +0000 (05:06 -0800)
committerGuenter Roeck <linux@roeck-us.net>
Thu, 26 Dec 2013 13:06:52 +0000 (05:06 -0800)
Use devm_hwmon_device_register_with_groups() and sysfs_create_groups() if
possible.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
compat.h
nct6775.c

index b18f4e23eea9ed31125c948a835fd9d271357650..de13589e82a9daa0b0e1e27c149f412b09b56672 100644 (file)
--- a/compat.h
+++ b/compat.h
@@ -7,6 +7,40 @@
 #error This driver is for kernel versions 2.6.16 and later
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0)
+static int sysfs_create_groups(struct kobject *kobj,
+                              const struct attribute_group **groups)
+{
+       int error = 0;
+       int i;
+
+       if (!groups)
+               return 0;
+
+       for (i = 0; groups[i]; i++) {
+               error = sysfs_create_group(kobj, groups[i]);
+               if (error) {
+                       while (--i >= 0)
+                               sysfs_remove_group(kobj, groups[i]);
+                       break;
+               }
+       }
+       return error;
+}
+
+static void sysfs_remove_groups(struct kobject *kobj,
+                               const struct attribute_group **groups)
+{
+       int i;
+
+       if (!groups)
+               return;
+       for (i = 0; groups[i]; i++)
+               sysfs_remove_group(kobj, groups[i]);
+}
+
+#endif
+
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 21)
 #if !(defined RHEL_MAJOR && RHEL_MAJOR == 5 && RHEL_MINOR >= 6)
 /* Simplified version for compatibility */
index c970e32e257ed16117ab32e51a6918f5be1cc212..f30c9b757c97ff3fe08ebd60ef92adca783262f0 100644 (file)
--- a/nct6775.c
+++ b/nct6775.c
@@ -736,11 +736,12 @@ struct nct6775_data {
        enum kinds kind;
        const char *name;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
        struct device *hwmon_dev;
-       struct attribute_group *group_in;
-       struct attribute_group *group_fan;
-       struct attribute_group *group_temp;
-       struct attribute_group *group_pwm;
+#endif
+
+       int num_attr_groups;
+       const struct attribute_group *groups[6];
 
        u16 reg_temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
                                    * 3=temp_crit, 4=temp_lcrit
@@ -954,7 +955,7 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg,
        struct sensor_device_attribute_2 *a2;
        struct attribute **attrs;
        struct sensor_device_template **t;
-       int err, i, j, count;
+       int i, count;
 
        if (repeat <= 0)
                return ERR_PTR(-EINVAL);
@@ -985,7 +986,7 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg,
 
        for (i = 0; i < repeat; i++) {
                t = tg->templates;
-               for (j = 0; *t != NULL; j++) {
+               while (*t != NULL) {
                        snprintf(su->name, sizeof(su->name),
                                 (*t)->dev_attr.attr.name, tg->base + i);
                        if ((*t)->s2) {
@@ -1014,10 +1015,6 @@ nct6775_create_attr_group(struct device *dev, struct sensor_template_group *tg,
                }
        }
 
-       err = sysfs_create_group(&dev->kobj, group);
-       if (err)
-               return ERR_PTR(-ENOMEM);
-
        return group;
 }
 
@@ -1326,19 +1323,20 @@ static void nct6775_update_pwm(struct device *dev)
                if (reg & 0x80)
                        data->pwm[2][i] = 0;
 
-               if (data->REG_WEIGHT_TEMP_SEL[i]) {
-                       reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
-                       data->pwm_weight_temp_sel[i] = reg & 0x1f;
-                       /* If weight is disabled, report weight source as 0 */
-                       if (j == 1 && !(reg & 0x80))
-                               data->pwm_weight_temp_sel[i] = 0;
+               if (!data->REG_WEIGHT_TEMP_SEL[i])
+                       continue;
 
-                       /* Weight temp data */
-                       for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) {
-                               data->weight_temp[j][i]
-                                 = nct6775_read_value(data,
-                                               data->REG_WEIGHT_TEMP[j][i]);
-                       }
+               reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
+               data->pwm_weight_temp_sel[i] = reg & 0x1f;
+               /* If weight is disabled, report weight source as 0 */
+               if (j == 1 && !(reg & 0x80))
+                       data->pwm_weight_temp_sel[i] = 0;
+
+               /* Weight temp data */
+               for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) {
+                       data->weight_temp[j][i]
+                         = nct6775_read_value(data,
+                                              data->REG_WEIGHT_TEMP[j][i]);
                }
        }
 }
@@ -1471,7 +1469,8 @@ static struct nct6775_data *nct6775_update_device(struct device *dev)
                                          = nct6775_read_temp(data,
                                                data->reg_temp[j][i]);
                        }
-                       if (!(data->have_temp_fixed & (1 << i)))
+                       if (i >= NUM_TEMP_FIXED ||
+                           !(data->have_temp_fixed & (1 << i)))
                                continue;
                        data->temp_offset[i]
                          = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]);
@@ -1559,7 +1558,7 @@ static int find_temp_source(struct nct6775_data *data, int index, int count)
                if (src == source)
                        return nr;
        }
-       return -1;
+       return -ENODEV;
 }
 
 static ssize_t
@@ -1658,7 +1657,7 @@ store_temp_beep(struct device *dev, struct device_attribute *attr,
 
        nr = find_temp_source(data, sattr->index, data->num_temp_beeps);
        if (nr < 0)
-               return -ENODEV;
+               return nr;
 
        bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE];
        regindex = bit >> 3;
@@ -2739,6 +2738,7 @@ store_fan_time(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
 static ssize_t
 show_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -2748,6 +2748,7 @@ show_name(struct device *dev, struct device_attribute *attr, char *buf)
 }
 
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+#endif
 
 static ssize_t
 show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
@@ -3000,7 +3001,6 @@ static struct sensor_device_template *nct6775_attributes_pwm_template[] = {
        &sensor_dev_template_pwm_auto_point6_temp,
        &sensor_dev_template_pwm_auto_point7_pwm,
        &sensor_dev_template_pwm_auto_point7_temp,      /* 35 */
-
        NULL
 };
 
@@ -3078,16 +3078,16 @@ static umode_t nct6775_other_is_visible(struct kobject *kobj,
        struct device *dev = container_of(kobj, struct device, kobj);
        struct nct6775_data *data = dev_get_drvdata(dev);
 
-       if (index == 1 && !data->have_vid)
+       if (index == 0 && !data->have_vid)
                return 0;
 
-       if (index == 2 || index == 3) {
-               if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 2] < 0)
+       if (index == 1 || index == 2) {
+               if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 1] < 0)
                        return 0;
        }
 
-       if (index == 4 || index == 5) {
-               if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 4] < 0)
+       if (index == 3 || index == 4) {
+               if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 3] < 0)
                        return 0;
        }
 
@@ -3100,14 +3100,15 @@ static umode_t nct6775_other_is_visible(struct kobject *kobj,
  * Any change in order or content must be matched.
  */
 static struct attribute *nct6775_attributes_other[] = {
+       &dev_attr_cpu0_vid.attr,                                /* 0 */
+       &sensor_dev_attr_intrusion0_alarm.dev_attr.attr,        /* 1 */
+       &sensor_dev_attr_intrusion1_alarm.dev_attr.attr,        /* 2 */
+       &sensor_dev_attr_intrusion0_beep.dev_attr.attr,         /* 3 */
+       &sensor_dev_attr_intrusion1_beep.dev_attr.attr,         /* 4 */
+       &sensor_dev_attr_beep_enable.dev_attr.attr,             /* 5 */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
        &dev_attr_name.attr,
-       &dev_attr_cpu0_vid.attr,                                /* 1 */
-       &sensor_dev_attr_intrusion0_alarm.dev_attr.attr,        /* 2 */
-       &sensor_dev_attr_intrusion1_alarm.dev_attr.attr,        /* 3 */
-       &sensor_dev_attr_intrusion0_beep.dev_attr.attr,         /* 4 */
-       &sensor_dev_attr_intrusion1_beep.dev_attr.attr,         /* 5 */
-       &sensor_dev_attr_beep_enable.dev_attr.attr,             /* 6 */
-
+#endif
        NULL
 };
 
@@ -3116,27 +3117,6 @@ static const struct attribute_group nct6775_group_other = {
        .is_visible = nct6775_other_is_visible,
 };
 
-/*
- * Driver and device management
- */
-
-static void nct6775_device_remove_files(struct device *dev)
-{
-       struct nct6775_data *data = dev_get_drvdata(dev);
-
-       if (data->group_pwm)
-               sysfs_remove_group(&dev->kobj, data->group_pwm);
-       if (data->group_in)
-               sysfs_remove_group(&dev->kobj, data->group_in);
-       if (data->group_fan)
-               sysfs_remove_group(&dev->kobj, data->group_fan);
-       if (data->group_temp)
-               sysfs_remove_group(&dev->kobj, data->group_temp);
-
-       sysfs_remove_group(&dev->kobj, &nct6775_group_other);
-}
-
-/* Get the monitoring functions started */
 static inline void nct6775_init_device(struct nct6775_data *data)
 {
        int i;
@@ -3302,7 +3282,7 @@ static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
 static int nct6775_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       struct nct6775_sio_data *sio_data = dev->platform_data;
+       struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
        struct nct6775_data *data;
        struct resource *res;
        int i, s, err = 0;
@@ -3313,6 +3293,7 @@ static int nct6775_probe(struct platform_device *pdev)
        int num_reg_temp, num_reg_temp_mon;
        u8 cr2a;
        struct attribute_group *group;
+       struct device *hwmon_dev;
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
        if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
@@ -3809,7 +3790,8 @@ static int nct6775_probe(struct platform_device *pdev)
                    !strlen(data->temp_label[src])) {
                        dev_info(dev,
                                 "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
-                                src, i, data->REG_TEMP_SEL[i], reg_temp_mon[i]);
+                                src, i, data->REG_TEMP_SEL[i],
+                                reg_temp_mon[i]);
                        continue;
                }
 
@@ -3940,62 +3922,60 @@ static int nct6775_probe(struct platform_device *pdev)
        /* Register sysfs hooks */
        group = nct6775_create_attr_group(dev, &nct6775_pwm_template_group,
                                          data->pwm_num);
-       if (IS_ERR(group)) {
-               err = PTR_ERR(group);
-               goto exit_remove;
-       }
-       data->group_pwm = group;
+       if (IS_ERR(group))
+               return PTR_ERR(group);
+
+       data->groups[data->num_attr_groups++] = group;
 
        group = nct6775_create_attr_group(dev, &nct6775_in_template_group,
                                          fls(data->have_in));
-       if (IS_ERR(group)) {
-               err = PTR_ERR(group);
-               goto exit_remove;
-       }
-       data->group_in = group;
+       if (IS_ERR(group))
+               return PTR_ERR(group);
+
+       data->groups[data->num_attr_groups++] = group;
 
        group = nct6775_create_attr_group(dev, &nct6775_fan_template_group,
                                          fls(data->has_fan));
-       if (IS_ERR(group)) {
-               err = PTR_ERR(group);
-               goto exit_remove;
-       }
-       data->group_fan = group;
+       if (IS_ERR(group))
+               return PTR_ERR(group);
+
+       data->groups[data->num_attr_groups++] = group;
 
        group = nct6775_create_attr_group(dev, &nct6775_temp_template_group,
                                          fls(data->have_temp));
-       if (IS_ERR(group)) {
-               err = PTR_ERR(group);
-               goto exit_remove;
-       }
-       data->group_temp = group;
+       if (IS_ERR(group))
+               return PTR_ERR(group);
 
-       err = sysfs_create_group(&dev->kobj, &nct6775_group_other);
-       if (err)
-               goto exit_remove;
+       data->groups[data->num_attr_groups++] = group;
+       data->groups[data->num_attr_groups++] = &nct6775_group_other;
 
-       data->hwmon_dev = hwmon_device_register(dev);
-       if (IS_ERR(data->hwmon_dev)) {
-               err = PTR_ERR(data->hwmon_dev);
-               goto exit_remove;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
+       err = sysfs_create_groups(&dev->kobj, data->groups);
+       if (err < 0)
+               return err;
+       hwmon_dev = hwmon_device_register(dev);
+       if (IS_ERR(hwmon_dev)) {
+               sysfs_remove_groups(&dev->kobj, data->groups);
+               return PTR_ERR(hwmon_dev);
        }
-
-       return 0;
-
-exit_remove:
-       nct6775_device_remove_files(dev);
-       return err;
+       data->hwmon_dev = hwmon_dev;
+#else
+       hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name,
+                                                          data, data->groups);
+#endif
+       return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
 static int nct6775_remove(struct platform_device *pdev)
 {
        struct nct6775_data *data = platform_get_drvdata(pdev);
 
        hwmon_device_unregister(data->hwmon_dev);
-       nct6775_device_remove_files(&pdev->dev);
-
+       sysfs_remove_groups(&pdev->dev.kobj, data->groups);
        return 0;
 }
+#endif
 
 static void nct6791_enable_io_mapping(int sioaddr)
 {
@@ -4083,7 +4063,7 @@ abort:
        data->valid = false;
        mutex_unlock(&data->update_lock);
 
-       return 0;
+       return err;
 }
 
 static const struct dev_pm_ops nct6775_dev_pm_ops = {
@@ -4105,7 +4085,9 @@ static struct platform_driver nct6775_driver = {
                .pm     = NCT6775_DEV_PM_OPS,
        },
        .probe          = nct6775_probe,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
        .remove         = nct6775_remove,
+#endif
 };
 
 static const char * const nct6775_sio_names[] __initconst = {
@@ -4172,6 +4154,7 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
                pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
                superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
        }
+
        if (sio_data->kind == nct6791)
                nct6791_enable_io_mapping(sioaddr);
 
@@ -4186,7 +4169,7 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
 /*
  * when Super-I/O functions move to a separate file, the Super-I/O
  * bus will manage the lifetime of the device and this module will only keep
- * track of the nct6775 driver. But since we platform_device_alloc(), we
+ * track of the nct6775 driver. But since we use platform_device_alloc(), we
  * must keep track of the device
  */
 static struct platform_device *pdev[2];