From 852534744c2d35626a604f128ff0b8ec12805591 Mon Sep 17 00:00:00 2001 From: Christofer Jonason Date: Wed, 4 Mar 2026 10:07:27 +0100 Subject: [PATCH 01/41] iio: adc: xilinx-xadc: Fix sequencer mode in postdisable for dual mux MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xadc_postdisable() unconditionally sets the sequencer to continuous mode. For dual external multiplexer configurations this is incorrect: simultaneous sampling mode is required so that ADC-A samples through the mux on VAUX[0-7] while ADC-B simultaneously samples through the mux on VAUX[8-15]. In continuous mode only ADC-A is active, so VAUX[8-15] channels return incorrect data. Since postdisable is also called from xadc_probe() to set the initial idle state, the wrong sequencer mode is active from the moment the driver loads. The preenable path already uses xadc_get_seq_mode() which returns SIMULTANEOUS for dual mux. Fix postdisable to do the same. Fixes: bdc8cda1d010 ("iio:adc: Add Xilinx XADC driver") Cc: stable@vger.kernel.org Signed-off-by: Christofer Jonason Reviewed-by: Andy Shevchenko Reviewed-by: Nuno Sá Reviewed-by: Salih Erim Signed-off-by: Jonathan Cameron --- drivers/iio/adc/xilinx-xadc-core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index e257c1b94a5f..3980dfacbcd7 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -817,6 +817,7 @@ static int xadc_postdisable(struct iio_dev *indio_dev) { struct xadc *xadc = iio_priv(indio_dev); unsigned long scan_mask; + int seq_mode; int ret; int i; @@ -824,6 +825,12 @@ static int xadc_postdisable(struct iio_dev *indio_dev) for (i = 0; i < indio_dev->num_channels; i++) scan_mask |= BIT(indio_dev->channels[i].scan_index); + /* + * Use the correct sequencer mode for the idle state: simultaneous + * mode for dual external mux configurations, continuous otherwise. + */ + seq_mode = xadc_get_seq_mode(xadc, scan_mask); + /* Enable all channels and calibration */ ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(0), scan_mask & 0xffff); if (ret) @@ -834,11 +841,11 @@ static int xadc_postdisable(struct iio_dev *indio_dev) return ret; ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_SEQ_MASK, - XADC_CONF1_SEQ_CONTINUOUS); + seq_mode); if (ret) return ret; - return xadc_power_adc_b(xadc, XADC_CONF1_SEQ_CONTINUOUS); + return xadc_power_adc_b(xadc, seq_mode); } static int xadc_preenable(struct iio_dev *indio_dev) From 673478bc29cf72010faaf293c1c8c667393335a0 Mon Sep 17 00:00:00 2001 From: Pengpeng Hou Date: Thu, 2 Apr 2026 13:40:15 +0800 Subject: [PATCH 02/41] iio: chemical: mhz19b: reject oversized serial replies mhz19b_receive_buf() appends each serdev chunk into the fixed MHZ19B_CMD_SIZE receive buffer and advances buf_idx by len without checking that the chunk fits in the remaining space. A large callback can therefore overflow st->buf before the command path validates the reply. Reset the reply state before each command and reject oversized serial replies before copying them into the fixed buffer. When an oversized reply is detected, wake the waiter and report -EMSGSIZE instead of overwriting st->buf. Fixes: 4572a70b3681 ("iio: chemical: Add support for Winsen MHZ19B CO2 sensor") Cc: stable@vger.kernel.org Signed-off-by: Pengpeng Hou Acked-by: Gyeyoung Baek Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/mhz19b.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/iio/chemical/mhz19b.c b/drivers/iio/chemical/mhz19b.c index 3c64154918b1..9d4cf432919e 100644 --- a/drivers/iio/chemical/mhz19b.c +++ b/drivers/iio/chemical/mhz19b.c @@ -52,6 +52,8 @@ struct mhz19b_state { struct completion buf_ready; u8 buf_idx; + bool buf_overflow; + /* * Serdev receive buffer. * When data is received from the MH-Z19B, @@ -106,6 +108,10 @@ static int mhz19b_serdev_cmd(struct iio_dev *indio_dev, int cmd, u16 arg) cmd_buf[8] = mhz19b_get_checksum(cmd_buf); /* Write buf to uart ctrl synchronously */ + st->buf_idx = 0; + st->buf_overflow = false; + reinit_completion(&st->buf_ready); + ret = serdev_device_write(serdev, cmd_buf, MHZ19B_CMD_SIZE, 0); if (ret < 0) return ret; @@ -121,6 +127,9 @@ static int mhz19b_serdev_cmd(struct iio_dev *indio_dev, int cmd, u16 arg) if (!ret) return -ETIMEDOUT; + if (st->buf_overflow) + return -EMSGSIZE; + if (st->buf[8] != mhz19b_get_checksum(st->buf)) { dev_err(dev, "checksum err"); return -EINVAL; @@ -240,6 +249,14 @@ static size_t mhz19b_receive_buf(struct serdev_device *serdev, { struct iio_dev *indio_dev = dev_get_drvdata(&serdev->dev); struct mhz19b_state *st = iio_priv(indio_dev); + size_t remaining = MHZ19B_CMD_SIZE - st->buf_idx; + + if (len > remaining) { + st->buf_idx = 0; + st->buf_overflow = true; + complete(&st->buf_ready); + return len; + } memcpy(st->buf + st->buf_idx, data, len); st->buf_idx += len; From b66f922f6a4fa92840f662fbcfeb4f8a0f774bcc Mon Sep 17 00:00:00 2001 From: Felix Gu Date: Fri, 27 Mar 2026 20:27:54 +0800 Subject: [PATCH 03/41] iio: light: veml6070: Fix resource leak in probe error path The driver calls i2c_new_dummy_device() to create a dummy device, then calls i2c_smbus_write_byte(). If i2c_smbus_write_byte() fails and returns, the cleanup via devm_add_action_or_reset() was never registered, so the dummy device leaks. Switch to devm_i2c_new_dummy_device() which registers cleanup atomically with device creation, eliminating the error-path window. Fixes: 7501bff87c3e ("iio: light: veml6070: add action for i2c_unregister_device") Reviewed-by: Andy Shevchenko Signed-off-by: Felix Gu Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/light/veml6070.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/iio/light/veml6070.c b/drivers/iio/light/veml6070.c index 74d7246e5225..4bbd86d0cb46 100644 --- a/drivers/iio/light/veml6070.c +++ b/drivers/iio/light/veml6070.c @@ -245,13 +245,6 @@ static const struct iio_info veml6070_info = { .write_raw = veml6070_write_raw, }; -static void veml6070_i2c_unreg(void *p) -{ - struct veml6070_data *data = p; - - i2c_unregister_device(data->client2); -} - static int veml6070_probe(struct i2c_client *client) { struct veml6070_data *data; @@ -281,7 +274,8 @@ static int veml6070_probe(struct i2c_client *client) if (ret < 0) return ret; - data->client2 = i2c_new_dummy_device(client->adapter, VEML6070_ADDR_DATA_LSB); + data->client2 = devm_i2c_new_dummy_device(&client->dev, client->adapter, + VEML6070_ADDR_DATA_LSB); if (IS_ERR(data->client2)) return dev_err_probe(&client->dev, PTR_ERR(data->client2), "i2c device for second chip address failed\n"); @@ -292,10 +286,6 @@ static int veml6070_probe(struct i2c_client *client) if (ret < 0) return ret; - ret = devm_add_action_or_reset(&client->dev, veml6070_i2c_unreg, data); - if (ret < 0) - return ret; - return devm_iio_device_register(&client->dev, indio_dev); } From 1a772719318c11e146f6fbe621fffd230a6f456a Mon Sep 17 00:00:00 2001 From: Radu Sabau Date: Wed, 8 Apr 2026 13:32:13 +0300 Subject: [PATCH 04/41] iio: adc: ad4695: Fix call ordering in offload buffer postenable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ad4695_enter_advanced_sequencer_mode() was called after spi_offload_trigger_enable(). That is wrong because ad4695_enter_advanced_sequencer_mode() issues regular SPI transfers to put the ADC into advanced sequencer mode, and not all SPI offload capable controllers support regular SPI transfers while offloading is enabled. Fix this by calling ad4695_enter_advanced_sequencer_mode() before spi_offload_trigger_enable(), so the ADC is fully configured before the first CNV pulse can occur. This is consistent with the same constraint that already applies to the BUSY_GP_EN write above it. Update the error unwind labels accordingly: add err_exit_conversion_mode so that a failure of spi_offload_trigger_enable() correctly exits conversion mode before clearing BUSY_GP_EN. Fixes: f09f140e3ea8 ("iio: adc: ad4695: Add support for SPI offload") Reviewed-by: Nuno Sá Reviewed-by: David Lechner Signed-off-by: Radu Sabau Cc: Stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/adc/ad4695.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/iio/adc/ad4695.c b/drivers/iio/adc/ad4695.c index cda419638d9a..53642de7330d 100644 --- a/drivers/iio/adc/ad4695.c +++ b/drivers/iio/adc/ad4695.c @@ -876,14 +876,14 @@ static int ad4695_offload_buffer_postenable(struct iio_dev *indio_dev) if (ret) goto err_unoptimize_message; - ret = spi_offload_trigger_enable(st->offload, st->offload_trigger, - &config); + ret = ad4695_enter_advanced_sequencer_mode(st, num_slots); if (ret) goto err_disable_busy_output; - ret = ad4695_enter_advanced_sequencer_mode(st, num_slots); + ret = spi_offload_trigger_enable(st->offload, st->offload_trigger, + &config); if (ret) - goto err_offload_trigger_disable; + goto err_exit_conversion_mode; mutex_lock(&st->cnv_pwm_lock); pwm_get_state(st->cnv_pwm, &state); @@ -895,23 +895,16 @@ static int ad4695_offload_buffer_postenable(struct iio_dev *indio_dev) ret = pwm_apply_might_sleep(st->cnv_pwm, &state); mutex_unlock(&st->cnv_pwm_lock); if (ret) - goto err_offload_exit_conversion_mode; + goto err_offload_trigger_disable; return 0; -err_offload_exit_conversion_mode: - /* - * We have to unwind in a different order to avoid triggering offload. - * ad4695_exit_conversion_mode() triggers a conversion, so it has to be - * done after spi_offload_trigger_disable(). - */ - spi_offload_trigger_disable(st->offload, st->offload_trigger); - ad4695_exit_conversion_mode(st); - goto err_disable_busy_output; - err_offload_trigger_disable: spi_offload_trigger_disable(st->offload, st->offload_trigger); +err_exit_conversion_mode: + ad4695_exit_conversion_mode(st); + err_disable_busy_output: regmap_clear_bits(st->regmap, AD4695_REG_GP_MODE, AD4695_REG_GP_MODE_BUSY_GP_EN); From 761e8b489e6cf166c574034b70637f8a7eadd0ee Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Tue, 31 Mar 2026 13:13:00 +0300 Subject: [PATCH 05/41] iio: gyro: adis16260: fix division by zero in write_raw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a validation check for the sampling frequency value before using it as a divisor. A user writing zero to the sampling_frequency sysfs attribute triggers a division by zero in the kernel. Fixes: 089a41985c6c ("staging: iio: adis16260 digital gyro driver") Signed-off-by: Antoniu Miclaus Reviewed-by: Nuno Sá Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/adis16260.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/iio/gyro/adis16260.c b/drivers/iio/gyro/adis16260.c index 586e6cfa14a9..91b9c5f18ec4 100644 --- a/drivers/iio/gyro/adis16260.c +++ b/drivers/iio/gyro/adis16260.c @@ -287,6 +287,9 @@ static int adis16260_write_raw(struct iio_dev *indio_dev, addr = adis16260_addresses[chan->scan_index][1]; return adis_write_reg_16(adis, addr, val); case IIO_CHAN_INFO_SAMP_FREQ: + if (val <= 0) + return -EINVAL; + if (spi_get_device_id(adis->spi)->driver_data) t = 256 / val; else From bb21ee31f5753a7972148798fd7dfb841dd33bdb Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Thu, 16 Apr 2026 14:14:42 +0300 Subject: [PATCH 06/41] iio: Fix iio_multiply_value use in iio_read_channel_processed_scale The function iio_multiply_value returns IIO_VAL_INT (1) on success or a negative error number on failure, while iio_read_channel_processed_scale should return an error code or 0. This creates a situation where the expected result is treated as an error. Fix this by checking the iio_multiply_value result separately, instead of passing it as a return value. Fixes: 05f958d003c9 ("iio: Improve iio_read_channel_processed_scale() precision") Signed-off-by: Svyatoslav Ryhel Reviewed-by: Hans de Goede Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/inkern.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 0df0ab3de270..9ce20cb05a9b 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -738,7 +738,11 @@ int iio_read_channel_processed_scale(struct iio_channel *chan, int *val, if (ret < 0) return ret; - return iio_multiply_value(val, scale, ret, pval, pval2); + ret = iio_multiply_value(val, scale, ret, pval, pval2); + if (ret < 0) + return ret; + + return 0; } else { ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW); if (ret < 0) From 7e5c0f97c66ad538b87c04a640573371fb434b4f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 16 Apr 2026 11:01:22 +0200 Subject: [PATCH 07/41] iio: adc: nxp-sar-adc: Avoid division by zero When Common Clock Framework is disabled, clk_get_rate() returns 0. This is used as part of the divisor to perform nanosecond delays with help of ndelay(). When the above condition occurs the compiler, due to unspecified behaviour, is free to do what it wants to. Here it saturates the value, which is logical from mathematics point of view. However, the ndelay() implementation has set a reasonable upper threshold and refuses to provide anything for such a long delay. That's why code may not be linked under these circumstances. To solve the issue, provide a wrapper that calls ndelay() when the value is known not to be zero. Fixes: 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202603311958.ly6uROit-lkp@intel.com/ Signed-off-by: Andy Shevchenko Acked-by: Daniel Lezcano Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/nxp-sar-adc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/nxp-sar-adc.c b/drivers/iio/adc/nxp-sar-adc.c index 9d9f2c76bed4..705dd7da1bd2 100644 --- a/drivers/iio/adc/nxp-sar-adc.c +++ b/drivers/iio/adc/nxp-sar-adc.c @@ -198,6 +198,15 @@ static void nxp_sar_adc_irq_cfg(struct nxp_sar_adc *info, bool enable) writel(0, NXP_SAR_ADC_IMR(info->regs)); } +static void nxp_sar_adc_wait_for(struct nxp_sar_adc *info, unsigned int cycles) +{ + u64 rate; + + rate = clk_get_rate(info->clk); + if (rate) + ndelay(div64_u64(NSEC_PER_SEC, rate * cycles)); +} + static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable) { u32 mcr; @@ -221,7 +230,7 @@ static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable) * configuration of NCMR and the setting of NSTART. */ if (enable) - ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk) * 3)); + nxp_sar_adc_wait_for(info, 3); return pwdn; } @@ -469,7 +478,7 @@ static void nxp_sar_adc_stop_conversion(struct nxp_sar_adc *info) * only when the capture finishes. The delay will be very * short, usec-ish, which is acceptable in the atomic context. */ - ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk)) * 80); + nxp_sar_adc_wait_for(info, 80); } static int nxp_sar_adc_start_conversion(struct nxp_sar_adc *info, bool raw) From 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 14 Apr 2026 13:30:06 +0100 Subject: [PATCH 08/41] iio: adc: npcm: fix unbalanced clk_disable_unprepare() The driver acquired the ADC clock with devm_clk_get() and read its rate, but never called clk_prepare_enable(). The probe error path and npcm_adc_remove() both called clk_disable_unprepare() unconditionally, causing the clk framework's enable/prepare counts to underflow on probe failure or module unbind. The issue went unnoticed because NPCM BMC firmware leaves the ADC clock enabled at boot, so the driver happened to work in practice. Switch to devm_clk_get_enabled() so the clock is properly enabled during probe and automatically released by the device-managed cleanup, and drop the now-redundant clk_disable_unprepare() from both the probe error path and remove(). While at it, drop the duplicate error message on devm_request_irq() failure since the IRQ core already logs it. Fixes: 9bf85fbc9d8f ("iio: adc: add NPCM ADC driver") Signed-off-by: David Carlier Reviewed-by: Andy Shevchenko Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/npcm_adc.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c index ddabb9600d46..61c8b825bda1 100644 --- a/drivers/iio/adc/npcm_adc.c +++ b/drivers/iio/adc/npcm_adc.c @@ -231,7 +231,7 @@ static int npcm_adc_probe(struct platform_device *pdev) if (IS_ERR(info->reset)) return PTR_ERR(info->reset); - info->adc_clk = devm_clk_get(&pdev->dev, NULL); + info->adc_clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(info->adc_clk)) { dev_warn(&pdev->dev, "ADC clock failed: can't read clk\n"); return PTR_ERR(info->adc_clk); @@ -244,17 +244,13 @@ static int npcm_adc_probe(struct platform_device *pdev) info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2); irq = platform_get_irq(pdev, 0); - if (irq < 0) { - ret = irq; - goto err_disable_clk; - } + if (irq < 0) + return irq; ret = devm_request_irq(&pdev->dev, irq, npcm_adc_isr, 0, "NPCM_ADC", indio_dev); - if (ret < 0) { - dev_err(dev, "failed requesting interrupt\n"); - goto err_disable_clk; - } + if (ret < 0) + return ret; reg_con = ioread32(info->regs + NPCM_ADCCON); info->vref = devm_regulator_get_optional(&pdev->dev, "vref"); @@ -262,7 +258,7 @@ static int npcm_adc_probe(struct platform_device *pdev) ret = regulator_enable(info->vref); if (ret) { dev_err(&pdev->dev, "Can't enable ADC reference voltage\n"); - goto err_disable_clk; + return ret; } iowrite32(reg_con & ~NPCM_ADCCON_REFSEL, @@ -272,10 +268,8 @@ static int npcm_adc_probe(struct platform_device *pdev) * Any error which is not ENODEV indicates the regulator * has been specified and so is a failure case. */ - if (PTR_ERR(info->vref) != -ENODEV) { - ret = PTR_ERR(info->vref); - goto err_disable_clk; - } + if (PTR_ERR(info->vref) != -ENODEV) + return PTR_ERR(info->vref); /* Use internal reference */ iowrite32(reg_con | NPCM_ADCCON_REFSEL, @@ -314,8 +308,6 @@ static int npcm_adc_probe(struct platform_device *pdev) iowrite32(reg_con & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON); if (!IS_ERR(info->vref)) regulator_disable(info->vref); -err_disable_clk: - clk_disable_unprepare(info->adc_clk); return ret; } @@ -332,7 +324,6 @@ static void npcm_adc_remove(struct platform_device *pdev) iowrite32(regtemp & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON); if (!IS_ERR(info->vref)) regulator_disable(info->vref); - clk_disable_unprepare(info->adc_clk); } static struct platform_driver npcm_adc_driver = { From 5aba4f94b225617a55fed442a70329b2ee19c0a5 Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Wed, 1 Apr 2026 14:08:29 +0300 Subject: [PATCH 09/41] iio: chemical: scd30: fix division by zero in write_raw Add a zero check for val2 before using it as a divisor when setting the sampling frequency. A user writing a zero fractional part to the sampling_frequency sysfs attribute triggers a division by zero in the kernel. Fixes: 64b3d8b1b0f5 ("iio: chemical: scd30: add core driver") Signed-off-by: Antoniu Miclaus Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/chemical/scd30_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/chemical/scd30_core.c b/drivers/iio/chemical/scd30_core.c index a665fcb78806..11d6bc1b63e6 100644 --- a/drivers/iio/chemical/scd30_core.c +++ b/drivers/iio/chemical/scd30_core.c @@ -256,7 +256,7 @@ static int scd30_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const guard(mutex)(&state->lock); switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: - if (val) + if (val || !val2) return -EINVAL; val = 1000000000 / val2; From d9eeb0ea0d2de658663bfaa9c26eccdd8fd64440 Mon Sep 17 00:00:00 2001 From: Guangshuo Li Date: Mon, 13 Apr 2026 21:46:04 +0800 Subject: [PATCH 10/41] counter: Fix refcount leak in counter_alloc() error path After device_initialize(), the lifetime of the embedded struct device is expected to be managed through the device core reference counting. In counter_alloc(), if dev_set_name() fails after device_initialize(), the error path removes the chrdev, frees the ID, and frees the backing allocation directly instead of releasing the device reference with put_device(). This bypasses the normal device lifetime rules and may leave the reference count of the embedded struct device unbalanced, resulting in a refcount leak. The issue was identified by a static analysis tool I developed and confirmed by manual review. Fix this by using put_device() in the dev_set_name() failure path and let counter_device_release() handle the final cleanup. Fixes: 4da08477ea1f ("counter: Set counter device name") Cc: stable@vger.kernel.org Signed-off-by: Guangshuo Li Link: https://lore.kernel.org/r/20260413134604.2861772-1-lgs201920130244@gmail.com Signed-off-by: William Breathitt Gray --- drivers/counter/counter-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/counter/counter-core.c b/drivers/counter/counter-core.c index 50bd30ba3d03..0b1dac61b7b5 100644 --- a/drivers/counter/counter-core.c +++ b/drivers/counter/counter-core.c @@ -124,7 +124,8 @@ struct counter_device *counter_alloc(size_t sizeof_priv) err_dev_set_name: - counter_chrdev_remove(counter); + put_device(dev); + return NULL; err_chrdev_add: ida_free(&counter_ida, dev->id); From a9aba21a539c668a66b58eeb08ad3909e5a54c2a Mon Sep 17 00:00:00 2001 From: Antoniu Miclaus Date: Wed, 1 Apr 2026 18:29:24 +0300 Subject: [PATCH 11/41] iio: adc: nxp-sar-adc: fix division by zero in write_raw Add a validation check for the sampling frequency value before using it as a divisor. A user writing zero or a negative value to the sampling_frequency sysfs attribute triggers a division by zero in the kernel. Also prevent unsigned integer underflow when the computed cycle count is smaller than NXP_SAR_ADC_CONV_TIME, which would wrap the u32 inpsamp to a huge value. Fixes: 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms") Signed-off-by: Antoniu Miclaus Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/nxp-sar-adc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/nxp-sar-adc.c b/drivers/iio/adc/nxp-sar-adc.c index 705dd7da1bd2..1711cae7d872 100644 --- a/drivers/iio/adc/nxp-sar-adc.c +++ b/drivers/iio/adc/nxp-sar-adc.c @@ -569,6 +569,9 @@ static int nxp_sar_adc_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: + if (val <= 0) + return -EINVAL; + /* * Configures the sample period duration in terms of the SAR * controller clock. The minimum acceptable value is 8. @@ -577,7 +580,11 @@ static int nxp_sar_adc_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec * sampling timing which gives us the number of cycles expected. * The value is 8-bit wide, consequently the max value is 0xFF. */ - inpsamp = clk_get_rate(info->clk) / val - NXP_SAR_ADC_CONV_TIME; + inpsamp = clk_get_rate(info->clk) / val; + if (inpsamp < NXP_SAR_ADC_CONV_TIME) + return -EINVAL; + + inpsamp -= NXP_SAR_ADC_CONV_TIME; nxp_sar_adc_conversion_timing_set(info, inpsamp); return 0; From a093999355084bdbfe6e97f1dd232e58a1525f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Monin?= Date: Wed, 1 Apr 2026 17:24:58 +0200 Subject: [PATCH 12/41] iio: buffer: Fix DMA fence leak in iio_buffer_enqueue_dmabuf() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iio_buffer_enqueue_dmabuf() allocates a struct iio_dma_fence (104 bytes, kmalloc-128) via kmalloc_obj()+dma_fence_init(), which sets the initial kref to 1. It then calls dma_resv_add_fence() which takes a second reference (kref=2), and stores a raw pointer in block->fence. On the success path the function returns without calling dma_fence_put() to release the initial reference, so every buffer enqueue permanently leaks one kmalloc-128 allocation. The iio_buffer_cleanup() work item only releases the temporary reference taken during completion signalling by iio_buffer_signal_dmabuf_done(); the initial reference from dma_fence_init() is never released. With four iio_rwdev instances at 240kHz and 512 samples per buffer, this produces ~1875 kmalloc-128 allocations per second matching the observed slab growth exactly. A test with ftrace confirmed that the dma_fence_destroy event was never triggered. Fix by calling dma_fence_put() after dma_resv_add_fence(), transferring ownership of the fence to the DMA reservation object. The DMA fence then gets properly discarded after being signalled. Fixes: 3e26d9f08fbe0 ("iio: core: Add new DMABUF interface infrastructure") Originally-by: James Nuss Signed-off-by: Benoît Monin Reviewed-by: Paul Cercueil Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 46f36a6ed271..5c3df993bea2 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -1909,6 +1909,7 @@ static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib, dma_resv_add_fence(dmabuf->resv, &fence->base, dma_to_ram ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ); + dma_fence_put(&fence->base); dma_resv_unlock(dmabuf->resv); cookie = dma_fence_begin_signalling(); From 49f79cd28f1e3333cbe0d616ce59ead0b24bf34e Mon Sep 17 00:00:00 2001 From: Advait Dhamorikar Date: Tue, 7 Apr 2026 12:50:59 +0530 Subject: [PATCH 13/41] iio: magnetometer: st_magn: fix default DRDY pin selection for LIS2MDL The device tree binding for st,lis2mdl does not support st,drdy-int-pin property. However, when no platform data is provided and the property is absent, the driver falls back to default_magn_pdata which hardcodes drdy_int_pin = 2. This causes `st_sensors_set_drdy_int_pin` to fail with -EINVAL because the LIS2MDL sensor settings have no INT2 DRDY mask defined. Fix this by checking the sensor's INT2 DRDY mask availability at probe time and selecting the appropriate default pin. Sensors that do not support INT2 DRDY will default to INT1, while all others retain the existing default of INT2. Fixes: 38934daf7b5c ("iio: magnetometer: st_magn: Provide default platform data") Signed-off-by: Advait Dhamorikar Reviewed-by: Andy Shevchenko Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/st_magn_core.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/iio/magnetometer/st_magn_core.c b/drivers/iio/magnetometer/st_magn_core.c index ef348d316c00..7644bd04654b 100644 --- a/drivers/iio/magnetometer/st_magn_core.c +++ b/drivers/iio/magnetometer/st_magn_core.c @@ -506,6 +506,11 @@ static const struct st_sensors_platform_data default_magn_pdata = { .drdy_int_pin = 2, }; +/* LIS2MDL only supports DRDY on INT1 */ +static const struct st_sensors_platform_data alt_magn_pdata = { + .drdy_int_pin = 1, +}; + static int st_magn_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, int *val, int *val2, long mask) @@ -628,8 +633,12 @@ int st_magn_common_probe(struct iio_dev *indio_dev) mdata->current_fullscale = &mdata->sensor_settings->fs.fs_avl[0]; mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz; - if (!pdata) - pdata = (struct st_sensors_platform_data *)&default_magn_pdata; + if (!pdata) { + if (mdata->sensor_settings->drdy_irq.int2.mask) + pdata = (struct st_sensors_platform_data *)&default_magn_pdata; + else + pdata = (struct st_sensors_platform_data *)&alt_magn_pdata; + } err = st_sensors_init_sensor(indio_dev, pdata); if (err < 0) From 1f4f0bcc5255dec5c4c3a1551bf49d8c33b69b20 Mon Sep 17 00:00:00 2001 From: Aldo Conte Date: Tue, 7 Apr 2026 17:17:01 +0200 Subject: [PATCH 14/41] iio: light: cm3323: fix reg_conf not being initialized correctly The code stores the return value of i2c_smbus_write_word_data() in data->reg_conf; however, this value represents the result of the write operation and not the value actually written to the configuration register. This meant that the contents of data->reg_conf did not truly reflect the contents of the hardware register. Instead, save the value of the register before the write and use this value in the I2C write. The bug was found by code inspection: i2c_smbus_write_word_data() returns 0 on success, not the value written to the register. Tested using i2c-stub on a Raspberry Pi 3B running a custom 6.19.10 kernel. Before loading the driver, the configuration register 0x00 CM3323_CMD_CONF was populated with 0x0030 using `i2cset -y 11 0x10 0x00 0x0030 w`, encoding an integration time of 320ms in bits[6:4]. Due to incorrect initialization of data->reg_conf in cm3323_init(), the print of integration_time returns 0.040000 instead of the expected 0.320000. This happens because the read of the integration_time depends on cm3323_get_it_bits() that is based on the value of data->reg_conf, which is erroneously set to 0. With this fix applied, data->reg_conf correctly saves 0x0030 after init and the successive integration_time reports 0.320000 as expected. Fixes: 8b0544263761 ("iio: light: Add support for Capella CM3323 color sensor") Cc: stable@vger.kernel.org Signed-off-by: Aldo Conte Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm3323.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/cm3323.c b/drivers/iio/light/cm3323.c index 79ad6e2209ca..0fe61b8a7029 100644 --- a/drivers/iio/light/cm3323.c +++ b/drivers/iio/light/cm3323.c @@ -89,15 +89,14 @@ static int cm3323_init(struct iio_dev *indio_dev) /* enable sensor and set auto force mode */ ret &= ~(CM3323_CONF_SD_BIT | CM3323_CONF_AF_BIT); + data->reg_conf = ret; - ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, ret); + ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, data->reg_conf); if (ret < 0) { dev_err(&data->client->dev, "Error writing reg_conf\n"); return ret; } - data->reg_conf = ret; - return 0; } From 8ce176501f836634f9c0419c0820140f968e9dc5 Mon Sep 17 00:00:00 2001 From: Shuvam Pandey Date: Mon, 6 Apr 2026 15:38:24 +0545 Subject: [PATCH 15/41] iio: adc: nxp-sar-adc: zero-initialize dma_slave_config nxp_sar_adc_start_cyclic_dma() only fills the RX-side members of dma_slave_config before passing it to dmaengine_slave_config(). Zero-initialize the structure so unused members do not contain stack garbage. Some DMA engines consult optional dma_slave_config fields, so leaving them uninitialized can cause DMA setup failures. Fixes: 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms") Signed-off-by: Shuvam Pandey Reviewed-by: David Lechner Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/nxp-sar-adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/nxp-sar-adc.c b/drivers/iio/adc/nxp-sar-adc.c index 1711cae7d872..8f4ed3db94f0 100644 --- a/drivers/iio/adc/nxp-sar-adc.c +++ b/drivers/iio/adc/nxp-sar-adc.c @@ -676,7 +676,7 @@ static void nxp_sar_adc_dma_cb(void *data) static int nxp_sar_adc_start_cyclic_dma(struct iio_dev *indio_dev) { struct nxp_sar_adc *info = iio_priv(indio_dev); - struct dma_slave_config config; + struct dma_slave_config config = { }; struct dma_async_tx_descriptor *desc; int ret; From 387c86b582e0782ab332e7bfcd4e6e3f93922961 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 9 Apr 2026 15:40:47 +0200 Subject: [PATCH 16/41] iio: pressure: bmp280: fix stack leak in bmp580 trigger handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bmp580_trigger_handler() declares its scan buffer on the stack without an initializer and then memcpy()s 3 bytes of 24-bit sensor data into each 4-byte __le32 field. The high byte of comp_temp and comp_press is left uninitialized, and the channel storagebits is 32, so two bytes of stack are pushed to userspace per scan. This is a regression from when the buffer lived in the private data, the move to a stack-local struct dropped the implicit zeroing. bme280_trigger_handler() was fixed up to handle this bug, but this driver was not fixed because there was no padding hole, but rather a short-fill issue. Fix this all by just zero-initializing the structure on the stack. Cc: Jonathan Cameron Cc: David Lechner Cc: "Nuno Sá" Cc: Andy Shevchenko Fixes: 872c8014e05e ("iio: pressure: bmp280: drop sensor_data array") Cc: stable Assisted-by: gregkh_clanker_t1000 Signed-off-by: Greg Kroah-Hartman Reviewed-by: David Lechner Signed-off-by: Jonathan Cameron --- drivers/iio/pressure/bmp280-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c index d983ce9c0b99..9b489766e457 100644 --- a/drivers/iio/pressure/bmp280-core.c +++ b/drivers/iio/pressure/bmp280-core.c @@ -2616,7 +2616,7 @@ static irqreturn_t bmp580_trigger_handler(int irq, void *p) __le32 comp_temp; __le32 comp_press; aligned_s64 timestamp; - } buffer; + } buffer = { }; int ret; guard(mutex)(&data->lock); From c9d8e9adaa63150ef7e833480b799d0bab83a276 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 9 Apr 2026 15:40:48 +0200 Subject: [PATCH 17/41] iio: imu: st_lsm6dsx: fix stack leak in tagged FIFO buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tagged FIFO path declares iio_buff on the stack with __aligned(8) but no initializer, but there is a hole in the structure, which will then leak to userspace as ST_LSM6DSX_SAMPLE_SIZE bytes (6) will be copied, but the space between that and the timestamp are not initialized. Commit c14edb4d0bdc ("iio:imu:st_lsm6dsx Fix alignment and data leak issues") moved the untagged FIFO path to a kzalloc'd buffer in hw->scan, but for the tagged path it only added the alignment qualifier and not the initializer :( Fix this by just zero-initializing the structure on the stack. Cc: Lorenzo Bianconi Cc: Jonathan Cameron Cc: David Lechner Cc: "Nuno Sá" Cc: Andy Shevchenko Fixes: c14edb4d0bdc ("iio:imu:st_lsm6dsx Fix alignment and data leak issues") Cc: stable Assisted-by: gregkh_clanker_t1000 Signed-off-by: Greg Kroah-Hartman Reviewed-by: David Lechner Signed-off-by: Jonathan Cameron --- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index 5b28a3ffcc3d..48291203d1cd 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -609,7 +609,7 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) * must be passed a buffer that is aligned to 8 bytes so * as to allow insertion of a naturally aligned timestamp. */ - u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8); + u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8) = { }; u8 tag; bool reset_ts = false; int i, err, read_len; From 474f8928d50b09f7dcf507049f08732640b88b49 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 9 Apr 2026 15:40:49 +0200 Subject: [PATCH 18/41] iio: imu: adis16550: fix stack leak in trigger handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit adis16550_trigger_handler() declares the scan data array on the stack without initializing it. The memcpy() at the bottom fills only the first 28 bytes (TEMP + 6 channels of GYRO/ACCEL data), and iio_push_to_buffers_with_timestamp() writes the s64 timestamp at the 8-byte-aligned offset 32. Bytes 28-31 remain uninitialized stack data which leaks to userspace on ever trigger. Fix this all by just zero-initializing the structure on the stack. Cc: Lars-Peter Clausen Cc: Michael Hennerich Cc: Jonathan Cameron Cc: David Lechner Cc: "Nuno Sá" Cc: Andy Shevchenko Fixes: e4570f4bb231 ("iio: imu: adis16550: align buffers for timestamp") Cc: stable Assisted-by: gregkh_clanker_t1000 Signed-off-by: Greg Kroah-Hartman Reviewed-by: David Lechner Signed-off-by: Jonathan Cameron --- drivers/iio/imu/adis16550.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/imu/adis16550.c b/drivers/iio/imu/adis16550.c index 1f2af506f4bd..75679612052f 100644 --- a/drivers/iio/imu/adis16550.c +++ b/drivers/iio/imu/adis16550.c @@ -836,7 +836,7 @@ static irqreturn_t adis16550_trigger_handler(int irq, void *p) u16 dummy; bool valid; struct iio_poll_func *pf = p; - __be32 data[ADIS16550_MAX_SCAN_DATA] __aligned(8); + __be32 data[ADIS16550_MAX_SCAN_DATA] __aligned(8) = { }; struct iio_dev *indio_dev = pf->indio_dev; struct adis16550 *st = iio_priv(indio_dev); struct adis *adis = iio_device_get_drvdata(indio_dev); From 5ace794c3ded38038a1f97f9ea26b9a8c835c111 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 10 Apr 2026 13:12:13 +0300 Subject: [PATCH 19/41] iio: adc: qcom-spmi-adc5-gen3: Fix off by one in adc5_gen3_get_fw_channel_data() The > in "if (chan > ADC5_MAX_CHANNEL)" should be >= to prevent an out of bound read of the adc->data->adc_chans[] array. Fixes: baff45179e90 ("iio: adc: Add support for QCOM PMIC5 Gen3 ADC") Signed-off-by: Dan Carpenter Reviewed-by: Konrad Dybcio Signed-off-by: Jonathan Cameron --- drivers/iio/adc/qcom-spmi-adc5-gen3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/qcom-spmi-adc5-gen3.c b/drivers/iio/adc/qcom-spmi-adc5-gen3.c index f8168a14b907..48c793b18d11 100644 --- a/drivers/iio/adc/qcom-spmi-adc5-gen3.c +++ b/drivers/iio/adc/qcom-spmi-adc5-gen3.c @@ -482,7 +482,7 @@ static int adc5_gen3_get_fw_channel_data(struct adc5_chip *adc, sid = FIELD_GET(ADC5_GEN3_VIRTUAL_SID_MASK, chan); chan = FIELD_GET(ADC5_GEN3_CHANNEL_MASK, chan); - if (chan > ADC5_MAX_CHANNEL) + if (chan >= ADC5_MAX_CHANNEL) return dev_err_probe(dev, -EINVAL, "%s invalid channel number %d\n", name, chan); From f9bbd943c34a9ad60e593a4b99ce2394e4e2381b Mon Sep 17 00:00:00 2001 From: Salah Triki Date: Mon, 27 Apr 2026 21:12:38 +0100 Subject: [PATCH 20/41] iio: adc: mt6359: fix unchecked return value in mt6358_read_imp In mt6358_read_imp(), the variable val_v is passed to regmap_read() but the return value is not checked. If the read fails, val_v remains uninitialized and its random stack content is subsequently reported as a measurement result. Initialize val_v to zero to ensure a predictable value is reported in case of bus failure and to prevent potential stack data leakage. This also satisfies static analyzers that might otherwise flag the variable as used uninitialized. Fixes: 3587914bf61d ("iio: adc: Add support for MediaTek MT6357/8/9 Auxiliary ADC") Signed-off-by: Salah Triki Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/mt6359-auxadc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/adc/mt6359-auxadc.c b/drivers/iio/adc/mt6359-auxadc.c index 6b9ed9b1fde2..1d9724ef0983 100644 --- a/drivers/iio/adc/mt6359-auxadc.c +++ b/drivers/iio/adc/mt6359-auxadc.c @@ -497,6 +497,7 @@ static int mt6358_read_imp(struct mt6359_auxadc *adc_dev, return ret; /* Read the params before stopping */ + val_v = 0; regmap_read(regmap, reg_adc0 + (cinfo->imp_adc_num << 1), &val_v); mt6358_stop_imp_conv(adc_dev); From d0a228d903425e653f18a4341e60c0538afb6d41 Mon Sep 17 00:00:00 2001 From: Salah Triki Date: Mon, 27 Apr 2026 22:33:19 +0100 Subject: [PATCH 21/41] iio: dac: max5821: fix return value check in powerdown sync The function max5821_sync_powerdown_mode() returned the result of i2c_master_send() directly. If a partial transfer occurred, it would be incorrectly treated as a success by the caller. While the caller currently handles the positive return value of 2 as success, this patch refactors the function to return 0 on full success and -EIO on short writes. This ensures robust error handling for incomplete transfers and improves code maintainability by using sizeof(outbuf). Fixes: 472988972737 ("iio: add support of the max5821") Signed-off-by: Salah Triki Reviewed-by: Andy Shevchenko Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/max5821.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/iio/dac/max5821.c b/drivers/iio/dac/max5821.c index e7e29359f8fe..dd4e35460195 100644 --- a/drivers/iio/dac/max5821.c +++ b/drivers/iio/dac/max5821.c @@ -90,6 +90,7 @@ static int max5821_sync_powerdown_mode(struct max5821_data *data, const struct iio_chan_spec *chan) { u8 outbuf[2]; + int ret; outbuf[0] = MAX5821_EXTENDED_COMMAND_MODE; @@ -103,7 +104,13 @@ static int max5821_sync_powerdown_mode(struct max5821_data *data, else outbuf[1] |= MAX5821_EXTENDED_POWER_UP; - return i2c_master_send(data->client, outbuf, 2); + ret = i2c_master_send(data->client, outbuf, sizeof(outbuf)); + if (ret < 0) + return ret; + if (ret != sizeof(outbuf)) + return -EIO; + + return 0; } static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev, From ba121d7582361fe74405f32724976aeff5c35177 Mon Sep 17 00:00:00 2001 From: Felix Gu Date: Mon, 27 Apr 2026 19:26:31 +0800 Subject: [PATCH 22/41] iio: adc: meson-saradc: fix calibration buffer leak on error meson_sar_adc_temp_sensor_init() allocates a buffer with nvmem_cell_read(), but the old code leaked it if syscon_regmap_lookup_by_phandle() failed. Fix this by adding missing kfree(buf). Fixes: d6f2eac64403 ("iio: adc: meson: no devm for nvmem_cell_get") Signed-off-by: Felix Gu Signed-off-by: Jonathan Cameron --- drivers/iio/adc/meson_saradc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c index 23991a3612bd..000e39ca5c62 100644 --- a/drivers/iio/adc/meson_saradc.c +++ b/drivers/iio/adc/meson_saradc.c @@ -817,9 +817,11 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev) } priv->tsc_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "amlogic,hhi-sysctrl"); - if (IS_ERR(priv->tsc_regmap)) + if (IS_ERR(priv->tsc_regmap)) { + kfree(buf); return dev_err_probe(dev, PTR_ERR(priv->tsc_regmap), "failed to get amlogic,hhi-sysctrl regmap\n"); + } trimming_bits = priv->param->temperature_trimming_bits; trimming_mask = BIT(trimming_bits) - 1; From eedf7602fbd929e97e0c480da501dc7a34beb2a8 Mon Sep 17 00:00:00 2001 From: Sanjay Chitroda Date: Sun, 26 Apr 2026 14:47:04 +0530 Subject: [PATCH 23/41] iio: ssp_sensors: cancel delayed work_refresh on remove The work_refresh may still be pending or running when the device is removed, cancel the delayed work_refresh in remove path. Fixes: 50dd64d57eee ("iio: common: ssp_sensors: Add sensorhub driver") Signed-off-by: Sanjay Chitroda Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/common/ssp_sensors/ssp_dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/common/ssp_sensors/ssp_dev.c b/drivers/iio/common/ssp_sensors/ssp_dev.c index da09c9f3ceb6..e2538a84c812 100644 --- a/drivers/iio/common/ssp_sensors/ssp_dev.c +++ b/drivers/iio/common/ssp_sensors/ssp_dev.c @@ -590,6 +590,7 @@ static void ssp_remove(struct spi_device *spi) ssp_clean_pending_list(data); free_irq(data->spi->irq, data); + cancel_delayed_work_sync(&data->work_refresh); timer_delete_sync(&data->wdt_timer); cancel_work_sync(&data->work_wdt); From ecae2ae606d493cf11457946436335bd0e726663 Mon Sep 17 00:00:00 2001 From: Rodrigo Alencar Date: Fri, 1 May 2026 10:14:54 +0100 Subject: [PATCH 24/41] iio: dac: ad5686: fix ref bit initialization for single-channel parts The reference bit position was ignored when writing the register at the probe() function (!!val was used). When such bit is 1, internal voltage reference is disabled so that an external one can be used. For multi-channel devices, bit 0 of the Internal Reference Setup command behaves the same way, so AD5686_REF_BIT_MSK is created. The issue exists since support for single-channel devices were first introduced. Fixes: be1b24d24541 ("iio:dac:ad5686: Add AD5691R/AD5692R/AD5693/AD5693R support") Reviewed-by: Andy Shevchenko Signed-off-by: Rodrigo Alencar Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5686.c | 6 +++--- drivers/iio/dac/ad5686.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 4b18498aa074..b85d5c5a864b 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -509,7 +509,7 @@ int ad5686_probe(struct device *dev, break; case AD5686_REGMAP: cmd = AD5686_CMD_INTERNAL_REFER_SETUP; - ref_bit_msk = 0; + ref_bit_msk = AD5686_REF_BIT_MSK; break; case AD5693_REGMAP: cmd = AD5686_CMD_CONTROL_REG; @@ -520,9 +520,9 @@ int ad5686_probe(struct device *dev, return -EINVAL; } - val = (has_external_vref | ref_bit_msk); + val = has_external_vref ? ref_bit_msk : 0; - ret = st->write(st, cmd, 0, !!val); + ret = st->write(st, cmd, 0, val); if (ret) return ret; diff --git a/drivers/iio/dac/ad5686.h b/drivers/iio/dac/ad5686.h index e7d36bae3e59..36e16c5c4581 100644 --- a/drivers/iio/dac/ad5686.h +++ b/drivers/iio/dac/ad5686.h @@ -46,6 +46,7 @@ #define AD5310_REF_BIT_MSK BIT(8) #define AD5683_REF_BIT_MSK BIT(12) +#define AD5686_REF_BIT_MSK BIT(0) #define AD5693_REF_BIT_MSK BIT(12) /** From d01220ee5e43c65a206df827b39bf5cf5f7b9dce Mon Sep 17 00:00:00 2001 From: Rodrigo Alencar Date: Fri, 1 May 2026 10:14:55 +0100 Subject: [PATCH 25/41] iio: dac: ad5686: fix input raw value check Fix range check for input raw value, which is off by one, i.e., for a 10-bit DAC the max valid value is 1023, but 1 << 10 equals 1024, which passes the previous check, allowing an out-of-range write. The issue exists since the ad5686 driver was first introduced. Fixes: c2f37c8dcadc ("iio: dac: New driver for AD5686R, AD5685R, AD5684R Digital to analog converters") Reviewed-by: Andy Shevchenko Signed-off-by: Rodrigo Alencar Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5686.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index b85d5c5a864b..27878a6318ff 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -154,7 +154,7 @@ static int ad5686_write_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - if (val > (1 << chan->scan_type.realbits) || val < 0) + if (val >= (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; mutex_lock(&st->lock); From 6f5ed4f2c7c83f33344e0ba179f72a12e5dad4a4 Mon Sep 17 00:00:00 2001 From: Felix Gu Date: Thu, 30 Apr 2026 21:29:06 +0800 Subject: [PATCH 26/41] iio: buffer: hw-consumer: fix use-after-free in error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the err_put_buffers cleanup path of iio_hw_consumer_alloc(), the code was using list_for_each_entry() to iterate through buffers while calling iio_buffer_put() which can free the current buffer if refcount drops to 0. The list_for_each_entry() loop macro then evaluates buf->head.next to continue iteration, accessing the freed buffer. Fix this by using list_for_each_entry_safe(). Fixes: 48b66f8f936f ("iio: Add hardware consumer buffer support") Reported-by: sashiko Closes: https://sashiko.dev/#/patchset/20260427-iio_buf-v1-1-2bbdac844647%40gmail.com Signed-off-by: Felix Gu Reviewed-by: Andy Shevchenko Reviewed-by: Nuno Sá Reviewed-by: Maxwell Doose Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/buffer/industrialio-hw-consumer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/buffer/industrialio-hw-consumer.c b/drivers/iio/buffer/industrialio-hw-consumer.c index 24d7df603760..700528c9a0a4 100644 --- a/drivers/iio/buffer/industrialio-hw-consumer.c +++ b/drivers/iio/buffer/industrialio-hw-consumer.c @@ -85,7 +85,7 @@ static struct hw_consumer_buffer *iio_hw_consumer_get_buffer( */ struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev) { - struct hw_consumer_buffer *buf; + struct hw_consumer_buffer *buf, *tmp; struct iio_hw_consumer *hwc; struct iio_channel *chan; int ret; @@ -116,7 +116,7 @@ struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev) return hwc; err_put_buffers: - list_for_each_entry(buf, &hwc->buffers, head) + list_for_each_entry_safe(buf, tmp, &hwc->buffers, head) iio_buffer_put(&buf->buffer); iio_channel_release_all(hwc->channels); err_free_hwc: From ebd250c2581ec46c64c73fdfa918c9a7f757505e Mon Sep 17 00:00:00 2001 From: Kim Seer Paller Date: Tue, 5 May 2026 12:34:32 +0800 Subject: [PATCH 27/41] iio: dac: ad3530r: Fix AD3531/AD3531R powerdown mode strings The AD3531/AD3531R has different output operating modes from the AD3530/AD3530R. According to the AD3531/AD3531R datasheet, the powerdown modes are: 01: 500 Ohm output impedance 10: 3.85 kOhm output impedance 11: 16 kOhm output impedance The driver currently uses the AD3530R modes (1k, 7.7k, 32k) for all variants, which is incorrect for AD3531/AD3531R. Add AD3531R-specific powerdown mode strings and assign them to the AD3531/AD3531R chip variants. Fixes: 93583174a3df ("iio: dac: ad3530r: Add driver for AD3530R and AD3531R") Signed-off-by: Kim Seer Paller Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad3530r.c | 54 +++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/drivers/iio/dac/ad3530r.c b/drivers/iio/dac/ad3530r.c index b97b46090d80..d9db3226ecd6 100644 --- a/drivers/iio/dac/ad3530r.c +++ b/drivers/iio/dac/ad3530r.c @@ -105,6 +105,12 @@ static const char * const ad3530r_powerdown_modes[] = { "32kohm_to_gnd", }; +static const char * const ad3531r_powerdown_modes[] = { + "500ohm_to_gnd", + "3.85kohm_to_gnd", + "16kohm_to_gnd", +}; + static int ad3530r_get_powerdown_mode(struct iio_dev *indio_dev, const struct iio_chan_spec *chan) { @@ -133,6 +139,13 @@ static const struct iio_enum ad3530r_powerdown_mode_enum = { .set = ad3530r_set_powerdown_mode, }; +static const struct iio_enum ad3531r_powerdown_mode_enum = { + .items = ad3531r_powerdown_modes, + .num_items = ARRAY_SIZE(ad3531r_powerdown_modes), + .get = ad3530r_get_powerdown_mode, + .set = ad3530r_set_powerdown_mode, +}; + static ssize_t ad3530r_get_dac_powerdown(struct iio_dev *indio_dev, uintptr_t private, const struct iio_chan_spec *chan, @@ -276,7 +289,20 @@ static const struct iio_chan_spec_ext_info ad3530r_ext_info[] = { { } }; -#define AD3530R_CHAN(_chan) \ +static const struct iio_chan_spec_ext_info ad3531r_ext_info[] = { + { + .name = "powerdown", + .shared = IIO_SEPARATE, + .read = ad3530r_get_dac_powerdown, + .write = ad3530r_set_dac_powerdown, + }, + IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad3531r_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, + &ad3531r_powerdown_mode_enum), + { } +}; + +#define AD3530R_CHAN(_chan, _ext_info) \ { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ @@ -284,25 +310,25 @@ static const struct iio_chan_spec_ext_info ad3530r_ext_info[] = { .output = 1, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE), \ - .ext_info = ad3530r_ext_info, \ + .ext_info = _ext_info, \ } static const struct iio_chan_spec ad3530r_channels[] = { - AD3530R_CHAN(0), - AD3530R_CHAN(1), - AD3530R_CHAN(2), - AD3530R_CHAN(3), - AD3530R_CHAN(4), - AD3530R_CHAN(5), - AD3530R_CHAN(6), - AD3530R_CHAN(7), + AD3530R_CHAN(0, ad3530r_ext_info), + AD3530R_CHAN(1, ad3530r_ext_info), + AD3530R_CHAN(2, ad3530r_ext_info), + AD3530R_CHAN(3, ad3530r_ext_info), + AD3530R_CHAN(4, ad3530r_ext_info), + AD3530R_CHAN(5, ad3530r_ext_info), + AD3530R_CHAN(6, ad3530r_ext_info), + AD3530R_CHAN(7, ad3530r_ext_info), }; static const struct iio_chan_spec ad3531r_channels[] = { - AD3530R_CHAN(0), - AD3530R_CHAN(1), - AD3530R_CHAN(2), - AD3530R_CHAN(3), + AD3530R_CHAN(0, ad3531r_ext_info), + AD3530R_CHAN(1, ad3531r_ext_info), + AD3530R_CHAN(2, ad3531r_ext_info), + AD3530R_CHAN(3, ad3531r_ext_info), }; static const struct ad3530r_chip_info ad3530_chip = { From 4701e471c16866e7aa8f5e6a3a6b0d31e097e2c9 Mon Sep 17 00:00:00 2001 From: Salah Triki Date: Tue, 5 May 2026 08:10:24 +0100 Subject: [PATCH 28/41] iio: temperature: tsys01: fix broken PROM checksum validation The current implementation of tsys01_crc_valid() incorrectly sums the first word (n_prom[0]) repeatedly instead of iterating over the 8 words retrieved from the PROM. This leads to a checksum mismatch and probe failure on hardware. According to the TSYS01 datasheet, the PROM consists of 8 words. A valid check must iterate through all 8 words to verify the integrity of the calibration data. The current driver only checks the first word 8 times. Note: This fix was identified during a code audit and is based on datasheet specifications. It has not been tested on real hardware. Fixes: 43e53407f680 ("Add tsys01 meas-spec driver support") Signed-off-by: Salah Triki Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/temperature/tsys01.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/temperature/tsys01.c b/drivers/iio/temperature/tsys01.c index 334bba6fdae6..104dd45598b0 100644 --- a/drivers/iio/temperature/tsys01.c +++ b/drivers/iio/temperature/tsys01.c @@ -119,7 +119,7 @@ static bool tsys01_crc_valid(u16 *n_prom) u8 sum = 0; for (cnt = 0; cnt < TSYS01_PROM_WORDS_NB; cnt++) - sum += ((n_prom[0] >> 8) + (n_prom[0] & 0xFF)); + sum += ((n_prom[cnt] >> 8) + (n_prom[cnt] & 0xFF)); return (sum == 0); } From 5237c3175cae5ab05f18878cec3301a04403859e Mon Sep 17 00:00:00 2001 From: Rodrigo Alencar Date: Tue, 5 May 2026 13:35:04 +0100 Subject: [PATCH 29/41] iio: dac: ad5686: acquire lock when doing powerdown control Protect access of pwr_down_mode and pwr_down_mask fields with existing mutex lock. Each channel exposes their own attributes for controlling powerdown modes and powerdown state. This fixes potential race conditions as those the write functions perform non-atomic read-modify-write operations to those pwr_down_* fields. This issue exists since the ad5686 driver was first introduced. Fixes: c2f37c8dcadc ("iio: dac: New driver for AD5686R, AD5685R, AD5684R Digital to analog converters") Signed-off-by: Rodrigo Alencar Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5686.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 27878a6318ff..2e443fcfeb39 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -30,6 +30,8 @@ static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev, { struct ad5686_state *st = iio_priv(indio_dev); + guard(mutex)(&st->lock); + return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1; } @@ -39,6 +41,8 @@ static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev, { struct ad5686_state *st = iio_priv(indio_dev); + guard(mutex)(&st->lock); + st->pwr_down_mode &= ~(0x3 << (chan->channel * 2)); st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2)); @@ -57,6 +61,8 @@ static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev, { struct ad5686_state *st = iio_priv(indio_dev); + guard(mutex)(&st->lock); + return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & (0x3 << (chan->channel * 2)))); } @@ -77,6 +83,8 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, if (ret) return ret; + guard(mutex)(&st->lock); + if (readin) st->pwr_down_mask |= (0x3 << (chan->channel * 2)); else From 8aeaf25a85263a7a43357e16ad78ab969f6f8aeb Mon Sep 17 00:00:00 2001 From: Rodrigo Alencar Date: Tue, 5 May 2026 13:35:05 +0100 Subject: [PATCH 30/41] iio: dac: ad5686: fix powerdown control on dual-channel devices Fix powerdown control by using a proper bit shift for the powerdown mask values. During initialization, powerdown bits are initialized so that unused bits are set to 1 and the correct bit shift is used. Dual-channel devices use one-hot encoding in the address and that reflects on the position of the powerdown bits, which are not channel-index based for that case. Quad-channel devices also use one-hot encoding for the channel address but the result of log2(address) coincides with the channel index value. Mask as 0x3U is used rather than 0x3, because shift can reach value of 30 (last channel of a 16-channel device), which would mess with the sign bit. The issue was introduced when first adding support for dual-channel devices, which overlooked powerdown control differences. Fixes: 7dc8faeab3e3 ("iio: dac: ad5686: add support for AD5338R") Signed-off-by: Rodrigo Alencar Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5686.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 2e443fcfeb39..a7213bc6b156 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -25,26 +25,37 @@ static const char * const ad5686_powerdown_modes[] = { "three_state" }; +static inline unsigned int ad5686_pd_mask_shift(const struct iio_chan_spec *chan) +{ + if (chan->channel == chan->address) + return chan->channel * 2; + + /* one-hot encoding is used in dual/quad channel devices */ + return __ffs(chan->address) * 2; +} + static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev, const struct iio_chan_spec *chan) { + unsigned int shift = ad5686_pd_mask_shift(chan); struct ad5686_state *st = iio_priv(indio_dev); guard(mutex)(&st->lock); - return ((st->pwr_down_mode >> (chan->channel * 2)) & 0x3) - 1; + return ((st->pwr_down_mode >> shift) & 0x3U) - 1; } static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, unsigned int mode) { + unsigned int shift = ad5686_pd_mask_shift(chan); struct ad5686_state *st = iio_priv(indio_dev); guard(mutex)(&st->lock); - st->pwr_down_mode &= ~(0x3 << (chan->channel * 2)); - st->pwr_down_mode |= ((mode + 1) << (chan->channel * 2)); + st->pwr_down_mode &= ~(0x3U << shift); + st->pwr_down_mode |= (mode + 1) << shift; return 0; } @@ -59,12 +70,12 @@ static const struct iio_enum ad5686_powerdown_mode_enum = { static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev, uintptr_t private, const struct iio_chan_spec *chan, char *buf) { + unsigned int shift = ad5686_pd_mask_shift(chan); struct ad5686_state *st = iio_priv(indio_dev); guard(mutex)(&st->lock); - return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & - (0x3 << (chan->channel * 2)))); + return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & (0x3U << shift))); } static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, @@ -86,9 +97,9 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, guard(mutex)(&st->lock); if (readin) - st->pwr_down_mask |= (0x3 << (chan->channel * 2)); + st->pwr_down_mask |= 0x3U << ad5686_pd_mask_shift(chan); else - st->pwr_down_mask &= ~(0x3 << (chan->channel * 2)); + st->pwr_down_mask &= ~(0x3U << ad5686_pd_mask_shift(chan)); switch (st->chip_info->regmap_type) { case AD5310_REGMAP: @@ -468,7 +479,7 @@ int ad5686_probe(struct device *dev, { struct ad5686_state *st; struct iio_dev *indio_dev; - unsigned int val, ref_bit_msk; + unsigned int val, ref_bit_msk, shift; bool has_external_vref; u8 cmd; int ret, i; @@ -492,9 +503,18 @@ int ad5686_probe(struct device *dev, has_external_vref = ret != -ENODEV; st->vref_mv = has_external_vref ? ret / 1000 : st->chip_info->int_vref_mv; + /* Initialize masks to all ones provided the max shift (last channel) */ + shift = ad5686_pd_mask_shift(&st->chip_info->channels[st->chip_info->num_channels - 1]); + st->pwr_down_mask = GENMASK(shift + 1, 0); + st->pwr_down_mode = GENMASK(shift + 1, 0); + /* Set all the power down mode for all channels to 1K pulldown */ - for (i = 0; i < st->chip_info->num_channels; i++) - st->pwr_down_mode |= (0x01 << (i * 2)); + for (i = 0; i < st->chip_info->num_channels; i++) { + shift = ad5686_pd_mask_shift(&st->chip_info->channels[i]); + st->pwr_down_mask &= ~(0x3U << shift); /* powered up state */ + st->pwr_down_mode &= ~(0x3U << shift); + st->pwr_down_mode |= 0x01U << shift; + } indio_dev->name = name; indio_dev->info = &ad5686_info; From 6bdc3023d62ed5c7d591f0eb27a5adb37fb892ae Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 5 May 2026 14:37:48 +0100 Subject: [PATCH 31/41] iio: gyro: itg3200: fix i2c read into the wrong stack location itg3200_read_all_channels() takes `__be16 *buf' as a parameter and fills the i2c_msg destination as `(char *)&buf'. Since `buf' is the parameter (a pointer), `&buf' is the address of the local pointer slot on the stack of itg3200_read_all_channels(), not the address of the caller's scan buffer. The (char *) cast hides the type mismatch. i2c_transfer() therefore writes ITG3200_SCAN_ELEMENTS * sizeof(s16) = 8 bytes into the parameter's stack slot, which is discarded when the function returns. The caller's scan buffer in itg3200_trigger_handler() is never written to, so iio_push_to_buffers_with_timestamp() pushes uninitialised stack contents to userspace via /dev/iio:deviceX every scan -- both a functional bug (no actual gyroscope or temperature data is delivered through the triggered buffer) and an information leak. The non-buffered read_raw() path is unaffected: it goes through itg3200_read_reg_s16() which uses `&out' on a local s16 value, where that is correct. Drop the spurious `&' so the i2c read writes into the caller's buffer. Fixes: 9dbf091da080 ("iio: gyro: Add itg3200") Cc: stable@vger.kernel.org Signed-off-by: David Carlier Reviewed-by: Andy Shevchenko Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/itg3200_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/gyro/itg3200_buffer.c b/drivers/iio/gyro/itg3200_buffer.c index cf97adfa9727..87efa2c74ca4 100644 --- a/drivers/iio/gyro/itg3200_buffer.c +++ b/drivers/iio/gyro/itg3200_buffer.c @@ -34,7 +34,7 @@ static int itg3200_read_all_channels(struct i2c_client *i2c, __be16 *buf) .addr = i2c->addr, .flags = i2c->flags | I2C_M_RD, .len = ITG3200_SCAN_ELEMENTS * sizeof(s16), - .buf = (char *)&buf, + .buf = (char *)buf, }, }; From 422b5bbf333f75fb486855ad0eedc23cf21f3277 Mon Sep 17 00:00:00 2001 From: Salah Triki Date: Thu, 7 May 2026 20:07:51 +0100 Subject: [PATCH 32/41] iio: adc: viperboard: Fix error handling in vprbrd_iio_read_raw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver proceeds to the reception phase even if the preceding transmission fails. This uses a goto error label for an early bail out and ensures the mutex is properly unlocked in case of failure. Fixes: ffd8a6e7a778 ("iio: adc: Add viperboard adc driver") Signed-off-by: Salah Triki Reviewed-by: Joshua Crofts Reviewed-by: Maxwell Doose Reviewed-by: Nuno Sá Cc: Signed-off-by: Jonathan Cameron --- drivers/iio/adc/viperboard_adc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iio/adc/viperboard_adc.c b/drivers/iio/adc/viperboard_adc.c index 9bb0b83c8f67..6efe1c618ef7 100644 --- a/drivers/iio/adc/viperboard_adc.c +++ b/drivers/iio/adc/viperboard_adc.c @@ -70,8 +70,10 @@ static int vprbrd_iio_read_raw(struct iio_dev *iio_dev, VPRBRD_USB_TYPE_OUT, 0x0000, 0x0000, admsg, sizeof(struct vprbrd_adc_msg), VPRBRD_USB_TIMEOUT_MS); if (ret != sizeof(struct vprbrd_adc_msg)) { - dev_err(&iio_dev->dev, "usb send error on adc read\n"); + mutex_unlock(&vb->lock); error = -EREMOTEIO; + dev_err(&iio_dev->dev, "usb send error on adc read\n"); + goto error; } ret = usb_control_msg(vb->usb_dev, From 8a3bee801d420be8a7a0bae4a26547b353b8fe22 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 22 Apr 2026 15:46:37 +0100 Subject: [PATCH 33/41] comedi: comedi_test: Fix limiting of convert_arg in waveform_ai_cmdtest() The function checks and possibly modifies the description of an asynchronous command to be run on the analog input subdevice of a comedi device attached to the "comedi_test" driver, returning 0 if no modifications were required, or a positive value that indicates which step of the checking process it failed on. Step 4 fixes up various argument values for various trigger sources. There are two bugs in the fixing up of the `convert_arg` value to keep the `scan_begin_arg` value within the range of `unsigned int` when `scan_begin_src` and `convert_src` both have the value `TRIG_TIMER`, which indicates that the corresponding `_arg` values hold a time period in nanoseconds. The code also uses `scan_end_arg` which hold the number of "conversions" within each "scan". The goal is to end up with the scan period being less than or equal to the convert period multiplied by the number of conversions per scan. It intends to do that by clamping the `convert_arg` value to a maximum value of `UINT_MAX / scan_end_arg` rounded down to a multiple of 1000 (`NSEC_PER_USEC`). (The rounding from nanoseconds to microseconds is because the driver is modelling a device that uses a 1 MHz clock for timing. This is partly because that is a more typical timing base for real hardware devices driven by comedi, and partly because the driver used to use `struct timeval` internally.) The first bug is that the code checks if `scan_begin_arg == TRIG_TIMER` when it should be checking if `scan_begin_src == TRIG_TIMER`. The bugged check will always fail because if `scan_begin_src == TRIG_TIMER`, then `scan_begin_arg` will be at least 1000 (`NSEC_PER_USEC`), otherwise `scan_begin_src == TRIG_FOLLOW` and `scan_begin_arg` will be 0. (N.B `TRIG_TIMER` is defined as `0x10`.) The second bug is that is rounding the maximum value down to a multiple of 1000000000 (`NSEC_PER_SEC`) instead of 1000 (`NSEC_PER_USEC`), however this bug is not reached due to the first bug. This patch fixes both bugs. Fixes: 783ddaebd397 ("staging: comedi: comedi_test: support scan_begin_src == TRIG_FOLLOW") Fixes: 5afdcad2f818 ("staging: comedi: comedi_test: limit maximum convert_arg") Cc: stable Signed-off-by: Ian Abbott Link: https://patch.msgid.link/20260422144637.27692-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/comedi/drivers/comedi_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c index 01aafce20ef8..4050f66193e5 100644 --- a/drivers/comedi/drivers/comedi_test.c +++ b/drivers/comedi/drivers/comedi_test.c @@ -324,10 +324,10 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, arg = min(arg, rounddown(UINT_MAX, (unsigned int)NSEC_PER_USEC)); arg = NSEC_PER_USEC * DIV_ROUND_CLOSEST(arg, NSEC_PER_USEC); - if (cmd->scan_begin_arg == TRIG_TIMER) { + if (cmd->scan_begin_src == TRIG_TIMER) { /* limit convert_arg to keep scan_begin_arg in range */ limit = UINT_MAX / cmd->scan_end_arg; - limit = rounddown(limit, (unsigned int)NSEC_PER_SEC); + limit = rounddown(limit, (unsigned int)NSEC_PER_USEC); arg = min(arg, limit); } err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); From 542f5248cb481073203e0dadab5bcbd28aeae308 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 22 Apr 2026 17:21:19 +0100 Subject: [PATCH 34/41] comedi: comedi_test: fix check for valid scan_begin_src in waveform_ai_cmdtest() Commit 783ddaebd397 ("staging: comedi: comedi_test: support scan_begin_src == TRIG_FOLLOW") neglected to add a test that `scan_begin_src` has only one bit set. The allowed values are `TRIG_FOLLOW` and `TRIG_TIMER`, but the code incorrectly also allows `TRIG_FOLLOW | TRIG_TIMER`. Add a call to `comedi_check_trigger_is_unique()` to check that only one trigger source bit is set. Fixes: 783ddaebd397 ("staging: comedi: comedi_test: support scan_begin_src == TRIG_FOLLOW") Cc: stable Signed-off-by: Ian Abbott Link: https://patch.msgid.link/20260422162138.36003-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/comedi/drivers/comedi_test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c index 4050f66193e5..1f430ffc7bd9 100644 --- a/drivers/comedi/drivers/comedi_test.c +++ b/drivers/comedi/drivers/comedi_test.c @@ -274,6 +274,7 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, /* Step 2a : make sure trigger sources are unique */ err |= comedi_check_trigger_is_unique(cmd->convert_src); + err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); err |= comedi_check_trigger_is_unique(cmd->stop_src); /* Step 2b : and mutually compatible */ From 4c19719eb8b8df08c5bec7c499f73ddaea6f09fc Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Tue, 14 Apr 2026 12:02:34 +0000 Subject: [PATCH 35/41] rust_binder: avoid calling pending_oneway_finished() on TF_UPDATE_TXN When an outdated transaction is removed from `oneway_todo` due to `TF_UPDATE_TXN`, its `Allocation` is dropped. The current implementation of `Allocation::drop` calls `pending_oneway_finished()`, assuming the transaction was executed. This leads to premature execution of the next queued one-way transaction. Fix this by taking the `oneway_node` from the `Allocation` of the outdated transaction before it is dropped. This prevents `Allocation::drop` from signaling completion. We do not call `take_oneway_node()` from `Transaction::cancel` because it's actually correct to call `pending_oneway_finished()` on cancel if the transaction did not come from `oneway_todo`. This ensures that if `BINDER_THREAD_EXIT` is invoked and cancels a oneway transaction, then the next transaction is taken from `oneway_todo`. This bug does not lead to any issues in the kernel, but may lead to Binder delivering transactions to userspace earlier than userspace expected to receive them. Cc: stable Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver") Assisted-by: Antigravity:gemini Signed-off-by: Alice Ryhl Acked-by: Carlos Llamas Link: https://patch.msgid.link/20260414-tf-update-txn-fix-v1-1-d2b83303acc9@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder/allocation.rs | 8 ++++++++ drivers/android/binder/transaction.rs | 11 ++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/android/binder/allocation.rs b/drivers/android/binder/allocation.rs index 0cab959e4b7e..b7b05e72970a 100644 --- a/drivers/android/binder/allocation.rs +++ b/drivers/android/binder/allocation.rs @@ -157,6 +157,14 @@ pub(crate) fn set_info_target_node(&mut self, target_node: NodeRef) { self.get_or_init_info().target_node = Some(target_node); } + pub(crate) fn take_oneway_node(&mut self) -> Option> { + if let Some(info) = self.allocation_info.as_mut() { + info.oneway_node.take() + } else { + None + } + } + /// Reserve enough space to push at least `num_fds` fds. pub(crate) fn info_add_fd_reserve(&mut self, num_fds: usize) -> Result { self.get_or_init_info() diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs index 47d5e4d88b07..1d9b66920a21 100644 --- a/drivers/android/binder/transaction.rs +++ b/drivers/android/binder/transaction.rs @@ -270,7 +270,8 @@ fn drop_outstanding_txn(&self) { /// Not used for replies. pub(crate) fn submit(self: DLArc, info: &mut TransactionInfo) -> BinderResult { // Defined before `process_inner` so that the destructor runs after releasing the lock. - let mut _t_outdated; + let _t_outdated; + let _oneway_node; let oneway = self.flags & TF_ONE_WAY != 0; let process = self.to.clone(); @@ -287,6 +288,14 @@ pub(crate) fn submit(self: DLArc, info: &mut TransactionInfo) -> BinderRes if let Some(t_outdated) = target_node.take_outdated_transaction(&self, &mut process_inner) { + let mut alloc_guard = t_outdated.allocation.lock(); + if let Some(alloc) = (*alloc_guard).as_mut() { + // Take the oneway node to prevent `Allocation::drop` from calling + // `pending_oneway_finished()`, which would be incorrect as this + // transaction is not being submitted. + _oneway_node = alloc.take_oneway_node(); + } + drop(alloc_guard); // Save the transaction to be dropped after locks are released. _t_outdated = t_outdated; } From f6d8fea9e3953151a4adb4f603503dc3dc9c69da Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Fri, 3 Apr 2026 18:18:58 +0000 Subject: [PATCH 36/41] rust_binder: Avoid holding lock when dropping delivered_death In 6c37bebd8c926, we switched to looping over the list and dropping each individual node, ostensibly without the lock held in the loop body. If the kernel were using Rust Edition 2024, the comment would be accurate, and the lock would not be held across the drop. However, the kernel is currently using 2021, so tail expression lifetime extension results in the lock being held across the drop. Explicitly binding the expression result to a variable makes the lockguard no longer part of a tail expression, causing the lock to be dropped before entering the loop body. This was detected via `CONFIG_PROVE_LOCKING` identifying an invalid wait context at the drop site. Reported-by: David Stevens Signed-off-by: Matthew Maurer Cc: stable Fixes: 6c37bebd8c92 ("rust_binder: avoid mem::take on delivered_deaths") Reviewed-by: Alice Ryhl Acked-by: Carlos Llamas Link: https://patch.msgid.link/20260403-lockhold-v1-1-c332b56cd8ae@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder/process.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs index 820cbd541435..96b8440ceac6 100644 --- a/drivers/android/binder/process.rs +++ b/drivers/android/binder/process.rs @@ -1402,7 +1402,12 @@ fn deferred_release(self: Arc) { // Clear delivered_deaths list. // // Scope ensures that MutexGuard is dropped while executing the body. - while let Some(delivered_death) = { self.inner.lock().delivered_deaths.pop_front() } { + while let Some(delivered_death) = { + // Explicitly bind to avoid tail expression lifetime extension of the lockguard + // Can be removed when the kernel moves to edition 2024 + let maybe_death = self.inner.lock().delivered_deaths.pop_front(); + maybe_death + } { drop(delivered_death); } From f74c8696f14149d5e43cc28b015326a759c48f00 Mon Sep 17 00:00:00 2001 From: Guangshuo Li Date: Tue, 5 May 2026 23:02:56 +0800 Subject: [PATCH 37/41] uio: uio_pci_generic_sva: fix double free of devm_kzalloc() memory uio_pci_sva allocates struct uio_pci_sva_dev with devm_kzalloc() in probe(), but then calls kfree(udev) both on the probe() error path (label out_free) and again in remove(). Because devm_kzalloc() allocations are devres-managed and are freed automatically when the device is detached (including after a failing probe() and during driver unbind), the explicit kfree() can lead to a double free. If probe() fails after devm_kzalloc(), the error path frees udev and devres cleanup will free it again when the core unwinds the partially bound device. On normal driver removal, remove() frees udev and devres will free it again when the device is detached. This issue was identified by a static analysis tool I developed and confirmed by manual review. Fix by removing the manual kfree() calls and dropping the now-unused label. Fixes: 3397c3cd859a2 ("uio: Add SVA support for PCI devices via uio_pci_generic_sva.c") Cc: stable Signed-off-by: Guangshuo Li Link: https://patch.msgid.link/20260505150256.614071-1-lgs201920130244@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_pci_generic_sva.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/uio/uio_pci_generic_sva.c b/drivers/uio/uio_pci_generic_sva.c index 4a46acd994a8..d05ef77f7e32 100644 --- a/drivers/uio/uio_pci_generic_sva.c +++ b/drivers/uio/uio_pci_generic_sva.c @@ -129,15 +129,13 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id) ret = devm_uio_register_device(&pdev->dev, &udev->info); if (ret) { dev_err(&pdev->dev, "Failed to register uio device\n"); - goto out_free; + goto out_disable; } pci_set_drvdata(pdev, udev); return 0; -out_free: - kfree(udev); out_disable: pci_disable_device(pdev); @@ -146,11 +144,8 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *id) static void remove(struct pci_dev *pdev) { - struct uio_pci_sva_dev *udev = pci_get_drvdata(pdev); - pci_release_regions(pdev); pci_disable_device(pdev); - kfree(udev); } static ssize_t pasid_show(struct device *dev, From ef15ccbb3e8640a723c42ad90eaf81d66ae02017 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 5 May 2026 20:45:12 +0200 Subject: [PATCH 38/41] parport: Fix race between port and client registration The parport subsystem registers port devices before they are fully initialised, resulting in a race condition where client drivers such as lp can attach to ports that are not completely initialised or even being torn down. When the port and client drivers are built as modules and loaded around the same time during boot, this occasionally results in a crash. I was able to make this happen reliably in a VM with a PC-style parallel port by patching parport_pc to fail probing: > --- a/drivers/parport/parport_pc.c > +++ b/drivers/parport/parport_pc.c > @@ -2069,7 +2069,7 @@ static struct parport *__parport_pc_probe_port(unsigned long int base, > if (!p) > goto out3; > > - base_res = request_region(base, 3, p->name); > + base_res = NULL; > if (!base_res) > goto out4; > and then running: while true; do modprobe lp & modprobe parport_pc wait rmmod lp parport_pc done for a few seconds. In the long term I think port registration should be changed to put the call to device_add() inside parport_announce_port(), but since the latter currently cannot fail this will require changing all port drivers. For now, add a flag to indicate whether a port has been "announced" and only try to attach client drivers to ports when the flag is set. Fixes: 6fa45a226897 ("parport: add device-model to parport subsystem") Closes: https://bugs.debian.org/1130365 Closes: https://lore.kernel.org/all/6ba903ad-9897-42bb-8c2d-337385cc3746@molgen.mpg.de/ Cc: stable Signed-off-by: Ben Hutchings Acked-by: Sudip Mukherjee Link: https://patch.msgid.link/afo6uBv68GDevbMD@decadent.org.uk Signed-off-by: Greg Kroah-Hartman --- drivers/parport/share.c | 11 +++++++++-- include/linux/parport.h | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/parport/share.c b/drivers/parport/share.c index ba5292828703..eb0977ca1605 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -214,10 +214,14 @@ static void get_lowlevel_driver(void) static int port_check(struct device *dev, void *dev_drv) { struct parport_driver *drv = dev_drv; + struct parport *port; /* only send ports, do not send other devices connected to bus */ - if (is_parport(dev)) - drv->match_port(to_parport_dev(dev)); + if (is_parport(dev)) { + port = to_parport_dev(dev); + if (test_bit(PARPORT_ANNOUNCED, &port->devflags)) + drv->match_port(port); + } return 0; } @@ -532,6 +536,7 @@ void parport_announce_port(struct parport *port) if (slave) attach_driver_chain(slave); } + set_bit(PARPORT_ANNOUNCED, &port->devflags); mutex_unlock(®istration_lock); } EXPORT_SYMBOL(parport_announce_port); @@ -561,6 +566,8 @@ void parport_remove_port(struct parport *port) mutex_lock(®istration_lock); + clear_bit(PARPORT_ANNOUNCED, &port->devflags); + /* Spread the word. */ detach_driver_chain(port); diff --git a/include/linux/parport.h b/include/linux/parport.h index 464c2ad28039..f64cb0676e3b 100644 --- a/include/linux/parport.h +++ b/include/linux/parport.h @@ -240,6 +240,7 @@ struct parport { unsigned long devflags; #define PARPORT_DEVPROC_REGISTERED 0 +#define PARPORT_ANNOUNCED 1 struct pardevice *proc_device; /* Currently register proc device */ struct list_head full_list; From 2eae90a457baa0048a96ed38ad93090ee38c8b2f Mon Sep 17 00:00:00 2001 From: Hongling Zeng Date: Mon, 18 May 2026 10:29:39 +0800 Subject: [PATCH 39/41] gpib: cb7210: Fix region leak when request_irq fails When request_irq() fails, the region allocated by request_region() is not released. Fix this by adding an error handling path with proper goto labels to release the region. Fixes: e9dc69956d4d ("staging: gpib: Add Computer Boards GPIB driver") Closes: https://lore.kernel.org/oe-kbuild-all/202605160620.ReBOadPX-lkp@intel.com/ Signed-off-by: Hongling Zeng Cc: stable Link: https://patch.msgid.link/20260518022939.16881-1-zenghongling@kylinos.cn Signed-off-by: Greg Kroah-Hartman --- drivers/gpib/cb7210/cb7210.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpib/cb7210/cb7210.c b/drivers/gpib/cb7210/cb7210.c index 6dd8637c5964..673b5bfe2e7d 100644 --- a/drivers/gpib/cb7210/cb7210.c +++ b/drivers/gpib/cb7210/cb7210.c @@ -1049,7 +1049,8 @@ static int cb_isa_attach(struct gpib_board *board, const struct gpib_board_confi if (!request_region(config->ibbase, cb7210_iosize, DRV_NAME)) { dev_err(board->gpib_dev, "ioports starting at 0x%x are already in use\n", config->ibbase); - return -EBUSY; + retval = -EBUSY; + goto err_release_region; } nec_priv->iobase = config->ibbase; cb_priv->fifo_iobase = nec7210_iobase(cb_priv); @@ -1062,11 +1063,16 @@ static int cb_isa_attach(struct gpib_board *board, const struct gpib_board_confi // install interrupt handler if (request_irq(config->ibirq, cb7210_interrupt, isr_flags, DRV_NAME, board)) { dev_err(board->gpib_dev, "failed to obtain IRQ %d\n", config->ibirq); - return -EBUSY; + retval = -EBUSY; + goto err_release_region; } cb_priv->irq = config->ibirq; return cb7210_init(cb_priv, board); + +err_release_region: + release_region(nec7210_iobase(cb_priv), cb7210_iosize); + return retval; } static void cb_isa_detach(struct gpib_board *board) From 36770417153644bc88281c7284730ef1d14d8d3c Mon Sep 17 00:00:00 2001 From: Xiaolei Wang Date: Mon, 18 May 2026 15:34:05 +0800 Subject: [PATCH 40/41] misc: rp1: Send IACK on IRQ activate to fix kdump/kexec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After a kexec/kdump reboot, the macb Ethernet controller fails to receive any packets, causing DHCP to hang indefinitely and the network interface to be unusable despite link being up. The root cause is that RP1's level-triggered MSI-X interrupt sources (such as macb on hwirq 6) may have their internal state machines stuck in the "waiting for IACK" state. This happens because the previous kernel crashed before sending the acknowledgment for a pending level interrupt. In this stuck state, RP1 will not generate new MSI-X writes even though the interrupt source remains asserted. Since no new MSI-X is sent, the GIC never sees a new edge, the chained IRQ handler is never invoked, and the interrupt is permanently lost. Fix this by sending MSIX_CFG_IACK in rp1_irq_activate(). This unconditionally resets the MSI-X state machine back to idle when a child device requests its interrupt. If the interrupt source is still asserted, RP1 will immediately issue a new MSI-X with the freshly configured msg_addr/msg_data, and normal interrupt delivery resumes. Writing IACK when the state machine is already idle (i.e., on a normal cold boot) is harmless — it has no effect. Fixes: 49d63971f963 ("misc: rp1: RaspberryPi RP1 misc driver") Cc: stable Signed-off-by: Xiaolei Wang Link: https://patch.msgid.link/20260518073405.2115003-1-xiaolei.wang@windriver.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/rp1/rp1_pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/misc/rp1/rp1_pci.c b/drivers/misc/rp1/rp1_pci.c index d210da84c30a..81685e3f3296 100644 --- a/drivers/misc/rp1/rp1_pci.c +++ b/drivers/misc/rp1/rp1_pci.c @@ -143,6 +143,7 @@ static int rp1_irq_activate(struct irq_domain *d, struct irq_data *irqd, struct rp1_dev *rp1 = d->host_data; msix_cfg_set(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_ENABLE); + msix_cfg_set(rp1, (unsigned int)irqd->hwirq, MSIX_CFG_IACK); return 0; } From 05d5d79440c2cc0784f91b61f2012753e66be472 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 30 May 2026 12:25:36 +0200 Subject: [PATCH 41/41] Revert "gpib: cb7210: Fix region leak when request_irq fails" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 2eae90a457baa0048a96ed38ad93090ee38c8b2f. Turns out not to be correct. Link: https://lore.kernel.org/r/PpNUbGhrvT8I_KayoDvQYI2PYjmMw1QEkuVBDZz2PwBsVVgPkBXJarc2mBM0IhiH3AQG0GtgqEsDRXNj3yUKEDBaZa25u73pAjvcE6vfRsg=@protonmail.com Reported-by: Dominik Karol Piątkowski Cc: Mark Brown Cc: Hongling Zeng Cc: Hongling Zeng Signed-off-by: Greg Kroah-Hartman --- drivers/gpib/cb7210/cb7210.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/gpib/cb7210/cb7210.c b/drivers/gpib/cb7210/cb7210.c index 673b5bfe2e7d..6dd8637c5964 100644 --- a/drivers/gpib/cb7210/cb7210.c +++ b/drivers/gpib/cb7210/cb7210.c @@ -1049,8 +1049,7 @@ static int cb_isa_attach(struct gpib_board *board, const struct gpib_board_confi if (!request_region(config->ibbase, cb7210_iosize, DRV_NAME)) { dev_err(board->gpib_dev, "ioports starting at 0x%x are already in use\n", config->ibbase); - retval = -EBUSY; - goto err_release_region; + return -EBUSY; } nec_priv->iobase = config->ibbase; cb_priv->fifo_iobase = nec7210_iobase(cb_priv); @@ -1063,16 +1062,11 @@ static int cb_isa_attach(struct gpib_board *board, const struct gpib_board_confi // install interrupt handler if (request_irq(config->ibirq, cb7210_interrupt, isr_flags, DRV_NAME, board)) { dev_err(board->gpib_dev, "failed to obtain IRQ %d\n", config->ibirq); - retval = -EBUSY; - goto err_release_region; + return -EBUSY; } cb_priv->irq = config->ibirq; return cb7210_init(cb_priv, board); - -err_release_region: - release_region(nec7210_iobase(cb_priv), cb7210_iosize); - return retval; } static void cb_isa_detach(struct gpib_board *board)