soc: mstr-ctrl: Retain Audio_HM voting until suspend

Restore change to retain audio_hm voting and
ensure AOP hang issue not seen by masking interrupt
wakeup of swr pinctrl pins.

Change-Id: I51bf36d6d6b0999abf10a4bc94cce900d1adf1d5
Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
This commit is contained in:
Laxminath Kasam
2020-04-28 00:02:32 +05:30
parent 61f235e5bd
commit d02c7efb35
6 changed files with 51 additions and 18 deletions

View File

@@ -378,6 +378,7 @@ struct rx_swr_ctrl_platform_data {
void *data), void *data),
void *swrm_handle, void *swrm_handle,
int action); int action);
int (*pinctrl_setup)(void *handle, bool enable);
}; };
enum { enum {
@@ -4104,6 +4105,7 @@ static int rx_macro_probe(struct platform_device *pdev)
rx_priv->swr_plat_data.clk = rx_swrm_clock; rx_priv->swr_plat_data.clk = rx_swrm_clock;
rx_priv->swr_plat_data.core_vote = rx_macro_core_vote; rx_priv->swr_plat_data.core_vote = rx_macro_core_vote;
rx_priv->swr_plat_data.handle_irq = NULL; rx_priv->swr_plat_data.handle_irq = NULL;
rx_priv->swr_plat_data.pinctrl_setup = NULL;
ret = of_property_read_u8_array(pdev->dev.of_node, ret = of_property_read_u8_array(pdev->dev.of_node,
"qcom,rx-bcl-pmic-params", bcl_pmic_params, "qcom,rx-bcl-pmic-params", bcl_pmic_params,

View File

@@ -81,6 +81,7 @@ struct tx_macro_swr_ctrl_platform_data {
void *data), void *data),
void *swrm_handle, void *swrm_handle,
int action); int action);
int (*pinctrl_setup)(void *handle, bool enable);
}; };
enum { enum {
@@ -2496,12 +2497,30 @@ static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
tx_macro_get_bcs, tx_macro_set_bcs), tx_macro_get_bcs, tx_macro_set_bcs),
}; };
static int tx_macro_pinctrl_setup(void *handle, bool enable)
{
struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
if (tx_priv == NULL) {
pr_err("%s: tx priv data is NULL\n", __func__);
return -EINVAL;
}
if (enable)
msm_cdc_pinctrl_set_wakeup_capable(
tx_priv->tx_swr_gpio_p, true);
else
msm_cdc_pinctrl_set_wakeup_capable(
tx_priv->tx_swr_gpio_p, false);
return 0;
}
static int tx_macro_register_event_listener(struct snd_soc_component *component, static int tx_macro_register_event_listener(struct snd_soc_component *component,
bool enable, bool is_dmic_sva) bool enable, bool is_dmic_sva)
{ {
struct device *tx_dev = NULL; struct device *tx_dev = NULL;
struct tx_macro_priv *tx_priv = NULL; struct tx_macro_priv *tx_priv = NULL;
int ret = 0; int ret = 0;
u32 dmic_sva = is_dmic_sva;
if (!component) if (!component)
return -EINVAL; return -EINVAL;
@@ -2523,17 +2542,17 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component,
if (enable) { if (enable) {
ret = swrm_wcd_notify( ret = swrm_wcd_notify(
tx_priv->swr_ctrl_data[0].tx_swr_pdev, tx_priv->swr_ctrl_data[0].tx_swr_pdev,
SWR_REGISTER_WAKEUP, NULL); SWR_REGISTER_WAKEUP, &dmic_sva);
if (!is_dmic_sva) msm_cdc_pinctrl_set_wakeup_capable(
msm_cdc_pinctrl_set_wakeup_capable( tx_priv->tx_swr_gpio_p, false);
tx_priv->tx_swr_gpio_p, false);
} else { } else {
if (!is_dmic_sva) /* while teardown we can reset the flag */
msm_cdc_pinctrl_set_wakeup_capable( dmic_sva = 0;
tx_priv->tx_swr_gpio_p, true); msm_cdc_pinctrl_set_wakeup_capable(
tx_priv->tx_swr_gpio_p, true);
ret = swrm_wcd_notify( ret = swrm_wcd_notify(
tx_priv->swr_ctrl_data[0].tx_swr_pdev, tx_priv->swr_ctrl_data[0].tx_swr_pdev,
SWR_DEREGISTER_WAKEUP, NULL); SWR_DEREGISTER_WAKEUP, &dmic_sva);
} }
} }
@@ -3324,6 +3343,7 @@ static int tx_macro_probe(struct platform_device *pdev)
tx_priv->swr_plat_data.clk = tx_macro_swrm_clock; tx_priv->swr_plat_data.clk = tx_macro_swrm_clock;
tx_priv->swr_plat_data.core_vote = tx_macro_core_vote; tx_priv->swr_plat_data.core_vote = tx_macro_core_vote;
tx_priv->swr_plat_data.handle_irq = NULL; tx_priv->swr_plat_data.handle_irq = NULL;
tx_priv->swr_plat_data.pinctrl_setup = tx_macro_pinctrl_setup;
mutex_init(&tx_priv->swr_clk_lock); mutex_init(&tx_priv->swr_clk_lock);
} }
tx_priv->is_used_tx_swr_gpio = is_used_tx_swr_gpio; tx_priv->is_used_tx_swr_gpio = is_used_tx_swr_gpio;

