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

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

Merge "audio-kernel: Synchronize hw vote and unvote requests"

parents 30fad2dc 31aa8754
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <soc/snd_event.h>
#include <linux/pm_runtime.h>
#include <soc/swr-common.h>
#include <dsp/digital-cdc-rsc-mgr.h>
#include "bolero-cdc.h"
#include "internal.h"
#include "bolero-clk-rsc.h"
@@ -1388,7 +1389,7 @@ int bolero_runtime_resume(struct device *dev)
	}

	if (priv->core_hw_vote_count == 0) {
		ret = clk_prepare_enable(priv->lpass_core_hw_vote);
		ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_core_hw_vote);
		if (ret < 0) {
			dev_err(dev, "%s:lpass core hw enable failed\n",
				__func__);
@@ -1406,7 +1407,7 @@ int bolero_runtime_resume(struct device *dev)
	}

	if (priv->core_audio_vote_count == 0) {
		ret = clk_prepare_enable(priv->lpass_audio_hw_vote);
		ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_audio_hw_vote);
		if (ret < 0) {
			dev_err(dev, "%s:lpass audio hw enable failed\n",
				__func__);
@@ -1431,7 +1432,8 @@ int bolero_runtime_suspend(struct device *dev)
	mutex_lock(&priv->vote_lock);
	if (priv->lpass_core_hw_vote != NULL) {
		if (--priv->core_hw_vote_count == 0)
			clk_disable_unprepare(priv->lpass_core_hw_vote);
			digital_cdc_rsc_mgr_hw_vote_disable(
					priv->lpass_core_hw_vote);
		if (priv->core_hw_vote_count < 0)
			priv->core_hw_vote_count = 0;
	} else {
@@ -1443,7 +1445,8 @@ int bolero_runtime_suspend(struct device *dev)

	if (priv->lpass_audio_hw_vote != NULL) {
		if (--priv->core_audio_vote_count == 0)
			clk_disable_unprepare(priv->lpass_audio_hw_vote);
			digital_cdc_rsc_mgr_hw_vote_disable(
					priv->lpass_audio_hw_vote);
		if (priv->core_audio_vote_count < 0)
			priv->core_audio_vote_count = 0;
	} else {
+5 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <asoc/msm-cdc-pinctrl.h>
#include <soc/swr-common.h>
#include <soc/swr-wcd.h>
#include <dsp/digital-cdc-rsc-mgr.h>
#include "bolero-cdc.h"
#include "bolero-cdc-registers.h"
#include "bolero-clk-rsc.h"
@@ -444,7 +445,8 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		if (va_priv->lpass_audio_hw_vote) {
			ret = clk_prepare_enable(va_priv->lpass_audio_hw_vote);
			ret = digital_cdc_rsc_mgr_hw_vote_enable(
					va_priv->lpass_audio_hw_vote);
			if (ret)
				dev_err(va_dev,
					"%s: lpass audio hw enable failed\n",
@@ -467,7 +469,8 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
		if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG))
			dev_dbg(va_dev, "%s: clock switch failed\n",__func__);
		if (va_priv->lpass_audio_hw_vote)
			clk_disable_unprepare(va_priv->lpass_audio_hw_vote);
			digital_cdc_rsc_mgr_hw_vote_disable(
				va_priv->lpass_audio_hw_vote);
		break;
	default:
		dev_err(va_priv->dev,
+4 −0
Original line number Diff line number Diff line
@@ -186,6 +186,10 @@ ifdef CONFIG_VOICE_MHI
	Q6_OBJS += voice_mhi.o
endif

ifdef CONFIG_DIGITAL_CDC_RSC_MGR
	Q6_OBJS += digital-cdc-rsc-mgr.o
endif

LINUX_INC +=	-Iinclude/linux

INCS +=		$(COMMON_INC) \
+100 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/ratelimit.h>
#include <dsp/digital-cdc-rsc-mgr.h>

struct mutex hw_vote_lock;
static bool is_init_done;

/**
 * digital_cdc_rsc_mgr_hw_vote_enable - Enables hw vote in DSP
 *
 * @vote_handle: vote handle for which voting needs to be done
 *
 * Returns 0 on success or -EINVAL/error code on failure
 */
int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle)
{
	int ret = 0;

	if (!is_init_done || vote_handle == NULL) {
		pr_err_ratelimited("%s: init failed or vote handle NULL\n",
				   __func__);
		return -EINVAL;
	}

	mutex_lock(&hw_vote_lock);
	ret = clk_prepare_enable(vote_handle);
	mutex_unlock(&hw_vote_lock);

	pr_debug("%s: return %d\n", __func__, ret);
	trace_printk("%s: return %d\n", __func__, ret);
	return ret;
}
EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_enable);

/**
 * digital_cdc_rsc_mgr_hw_vote_disable - Disables hw vote in DSP
 *
 * @vote_handle: vote handle for which voting needs to be disabled
 *
 */
void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle)
{
	if (!is_init_done || vote_handle == NULL) {
		pr_err_ratelimited("%s: init failed or vote handle NULL\n",
				   __func__);
		return;
	}

	mutex_lock(&hw_vote_lock);
	clk_disable_unprepare(vote_handle);
	mutex_unlock(&hw_vote_lock);
	trace_printk("%s\n", __func__);
}
EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_disable);

/**
 * digital_cdc_rsc_mgr_hw_vote_reset - Resets hw vote count
 *
 */
void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle)
{
	int count = 0;

	if (!is_init_done || vote_handle == NULL) {
		pr_err_ratelimited("%s: init failed or vote handle NULL\n",
				   __func__);
		return;
	}

	mutex_lock(&hw_vote_lock);
	while (__clk_is_enabled(vote_handle)) {
		clk_disable_unprepare(vote_handle);
		count++;
	}
	pr_debug("%s: Vote count after SSR: %d\n", __func__, count);
	trace_printk("%s: Vote count after SSR: %d\n", __func__, count);

	while (count--)
		clk_prepare_enable(vote_handle);
	mutex_unlock(&hw_vote_lock);
}
EXPORT_SYMBOL(digital_cdc_rsc_mgr_hw_vote_reset);

void digital_cdc_rsc_mgr_init()
{
	mutex_init(&hw_vote_lock);
	is_init_done = true;
}

void digital_cdc_rsc_mgr_exit()
{
	mutex_destroy(&hw_vote_lock);
	is_init_done = false;
}
+3 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved.
 * Copyright (c) 2017, 2019-2020 The Linux Foundation. All rights reserved.
 */

#include <linux/kernel.h>
@@ -24,11 +24,13 @@ static int __init audio_q6_init(void)
	avtimer_init();
	msm_mdf_init();
	voice_mhi_init();
	digital_cdc_rsc_mgr_init();
	return 0;
}

static void __exit audio_q6_exit(void)
{
	digital_cdc_rsc_mgr_exit();
	msm_mdf_exit();
	avtimer_exit();
	audio_slimslave_exit();
Loading