Now that the iio_buffer_set_attrs() has been removed, we can be sure that
no accidents can happen with drivers that try to provide extra buffer
attributes that expand to iio_dev objects.

So, we can convert all remaining buffer attributes to expand to iio_buffer
objects.
These will look a bit weird at first, as most of them will just pass back
their reference to the IIO device.
But this can also allow for newer (maybe more interesting) uses.

Signed-off-by: Alexandru Ardelean <alexandru.ardel...@analog.com>
---
 drivers/iio/accel/adxl372.c                   | 36 ++++-----
 drivers/iio/accel/bmc150-accel-core.c         | 34 ++++-----
 drivers/iio/adc/at91-sama5d2_adc.c            | 30 ++++----
 .../buffer/industrialio-buffer-dmaengine.c    | 13 ++--
 .../cros_ec_sensors/cros_ec_sensors_core.c    | 30 ++++----
 .../common/hid-sensors/hid-sensor-trigger.c   | 32 ++++----
 drivers/iio/industrialio-buffer.c             | 73 +++----------------
 include/linux/iio/sysfs.h                     | 50 +++++++++++++
 8 files changed, 148 insertions(+), 150 deletions(-)

diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c
index 8ba1453b8dbf..a90aaa518816 100644
--- a/drivers/iio/accel/adxl372.c
+++ b/drivers/iio/accel/adxl372.c
@@ -978,39 +978,39 @@ static ssize_t adxl372_show_filter_freq_avail(struct 
device *dev,
        return len;
 }
 
-static ssize_t adxl372_get_fifo_enabled(struct device *dev,
-                                         struct device_attribute *attr,
-                                         char *buf)
+static ssize_t adxl372_get_fifo_enabled(struct iio_buffer *buffer,
+                                       struct iio_buf_attr *attr,
+                                       char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct adxl372_state *st = iio_priv(indio_dev);
 
        return sprintf(buf, "%d\n", st->fifo_mode);
 }
 
-static ssize_t adxl372_get_fifo_watermark(struct device *dev,
-                                         struct device_attribute *attr,
+static ssize_t adxl372_get_fifo_watermark(struct iio_buffer *buffer,
+                                         struct iio_buf_attr *attr,
                                          char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct adxl372_state *st = iio_priv(indio_dev);
 
        return sprintf(buf, "%d\n", st->watermark);
 }
 
-static IIO_CONST_ATTR(hwfifo_watermark_min, "1");
-static IIO_CONST_ATTR(hwfifo_watermark_max,
-                     __stringify(ADXL372_FIFO_SIZE));
-static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
-                      adxl372_get_fifo_watermark, NULL, 0);
-static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
-                      adxl372_get_fifo_enabled, NULL, 0);
+static IIO_BUF_CONST_ATTR(hwfifo_watermark_min, "1");
+static IIO_BUF_CONST_ATTR(hwfifo_watermark_max,
+                         __stringify(ADXL372_FIFO_SIZE));
+static IIO_BUF_ATTR(hwfifo_watermark, 0444,
+                   adxl372_get_fifo_watermark, NULL);
+static IIO_BUF_ATTR(hwfifo_enabled, 0444,
+                   adxl372_get_fifo_enabled, NULL);
 
 static const struct attribute *adxl372_fifo_attributes[] = {
-       &iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
-       &iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+       &iio_buf_const_attr_hwfifo_watermark_min.buf_attr.attr,
+       &iio_buf_const_attr_hwfifo_watermark_max.buf_attr.attr,
+       &iio_buf_attr_hwfifo_watermark.attr,
+       &iio_buf_attr_hwfifo_enabled.attr,
        NULL,
 };
 
diff --git a/drivers/iio/accel/bmc150-accel-core.c 
b/drivers/iio/accel/bmc150-accel-core.c
index c641ee552038..bddda8f28fb8 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -767,11 +767,11 @@ static int bmc150_accel_validate_trigger(struct iio_dev 
*indio_dev,
        return -EINVAL;
 }
 
