Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f1c3f00c authored by Aditya Bavanari's avatar Aditya Bavanari Committed by Akhil Karuturi
Browse files

soc: Vote or unvote core and audio hw based on count



In order to synchronize the core and audio hw votes
in SSR use cases, vote or unvote for these
based on clock count.

Change-Id: I0047e2cc689cc96b34992e5f6f59dae84d1d4e4b
Signed-off-by: default avatarAditya Bavanari <abavanar@codeaurora.org>
parent e000435f
Loading
Loading
Loading
Loading
+87 −47
Original line number Diff line number Diff line
@@ -389,33 +389,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;
}

@@ -1755,6 +1799,7 @@ static irqreturn_t swr_mstr_interrupt(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;
@@ -1979,6 +2024,7 @@ static irqreturn_t swr_mstr_interrupt(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;
@@ -2155,22 +2201,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);
}

@@ -2185,22 +2224,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);
}
@@ -2536,6 +2564,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);
@@ -2690,6 +2719,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:
@@ -2723,6 +2753,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;
@@ -3200,12 +3231,21 @@ 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",
				__func__, swrm->state);
		else
			swrm_device_down(&pdev->dev);
		mutex_lock(&swrm->devlock);
		swrm->dev_up = false;
		mutex_unlock(&swrm->devlock);
		mutex_lock(&swrm->reslock);
		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 */
+1 −0
Original line number Diff line number Diff line
@@ -133,6 +133,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;