[PATCH v5 09/13] gpio: mxc: use cleanup guard for pm_runtime_get_noresume() balance
From: Peng Fan (OSS)
Date: Fri Oct 09 2026 - 14:29:05 EST
From: Peng Fan <peng.fan@xxxxxxx>
pm_runtime_get_noresume() in probe must be balanced by
pm_runtime_put_noidle() on error paths, or pm_runtime_put_autosuspend()
on success. devm_pm_runtime_get_noresume() cannot be used here because
its devres action (pm_runtime_put_noidle()) would fire on unbind in
addition to the success-path pm_runtime_put_autosuspend(), causing a
usage counter underflow.
Use a __free guard to automatically call pm_runtime_put_noidle() on
error paths, and disarm it with no_free_ptr() before the success-path
pm_runtime_put_autosuspend().
Signed-off-by: Peng Fan <peng.fan@xxxxxxx>
---
drivers/gpio/gpio-mxc.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index 5ae9cdee6424..3d5a6566d3f4 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -445,6 +445,8 @@ static void mxc_update_irq_chained_handler(struct mxc_gpio_port *port, bool enab
}
}
+DEFINE_FREE(pm_runtime_put_noidle, struct device *, if (_T) pm_runtime_put_noidle(_T))
+
static int mxc_gpio_probe(struct platform_device *pdev)
{
struct gpio_generic_chip_config config = { };
@@ -486,6 +488,9 @@ static int mxc_gpio_probe(struct platform_device *pdev)
return PTR_ERR(port->clk);
pm_runtime_get_noresume(dev);
+
+ struct device *pm_guard __free(pm_runtime_put_noidle) = dev;
+
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
@@ -556,6 +561,8 @@ static int mxc_gpio_probe(struct platform_device *pdev)
mxc_update_irq_chained_handler(port, true);
platform_set_drvdata(pdev, port);
+
+ pm_guard = no_free_ptr(pm_guard);
pm_runtime_put_autosuspend(dev);
return 0;
@@ -564,7 +571,6 @@ static int mxc_gpio_probe(struct platform_device *pdev)
irq_domain_remove(port->domain);
out_bgio:
pm_runtime_disable(dev);
- pm_runtime_put_noidle(dev);
dev_info(dev, "%s failed with errno %d\n", __func__, err);
return err;
}
--
2.51.0