[PATCH v2] gpio: omap: handle debounce clock preparation failure
From: Jiawen Liu
Date: Mon Nov 09 2026 - 09:02:58 EST
omap_gpio_probe() ignores the return value of clk_prepare() for the
debounce clock. If preparation fails, the driver still treats debounce as
available and may use or unprepare a clock that was not prepared.
Use devm_clk_get_prepared() and disable debounce if the clock cannot be
obtained or prepared. This keeps the existing behavior for clock lookup
failures. Remove both manual clk_unprepare() calls because the managed
clock is released on probe failure and device removal.
An earlier managed-clock conversion was dropped after a reported boot
failure. A follow-up removing the two manual unprepare calls was reported
to restore boot. This change also removes those calls.
Built gpio-omap.o with ARM multi_v7_defconfig and Clang 19; the current
patch has not been tested on OMAP hardware.
The original report was generated using BMC-Agent; source review and
maintainer feedback informed this revision.
Fixes: 5d9452e7c52a ("gpio: omap: fix clk_prepare/unprepare usage")
Suggested-by: Andreas Kemnade <andreas@xxxxxxxxxxxx>
Link: https://lore.kernel.org/r/tencent_B4F504456790E8BA3C4EAB80F4BFB6954E08@xxxxxx
Link: https://lkml.rescloud.iu.edu/hypermail/linux/kernel/2412.2/00414.html
Signed-off-by: Jiawen Liu <1298662399@xxxxxx>
---
Changes in v2:
- Use devm_clk_get_prepared() and remove both manual unprepare calls.
- Disable debounce on prepare failure, retaining clock-get failure behavior.
- Add the Fixes tag and describe the earlier managed-clock attempt.
Built with ARCH=arm, LLVM=-19, multi_v7_defconfig, W=1 and
CONFIG_GPIO_OMAP=y. No OMAP hardware test or current reproducer is available.
drivers/gpio/gpio-omap.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index a9734b2a1..314bbb48e 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1446,13 +1446,11 @@ static int omap_gpio_probe(struct platform_device *pdev)
}
if (bank->dbck_flag) {
- bank->dbck = devm_clk_get(dev, "dbclk");
+ bank->dbck = devm_clk_get_prepared(dev, "dbclk");
if (IS_ERR(bank->dbck)) {
dev_err(dev,
- "Could not get gpio dbck. Disable debounce\n");
+ "Could not get or prepare gpio dbck. Disable debounce\n");
bank->dbck_flag = false;
- } else {
- clk_prepare(bank->dbck);
}
}
@@ -1470,8 +1468,6 @@ static int omap_gpio_probe(struct platform_device *pdev)
if (ret) {
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
- if (bank->dbck_flag)
- clk_unprepare(bank->dbck);
return ret;
}
@@ -1492,8 +1488,6 @@ static void omap_gpio_remove(struct platform_device *pdev)
cpu_pm_unregister_notifier(&bank->nb);
gpiochip_remove(&bank->chip);
pm_runtime_disable(&pdev->dev);
- if (bank->dbck_flag)
- clk_unprepare(bank->dbck);
}
static int omap_gpio_runtime_suspend(struct device *dev)
--
2.34.1