123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- // 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;
- }
|