diff mbox series

[RFC,03/10] clk: Avoid non needed runtime PM calls

Message ID 20250326-cross-lock-dep-v1-3-3199e49e8652@bootlin.com (mailing list archive)
State New
Headers show
Series Fix the ABBA locking situation between clk and runtime PM | expand

Commit Message

Miquel Raynal March 26, 2025, 6:26 p.m. UTC
clk_core_is_prepared() needs the clock to be runtime resumed in order to
call the ->is_prepared() callback. But at the same time, clk_prepare()
runtime resumes the clock and clk_unprepare() runtime disables it.

The fact that the clock might be runtime resumed do not indicate it's
been prepared, however the fact that it's been prepared implies that
it's been runtime resumed.

We can safely check the runtime status of the clock (and RPM increment
it in this case) instead of actually calling resume. With this little
trick, clk_core_is_prepared() can be called from anywhere without extra
constraint regarding the fact that the prepare_lock mutex might be
acquired or not already.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 drivers/clk/clk.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 7df9965bcbdffd641e6dbf5bff3d3b20079a3af3..1c15d72cd3daeeb5bb4f0d94c9f387526fab75ae 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -119,6 +119,20 @@  static int clk_pm_runtime_get(struct clk_core *core)
 	return pm_runtime_resume_and_get(core->dev);
 }
 
+static int clk_pm_runtime_get_if_active(struct clk_core *core)
+{
+	int ret;
+
+	if (!core || !core->rpm_enabled)
+		return 0;
+
+	ret = pm_runtime_get_if_active(core->dev);
+	if (ret == 1)
+		return 0;
+
+	return -EINVAL;
+}
+
 static void clk_pm_runtime_put(struct clk_core *core)
 {
 	if (!core->rpm_enabled)
@@ -295,7 +309,7 @@  static bool clk_core_is_prepared(struct clk_core *core)
 	if (!core->ops->is_prepared)
 		return core->prepare_count;
 
-	if (!clk_pm_runtime_get(core)) {
+	if (!clk_pm_runtime_get_if_active(core)) {
 		ret = core->ops->is_prepared(core->hw);
 		clk_pm_runtime_put(core);
 	}