asoc: update digital_cdc_rsc_mgr_hw_vote API

Update digital_cdc_rsc_mgr_hw_vote_enable/disable API with device
info for easy debug. Also, add swrm clock enable checks during SSR.
When SSR happens, swrm->hw_core_clk_en and swrm->aud_core_clk_en will
be reset without resetting audio_vote and core_vote clk. This would
cause clk mismatch in audio driver and adsp and device fails suspending
when there's no audio usecase. Make this change to reset audio_vote
and core_vote clk when receiving SWR_DEVICE_SSR_DOWN.

Change-Id: I9875aac9f6faf8b6481457a70f31b005073369e0
Signed-off-by: Meng Wang <quic_mengw@quicinc.com>
This commit is contained in:
Meng Wang
2021-12-21 09:12:31 +08:00
committed by Gerrit - the friendly Code Review server
부모 42e49611b0
커밋 95c95b2d67
6개의 변경된 파일34개의 추가작업 그리고 22개의 파일을 삭제

파일 보기

@@ -1383,7 +1383,7 @@ int lpass_cdc_runtime_resume(struct device *dev)
}
if (priv->core_hw_vote_count == 0) {
ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_core_hw_vote);
ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_core_hw_vote, dev);
if (ret < 0) {
dev_err_ratelimited(dev, "%s:lpass core hw enable failed\n",
__func__);
@@ -1401,7 +1401,7 @@ audio_vote:
}
if (priv->core_audio_vote_count == 0) {
ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_audio_hw_vote);
ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_audio_hw_vote, dev);
if (ret < 0) {
dev_err_ratelimited(dev, "%s:lpass audio hw enable failed\n",
__func__);
@@ -1429,7 +1429,7 @@ int lpass_cdc_runtime_suspend(struct device *dev)
if (priv->lpass_core_hw_vote != NULL) {
if (--priv->core_hw_vote_count == 0)
digital_cdc_rsc_mgr_hw_vote_disable(
priv->lpass_core_hw_vote);
priv->lpass_core_hw_vote, dev);
if (priv->core_hw_vote_count < 0)
priv->core_hw_vote_count = 0;
} else {
@@ -1442,7 +1442,7 @@ int lpass_cdc_runtime_suspend(struct device *dev)
if (priv->lpass_audio_hw_vote != NULL) {
if (--priv->core_audio_vote_count == 0)
digital_cdc_rsc_mgr_hw_vote_disable(
priv->lpass_audio_hw_vote);
priv->lpass_audio_hw_vote, dev);
if (priv->core_audio_vote_count < 0)
priv->core_audio_vote_count = 0;
} else {

파일 보기

@@ -366,7 +366,7 @@ int mi2s_tdm_hw_vote_req(struct msm_common_pdata *pdata, int enable)
if (enable) {
if (atomic_read(&pdata->lpass_audio_hw_vote_ref_cnt) == 0) {
ret = digital_cdc_rsc_mgr_hw_vote_enable(pdata->lpass_audio_hw_vote);
ret = digital_cdc_rsc_mgr_hw_vote_enable(pdata->lpass_audio_hw_vote, NULL);
if (ret < 0) {
pr_err("%s lpass audio hw vote enable failed %d\n",
__func__, ret);
@@ -377,7 +377,7 @@ int mi2s_tdm_hw_vote_req(struct msm_common_pdata *pdata, int enable)
} else {
atomic_dec(&pdata->lpass_audio_hw_vote_ref_cnt);
if (atomic_read(&pdata->lpass_audio_hw_vote_ref_cnt) == 0)
digital_cdc_rsc_mgr_hw_vote_disable(pdata->lpass_audio_hw_vote);
digital_cdc_rsc_mgr_hw_vote_disable(pdata->lpass_audio_hw_vote, NULL);
else if (atomic_read(&pdata->lpass_audio_hw_vote_ref_cnt) < 0)
atomic_set(&pdata->lpass_audio_hw_vote_ref_cnt, 0);
}

파일 보기

@@ -1,12 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-only */
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/ratelimit.h>
#include <dsp/digital-cdc-rsc-mgr.h>
#include <linux/dev_printk.h>
struct mutex hw_vote_lock;
static bool is_init_done;
@@ -15,10 +17,11 @@ static bool is_init_done;
* digital_cdc_rsc_mgr_hw_vote_enable - Enables hw vote in DSP
*
* @vote_handle: vote handle for which voting needs to be done
* @dev: indicate which device votes
*
* Returns 0 on success or -EINVAL/error code on failure
*/
int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle)
int digital_cdc_rsc_mgr_hw_vote_enable(struct clk *vote_handle, struct device *dev)
{
int ret = 0;
@@ -32,7 +35,7 @@ int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle)
ret = clk_prepare_enable(vote_handle);
mutex_unlock(&hw_vote_lock);
pr_debug("%s: return %d\n", __func__, ret);
dev_dbg(dev, "%s: return %d\n", __func__, ret);
trace_printk("%s: return %d\n", __func__, ret);
return ret;
}
@@ -42,9 +45,10 @@ EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_enable);
* digital_cdc_rsc_mgr_hw_vote_disable - Disables hw vote in DSP
*
* @vote_handle: vote handle for which voting needs to be disabled
* @dev: indicate which device unvotes
*
*/
void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle)
void digital_cdc_rsc_mgr_hw_vote_disable(struct clk *vote_handle, struct device *dev)
{
if (!is_init_done || vote_handle == NULL) {
pr_err_ratelimited("%s: init failed or vote handle NULL\n",
@@ -55,6 +59,7 @@ void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle)
mutex_lock(&hw_vote_lock);
clk_disable_unprepare(vote_handle);
mutex_unlock(&hw_vote_lock);
dev_dbg(dev, "%s: leave\n", __func__);
trace_printk("%s\n", __func__);
}
EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_disable);

