Skip to content

Commit 577a66e

Browse files
mattmart3jic23
authored andcommitted
iio: iio-mux: kzalloc instead of devm_kzalloc to ensure page alignment
During channel configuration, the iio-mux driver allocates a page with devm_kzalloc(PAGE_SIZE) to read channel ext_info. However, the resulting buffer points to an offset of the page due to the devres header sitting at the beginning of the allocated area. This leads to failure in the provider driver when sysfs_emit* helpers are used to format the ext_info attributes. Switch to plain kzalloc version. The devres version is not strictly necessary as the buffer is only accessed during the channel configuration phase. Rely on __free cleanup to deallocate the buffer. Also, move the ext_info handling into a new function to have the page buffer definition and assignment in one statement as suggested by cleanup documentation. Signed-off-by: Matteo Martelli <[email protected]> Fixes: 7ba9df5 ("iio: multiplexer: new iio category and iio-mux driver") Reviewed-by: David Lechner <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jonathan Cameron <[email protected]>
1 parent f5ab868 commit 577a66e

File tree

1 file changed

+46
-38
lines changed

1 file changed

+46
-38
lines changed

drivers/iio/multiplexer/iio-mux.c

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Author: Peter Rosin <[email protected]>
88
*/
99

10+
#include <linux/cleanup.h>
1011
#include <linux/err.h>
1112
#include <linux/iio/consumer.h>
1213
#include <linux/iio/iio.h>
@@ -237,49 +238,18 @@ static ssize_t mux_write_ext_info(struct iio_dev *indio_dev, uintptr_t private,
237238
return ret;
238239
}
239240

240-
static int mux_configure_channel(struct device *dev, struct mux *mux,
241-
u32 state, const char *label, int idx)
241+
static int mux_configure_chan_ext_info(struct device *dev, struct mux *mux,
242+
int idx, int num_ext_info)
242243
{
243244
struct mux_child *child = &mux->child[idx];
244-
struct iio_chan_spec *chan = &mux->chan[idx];
245245
struct iio_chan_spec const *pchan = mux->parent->channel;
246-
char *page = NULL;
247-
int num_ext_info;
248246
int i;
249247
int ret;
250248

251-
chan->indexed = 1;
252-
chan->output = pchan->output;
253-
chan->datasheet_name = label;
254-
chan->ext_info = mux->ext_info;
255-
256-
ret = iio_get_channel_type(mux->parent, &chan->type);
257-
if (ret < 0) {
258-
dev_err(dev, "failed to get parent channel type\n");
259-
return ret;
260-
}
261-
262-
if (iio_channel_has_info(pchan, IIO_CHAN_INFO_RAW))
263-
chan->info_mask_separate |= BIT(IIO_CHAN_INFO_RAW);
264-
if (iio_channel_has_info(pchan, IIO_CHAN_INFO_SCALE))
265-
chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SCALE);
266-
267-
if (iio_channel_has_available(pchan, IIO_CHAN_INFO_RAW))
268-
chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_RAW);
269-
270-
if (state >= mux_control_states(mux->control)) {
271-
dev_err(dev, "too many channels\n");
272-
return -EINVAL;
273-
}
274-
275-
chan->channel = state;
249+
char *page __free(kfree) = kzalloc(PAGE_SIZE, GFP_KERNEL);
250+
if (!page)
251+
return -ENOMEM;
276252

277-
num_ext_info = iio_get_channel_ext_info_count(mux->parent);
278-
if (num_ext_info) {
279-
page = devm_kzalloc(dev, PAGE_SIZE, GFP_KERNEL);
280-
if (!page)
281-
return -ENOMEM;
282-
}
283253
child->ext_info_cache = devm_kcalloc(dev,
284254
num_ext_info,
285255
sizeof(*child->ext_info_cache),
@@ -318,8 +288,46 @@ static int mux_configure_channel(struct device *dev, struct mux *mux,
318288
child->ext_info_cache[i].size = ret;
319289
}
320290

321-
if (page)
322-
devm_kfree(dev, page);
291+
return 0;
292+
}
293+
294+
static int mux_configure_channel(struct device *dev, struct mux *mux, u32 state,
295+
const char *label, int idx)
296+
{
297+
struct iio_chan_spec *chan = &mux->chan[idx];
298+
struct iio_chan_spec const *pchan = mux->parent->channel;
299+
int num_ext_info;
300+
int ret;
301+
302+
chan->indexed = 1;
303+
chan->output = pchan->output;
304+
chan->datasheet_name = label;
305+
chan->ext_info = mux->ext_info;
306+
307+
ret = iio_get_channel_type(mux->parent, &chan->type);
308+
if (ret < 0) {
309+
dev_err(dev, "failed to get parent channel type\n");
310+
return ret;
311+
}
312+
313+
if (iio_channel_has_info(pchan, IIO_CHAN_INFO_RAW))
314+
chan->info_mask_separate |= BIT(IIO_CHAN_INFO_RAW);
315+
if (iio_channel_has_info(pchan, IIO_CHAN_INFO_SCALE))
316+
chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SCALE);
317+
318+
if (iio_channel_has_available(pchan, IIO_CHAN_INFO_RAW))
319+
chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_RAW);
320+
321+
if (state >= mux_control_states(mux->control)) {
322+
dev_err(dev, "too many channels\n");
323+
return -EINVAL;
324+
}
325+
326+
chan->channel = state;
327+
328+
num_ext_info = iio_get_channel_ext_info_count(mux->parent);
329+
if (num_ext_info)
330+
return mux_configure_chan_ext_info(dev, mux, idx, num_ext_info);
323331

324332
return 0;
325333
}

0 commit comments

Comments
 (0)