From 5b1fd5953199b448060ced40b3e000091c4acdc0 Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Mon, 24 Apr 2023 11:32:43 +0530 Subject: [PATCH 1/2] soc: reduce the auto suspend timeout when swr event finished the APSS would suspend within ~120ms after audio off, if system suspend swrm_suspend() is called before swrm_runtime_suspend. The clock stop sequence require writing IPC and expect interrupt, which would stop the APSS to be suspended. Reduce the auto suspend time specifically when swr event is done can call the swrm_runtime_suspend Change-Id: Iee0c9143d65e5a8e68a8e20ab73bea9def1920bd Signed-off-by: Junkai Cai Signed-off-by: Soumya Managoli --- soc/swr-mstr-ctrl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 752d5c2b2940..2cd057c34b71 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1738,6 +1738,8 @@ static int swrm_slvdev_datapath_control(struct swr_master *master, bool enable) dev_dbg(&master->dev, "%s: pm_runtime auto suspend triggered\n", __func__); pm_runtime_mark_last_busy(swrm->dev); + if (!enable) + pm_runtime_set_autosuspend_delay(swrm->dev, 80); pm_runtime_put_autosuspend(swrm->dev); } exit: @@ -3327,6 +3329,9 @@ exit: if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); + dev_dbg(dev, "%s: pm_runtime: suspend done state: %d\n", + __func__, swrm->state); + pm_runtime_set_autosuspend_delay(dev, auto_suspend_timer); return ret; } #endif /* CONFIG_PM */ From 19791049de77c8fea4ce4bd689aba9bcd3bc557a Mon Sep 17 00:00:00 2001 From: Soumya Managoli Date: Mon, 24 Apr 2023 12:08:53 +0530 Subject: [PATCH 2/2] soc: swr-mstr-ctrl: add new lock to sync runtime_resume and runtime_suspend runtime_suspend may get from multi functions and reslock is unlock and lock inbetween which may cause clk count mismatch with multi rutime_suspend called. Add new lock to make sure runtime_suspend is run in sequence. Change-Id: Ie465ded6dc1db1244035e9f4d216466b630df82b Signed-off-by: Meng Wang Signed-off-by: Soumya Managoli --- soc/swr-mstr-ctrl.c | 9 +++++++++ soc/swr-mstr-ctrl.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 2cd057c34b71..a41b2f5cee97 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -2850,6 +2850,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_init(&swrm->clklock); mutex_init(&swrm->devlock); mutex_init(&swrm->pm_lock); + mutex_init(&swrm->runtime_lock); swrm->wlock_holders = 0; swrm->pm_state = SWRM_PM_SLEEPABLE; init_waitqueue_head(&swrm->pm_wq); @@ -3022,6 +3023,7 @@ err_irq_fail: mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->pm_lock); pm_qos_remove_request(&swrm->pm_qos_req); + mutex_destroy(&swrm->runtime_lock); err_pdata_fail: err_memory_fail: @@ -3061,6 +3063,7 @@ static int swrm_remove(struct platform_device *pdev) mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->pm_lock); pm_qos_remove_request(&swrm->pm_qos_req); + mutex_destroy(&swrm->runtime_lock); devm_kfree(&pdev->dev, swrm); return 0; } @@ -3092,6 +3095,7 @@ static int swrm_runtime_resume(struct device *dev) dev_dbg(dev, "%s: pm_runtime: resume, state:%d\n", __func__, swrm->state); + mutex_lock(&swrm->runtime_lock); mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { @@ -3103,6 +3107,7 @@ static int swrm_runtime_resume(struct device *dev) if (swrm->req_clk_switch) swrm->req_clk_switch = false; mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); return 0; } if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { @@ -3120,6 +3125,7 @@ static int swrm_runtime_resume(struct device *dev) pr_err("%s: irq data is NULL\n", __func__); mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); return IRQ_NONE; } mutex_lock(&swrm->irq_lock); @@ -3211,6 +3217,7 @@ exit: if (swrm->req_clk_switch) swrm->req_clk_switch = false; mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); return ret; } @@ -3232,6 +3239,7 @@ static int swrm_runtime_suspend(struct device *dev) swrm->state = SWR_MSTR_SSR; return 0; } + mutex_lock(&swrm->runtime_lock); mutex_lock(&swrm->reslock); mutex_lock(&swrm->force_down_lock); current_state = swrm->state; @@ -3329,6 +3337,7 @@ exit: if (!hw_core_err) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); + mutex_unlock(&swrm->runtime_lock); dev_dbg(dev, "%s: pm_runtime: suspend done state: %d\n", __func__, swrm->state); pm_runtime_set_autosuspend_delay(dev, auto_suspend_timer); diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index 8cb613aaf125..1793d8bdfa09 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _SWR_WCD_CTRL_H @@ -134,6 +135,7 @@ struct swr_mstr_ctrl { struct mutex reslock; struct mutex pm_lock; struct mutex irq_lock; + struct mutex runtime_lock; u32 swrm_base_reg; char __iomem *swrm_dig_base; char __iomem *swrm_hctl_reg;