From: David Carlier <devnexen@gmail.com>
To: Jonathan Cameron <jic23@kernel.org>
Cc: "Tomer Maimon" <tmaimon77@gmail.com>,
"Avi Fishman" <avifishman70@gmail.com>,
"Tali Perry" <tali.perry1@gmail.com>,
"Andrew Jeffery" <andrew@codeconstruct.com.au>,
"Patrick Venture" <venture@google.com>,
"Nancy Yuen" <yuenn@google.com>,
"Benjamin Fair" <benjaminfair@google.com>,
"David Lechner" <dlechner@baylibre.com>,
"Nuno Sá" <nuno.sa@analog.com>,
"Andy Shevchenko" <andy@kernel.org>,
linux-iio@vger.kernel.org, openbmc@lists.ozlabs.org,
linux-kernel@vger.kernel.org,
"David Carlier" <devnexen@gmail.com>
Subject: [PATCH] iio: adc: npcm: fix unbalanced clk_disable_unprepare()
Date: Sat, 11 Apr 2026 13:35:17 +0100 [thread overview]
Message-ID: <20260411123517.15083-1-devnexen@gmail.com> (raw)
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().
Fixes: 9bf85fbc9d8f ("iio: adc: add NPCM ADC driver")
Signed-off-by: David Carlier <devnexen@gmail.com>
---
drivers/iio/adc/npcm_adc.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/iio/adc/npcm_adc.c b/drivers/iio/adc/npcm_adc.c
index ddabb9600d46..6acafef3e7c7 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,16 +244,14 @@ 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;
+ return ret;
}
reg_con = ioread32(info->regs + NPCM_ADCCON);
@@ -262,7 +260,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,
@@ -274,7 +272,7 @@ static int npcm_adc_probe(struct platform_device *pdev)
*/
if (PTR_ERR(info->vref) != -ENODEV) {
ret = PTR_ERR(info->vref);
- goto err_disable_clk;
+ return ret;
}
/* Use internal reference */
@@ -314,8 +312,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 +328,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 = {
--
2.53.0
next reply other threads:[~2026-04-11 12:35 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-11 12:35 David Carlier [this message]
2026-04-11 12:46 ` [PATCH] iio: adc: npcm: fix unbalanced clk_disable_unprepare() Nuno Sá
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260411123517.15083-1-devnexen@gmail.com \
--to=devnexen@gmail.com \
--cc=andrew@codeconstruct.com.au \
--cc=andy@kernel.org \
--cc=avifishman70@gmail.com \
--cc=benjaminfair@google.com \
--cc=dlechner@baylibre.com \
--cc=jic23@kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nuno.sa@analog.com \
--cc=openbmc@lists.ozlabs.org \
--cc=tali.perry1@gmail.com \
--cc=tmaimon77@gmail.com \
--cc=venture@google.com \
--cc=yuenn@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox