Merge branch 'sfc-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc
[firefly-linux-kernel-4.4.55.git] / drivers / staging / iio / iio_hwmon.c
index c7a5f97576c7ab8fb2791e8ce31379c915453be1..93af756ba48cca797560a7118e3c3d0e19f4d6c5 100644 (file)
@@ -55,63 +55,58 @@ static ssize_t iio_hwmon_read_val(struct device *dev,
        return sprintf(buf, "%d\n", result);
 }
 
-static void iio_hwmon_free_attrs(struct iio_hwmon_state *st)
+static ssize_t show_name(struct device *dev, struct device_attribute *attr,
+                        char *buf)
 {
-       int i;
-       struct sensor_device_attribute *a;
-       for (i = 0; i < st->num_channels; i++)
-               if (st->attrs[i]) {
-                       a = to_sensor_dev_attr(
-                               container_of(st->attrs[i],
-                                            struct device_attribute,
-                                            attr));
-                       kfree(a);
-               }
+       return sprintf(buf, "iio_hwmon\n");
 }
 
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
 static int iio_hwmon_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
        struct iio_hwmon_state *st;
        struct sensor_device_attribute *a;
        int ret, i;
        int in_i = 1, temp_i = 1, curr_i = 1;
        enum iio_chan_type type;
+       struct iio_channel *channels;
 
-       st = kzalloc(sizeof(*st), GFP_KERNEL);
-       if (st == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       channels = iio_channel_get_all(dev);
+       if (IS_ERR(channels))
+               return PTR_ERR(channels);
 
-       st->channels = iio_channel_get_all(dev_name(&pdev->dev));
-       if (IS_ERR(st->channels)) {
-               ret = PTR_ERR(st->channels);
-               goto error_free_state;
-       }
+       st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
+       if (st == NULL)
+               return -ENOMEM;
+
+       st->channels = channels;
 
        /* count how many attributes we have */
        while (st->channels[st->num_channels].indio_dev)
                st->num_channels++;
 
-       st->attrs = kzalloc(sizeof(st->attrs) * (st->num_channels + 1),
-                           GFP_KERNEL);
+       st->attrs = devm_kzalloc(dev,
+                                sizeof(*st->attrs) * (st->num_channels + 2),
+                                GFP_KERNEL);
        if (st->attrs == NULL) {
                ret = -ENOMEM;
                goto error_release_channels;
        }
+
        for (i = 0; i < st->num_channels; i++) {
-               a = kzalloc(sizeof(*a), GFP_KERNEL);
+               a = devm_kzalloc(dev, sizeof(*a), GFP_KERNEL);
                if (a == NULL) {
                        ret = -ENOMEM;
-                       goto error_free_attrs;
+                       goto error_release_channels;
                }
 
                sysfs_attr_init(&a->dev_attr.attr);
                ret = iio_get_channel_type(&st->channels[i], &type);
-               if (ret < 0) {
-                       kfree(a);
-                       goto error_free_attrs;
-               }
+               if (ret < 0)
+                       goto error_release_channels;
+
                switch (type) {
                case IIO_VOLTAGE:
                        a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
@@ -130,27 +125,25 @@ static int iio_hwmon_probe(struct platform_device *pdev)
                        break;
                default:
                        ret = -EINVAL;
-                       kfree(a);
-                       goto error_free_attrs;
+                       goto error_release_channels;
                }
                if (a->dev_attr.attr.name == NULL) {
-                       kfree(a);
                        ret = -ENOMEM;
-                       goto error_free_attrs;
+                       goto error_release_channels;
                }
                a->dev_attr.show = iio_hwmon_read_val;
                a->dev_attr.attr.mode = S_IRUGO;
                a->index = i;
                st->attrs[i] = &a->dev_attr.attr;
        }
-
+       st->attrs[st->num_channels] = &dev_attr_name.attr;
        st->attr_group.attrs = st->attrs;
        platform_set_drvdata(pdev, st);
-       ret = sysfs_create_group(&pdev->dev.kobj, &st->attr_group);
+       ret = sysfs_create_group(&dev->kobj, &st->attr_group);
        if (ret < 0)
-               goto error_free_attrs;
+               goto error_release_channels;
 
-       st->hwmon_dev = hwmon_device_register(&pdev->dev);
+       st->hwmon_dev = hwmon_device_register(dev);
        if (IS_ERR(st->hwmon_dev)) {
                ret = PTR_ERR(st->hwmon_dev);
                goto error_remove_group;
@@ -158,15 +151,9 @@ static int iio_hwmon_probe(struct platform_device *pdev)
        return 0;
 
 error_remove_group:
-       sysfs_remove_group(&pdev->dev.kobj, &st->attr_group);
-error_free_attrs:
-       iio_hwmon_free_attrs(st);
-       kfree(st->attrs);
+       sysfs_remove_group(&dev->kobj, &st->attr_group);
 error_release_channels:
        iio_channel_release_all(st->channels);
-error_free_state:
-       kfree(st);
-error_ret:
        return ret;
 }
 
@@ -176,17 +163,21 @@ static int iio_hwmon_remove(struct platform_device *pdev)
 
        hwmon_device_unregister(st->hwmon_dev);
        sysfs_remove_group(&pdev->dev.kobj, &st->attr_group);
-       iio_hwmon_free_attrs(st);
-       kfree(st->attrs);
        iio_channel_release_all(st->channels);
 
        return 0;
 }
 
+static struct of_device_id iio_hwmon_of_match[] = {
+       { .compatible = "iio-hwmon", },
+       { }
+};
+
 static struct platform_driver __refdata iio_hwmon_driver = {
        .driver = {
                .name = "iio_hwmon",
                .owner = THIS_MODULE,
+               .of_match_table = iio_hwmon_of_match,
        },
        .probe = iio_hwmon_probe,
        .remove = iio_hwmon_remove,