Commit cbe88bcc authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Jonathan Cameron

iio: buffer: Coalesce adjacent demux table entries

When copying multiple multiple samples that are adjacent in both the source as
well as the destination buffer, instead of creating a new demux table entry for
each sample just increase the length of the previous entry by the size of the
new sample. This makes the demuxing process slightly more efficient.
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 61072dbc
...@@ -942,13 +942,34 @@ int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data) ...@@ -942,13 +942,34 @@ int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data)
} }
EXPORT_SYMBOL_GPL(iio_push_to_buffers); EXPORT_SYMBOL_GPL(iio_push_to_buffers);
static int iio_buffer_add_demux(struct iio_buffer *buffer,
struct iio_demux_table **p, unsigned int in_loc, unsigned int out_loc,
unsigned int length)
{
if (*p && (*p)->from + (*p)->length == in_loc &&
(*p)->to + (*p)->length == out_loc) {
(*p)->length += length;
} else {
*p = kmalloc(sizeof(*p), GFP_KERNEL);
if (*p == NULL)
return -ENOMEM;
(*p)->from = in_loc;
(*p)->to = out_loc;
(*p)->length = length;
list_add_tail(&(*p)->l, &buffer->demux_list);
}
return 0;
}
static int iio_buffer_update_demux(struct iio_dev *indio_dev, static int iio_buffer_update_demux(struct iio_dev *indio_dev,
struct iio_buffer *buffer) struct iio_buffer *buffer)
{ {
const struct iio_chan_spec *ch; const struct iio_chan_spec *ch;
int ret, in_ind = -1, out_ind, length; int ret, in_ind = -1, out_ind, length;
unsigned in_loc = 0, out_loc = 0; unsigned in_loc = 0, out_loc = 0;
struct iio_demux_table *p; struct iio_demux_table *p = NULL;
/* Clear out any old demux */ /* Clear out any old demux */
iio_buffer_demux_free(buffer); iio_buffer_demux_free(buffer);
...@@ -981,11 +1002,6 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev, ...@@ -981,11 +1002,6 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev,
/* Make sure we are aligned */ /* Make sure we are aligned */
in_loc = roundup(in_loc, length) + length; in_loc = roundup(in_loc, length) + length;
} }
p = kmalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL) {
ret = -ENOMEM;
goto error_clear_mux_table;
}
ch = iio_find_channel_from_si(indio_dev, in_ind); ch = iio_find_channel_from_si(indio_dev, in_ind);
if (ch->scan_type.repeat > 1) if (ch->scan_type.repeat > 1)
length = ch->scan_type.storagebits / 8 * length = ch->scan_type.storagebits / 8 *
...@@ -994,20 +1010,14 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev, ...@@ -994,20 +1010,14 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev,
length = ch->scan_type.storagebits / 8; length = ch->scan_type.storagebits / 8;
out_loc = roundup(out_loc, length); out_loc = roundup(out_loc, length);
in_loc = roundup(in_loc, length); in_loc = roundup(in_loc, length);
p->from = in_loc; ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length);
p->to = out_loc; if (ret)
p->length = length; goto error_clear_mux_table;
list_add_tail(&p->l, &buffer->demux_list);
out_loc += length; out_loc += length;
in_loc += length; in_loc += length;
} }
/* Relies on scan_timestamp being last */ /* Relies on scan_timestamp being last */
if (buffer->scan_timestamp) { if (buffer->scan_timestamp) {
p = kmalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL) {
ret = -ENOMEM;
goto error_clear_mux_table;
}
ch = iio_find_channel_from_si(indio_dev, ch = iio_find_channel_from_si(indio_dev,
indio_dev->scan_index_timestamp); indio_dev->scan_index_timestamp);
if (ch->scan_type.repeat > 1) if (ch->scan_type.repeat > 1)
...@@ -1017,10 +1027,9 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev, ...@@ -1017,10 +1027,9 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev,
length = ch->scan_type.storagebits / 8; length = ch->scan_type.storagebits / 8;
out_loc = roundup(out_loc, length); out_loc = roundup(out_loc, length);
in_loc = roundup(in_loc, length); in_loc = roundup(in_loc, length);
p->from = in_loc; ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length);
p->to = out_loc; if (ret)
p->length = length; goto error_clear_mux_table;
list_add_tail(&p->l, &buffer->demux_list);
out_loc += length; out_loc += length;
in_loc += length; in_loc += length;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment