29.06.2019 16:28, Dmitry Osipenko пишет: > 28.06.2019 5:12, Sowjanya Komatineni пишет: >> This patch creates APIs for supporting Tegra210 clock driver to >> perform DFLL suspend and resume operation. >> >> During suspend, DFLL mode is saved and on resume Tegra210 clock driver >> invokes DFLL resume API to re-initialize DFLL to enable target device >> clock in open loop mode or closed loop mode. >> >> Acked-by: Thierry Reding <treding@xxxxxxxxxx> >> Signed-off-by: Sowjanya Komatineni <skomatineni@xxxxxxxxxx> >> --- >> drivers/clk/tegra/clk-dfll.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ >> drivers/clk/tegra/clk-dfll.h | 2 ++ >> 2 files changed, 80 insertions(+) >> >> diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c >> index f8688c2ddf1a..a1f37cf99b00 100644 >> --- a/drivers/clk/tegra/clk-dfll.c >> +++ b/drivers/clk/tegra/clk-dfll.c >> @@ -277,6 +277,7 @@ struct tegra_dfll { >> unsigned long dvco_rate_min; >> >> enum dfll_ctrl_mode mode; >> + enum dfll_ctrl_mode resume_mode; >> enum dfll_tune_range tune_range; >> struct dentry *debugfs_dir; >> struct clk_hw dfll_clk_hw; >> @@ -1864,6 +1865,83 @@ static int dfll_fetch_common_params(struct tegra_dfll *td) >> } >> >> /* >> + * tegra_dfll_suspend >> + * @pdev: DFLL instance >> + * >> + * dfll controls clock/voltage to other devices, including CPU. Therefore, >> + * dfll driver pm suspend callback does not stop cl-dvfs operations. >> + */ >> +void tegra_dfll_suspend(struct platform_device *pdev) >> +{ >> + struct tegra_dfll *td = dev_get_drvdata(&pdev->dev); >> + >> + if (!td) >> + return; >> + >> + if (td->mode <= DFLL_DISABLED) >> + return; >> + >> + td->resume_mode = td->mode; >> + switch (td->mode) { >> + case DFLL_CLOSED_LOOP: >> + dfll_set_mode(td, DFLL_CLOSED_LOOP); >> + dfll_set_frequency_request(td, &td->last_req); >> + >> + dfll_unlock(td); >> + break; >> + default: >> + break; >> + } >> +} >> + >> +/** >> + * tegra_dfll_resume - reprogram the DFLL after context-loss >> + * @pdev: DFLL instance >> + * >> + * Re-initialize and enable target device clock in open loop mode. Called >> + * directly from SoC clock resume syscore operation. Closed loop will be >> + * re-entered in platform syscore ops as well after CPU clock source is >> + * switched to DFLL in open loop. >> + */ >> +void tegra_dfll_resume(struct platform_device *pdev, bool on_dfll) >> +{ >> + struct tegra_dfll *td = dev_get_drvdata(&pdev->dev); >> + >> + if (!td) >> + return; >> + >> + if (on_dfll) { >> + if (td->resume_mode == DFLL_CLOSED_LOOP) >> + dfll_lock(td); >> + td->resume_mode = DFLL_DISABLED; >> + return; >> + } >> + >> + reset_control_deassert(td->dvco_rst); >> + >> + pm_runtime_get(td->dev); > > pm_runtime_get_sync()? > > Otherwise looks like you're risking a lot here because pm_runtime_get() is an > asynchronous request. It looks like DFLL driver should be masked as IRQ-safe using pm_runtime_irq_safe() and then the synchronous resume could be used..