diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index 2db0c5b30a35..1b28382f6fc0 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -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"
@@ -1379,7 +1380,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__);
@@ -1397,7 +1398,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__);
@@ -1422,7 +1423,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 {
@@ -1434,7 +1436,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 {
diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c
index 85d4ae399703..02534d6a4f1f 100644
--- a/asoc/codecs/bolero/va-macro.c
+++ b/asoc/codecs/bolero/va-macro.c
@@ -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,
diff --git a/dsp/Kbuild b/dsp/Kbuild
index 006de44589f2..43180e7a3dc3 100644
--- a/dsp/Kbuild
+++ b/dsp/Kbuild
@@ -184,6 +184,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) \
diff --git a/dsp/digital-cdc-rsc-mgr.c b/dsp/digital-cdc-rsc-mgr.c
new file mode 100644
index 000000000000..4206523ea85b
--- /dev/null
+++ b/dsp/digital-cdc-rsc-mgr.c
@@ -0,0 +1,100 @@
+/* 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;
+}
diff --git a/dsp/q6_init.c b/dsp/q6_init.c
index fb18741d3838..e990f2a15109 100644
--- a/dsp/q6_init.c
+++ b/dsp/q6_init.c
@@ -1,6 +1,6 @@
 // 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();
diff --git a/dsp/q6_init.h b/dsp/q6_init.h
index 4df2e032700f..77ba743484b4 100644
--- a/dsp/q6_init.h
+++ b/dsp/q6_init.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef __Q6_INIT_H__
@@ -80,5 +80,19 @@ static inline void voice_mhi_exit(void)
 	return;
 }
 #endif
+
+#ifdef CONFIG_DIGITAL_CDC_RSC_MGR
+void digital_cdc_rsc_mgr_init(void);
+void digital_cdc_rsc_mgr_exit(void);
+#else
+static inline void digital_cdc_rsc_mgr_init(void)
+{
+}
+
+static inline void digital_cdc_rsc_mgr_exit(void)
+{
+}
+#endif /* CONFIG_DIGITAL_CDC_RSC_MGR */
+
 #endif
 
diff --git a/include/dsp/digital-cdc-rsc-mgr.h b/include/dsp/digital-cdc-rsc-mgr.h
new file mode 100644
index 000000000000..685cd5c1fc5f
--- /dev/null
+++ b/include/dsp/digital-cdc-rsc-mgr.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef DIGITAL_CDC_RSC_MGR_H
+#define DIGITAL_CDC_RSC_MGR_H
+
+#ifdef CONFIG_DIGITAL_CDC_RSC_MGR
+
+int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle);
+void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle);
+void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle);
+
+#else
+
+static inline int digital_cdc_rsc_mgr_hw_vote_enable(struct clk* vote_handle)
+{
+	return 0;
+}
+
+static inline void digital_cdc_rsc_mgr_hw_vote_disable(struct clk* vote_handle)
+{
+}
+
+static inline void digital_cdc_rsc_mgr_hw_vote_reset(struct clk* vote_handle)
+{
+}
+
+#endif /* CONFIG_DIGITAL_CDC_RSC_MGR */
+
+#endif /* DIGITAL_CDC_RSC_MGR_H */
diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c
index c3d2326af593..0b0eef5ab9cc 100644
--- a/soc/pinctrl-lpi.c
+++ b/soc/pinctrl-lpi.c
@@ -16,6 +16,7 @@
 #include <linux/clk.h>
 #include <linux/bitops.h>
 #include <soc/snd_event.h>
+#include <dsp/digital-cdc-rsc-mgr.h>
 #include <linux/pm_runtime.h>
 #include <dsp/audio_notifier.h>
 
@@ -469,6 +470,7 @@ static int lpi_notifier_service_cb(struct notifier_block *this,
 				   unsigned long opcode, void *ptr)
 {
 	static bool initial_boot = true;
+	struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev);
 
 	pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
 
@@ -484,6 +486,17 @@ static int lpi_notifier_service_cb(struct notifier_block *this,
 	case AUDIO_NOTIFIER_SERVICE_UP:
 		if (initial_boot)
 			initial_boot = false;
+
+		/* Reset HW votes after SSR */
+		if (!lpi_dev_up) {
+			if (state->lpass_core_hw_vote)
+				digital_cdc_rsc_mgr_hw_vote_reset(
+					state->lpass_core_hw_vote);
+			if (state->lpass_audio_hw_vote)
+				digital_cdc_rsc_mgr_hw_vote_reset(
+					state->lpass_audio_hw_vote);
+		}
+
 		lpi_dev_up = true;
 		snd_event_notify(lpi_dev, SND_EVENT_UP);
 		break;
@@ -870,7 +883,7 @@ int lpi_pinctrl_runtime_resume(struct device *dev)
 	}
 
 	mutex_lock(&state->core_hw_vote_lock);
-	ret = clk_prepare_enable(hw_vote);
+	ret = digital_cdc_rsc_mgr_hw_vote_enable(hw_vote);
 	if (ret < 0) {
 		pm_runtime_set_autosuspend_delay(dev,
 						 LPI_AUTO_SUSPEND_DELAY_ERROR);
@@ -906,7 +919,7 @@ int lpi_pinctrl_runtime_suspend(struct device *dev)
 
 	mutex_lock(&state->core_hw_vote_lock);
 	if (state->core_hw_vote_status) {
-		clk_disable_unprepare(hw_vote);
+		digital_cdc_rsc_mgr_hw_vote_disable(hw_vote);
 		state->core_hw_vote_status = false;
 	}
 	mutex_unlock(&state->core_hw_vote_lock);
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index 4aa5c0c6aa5f..77ece45ea049 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -22,6 +22,7 @@
 #include <soc/swr-common.h>
 #include <linux/regmap.h>
 #include <dsp/msm-audio-event-notify.h>
+#include <dsp/digital-cdc-rsc-mgr.h>
 #include "swrm_registers.h"
 #include "swr-mstr-ctrl.h"
 
@@ -378,8 +379,8 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
 				}
 				if (++swrm->hw_core_clk_en == 1) {
 					ret =
-					   clk_prepare_enable(
-						swrm->lpass_core_hw_vote);
+					   digital_cdc_rsc_mgr_hw_vote_enable(
+							swrm->lpass_core_hw_vote);
 					if (ret < 0) {
 						dev_err(swrm->dev,
 							"%s:lpass core hw enable failed\n",
@@ -392,8 +393,8 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
 				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);
+					digital_cdc_rsc_mgr_hw_vote_disable(
+							swrm->lpass_core_hw_vote);
 			}
 		}
 	}
@@ -410,8 +411,8 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
 				}
 				if (++swrm->aud_core_clk_en == 1) {
 					ret =
-					   clk_prepare_enable(
-						swrm->lpass_core_audio);
+					   digital_cdc_rsc_mgr_hw_vote_enable(
+							swrm->lpass_core_audio);
 					if (ret < 0) {
 						dev_err(swrm->dev,
 							"%s:lpass audio hw enable failed\n",
@@ -424,8 +425,8 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
 				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);
+					digital_cdc_rsc_mgr_hw_vote_disable(
+							swrm->lpass_core_audio);
 			}
 		}
 	}
@@ -3334,6 +3335,8 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
 			swrm_device_down(&pdev->dev);
 		mutex_lock(&swrm->devlock);
 		swrm->dev_up = false;
+		swrm->hw_core_clk_en = 0;
+		swrm->aud_core_clk_en = 0;
 		mutex_unlock(&swrm->devlock);
 		mutex_lock(&swrm->reslock);
 		swrm->state = SWR_MSTR_SSR;