iio: refactor info mask and ext_info attribute creation.
authorJonathan Cameron <jic23@kernel.org>
Sun, 8 Sep 2013 13:57:00 +0000 (14:57 +0100)
committerJonathan Cameron <jic23@kernel.org>
Sun, 15 Sep 2013 16:43:20 +0000 (17:43 +0100)
Introduce an enum to specify whether the attribute is separate or
shared.

Factor out the bitmap handling for loop into a separate function.

Tidy up error handling and add a NULL assignment to squish a false
positive warning from GCC.

Change ext_info shared type from boolean to enum and update in all
drivers.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
15 files changed:
drivers/iio/dac/ad5064.c
drivers/iio/dac/ad5380.c
drivers/iio/dac/ad5446.c
drivers/iio/dac/ad5504.c
drivers/iio/dac/ad5624r_spi.c
drivers/iio/dac/ad5686.c
drivers/iio/dac/ad5755.c
drivers/iio/dac/ad5791.c
drivers/iio/dac/ad7303.c
drivers/iio/dac/mcp4725.c
drivers/iio/frequency/adf4350.c
drivers/iio/iio_core.h
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
include/linux/iio/iio.h

index a3a52be..b18e8c4 100644 (file)
@@ -285,8 +285,9 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
                .name = "powerdown",
                .read = ad5064_read_dac_powerdown,
                .write = ad5064_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &ad5064_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5064_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5064_powerdown_mode_enum),
        { },
 };
index 1c44ae3..4c791e6 100644 (file)
@@ -247,8 +247,10 @@ static struct iio_chan_spec_ext_info ad5380_ext_info[] = {
                .name = "powerdown",
                .read = ad5380_read_dac_powerdown,
                .write = ad5380_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5380_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5380_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum),
        { },
 };
index 96e9ed4..6dcb6d9 100644 (file)
@@ -132,8 +132,9 @@ static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = {
                .name = "powerdown",
                .read = ad5446_read_dac_powerdown,
                .write = ad5446_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &ad5446_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5446_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5446_powerdown_mode_enum),
        { },
 };
index caffb16..31f4ff2 100644 (file)
@@ -248,8 +248,10 @@ static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
                .name = "powerdown",
                .read = ad5504_read_dac_powerdown,
                .write = ad5504_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5504_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum),
        { },
 };
index 714af75..dbb1289 100644 (file)
@@ -163,8 +163,10 @@ static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
                .name = "powerdown",
                .read = ad5624r_read_dac_powerdown,
                .write = ad5624r_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5624r_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum),
        { },
 };
index 3e1080f..f472b48 100644 (file)
@@ -264,8 +264,9 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
                .name = "powerdown",
                .read = ad5686_read_dac_powerdown,
                .write = ad5686_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &ad5686_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5686_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
        { },
 };
index 36a4361..f305a0c 100644 (file)
@@ -386,6 +386,7 @@ static const struct iio_chan_spec_ext_info ad5755_ext_info[] = {
                .name = "powerdown",
                .read = ad5755_read_powerdown,
                .write = ad5755_write_powerdown,
+               .shared = IIO_SEPARATE,
        },
        { },
 };
index ce74589..3cee89b 100644 (file)
@@ -287,11 +287,12 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
 static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
        {
                .name = "powerdown",
-               .shared = true,
+               .shared = IIO_SHARED_BY_TYPE,
                .read = ad5791_read_dac_powerdown,
                .write = ad5791_write_dac_powerdown,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5791_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5791_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
        { },
 };
index ed2d276..d0505fd 100644 (file)
@@ -169,6 +169,7 @@ static const struct iio_chan_spec_ext_info ad7303_ext_info[] = {
                .name = "powerdown",
                .read = ad7303_read_dac_powerdown,
                .write = ad7303_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
        { },
 };
index 1f4a48e..6711a33 100644 (file)
@@ -195,8 +195,9 @@ static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
                .name = "powerdown",
                .read = mcp4725_read_powerdown,
                .write = mcp4725_write_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &mcp4725_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &mcp4725_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum),
        { },
 };
index a7b30be..8515254 100644 (file)
@@ -351,6 +351,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
        .read = adf4350_read, \
        .write = adf4350_write, \
        .private = _ident, \
+       .shared = IIO_SEPARATE, \
 }
 
 static const struct iio_chan_spec_ext_info adf4350_ext_info[] = {
index 05c1b74..6be5ab8 100644 (file)
@@ -30,7 +30,7 @@ int __iio_add_chan_devattr(const char *postfix,
                                                const char *buf,
                                                size_t len),
                           u64 mask,
-                          bool generic,
+                          enum iio_shared_by shared_by,
                           struct device *dev,
                           struct list_head *attr_list);
 
