From 947f1079074a260ba200419d5cba6b8549d5ac0c Mon Sep 17 00:00:00 2001 From: Joshua Crofts Date: Wed, 8 Jul 2026 07:34:13 +0200 Subject: [PATCH 01/31] iio: adc: max34408: add missing 'select REGMAP_I2C' to Kconfig The Kconfig entry for the MAX34408 is missing a 'select REGMAP_I2C', causing build failures. Fixes: cf27775838c5 ("iio: adc: Add driver support for MAX34408/9") Cc: stable@vger.kernel.org Signed-off-by: Joshua Crofts Reviewed-by: Andy Shevchenko Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 3755a81c1efd..9deecd2cd3b4 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -1086,6 +1086,7 @@ config MAX14001 config MAX34408 tristate "Maxim max34408/max344089 ADC driver" depends on I2C + select REGMAP_I2C help Say yes here to build support for Maxim max34408/max34409 current sense monitor with 8-bits ADC interface with overcurrent delay/threshold and From b7c969d0d445c415b8e9f32627d7e8f092c7e916 Mon Sep 17 00:00:00 2001 From: Joshua Crofts Date: Wed, 8 Jul 2026 07:34:14 +0200 Subject: [PATCH 02/31] iio: adc: max14001: add missing 'select REGMAP' to Kconfig The Kconfig entry for the MAX14001 is missing a 'select REGMAP', causing build failures. Fixes: 59795109fa67 ("iio: adc: max14001: New driver") Cc: stable@vger.kernel.org Signed-off-by: Joshua Crofts Reviewed-by: Andy Shevchenko Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 9deecd2cd3b4..c6d3cf68b1f7 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -1076,6 +1076,7 @@ config MAX1363 config MAX14001 tristate "Analog Devices MAX14001/MAX14002 ADC driver" depends on SPI + select REGMAP help Say yes here to build support for Analog Devices MAX14001/MAX14002 Configurable, Isolated 10-bit ADCs for Multi-Range Binary Inputs. From 967d066f5334740f656577bc51c381a1bb707b61 Mon Sep 17 00:00:00 2001 From: Sanjay Chitroda Date: Thu, 25 Jun 2026 17:46:11 +0530 Subject: [PATCH 03/31] iio: temperature: hid-sensor-temperature: switch to non-devm iio_device_register() Avoid using devm_iio_device_register(), as this driver requires explicit error handling and teardown ordering. With devm_iio_device_register(), IIO device remains registered until the devres cleanup phase. However, driver's remove() callback removes the sensor hub callback and trigger support. This can create a race window where IIO device is still visible and read_raw() requests are issued. These requests might call sensor_hub_input_attr_get_raw_value(), which waits up to 5 seconds for a response from the sensor hub callback that has already been removed. Add an explicit iio_device_unregister() call in the teardown path to ensure deterministic cleanup, so that userspace can no longer access the device once backend resources begin to be dismantled. Fixes: 59d0f2da3569 ("iio: hid: Add temperature sensor support") Cc: stable@vger.kernel.org Reviewed-by: Maxwell Doose Reviewed-by: Andy Shevchenko Signed-off-by: Sanjay Chitroda Acked-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/hid-sensor-temperature.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iio/temperature/hid-sensor-temperature.c b/drivers/iio/temperature/hid-sensor-temperature.c index 9f628a8e5cfb..34bff7e9f3a3 100644 --- a/drivers/iio/temperature/hid-sensor-temperature.c +++ b/drivers/iio/temperature/hid-sensor-temperature.c @@ -244,7 +244,7 @@ static int hid_temperature_probe(struct platform_device *pdev) if (ret) goto error_remove_trigger; - ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); + ret = iio_device_register(indio_dev); if (ret) goto error_remove_callback; @@ -264,6 +264,7 @@ static void hid_temperature_remove(struct platform_device *pdev) struct iio_dev *indio_dev = platform_get_drvdata(pdev); struct temperature_state *temp_st = iio_priv(indio_dev); + iio_device_unregister(indio_dev); sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TEMPERATURE); hid_sensor_remove_trigger(indio_dev, &temp_st->common_attributes); } From a130404ce0b69ca1438126bd81c1985d3b4d2e6f Mon Sep 17 00:00:00 2001 From: Erick Henrique Date: Fri, 3 Jul 2026 17:52:36 -0300 Subject: [PATCH 04/31] iio: dac: m62332: Fix regulator reference count imbalance m62332_set_value() enables the Vcc regulator on every write of a non-zero value and disables it on every write of zero, without tracking the channel's current state. Because the regulator is reference counted, changing a channel directly from one non-zero value to another enables it more than once, while a later write of zero disables it only once. The reference count never returns to zero and the regulator is left enabled indefinitely. Only enable the regulator on the transition from zero to non-zero, and only disable it on the transition from non-zero to zero, using the previously stored channel value to detect the edge. Balance the regulator on the I2C error path so the reference count stays consistent if the write fails. Fixes: b87b0c0f81e8 ("iio: add m62332 DAC driver") Reported-by: Sashiko Closes: https://sashiko.dev/#/patchset/20260418130322.106769-1-erick.henrique.rodrigues%40usp.br Cc: stable@vger.kernel.org Signed-off-by: Erick Henrique Signed-off-by: Jonathan Cameron --- drivers/iio/dac/m62332.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/iio/dac/m62332.c b/drivers/iio/dac/m62332.c index 7e80c0eb5cc1..60bb672b70e2 100644 --- a/drivers/iio/dac/m62332.c +++ b/drivers/iio/dac/m62332.c @@ -32,6 +32,7 @@ static int m62332_set_value(struct iio_dev *indio_dev, u8 val, int channel) { struct m62332_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; + bool enabling, disabling; u8 outbuf[2]; int res; @@ -43,7 +44,10 @@ static int m62332_set_value(struct iio_dev *indio_dev, u8 val, int channel) mutex_lock(&data->mutex); - if (val) { + enabling = val && !data->raw[channel]; + disabling = !val && data->raw[channel]; + + if (enabling) { res = regulator_enable(data->vcc); if (res) goto out; @@ -52,14 +56,17 @@ static int m62332_set_value(struct iio_dev *indio_dev, u8 val, int channel) res = i2c_master_send(client, outbuf, ARRAY_SIZE(outbuf)); if (res >= 0 && res != ARRAY_SIZE(outbuf)) res = -EIO; - if (res < 0) + if (res < 0) { + if (enabling) + regulator_disable(data->vcc); goto out; + } + + if (disabling) + regulator_disable(data->vcc); data->raw[channel] = val; - if (!val) - regulator_disable(data->vcc); - mutex_unlock(&data->mutex); return 0; From a41000ba3a230bed1e422f283486ff8f77fe0d30 Mon Sep 17 00:00:00 2001 From: Laxman Acharya Padhya Date: Sat, 4 Jul 2026 14:19:12 +0545 Subject: [PATCH 05/31] iio: light: gp2ap002: Disable regulators on resume failure If enabling VIO fails after VDD has been enabled, runtime resume returns without disabling VDD. Likewise, if device reinitialization fails, both supplies remain enabled. The runtime PM core keeps the device suspended when its resume callback fails, so the supplies must be restored to the suspended state. Disable the supplies enabled by the callback before returning an error. Fixes: 97d642e23037 ("iio: light: Add a driver for Sharp GP2AP002x00F") Assisted-by: Codex:gpt-5 Signed-off-by: Laxman Acharya Padhya Reviewed-by: Linus Walleij Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/light/gp2ap002.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c index a8db514cca5e..05773e24931b 100644 --- a/drivers/iio/light/gp2ap002.c +++ b/drivers/iio/light/gp2ap002.c @@ -669,7 +669,7 @@ static int gp2ap002_runtime_resume(struct device *dev) ret = regulator_enable(gp2ap002->vio); if (ret) { dev_err(dev, "failed to enable VIO regulator in resume path\n"); - return ret; + goto out_disable_vdd; } msleep(20); @@ -677,13 +677,19 @@ static int gp2ap002_runtime_resume(struct device *dev) ret = gp2ap002_init(gp2ap002); if (ret) { dev_err(dev, "re-initialization failed\n"); - return ret; + goto out_disable_vio; } /* Re-activate the IRQ */ enable_irq(gp2ap002->irq); return 0; + +out_disable_vio: + regulator_disable(gp2ap002->vio); +out_disable_vdd: + regulator_disable(gp2ap002->vdd); + return ret; } static DEFINE_RUNTIME_DEV_PM_OPS(gp2ap002_dev_pm_ops, gp2ap002_runtime_suspend, From bcb721c1bcb02ab225b3937bf131a0bc6fc1fecd Mon Sep 17 00:00:00 2001 From: Paul Geurts Date: Mon, 6 Jul 2026 09:48:03 +0200 Subject: [PATCH 06/31] iio: ti-ads7138: Disable STATS_EN bit while reading conversion results There is a data race in reading the STATS registers, resulting in wrong data being read. When the data in the RECENT register switches between 0x24F0 and 0x2500, occasionally value 0x2400 or 0x25F0 is read. This happens when the value is updated in between reading MSB and LSB. The data sheet says: "Until a new conversion result is available, previous values can be read from the statistics registers. Before reading the statistics registers, set STATS_EN to 0 to prevent any updates to this register block." As the STATS_EN is currently not cleared, the values of the stats registers might change mid read, giving faulty values. Disable the STATS_EN bit before reading one of the statistics registers to make sure the device does not update the register mid read. This is applicable to registers MAX_CHn_xSB, MIN_CHn_xSB and RECENT_CHn_xSB. This means reading one of the statistics registers resets the MAX and MIN registers. This is unfortunate, but necessary to get correct data from the device. Signed-off-by: Paul Geurts Fixes: 024b08fee342 ("iio: adc: Add driver for ADS7128 / ADS7138") Reviewed-by: David Lechner Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ti-ads7138.c | 42 ++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/iio/adc/ti-ads7138.c b/drivers/iio/adc/ti-ads7138.c index af87f5f19a0f..da82a6947b2b 100644 --- a/drivers/iio/adc/ti-ads7138.c +++ b/drivers/iio/adc/ti-ads7138.c @@ -227,6 +227,26 @@ static int ads7138_osr_to_bits(int osr) return -EINVAL; } +static int ads7138_read_statistics(const struct i2c_client *client, u8 reg, + u8 *out_values, u8 length) +{ + int ret; + + /* Disable statistics update so the value is not updated mid read */ + ret = ads7138_i2c_clear_bit(client, ADS7138_REG_GENERAL_CFG, + ADS7138_GENERAL_CFG_STATS_EN); + if (ret) + return ret; + + ret = ads7138_i2c_read_block(client, reg, out_values, length); + if (ret) + return ret; + + /* Enable statistics update after read */ + return ads7138_i2c_set_bit(client, ADS7138_REG_GENERAL_CFG, + ADS7138_GENERAL_CFG_STATS_EN); +} + static int ads7138_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -236,28 +256,32 @@ static int ads7138_read_raw(struct iio_dev *indio_dev, u8 values[2]; switch (mask) { + /* + * Reading the statistics registers reinitializes them. This is + * unfortunate but necessary to prevent data races. + */ case IIO_CHAN_INFO_RAW: - ret = ads7138_i2c_read_block(data->client, - ADS7138_REG_RECENT_LSB_CH(chan->channel), - values, ARRAY_SIZE(values)); + ret = ads7138_read_statistics(data->client, + ADS7138_REG_RECENT_LSB_CH(chan->channel), + values, ARRAY_SIZE(values)); if (ret) return ret; *val = get_unaligned_le16(values); return IIO_VAL_INT; case IIO_CHAN_INFO_PEAK: - ret = ads7138_i2c_read_block(data->client, - ADS7138_REG_MAX_LSB_CH(chan->channel), - values, ARRAY_SIZE(values)); + ret = ads7138_read_statistics(data->client, + ADS7138_REG_MAX_LSB_CH(chan->channel), + values, ARRAY_SIZE(values)); if (ret) return ret; *val = get_unaligned_le16(values); return IIO_VAL_INT; case IIO_CHAN_INFO_TROUGH: - ret = ads7138_i2c_read_block(data->client, - ADS7138_REG_MIN_LSB_CH(chan->channel), - values, ARRAY_SIZE(values)); + ret = ads7138_read_statistics(data->client, + ADS7138_REG_MIN_LSB_CH(chan->channel), + values, ARRAY_SIZE(values)); if (ret) return ret; From 739aac87638f06fcf851df41ecd52d30ab7b0570 Mon Sep 17 00:00:00 2001 From: Joshua Crofts Date: Wed, 8 Jul 2026 21:50:28 +0200 Subject: [PATCH 07/31] iio: dac: mcp47feb02: add missing 'select REGMAP_I2C' to Kconfig The Kconfig entry for the MCP47FEB02 is missing a 'select REGMAP_I2C', causing build failures. Fixes: bf394cc80369 ("iio: dac: adding support for Microchip MCP47FEB02") Cc: stable@vger.kernel.org Signed-off-by: Joshua Crofts Signed-off-by: Jonathan Cameron --- drivers/iio/dac/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 657c68e75542..14a246729d2b 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -552,6 +552,7 @@ config MCP4728 config MCP47FEB02 tristate "MCP47F(E/V)B01/02/04/08/11/12/14/18/21/22/24/28 DAC driver" depends on I2C + select REGMAP_I2C help Say yes here if you want to build the driver for the Microchip: - 8-bit DAC: From f2c5c76306fadb834dd5ea76cab0b7cd447e6035 Mon Sep 17 00:00:00 2001 From: Babanpreet Singh Date: Sat, 18 Jul 2026 18:22:36 +0000 Subject: [PATCH 08/31] iio: dac: ad3552r-hs: fix scnprintf() buffer bound in data source show ad3552r_hs_show_data_source_avail() formats the available data source names into a 128-byte stack buffer, but bounds each scnprintf() with PAGE_SIZE instead of the buffer size, so the bound does not protect the destination at all. This cannot overflow today - dbgfs_attr_source[] has two entries, "normal" and "ramp-16bit", 18 bytes formatted - but the bound stops protecting the stack the day the table grows. Use sizeof(buf) so the bound matches the destination. Found by smatch: drivers/iio/dac/ad3552r-hs.c:593 ad3552r_hs_show_data_source_avail() error: scnprintf() 'buf[len]' too small (128 vs 4096) Fixes: b1c5d68ea66e ("iio: dac: ad3552r-hs: add support for internal ramp") Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Babanpreet Singh Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad3552r-hs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/dac/ad3552r-hs.c b/drivers/iio/dac/ad3552r-hs.c index 6bc64f53bce9..5d6c2517a7a8 100644 --- a/drivers/iio/dac/ad3552r-hs.c +++ b/drivers/iio/dac/ad3552r-hs.c @@ -591,7 +591,7 @@ static ssize_t ad3552r_hs_show_data_source_avail(struct file *f, int i; for (i = 0; i < ARRAY_SIZE(dbgfs_attr_source); i++) { - len += scnprintf(buf + len, PAGE_SIZE - len, "%s ", + len += scnprintf(buf + len, sizeof(buf) - len, "%s ", dbgfs_attr_source[i]); } buf[len - 1] = '\n'; From 6288b593e76eb10329326f2cd51e32557203b9e5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 15 Jul 2026 08:42:43 -0700 Subject: [PATCH 09/31] iio: buffer: Fix potential use-after-free in anonymous buffer release An anonymous buffer handle holds a reference to the underlying IIO device. The reference is dropped in the buffer handle's release function. If the device has been removed, either through unbind or hot-unplug, the buffer handle might hold the last reference. The release function takes the mutex for the buffer using a guard, which means the unlock happens after all the code in the function, including `iio_device_put()`. If the anonymous buffer holds the last reference this might free both the IIO device and the buffer, which contains the mutex, leading to use-after-free when the mutex is unlocked. Fix this by using a scoped guard just around the buffer dmabuf list access, making sure the mutex is unlocked before releasing the IIO device. Version 10 of the patch that introduced this issue used this exact scheme of first unlocking and then dropping the reference [1]. During review it was suggested to use a guard instead, and version 11 made that change [2]. Reported-by: codex:gpt-5.6 Fixes: 3e26d9f08fbe ("iio: core: Add new DMABUF interface infrastructure") Signed-off-by: Lars-Peter Clausen Link: https://lore.kernel.org/linux-iio/20240605110845.86740-4-paul@crapouillou.net #[1] Link: https://lore.kernel.org/linux-iio/20240618100302.72886-4-paul@crapouillou.net #[2] Reviewed-by: Andy Shevchenko Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 531fc4ccc15d..04b3916f89e2 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1619,12 +1619,16 @@ static int iio_buffer_chrdev_release(struct inode *inode, struct file *filep) wake_up(&buffer->pollq); - guard(mutex)(&buffer->dmabufs_mutex); - - /* Close all attached DMABUFs */ - list_for_each_entry_safe(priv, tmp, &buffer->dmabufs, entry) { - list_del_init(&priv->entry); - iio_buffer_dmabuf_put(priv->attach); + /* + * The mutex must be unlocked before iio_device_put(), which might drop the + * last reference and free the buffer. + */ + scoped_guard(mutex, &buffer->dmabufs_mutex) { + /* Close all attached DMABUFs */ + list_for_each_entry_safe(priv, tmp, &buffer->dmabufs, entry) { + list_del_init(&priv->entry); + iio_buffer_dmabuf_put(priv->attach); + } } kfree(ib); From f25ec4627d935dedfb5fe83bd2c2678cdcc19611 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 15 Jul 2026 08:42:44 -0700 Subject: [PATCH 10/31] iio: buffer: Tie IIO dma fence lock lifetime to the fence The `iio_dma_fence` implementation currently uses a lock embedded in the `iio_dmabuf_priv`. But the `iio_dma_fence` can outlive the `iio_dmabuf_priv`, which can cause a use-after-free. Tie the lifetime of the lock to the lifetime of the fence by embedding them in the same struct. We can't just hold a reference to the `iio_dmabuf_priv` from the `iio_dma_fence` since `iio_buffer_dmabuf_release()` might sleep and the fence release callback is not allowed to sleep. Note that the `dma_fence` framework now has an internal lock that gets used when the passing `NULL` for `lock` in `dma_fence_init()`, but in order to allow this patch to be backportable use an external lock. Reported-by: codex:gpt-5.6 Fixes: 3e26d9f08fbe ("iio: core: Add new DMABUF interface infrastructure") Signed-off-by: Lars-Peter Clausen Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 04b3916f89e2..31c06bffdce8 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -47,9 +47,6 @@ struct iio_dmabuf_priv { u64 context; - /* Spinlock used for locking the dma_fence */ - spinlock_t lock; - struct dma_buf_attachment *attach; struct sg_table *sgt; enum dma_data_direction dir; @@ -58,6 +55,7 @@ struct iio_dmabuf_priv { struct iio_dma_fence { struct dma_fence base; + spinlock_t lock; /* protects base */ struct iio_dmabuf_priv *priv; struct work_struct work; }; @@ -1706,7 +1704,6 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib, if (!priv) return -ENOMEM; - spin_lock_init(&priv->lock); priv->context = dma_fence_context_alloc(1); dmabuf = dma_buf_get(fd); @@ -1896,6 +1893,8 @@ static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib, goto err_attachment_put; } + spin_lock_init(&fence->lock); + fence->priv = priv; seqno = atomic_add_return(1, &priv->seqno); @@ -1906,7 +1905,7 @@ static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib, * the dma_fence. */ dma_fence_init(&fence->base, &iio_buffer_dma_fence_ops, - &priv->lock, priv->context, seqno); + &fence->lock, priv->context, seqno); ret = iio_dma_resv_lock(dmabuf, nonblock); if (ret) From 8662e56c31cf23b61ca3d11b516efb94c35b8026 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 15 Jul 2026 08:42:45 -0700 Subject: [PATCH 11/31] iio: buffer: Make IIO DMA fence release RCU-safe The `dma_fence` documentation states that if a custom release implementation is provided, the `dma_fence` object must be freed in an RCU-safe way. The current `iio_dma_fence` implementation uses `kfree()`, which might result in a use-after-free. Remove the custom `release` implementation. This makes the DMA fence core fall back to `dma_fence_free()`, which calls `kfree_rcu()` on the fence. This requires that the fence be the first member of `struct iio_dma_fence`. Using the default release method for extended DMA fence structures is a common pattern. Reported-by: codex:gpt-5.6 Fixes: 3e26d9f08fbe ("iio: core: Add new DMABUF interface infrastructure") Signed-off-by: Lars-Peter Clausen Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 31c06bffdce8..2c9ec93dff47 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -54,6 +54,10 @@ struct iio_dmabuf_priv { }; struct iio_dma_fence { + /* + * Must remain the first member so the default release callback can pass + * the fence directly to dma_fence_free(). + */ struct dma_fence base; spinlock_t lock; /* protects base */ struct iio_dmabuf_priv *priv; @@ -1828,18 +1832,9 @@ iio_buffer_dma_fence_get_driver_name(struct dma_fence *fence) return "iio"; } -static void iio_buffer_dma_fence_release(struct dma_fence *fence) -{ - struct iio_dma_fence *iio_fence = - container_of(fence, struct iio_dma_fence, base); - - kfree(iio_fence); -} - static const struct dma_fence_ops iio_buffer_dma_fence_ops = { .get_driver_name = iio_buffer_dma_fence_get_driver_name, .get_timeline_name = iio_buffer_dma_fence_get_driver_name, - .release = iio_buffer_dma_fence_release, }; static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib, From 26e9213898fc949923188ef0aeea31fc87708836 Mon Sep 17 00:00:00 2001 From: Rupesh Majhi Date: Sun, 19 Jul 2026 03:07:52 +0300 Subject: [PATCH 12/31] iio: pressure: dps310: fix NULL pointer dereference on ACPI probe When the device is enumerated through its ACPI HID (IFX3100), i2c_client_get_device_id() returns NULL: the ACPI-derived client name does not match the driver's i2c_device_id table. dps310_probe() then dereferences that NULL pointer in "iio->name = id->name" and crashes the kernel during probe. The IIO device name is always "dps310", so set it directly and drop the now-unused device-id lookup. Fixes: 72ff282819d0 ("iio: pressure: dps310: Add ACPI HID table") Cc: stable@vger.kernel.org Signed-off-by: Rupesh Majhi Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/dps310.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c index f45af72a0554..45bdb8c7670f 100644 --- a/drivers/iio/pressure/dps310.c +++ b/drivers/iio/pressure/dps310.c @@ -845,7 +845,6 @@ static const struct iio_info dps310_info = { static int dps310_probe(struct i2c_client *client) { - const struct i2c_device_id *id = i2c_client_get_device_id(client); struct dps310_data *data; struct iio_dev *iio; int rc; @@ -858,7 +857,7 @@ static int dps310_probe(struct i2c_client *client) data->client = client; mutex_init(&data->lock); - iio->name = id->name; + iio->name = DPS310_DEV_NAME; iio->channels = dps310_channels; iio->num_channels = ARRAY_SIZE(dps310_channels); iio->info = &dps310_info; From c132aef0e757a39036b1d40faf0569f2e343b13e Mon Sep 17 00:00:00 2001 From: Vidhu Sarwal Date: Mon, 13 Jul 2026 07:58:29 +0530 Subject: [PATCH 13/31] iio: light: ltrf216a: fix runtime PM reference leak in error path ltrf216a_get_lux() acquires a runtime PM reference by calling ltrf216a_set_power_state(data, true). However, if ltrf216a_read_data() fails, the function returns immediately without dropping the reference. This leaves the runtime PM usage count unbalanced, preventing the device from autosuspending after a failed read. Fix this by releasing the runtime PM reference before returning from the error path. Fixes: 83f0bcd40d5c ("iio: light: Add support for ltrf216a sensor") Signed-off-by: Vidhu Sarwal Reviewed-by: Joshua Crofts Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/light/ltrf216a.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iio/light/ltrf216a.c b/drivers/iio/light/ltrf216a.c index aad96fc91565..dd8f3260b1d8 100644 --- a/drivers/iio/light/ltrf216a.c +++ b/drivers/iio/light/ltrf216a.c @@ -248,11 +248,10 @@ static int ltrf216a_get_lux(struct ltrf216a_data *data) return ret; greendata = ltrf216a_read_data(data, LTRF216A_ALS_DATA_0); + ltrf216a_set_power_state(data, false); if (greendata < 0) return greendata; - ltrf216a_set_power_state(data, false); - lux = greendata * data->info->lux_multiplier * LTRF216A_WIN_FAC; return lux; From b7e6e9af0d723afdec92364d5e7e064eeef44c8e Mon Sep 17 00:00:00 2001 From: Vidhu Sarwal Date: Wed, 15 Jul 2026 06:45:42 +0530 Subject: [PATCH 14/31] iio: light: opt4060: Reject integration times with a non-zero seconds part When setting the integration time, opt4060_write_raw() only uses val2 and ignores val. As a result, a write such as 1.000600 is accepted and programmed as 600 us, silently discarding the whole seconds part. Since all supported integration times are less than one second, any non-zero val represents an invalid input. Reject such values instead of silently accepting them. Fixes: 0c6db4506ad0 ("iio: light: Add support for TI OPT4060 color sensor") Signed-off-by: Vidhu Sarwal Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/light/opt4060.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/iio/light/opt4060.c b/drivers/iio/light/opt4060.c index c391ad3271c6..cf6f69e5be35 100644 --- a/drivers/iio/light/opt4060.c +++ b/drivers/iio/light/opt4060.c @@ -632,6 +632,9 @@ static int opt4060_write_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_INT_TIME: + if (val) + return -EINVAL; + int_time = opt4060_als_time_to_index(val2); if (int_time < 0) return int_time; From 0ba0ed0d42ebd3144f0050c48374817f5f3f07d6 Mon Sep 17 00:00:00 2001 From: Vidhu Sarwal Date: Wed, 15 Jul 2026 06:45:43 +0530 Subject: [PATCH 15/31] iio: light: opt4060: Fix pointer type passed to div_u64_rem() div_u64_rem() expects a u32 * for the remainder, but opt4060_read_ev_period() passes val2, which is declared as an int *. While this has no functional impact, it triggers a pointer type mismatch. There is no behavioural change because int and u32 have the same size and representation on all supported architectures, and the remainder is always less than MICRO, so it fits within the positive range of int. Use a local u32 to receive the remainder before assigning it to *val2. Fixes: 0c6db4506ad0 ("iio: light: Add support for TI OPT4060 color sensor") Signed-off-by: Vidhu Sarwal Signed-off-by: Jonathan Cameron --- drivers/iio/light/opt4060.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/light/opt4060.c b/drivers/iio/light/opt4060.c index cf6f69e5be35..e3aabfb14d5d 100644 --- a/drivers/iio/light/opt4060.c +++ b/drivers/iio/light/opt4060.c @@ -713,6 +713,7 @@ static ssize_t opt4060_read_ev_period(struct opt4060_chip *chip, int *val, { int ret, pers, fault_count, int_time; u64 uval; + u32 rem; int_time = opt4060_int_time_reg[chip->int_time][0]; @@ -738,7 +739,8 @@ static ssize_t opt4060_read_ev_period(struct opt4060_chip *chip, int *val, } uval = mul_u32_u32(int_time, pers); - *val = div_u64_rem(uval, MICRO, val2); + *val = div_u64_rem(uval, MICRO, &rem); + *val2 = rem; return IIO_VAL_INT_PLUS_MICRO; } From ad367638212a9f2495ecfa59c886f0cfb7934e9c Mon Sep 17 00:00:00 2001 From: Vidhu Sarwal Date: Wed, 15 Jul 2026 06:45:44 +0530 Subject: [PATCH 16/31] iio: light: opt4060: Fix incorrect register name in threshold read error message opt4060_get_thresholds() correctly reads OPT4060_THRESHOLD_HIGH, but logs "Failed to read THRESHOLD_LOW." if the read fails. This is a copy-and-paste mistake, as the preceding low-threshold read already uses the correct error message. Update the error message to reference OPT4060_THRESHOLD_HIGH. Fixes: 0c6db4506ad0 ("iio: light: Add support for TI OPT4060 color sensor") Signed-off-by: Vidhu Sarwal Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/light/opt4060.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/light/opt4060.c b/drivers/iio/light/opt4060.c index e3aabfb14d5d..f79dd342937d 100644 --- a/drivers/iio/light/opt4060.c +++ b/drivers/iio/light/opt4060.c @@ -810,7 +810,7 @@ static int opt4060_get_thresholds(struct opt4060_chip *chip, u32 *th_lo, u32 *th ret = regmap_read(chip->regmap, OPT4060_THRESHOLD_HIGH, ®val); if (ret) { - dev_err(chip->dev, "Failed to read THRESHOLD_LOW.\n"); + dev_err(chip->dev, "Failed to read THRESHOLD_HIGH.\n"); return ret; } *th_hi = opt4060_calc_val_from_th_reg(regval); From 3b2cd82c524c75a2173f2e3f874652a75f81cd1d Mon Sep 17 00:00:00 2001 From: Nikhil Gautam Date: Tue, 14 Jul 2026 17:01:31 +0530 Subject: [PATCH 17/31] iio: light: opt4001: Fix power down clearing bits of the wrong register opt4001_power_down() intends to clear the operating mode bits in the CTRL register but reads OPT4001_DEVICE_ID instead of OPT4001_CTRL, so the value written back to CTRL contains device ID bits rather than the current configuration. Fix and simplify this by using regmap_clear_bits() on the CTRL register directly in the devm action, and drop opt4001_power_down() which has no other users. Suggested-by: Jonathan Cameron Fixes: 9a9608418292 ("iio: light: Add support for TI OPT4001 light sensor") Signed-off-by: Nikhil Gautam Reviewed-by: Andy Shevchenko Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/light/opt4001.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/drivers/iio/light/opt4001.c b/drivers/iio/light/opt4001.c index dd152d921b48..288e699734af 100644 --- a/drivers/iio/light/opt4001.c +++ b/drivers/iio/light/opt4001.c @@ -222,33 +222,14 @@ static int opt4001_set_conf(struct opt4001_chip *chip) return ret; } -static int opt4001_power_down(struct opt4001_chip *chip) -{ - struct device *dev = &chip->client->dev; - int ret; - unsigned int reg; - - ret = regmap_read(chip->regmap, OPT4001_DEVICE_ID, ®); - if (ret) { - dev_err(dev, "Failed to read configuration\n"); - return ret; - } - - /* MODE_OFF is 0x0 so just set bits to 0 */ - reg &= ~OPT4001_CTRL_OPER_MODE_MASK; - - ret = regmap_write(chip->regmap, OPT4001_CTRL, reg); - if (ret) - dev_err(dev, "Failed to set configuration to power down\n"); - - return ret; -} - static void opt4001_chip_off_action(void *data) { struct opt4001_chip *chip = data; + int ret; - opt4001_power_down(chip); + ret = regmap_clear_bits(chip->regmap, OPT4001_CTRL, OPT4001_CTRL_OPER_MODE_MASK); + if (ret) + dev_err(&chip->client->dev, "Failed to power down\n"); } static const struct iio_chan_spec opt4001_channels[] = { From afa28741c9a2cf6edb2e41e25ff146a562160bb3 Mon Sep 17 00:00:00 2001 From: Nikhil Gautam Date: Tue, 14 Jul 2026 17:01:32 +0530 Subject: [PATCH 18/31] iio: light: opt4001: Fix incompatible pointer type passed to div_u64_rem() div_u64_rem() takes a u32 * for the remainder but is passed val2, which is an int *. There is no functional impact as int and u32 have the same size and representation on all supported architectures and the remainder is always smaller than the divisor, so it fits in the positive range of int. Fix the type mismatch by using a local u32 for the remainder and assigning the result to *val2. Fixes: 9a9608418292 ("iio: light: Add support for TI OPT4001 light sensor") Signed-off-by: Nikhil Gautam Reviewed-by: Andy Shevchenko Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/light/opt4001.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/iio/light/opt4001.c b/drivers/iio/light/opt4001.c index 288e699734af..944923cb8f28 100644 --- a/drivers/iio/light/opt4001.c +++ b/drivers/iio/light/opt4001.c @@ -173,6 +173,7 @@ static int opt4001_read_lux_value(struct iio_dev *indio_dev, u8 crc; u8 calc_crc; u64 lux_raw; + u32 rem; int ret; ret = regmap_read(chip->regmap, OPT4001_LIGHT1_MSB, &light1); @@ -199,8 +200,8 @@ static int opt4001_read_lux_value(struct iio_dev *indio_dev, lux_raw = lux_raw << exp; lux_raw = lux_raw * chip->chip_info->mul; - *val = div_u64_rem(lux_raw, chip->chip_info->div, val2); - *val2 = *val2 * 100; + *val = div_u64_rem(lux_raw, chip->chip_info->div, &rem); + *val2 = rem * 100; return IIO_VAL_INT_PLUS_NANO; } From d0f21621f8b2b46661ea066d20705dbf7253db87 Mon Sep 17 00:00:00 2001 From: Nikhil Gautam Date: Tue, 14 Jul 2026 17:01:33 +0530 Subject: [PATCH 19/31] iio: light: opt4001: Reject integration times with a non-zero seconds part opt4001_write_raw() only looks at val2 when setting the integration time, so a write such as 1.000600 is silently accepted as 600 us. Return -EINVAL if val is non-zero. Fixes: 9a9608418292 ("iio: light: Add support for TI OPT4001 light sensor") Signed-off-by: Nikhil Gautam Reviewed-by: Andy Shevchenko Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/light/opt4001.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/iio/light/opt4001.c b/drivers/iio/light/opt4001.c index 944923cb8f28..2448d6330489 100644 --- a/drivers/iio/light/opt4001.c +++ b/drivers/iio/light/opt4001.c @@ -269,6 +269,9 @@ static int opt4001_write_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_INT_TIME: + if (val) + return -EINVAL; + int_time = opt4001_als_time_to_index(val2); if (int_time < 0) return int_time; From d64bfd9f3352b9d9bdeca06de1a0a1c1bd47b896 Mon Sep 17 00:00:00 2001 From: Nikhil Gautam Date: Tue, 14 Jul 2026 17:01:34 +0530 Subject: [PATCH 20/31] iio: light: opt4001: Fix reversed GENMASK() arguments in fault count mask GENMASK(h, l) requires h >= l, but OPT4001_CTRL_FAULT_COUNT is defined as GENMASK(0, 1). The define is currently unused so there is no functional impact, but fix it before anyone builds on it, and add the _MASK suffix for consistency with the neighbouring definitions. Fixes: 9a9608418292 ("iio: light: Add support for TI OPT4001 light sensor") Signed-off-by: Nikhil Gautam Reviewed-by: Andy Shevchenko Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/light/opt4001.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/light/opt4001.c b/drivers/iio/light/opt4001.c index 2448d6330489..aa3d87995b7c 100644 --- a/drivers/iio/light/opt4001.c +++ b/drivers/iio/light/opt4001.c @@ -39,7 +39,7 @@ #define OPT4001_CTRL_OPER_MODE_MASK GENMASK(5, 4) #define OPT4001_CTRL_LATCH_MASK GENMASK(3, 3) #define OPT4001_CTRL_INT_POL_MASK GENMASK(2, 2) -#define OPT4001_CTRL_FAULT_COUNT GENMASK(0, 1) +#define OPT4001_CTRL_FAULT_COUNT_MASK GENMASK(1, 0) /* OPT4001 constants */ #define OPT4001_DEVICE_ID_VAL 0x121 From a3c03cf36a083893dedad928915471dc8c10692e Mon Sep 17 00:00:00 2001 From: Can Peng Date: Tue, 14 Jul 2026 17:18:45 +0800 Subject: [PATCH 21/31] iio: dac: ad5446: fix OF module device table The ad5446 I2C driver exports its OF match table with MODULE_DEVICE_TABLE(OF, ...). The device table type is used by modpost when generating module aliases, and scripts/mod/file2alias.c matches the lowercase "of" type. Using "OF" prevents the OF table from being recognized, so no OF module alias is generated for the I2C driver. Use the lowercase "of" type so OF-based module autoloading works. Fixes: 876d94024087 ("iio: dac: ad5446: Separate I2C/SPI into different drivers") Signed-off-by: Can Peng Reviewed-by: Joshua Crofts Reviewed-by: Andy Shevchenko Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5446-i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/dac/ad5446-i2c.c b/drivers/iio/dac/ad5446-i2c.c index 2d4c8908d91e..cb3100fa32d9 100644 --- a/drivers/iio/dac/ad5446-i2c.c +++ b/drivers/iio/dac/ad5446-i2c.c @@ -84,7 +84,7 @@ static const struct of_device_id ad5446_i2c_of_ids[] = { { .compatible = "adi,ad5622", .data = &ad5622_chip_info }, { } }; -MODULE_DEVICE_TABLE(OF, ad5446_i2c_of_ids); +MODULE_DEVICE_TABLE(of, ad5446_i2c_of_ids); static struct i2c_driver ad5446_i2c_driver = { .driver = { From bcd3f72e26314edfce7eaf8d7160b3119c7b7fed Mon Sep 17 00:00:00 2001 From: Moksh Panicker Date: Mon, 13 Jul 2026 03:00:46 +0000 Subject: [PATCH 22/31] iio: chemical: atlas-sensor: fix PM reference leak in buffer postenable atlas_buffer_postenable() acquires a runtime PM reference with pm_runtime_resume_and_get() but returns the result of atlas_set_interrupt() directly. If atlas_set_interrupt() fails, the runtime PM reference is leaked and the device can never autosuspend. Add pm_runtime_put_autosuspend() on the error path to balance the reference. Fixes: 0e4f336f50de ("iio: chemical: atlas-sensor: Balance runtime pm + pm_runtime_resume_and_get()") Cc: stable@vger.kernel.org Signed-off-by: Moksh Panicker Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/atlas-sensor.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c index 0e2edcff63f9..b2c1a598b3a5 100644 --- a/drivers/iio/chemical/atlas-sensor.c +++ b/drivers/iio/chemical/atlas-sensor.c @@ -413,7 +413,11 @@ static int atlas_buffer_postenable(struct iio_dev *indio_dev) if (ret) return ret; - return atlas_set_interrupt(data, true); + ret = atlas_set_interrupt(data, true); + if (ret) + pm_runtime_put_autosuspend(&data->client->dev); + + return ret; } static int atlas_buffer_predisable(struct iio_dev *indio_dev) From 60f6f7fd5f89c7f55991c5dc59f3ccc74cd6efd7 Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Mon, 13 Jul 2026 11:40:42 +0300 Subject: [PATCH 23/31] iio: adc: adi-axi-adc: add data size support for AD408X backend The AD408X AXI core can pack the sample data on the bus using different word widths. Expose this through the data_size_set backend operation so that frontends can program the packet format field (bits 3:2 of the CNTRL_3 register) according to the ADC resolution: 20-bit, 16-bit and 14-bit map to packet format values 0, 1 and 2 respectively. Signed-off-by: Antoniu Miclaus Reviewed-by: David Lechner Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/adi-axi-adc.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index ced0a2321ecf..aac6f4a0705e 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -54,6 +54,10 @@ #define AXI_AD485X_PACKET_FORMAT_24BIT 0x1 #define AXI_AD485X_PACKET_FORMAT_32BIT 0x2 #define AXI_AD408X_CNTRL_3_FILTER_EN_MSK BIT(0) +#define AXI_AD408X_CNTRL_3_PACKET_FORMAT_MSK GENMASK(3, 2) +#define AXI_AD408X_PACKET_FORMAT_20BIT 0x0 +#define AXI_AD408X_PACKET_FORMAT_16BIT 0x1 +#define AXI_AD408X_PACKET_FORMAT_14BIT 0x2 #define ADI_AXI_ADC_REG_SYNC_STATUS 0x0068 #define ADI_AXI_ADC_SYNC_STATUS_ADC_SYNC_MSK BIT(0) @@ -437,6 +441,31 @@ static int axi_adc_ad408x_filter_type_set(struct iio_backend *back, AXI_AD408X_CNTRL_3_FILTER_EN_MSK); } +static int axi_adc_ad408x_data_size_set(struct iio_backend *back, + unsigned int size) +{ + struct adi_axi_adc_state *st = iio_backend_get_priv(back); + unsigned int val; + + switch (size) { + case 20: + val = AXI_AD408X_PACKET_FORMAT_20BIT; + break; + case 16: + val = AXI_AD408X_PACKET_FORMAT_16BIT; + break; + case 14: + val = AXI_AD408X_PACKET_FORMAT_14BIT; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(st->regmap, ADI_AXI_ADC_REG_CNTRL_3, + AXI_AD408X_CNTRL_3_PACKET_FORMAT_MSK, + FIELD_PREP(AXI_AD408X_CNTRL_3_PACKET_FORMAT_MSK, val)); +} + static int axi_adc_ad408x_interface_data_align(struct iio_backend *back, u32 timeout_us) { @@ -660,6 +689,7 @@ static const struct iio_backend_ops adi_ad408x_ops = { .free_buffer = axi_adc_free_buffer, .data_sample_trigger = axi_adc_data_sample_trigger, .filter_type_set = axi_adc_ad408x_filter_type_set, + .data_size_set = axi_adc_ad408x_data_size_set, .interface_data_align = axi_adc_ad408x_interface_data_align, .num_lanes_set = axi_adc_num_lanes_set, .debugfs_reg_access = iio_backend_debugfs_ptr(axi_adc_reg_access), From d39afd249d1ef5cb03b6f1dc22a68e6385de413d Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Mon, 13 Jul 2026 11:40:43 +0300 Subject: [PATCH 24/31] iio: adc: ad4080: configure backend data size The AXI backend needs to know the ADC word width in order to pack the sample data correctly on the bus. During channel setup, program the backend packet format via iio_backend_data_size_set() using the channel resolution, so the data is transferred according to the device's realbits. The backend packet format field defaults to 20-bit packing, so the 20-bit parts (AD4080/AD4081/AD4082, AD4880) were unaffected. The 16-bit (AD4083/AD4084/AD4085, AD4884) and 14-bit (AD4086/AD4087/AD4088) parts, however, were left packing data at the wrong width, producing corrupt buffered captures. Fixes: 6c3e7265734b ("iio: adc: ad4080: add support for AD4084") Signed-off-by: Antoniu Miclaus Reviewed-by: David Lechner Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad4080.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/iio/adc/ad4080.c b/drivers/iio/adc/ad4080.c index 8d2953341b15..8feb0c7f7fcb 100644 --- a/drivers/iio/adc/ad4080.c +++ b/drivers/iio/adc/ad4080.c @@ -698,6 +698,11 @@ static int ad4080_setup_channel(struct ad4080_state *st, unsigned int ch) if (ret) return ret; + ret = iio_backend_data_size_set(st->back[ch], + st->info->channels[0].scan_type.realbits); + if (ret) + return ret; + if (!st->lvds_cnv_en) return 0; From a40b2e7a17f26e38ab054363c9c7cde149588357 Mon Sep 17 00:00:00 2001 From: Cong Nguyen Date: Mon, 27 Jul 2026 22:51:15 +0700 Subject: [PATCH 25/31] iio: srf04: fix pm_runtime handling on probe error path When pm_runtime_set_active() fails during probe, the driver logs the error and unregisters the IIO device, but then falls through and still calls pm_runtime_enable() before returning the error. Since probe returns an error, srf04_remove() is never called, so runtime PM is left enabled without a matching pm_runtime_disable(). This leaks the enable and triggers an "Unbalanced pm_runtime_enable!" warning on a subsequent bind of the device. Return the error right after unregistering the IIO device so that runtime PM is not enabled on the failure path. Fixes: 2251157b335b ("iio: srf04: add power management feature") Cc: stable@vger.kernel.org Signed-off-by: Cong Nguyen Signed-off-by: Jonathan Cameron --- drivers/iio/proximity/srf04.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/proximity/srf04.c b/drivers/iio/proximity/srf04.c index e97f9a20ac7a..337938657449 100644 --- a/drivers/iio/proximity/srf04.c +++ b/drivers/iio/proximity/srf04.c @@ -331,6 +331,7 @@ static int srf04_probe(struct platform_device *pdev) if (ret) { dev_err(data->dev, "pm_runtime_set_active: %d\n", ret); iio_device_unregister(indio_dev); + return ret; } pm_runtime_enable(data->dev); From 06fab97602fe400bea843176f485bbac07a668e2 Mon Sep 17 00:00:00 2001 From: Cong Nguyen Date: Sun, 2 Aug 2026 13:55:40 +0700 Subject: [PATCH 26/31] iio: gyro: mpu3050: fix sign of raw angular velocity readings The MPU-3050 gyroscope output registers hold 16-bit two's complement values; the angular velocity channels are declared with .sign = 's'. When mpu3050_read_raw() handles IIO_CHAN_INFO_RAW it reads the register via a big-endian regmap_bulk_read() and assigns it with: *val = be16_to_cpu(raw_val); be16_to_cpu() yields an unsigned 16-bit quantity, so negative rates (bit 15 set) are reported to userspace as large positive integers (e.g. -1 becomes 65535) instead of the correct negative value. Cast to s16 before the assignment, matching the temperature channel a few lines above which already handles the sign correctly. Fixes: 3904b28efb2c ("iio: gyro: Add driver for the MPU-3050 gyroscope") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4 Signed-off-by: Cong Nguyen Reviewed-by: Linus Walleij Reviewed-by: Joshua Crofts Reviewed-by: David Lechner Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/mpu3050-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c index d84e04e4b431..07c0f9011c63 100644 --- a/drivers/iio/gyro/mpu3050-core.c +++ b/drivers/iio/gyro/mpu3050-core.c @@ -356,7 +356,7 @@ static int mpu3050_read_raw(struct iio_dev *indio_dev, goto out_read_raw_unlock; } - *val = be16_to_cpu(raw_val); + *val = (s16)be16_to_cpu(raw_val); ret = IIO_VAL_INT; goto out_read_raw_unlock; From d378fceaafd79e0dc59d3546bda251a3058062c0 Mon Sep 17 00:00:00 2001 From: Moksh Panicker Date: Sun, 2 Aug 2026 19:07:01 +0000 Subject: [PATCH 27/31] iio: light: apds9306: fix PM reference leak in apds9306_read_data() apds9306_read_data() calls pm_runtime_resume_and_get() but several error paths return directly without calling pm_runtime_put_autosuspend(), leaking the runtime PM reference and preventing the device from autosuspending. Use PM_RUNTIME_ACQUIRE_AUTOSUSPEND() and PM_RUNTIME_ACQUIRE_ERR() to automatically handle runtime PM reference release on all return paths. Fixes: 620d1e6c7a3f ("iio: light: Add support for APDS9306 Light Sensor") Signed-off-by: Moksh Panicker Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/apds9306.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/iio/light/apds9306.c b/drivers/iio/light/apds9306.c index 5ca4c87524fe..d582bda4d847 100644 --- a/drivers/iio/light/apds9306.c +++ b/drivers/iio/light/apds9306.c @@ -469,9 +469,9 @@ static int apds9306_read_data(struct apds9306_data *data, int *val, int reg) int status = 0; u8 buff[3]; - ret = pm_runtime_resume_and_get(data->dev); - if (ret) - return ret; + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(data->dev, pm); + if (PM_RUNTIME_ACQUIRE_ERR(&pm)) + return PM_RUNTIME_ACQUIRE_ERR(&pm); ret = regmap_field_read(rf->intg_time, &intg_time_idx); if (ret) @@ -535,8 +535,6 @@ static int apds9306_read_data(struct apds9306_data *data, int *val, int reg) *val = get_unaligned_le24(&buff); - pm_runtime_put_autosuspend(data->dev); - return 0; } From 579c049b4cb6fc72ce2c505fc5334540be0efcd3 Mon Sep 17 00:00:00 2001 From: Nikhil Gautam Date: Wed, 22 Jul 2026 21:52:45 +0530 Subject: [PATCH 28/31] iio: light: gp2ap002: Fix unbalanced runtime PM on repeated event writes The IIO core does not filter duplicate writes to the event enable attribute, so writing the same value twice invokes write_event_config() twice. Enabling twice leaks a runtime PM reference, preventing the device from ever suspending again; disabling twice underflows the usage count and triggers a "Runtime PM usage count underflow" warning. Bail out early when the requested state matches the current state. While at it, switch to pm_runtime_resume_and_get() so a failed resume is propagated to userspace instead of silently marking the event enabled. Fixes: 97d642e23037c ("iio: light: Add a driver for Sharp GP2AP002x00F") Signed-off-by: Nikhil Gautam Signed-off-by: Jonathan Cameron --- drivers/iio/light/gp2ap002.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c index 05773e24931b..708a77006529 100644 --- a/drivers/iio/light/gp2ap002.c +++ b/drivers/iio/light/gp2ap002.c @@ -342,6 +342,10 @@ static int gp2ap002_write_event_config(struct iio_dev *indio_dev, bool state) { struct gp2ap002 *gp2ap002 = iio_priv(indio_dev); + int ret; + + if (state == gp2ap002->enabled) + return 0; if (state) { /* @@ -349,13 +353,16 @@ static int gp2ap002_write_event_config(struct iio_dev *indio_dev, * already) and reintialize the sensor by using runtime_pm * callbacks. */ - pm_runtime_get_sync(gp2ap002->dev); - gp2ap002->enabled = true; + ret = pm_runtime_resume_and_get(gp2ap002->dev); + if (ret) + return ret; + } else { pm_runtime_put_autosuspend(gp2ap002->dev); - gp2ap002->enabled = false; } + gp2ap002->enabled = state; + return 0; } From 5d89e7cbac40057f5241a0832a86ce0fe97e4818 Mon Sep 17 00:00:00 2001 From: Nikhil Gautam Date: Wed, 22 Jul 2026 21:52:46 +0530 Subject: [PATCH 29/31] iio: light: gp2ap002: re-enable irq if runtime suspend fails gp2ap002_runtime_suspend() disables the irq before writing OPMOD. If the write fails, the callback returns an error with the irq still disabled while the PM core marks the device active again. re-enable the irq before returning the error so the irq state matches the active state the PM core restores. Fixes: 97d642e23037c ("iio: light: Add a driver for Sharp GP2AP002x00F") Signed-off-by: Nikhil Gautam Signed-off-by: Jonathan Cameron --- drivers/iio/light/gp2ap002.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c index 708a77006529..de29081fd3b2 100644 --- a/drivers/iio/light/gp2ap002.c +++ b/drivers/iio/light/gp2ap002.c @@ -649,6 +649,7 @@ static int gp2ap002_runtime_suspend(struct device *dev) /* Disable chip and IRQ, everything off */ ret = regmap_write(gp2ap002->map, GP2AP002_OPMOD, 0x00); if (ret) { + enable_irq(gp2ap002->irq); dev_err(gp2ap002->dev, "error setting up operation mode\n"); return ret; } From 3364c56b20c1c496bdb8c8df32f96a9947dbf98e Mon Sep 17 00:00:00 2001 From: Cong Nguyen Date: Sun, 2 Aug 2026 14:12:46 +0700 Subject: [PATCH 30/31] iio: adc: pac1921: fix wrong channel used in trigger handler read pac1921_trigger_handler() walks the enabled channels with iio_for_each_active_channel(), which yields the scan index (bit) of each active channel, while ch is a separate counter used to pack the samples contiguously into the scan buffer. The register to read was looked up with the packing counter instead of the scan index: ret = pac1921_read_res(priv, idev->channels[ch].address, &val); pac1921_channels[] is ordered by scan index, so channels[bit] is the channel that is actually enabled, whereas channels[ch] is merely the ch-th array entry. These coincide only when the enabled channels form a contiguous prefix (e.g. all channels enabled). With a sparse scan mask - for example when only the power channel (scan index 3) is enabled - the handler reads the wrong register (VBUS instead of VPOWER) and pushes it to userspace as the enabled channel's data. Index the channel array by the scan index (bit) to read the correct register, keeping ch only for contiguous packing into the scan buffer. Fixes: 371f778b83cd ("iio: adc: add support for pac1921") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4 Signed-off-by: Cong Nguyen Acked-by: Matteo Martelli Reviewed-by: David Lechner Signed-off-by: Jonathan Cameron --- drivers/iio/adc/pac1921.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/pac1921.c b/drivers/iio/adc/pac1921.c index 68bdd2f30bad..f0bab94462f4 100644 --- a/drivers/iio/adc/pac1921.c +++ b/drivers/iio/adc/pac1921.c @@ -1037,7 +1037,7 @@ static irqreturn_t pac1921_trigger_handler(int irq, void *p) iio_for_each_active_channel(idev, bit) { u16 val; - ret = pac1921_read_res(priv, idev->channels[ch].address, &val); + ret = pac1921_read_res(priv, idev->channels[bit].address, &val); if (ret) goto done; From be61c8c6252671ecf1fee0ad90f87669e0be1e20 Mon Sep 17 00:00:00 2001 From: Fan Wu Date: Sun, 2 Aug 2026 07:18:58 +0000 Subject: [PATCH 31/31] iio: chemical: atlas-sensor: use iio_trigger_poll_nested() to fix remove UAF The atlas driver requests its hardware data-ready IRQ with devm_request_threaded_irq(); its threaded handler queues an irq_work, atlas_work_handler(), that calls iio_trigger_poll(data->trig). The IRQ is devm-managed, so free_irq() runs from the devres unwind after atlas_remove() returns without flushing that irq_work. Once a buffer is enabled, conversion-complete IRQs keep firing and queueing it; a pending irq_work can therefore run after the unwind has freed atlas_data/indio_dev and the trigger, when atlas_work_handler() derives the atlas_data pointer via container_of() and dereferences data->trig, a use-after-free. Call iio_trigger_poll_nested() directly from the threaded handler instead of bouncing through irq_work. free_irq() then drains the threaded handler, closing the window; other iio drivers with a threaded data-ready IRQ do the same (e.g. bmi270). This issue was found by an in-house static analysis tool. Fixes: 7103b99b031c ("iio: chemical: atlas-ph-sensor: reorg driver to allow multiple chips") Cc: stable@vger.kernel.org # v6.4+ Assisted-by: Codex:gpt-5.6 Signed-off-by: Fan Wu Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/atlas-sensor.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c index b2c1a598b3a5..aa625f39b85e 100644 --- a/drivers/iio/chemical/atlas-sensor.c +++ b/drivers/iio/chemical/atlas-sensor.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -88,7 +87,6 @@ struct atlas_data { struct iio_trigger *trig; const struct atlas_device *chip; struct regmap *regmap; - struct irq_work work; unsigned int interrupt_enabled; /* 96-bit data + 32-bit pad + 64-bit timestamp */ __be32 buffer[6] __aligned(8); @@ -441,13 +439,6 @@ static const struct iio_buffer_setup_ops atlas_buffer_setup_ops = { .predisable = atlas_buffer_predisable, }; -static void atlas_work_handler(struct irq_work *work) -{ - struct atlas_data *data = container_of(work, struct atlas_data, work); - - iio_trigger_poll(data->trig); -} - static irqreturn_t atlas_trigger_handler(int irq, void *private) { struct iio_poll_func *pf = private; @@ -474,7 +465,7 @@ static irqreturn_t atlas_interrupt_handler(int irq, void *private) struct iio_dev *indio_dev = private; struct atlas_data *data = iio_priv(indio_dev); - irq_work_queue(&data->work); + iio_trigger_poll_nested(data->trig); return IRQ_HANDLED; } @@ -670,8 +661,6 @@ static int atlas_probe(struct i2c_client *client) goto unregister_trigger; } - init_irq_work(&data->work, atlas_work_handler); - if (client->irq > 0) { /* interrupt pin toggles on new conversion */ ret = devm_request_threaded_irq(&client->dev, client->irq,