View File

@@ -130,6 +130,7 @@ struct va_macro_swr_ctrl_platform_data {
void *data), void *data),
void *swrm_handle, void *swrm_handle,
int action); int action);
int (*pinctrl_setup)(void *handle, bool enable);
}; };
struct va_macro_priv { struct va_macro_priv {
@@ -3229,6 +3230,7 @@ static int va_macro_probe(struct platform_device *pdev)
va_priv->swr_plat_data.clk = va_macro_swrm_clock; va_priv->swr_plat_data.clk = va_macro_swrm_clock;
va_priv->swr_plat_data.core_vote = va_macro_core_vote; va_priv->swr_plat_data.core_vote = va_macro_core_vote;
va_priv->swr_plat_data.handle_irq = NULL; va_priv->swr_plat_data.handle_irq = NULL;
va_priv->swr_plat_data.pinctrl_setup = NULL;
mutex_init(&va_priv->swr_clk_lock); mutex_init(&va_priv->swr_clk_lock);
} }
va_priv->is_used_va_swr_gpio = is_used_va_swr_gpio; va_priv->is_used_va_swr_gpio = is_used_va_swr_gpio;

View File

@@ -166,6 +166,7 @@ struct wsa_macro_swr_ctrl_platform_data {
void *data), void *data),
void *swrm_handle, void *swrm_handle,
int action); int action);
int (*pinctrl_setup)(void *handle, bool enable);
}; };
struct wsa_macro_bcl_pmic_params { struct wsa_macro_bcl_pmic_params {
@@ -3194,6 +3195,7 @@ static int wsa_macro_probe(struct platform_device *pdev)
wsa_priv->swr_plat_data.clk = wsa_swrm_clock; wsa_priv->swr_plat_data.clk = wsa_swrm_clock;
wsa_priv->swr_plat_data.core_vote = wsa_macro_core_vote; wsa_priv->swr_plat_data.core_vote = wsa_macro_core_vote;
wsa_priv->swr_plat_data.handle_irq = NULL; wsa_priv->swr_plat_data.handle_irq = NULL;
wsa_priv->swr_plat_data.pinctrl_setup = NULL;
ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id", ret = of_property_read_u32(pdev->dev.of_node, "qcom,default-clk-id",
&default_clk_id); &default_clk_id);

View File

