public inbox for drm-ai-reviews@public-inbox.freedesktop.org
 help / color / mirror / Atom feed
* [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm]
@ 2026-05-27  9:48 Hans de Goede
  2026-05-27  9:48 ` [PATCH 1/3] clk: Add __clk_disable_unprepare_counts_only() helper Hans de Goede
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Hans de Goede @ 2026-05-27  9:48 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Thomas Zimmermann,
	Javier Martinez Canillas
  Cc: Hans de Goede, Maarten Lankhorst, Maxime Ripard, Helge Deller,
	Bjorn Andersson, Konrad Dybcio, Dmitry Baryshkov, Rob Clark,
	linux-clk, dri-devel, ~postmarketos/upstreaming

Hi Michael, Stephen, et al.,

The device-tree simple-framebuffer device is special in that it does not
describe actual hardware, but it allows firmware (e.g. u-boot) to pass a
firmware initialized framebuffer to the OS to use as display during boot.

To avoid clocks used by the firmware framebuffer getting touched while in
use, the DT node contains a list of clocks which should not be touched
while the simple-framebuffer is in use.

Conceptually this is fine, in practice the *do not touch* is implemented as
a clk_prepare_enable() + clk_disable_unprepare() pair, with the disabling
happening when the simple-framebuffer driver gets replaced by the real
display-engine driver.

The simple-framebuffer concept assumes that the order in which resources
are acquired does not matter since they are already on, so power-sequencing
is not an issue. But clk_disable_unprepare() actually turns the clock off,
messing with the hardware state before the real display driver loads,
without any knowledge of the proper power-off sequence for the display.

The turning off of the clocks outside of a proper power-off sequence causes
the following error when the msm display driver tries to re-enable them:

[    2.980181] disp_cc_mdss_dptx3_pixel0_clk_src: rcg didn't update its configuration.
[    2.980272] WARNING: drivers/clk/qcom/clk-rcg2.c:136 at update_config+0xdc/0x100

Resulting in a non working display.

To fix this, we need a way to properly implement the "do not touch" concept
for clocks. clk_prepare_enable() is fine, the clocks are already on so no
ordering worries and it ensures that the clocks and their parents cannot
get turned off by incrementing their enable, prepare and protect counts.

clk_disable_unprepare() is a problem though since it actually turns the
clocks off. Instead something is needed which only decrements those counts.

This series introduces a new clk-core function called
__clk_disable_unprepare_counts_only() (1) which does just that. Prefixed
with '__' to indicate that normally drivers should not use this.

Michael, Stephen sorry for needing to add a new clk-core function for this,
but I see no other way of solving this (2)(3). The changes are not that
big / not too bad.

I've also considered making __clk_disable_unprepare_counts_only() implement
all the logic itself instead of adding the extra parameter to
clk_core_unprepare() and clk_core_disable() but that leads in duplicating
quite a bit of logic (4) so this seems better.

The other 2 patches just replace the clk_disable_unprepare() calls in
the simple[fb|drm] driver with the new helper.

This series fixes the display not coming up after switching to the msm
driver when a simple-framebuffer node with clocks listed is used.

Regards,

Hans


1) I'm open to changing the name, this is the best I could come up with.

2) One option considered was detaching the simple-framebuffer driver later,
   after the real display driver has had a chance to claim the clocks. But
   this won't work in cases where the real display driver picks different
   parent clocks then the boot firmware did and needs to reparent clocks.

   Basically the goal is for things to behave as if the simple-framebuffer
   driver was not there at all, because that leaves the hw in the state
   the real display driver expects.

3) There is precedence for something like this in other places in the
   kernel, e.g. pm_runtime_put_noidle() and the power_off parameter
   to dev_pm_domain_detach()

4) With the risk of the 2 copies of that logic diverging over time.



Hans de Goede (3):
  clk: Add __clk_disable_unprepare_counts_only() helper
  drm/sysfb: simpledrm: Use __clk_disable_unprepare_counts_only()
  fbdev: simplefb: Use __clk_disable_unprepare_counts_only()

 drivers/clk/clk.c                 | 41 ++++++++++++++++++++++---------
 drivers/gpu/drm/sysfb/simpledrm.c |  4 +--
 drivers/video/fbdev/simplefb.c    |  2 +-
 include/linux/clk.h               | 14 +++++++++++
 4 files changed, 46 insertions(+), 15 deletions(-)

-- 
2.54.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/3] clk: Add __clk_disable_unprepare_counts_only() helper
  2026-05-27  9:48 [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Hans de Goede
@ 2026-05-27  9:48 ` Hans de Goede
  2026-05-28  2:34   ` Claude review: " Claude Code Review Bot
  2026-05-27  9:48 ` [PATCH 2/3] drm/sysfb: simpledrm: Use __clk_disable_unprepare_counts_only() Hans de Goede
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Hans de Goede @ 2026-05-27  9:48 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Thomas Zimmermann,
	Javier Martinez Canillas
  Cc: Hans de Goede, Maarten Lankhorst, Maxime Ripard, Helge Deller,
	Bjorn Andersson, Konrad Dybcio, Dmitry Baryshkov, Rob Clark,
	linux-clk, dri-devel, ~postmarketos/upstreaming

The device-tree simple-framebuffer device is special in that it does not
describe actual hardware, but it allows firmware (e.g. u-boot) to pass a
firmware initialized framebuffer to the OS to use as display during boot.

To avoid clocks used by the firmware framebuffer getting touched while in
use, the DT node contains a list of clocks and the simpledrm driver calls
clk_prepare_enable() on these clocks. When the real display driver loads
simpledrm gets unbound and calls clk_disable_unprepare().

The simple-framebuffer concept assumes that the order in which resources
are acquired does not matter since they are already on, so power-sequencing
is not an issue. But clk_disable_unprepare() actually turns the clock off,
messing with the hardware state before the real display driver loads,
without any knowledge of the proper power-off sequence for the display.

Sometimes this leaves the hardware in an undefined state e.g. on some
Qualcomm platforms turning off the DP clocks at simpledrm remove() results
in the following error when the msm display driver tries to re-enable them:

