summaryrefslogtreecommitdiff
path: root/drivers/iio/adc
diff options
context:
space:
mode:
authorStepan Ionichev <sozdayvek@gmail.com>2026-05-21 00:09:24 +0500
committerJonathan Cameron <jic23@kernel.org>2026-05-26 19:22:57 +0100
commit929fec2964f71d4b1ac664ee963d8226c5cf01c6 (patch)
treeee1962181d660121e01d6ce06a03114014c511d5 /drivers/iio/adc
parent744bccc2647c6b2206290e8e40890a23812116b3 (diff)
downloadlinux-next-929fec2964f71d4b1ac664ee963d8226c5cf01c6.tar.gz
linux-next-929fec2964f71d4b1ac664ee963d8226c5cf01c6.zip
iio: adc: qcom-spmi-iadc: balance enable_irq_wake() on driver unbind
iadc_probe() calls enable_irq_wake() after a successful devm_request_irq(), but the driver has no remove callback or matching disable_irq_wake(), so the wake reference count on the IRQ is leaked on module unload or driver unbind. Check the IRQ request error first, then register a devm action that calls disable_irq_wake() so the wake reference is released in the same scope as the enable. While here, drop the inverted "if (!ret) ... else return ret" in favour of the standard "if (ret) return ret;" pattern. Signed-off-by: Stepan Ionichev <sozdayvek@gmail.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/adc')
-rw-r--r--drivers/iio/adc/qcom-spmi-iadc.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/iio/adc/qcom-spmi-iadc.c b/drivers/iio/adc/qcom-spmi-iadc.c
index b64a8a407168..0ec3a0c4b1de 100644
--- a/drivers/iio/adc/qcom-spmi-iadc.c
+++ b/drivers/iio/adc/qcom-spmi-iadc.c
@@ -481,6 +481,11 @@ static const struct iio_chan_spec iadc_channels[] = {
},
};
+static void iadc_disable_irq_wake(void *data)
+{
+ disable_irq_wake((unsigned long)data);
+}
+
static int iadc_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
@@ -538,9 +543,16 @@ static int iadc_probe(struct platform_device *pdev)
if (!iadc->poll_eoc) {
ret = devm_request_irq(dev, irq_eoc, iadc_isr, 0,
"spmi-iadc", iadc);
- if (!ret)
- enable_irq_wake(irq_eoc);
- else
+ if (ret)
+ return ret;
+
+ ret = enable_irq_wake(irq_eoc);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(dev, iadc_disable_irq_wake,
+ (void *)(unsigned long)irq_eoc);
+ if (ret)
return ret;
} else {
ret = devm_device_init_wakeup(iadc->dev);