From 66d6fd1364243ab37b63147e6fc4807ed3d9f1e0 Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Wed, 27 Mar 2019 17:34:48 +0530 Subject: [PATCH] soundwire: Vote for LPASS HW Core before soundwire register access Vote for LPASS HW core before soundwire register access to avoid register access violations. Change-Id: Ie7ff73bbab64825bf07736f11ef9685e732fc8ae Signed-off-by: Sudheer Papothi --- soc/swr-mstr-ctrl.c | 32 ++++++++++++++++++++++++++++++++ soc/swr-mstr-ctrl.h | 1 + 2 files changed, 33 insertions(+) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 8d82ff1ec7..26965a3ee9 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -1441,6 +1441,8 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) } mutex_lock(&swrm->reslock); + if (swrm->lpass_core_hw_vote) + clk_prepare_enable(swrm->lpass_core_hw_vote); swrm_clk_request(swrm, true); mutex_unlock(&swrm->reslock); @@ -1608,6 +1610,8 @@ handle_irq: mutex_lock(&swrm->reslock); swrm_clk_request(swrm, false); + if (swrm->lpass_core_hw_vote) + clk_disable_unprepare(swrm->lpass_core_hw_vote); mutex_unlock(&swrm->reslock); swrm_unlock_sleep(swrm); return ret; @@ -1897,6 +1901,7 @@ static int swrm_probe(struct platform_device *pdev) u32 i, num_ports, port_num, port_type, ch_mask; u32 *temp, map_size, map_length, ch_iter = 0, old_port_num = 0; int ret = 0; + struct clk *lpass_core_hw_vote = NULL; /* Allocate soundwire master driver structure */ swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl), @@ -2136,6 +2141,17 @@ static int swrm_probe(struct platform_device *pdev) if (pdev->dev.of_node) of_register_swr_devices(&swrm->master); + /* Register LPASS core hw vote */ + lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote"); + if (IS_ERR(lpass_core_hw_vote)) { + ret = PTR_ERR(lpass_core_hw_vote); + dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n", + __func__, "lpass_core_hw_vote", ret); + lpass_core_hw_vote = NULL; + ret = 0; + } + swrm->lpass_core_hw_vote = lpass_core_hw_vote; + dbgswrm = swrm; debugfs_swrm_dent = debugfs_create_dir(dev_name(&pdev->dev), 0); if (!IS_ERR(debugfs_swrm_dent)) { @@ -2236,6 +2252,12 @@ static int swrm_runtime_resume(struct device *dev) __func__, swrm->state); mutex_lock(&swrm->reslock); + if (swrm->lpass_core_hw_vote) + ret = clk_prepare_enable(swrm->lpass_core_hw_vote); + if (ret < 0) + dev_err(dev, "%s:lpass core hw enable failed\n", + __func__); + if ((swrm->state == SWR_MSTR_DOWN) || (swrm->state == SWR_MSTR_SSR && swrm->dev_up)) { if (swrm->clk_stop_mode0_supp) { @@ -2272,6 +2294,8 @@ static int swrm_runtime_resume(struct device *dev) swrm->state = SWR_MSTR_UP; } exit: + if (swrm->lpass_core_hw_vote) + clk_disable_unprepare(swrm->lpass_core_hw_vote); pm_runtime_set_autosuspend_delay(&pdev->dev, auto_suspend_timer); mutex_unlock(&swrm->reslock); return ret; @@ -2292,6 +2316,12 @@ static int swrm_runtime_suspend(struct device *dev) mutex_lock(&swrm->force_down_lock); current_state = swrm->state; mutex_unlock(&swrm->force_down_lock); + if (swrm->lpass_core_hw_vote) + ret = clk_prepare_enable(swrm->lpass_core_hw_vote); + if (ret < 0) + dev_err(dev, "%s:lpass core hw enable failed\n", + __func__); + if ((current_state == SWR_MSTR_UP) || (current_state == SWR_MSTR_SSR)) { @@ -2337,6 +2367,8 @@ static int swrm_runtime_suspend(struct device *dev) if (current_state != SWR_MSTR_SSR) swrm->state = SWR_MSTR_DOWN; exit: + if (swrm->lpass_core_hw_vote) + clk_disable_unprepare(swrm->lpass_core_hw_vote); mutex_unlock(&swrm->reslock); return ret; } diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h index fab66c39d2..96aa048e0e 100644 --- a/soc/swr-mstr-ctrl.h +++ b/soc/swr-mstr-ctrl.h @@ -154,6 +154,7 @@ struct swr_mstr_ctrl { int wlock_holders; u32 intr_mask; struct port_params **port_param; + struct clk *lpass_core_hw_vote; u8 num_usecase; };