Hi, On Tue, Mar 31, 2020 at 6:58 AM Kalyan Thota <kalyan_t@xxxxxxxxxxxxxx> wrote: > > "The PM core always increments the runtime usage counter > before calling the ->suspend() callback and decrements it > after calling the ->resume() callback" > > DPU and DSI are managed as runtime devices. When > suspend is triggered, PM core adds a refcount on all the > devices and calls device suspend, since usage count is > already incremented, runtime suspend was not getting called > and it kept the clocks on which resulted in target not > entering into XO shutdown. > > Add changes to force suspend on runtime devices during pm sleep. > > Changes in v1: > - Remove unnecessary checks in the function > _dpu_kms_disable_dpu (Rob Clark). > > Changes in v2: > - Avoid using suspend_late to reset the usagecount > as suspend_late might not be called during suspend > call failures (Doug). > > Changes in v3: > - Use force suspend instead of managing device usage_count > via runtime put and get API's to trigger callbacks (Doug). > > Signed-off-by: Kalyan Thota <kalyan_t@xxxxxxxxxxxxxx> > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 2 ++ > drivers/gpu/drm/msm/dsi/dsi.c | 2 ++ > drivers/gpu/drm/msm/msm_drv.c | 4 ++++ > 3 files changed, 8 insertions(+) This looks much saner to me. Thanks! I assume it still works fine for you? I'm still no expert on how all the pieces of DRM drivers work together, but at least there's not a bunch of strange fiddling with pm_runtime state and hopefully it will avoid weird corner cases... > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > index ce19f1d..b886d9d 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c > @@ -1123,6 +1123,8 @@ static int __maybe_unused dpu_runtime_resume(struct device *dev) > > static const struct dev_pm_ops dpu_pm_ops = { > SET_RUNTIME_PM_OPS(dpu_runtime_suspend, dpu_runtime_resume, NULL) > + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, > + pm_runtime_force_resume) > }; > > static const struct of_device_id dpu_dt_match[] = { > diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c > index 55ea4bc2..62704885 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi.c > +++ b/drivers/gpu/drm/msm/dsi/dsi.c > @@ -161,6 +161,8 @@ static int dsi_dev_remove(struct platform_device *pdev) > > static const struct dev_pm_ops dsi_pm_ops = { > SET_RUNTIME_PM_OPS(msm_dsi_runtime_suspend, msm_dsi_runtime_resume, NULL) > + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, > + pm_runtime_force_resume) > }; > > static struct platform_driver dsi_driver = { > diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c > index 7d985f8..2b8c99c 100644 > --- a/drivers/gpu/drm/msm/msm_drv.c > +++ b/drivers/gpu/drm/msm/msm_drv.c > @@ -1051,6 +1051,8 @@ static int msm_pm_suspend(struct device *dev) > return ret; > } > > + pm_runtime_force_suspend(dev); nit: check return value of pm_runtime_force_suspend()? > + > return 0; > } > > @@ -1063,6 +1065,8 @@ static int msm_pm_resume(struct device *dev) > if (WARN_ON(!priv->pm_state)) > return -ENOENT; > > + pm_runtime_force_resume(dev); nit: check return value of pm_runtime_force_resume()? -Doug