When enabling/disabling a clock or reset signal, confirm that the change
has completed before returning from the function. A somewhat arbitrary
100ms timeout is defined to ensure that the system doesn't lock up in
the case of an error.

Since we need to dynamically determine if we're waiting for a 0 bit or a
1 bit, it's easier to use wait_for_bit_32() than readl_poll_timeout().

This change is needed for reliable initialization of the I2C driver
which is added in a following patch.

Fixes: 1918ff5c95be ("clk: renesas: Add RZ/G2L & RZ/G2LC CPG driver")
Signed-off-by: Paul Barker <paul.barker...@bp.renesas.com>
---
 drivers/clk/renesas/rzg2l-cpg.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index e54508c35ce2..dba009997a81 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -23,10 +23,18 @@
 #include <linux/iopoll.h>
 #include <reset-uclass.h>
 #include <reset.h>
+#include <wait_bit.h>
 
 #include "rzg2l-cpg.h"
 
+/*
+ * Monitor registers for both clock and reset signals are offset by 0x180 from
+ * the corresponding control registers.
+ */
 #define CLK_MON_R(reg)         (0x180 + (reg))
+#define RST_MON_R(reg)         (0x180 + (reg))
+
+#define CPG_TIMEOUT_MSEC       100
 
 static ulong rzg2l_cpg_clk_get_rate_by_id(struct udevice *dev, unsigned int 
id);
 static ulong rzg2l_cpg_clk_get_rate_by_name(struct udevice *dev, const char 
*name);
@@ -83,9 +91,9 @@ static int rzg2l_cpg_clk_set(struct clk *clk, bool enable)
                value |= BIT(mod_clk->bit);
        writel(value, data->base + mod_clk->off);
 
-       if (enable && readl_poll_timeout(data->base + CLK_MON_R(mod_clk->off),
-                                        value, (value & BIT(mod_clk->bit)),
-                                        10)) {
+       if (enable && wait_for_bit_32(data->base + CLK_MON_R(mod_clk->off),
+                                     BIT(mod_clk->bit), enable,
+                                     CPG_TIMEOUT_MSEC, false)) {
                dev_err(clk->dev, "Timeout\n");
                return -ETIMEDOUT;
        }
@@ -420,7 +428,8 @@ static int rzg2l_cpg_rst_set(struct reset_ctl *reset_ctl, 
bool asserted)
                value |= BIT(rst->bit);
        writel(value, data->base + rst->off);
 
-       return 0;
+       return wait_for_bit_32(data->base + RST_MON_R(rst->off), BIT(rst->bit),
+                              asserted, CPG_TIMEOUT_MSEC, false);
 }
 
 static int rzg2l_cpg_rst_assert(struct reset_ctl *reset_ctl)
-- 
2.39.2

Reply via email to