파일 보기

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef DIGITAL_CDC_RSC_MGR_H
@@ -10,25 +11,25 @@
#ifdef CONFIG_DIGITAL_CDC_RSC_MGR
int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle);
void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle);
void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle);
int digital_cdc_rsc_mgr_hw_vote_enable(struct clk *vote_handle, struct device *dev);
void digital_cdc_rsc_mgr_hw_vote_disable(struct clk *vote_handle, struct device *dev);
void digital_cdc_rsc_mgr_hw_vote_reset(struct clk *vote_handle);
void digital_cdc_rsc_mgr_init(void);
void digital_cdc_rsc_mgr_exit(void);
#else
static inline int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle)
static inline int digital_cdc_rsc_mgr_hw_vote_enable(struct clk *vote_handle, struct device *dev)
{
return 0;
}
static inline void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle)
static inline void digital_cdc_rsc_mgr_hw_vote_disable(struct clk *vote_handle, struct device *dev)
{
}
static inline void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle)
static inline void digital_cdc_rsc_mgr_hw_vote_reset(struct clk *vote_handle)
{
}

파일 보기

@@ -905,7 +905,7 @@ int lpi_pinctrl_runtime_resume(struct device *dev)
}
mutex_lock(&state->core_hw_vote_lock);
ret = digital_cdc_rsc_mgr_hw_vote_enable(hw_vote);
ret = digital_cdc_rsc_mgr_hw_vote_enable(hw_vote, dev);
if (ret < 0) {
pm_runtime_set_autosuspend_delay(dev,
LPI_AUTO_SUSPEND_DELAY_ERROR);
@@ -941,7 +941,7 @@ int lpi_pinctrl_runtime_suspend(struct device *dev)
mutex_lock(&state->core_hw_vote_lock);
if (state->core_hw_vote_status) {
digital_cdc_rsc_mgr_hw_vote_disable(hw_vote);
digital_cdc_rsc_mgr_hw_vote_disable(hw_vote, dev);
state->core_hw_vote_status = false;
}
mutex_unlock(&state->core_hw_vote_lock);

파일 보기

@@ -425,7 +425,7 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
if (++swrm->hw_core_clk_en == 1) {
ret =
digital_cdc_rsc_mgr_hw_vote_enable(
swrm->lpass_core_hw_vote);
swrm->lpass_core_hw_vote, swrm->dev);
if (ret < 0) {
dev_err_ratelimited(swrm->dev,
"%s:lpass core hw enable failed\n",
@@ -439,7 +439,7 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
swrm->hw_core_clk_en = 0;
else if (swrm->hw_core_clk_en == 0)
digital_cdc_rsc_mgr_hw_vote_disable(
swrm->lpass_core_hw_vote);
swrm->lpass_core_hw_vote, swrm->dev);
}
}
}
@@ -457,7 +457,7 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
if (++swrm->aud_core_clk_en == 1) {
ret =
digital_cdc_rsc_mgr_hw_vote_enable(
swrm->lpass_core_audio);
swrm->lpass_core_audio, swrm->dev);
if (ret < 0) {
dev_err_ratelimited(swrm->dev,
"%s:lpass audio hw enable failed\n",
@@ -471,7 +471,7 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
swrm->aud_core_clk_en = 0;
else if (swrm->aud_core_clk_en == 0)
digital_cdc_rsc_mgr_hw_vote_disable(
swrm->lpass_core_audio);
swrm->lpass_core_audio, swrm->dev);
}
}
}
@@ -3681,7 +3681,13 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
swrm_device_down(&pdev->dev);
mutex_lock(&swrm->devlock);
swrm->dev_up = false;
if (swrm->hw_core_clk_en)
digital_cdc_rsc_mgr_hw_vote_disable(
swrm->lpass_core_hw_vote, swrm->dev);
swrm->hw_core_clk_en = 0;
if (swrm->aud_core_clk_en)
digital_cdc_rsc_mgr_hw_vote_disable(
swrm->lpass_core_audio, swrm->dev);
swrm->aud_core_clk_en = 0;
mutex_unlock(&swrm->devlock);
mutex_lock(&swrm->reslock);