Add 'qcom/opensource/audio-kernel/' from commit '0ee387dfadf349618494d6f82ec8cec796ebef70'
git-subtree-dir: qcom/opensource/audio-kernel git-subtree-mainline:99ab089c55
git-subtree-split:0ee387dfad
Change-Id: repo: https://git.codelinaro.org/clo/la/platform/vendor/qcom/opensource/audio-kernel-ar tag: AUDIO.LA.9.0.r1-07400-lanai.0
This commit is contained in:
102
qcom/opensource/audio-kernel/dsp/digital-cdc-rsc-mgr.c
Normal file
102
qcom/opensource/audio-kernel/dsp/digital-cdc-rsc-mgr.c
Normal file
@@ -0,0 +1,102 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <dsp/digital-cdc-rsc-mgr.h>
|
||||
#include <linux/dev_printk.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
|
||||
* @dev: indicate which device votes
|
||||
*
|
||||
* Returns 0 on success or -EINVAL/error code on failure
|
||||
*/
|
||||
int digital_cdc_rsc_mgr_hw_vote_enable(struct clk *vote_handle, struct device *dev)
|
||||
{
|
||||
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);
|
||||
|
||||
dev_dbg(dev, "%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
|
||||
* @dev: indicate which device unvotes
|
||||
*
|
||||
*/
|
||||
void digital_cdc_rsc_mgr_hw_vote_disable(struct clk *vote_handle, struct device *dev)
|
||||
{
|
||||
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);
|
||||
dev_dbg(dev, "%s: leave\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);
|
||||
|
||||
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(void)
|
||||
{
|
||||
mutex_init(&hw_vote_lock);
|
||||
is_init_done = true;
|
||||
}
|
||||
|
||||
void digital_cdc_rsc_mgr_exit(void)
|
||||
{
|
||||
mutex_destroy(&hw_vote_lock);
|
||||
is_init_done = false;
|
||||
}
|
Reference in New Issue
Block a user