From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 819EE34751B; Tue, 16 Jun 2026 19:10:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781637024; cv=none; b=ZNXfexRtKW5DUv/O/ANvzKbS1xTixuMAiiKXgKeY+FkSTS1zzLidN+0w2rdpRC+lZnAhPolHi/7fqx3dTFeWf3dz19NJCozbei8h97ATr8SLCekcVHBsVaJCNkTQVwXy+9wKIoJsSBZ+e7aIMQRPoPJDs1kKS6IlBtz5Bf8Blxc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781637024; c=relaxed/simple; bh=mMbkWyM9eS4cr9qejCTvonZIoT8UWJbRBjzDEE0Ntag=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mGAaj4GRnn74hP/SP6D9+Ck/iiAGyL1n1iYHVjkq+WhniMGPzKz/Psh8TaZ5z86omNqxGbD+iZ28EF2nXT8CVgY2SWimXcks+vF9MRISh38Hkm5Ge7WVqwRrXRcNxwTpydPdKtHK3wA/5wRjRR79NOkWXSD4ng5kdJfwGCEktzI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=wckrU+tp; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="wckrU+tp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1B1BE1F00A3A; Tue, 16 Jun 2026 19:10:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1781637023; bh=0Zag5D9tJgoasGYtIWPQgepxbGs890VDC95iWsiQsTk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=wckrU+tpEC1CvSW8y+JFl2DUXzamWvJ+gbugI+DWRm3U0OIkAyb6j81pXWwMmCeDu i8+Mol7SezF3lgLd2kHdp0zrsh33xvjaqv/cqfTDUrg0egr3Af4MJlCCA4SE3mSzf6 DcZblrFp/FxXGaNV1jqb5EAF9XGsesSamuwwSTC8= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, David Carlier , Andy Shevchenko , Stable@vger.kernel.org, Jonathan Cameron , Sasha Levin Subject: [PATCH 5.10 319/342] iio: adc: npcm: fix unbalanced clk_disable_unprepare() Date: Tue, 16 Jun 2026 20:30:15 +0530 Message-ID: <20260616145103.405506972@linuxfoundation.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260616145048.348037099@linuxfoundation.org> References: <20260616145048.348037099@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: David Carlier [ 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. Fixes: 9bf85fbc9d8f ("iio: adc: add NPCM ADC driver") Signed-off-by: David Carlier Reviewed-by: Andy Shevchenko Cc: Signed-off-by: Jonathan Cameron Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/iio/adc/npcm_adc.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) --- a/drivers/iio/adc/npcm_adc.c +++ b/drivers/iio/adc/npcm_adc.c @@ -180,7 +180,6 @@ static int npcm_adc_probe(struct platfor u32 reg_con; struct npcm_adc *info; struct iio_dev *indio_dev; - struct device *dev = &pdev->dev; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); if (!indio_dev) @@ -197,7 +196,7 @@ static int npcm_adc_probe(struct platfor 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); @@ -210,17 +209,13 @@ static int npcm_adc_probe(struct platfor info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2); irq = platform_get_irq(pdev, 0); - if (irq <= 0) { - ret = -EINVAL; - goto err_disable_clk; - } + if (irq <= 0) + return -EINVAL; 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"); @@ -228,7 +223,7 @@ static int npcm_adc_probe(struct platfor 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, @@ -238,10 +233,8 @@ static int npcm_adc_probe(struct platfor * 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, @@ -280,8 +273,6 @@ err_iio_register: 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; } @@ -298,7 +289,6 @@ static int npcm_adc_remove(struct platfo 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); return 0; }