mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
can: rcar_canfd: change the initializing flow for clocks and resets
[ Upstream commitbef9004c5b] 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:76e9353a80("can: rcar_canfd: Add support for RZ/G2L family") Signed-off-by: Tu Nguyen <tu.nguyen.xg@renesas.com> Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com> Tested-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Vincent Mailhol <mailhol@kernel.org> Link: https://patch.msgid.link/20260625135216.130450-1-biju.das.jz@bp.renesas.com Cc: stable@kernel.org Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
441e9c3328
commit
584a5d96b6
@@ -1999,27 +1999,27 @@ static int rcar_canfd_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
err = reset_control_reset(gpriv->rstc1);
|
||||
if (err)
|
||||
goto fail_dev;
|
||||
err = reset_control_reset(gpriv->rstc2);
|
||||
if (err) {
|
||||
reset_control_assert(gpriv->rstc1);
|
||||
goto fail_dev;
|
||||
}
|
||||
|
||||
/* 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_reset;
|
||||
goto fail_dev;
|
||||
}
|
||||
|
||||
err = reset_control_reset(gpriv->rstc1);
|
||||
if (err)
|
||||
goto fail_clk;
|
||||
err = reset_control_reset(gpriv->rstc2);
|
||||
if (err) {
|
||||
reset_control_assert(gpriv->rstc1);
|
||||
goto fail_clk;
|
||||
}
|
||||
|
||||
err = rcar_canfd_reset_controller(gpriv);
|
||||
if (err) {
|
||||
dev_err(dev, "reset controller failed: %pe\n", ERR_PTR(err));
|
||||
goto fail_clk;
|
||||
goto fail_reset;
|
||||
}
|
||||
|
||||
/* Controller in Global reset & Channel reset mode */
|
||||
@@ -2070,11 +2070,11 @@ fail_channel:
|
||||
rcar_canfd_channel_remove(gpriv, ch);
|
||||
fail_mode:
|
||||
rcar_canfd_disable_global_interrupts(gpriv);
|
||||
fail_clk:
|
||||
clk_disable_unprepare(gpriv->clkp);
|
||||
fail_reset:
|
||||
reset_control_assert(gpriv->rstc1);
|
||||
reset_control_assert(gpriv->rstc2);
|
||||
fail_clk:
|
||||
clk_disable_unprepare(gpriv->clkp);
|
||||
fail_dev:
|
||||
return err;
|
||||
}
|
||||
@@ -2094,9 +2094,9 @@ static void rcar_canfd_remove(struct platform_device *pdev)
|
||||
|
||||
/* Enter global sleep mode */
|
||||
rcar_canfd_set_bit(gpriv->base, RCANFD_GCTR, RCANFD_GCTR_GSLPR);
|
||||
clk_disable_unprepare(gpriv->clkp);
|
||||
reset_control_assert(gpriv->rstc1);
|
||||
reset_control_assert(gpriv->rstc2);
|
||||
clk_disable_unprepare(gpriv->clkp);
|
||||
}
|
||||
|
||||
static int __maybe_unused rcar_canfd_suspend(struct device *dev)
|
||||
|
||||
Reference in New Issue
Block a user