diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 07f831ce85..3824d71c9f 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -3261,7 +3261,7 @@ exit: if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); - if (swrm_clk_req_err) + if (swrm_clk_req_err || aud_core_err || hw_core_err) pm_runtime_set_autosuspend_delay(&pdev->dev, ERR_AUTO_SUSPEND_TIMER_VAL); else @@ -3292,6 +3292,10 @@ static int swrm_runtime_suspend(struct device *dev) __func__, swrm->state); dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n", __func__, swrm->state); + if (swrm->state == SWR_MSTR_SSR_RESET) { + swrm->state = SWR_MSTR_SSR; + return 0; + } mutex_lock(&swrm->runtime_lock); mutex_lock(&swrm->reslock); mutex_lock(&swrm->force_down_lock); @@ -3638,6 +3642,18 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) dev_err(swrm->dev, "%s: clock voting not zero\n", __func__); + if (swrm->state == SWR_MSTR_UP || + pm_runtime_autosuspend_expiration(swrm->dev)) { + swrm->state = SWR_MSTR_SSR_RESET; + dev_dbg(swrm->dev, + "%s:suspend swr if active at SSR up\n", + __func__); + pm_runtime_set_autosuspend_delay(swrm->dev, + ERR_AUTO_SUSPEND_TIMER_VAL); + usleep_range(50000, 50100); + swrm->state = SWR_MSTR_SSR; + } + mutex_lock(&swrm->devlock); swrm->dev_up = true; mutex_unlock(&swrm->devlock); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index db58e4ee47..6ce199be61 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -52,6 +52,7 @@ enum { SWR_MSTR_UP, SWR_MSTR_DOWN, SWR_MSTR_SSR, + SWR_MSTR_SSR_RESET, }; enum swrm_pm_state {