Skip to content

Commit 15097c7

Browse files
commodojic23
authored andcommitted
iio: buffer: wrap all buffer attributes into iio_dev_attr
This change wraps all buffer attributes into iio_dev_attr objects, and assigns a reference to the IIO buffer they belong to. With the addition of multiple IIO buffers per one IIO device, we need a way to know which IIO buffer is being enabled/disabled/controlled. We know that all buffer attributes are device_attributes. So we can wrap them with a iio_dev_attr types. In the iio_dev_attr type, we can also hold a reference to an IIO buffer. So, we end up being able to allocate wrapped attributes for all buffer attributes (even the one from other drivers). The neat part with this mechanism, is that we don't need to add any extra cleanup, because these attributes are being added to a dynamic list that will get cleaned up via iio_free_chan_devattr_list(). With this change, the 'buffer->scan_el_dev_attr_list' list is being renamed to 'buffer->buffer_attr_list', effectively merging (or finalizing the merge) of the buffer/ & scan_elements/ attributes internally. Accessing these new buffer attributes can now be done via 'to_iio_dev_attr(attr)->buffer' inside the show/store handlers. Signed-off-by: Alexandru Ardelean <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jonathan Cameron <[email protected]>
1 parent 3e3d11b commit 15097c7

File tree

3 files changed

+54
-29
lines changed

3 files changed

+54
-29
lines changed

drivers/iio/industrialio-buffer.c

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,7 @@ static ssize_t iio_scan_el_show(struct device *dev,
253253
char *buf)
254254
{
255255
int ret;
256-
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
257-
struct iio_buffer *buffer = indio_dev->buffer;
256+
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
258257

259258
/* Ensure ret is 0 or 1. */
260259
ret = !!test_bit(to_iio_dev_attr(attr)->address,
@@ -367,8 +366,8 @@ static ssize_t iio_scan_el_store(struct device *dev,
367366
int ret;
368367
bool state;
369368
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
370-
struct iio_buffer *buffer = indio_dev->buffer;
371369
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
370+
struct iio_buffer *buffer = this_attr->buffer;
372371

373372
ret = strtobool(buf, &state);
374373
if (ret < 0)
@@ -402,8 +401,7 @@ static ssize_t iio_scan_el_ts_show(struct device *dev,
402401
struct device_attribute *attr,
403402
char *buf)
404403
{
405-
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
406-
struct iio_buffer *buffer = indio_dev->buffer;
404+
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
407405

408406
return sprintf(buf, "%d\n", buffer->scan_timestamp);
409407
}
@@ -415,7 +413,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
415413
{
416414
int ret;
417415
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
418-
struct iio_buffer *buffer = indio_dev->buffer;
416+
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
419417
bool state;
420418

421419
ret = strtobool(buf, &state);
@@ -448,7 +446,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
448446
IIO_SEPARATE,
449447
&indio_dev->dev,
450448
buffer,
451-
&buffer->scan_el_dev_attr_list);
449+
&buffer->buffer_attr_list);
452450
if (ret)
453451
return ret;
454452
attrcount++;
@@ -460,7 +458,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
460458
0,
461459
&indio_dev->dev,
462460
buffer,
463-
&buffer->scan_el_dev_attr_list);
461+
&buffer->buffer_attr_list);
464462
if (ret)
465463
return ret;
466464
attrcount++;
@@ -473,7 +471,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
473471
0,
474472
&indio_dev->dev,
475473
buffer,
476-
&buffer->scan_el_dev_attr_list);
474+
&buffer->buffer_attr_list);
477475
else
478476
ret = __iio_add_chan_devattr("en",
479477
chan,
@@ -483,7 +481,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
483481
0,
484482
&indio_dev->dev,
485483
buffer,
486-
&buffer->scan_el_dev_attr_list);
484+
&buffer->buffer_attr_list);
487485
if (ret)
488486
return ret;
489487
attrcount++;
@@ -495,8 +493,7 @@ static ssize_t iio_buffer_read_length(struct device *dev,
495493
struct device_attribute *attr,
496494
char *buf)
497495
{
498-
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
499-
struct iio_buffer *buffer = indio_dev->buffer;
496+
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
500497

501498
return sprintf(buf, "%d\n", buffer->length);
502499
}
@@ -506,7 +503,7 @@ static ssize_t iio_buffer_write_length(struct device *dev,
506503
const char *buf, size_t len)
507504
{
508505
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
509-
struct iio_buffer *buffer = indio_dev->buffer;
506+
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
510507
unsigned int val;
511508
int ret;
512509

@@ -538,8 +535,7 @@ static ssize_t iio_buffer_show_enable(struct device *dev,
538535
struct device_attribute *attr,
539536
char *buf)
540537
{
541-
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
542-
struct iio_buffer *buffer = indio_dev->buffer;
538+
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
543539

544540
return sprintf(buf, "%d\n", iio_buffer_is_active(buffer));
545541
}
@@ -1154,7 +1150,7 @@ static ssize_t iio_buffer_store_enable(struct device *dev,
11541150
int ret;
11551151
bool requested_state;
11561152
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1157-
struct iio_buffer *buffer = indio_dev->buffer;
1153+
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
11581154
bool inlist;
11591155

11601156
ret = strtobool(buf, &requested_state);
@@ -1183,8 +1179,7 @@ static ssize_t iio_buffer_show_watermark(struct device *dev,
11831179
struct device_attribute *attr,
11841180
char *buf)
11851181
{
1186-
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1187-
struct iio_buffer *buffer = indio_dev->buffer;
1182+
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
11881183

11891184
return sprintf(buf, "%u\n", buffer->watermark);
11901185
}
@@ -1195,7 +1190,7 @@ static ssize_t iio_buffer_store_watermark(struct device *dev,
11951190
size_t len)
11961191
{
11971192
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1198-
struct iio_buffer *buffer = indio_dev->buffer;
1193+
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
11991194
unsigned int val;
12001195
int ret;
12011196

@@ -1228,8 +1223,7 @@ static ssize_t iio_dma_show_data_available(struct device *dev,
12281223
struct device_attribute *attr,
12291224
char *buf)
12301225
{
1231-
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
1232-
struct iio_buffer *buffer = indio_dev->buffer;
1226+
struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer;
12331227

12341228
return sprintf(buf, "%zu\n", iio_buffer_data_available(buffer));
12351229
}
@@ -1254,6 +1248,27 @@ static struct attribute *iio_buffer_attrs[] = {
12541248
&dev_attr_data_available.attr,
12551249
};
12561250

1251+
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
1252+
1253+
static struct attribute *iio_buffer_wrap_attr(struct iio_buffer *buffer,
1254+
struct attribute *attr)
1255+
{
1256+
struct device_attribute *dattr = to_dev_attr(attr);
1257+
struct iio_dev_attr *iio_attr;
1258+
1259+
iio_attr = kzalloc(sizeof(*iio_attr), GFP_KERNEL);
1260+
if (!iio_attr)
1261+
return NULL;
1262+
1263+
iio_attr->buffer = buffer;
1264+
memcpy(&iio_attr->dev_attr, dattr, sizeof(iio_attr->dev_attr));
1265+
iio_attr->dev_attr.attr.name = kstrdup_const(attr->name, GFP_KERNEL);
1266+
1267+
list_add(&iio_attr->l, &buffer->buffer_attr_list);
1268+
1269+
return &iio_attr->dev_attr.attr;
1270+
}
1271+
12571272
static int iio_buffer_register_legacy_sysfs_groups(struct iio_dev *indio_dev,
12581273
struct attribute **buffer_attrs,
12591274
int buffer_attrcount,
@@ -1329,7 +1344,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
13291344
}
13301345

13311346
scan_el_attrcount = 0;
1332-
INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list);
1347+
INIT_LIST_HEAD(&buffer->buffer_attr_list);
13331348
channels = indio_dev->channels;
13341349
if (channels) {
13351350
/* new magic */
@@ -1376,9 +1391,19 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
13761391

13771392
buffer_attrcount += ARRAY_SIZE(iio_buffer_attrs);
13781393

1379-
attrn = buffer_attrcount;
1394+
for (i = 0; i < buffer_attrcount; i++) {
1395+
struct attribute *wrapped;
1396+
1397+
wrapped = iio_buffer_wrap_attr(buffer, attr[i]);
1398+
if (!wrapped) {
1399+
ret = -ENOMEM;
1400+
goto error_free_scan_mask;
1401+
}
1402+
attr[i] = wrapped;
1403+
}
13801404

1381-
list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l)
1405+
attrn = 0;
1406+
list_for_each_entry(p, &buffer->buffer_attr_list, l)
13821407
attr[attrn++] = &p->dev_attr.attr;
13831408

13841409
buffer->buffer_group.name = kasprintf(GFP_KERNEL, "buffer%d", index);
@@ -1412,7 +1437,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer,
14121437
error_free_scan_mask:
14131438
bitmap_free(buffer->scan_mask);
14141439
error_cleanup_dynamic:
1415-
iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list);
1440+
iio_free_chan_devattr_list(&buffer->buffer_attr_list);
14161441

14171442
return ret;
14181443
}
@@ -1443,7 +1468,7 @@ static void __iio_buffer_free_sysfs_and_mask(struct iio_buffer *buffer)
14431468
bitmap_free(buffer->scan_mask);
14441469
kfree(buffer->buffer_group.name);
14451470
kfree(buffer->buffer_group.attrs);
1446-
iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list);
1471+
iio_free_chan_devattr_list(&buffer->buffer_attr_list);
14471472
}
14481473

14491474
void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev)

drivers/iio/industrialio-core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1357,7 +1357,7 @@ void iio_free_chan_devattr_list(struct list_head *attr_list)
13571357
struct iio_dev_attr *p, *n;
13581358

13591359
list_for_each_entry_safe(p, n, attr_list, l) {
1360-
kfree(p->dev_attr.attr.name);
1360+
kfree_const(p->dev_attr.attr.name);
13611361
list_del(&p->l);
13621362
kfree(p);
13631363
}

include/linux/iio/buffer_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ struct iio_buffer {
9797
/* @scan_timestamp: Does the scan mode include a timestamp. */
9898
bool scan_timestamp;
9999

100-
/* @scan_el_dev_attr_list: List of scan element related attributes. */
101-
struct list_head scan_el_dev_attr_list;
100+
/* @buffer_attr_list: List of buffer attributes. */
101+
struct list_head buffer_attr_list;
102102

103103
/*
104104
* @buffer_group: Attributes of the new buffer group.

0 commit comments

Comments
 (0)