asoc: lpass-cdc: add put_autosuspend to pair with pm_runtime_get_sync
When reading/writing lpass codec registers, pm_runtime_put_autosuspend is missed when vote fails and it causes device fails suspending after ssr. Add pm_runtime_put_autosuspend to pair with pm_runtime_get_sync. When LPASS_CDC_MACRO_EVT_PRE_SSR_UP comes, core vote is needed before resetting GFMUX reg and dev_up is not set to true yet. Add pre_dev_up flag to indicate PRE_SSR_UP and be used in lpass_cdc_check_core_votes to avoid false alarm. Change-Id: Ic12ecd9645f291078e32f4921f9f77c2d85e4b8c Signed-off-by: Meng Wang <mengw@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
043966829b
commit
a8bd9abc48
@@ -1,5 +1,5 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LPASS_CDC_INTERNAL_H
|
#ifndef _LPASS_CDC_INTERNAL_H
|
||||||
@@ -56,6 +56,7 @@ struct lpass_cdc_priv {
|
|||||||
bool va_without_decimation;
|
bool va_without_decimation;
|
||||||
bool macros_supported[MAX_MACRO];
|
bool macros_supported[MAX_MACRO];
|
||||||
bool dev_up;
|
bool dev_up;
|
||||||
|
bool pre_dev_up;
|
||||||
bool initial_boot;
|
bool initial_boot;
|
||||||
struct macro_ops macro_params[MAX_MACRO];
|
struct macro_ops macro_params[MAX_MACRO];
|
||||||
struct snd_soc_dai_driver *lpass_cdc_dais;
|
struct snd_soc_dai_driver *lpass_cdc_dais;
|
||||||
|
@@ -727,8 +727,6 @@ static int lpass_cdc_va_macro_core_vote(void *handle, bool enable)
|
|||||||
if (lpass_cdc_check_core_votes(va_priv->dev)) {
|
if (lpass_cdc_check_core_votes(va_priv->dev)) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
pm_runtime_put_autosuspend(va_priv->dev);
|
|
||||||
pm_runtime_mark_last_busy(va_priv->dev);
|
|
||||||
rc = -ENOTSYNC;
|
rc = -ENOTSYNC;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@@ -108,13 +108,13 @@ static int __lpass_cdc_reg_read(struct lpass_cdc_priv *priv,
|
|||||||
mutex_lock(&priv->vote_lock);
|
mutex_lock(&priv->vote_lock);
|
||||||
if (((priv->lpass_core_hw_vote && !priv->core_hw_vote_count) ||
|
if (((priv->lpass_core_hw_vote && !priv->core_hw_vote_count) ||
|
||||||
(priv->lpass_audio_hw_vote && !priv->core_audio_vote_count))) {
|
(priv->lpass_audio_hw_vote && !priv->core_audio_vote_count))) {
|
||||||
mutex_unlock(&priv->vote_lock);
|
goto vote_err;
|
||||||
goto ssr_err;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lpass_cdc_ahb_read_device(
|
lpass_cdc_ahb_read_device(
|
||||||
priv->macro_params[macro_id].io_base, reg, val);
|
priv->macro_params[macro_id].io_base, reg, val);
|
||||||
|
|
||||||
|
vote_err:
|
||||||
if (priv->macro_params[VA_MACRO].dev) {
|
if (priv->macro_params[VA_MACRO].dev) {
|
||||||
mutex_unlock(&priv->vote_lock);
|
mutex_unlock(&priv->vote_lock);
|
||||||
pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev);
|
pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev);
|
||||||
@@ -142,13 +142,13 @@ static int __lpass_cdc_reg_write(struct lpass_cdc_priv *priv,
|
|||||||
mutex_lock(&priv->vote_lock);
|
mutex_lock(&priv->vote_lock);
|
||||||
if (((priv->lpass_core_hw_vote && !priv->core_hw_vote_count) ||
|
if (((priv->lpass_core_hw_vote && !priv->core_hw_vote_count) ||
|
||||||
(priv->lpass_audio_hw_vote && !priv->core_audio_vote_count))) {
|
(priv->lpass_audio_hw_vote && !priv->core_audio_vote_count))) {
|
||||||
mutex_unlock(&priv->vote_lock);
|
goto vote_err;
|
||||||
goto ssr_err;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lpass_cdc_ahb_write_device(
|
lpass_cdc_ahb_write_device(
|
||||||
priv->macro_params[macro_id].io_base, reg, val);
|
priv->macro_params[macro_id].io_base, reg, val);
|
||||||
|
|
||||||
|
vote_err:
|
||||||
if (priv->macro_params[VA_MACRO].dev) {
|
if (priv->macro_params[VA_MACRO].dev) {
|
||||||
mutex_unlock(&priv->vote_lock);
|
mutex_unlock(&priv->vote_lock);
|
||||||
pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev);
|
pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev);
|
||||||
@@ -848,6 +848,10 @@ static int lpass_cdc_ssr_enable(struct device *dev, void *data)
|
|||||||
}
|
}
|
||||||
trace_printk("%s: clk count reset\n", __func__);
|
trace_printk("%s: clk count reset\n", __func__);
|
||||||
|
|
||||||
|
mutex_lock(&priv->clk_lock);
|
||||||
|
priv->pre_dev_up = true;
|
||||||
|
mutex_unlock(&priv->clk_lock);
|
||||||
|
|
||||||
if (priv->rsc_clk_cb)
|
if (priv->rsc_clk_cb)
|
||||||
priv->rsc_clk_cb(priv->clk_dev, LPASS_CDC_MACRO_EVT_SSR_GFMUX_UP);
|
priv->rsc_clk_cb(priv->clk_dev, LPASS_CDC_MACRO_EVT_SSR_GFMUX_UP);
|
||||||
|
|
||||||
@@ -899,6 +903,7 @@ static void lpass_cdc_ssr_disable(struct device *dev, void *data)
|
|||||||
|
|
||||||
mutex_lock(&priv->clk_lock);
|
mutex_lock(&priv->clk_lock);
|
||||||
priv->dev_up = false;
|
priv->dev_up = false;
|
||||||
|
priv->pre_dev_up = false;
|
||||||
mutex_unlock(&priv->clk_lock);
|
mutex_unlock(&priv->clk_lock);
|
||||||
if (priv->rsc_clk_cb)
|
if (priv->rsc_clk_cb)
|
||||||
priv->rsc_clk_cb(priv->clk_dev, LPASS_CDC_MACRO_EVT_SSR_DOWN);
|
priv->rsc_clk_cb(priv->clk_dev, LPASS_CDC_MACRO_EVT_SSR_DOWN);
|
||||||
@@ -1288,6 +1293,7 @@ static int lpass_cdc_probe(struct platform_device *pdev)
|
|||||||
BLOCKING_INIT_NOTIFIER_HEAD(&priv->notifier);
|
BLOCKING_INIT_NOTIFIER_HEAD(&priv->notifier);
|
||||||
priv->dev = &pdev->dev;
|
priv->dev = &pdev->dev;
|
||||||
priv->dev_up = true;
|
priv->dev_up = true;
|
||||||
|
priv->pre_dev_up = true;
|
||||||
priv->initial_boot = true;
|
priv->initial_boot = true;
|
||||||
priv->regmap = lpass_cdc_regmap_init(priv->dev,
|
priv->regmap = lpass_cdc_regmap_init(priv->dev,
|
||||||
&lpass_cdc_regmap_config);
|
&lpass_cdc_regmap_config);
|
||||||
@@ -1451,7 +1457,7 @@ bool lpass_cdc_check_core_votes(struct device *dev)
|
|||||||
bool ret = true;
|
bool ret = true;
|
||||||
trace_printk("%s, enter\n", __func__);
|
trace_printk("%s, enter\n", __func__);
|
||||||
mutex_lock(&priv->vote_lock);
|
mutex_lock(&priv->vote_lock);
|
||||||
if (!priv->dev_up ||
|
if (!priv->pre_dev_up ||
|
||||||
(priv->lpass_core_hw_vote && !priv->core_hw_vote_count) ||
|
(priv->lpass_core_hw_vote && !priv->core_hw_vote_count) ||
|
||||||
(priv->lpass_audio_hw_vote && !priv->core_audio_vote_count))
|
(priv->lpass_audio_hw_vote && !priv->core_audio_vote_count))
|
||||||
ret = false;
|
ret = false;
|
||||||
|
Reference in New Issue
Block a user