From 4097c9a64d1009d97dcee772bd8b15381bc7507d Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 16 Nov 2020 12:57:13 +0200 Subject: [PATCH] bus: ti-sysc: Assert reset only after disabling clocks The rstctrl reset must be asserted after gating the module clock as described in the TRM at least for IVA. Otherwise the rstctrl reset done with module clock enabled can hang the system. Note that this issue is has been only seen with related IVA changes that we do not currently have merged. So probably no need to apply this patch as a fix. Signed-off-by: Tony Lindgren --- drivers/bus/ti-sysc.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 16132e6e91f8..2b99fd5a4740 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -1222,10 +1222,10 @@ static int __maybe_unused sysc_runtime_suspend(struct device *dev) ddata->enabled = false; err_allow_idle: - reset_control_assert(ddata->rsts); - sysc_clkdm_allow_idle(ddata); + reset_control_assert(ddata->rsts); + return error; } @@ -1945,6 +1945,7 @@ static int sysc_reset(struct sysc *ddata) */ static int sysc_init_module(struct sysc *ddata) { + bool rstctrl_deasserted = false; int error = 0; error = sysc_clockdomain_init(ddata); @@ -1969,6 +1970,7 @@ static int sysc_init_module(struct sysc *ddata) error = reset_control_deassert(ddata->rsts); if (error) goto err_main_clocks; + rstctrl_deasserted = true; } ddata->revision = sysc_read_revision(ddata); @@ -1978,13 +1980,13 @@ static int sysc_init_module(struct sysc *ddata) if (ddata->legacy_mode) { error = sysc_legacy_init(ddata); if (error) - goto err_reset; + goto err_main_clocks; } if (!ddata->legacy_mode) { error = sysc_enable_module(ddata->dev); if (error) - goto err_reset; + goto err_main_clocks; } error = sysc_reset(ddata); @@ -1994,10 +1996,6 @@ static int sysc_init_module(struct sysc *ddata) if (error && !ddata->legacy_mode) sysc_disable_module(ddata->dev); -err_reset: - if (error && !(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) - reset_control_assert(ddata->rsts); - err_main_clocks: if (error) sysc_disable_main_clocks(ddata); @@ -2008,6 +2006,10 @@ err_opt_clocks: sysc_clkdm_allow_idle(ddata); } + if (error && rstctrl_deasserted && + !(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) + reset_control_assert(ddata->rsts); + return error; } @@ -2975,9 +2977,6 @@ static int sysc_probe(struct platform_device *pdev) } /* Balance use counts as PM runtime should have enabled these all */ - if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) - reset_control_assert(ddata->rsts); - if (!(ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))) { sysc_disable_main_clocks(ddata); @@ -2985,6 +2984,9 @@ static int sysc_probe(struct platform_device *pdev) sysc_clkdm_allow_idle(ddata); } + if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) + reset_control_assert(ddata->rsts); + sysc_show_registers(ddata); ddata->dev->type = &sysc_device_type;