[    2.980181] disp_cc_mdss_dptx3_pixel0_clk_src: rcg didn't update its configuration.
[    2.980272] WARNING: drivers/clk/qcom/clk-rcg2.c:136 at update_config+0xdc/0x100

Clocks from the simple-framebuffer DT node are not so much clocks which
the simpledrm driver should take full control of, but rather are clocks
which should not be touched as long as the firmware framebuffer is in use.
This includes not turning them off before handing over control to the real
display driver.

Add a new __clk_disable_unprepare_counts_only() helper which decrements the
enable, prepare and protect counts of the clock and its parents, so that
the real display can take control over the clocks, but which does not
actually disable any clocks.

Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
---
 drivers/clk/clk.c   | 41 +++++++++++++++++++++++++++++------------
 include/linux/clk.h | 14 ++++++++++++++
 2 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 47093cda9df3..8c92d3551556 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1037,7 +1037,7 @@ int devm_clk_rate_exclusive_get(struct device *dev, struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(devm_clk_rate_exclusive_get);
 
-static void clk_core_unprepare(struct clk_core *core)
+static void clk_core_unprepare(struct clk_core *core, bool call_unprepare_op)
 {
 	lockdep_assert_held(&prepare_lock);
 
@@ -1062,18 +1062,18 @@ static void clk_core_unprepare(struct clk_core *core)
 
 	trace_clk_unprepare(core);
 
-	if (core->ops->unprepare)
+	if (call_unprepare_op && core->ops->unprepare)
 		core->ops->unprepare(core->hw);
 
 	trace_clk_unprepare_complete(core);
-	clk_core_unprepare(core->parent);
+	clk_core_unprepare(core->parent, call_unprepare_op);
 	clk_pm_runtime_put(core);
 }
 
 static void clk_core_unprepare_lock(struct clk_core *core)
 {
 	clk_prepare_lock();
-	clk_core_unprepare(core);
+	clk_core_unprepare(core, true);
 	clk_prepare_unlock();
 }
 
@@ -1140,7 +1140,7 @@ static int clk_core_prepare(struct clk_core *core)
 
 	return 0;
 unprepare:
-	clk_core_unprepare(core->parent);
+	clk_core_unprepare(core->parent, true);
 runtime_put:
 	clk_pm_runtime_put(core);
 	return ret;
@@ -1178,7 +1178,7 @@ int clk_prepare(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(clk_prepare);
 
-static void clk_core_disable(struct clk_core *core)
+static void clk_core_disable(struct clk_core *core, bool call_disable_op)
 {
 	lockdep_assert_held(&enable_lock);
 
@@ -1197,12 +1197,12 @@ static void clk_core_disable(struct clk_core *core)
 
 	trace_clk_disable(core);
 
-	if (core->ops->disable)
+	if (call_disable_op && core->ops->disable)
 		core->ops->disable(core->hw);
 
 	trace_clk_disable_complete(core);
 
-	clk_core_disable(core->parent);
+	clk_core_disable(core->parent, call_disable_op);
 }
 
 static void clk_core_disable_lock(struct clk_core *core)
@@ -1210,7 +1210,7 @@ static void clk_core_disable_lock(struct clk_core *core)
 	unsigned long flags;
 
 	flags = clk_enable_lock();
-	clk_core_disable(core);
+	clk_core_disable(core, true);
 	clk_enable_unlock(flags);
 }
 
@@ -1235,6 +1235,23 @@ void clk_disable(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(clk_disable);
 
+void __clk_disable_unprepare_counts_only(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (IS_ERR_OR_NULL(clk))
+		return;
+
+	flags = clk_enable_lock();
+	clk_core_disable(clk->core, false);
+	clk_enable_unlock(flags);
+
+	clk_prepare_lock();
+	clk_core_unprepare(clk->core, false);
+	clk_prepare_unlock();
+}
+EXPORT_SYMBOL_GPL(__clk_disable_unprepare_counts_only);
+
 static int clk_core_enable(struct clk_core *core)
 {
 	int ret = 0;
@@ -1262,7 +1279,7 @@ static int clk_core_enable(struct clk_core *core)
 		trace_clk_enable_complete(core);
 
 		if (ret) {
-			clk_core_disable(core->parent);
+			clk_core_disable(core->parent, true);
 			return ret;
 		}
 	}
@@ -2451,7 +2468,7 @@ static void clk_change_rate(struct clk_core *core)
 
 	if (core->flags & CLK_SET_RATE_UNGATE) {
 		clk_core_disable_lock(core);
-		clk_core_unprepare(core);
+		clk_core_unprepare(core, true);
 	}
 
 	if (core->flags & CLK_OPS_PARENT_ENABLE)
@@ -4063,7 +4080,7 @@ static int __clk_core_init(struct clk_core *core)
 		if (ret) {
 			pr_warn("%s: critical clk '%s' failed to enable\n",
 			       __func__, core->name);
-			clk_core_unprepare(core);
+			clk_core_unprepare(core, true);
 			goto out;
 		}
 	}
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 998ba3f261da..7dee0dbb9018 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -783,6 +783,19 @@ void clk_disable(struct clk *clk);
  */
 void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks);
 