-static ssize_t bmc150_accel_get_fifo_watermark(struct device *dev,
-                                              struct device_attribute *attr,
+static ssize_t bmc150_accel_get_fifo_watermark(struct iio_buffer *buffer,
+                                              struct iio_buf_attr *attr,
                                               char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct bmc150_accel_data *data = iio_priv(indio_dev);
        int wm;
 
@@ -782,11 +782,11 @@ static ssize_t bmc150_accel_get_fifo_watermark(struct 
device *dev,
        return sprintf(buf, "%d\n", wm);
 }
 
-static ssize_t bmc150_accel_get_fifo_state(struct device *dev,
-                                          struct device_attribute *attr,
+static ssize_t bmc150_accel_get_fifo_state(struct iio_buffer *buffer,
+                                          struct iio_buf_attr *attr,
                                           char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct bmc150_accel_data *data = iio_priv(indio_dev);
        bool state;
 
@@ -811,19 +811,19 @@ static const struct iio_chan_spec_ext_info 
bmc150_accel_ext_info[] = {
        { }
 };
 
-static IIO_CONST_ATTR(hwfifo_watermark_min, "1");
-static IIO_CONST_ATTR(hwfifo_watermark_max,
-                     __stringify(BMC150_ACCEL_FIFO_LENGTH));
-static IIO_DEVICE_ATTR(hwfifo_enabled, S_IRUGO,
-                      bmc150_accel_get_fifo_state, NULL, 0);
-static IIO_DEVICE_ATTR(hwfifo_watermark, S_IRUGO,
-                      bmc150_accel_get_fifo_watermark, NULL, 0);
+static IIO_BUF_CONST_ATTR(hwfifo_watermark_min, "1");
+static IIO_BUF_CONST_ATTR(hwfifo_watermark_max,
+                         __stringify(BMC150_ACCEL_FIFO_LENGTH));
+static IIO_BUF_ATTR(hwfifo_enabled, S_IRUGO,
+                   bmc150_accel_get_fifo_state, NULL);
+static IIO_BUF_ATTR(hwfifo_watermark, S_IRUGO,
+                   bmc150_accel_get_fifo_watermark, NULL);
 
 static const struct attribute *bmc150_accel_fifo_attributes[] = {
-       &iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
-       &iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+       &iio_buf_const_attr_hwfifo_watermark_min.buf_attr.attr,
+       &iio_buf_const_attr_hwfifo_watermark_max.buf_attr.attr,
+       &iio_buf_attr_hwfifo_watermark.attr,
+       &iio_buf_attr_hwfifo_enabled.attr,
        NULL,
 };
 
diff --git a/drivers/iio/adc/at91-sama5d2_adc.c 
b/drivers/iio/adc/at91-sama5d2_adc.c
index 6edcc99009d1..f86ee1b0b051 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -1612,31 +1612,29 @@ static void at91_adc_hw_init(struct iio_dev *indio_dev)
        at91_adc_config_emr(st);
 }
 
-static ssize_t at91_adc_get_fifo_state(struct device *dev,
-                                      struct device_attribute *attr, char *buf)
+static ssize_t at91_adc_get_fifo_state(struct iio_buffer *buffer,
+                                      struct iio_buf_attr *attr, char *buf)
 {
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct at91_adc_state *st = iio_priv(indio_dev);
 
        return scnprintf(buf, PAGE_SIZE, "%d\n", !!st->dma_st.dma_chan);
 }
 
-static ssize_t at91_adc_get_watermark(struct device *dev,
-                                     struct device_attribute *attr, char *buf)
+static ssize_t at91_adc_get_watermark(struct iio_buffer *buffer,
+                                     struct iio_buf_attr *attr, char *buf)
 {
-       struct iio_dev *indio_dev = dev_get_drvdata(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct at91_adc_state *st = iio_priv(indio_dev);
 
        return scnprintf(buf, PAGE_SIZE, "%d\n", st->dma_st.watermark);
 }
 
-static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
-                      at91_adc_get_fifo_state, NULL, 0);
-static IIO_DEVICE_ATTR(hwfifo_watermark, 0444,
-                      at91_adc_get_watermark, NULL, 0);
+static IIO_BUF_ATTR(hwfifo_enabled, 0444, at91_adc_get_fifo_state, NULL);
+static IIO_BUF_ATTR(hwfifo_watermark, 0444, at91_adc_get_watermark, NULL);
 
-static IIO_CONST_ATTR(hwfifo_watermark_min, "2");
-static IIO_CONST_ATTR(hwfifo_watermark_max, AT91_HWFIFO_MAX_SIZE_STR);
+static IIO_BUF_CONST_ATTR(hwfifo_watermark_min, "2");
+static IIO_BUF_CONST_ATTR(hwfifo_watermark_max, AT91_HWFIFO_MAX_SIZE_STR);
 
 static IIO_CONST_ATTR(oversampling_ratio_available,
                      __stringify(AT91_OSR_1SAMPLES) " "
@@ -1653,10 +1651,10 @@ static const struct attribute_group 
at91_adc_attribute_group = {
 };
 
 static const struct attribute *at91_adc_fifo_attributes[] = {
-       &iio_const_attr_hwfifo_watermark_min.dev_attr.attr,
-       &iio_const_attr_hwfifo_watermark_max.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+       &iio_buf_const_attr_hwfifo_watermark_min.buf_attr.attr,
+       &iio_buf_const_attr_hwfifo_watermark_max.buf_attr.attr,
+       &iio_buf_attr_hwfifo_watermark.attr,
+       &iio_buf_attr_hwfifo_enabled.attr,
        NULL,
 };
 
diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c 
b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
index b0cb9a35f5cd..2cd5fd3fe191 100644
--- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c
+++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c
@@ -129,21 +129,20 @@ static const struct iio_dma_buffer_ops 
iio_dmaengine_default_ops = {
        .abort = iio_dmaengine_buffer_abort,
 };
 
-static ssize_t iio_dmaengine_buffer_get_length_align(struct device *dev,
-       struct device_attribute *attr, char *buf)
+static ssize_t iio_dmaengine_buffer_get_length_align(struct iio_buffer *buffer,
+       struct iio_buf_attr *attr, char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct dmaengine_buffer *dmaengine_buffer =
-               iio_buffer_to_dmaengine_buffer(indio_dev->buffer);
+               iio_buffer_to_dmaengine_buffer(buffer);
 
        return sprintf(buf, "%zu\n", dmaengine_buffer->align);
 }
 
-static IIO_DEVICE_ATTR(length_align_bytes, 0444,
-                      iio_dmaengine_buffer_get_length_align, NULL, 0);
+static IIO_BUF_ATTR(length_align_bytes, 0444,
+                   iio_dmaengine_buffer_get_length_align, NULL);
 
 static const struct attribute *iio_dmaengine_buffer_attrs[] = {
-       &iio_dev_attr_length_align_bytes.dev_attr.attr,
+       &iio_buf_attr_length_align_bytes.attr,
        NULL,
 };
 
diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c 
b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
index 1eafcf04ad69..5c6c4e6fec9b 100644
--- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
+++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
@@ -116,11 +116,11 @@ static int cros_ec_sensor_set_ec_rate(struct 
cros_ec_sensors_core_state *st,
        return ret;
 }
 
-static ssize_t cros_ec_sensor_set_report_latency(struct device *dev,
-                                                struct device_attribute *attr,
+static ssize_t cros_ec_sensor_set_report_latency(struct iio_buffer *buffer,
+                                                struct iio_buf_attr *attr,
                                                 const char *buf, size_t len)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
        int integer, fract, ret;
        int latency;
@@ -138,11 +138,11 @@ static ssize_t cros_ec_sensor_set_report_latency(struct 
device *dev,
        return len;
 }
 
-static ssize_t cros_ec_sensor_get_report_latency(struct device *dev,
-                                                struct device_attribute *attr,
+static ssize_t cros_ec_sensor_get_report_latency(struct iio_buffer *buffer,
+                                                struct iio_buf_attr *attr,
                                                 char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
        int latency, ret;
 
@@ -161,25 +161,25 @@ static ssize_t cros_ec_sensor_get_report_latency(struct 
device *dev,
                       (latency % 1000) * 1000);
 }
 
-static IIO_DEVICE_ATTR(hwfifo_timeout, 0644,
-                      cros_ec_sensor_get_report_latency,
-                      cros_ec_sensor_set_report_latency, 0);
+static IIO_BUF_ATTR(hwfifo_timeout, 0644,
+                   cros_ec_sensor_get_report_latency,
+                   cros_ec_sensor_set_report_latency);
 
-static ssize_t hwfifo_watermark_max_show(struct device *dev,
-                                        struct device_attribute *attr,
+static ssize_t hwfifo_watermark_max_show(struct iio_buffer *buffer,
+                                        struct iio_buf_attr *attr,
                                         char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct cros_ec_sensors_core_state *st = iio_priv(indio_dev);
 
        return sprintf(buf, "%d\n", st->fifo_max_event_count);
 }
 
-static IIO_DEVICE_ATTR_RO(hwfifo_watermark_max, 0);
+static IIO_BUF_ATTR(hwfifo_watermark_max, 0444, hwfifo_watermark_max_show, 
NULL);
 
 static const struct attribute *cros_ec_sensor_fifo_attributes[] = {
-       &iio_dev_attr_hwfifo_timeout.dev_attr.attr,
-       &iio_dev_attr_hwfifo_watermark_max.dev_attr.attr,
+       &iio_buf_attr_hwfifo_timeout.attr,
+       &iio_buf_attr_hwfifo_watermark_max.attr,
        NULL,
 };
 
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c 
b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 064c32bec9c7..c04dca7a457b 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -19,11 +19,11 @@
 #include <linux/iio/sysfs.h>
 #include "hid-sensor-trigger.h"
 
-static ssize_t _hid_sensor_set_report_latency(struct device *dev,
-                                             struct device_attribute *attr,
+static ssize_t _hid_sensor_set_report_latency(struct iio_buffer *buffer,
+                                             struct iio_buf_attr *attr,
                                              const char *buf, size_t len)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
        int integer, fract, ret;
        int latency;
@@ -42,11 +42,11 @@ static ssize_t _hid_sensor_set_report_latency(struct device 
*dev,
        return len;
 }
 
-static ssize_t _hid_sensor_get_report_latency(struct device *dev,
-                                             struct device_attribute *attr,
+static ssize_t _hid_sensor_get_report_latency(struct iio_buffer *buffer,
+                                             struct iio_buf_attr *attr,
                                              char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
        int latency;
 
@@ -57,11 +57,11 @@ static ssize_t _hid_sensor_get_report_latency(struct device 
*dev,
        return sprintf(buf, "%d.%06u\n", latency / 1000, (latency % 1000) * 
1000);
 }
 
-static ssize_t _hid_sensor_get_fifo_state(struct device *dev,
-                                         struct device_attribute *attr,
+static ssize_t _hid_sensor_get_fifo_state(struct iio_buffer *buffer,
+                                         struct iio_buf_attr *attr,
                                          char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev *indio_dev = iio_buffer_get_iio_dev(buffer);
        struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
        int latency;
 
@@ -72,15 +72,15 @@ static ssize_t _hid_sensor_get_fifo_state(struct device 
*dev,
        return sprintf(buf, "%d\n", !!latency);
 }
 
-static IIO_DEVICE_ATTR(hwfifo_timeout, 0644,
-                      _hid_sensor_get_report_latency,
-                      _hid_sensor_set_report_latency, 0);
-static IIO_DEVICE_ATTR(hwfifo_enabled, 0444,
-                      _hid_sensor_get_fifo_state, NULL, 0);
+static IIO_BUF_ATTR(hwfifo_timeout, 0644,
+                   _hid_sensor_get_report_latency,
+                   _hid_sensor_set_report_latency);
+static IIO_BUF_ATTR(hwfifo_enabled, 0444,
+                   _hid_sensor_get_fifo_state, NULL);
 
 static const struct attribute *hid_sensor_fifo_attributes[] = {
-       &iio_dev_attr_hwfifo_timeout.dev_attr.attr,
-       &iio_dev_attr_hwfifo_enabled.dev_attr.attr,
+       &iio_buf_attr_hwfifo_timeout.attr,
+       &iio_buf_attr_hwfifo_enabled.attr,
        NULL,
 };
 
diff --git a/drivers/iio/industrialio-buffer.c 
b/drivers/iio/industrialio-buffer.c
index 342e5432f7d9..6307ea84bbc7 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -26,31 +26,19 @@
 #include <linux/iio/buffer.h>
 #include <linux/iio/buffer_impl.h>
 
-/**
- * struct iio_buf_attr - iio buffer specific attribute
- * @attr:      underlying attribute
- * @address:   associated register address
- * @l:         list head for maintaining list of dynamically created attrs
- * @c:         specification for the underlying channel
- * @show:      sysfs show hook for this attribute
- * @store:     sysfs store hook for this attribute
- */
-struct iio_buf_attr {
-       struct attribute attr;
-       u64 address;
-       struct list_head l;
-       struct iio_chan_spec const *c;
-       ssize_t (*show)(struct iio_buffer *buffer, struct iio_buf_attr *attr,
-                       char *buf);
-       ssize_t (*store)(struct iio_buffer *buffer, struct iio_buf_attr *attr,
-                        const char *buf, size_t count);
-};
-
 static const char * const iio_endian_prefix[] = {
        [IIO_BE] = "be",
        [IIO_LE] = "le",
 };
 
+ssize_t iio_read_buf_const_attr(struct iio_buffer *buffer,
+                               struct iio_buf_attr *attr,
+                               char *buf)
+{
+       return sprintf(buf, "%s\n", to_iio_buf_const_attr(attr)->string);
+}
+EXPORT_SYMBOL(iio_read_buf_const_attr);
+
 static bool iio_buffer_is_active(struct iio_buffer *buf)
 {
        return !list_empty(&buf->buffer_list);
@@ -1300,10 +1288,6 @@ static ssize_t iio_dma_show_data_available(struct 
iio_buffer *buffer,
        return sprintf(buf, "%zu\n", iio_buffer_data_available(buffer));
 }
 
-#define IIO_BUF_ATTR(_name, _mode, _show, _store)      \
-       struct iio_buf_attr iio_buf_attr_##_name =      \
-               __ATTR(_name, _mode, _show, _store)
-
 static IIO_BUF_ATTR(length, S_IRUGO | S_IWUSR,
                    iio_buffer_read_length, iio_buffer_write_length);
 static struct iio_buf_attr buf_attr_length_ro = __ATTR(length,
@@ -1324,39 +1308,14 @@ static struct attribute *iio_buffer_attrs[] = {
        &iio_buf_attr_data_available.attr,
 };
 
-static bool iio_buffer_attr_is_core(struct attribute *attr)
-{
-       struct attribute *a;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(iio_buffer_attrs); i++) {
-               a = iio_buffer_attrs[i];
-               if (!strcmp(attr->name, a->name))
-                       return true;
-       }
-
-       return false;
-}
-
-#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
-#define to_iio_buf_attr(_attr) container_of(_attr, struct iio_buf_attr, attr)
-
 static ssize_t iio_buffer_dir_attr_show(struct kobject *kobj,
                                        struct attribute *attr,
                                        char *buf)
 {
        struct iio_buffer *buffer = container_of(kobj, struct iio_buffer, 
buffer_dir);
-       struct device_attribute *dattr;
-       struct iio_buf_attr *battr;
-
-       if (iio_buffer_attr_is_core(attr)) {
-               battr = to_iio_buf_attr(attr);
-               return battr->show(buffer, battr, buf);
-       }
-
-       dattr = to_dev_attr(attr);
+       struct iio_buf_attr *battr = to_iio_buf_attr(attr);
 
-       return dattr->show(&buffer->indio_dev->dev, dattr, buf);
+       return battr->show(buffer, battr, buf);
 }
 
 static ssize_t iio_buffer_dir_attr_store(struct kobject *kobj,
@@ -1365,17 +1324,9 @@ static ssize_t iio_buffer_dir_attr_store(struct kobject 
*kobj,
                                         size_t len)
 {
        struct iio_buffer *buffer = container_of(kobj, struct iio_buffer, 
buffer_dir);
-       struct device_attribute *dattr;
-       struct iio_buf_attr *battr;
-
-       if (iio_buffer_attr_is_core(attr)) {
-               battr = to_iio_buf_attr(attr);
-               return battr->store(buffer, battr, buf, len);
-       }
-
-       dattr = to_dev_attr(attr);
+       struct iio_buf_attr *battr = to_iio_buf_attr(attr);
 
-       return dattr->store(&buffer->indio_dev->dev, dattr, buf, len);
+       return battr->store(buffer, battr, buf, len);
 }
 
 static const struct sysfs_ops iio_buffer_dir_sysfs_ops = {
diff --git a/include/linux/iio/sysfs.h b/include/linux/iio/sysfs.h
index b532c875bc24..d25b47971c09 100644
--- a/include/linux/iio/sysfs.h
+++ b/include/linux/iio/sysfs.h
@@ -9,6 +9,7 @@
 #ifndef _INDUSTRIAL_IO_SYSFS_H_
 #define _INDUSTRIAL_IO_SYSFS_H_
 
+struct iio_buffer;
 struct iio_chan_spec;
 
 /**
@@ -28,6 +29,55 @@ struct iio_dev_attr {
 #define to_iio_dev_attr(_dev_attr)                             \
        container_of(_dev_attr, struct iio_dev_attr, dev_attr)
 
+/**
+ * struct iio_buf_attr - iio buffer specific attribute
+ * @attr:      underlying attribute
+ * @address:   associated register address
+ * @l:         list head for maintaining list of dynamically created attrs
+ * @c:         specification for the underlying channel
+ * @show:      sysfs show hook for this attribute
+ * @store:     sysfs store hook for this attribute
+ */
+struct iio_buf_attr {
+       struct attribute attr;
+       u64 address;
+       struct list_head l;
+       struct iio_chan_spec const *c;
+       ssize_t (*show)(struct iio_buffer *buffer, struct iio_buf_attr *attr,
+                       char *buf);
+       ssize_t (*store)(struct iio_buffer *buffer, struct iio_buf_attr *attr,
+                        const char *buf, size_t count);
+};
+
+/**
+ * struct iio_buf_const_attr - constant buffer specific attribute
+ *                         often used for things constant parameters of buffers
+ * @string:    attribute string
+ * @buf_attr:  underlying buffer attribute
+ */
+struct iio_buf_const_attr {
+       const char *string;
+       struct iio_buf_attr buf_attr;
+};
+
+#define to_iio_buf_attr(_attr) container_of(_attr, struct iio_buf_attr, attr)
+
+#define IIO_BUF_ATTR(_name, _mode, _show, _store)      \
+       struct iio_buf_attr iio_buf_attr_##_name =      \
+               __ATTR(_name, _mode, _show, _store)
+
+#define IIO_BUF_CONST_ATTR(_name, _string)                             \
+       struct iio_buf_const_attr iio_buf_const_attr_##_name            \
+       = { .string = _string,                                          \
+           .buf_attr = __ATTR(_name, 0444, iio_read_buf_const_attr, NULL)}
+
+#define to_iio_buf_const_attr(_buf_attr) \
+       container_of(_buf_attr, struct iio_buf_const_attr, buf_attr)
+
+ssize_t iio_read_buf_const_attr(struct iio_buffer *buffer,
+                               struct iio_buf_attr *attr,
+                               char *len);
+
 ssize_t iio_read_const_attr(struct device *dev,
                            struct device_attribute *attr,
                            char *len);
-- 
2.17.1

Reply via email to