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

Commit bb52e209 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents d92d4107 eb04461c
Loading
Loading
Loading
Loading
+80 −47
Original line number Diff line number Diff line
@@ -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;
}

@@ -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;
@@ -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;
@@ -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);
}

@@ -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);
}
@@ -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);
@@ -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:
@@ -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;
@@ -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",
@@ -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 */
+1 −0
Original line number Diff line number Diff line
@@ -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;