RE: [PATCH] can: rcar_canfd: Change the initializing flow for clocks and resets
From: Biju Das
Date: Thu Jul 23 2026 - 04:04:27 EST
Hi All,
> -----Original Message-----
> From: Biju <biju.das.au@xxxxxxxxx>
> Sent: 25 June 2026 14:52
> Subject: [PATCH] can: rcar_canfd: Change the initializing flow for clocks and resets
>
> From: Tu Nguyen <tu.nguyen.xg@xxxxxxxxxxx>
>
> Testing CANFD on RZ/G3E shows that many registers do not reset to their initial values with the current
> flow of deasserting resets first and then enabling clocks.
>
> Based on the HW manual, clocks should be supplied first and the resets deasserted afterward.
>
> section 7.4.3 Procedure for Activating Modules: RZ/G2L section 4.4.9.3 Procedure for Starting up Units:
> RZ/G3E
>
> So, update the order of the initializing flow for resets and clocks to match the hardware manual,
> resetting all CANFD registers to their initial values. Also update rcar_canfd_global_deinit() to assert
> resets before disabling clocks, so the teardown path mirrors the new init ordering.
>
> Fixes: 76e9353a80e9 ("can: rcar_canfd: Add support for RZ/G2L family")
> Signed-off-by: Tu Nguyen <tu.nguyen.xg@xxxxxxxxxxx>
> Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
> ---
> drivers/net/can/rcar/rcar_canfd.c | 32 +++++++++++++++----------------
> 1 file changed, 16 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
> index eaf8cac78038..fcc37b73ed43 100644
> --- a/drivers/net/can/rcar/rcar_canfd.c
> +++ b/drivers/net/can/rcar/rcar_canfd.c
> @@ -2003,20 +2003,12 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
> u32 ch, sts;
> int err;
>
> - err = reset_control_reset(gpriv->rstc1);
> - if (err)
> - return err;
> -
> - err = reset_control_reset(gpriv->rstc2);
> - if (err)
> - goto fail_reset1;
> -
> /* Enable peripheral clock for register access */
> err = clk_prepare_enable(gpriv->clkp);
> if (err) {
> dev_err(dev, "failed to enable peripheral clock: %pe\n",
> ERR_PTR(err));
> - goto fail_reset2;
> + return err;
> }
>
> /* Enable RAM clock */
> @@ -2027,10 +2019,18 @@ static int rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
> goto fail_clk;
> }
>
> + err = reset_control_reset(gpriv->rstc1);
> + if (err)
> + goto fail_ram_clk;
> +
> + err = reset_control_reset(gpriv->rstc2);
> + if (err)
> + goto fail_reset1;
> +
> err = rcar_canfd_reset_controller(gpriv);
> if (err) {
> dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
> - goto fail_ram_clk;
> + goto fail_reset2;
> }
>
> /* Controller in Global reset & Channel reset mode */ @@ -2068,14 +2068,14 @@ static int
> rcar_canfd_global_init(struct rcar_canfd_global *gpriv)
>
> fail_mode:
> rcar_canfd_disable_global_interrupts(gpriv);
> -fail_ram_clk:
> - clk_disable_unprepare(gpriv->clk_ram);
> -fail_clk:
> - clk_disable_unprepare(gpriv->clkp);
> fail_reset2:
> reset_control_assert(gpriv->rstc2);
> fail_reset1:
> reset_control_assert(gpriv->rstc1);
> +fail_ram_clk:
> + clk_disable_unprepare(gpriv->clk_ram);
> +fail_clk:
> + clk_disable_unprepare(gpriv->clkp);
> return err;
> }
>
> @@ -2090,10 +2090,10 @@ static void rcar_canfd_global_deinit(struct rcar_canfd_global *gpriv, bool full)
> rcar_canfd_set_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GSLPR);
> }
>
> - clk_disable_unprepare(gpriv->clk_ram);
> - clk_disable_unprepare(gpriv->clkp);
> reset_control_assert(gpriv->rstc2);
> reset_control_assert(gpriv->rstc1);
> + clk_disable_unprepare(gpriv->clk_ram);
> + clk_disable_unprepare(gpriv->clkp);
> }
>
> static int rcar_canfd_probe(struct platform_device *pdev)
> --
> 2.43.0
Gentle ping.
Cheers,
Biju