FAILED: patch "[PATCH] iio: adc: npcm: fix unbalanced clk_disable_unprepare()" failed to apply to 5.15-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026060419-driver-wreath-7a8d@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c Mon Sep 17 00:00:00 2001
From: David Carlier <[email protected]>
Date: Tue, 14 Apr 2026 13:30:06 +0100
Subject: [PATCH] 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.
drivers/iio/adc/npcm_adc.c +8 -17
@@ -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 = {
Sasha Levin
maintainerPATCH 1/3 iio: adc: fix the return value handle for platform_get_irq()
From: Ruan Jinjie <[email protected]>
[ Upstream commit c09ddcdd4dd32ee9768dc233ead4b3d726f26d38 ]
There is no possible for platform_get_irq() to return 0 and the return value of platform_get_irq() is more sensible to show the error reason.
Stable-dep-of: 0d42e2c0bd6c ("iio: adc: npcm: fix unbalanced clk_disable_unprepare()")
--- drivers/iio/adc/bcm_iproc_adc.c | 4 ++-- drivers/iio/adc/lpc32xx_adc.c | 4 ++-- drivers/iio/adc/npcm_adc.c | 4 ++-- drivers/iio/adc/spear_adc.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-)
drivers/iio/adc/bcm_iproc_adc.c +2 -2
@@ -540,8 +540,8 @@ static int iproc_adc_probe(struct platform_device *pdev) } adc_priv->irqno =platform_get_irq (pdev,0 ); -if (adc_priv->irqno <=0 ) -return -ENODEV ; +if (adc_priv->irqno <0 ) +return adc_priv->irqno; ret =regmap_update_bits (adc_priv->regmap,IPROC_REGCTL2 ,IPROC_ADC_AUXIN_SCAN_ENA ,0 );
drivers/iio/adc/lpc32xx_adc.c +2 -2
@@ -173,8 +173,8 @@ static int lpc32xx_adc_probe(struct platform_device *pdev) } irq =platform_get_irq (pdev,0 ); -if (irq <=0 ) -return -ENXIO ; +if (irq <0 ) +return irq; retval =devm_request_irq (&pdev->dev, irq, lpc32xx_adc_isr,0 ,LPC32XXAD_NAME , st);
drivers/iio/adc/npcm_adc.c +2 -2
@@ -221,8 +221,8 @@ 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 = -EINVAL ; +if (irq <0 ) { + ret = irq; goto err_disable_clk; }
drivers/iio/adc/spear_adc.c +2 -2
@@ -311,8 +311,8 @@ static int spear_adc_probe(struct platform_device *pdev) } irq =platform_get_irq (pdev,0 ); -if (irq <=0 ) { - ret = -EINVAL ; +if (irq <0 ) { + ret = irq; goto errout2; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/3 iio: adc: npcm: Convert to platform remove callback returning void
From: Uwe Kleine-König <[email protected]>
[ Upstream commit 5253a5cc7709688b9a000f7928bfaa3366d0af98 ]
The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks. To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new() which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove().
Trivially convert this driver from always returning zero in the remove callback to the void returning variant.
Stable-dep-of: 0d42e2c0bd6c ("iio: adc: npcm: fix unbalanced clk_disable_unprepare()")
--- drivers/iio/adc/npcm_adc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/iio/adc/npcm_adc.c +2 -4
@@ -297,7 +297,7 @@ static int npcm_adc_probe(struct platform_device *pdev)return ret; } -static int npcm_adc_remove (struct platform_device *pdev) +static void npcm_adc_remove (struct platform_device *pdev) {struct iio_dev *indio_dev =platform_get_drvdata (pdev);struct npcm_adc *info =iio_priv (indio_dev);
@@ -310,13 +310,11 @@ static int npcm_adc_remove(struct platform_device *pdev)if (!IS_ERR (info->vref))regulator_disable (info->vref);clk_disable_unprepare (info->adc_clk); - -return 0 ; }static struct platform_driver npcm_adc_driver = { .probe = npcm_adc_probe, - .remove = npcm_adc_remove, + .remove_new = npcm_adc_remove, .driver = { .name ="npcm_adc" , .of_match_table = npcm_adc_match,
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/3 iio: adc: npcm: fix unbalanced clk_disable_unprepare()
In reply to Sasha LevinFrom: David Carlier <[email protected]>
[ Upstream commit 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c ]
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.
--- drivers/iio/adc/npcm_adc.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-)
drivers/iio/adc/npcm_adc.c +8 -17
@@ -208,7 +208,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);
@@ -221,17 +221,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" );
@@ -239,7 +235,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,
@@ -249,10 +245,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,
@@ -291,8 +285,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; }
@@ -309,7 +301,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 = {
Signature · 1 line
2.53.0