diff options
author | Tony Lindgren <tony@atomide.com> | 2019-05-27 04:51:56 -0700 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2019-05-28 05:19:16 -0700 |
commit | ea5a2e4d54675b06991ef3452e8e51ce6519a8db (patch) | |
tree | 2dd2a3a94bf289400aefe2fdd21826437057ccd0 | |
parent | 8383e25994efadbd76cf6db7b19776cb8931e5da (diff) | |
download | linux-ea5a2e4d54675b06991ef3452e8e51ce6519a8db.tar.gz linux-ea5a2e4d54675b06991ef3452e8e51ce6519a8db.tar.bz2 linux-ea5a2e4d54675b06991ef3452e8e51ce6519a8db.zip |
bus: ti-sysc: Do rstctrl reset handling in two phases
We need to deassert rstctrl resets before enabling clocks to avoid clock
"failed to enable" errors. For asserting rstctrl reset, the clocks need
to be enabled.
As the reset controller status is not available for arrays, let's use
devm_reset_control_get_optional() so we can get the status after reset.
Note that depends on a proper PRM rstctrl driver, so far I've only
tested this with earlier reset-simple patches.
Tested-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r-- | drivers/bus/ti-sysc.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index f36f3e8b38f3..bc4dbaa027cf 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -497,7 +497,7 @@ static void sysc_clkdm_allow_idle(struct sysc *ddata) static int sysc_init_resets(struct sysc *ddata) { ddata->rsts = - devm_reset_control_array_get_optional_exclusive(ddata->dev); + devm_reset_control_get_optional(ddata->dev, "rstctrl"); if (IS_ERR(ddata->rsts)) return PTR_ERR(ddata->rsts); @@ -1420,7 +1420,7 @@ static int sysc_legacy_init(struct sysc *ddata) */ static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset) { - int error; + int error, val; if (!ddata->rsts) return 0; @@ -1431,7 +1431,14 @@ static int sysc_rstctrl_reset_deassert(struct sysc *ddata, bool reset) return error; } - return reset_control_deassert(ddata->rsts); + error = reset_control_deassert(ddata->rsts); + if (error == -EEXIST) + return 0; + + error = readx_poll_timeout(reset_control_status, ddata->rsts, val, + val == 0, 100, MAX_MODULE_SOFTRESET_WAIT); + + return error; } /* @@ -1489,12 +1496,8 @@ static int sysc_init_module(struct sysc *ddata) { int error = 0; bool manage_clocks = true; - bool reset = true; - if (ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) - reset = false; - - error = sysc_rstctrl_reset_deassert(ddata, reset); + error = sysc_rstctrl_reset_deassert(ddata, false); if (error) return error; @@ -1518,6 +1521,12 @@ static int sysc_init_module(struct sysc *ddata) goto err_opt_clocks; } + if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) { + error = sysc_rstctrl_reset_deassert(ddata, true); + if (error) + goto err_main_clocks; + } + ddata->revision = sysc_read_revision(ddata); sysc_init_revision_quirks(ddata); |