@@ -2458,6 +2458,8 @@ static int swrm_probe(struct platform_device *pdev)
ret = -EINVAL; ret = -EINVAL;
goto err_pdata_fail; goto err_pdata_fail;
} }
swrm->pinctrl_setup = pdata->pinctrl_setup;
if (of_property_read_u32(pdev->dev.of_node, if (of_property_read_u32(pdev->dev.of_node,
"qcom,swr-clock-stop-mode0", "qcom,swr-clock-stop-mode0",
&swrm->clk_stop_mode0_supp)) { &swrm->clk_stop_mode0_supp)) {
@@ -2779,7 +2781,6 @@ static int swrm_runtime_resume(struct device *dev)
int ret = 0; int ret = 0;
bool swrm_clk_req_err = false; bool swrm_clk_req_err = false;
bool hw_core_err = false; bool hw_core_err = false;
bool aud_core_err = false;
struct swr_master *mstr = &swrm->master; struct swr_master *mstr = &swrm->master;
struct swr_device *swr_dev; struct swr_device *swr_dev;
u32 temp = 0; u32 temp = 0;
@@ -2798,7 +2799,7 @@ static int swrm_runtime_resume(struct device *dev)
if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) {
dev_err(dev, "%s:lpass audio hw enable failed\n", dev_err(dev, "%s:lpass audio hw enable failed\n",
__func__); __func__);
aud_core_err = true; swrm->aud_core_err = true;
} }
if ((swrm->state == SWR_MSTR_DOWN) || if ((swrm->state == SWR_MSTR_DOWN) ||
@@ -2817,6 +2818,9 @@ static int swrm_runtime_resume(struct device *dev)
irq_get_irq_data(swrm->wake_irq))) irq_get_irq_data(swrm->wake_irq)))
disable_irq_nosync(swrm->wake_irq); disable_irq_nosync(swrm->wake_irq);
mutex_unlock(&swrm->irq_lock); mutex_unlock(&swrm->irq_lock);
if (swrm->dmic_sva && swrm->pinctrl_setup)
swrm->pinctrl_setup(swrm->handle,
false);
} }
if (swrm->ipc_wakeup) if (swrm->ipc_wakeup)
msm_aud_evt_blocking_notifier_call_chain( msm_aud_evt_blocking_notifier_call_chain(
@@ -2890,7 +2894,7 @@ static int swrm_runtime_resume(struct device *dev)
swrm->state = SWR_MSTR_UP; swrm->state = SWR_MSTR_UP;
} }
exit: exit:
if (!aud_core_err) if (ret && !swrm->aud_core_err)
swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false);
if (!hw_core_err) if (!hw_core_err)
swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
@@ -2913,7 +2917,6 @@ static int swrm_runtime_suspend(struct device *dev)
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev); struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
int ret = 0; int ret = 0;
bool hw_core_err = false; bool hw_core_err = false;
bool aud_core_err = false;
struct swr_master *mstr = &swrm->master; struct swr_master *mstr = &swrm->master;
struct swr_device *swr_dev; struct swr_device *swr_dev;
int current_state = 0; int current_state = 0;
@@ -2932,11 +2935,6 @@ static int swrm_runtime_suspend(struct device *dev)
__func__); __func__);
hw_core_err = true; hw_core_err = true;
} }
if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) {
dev_err(dev, "%s:lpass audio hw enable failed\n",
__func__);
aud_core_err = true;
}
if ((current_state == SWR_MSTR_UP) || if ((current_state == SWR_MSTR_UP) ||
(current_state == SWR_MSTR_SSR)) { (current_state == SWR_MSTR_SSR)) {
@@ -3005,6 +3003,8 @@ static int swrm_runtime_suspend(struct device *dev)
if (swrm->clk_stop_mode0_supp) { if (swrm->clk_stop_mode0_supp) {
if (swrm->wake_irq > 0) { if (swrm->wake_irq > 0) {
if (swrm->dmic_sva && swrm->pinctrl_setup)
swrm->pinctrl_setup(swrm->handle, true);
enable_irq(swrm->wake_irq); enable_irq(swrm->wake_irq);
} else if (swrm->ipc_wakeup) { } else if (swrm->ipc_wakeup) {
msm_aud_evt_blocking_notifier_call_chain( msm_aud_evt_blocking_notifier_call_chain(
@@ -3018,10 +3018,11 @@ static int swrm_runtime_suspend(struct device *dev)
if (current_state != SWR_MSTR_SSR) if (current_state != SWR_MSTR_SSR)
swrm->state = SWR_MSTR_DOWN; swrm->state = SWR_MSTR_DOWN;
exit: exit:
if (!aud_core_err) if (!swrm->aud_core_err)
swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false);
if (!hw_core_err) if (!hw_core_err)
swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
swrm->aud_core_err = false;
mutex_unlock(&swrm->reslock); mutex_unlock(&swrm->reslock);
trace_printk("%s: pm_runtime: suspend done state: %d\n", trace_printk("%s: pm_runtime: suspend done state: %d\n",
__func__, swrm->state); __func__, swrm->state);
@@ -3353,10 +3354,12 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
case SWR_REGISTER_WAKEUP: case SWR_REGISTER_WAKEUP:
msm_aud_evt_blocking_notifier_call_chain( msm_aud_evt_blocking_notifier_call_chain(
SWR_WAKE_IRQ_REGISTER, (void *)swrm); SWR_WAKE_IRQ_REGISTER, (void *)swrm);
swrm->dmic_sva = *(u32 *)data;
break; break;
case SWR_DEREGISTER_WAKEUP: case SWR_DEREGISTER_WAKEUP:
msm_aud_evt_blocking_notifier_call_chain( msm_aud_evt_blocking_notifier_call_chain(
SWR_WAKE_IRQ_DEREGISTER, (void *)swrm); SWR_WAKE_IRQ_DEREGISTER, (void *)swrm);
swrm->dmic_sva = 0;
break; break;
case SWR_SET_PORT_MAP: case SWR_SET_PORT_MAP:
if (!data) { if (!data) {

View File

@@ -115,6 +115,7 @@ struct swr_ctrl_platform_data {
int (*core_vote)(void *handle, bool enable); int (*core_vote)(void *handle, bool enable);
int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq,
void *data), void *swr_handle, int type); void *data), void *swr_handle, int type);
int (*pinctrl_setup)(void *handle, bool enable);
}; };
struct swr_mstr_ctrl { struct swr_mstr_ctrl {
@@ -148,6 +149,7 @@ struct swr_mstr_ctrl {
int (*core_vote)(void *handle, bool enable); int (*core_vote)(void *handle, bool enable);
int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq, int (*reg_irq)(void *handle, irqreturn_t(*irq_handler)(int irq,
void *data), void *swr_handle, int type); void *data), void *swr_handle, int type);
int (*pinctrl_setup)(void *handle, bool enable);
int irq; int irq;
int wake_irq; int wake_irq;
int version; int version;
@@ -173,8 +175,10 @@ struct swr_mstr_ctrl {
u32 clk_stop_mode0_supp; u32 clk_stop_mode0_supp;
struct work_struct wakeup_work; struct work_struct wakeup_work;
u32 ipc_wakeup; u32 ipc_wakeup;
u32 dmic_sva;
bool dev_up; bool dev_up;
bool ipc_wakeup_triggered; bool ipc_wakeup_triggered;
bool aud_core_err;
struct pm_qos_request pm_qos_req; struct pm_qos_request pm_qos_req;
enum swrm_pm_state pm_state; enum swrm_pm_state pm_state;
wait_queue_head_t pm_wq; wait_queue_head_t pm_wq;