index 96e97ad..7ea2edb 100644 (file)
@@ -208,7 +208,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
                                     &iio_show_scan_index,
                                     NULL,
                                     0,
-                                    0,
+                                    IIO_SEPARATE,
                                     &indio_dev->dev,
                                     &buffer->scan_el_dev_attr_list);
        if (ret)
index 2cb4841..d380c72 100644 (file)
@@ -517,14 +517,15 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                                                struct device_attribute *attr,
                                                const char *buf,
                                                size_t len),
-                          bool generic)
+                          enum iio_shared_by shared_by)
 {
-       int ret;
-       char *name_format, *full_postfix;
+       int ret = 0;
+       char *name_format = NULL;
+       char *full_postfix;
        sysfs_attr_init(&dev_attr->attr);
 
        /* Build up postfix of <extend_name>_<modifier>_postfix */
-       if (chan->modified && !generic) {
+       if (chan->modified && (shared_by == IIO_SEPARATE)) {
                if (chan->extend_name)
                        full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
                                                 iio_modifier_names[chan
@@ -545,53 +546,62 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                                                 chan->extend_name,
                                                 postfix);
        }
-       if (full_postfix == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       if (full_postfix == NULL)
+               return -ENOMEM;
 
        if (chan->differential) { /* Differential can not have modifier */
-               if (generic)
+               switch (shared_by) {
+               case IIO_SHARED_BY_TYPE:
                        name_format
                                = kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
                                            iio_direction[chan->output],
                                            iio_chan_type_name_spec[chan->type],
                                            iio_chan_type_name_spec[chan->type],
                                            full_postfix);
-               else if (chan->indexed)
+                       break;
+               case IIO_SEPARATE:
+                       if (!chan->indexed) {
+                               WARN_ON("Differential channels must be indexed\n");
+                               ret = -EINVAL;
+                               goto error_free_full_postfix;
+                       }
                        name_format
-                               = kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s",
+                               = kasprintf(GFP_KERNEL,
+                                           "%s_%s%d-%s%d_%s",
                                            iio_direction[chan->output],
                                            iio_chan_type_name_spec[chan->type],
                                            chan->channel,
                                            iio_chan_type_name_spec[chan->type],
                                            chan->channel2,
                                            full_postfix);
-               else {
-                       WARN_ON("Differential channels must be indexed\n");
-                       ret = -EINVAL;
-                       goto error_free_full_postfix;
+                       break;
                }
        } else { /* Single ended */
-               if (generic)
-                       name_format
-                               = kasprintf(GFP_KERNEL, "%s_%s_%s",
-                                           iio_direction[chan->output],
-                                           iio_chan_type_name_spec[chan->type],
-                                           full_postfix);
-               else if (chan->indexed)
-                       name_format
-                               = kasprintf(GFP_KERNEL, "%s_%s%d_%s",
-                                           iio_direction[chan->output],
-                                           iio_chan_type_name_spec[chan->type],
-                                           chan->channel,
-                                           full_postfix);
-               else
+               switch (shared_by) {
+               case IIO_SHARED_BY_TYPE:
                        name_format
                                = kasprintf(GFP_KERNEL, "%s_%s_%s",
                                            iio_direction[chan->output],
                                            iio_chan_type_name_spec[chan->type],
                                            full_postfix);
+                       break;
+
+               case IIO_SEPARATE:
+                       if (chan->indexed)
+                               name_format
+                                       = kasprintf(GFP_KERNEL, "%s_%s%d_%s",
+                                                   iio_direction[chan->output],
+                                                   iio_chan_type_name_spec[chan->type],
+                                                   chan->channel,
+                                                   full_postfix);
+                       else
+                               name_format
+                                       = kasprintf(GFP_KERNEL, "%s_%s_%s",
+                                                   iio_direction[chan->output],
+                                                   iio_chan_type_name_spec[chan->type],
+                                                   full_postfix);
+                       break;
+               }
        }
        if (name_format == NULL) {
                ret = -ENOMEM;
@@ -615,16 +625,11 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                dev_attr->attr.mode |= S_IWUSR;
                dev_attr->store = writefunc;
        }
-       kfree(name_format);
-       kfree(full_postfix);
-
-       return 0;
-
 error_free_name_format:
        kfree(name_format);
 error_free_full_postfix:
        kfree(full_postfix);
-error_ret:
+
        return ret;
 }
 
@@ -643,7 +648,7 @@ int __iio_add_chan_devattr(const char *postfix,
                                                const char *buf,
                                                size_t len),
                           u64 mask,
-                          bool generic,
+                          enum iio_shared_by shared_by,
                           struct device *dev,
                           struct list_head *attr_list)
 {
@@ -657,7 +662,7 @@ int __iio_add_chan_devattr(const char *postfix,
        }
        ret = __iio_device_attr_init(&iio_attr->dev_attr,
                                     postfix, chan,
-                                    readfunc, writefunc, generic);
+                                    readfunc, writefunc, shared_by);
        if (ret)
                goto error_iio_dev_attr_free;
        iio_attr->c = chan;
@@ -665,7 +670,7 @@ int __iio_add_chan_devattr(const char *postfix,
        list_for_each_entry(t, attr_list, l)
                if (strcmp(t->dev_attr.attr.name,
                           iio_attr->dev_attr.attr.name) == 0) {
-                       if (!generic)
+                       if (shared_by == IIO_SEPARATE)
                                dev_err(dev, "tried to double register : %s\n",
                                        t->dev_attr.attr.name);
                        ret = -EBUSY;
@@ -683,46 +688,54 @@ error_ret:
        return ret;
 }
 
-static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
-                                       struct iio_chan_spec const *chan)
+static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
+                                        struct iio_chan_spec const *chan,
+                                        enum iio_shared_by shared_by,
+                                        const long *infomask)
 {
-       int ret, attrcount = 0;
-       int i;
-       const struct iio_chan_spec_ext_info *ext_info;
+       int i, ret, attrcount = 0;
 
-       if (chan->channel < 0)
-               return 0;
-       for_each_set_bit(i, &chan->info_mask_separate, sizeof(long)*8) {
+       for_each_set_bit(i, infomask, sizeof(infomask)*8) {
                ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
                                             chan,
                                             &iio_read_channel_info,
                                             &iio_write_channel_info,
                                             i,
-                                            0,
+                                            shared_by,
                                             &indio_dev->dev,
                                             &indio_dev->channel_attr_list);
-               if (ret < 0)
-                       goto error_ret;
-               attrcount++;
-       }
-       for_each_set_bit(i, &chan->info_mask_shared_by_type, sizeof(long)*8) {
-               ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
-                                            chan,
-                                            &iio_read_channel_info,
-                                            &iio_write_channel_info,
-                                            i,
-                                            1,
-                                            &indio_dev->dev,
-                                            &indio_dev->channel_attr_list);
-               if (ret == -EBUSY) {
-                       ret = 0;
+               if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE))
                        continue;
