RE: [PATCH] can: rcar_canfd: Change the initializing flow for clocks and resets
Biju Das <[email protected]> Thu, 23 Jul 2026 08:02:08 +0000
| Newsgroups | org.kernel.vger.linux-can,org.kernel.vger.linux-kernel,org.kernel.vger.linux-renesas-soc |
|---|---|
| Message-ID | <TY3PR01MB113465FDE69A565A731E9238586C02@TY3PR01MB11346.jpnprd01.prod.outlook.com> |
Hi All, > -----Original Message----- > From: Biju <[email protected]> > Sent: 25 June 2026 14:52 > Subject: [PATCH] can: rcar_canfd: Change the initializing flow for clocks and resets > > From: Tu Nguyen <[email protected]> > > 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 <[email protected]> > Signed-off-by: Biju Das <[email protected]> > --- > 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