/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ #include #include #include #include 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(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; }