-               } else if (ret < 0) {
-                       goto error_ret;
-               }
+               else if (ret < 0)
+                       return ret;
                attrcount++;
        }
 
+       return attrcount;
+}
+
+static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
+                                       struct iio_chan_spec const *chan)
+{
+       int ret, attrcount = 0;
+       const struct iio_chan_spec_ext_info *ext_info;
+
+       if (chan->channel < 0)
+               return 0;
+       ret = iio_device_add_info_mask_type(indio_dev, chan,
+                                           IIO_SEPARATE,
+                                           &chan->info_mask_separate);
+       if (ret < 0)
+               return ret;
+       attrcount += ret;
+
+       ret = iio_device_add_info_mask_type(indio_dev, chan,
+                                           IIO_SHARED_BY_TYPE,
+                                           &chan->info_mask_shared_by_type);
+       if (ret < 0)
+               return ret;
+       attrcount += ret;
+
        if (chan->ext_info) {
                unsigned int i = 0;
                for (ext_info = chan->ext_info; ext_info->name; ext_info++) {
@@ -741,15 +754,13 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
                                continue;
 
                        if (ret)
-                               goto error_ret;
+                               return ret;
 
                        attrcount++;
                }
        }
 
-       ret = attrcount;
-error_ret:
-       return ret;
+       return attrcount;
 }
 
 static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev,
index bc408e2..21de272 100644 (file)
@@ -39,6 +39,11 @@ enum iio_chan_info_enum {
        IIO_CHAN_INFO_INT_TIME,
 };
 
+enum iio_shared_by {
+       IIO_SEPARATE,
+       IIO_SHARED_BY_TYPE
+};
+
 enum iio_endian {
        IIO_CPU,
        IIO_BE,
@@ -58,7 +63,7 @@ struct iio_dev;
  */
 struct iio_chan_spec_ext_info {
        const char *name;
-       bool shared;
+       enum iio_shared_by shared;
        ssize_t (*read)(struct iio_dev *, uintptr_t private,
                        struct iio_chan_spec const *, char *buf);
        ssize_t (*write)(struct iio_dev *, uintptr_t private,
@@ -126,7 +131,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,
 #define IIO_ENUM_AVAILABLE(_name, _e) \
 { \
        .name = (_name "_available"), \
-       .shared = true, \
+       .shared = IIO_SHARED_BY_TYPE, \
        .read = iio_enum_available_read, \
        .private = (uintptr_t)(_e), \
 }