+/**
+ * __clk_disable_unprepare_counts_only - Decrement enable and prepare counts
+ *
+ * Like clk_disable_unprepare() but then only decrement the enable, prepare and
+ * protect counts of the clock and its parents without actually disabling any
+ * clocks.
+ *
+ * This function should only be used in special case where the clocks should
+ * stay on while handing control over from an early-boot driver like simpledrm
+ * to a later more featureful driver. When in doubt do NOT use this function.
+ */
+void __clk_disable_unprepare_counts_only(struct clk *clk);
+
 /**
  * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
  *		  This is only valid once the clock source has been enabled.
@@ -1099,6 +1112,7 @@ static inline int __must_check clk_bulk_enable(int num_clks,
 
 static inline void clk_disable(struct clk *clk) {}
 
+static inline void __clk_disable_unprepare_counts_only(struct clk *clk) {}
 
 static inline void clk_bulk_disable(int num_clks,
 				    const struct clk_bulk_data *clks) {}
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/3] drm/sysfb: simpledrm: Use __clk_disable_unprepare_counts_only()
  2026-05-27  9:48 [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Hans de Goede
  2026-05-27  9:48 ` [PATCH 1/3] clk: Add __clk_disable_unprepare_counts_only() helper Hans de Goede
@ 2026-05-27  9:48 ` Hans de Goede
  2026-05-28  2:34   ` Claude review: " Claude Code Review Bot
  2026-05-27  9:48 ` [PATCH 3/3] fbdev: simplefb: " Hans de Goede
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Hans de Goede @ 2026-05-27  9:48 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Thomas Zimmermann,
	Javier Martinez Canillas
  Cc: Hans de Goede, Maarten Lankhorst, Maxime Ripard, Helge Deller,
	Bjorn Andersson, Konrad Dybcio, Dmitry Baryshkov, Rob Clark,
	linux-clk, dri-devel, ~postmarketos/upstreaming

simpledrm_device_init_clocks() calls clk_prepare_enable() to avoid clocks
used by the framebuffer getting turned off while in use.

simpledrm_device_release_clocks() then must call clk_disable_unprepare()
to balance the enable count. clk_disable_unprepare() actually turns the
clock off, messing with the hardware state before the real display driver
loads, without any knowledge of the proper display power-off sequence.

Sometimes this leaves the hardware in an undefined state e.g. on some
Qualcomm platforms turning off the DP clocks at simpledrm remove() results
in the following error when the msm display driver tries to re-enable them:

[    2.980181] disp_cc_mdss_dptx3_pixel0_clk_src: rcg didn't update its configuration.
[    2.980272] WARNING: drivers/clk/qcom/clk-rcg2.c:136 at update_config+0xdc/0x100

Switch to using the new __clk_disable_unprepare_counts_only() function,
which decrements the counts without actually turning off the clocks.

Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
---
 drivers/gpu/drm/sysfb/simpledrm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/sysfb/simpledrm.c b/drivers/gpu/drm/sysfb/simpledrm.c
index 7a95d2dacd9d..6927a32ed282 100644
--- a/drivers/gpu/drm/sysfb/simpledrm.c
+++ b/drivers/gpu/drm/sysfb/simpledrm.c
@@ -261,7 +261,7 @@ static void simpledrm_device_release_clocks(void *res)
 
 	for (i = 0; i < sdev->clk_count; ++i) {
 		if (sdev->clks[i]) {
-			clk_disable_unprepare(sdev->clks[i]);
+			__clk_disable_unprepare_counts_only(sdev->clks[i]);
 			clk_put(sdev->clks[i]);
 		}
 	}
@@ -315,7 +315,7 @@ static int simpledrm_device_init_clocks(struct simpledrm_device *sdev)
 	while (i) {
 		--i;
 		if (sdev->clks[i]) {
-			clk_disable_unprepare(sdev->clks[i]);
+			__clk_disable_unprepare_counts_only(sdev->clks[i]);
 			clk_put(sdev->clks[i]);
 		}
 	}
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/3] fbdev: simplefb: Use __clk_disable_unprepare_counts_only()
  2026-05-27  9:48 [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Hans de Goede
  2026-05-27  9:48 ` [PATCH 1/3] clk: Add __clk_disable_unprepare_counts_only() helper Hans de Goede
  2026-05-27  9:48 ` [PATCH 2/3] drm/sysfb: simpledrm: Use __clk_disable_unprepare_counts_only() Hans de Goede
@ 2026-05-27  9:48 ` Hans de Goede
  2026-05-28  2:34   ` Claude review: " Claude Code Review Bot
  2026-05-27 12:04 ` [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Maxime Ripard
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Hans de Goede @ 2026-05-27  9:48 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Thomas Zimmermann,
	Javier Martinez Canillas
  Cc: Hans de Goede, Maarten Lankhorst, Maxime Ripard, Helge Deller,
	Bjorn Andersson, Konrad Dybcio, Dmitry Baryshkov, Rob Clark,
	linux-clk, dri-devel, ~postmarketos/upstreaming

simplefb_clocks_enable() calls clk_prepare_enable() to avoid clocks used by
the framebuffer getting turned off while in use.

This requires simplefb_clocks_destroy() calling clk_disable_unprepare() to
balance the enable count. clk_disable_unprepare() actually turns the clock
off, messing with the hardware state before the real display driver loads,
without any knowledge of the proper display power-off sequence.

Sometimes this leaves the hardware in an undefined state e.g. on some
Qualcomm platforms turning off the DP clocks at simplefb_destroy() results
in the following error when the msm display driver tries to re-enable them:

[    2.980181] disp_cc_mdss_dptx3_pixel0_clk_src: rcg didn't update its configuration.
[    2.980272] WARNING: drivers/clk/qcom/clk-rcg2.c:136 at update_config+0xdc/0x100

Resulting in a non work display output.

Switch to using the new __clk_disable_unprepare_counts_only() function,
which decrements the counts without actually turning off the clocks.

Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
---
 drivers/video/fbdev/simplefb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index 60e5dcec201f..b1e0dba6d127 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -303,7 +303,7 @@ static void simplefb_clocks_destroy(struct simplefb_par *par)
 	for (i = 0; i < par->clk_count; i++) {
 		if (par->clks[i]) {
 			if (par->clks_enabled)
-				clk_disable_unprepare(par->clks[i]);
+				__clk_disable_unprepare_counts_only(par->clks[i]);
 			clk_put(par->clks[i]);
 		}
 	}
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm]
  2026-05-27  9:48 [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Hans de Goede
                   ` (2 preceding siblings ...)
  2026-05-27  9:48 ` [PATCH 3/3] fbdev: simplefb: " Hans de Goede
@ 2026-05-27 12:04 ` Maxime Ripard
  2026-05-27 12:21   ` Hans de Goede
  2026-05-27 23:03 ` Brian Masney
  2026-05-28  2:34 ` Claude review: " Claude Code Review Bot
  5 siblings, 1 reply; 13+ messages in thread
From: Maxime Ripard @ 2026-05-27 12:04 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Michael Turquette, Stephen Boyd, Thomas Zimmermann,
	Javier Martinez Canillas, Maarten Lankhorst, Helge Deller,
	Bjorn Andersson, Konrad Dybcio, Dmitry Baryshkov, Rob Clark,
	linux-clk, dri-devel, ~postmarketos/upstreaming

[-- Attachment #1: Type: text/plain, Size: 4852 bytes --]

Hi Hans,

On Wed, May 27, 2026 at 11:48:08AM +0200, Hans de Goede wrote:
> Hi Michael, Stephen, et al.,
> 
> The device-tree simple-framebuffer device is special in that it does not
> describe actual hardware, but it allows firmware (e.g. u-boot) to pass a
> firmware initialized framebuffer to the OS to use as display during boot.
> 
> To avoid clocks used by the firmware framebuffer getting touched while in
> use, the DT node contains a list of clocks which should not be touched
> while the simple-framebuffer is in use.
> 
> Conceptually this is fine, in practice the *do not touch* is implemented as
> a clk_prepare_enable() + clk_disable_unprepare() pair, with the disabling
> happening when the simple-framebuffer driver gets replaced by the real
> display-engine driver.

Which is also pretty fragile because it doesn't lock the rate either.

> The simple-framebuffer concept assumes that the order in which resources
> are acquired does not matter since they are already on, so power-sequencing
> is not an issue. But clk_disable_unprepare() actually turns the clock off,
> messing with the hardware state before the real display driver loads,
> without any knowledge of the proper power-off sequence for the display.
> 
> The turning off of the clocks outside of a proper power-off sequence causes
> the following error when the msm display driver tries to re-enable them:
> 
> [    2.980181] disp_cc_mdss_dptx3_pixel0_clk_src: rcg didn't update its configuration.
> [    2.980272] WARNING: drivers/clk/qcom/clk-rcg2.c:136 at update_config+0xdc/0x100
> 
> Resulting in a non working display.
> 
> To fix this, we need a way to properly implement the "do not touch" concept
> for clocks.

I'm not sure it's something we can enforce, really. The firmware can
modify clocks behind our back. Other clocks might change this one as a
side-effect of a rate change or reparenting, etc. It's just not
something we can commit to.

> clk_prepare_enable() is fine, the clocks are already on so no
> ordering worries and it ensures that the clocks and their parents cannot
> get turned off by incrementing their enable, prepare and protect counts.
> 
> clk_disable_unprepare() is a problem though since it actually turns the
> clocks off. Instead something is needed which only decrements those counts.
> 
> This series introduces a new clk-core function called
> __clk_disable_unprepare_counts_only() (1) which does just that. Prefixed
> with '__' to indicate that normally drivers should not use this.
> 
> Michael, Stephen sorry for needing to add a new clk-core function for this,
> but I see no other way of solving this (2)(3). The changes are not that
> big / not too bad.
> 
> I've also considered making __clk_disable_unprepare_counts_only() implement
> all the logic itself instead of adding the extra parameter to
> clk_core_unprepare() and clk_core_disable() but that leads in duplicating
> quite a bit of logic (4) so this seems better.
> 
> The other 2 patches just replace the clk_disable_unprepare() calls in
> the simple[fb|drm] driver with the new helper.
> 
> This series fixes the display not coming up after switching to the msm
> driver when a simple-framebuffer node with clocks listed is used.
>
> 1) I'm open to changing the name, this is the best I could come up with.
> 
> 2) One option considered was detaching the simple-framebuffer driver later,
>    after the real display driver has had a chance to claim the clocks. But
>    this won't work in cases where the real display driver picks different
>    parent clocks then the boot firmware did and needs to reparent clocks.
> 
>    Basically the goal is for things to behave as if the simple-framebuffer
>    driver was not there at all, because that leaves the hw in the state
>    the real display driver expects.

So I know it's not really what you had in mind, but if you are only
concerned about the transition from the bootloader to the DRM driver,
then I think supporting the following work would help:

https://lore.kernel.org/r/20260423-drm-state-readout-v2-0-8549f87cb978@kernel.org

With that series, we can build the initial KMS state from the hardware
state, which means that if you were to change the resolution at boot, it
would be executed just like any mode change in KMS.

The initial state allocation is now fallible as well, so if you remove
simple-framebuffer after drm_mode_config_create_initial_state has been
called and has succeeded, then you know that the driver is now in
charge, picked up the configuration, and has taken all the resources
needed to continue running. And if it fails for any reason,
simple-framebuffer is still functional.

This should help mitigate your initial problem, even though it's a
widely different solution.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm]
  2026-05-27 12:04 ` [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Maxime Ripard
@ 2026-05-27 12:21   ` Hans de Goede
  2026-05-27 12:48     ` Maxime Ripard
  0 siblings, 1 reply; 13+ messages in thread
From: Hans de Goede @ 2026-05-27 12:21 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Michael Turquette, Stephen Boyd, Thomas Zimmermann,
	Javier Martinez Canillas, Maarten Lankhorst, Helge Deller,
	Bjorn Andersson, Konrad Dybcio, Dmitry Baryshkov, Rob Clark,
	linux-clk, dri-devel, ~postmarketos/upstreaming

Hi,

On 27-May-26 14:04, Maxime Ripard wrote:
> Hi Hans,
> 
> On Wed, May 27, 2026 at 11:48:08AM +0200, Hans de Goede wrote:
>> Hi Michael, Stephen, et al.,
>>
>> The device-tree simple-framebuffer device is special in that it does not
>> describe actual hardware, but it allows firmware (e.g. u-boot) to pass a
>> firmware initialized framebuffer to the OS to use as display during boot.
>>
>> To avoid clocks used by the firmware framebuffer getting touched while in
>> use, the DT node contains a list of clocks which should not be touched
>> while the simple-framebuffer is in use.
>>
>> Conceptually this is fine, in practice the *do not touch* is implemented as
>> a clk_prepare_enable() + clk_disable_unprepare() pair, with the disabling
>> happening when the simple-framebuffer driver gets replaced by the real
>> display-engine driver.
> 
> Which is also pretty fragile because it doesn't lock the rate either.

That depends on how the clks are configured / setup by the clk driver
if the CLK_SET_RATE_GATE is set in clk_core.flags then protect_count
will get incremented and from then on the rate will be locked.

We could even have the simpledrm / simplefb code call 
clk_rate_exclusive_get() to lock the rate.

So there are multiple ways to lock the rate if necessary but so far
in the real world there has been no need for this AFAICT.

So IMHO this is something to worry about if / when we hit this
actually happening in a real world scenario.

>> The simple-framebuffer concept assumes that the order in which resources
>> are acquired does not matter since they are already on, so power-sequencing
>> is not an issue. But clk_disable_unprepare() actually turns the clock off,
>> messing with the hardware state before the real display driver loads,
>> without any knowledge of the proper power-off sequence for the display.
>>
>> The turning off of the clocks outside of a proper power-off sequence causes
>> the following error when the msm display driver tries to re-enable them:
>>
>> [    2.980181] disp_cc_mdss_dptx3_pixel0_clk_src: rcg didn't update its configuration.
>> [    2.980272] WARNING: drivers/clk/qcom/clk-rcg2.c:136 at update_config+0xdc/0x100
>>
>> Resulting in a non working display.
>>
>> To fix this, we need a way to properly implement the "do not touch" concept
>> for clocks.
> 
> I'm not sure it's something we can enforce, really. The firmware can
> modify clocks behind our back.

Generally speaking there is a contract with the firmware that either
the clock is firmware controlled and the OS can maybe make firmware calls
to request changes; or the OS is in control. Both trying to control
the same clk at the same time is a bug and IMHO unrelated to the issue
at hand which is about clks which are under OS control only.

> Other clocks might change this one as a
> side-effect of a rate change or reparenting, etc. It's just not
> something we can commit to.

See above, this is exactly what the protect_count in the clk-core
is for.

> 
>> clk_prepare_enable() is fine, the clocks are already on so no
>> ordering worries and it ensures that the clocks and their parents cannot
>> get turned off by incrementing their enable, prepare and protect counts.
>>
>> clk_disable_unprepare() is a problem though since it actually turns the
>> clocks off. Instead something is needed which only decrements those counts.
>>
>> This series introduces a new clk-core function called
>> __clk_disable_unprepare_counts_only() (1) which does just that. Prefixed
>> with '__' to indicate that normally drivers should not use this.
>>
>> Michael, Stephen sorry for needing to add a new clk-core function for this,
>> but I see no other way of solving this (2)(3). The changes are not that
>> big / not too bad.
>>
>> I've also considered making __clk_disable_unprepare_counts_only() implement
>> all the logic itself instead of adding the extra parameter to
>> clk_core_unprepare() and clk_core_disable() but that leads in duplicating
>> quite a bit of logic (4) so this seems better.
>>
>> The other 2 patches just replace the clk_disable_unprepare() calls in
>> the simple[fb|drm] driver with the new helper.
>>
>> This series fixes the display not coming up after switching to the msm
>> driver when a simple-framebuffer node with clocks listed is used.
>>
>> 1) I'm open to changing the name, this is the best I could come up with.
>>
>> 2) One option considered was detaching the simple-framebuffer driver later,
>>    after the real display driver has had a chance to claim the clocks. But
>>    this won't work in cases where the real display driver picks different
>>    parent clocks then the boot firmware did and needs to reparent clocks.
>>
>>    Basically the goal is for things to behave as if the simple-framebuffer
>>    driver was not there at all, because that leaves the hw in the state
>>    the real display driver expects.
> 
> So I know it's not really what you had in mind, but if you are only
> concerned about the transition from the bootloader to the DRM driver,
> then I think supporting the following work would help:
> 
> https://lore.kernel.org/r/20260423-drm-state-readout-v2-0-8549f87cb978@kernel.org
> 
> With that series, we can build the initial KMS state from the hardware
> state, which means that if you were to change the resolution at boot, it
> would be executed just like any mode change in KMS.

Hmm, so your suggestion would be to have the initial KMS driver probe()
only do a read back without touching anything. Then claim clks matching
the read back config and then only release the simple* driver and thus
the clocks after this?

That is certainly an interesting proposal but IMHO almost orthogonal
to this one (1). Even if it may fix the issue in the end, it seems
that that work is still quite a way from going upstream and even then
initially it only potentially fixes this for the TIDSS driver since
that solution needs a lot of per driver work.

Where as my proposed fix here is much simpler and fixes the issue
for all drivers in one go.

So I would still like to move forward with the fix proposed here.

Regards,

Hans


1) As you write yourself:

> This should help mitigate your initial problem, even though it's a
> widely different solution.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm]
  2026-05-27 12:21   ` Hans de Goede
@ 2026-05-27 12:48     ` Maxime Ripard
  2026-05-27 15:09       ` Hans de Goede
  0 siblings, 1 reply; 13+ messages in thread
From: Maxime Ripard @ 2026-05-27 12:48 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Michael Turquette, Stephen Boyd, Thomas Zimmermann,
	Javier Martinez Canillas, Maarten Lankhorst, Helge Deller,
	Bjorn Andersson, Konrad Dybcio, Dmitry Baryshkov, Rob Clark,
	linux-clk, dri-devel, ~postmarketos/upstreaming

[-- Attachment #1: Type: text/plain, Size: 3798 bytes --]

On Wed, May 27, 2026 at 02:21:50PM +0200, Hans de Goede wrote:
> >> clk_prepare_enable() is fine, the clocks are already on so no
> >> ordering worries and it ensures that the clocks and their parents cannot
> >> get turned off by incrementing their enable, prepare and protect counts.
> >>
> >> clk_disable_unprepare() is a problem though since it actually turns the
> >> clocks off. Instead something is needed which only decrements those counts.
> >>
> >> This series introduces a new clk-core function called
> >> __clk_disable_unprepare_counts_only() (1) which does just that. Prefixed
> >> with '__' to indicate that normally drivers should not use this.
> >>
> >> Michael, Stephen sorry for needing to add a new clk-core function for this,
> >> but I see no other way of solving this (2)(3). The changes are not that
> >> big / not too bad.
> >>
> >> I've also considered making __clk_disable_unprepare_counts_only() implement
> >> all the logic itself instead of adding the extra parameter to
> >> clk_core_unprepare() and clk_core_disable() but that leads in duplicating
> >> quite a bit of logic (4) so this seems better.
> >>
> >> The other 2 patches just replace the clk_disable_unprepare() calls in
> >> the simple[fb|drm] driver with the new helper.
> >>
> >> This series fixes the display not coming up after switching to the msm
> >> driver when a simple-framebuffer node with clocks listed is used.
> >>
> >> 1) I'm open to changing the name, this is the best I could come up with.
> >>
> >> 2) One option considered was detaching the simple-framebuffer driver later,
> >>    after the real display driver has had a chance to claim the clocks. But
> >>    this won't work in cases where the real display driver picks different
> >>    parent clocks then the boot firmware did and needs to reparent clocks.
> >>
> >>    Basically the goal is for things to behave as if the simple-framebuffer
> >>    driver was not there at all, because that leaves the hw in the state
> >>    the real display driver expects.
> > 
> > So I know it's not really what you had in mind, but if you are only
> > concerned about the transition from the bootloader to the DRM driver,
> > then I think supporting the following work would help:
> > 
> > https://lore.kernel.org/r/20260423-drm-state-readout-v2-0-8549f87cb978@kernel.org
> > 
> > With that series, we can build the initial KMS state from the hardware
> > state, which means that if you were to change the resolution at boot, it
> > would be executed just like any mode change in KMS.
> 
> Hmm, so your suggestion would be to have the initial KMS driver probe()
> only do a read back without touching anything. Then claim clks matching
> the read back config and then only release the simple* driver and thus
> the clocks after this?

Almost. Part of the call to drm_mode_config_create_initial_state() if
needed to make it grab its resources. See atomic_install_state in that
series. So probe wouldn't have anything more to do.

> That is certainly an interesting proposal but IMHO almost orthogonal
> to this one (1).

Why do you think it's orthogonal? It would completely fix your problem.

> Even if it may fix the issue in the end, it seems that that work is
> still quite a way from going upstream

It's likely to be merged in the next few weeks.

> and even then initially it only potentially fixes this for the TIDSS
> driver since that solution needs a lot of per driver work.

I mean, yeah, but the good thing is that you only have one driver to
care about, right?

> Where as my proposed fix here is much simpler and fixes the issue
> for all drivers in one go.

At the expense of exposing an unsafe function for only a single user and
usecase.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm]
  2026-05-27 12:48     ` Maxime Ripard
@ 2026-05-27 15:09       ` Hans de Goede
  0 siblings, 0 replies; 13+ messages in thread
From: Hans de Goede @ 2026-05-27 15:09 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Michael Turquette, Stephen Boyd, Thomas Zimmermann,
	Javier Martinez Canillas, Maarten Lankhorst, Helge Deller,
	Bjorn Andersson, Konrad Dybcio, Dmitry Baryshkov, Rob Clark,
	linux-clk, dri-devel, ~postmarketos/upstreaming

Hi Maxime,

On 27-May-26 14:48, Maxime Ripard wrote:
> On Wed, May 27, 2026 at 02:21:50PM +0200, Hans de Goede wrote:
>>>> clk_prepare_enable() is fine, the clocks are already on so no
>>>> ordering worries and it ensures that the clocks and their parents cannot
>>>> get turned off by incrementing their enable, prepare and protect counts.
>>>>
>>>> clk_disable_unprepare() is a problem though since it actually turns the
>>>> clocks off. Instead something is needed which only decrements those counts.
>>>>
>>>> This series introduces a new clk-core function called
>>>> __clk_disable_unprepare_counts_only() (1) which does just that. Prefixed
>>>> with '__' to indicate that normally drivers should not use this.
>>>>
>>>> Michael, Stephen sorry for needing to add a new clk-core function for this,
>>>> but I see no other way of solving this (2)(3). The changes are not that
>>>> big / not too bad.
>>>>
>>>> I've also considered making __clk_disable_unprepare_counts_only() implement
>>>> all the logic itself instead of adding the extra parameter to
>>>> clk_core_unprepare() and clk_core_disable() but that leads in duplicating
>>>> quite a bit of logic (4) so this seems better.
>>>>
>>>> The other 2 patches just replace the clk_disable_unprepare() calls in
>>>> the simple[fb|drm] driver with the new helper.
>>>>
>>>> This series fixes the display not coming up after switching to the msm
>>>> driver when a simple-framebuffer node with clocks listed is used.
>>>>
>>>> 1) I'm open to changing the name, this is the best I could come up with.
>>>>
>>>> 2) One option considered was detaching the simple-framebuffer driver later,
>>>>    after the real display driver has had a chance to claim the clocks. But
>>>>    this won't work in cases where the real display driver picks different
>>>>    parent clocks then the boot firmware did and needs to reparent clocks.
>>>>
>>>>    Basically the goal is for things to behave as if the simple-framebuffer
>>>>    driver was not there at all, because that leaves the hw in the state
>>>>    the real display driver expects.
>>>
>>> So I know it's not really what you had in mind, but if you are only
>>> concerned about the transition from the bootloader to the DRM driver,
>>> then I think supporting the following work would help:
>>>
>>> https://lore.kernel.org/r/20260423-drm-state-readout-v2-0-8549f87cb978@kernel.org
>>>
>>> With that series, we can build the initial KMS state from the hardware
>>> state, which means that if you were to change the resolution at boot, it
>>> would be executed just like any mode change in KMS.
>>
>> Hmm, so your suggestion would be to have the initial KMS driver probe()
>> only do a read back without touching anything. Then claim clks matching
>> the read back config and then only release the simple* driver and thus
>> the clocks after this?
> 
> Almost. Part of the call to drm_mode_config_create_initial_state() if
> needed to make it grab its resources. See atomic_install_state in that
> series. So probe wouldn't have anything more to do.
> 
>> That is certainly an interesting proposal but IMHO almost orthogonal
>> to this one (1).
> 
> Why do you think it's orthogonal?
> It would completely fix your problem.

AFAICT in its current version it does not contain a mechanism to
delay the remove conflicting framebuffer call, so no it does not
fix my problem.

>> Even if it may fix the issue in the end, it seems that that work is
>> still quite a way from going upstream
> 
> It's likely to be merged in the next few weeks.
> 
>> and even then initially it only potentially fixes this for the TIDSS
>> driver since that solution needs a lot of per driver work.
> 
> I mean, yeah, but the good thing is that you only have one driver to
> care about, right?

I would prefer my proposed KISS solution, which works everywhere, over
your quite complex solution which requires complex per driver changes.

When I was still working on:

https://fedoraproject.org/wiki/Changes/FlickerFreeBoot

I needed to constantly fix i915 fastset support and when I stopped
fixing it due to -ENOTIME it pretty much was broken most of the time.

Last time I check modern (Alderlake +) laptops never had working
fastset support and there always is a visible most set on newer
laptop models because of this.

This state-readback stuff is quite complicated, as the list of
known issues in your cover-letter shows. I wish you all the best
with it, but I really do not see this as a good alternative for
fixing the issues *this* series tries to address given the huge
disparity in complexity between the 2 fixes.

I'm also worried that the readback stuff is likely going to be fragile
so might end up being disabled or automatically detect some issue and
disable itself at which point we're back to having the original
problem this series tries to fix.

Also atm AFAIK there are no plans to add state readback support to
msm and there are a lot of other higher priority items to work on.

###

Anyways since your patch-series will not work for msm in its
current state, I would still very much like to hear from the clock
maintainers what they think of the approach suggested here.

Regards,

Hans



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm]
  2026-05-27  9:48 [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Hans de Goede
                   ` (3 preceding siblings ...)
  2026-05-27 12:04 ` [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Maxime Ripard
@ 2026-05-27 23:03 ` Brian Masney
  2026-05-28  2:34 ` Claude review: " Claude Code Review Bot
  5 siblings, 0 replies; 13+ messages in thread
From: Brian Masney @ 2026-05-27 23:03 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Michael Turquette, Stephen Boyd, Thomas Zimmermann,
	Javier Martinez Canillas, Maarten Lankhorst, Maxime Ripard,
	Helge Deller, Bjorn Andersson, Konrad Dybcio, Dmitry Baryshkov,
	Rob Clark, linux-clk, dri-devel, ~postmarketos/upstreaming

Hi Hans,

On Wed, May 27, 2026 at 11:48:08AM +0200, Hans de Goede wrote:
> 2) One option considered was detaching the simple-framebuffer driver later,
>    after the real display driver has had a chance to claim the clocks. But
>    this won't work in cases where the real display driver picks different
>    parent clocks then the boot firmware did and needs to reparent clocks.

Why won't that work in the case where different parent clocks are selected?
I'll describe a scenario below.

> 
>    Basically the goal is for things to behave as if the simple-framebuffer
>    driver was not there at all, because that leaves the hw in the state
>    the real display driver expects.

I think the deferred unbinding could have some potential here where
there is some kind of notification mechanism between simple-framebuffer
and the real drm driver. So:

- simple-framebuffer driver takes reference(s) to the clk(s).

- real drm driver eventually loads, takes reference(s) to the necessary
  clk(s).

- real drm driver sends a notification to simple-framebuffer that it's
  done, and has control.

- simple-framebuffer can unbind and release its references to the clks.

No clks will be shutdown prematurely in this scenario.

If the real drm driver needs a different parent, then presumably things
should be setup correctly, and simple-framebuffer can have the clocks
shut down when it calls clk_disable_unprepare(). If the real drm driver
needed those clks, then it should hold a reference to them.

I'm intentionally not going through how to do the notification mechanism
here.

Brian


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Claude review: clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm]
  2026-05-27  9:48 [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Hans de Goede
                   ` (4 preceding siblings ...)
  2026-05-27 23:03 ` Brian Masney
@ 2026-05-28  2:34 ` Claude Code Review Bot
  5 siblings, 0 replies; 13+ messages in thread
From: Claude Code Review Bot @ 2026-05-28  2:34 UTC (permalink / raw)
  To: dri-devel-reviews

Overall Series Review

Subject: clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm]
Author: Hans de Goede <johannes.goede@oss.qualcomm.com>
Patches: 9
Reviewed: 2026-05-28T12:34:29.409298

---

This is a well-motivated series fixing a real problem: simpledrm/simplefb call `clk_disable_unprepare()` on teardown, which actually turns off clocks before the real display driver has loaded, leaving hardware in an undefined state on Qualcomm platforms. The proposed solution — decrement refcounts without touching hardware — is conceptually sound, and the cover letter is thorough in discussing alternatives.

However, the implementation has a significant gap: the counts-only unprepare path still calls `clk_pm_runtime_put()`, which can actually power down the clock controller device, undermining the "don't touch hardware" intent. The tracepoint emissions in the counts-only path are also misleading. These issues should be addressed before the clk maintainers are likely to accept this.

The simpledrm error-path change in patch 2 is also questionable — during init failure, the clocks were genuinely enabled by simpledrm itself and may actually need proper disable/unprepare.

---
Generated by Claude Code Patch Reviewer

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Claude review: clk: Add __clk_disable_unprepare_counts_only() helper
  2026-05-27  9:48 ` [PATCH 1/3] clk: Add __clk_disable_unprepare_counts_only() helper Hans de Goede
@ 2026-05-28  2:34   ` Claude Code Review Bot
  0 siblings, 0 replies; 13+ messages in thread
From: Claude Code Review Bot @ 2026-05-28  2:34 UTC (permalink / raw)
  To: dri-devel-reviews

Patch Review

**pm_runtime leak/hazard in unprepare path:**
The patch gates `core->ops->unprepare` with the new `call_unprepare_op` flag, but `clk_pm_runtime_put(core)` at the end of `clk_core_unprepare()` is still called unconditionally:

```c
	if (call_unprepare_op && core->ops->unprepare)
		core->ops->unprepare(core->hw);

	trace_clk_unprepare_complete(core);
	clk_core_unprepare(core->parent, call_unprepare_op);
	clk_pm_runtime_put(core);   // <-- still called in counts-only mode
```

When `clk_core_prepare()` was called by simpledrm, it called `clk_pm_runtime_get()` (line 1110 of clk.c in drm-next). The matching `clk_pm_runtime_put()` calls `pm_runtime_put_sync()`, which can trigger the clock controller device's `runtime_suspend` callback. If simpledrm held the only prepare reference on clocks from a given controller, this could power down the controller's power domain — exactly the kind of hardware disturbance the series is trying to avoid.

This should either be gated the same way as the ops callback, or the rationale for why it's safe should be documented.

**Misleading tracepoints:**
`trace_clk_unprepare` / `trace_clk_unprepare_complete` and `trace_clk_disable` / `trace_clk_disable_complete` fire regardless of the `call_*_op` flag. When no actual disable/unprepare happens, these trace events are misleading and could confuse ftrace-based debugging. Consider gating them with the same boolean, or adding distinct trace events for counts-only operations.

**WARN for CLK_IS_CRITICAL:**
In the counts-only path, the WARN for decrementing a critical clock's last reference still fires:

```c
	if (WARN(core->enable_count == 1 && core->flags & CLK_IS_CRITICAL,
	    "Disabling critical %s\n", core->name))
		return;
```

While CLK_IS_CRITICAL clocks shouldn't appear in simple-framebuffer DT nodes, the semantic is arguably wrong: we're not "disabling" the clock, we're releasing a count. This is a minor concern but could be confusing if it triggers.

**API naming and export:**
The function is `EXPORT_SYMBOL_GPL` and the `__` prefix clearly signals "internal/unusual." The kerneldoc is good. Consider whether a `clk_release_counts()` or `clk_detach_counts()` name would be clearer, since the function doesn't disable or unprepare anything.

**Overall correctness of the bool-parameter approach:**
Adding `bool call_unprepare_op` / `bool call_disable_op` to internal functions is a reasonable pattern (the cover letter correctly notes that duplicating the logic is worse). The changes to all existing callers to pass `true` are mechanically correct — I verified each call site:
- `clk_core_unprepare_lock()` — passes `true` ✓
- `clk_core_prepare()` error path — passes `true` ✓  
- `clk_change_rate()` — passes `true` ✓
- `__clk_core_init()` — passes `true` ✓
- `clk_core_disable_lock()` — passes `true` ✓
- `clk_core_enable()` error path — passes `true` ✓

---
Generated by Claude Code Patch Reviewer

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Claude review: drm/sysfb: simpledrm: Use __clk_disable_unprepare_counts_only()
  2026-05-27  9:48 ` [PATCH 2/3] drm/sysfb: simpledrm: Use __clk_disable_unprepare_counts_only() Hans de Goede
@ 2026-05-28  2:34   ` Claude Code Review Bot
  0 siblings, 0 replies; 13+ messages in thread
From: Claude Code Review Bot @ 2026-05-28  2:34 UTC (permalink / raw)
  To: dri-devel-reviews

Patch Review

**Normal teardown path — correct:**
The change in `simpledrm_device_release_clocks()` is the core fix and is correct. When simpledrm is being replaced by the real display driver, clocks should stay on:

```c
	for (i = 0; i < sdev->clk_count; ++i) {
		if (sdev->clks[i]) {
			__clk_disable_unprepare_counts_only(sdev->clks[i]);
			clk_put(sdev->clks[i]);
		}
	}
```

**Error path during init — questionable:**
The error cleanup in `simpledrm_device_init_clocks()` is also changed to counts-only:

```c
	while (i) {
		--i;
		if (sdev->clks[i]) {
			__clk_disable_unprepare_counts_only(sdev->clks[i]);
			clk_put(sdev->clks[i]);
		}
	}
```

This error path runs when `devm_add_action_or_reset()` or a later `of_clk_get()` / `clk_prepare_enable()` fails. In this scenario simpledrm never fully initialized and will not be providing a framebuffer — the clocks it enabled should arguably be properly disabled via `clk_disable_unprepare()`, since simpledrm is aborting, not handing off to a real driver. Using counts-only here means clocks that simpledrm actually turned on (if the firmware hadn't already) will be left running with zero refcount.

Consider keeping `clk_disable_unprepare()` in the error path, since the "don't touch hardware during handoff" rationale doesn't apply when init is failing.

---
Generated by Claude Code Patch Reviewer

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Claude review: fbdev: simplefb: Use __clk_disable_unprepare_counts_only()
  2026-05-27  9:48 ` [PATCH 3/3] fbdev: simplefb: " Hans de Goede
@ 2026-05-28  2:34   ` Claude Code Review Bot
  0 siblings, 0 replies; 13+ messages in thread
From: Claude Code Review Bot @ 2026-05-28  2:34 UTC (permalink / raw)
  To: dri-devel-reviews

Patch Review

**Straightforward and correct:**

```c
	if (par->clks_enabled)
		__clk_disable_unprepare_counts_only(par->clks[i]);
```

The `par->clks_enabled` guard ensures this only runs when clocks were successfully enabled. This path is only for the normal teardown/handoff case. No error-path concern here.

Minor: the commit message has a typo — "non work display output" should be "non working display output."

---
Generated by Claude Code Patch Reviewer

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-05-28  2:34 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-27  9:48 [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Hans de Goede
2026-05-27  9:48 ` [PATCH 1/3] clk: Add __clk_disable_unprepare_counts_only() helper Hans de Goede
2026-05-28  2:34   ` Claude review: " Claude Code Review Bot
2026-05-27  9:48 ` [PATCH 2/3] drm/sysfb: simpledrm: Use __clk_disable_unprepare_counts_only() Hans de Goede
2026-05-28  2:34   ` Claude review: " Claude Code Review Bot
2026-05-27  9:48 ` [PATCH 3/3] fbdev: simplefb: " Hans de Goede
2026-05-28  2:34   ` Claude review: " Claude Code Review Bot
2026-05-27 12:04 ` [PATCH 0/3] clk: Add __clk_disable_unprepare_counts_only() and use this in simple[fb|drm] Maxime Ripard
2026-05-27 12:21   ` Hans de Goede
2026-05-27 12:48     ` Maxime Ripard
2026-05-27 15:09       ` Hans de Goede
2026-05-27 23:03 ` Brian Masney
2026-05-28  2:34 ` Claude review: " Claude Code Review Bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox