Loading soc/swr-mstr-ctrl.c +80 −47 Original line number Diff line number Diff line Loading @@ -364,33 +364,77 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, { int ret = 0; mutex_lock(&swrm->devlock); if (core_type == LPASS_HW_CORE) { if (swrm->lpass_core_hw_vote) { if (enable) { if (!swrm->dev_up) { dev_dbg(swrm->dev, "%s: device is down or SSR state\n", __func__); trace_printk("%s: device is down or SSR state\n", __func__); mutex_unlock(&swrm->devlock); return -ENODEV; } if (++swrm->hw_core_clk_en == 1) { ret = clk_prepare_enable(swrm->lpass_core_hw_vote); if (ret < 0) clk_prepare_enable( swrm->lpass_core_hw_vote); if (ret < 0) { dev_err(swrm->dev, "%s:lpass core hw enable failed\n", __func__); } else clk_disable_unprepare(swrm->lpass_core_hw_vote); --swrm->hw_core_clk_en; } } } else { --swrm->hw_core_clk_en; if (swrm->hw_core_clk_en < 0) swrm->hw_core_clk_en = 0; else if (swrm->hw_core_clk_en == 0) clk_disable_unprepare( swrm->lpass_core_hw_vote); } } } if (core_type == LPASS_AUDIO_CORE) { if (swrm->lpass_core_audio) { if (enable) { if (!swrm->dev_up) { dev_dbg(swrm->dev, "%s: device is down or SSR state\n", __func__); trace_printk("%s: device is down or SSR state\n", __func__); mutex_unlock(&swrm->devlock); return -ENODEV; } if (++swrm->aud_core_clk_en == 1) { ret = clk_prepare_enable(swrm->lpass_core_audio); if (ret < 0) clk_prepare_enable( swrm->lpass_core_audio); if (ret < 0) { dev_err(swrm->dev, "%s:lpass audio hw enable failed\n", __func__); } else clk_disable_unprepare(swrm->lpass_core_audio); --swrm->aud_core_clk_en; } } } else { --swrm->aud_core_clk_en; if (swrm->aud_core_clk_en < 0) swrm->aud_core_clk_en = 0; else if (swrm->aud_core_clk_en == 0) clk_disable_unprepare( swrm->lpass_core_audio); } } } mutex_unlock(&swrm->devlock); dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); return ret; } Loading Loading @@ -1864,6 +1908,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) return IRQ_NONE; } mutex_lock(&swrm->ssr_lock); mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { ret = IRQ_NONE; Loading Loading @@ -2077,6 +2122,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); exit: mutex_unlock(&swrm->reslock); mutex_unlock(&swrm->ssr_lock); swrm_unlock_sleep(swrm); trace_printk("%s exit\n", __func__); return ret; Loading Loading @@ -2253,22 +2299,15 @@ static void swrm_device_wakeup_vote(struct swr_master *mstr) dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); return; } if (++swrm->hw_core_clk_en == 1) if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) dev_err(swrm->dev, "%s:lpass core hw enable failed\n", __func__); --swrm->hw_core_clk_en; } if ( ++swrm->aud_core_clk_en == 1) if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) dev_err(swrm->dev, "%s:lpass audio hw enable failed\n", __func__); --swrm->aud_core_clk_en; } dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); mutex_unlock(&swrm->reslock); pm_runtime_get_sync(swrm->dev); } Loading @@ -2283,22 +2322,11 @@ static void swrm_device_wakeup_unvote(struct swr_master *mstr) } pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); --swrm->aud_core_clk_en; if (swrm->aud_core_clk_en < 0) swrm->aud_core_clk_en = 0; else if (swrm->aud_core_clk_en == 0) mutex_lock(&swrm->reslock); swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); --swrm->hw_core_clk_en; if (swrm->hw_core_clk_en < 0) swrm->hw_core_clk_en = 0; else if (swrm->hw_core_clk_en == 0) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); swrm_unlock_sleep(swrm); } Loading Loading @@ -2627,6 +2655,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->ssr_lock); swrm->wlock_holders = 0; swrm->pm_state = SWRM_PM_SLEEPABLE; init_waitqueue_head(&swrm->pm_wq); Loading Loading @@ -2775,6 +2804,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_destroy(&swrm->iolock); mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->pm_lock); mutex_destroy(&swrm->ssr_lock); pm_qos_remove_request(&swrm->pm_qos_req); err_pdata_fail: Loading Loading @@ -2808,6 +2838,7 @@ static int swrm_remove(struct platform_device *pdev) mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->pm_lock); mutex_destroy(&swrm->ssr_lock); pm_qos_remove_request(&swrm->pm_qos_req); devm_kfree(&pdev->dev, swrm); return 0; Loading Loading @@ -3294,6 +3325,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_SSR_DOWN: trace_printk("%s: swr device down called\n", __func__); mutex_lock(&swrm->ssr_lock); mutex_lock(&swrm->mlock); if (swrm->state == SWR_MSTR_DOWN) dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", Loading @@ -3307,6 +3339,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) swrm->state = SWR_MSTR_SSR; mutex_unlock(&swrm->reslock); mutex_unlock(&swrm->mlock); mutex_unlock(&swrm->ssr_lock); break; case SWR_DEVICE_SSR_UP: /* wait for clk voting to be zero */ Loading soc/swr-mstr-ctrl.h +1 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,7 @@ struct swr_mstr_ctrl { struct mutex reslock; struct mutex pm_lock; struct mutex irq_lock; struct mutex ssr_lock; u32 swrm_base_reg; char __iomem *swrm_dig_base; char __iomem *swrm_hctl_reg; Loading Loading
soc/swr-mstr-ctrl.c +80 −47 Original line number Diff line number Diff line Loading @@ -364,33 +364,77 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm, { int ret = 0; mutex_lock(&swrm->devlock); if (core_type == LPASS_HW_CORE) { if (swrm->lpass_core_hw_vote) { if (enable) { if (!swrm->dev_up) { dev_dbg(swrm->dev, "%s: device is down or SSR state\n", __func__); trace_printk("%s: device is down or SSR state\n", __func__); mutex_unlock(&swrm->devlock); return -ENODEV; } if (++swrm->hw_core_clk_en == 1) { ret = clk_prepare_enable(swrm->lpass_core_hw_vote); if (ret < 0) clk_prepare_enable( swrm->lpass_core_hw_vote); if (ret < 0) { dev_err(swrm->dev, "%s:lpass core hw enable failed\n", __func__); } else clk_disable_unprepare(swrm->lpass_core_hw_vote); --swrm->hw_core_clk_en; } } } else { --swrm->hw_core_clk_en; if (swrm->hw_core_clk_en < 0) swrm->hw_core_clk_en = 0; else if (swrm->hw_core_clk_en == 0) clk_disable_unprepare( swrm->lpass_core_hw_vote); } } } if (core_type == LPASS_AUDIO_CORE) { if (swrm->lpass_core_audio) { if (enable) { if (!swrm->dev_up) { dev_dbg(swrm->dev, "%s: device is down or SSR state\n", __func__); trace_printk("%s: device is down or SSR state\n", __func__); mutex_unlock(&swrm->devlock); return -ENODEV; } if (++swrm->aud_core_clk_en == 1) { ret = clk_prepare_enable(swrm->lpass_core_audio); if (ret < 0) clk_prepare_enable( swrm->lpass_core_audio); if (ret < 0) { dev_err(swrm->dev, "%s:lpass audio hw enable failed\n", __func__); } else clk_disable_unprepare(swrm->lpass_core_audio); --swrm->aud_core_clk_en; } } } else { --swrm->aud_core_clk_en; if (swrm->aud_core_clk_en < 0) swrm->aud_core_clk_en = 0; else if (swrm->aud_core_clk_en == 0) clk_disable_unprepare( swrm->lpass_core_audio); } } } mutex_unlock(&swrm->devlock); dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); return ret; } Loading Loading @@ -1864,6 +1908,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) return IRQ_NONE; } mutex_lock(&swrm->ssr_lock); mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { ret = IRQ_NONE; Loading Loading @@ -2077,6 +2122,7 @@ static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); exit: mutex_unlock(&swrm->reslock); mutex_unlock(&swrm->ssr_lock); swrm_unlock_sleep(swrm); trace_printk("%s exit\n", __func__); return ret; Loading Loading @@ -2253,22 +2299,15 @@ static void swrm_device_wakeup_vote(struct swr_master *mstr) dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__); return; } if (++swrm->hw_core_clk_en == 1) if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) { mutex_lock(&swrm->reslock); if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) dev_err(swrm->dev, "%s:lpass core hw enable failed\n", __func__); --swrm->hw_core_clk_en; } if ( ++swrm->aud_core_clk_en == 1) if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) { if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) dev_err(swrm->dev, "%s:lpass audio hw enable failed\n", __func__); --swrm->aud_core_clk_en; } dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); mutex_unlock(&swrm->reslock); pm_runtime_get_sync(swrm->dev); } Loading @@ -2283,22 +2322,11 @@ static void swrm_device_wakeup_unvote(struct swr_master *mstr) } pm_runtime_mark_last_busy(swrm->dev); pm_runtime_put_autosuspend(swrm->dev); dev_dbg(swrm->dev, "%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); trace_printk("%s: hw_clk_en: %d audio_core_clk_en: %d\n", __func__, swrm->hw_core_clk_en, swrm->aud_core_clk_en); --swrm->aud_core_clk_en; if (swrm->aud_core_clk_en < 0) swrm->aud_core_clk_en = 0; else if (swrm->aud_core_clk_en == 0) mutex_lock(&swrm->reslock); swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false); --swrm->hw_core_clk_en; if (swrm->hw_core_clk_en < 0) swrm->hw_core_clk_en = 0; else if (swrm->hw_core_clk_en == 0) swrm_request_hw_vote(swrm, LPASS_HW_CORE, false); mutex_unlock(&swrm->reslock); swrm_unlock_sleep(swrm); } Loading Loading @@ -2627,6 +2655,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->ssr_lock); swrm->wlock_holders = 0; swrm->pm_state = SWRM_PM_SLEEPABLE; init_waitqueue_head(&swrm->pm_wq); Loading Loading @@ -2775,6 +2804,7 @@ static int swrm_probe(struct platform_device *pdev) mutex_destroy(&swrm->iolock); mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->pm_lock); mutex_destroy(&swrm->ssr_lock); pm_qos_remove_request(&swrm->pm_qos_req); err_pdata_fail: Loading Loading @@ -2808,6 +2838,7 @@ static int swrm_remove(struct platform_device *pdev) mutex_destroy(&swrm->clklock); mutex_destroy(&swrm->force_down_lock); mutex_destroy(&swrm->pm_lock); mutex_destroy(&swrm->ssr_lock); pm_qos_remove_request(&swrm->pm_qos_req); devm_kfree(&pdev->dev, swrm); return 0; Loading Loading @@ -3294,6 +3325,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) break; case SWR_DEVICE_SSR_DOWN: trace_printk("%s: swr device down called\n", __func__); mutex_lock(&swrm->ssr_lock); mutex_lock(&swrm->mlock); if (swrm->state == SWR_MSTR_DOWN) dev_dbg(swrm->dev, "%s:SWR master is already Down:%d\n", Loading @@ -3307,6 +3339,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) swrm->state = SWR_MSTR_SSR; mutex_unlock(&swrm->reslock); mutex_unlock(&swrm->mlock); mutex_unlock(&swrm->ssr_lock); break; case SWR_DEVICE_SSR_UP: /* wait for clk voting to be zero */ Loading
soc/swr-mstr-ctrl.h +1 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,7 @@ struct swr_mstr_ctrl { struct mutex reslock; struct mutex pm_lock; struct mutex irq_lock; struct mutex ssr_lock; u32 swrm_base_reg; char __iomem *swrm_dig_base; char __iomem *swrm_hctl_reg; Loading