diff mbox series

[v2,06/14] ASoC: amd: acp: Add new interrupt handle callbacks in acp_common_hw_ops

Message ID 20250310183201.11979-7-venkataprasad.potturu@amd.com (mailing list archive)
State New
Headers show
Series Implement acp_common_hw_ops support for all acp platforms | expand

Commit Message

Venkata Prasad Potturu March 10, 2025, 6:31 p.m. UTC
Add new interrupt handle callbacks in acp_common_hw_ops.
Refactor and move interrupt handler registration form platform
driver to pci driver.

Signed-off-by: Venkata Prasad Potturu <venkataprasad.potturu@amd.com>
---
 sound/soc/amd/acp/acp-i2s.c           |  4 +-
 sound/soc/amd/acp/acp-legacy-common.c | 79 +++++++++++++++++++++++----
 sound/soc/amd/acp/acp-pci.c           | 29 +++++++---
 sound/soc/amd/acp/acp-pdm.c           | 12 ++--
 sound/soc/amd/acp/acp-platform.c      | 50 +++--------------
 sound/soc/amd/acp/acp-rembrandt.c     | 15 ++++-
 sound/soc/amd/acp/acp-renoir.c        | 15 ++++-
 sound/soc/amd/acp/acp63.c             | 15 ++++-
 sound/soc/amd/acp/acp70.c             | 15 ++++-
 sound/soc/amd/acp/amd.h               | 29 +++++++++-
 sound/soc/amd/acp/chip_offset_byte.h  | 12 ++--
 11 files changed, 184 insertions(+), 91 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/amd/acp/acp-i2s.c b/sound/soc/amd/acp/acp-i2s.c
index 89e99ed4275a..2f458c76f9fc 100644
--- a/sound/soc/amd/acp/acp-i2s.c
+++ b/sound/soc/amd/acp/acp-i2s.c
@@ -617,7 +617,7 @@  static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
 	writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr);
 	writel(FIFO_SIZE, adata->acp_base + reg_fifo_size);
 
-	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
 	ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) |
 			BIT(BT_RX_THRESHOLD(rsrc->offset)) |
 			BIT(I2S_TX_THRESHOLD(rsrc->offset)) |
@@ -625,7 +625,7 @@  static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
 			BIT(HS_RX_THRESHOLD(rsrc->offset)) |
 			BIT(HS_TX_THRESHOLD(rsrc->offset));
 
-	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
 
 	return 0;
 }
diff --git a/sound/soc/amd/acp/acp-legacy-common.c b/sound/soc/amd/acp/acp-legacy-common.c
index 886615798b93..13fddce8df56 100644
--- a/sound/soc/amd/acp/acp-legacy-common.c
+++ b/sound/soc/amd/acp/acp-legacy-common.c
@@ -27,26 +27,76 @@  const struct snd_acp_hw_ops acp_common_hw_ops = {
 	/* ACP hardware initilizations */
 	.acp_init = acp_init,
 	.acp_deinit = acp_deinit,
+
+	/* ACP Interrupts*/
+	.irq = acp_irq_handler,
+	.en_interrupts = acp_enable_interrupts,
+	.dis_interrupts = acp_disable_interrupts,
 };
 EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON");
-void acp_enable_interrupts(struct acp_dev_data *adata)
+
+irqreturn_t acp_irq_handler(int irq, void *data)
 {
+	struct acp_chip_info *chip = data;
+	struct acp_dev_data *adata = chip->adata;
 	struct acp_resource *rsrc = adata->rsrc;
+	struct acp_stream *stream;
+	u16 i2s_flag = 0;
+	u32 ext_intr_stat, ext_intr_stat1;
+
+	if (adata->rsrc->no_of_ctrls == 2)
+		ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(chip, (rsrc->irqp_used - 1)));
+
+	ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used));
+
+	spin_lock(&adata->acp_lock);
+	list_for_each_entry(stream, &adata->stream_list, list) {
+		if (ext_intr_stat & stream->irq_bit) {
+			writel(stream->irq_bit,
+			       ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used));
+			snd_pcm_period_elapsed(stream->substream);
+			i2s_flag = 1;
+		}
+		if (adata->rsrc->no_of_ctrls == 2) {
+			if (ext_intr_stat1 & stream->irq_bit) {
+				writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip,
+				       (rsrc->irqp_used - 1)));
+				snd_pcm_period_elapsed(stream->substream);
+				i2s_flag = 1;
+			}
+		}
+	}
+	spin_unlock(&adata->acp_lock);
+	if (i2s_flag)
+		return IRQ_HANDLED;
+
+	return IRQ_NONE;
+}
+
+int acp_enable_interrupts(struct acp_chip_info *chip)
+{
+	struct acp_resource *rsrc;
 	u32 ext_intr_ctrl;
 
-	writel(0x01, ACP_EXTERNAL_INTR_ENB(adata));
-	ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+	rsrc = chip->rsrc;
+	writel(0x01, ACP_EXTERNAL_INTR_ENB(chip));
+	ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
 	ext_intr_ctrl |= ACP_ERROR_MASK;
-	writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+	writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
+
+	return 0;
 }
 EXPORT_SYMBOL_NS_GPL(acp_enable_interrupts, "SND_SOC_ACP_COMMON");
 
-void acp_disable_interrupts(struct acp_dev_data *adata)
+int acp_disable_interrupts(struct acp_chip_info *chip)
 {
-	struct acp_resource *rsrc = adata->rsrc;
+	struct acp_resource *rsrc;
+
+	rsrc = chip->rsrc;
+	writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used));
+	writel(0x00, ACP_EXTERNAL_INTR_ENB(chip));
 
-	writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
-	writel(0x00, ACP_EXTERNAL_INTR_ENB(adata));
+	return 0;
 }
 EXPORT_SYMBOL_NS_GPL(acp_disable_interrupts, "SND_SOC_ACP_COMMON");
 
@@ -90,19 +140,23 @@  void restore_acp_pdm_params(struct snd_pcm_substream *substream,
 			    struct acp_dev_data *adata)
 {
 	struct snd_soc_dai *dai;
+	struct device *dev;
+	struct acp_chip_info *chip;
 	struct snd_soc_pcm_runtime *soc_runtime;
 	u32 ext_int_ctrl;
 
 	soc_runtime = snd_soc_substream_to_rtd(substream);
 	dai = snd_soc_rtd_to_cpu(soc_runtime, 0);
+	dev = dai->component->dev;
+	chip = dev_get_platdata(dev);
 	/* Programming channel mask and sampling rate */
 	writel(adata->ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS);
 	writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR);
 
 	/* Enabling ACP Pdm interuppts */
-	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
+	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0));
 	ext_int_ctrl |= PDM_DMA_INTR_MASK;
-	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
+	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0));
 	set_acp_pdm_clk(substream, dai);
 }
 EXPORT_SYMBOL_NS_GPL(restore_acp_pdm_params, "SND_SOC_ACP_COMMON");
@@ -113,6 +167,7 @@  static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
 	struct device *dev = dai->component->dev;
 	struct acp_dev_data *adata = dev_get_drvdata(dev);
 	struct acp_resource *rsrc = adata->rsrc;
+	struct acp_chip_info *chip = dev_get_platdata(dev);
 	struct acp_stream *stream = substream->runtime->private_data;
 	u32 reg_dma_size, reg_fifo_size, reg_fifo_addr;
 	u32 phy_addr, acp_fifo_addr, ext_int_ctrl;
@@ -185,7 +240,7 @@  static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
 	writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr);
 	writel(FIFO_SIZE, adata->acp_base + reg_fifo_size);
 
-	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
 	ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) |
 			BIT(BT_RX_THRESHOLD(rsrc->offset)) |
 			BIT(I2S_TX_THRESHOLD(rsrc->offset)) |
@@ -193,7 +248,7 @@  static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
 			BIT(HS_RX_THRESHOLD(rsrc->offset)) |
 			BIT(HS_TX_THRESHOLD(rsrc->offset));
 
-	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, rsrc->irqp_used));
+	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
 	return 0;
 }
 
diff --git a/sound/soc/amd/acp/acp-pci.c b/sound/soc/amd/acp/acp-pci.c
index 99297a388ed7..1ef9faba1d8a 100644
--- a/sound/soc/amd/acp/acp-pci.c
+++ b/sound/soc/amd/acp/acp-pci.c
@@ -26,6 +26,15 @@ 
 #define ACP3x_REG_START	0x1240000
 #define ACP3x_REG_END	0x125C000
 
+static irqreturn_t irq_handler(int irq, void *data)
+{
+	struct acp_chip_info *chip = data;
+
+	if (chip && chip->acp_hw_ops && chip->acp_hw_ops->irq)
+		return chip->acp_hw_ops->irq(irq, chip);
+
+	return IRQ_NONE;
+}
 static void acp_fill_platform_dev_info(struct platform_device_info *pdevinfo,
 				       struct device *parent,
 				       struct fwnode_handle *fw_node,
@@ -166,6 +175,13 @@  static int acp_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id
 	if (ret)
 		goto release_regions;
 
+	ret = devm_request_irq(dev, pci->irq, irq_handler,
+			       IRQF_SHARED, "ACP_I2S_IRQ", chip);
+	if (ret) {
+		dev_err(&pci->dev, "ACP I2S IRQ request failed %d\n", ret);
+		return ret;
+	}
+
 	check_acp_config(pci, chip);
 	if (!chip->is_pdm_dev && !chip->is_i2s_config)
 		goto skip_pdev_creation;
@@ -213,20 +229,17 @@  static int __maybe_unused snd_acp_suspend(struct device *dev)
 static int __maybe_unused snd_acp_resume(struct device *dev)
 {
 	struct acp_chip_info *chip;
-	struct acp_dev_data *adata;
-	struct device child;
 	int ret;
 
 	chip = dev_get_drvdata(dev);
 	ret = acp_hw_init(chip);
 	if (ret)
 		dev_err(dev, "ACP init failed\n");
-	if (chip->chip_pdev) {
-		child = chip->chip_pdev->dev;
-		adata = dev_get_drvdata(&child);
-		if (adata)
-			acp_enable_interrupts(adata);
-	}
+
+	ret = acp_hw_en_interrupts(chip);
+	if (ret)
+		dev_err(dev, "ACP en-interrupts failed\n");
+
 	return ret;
 }
 
diff --git a/sound/soc/amd/acp/acp-pdm.c b/sound/soc/amd/acp/acp-pdm.c
index d4855da05b6a..9a820ef3bf46 100644
--- a/sound/soc/amd/acp/acp-pdm.c
+++ b/sound/soc/amd/acp/acp-pdm.c
@@ -145,7 +145,7 @@  static int acp_dmic_dai_startup(struct snd_pcm_substream *substream,
 {
 	struct acp_stream *stream = substream->runtime->private_data;
 	struct device *dev = dai->component->dev;
-	struct acp_dev_data *adata = dev_get_drvdata(dev);
+	struct acp_chip_info *chip = dev_get_platdata(dev);
 	u32 ext_int_ctrl;
 
 	stream->dai_id = DMIC_INSTANCE;
@@ -154,9 +154,9 @@  static int acp_dmic_dai_startup(struct snd_pcm_substream *substream,
 	stream->reg_offset = ACP_REGION2_OFFSET;
 
 	/* Enable DMIC Interrupts */
-	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
+	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0));
 	ext_int_ctrl |= PDM_DMA_INTR_MASK;
-	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
+	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0));
 
 	return 0;
 }
@@ -165,13 +165,13 @@  static void acp_dmic_dai_shutdown(struct snd_pcm_substream *substream,
 				  struct snd_soc_dai *dai)
 {
 	struct device *dev = dai->component->dev;
-	struct acp_dev_data *adata = dev_get_drvdata(dev);
+	struct acp_chip_info *chip = dev_get_platdata(dev);
 	u32 ext_int_ctrl;
 
 	/* Disable DMIC interrupts */
-	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(adata, 0));
+	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0));
 	ext_int_ctrl &= ~PDM_DMA_INTR_MASK;
-	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(adata, 0));
+	writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0));
 }
 
 const struct snd_soc_dai_ops acp_dmic_dai_ops = {
diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c
index 7d6abff28b23..9b181fb5861c 100644
--- a/sound/soc/amd/acp/acp-platform.c
+++ b/sound/soc/amd/acp/acp-platform.c
@@ -107,43 +107,6 @@  static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = {
 	.periods_max = CAPTURE_MAX_NUM_PERIODS,
 };
 
-static irqreturn_t i2s_irq_handler(int irq, void *data)
-{
-	struct acp_dev_data *adata = data;
-	struct acp_resource *rsrc = adata->rsrc;
-	struct acp_stream *stream;
-	u16 i2s_flag = 0;
-	u32 ext_intr_stat, ext_intr_stat1;
-
-	if (adata->rsrc->no_of_ctrls == 2)
-		ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(adata, (rsrc->irqp_used - 1)));
-
-	ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
-
-	spin_lock(&adata->acp_lock);
-	list_for_each_entry(stream, &adata->stream_list, list) {
-		if (ext_intr_stat & stream->irq_bit) {
-			writel(stream->irq_bit,
-			       ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used));
-			snd_pcm_period_elapsed(stream->substream);
-			i2s_flag = 1;
-		}
-		if (adata->rsrc->no_of_ctrls == 2) {
-			if (ext_intr_stat1 & stream->irq_bit) {
-				writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(adata,
-				       (rsrc->irqp_used - 1)));
-				snd_pcm_period_elapsed(stream->substream);
-				i2s_flag = 1;
-			}
-		}
-	}
-	spin_unlock(&adata->acp_lock);
-	if (i2s_flag)
-		return IRQ_HANDLED;
-
-	return IRQ_NONE;
-}
-
 void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream)
 {
 	struct acp_resource *rsrc = adata->rsrc;
@@ -278,7 +241,7 @@  static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs
 	}
 	runtime->private_data = stream;
 
-	writel(1, ACP_EXTERNAL_INTR_ENB(adata));
+	writel(1, ACP_EXTERNAL_INTR_ENB(chip));
 
 	spin_lock_irq(&adata->acp_lock);
 	list_add_tail(&stream->list, &adata->stream_list);
@@ -363,16 +326,17 @@  static const struct snd_soc_component_driver acp_pcm_component = {
 int acp_platform_register(struct device *dev)
 {
 	struct acp_dev_data *adata = dev_get_drvdata(dev);
+	struct acp_chip_info *chip;
 	struct snd_soc_dai_driver;
 	unsigned int status;
 
-	status = devm_request_irq(dev, adata->i2s_irq, i2s_irq_handler,
-				  IRQF_SHARED, "ACP_I2S_IRQ", adata);
-	if (status) {
-		dev_err(dev, "ACP I2S IRQ request failed\n");
-		return status;
+	chip = dev_get_platdata(dev);
+	if (!chip || !chip->base) {
+		dev_err(dev, "ACP chip data is NULL\n");
+		return -ENODEV;
 	}
 
+	chip->adata = adata;
 	status = devm_snd_soc_register_component(dev, &acp_pcm_component,
 						 adata->dai_driver,
 						 adata->num_dai);
diff --git a/sound/soc/amd/acp/acp-rembrandt.c b/sound/soc/amd/acp/acp-rembrandt.c
index eb09878c0d5c..13633b3f3730 100644
--- a/sound/soc/amd/acp/acp-rembrandt.c
+++ b/sound/soc/amd/acp/acp-rembrandt.c
@@ -192,6 +192,7 @@  static int rembrandt_audio_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	chip->rsrc = &rsrc;
 	adata->i2s_irq = res->start;
 	adata->dev = dev;
 	adata->dai_driver = acp_rmb_dai;
@@ -208,7 +209,11 @@  static int rembrandt_audio_probe(struct platform_device *pdev)
 		if (ret)
 			return ret;
 	}
-	acp_enable_interrupts(adata);
+	ret = acp_hw_en_interrupts(chip);
+	if (ret) {
+		dev_err(dev, "ACP en-interrupts failed\n");
+		return ret;
+	}
 	acp_platform_register(dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
 	pm_runtime_use_autosuspend(&pdev->dev);
@@ -221,9 +226,13 @@  static int rembrandt_audio_probe(struct platform_device *pdev)
 static void rembrandt_audio_remove(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct acp_dev_data *adata = dev_get_drvdata(dev);
+	struct acp_chip_info *chip = dev_get_platdata(dev);
+	int ret;
+
+	ret = acp_hw_dis_interrupts(chip);
+	if (ret)
+		dev_err(dev, "ACP dis-interrupts failed\n");
 
-	acp_disable_interrupts(adata);
 	acp_platform_unregister(dev);
 	pm_runtime_disable(&pdev->dev);
 }
diff --git a/sound/soc/amd/acp/acp-renoir.c b/sound/soc/amd/acp/acp-renoir.c
index 2b47c6bfc9e7..94ecb17684b7 100644
--- a/sound/soc/amd/acp/acp-renoir.c
+++ b/sound/soc/amd/acp/acp-renoir.c
@@ -142,6 +142,7 @@  static int renoir_audio_probe(struct platform_device *pdev)
 		return ret;
 	adata->i2s_irq = ret;
 
+	chip->rsrc = &rsrc;
 	adata->dev = dev;
 	adata->dai_driver = acp_renoir_dai;
 	adata->num_dai = ARRAY_SIZE(acp_renoir_dai);
@@ -150,7 +151,11 @@  static int renoir_audio_probe(struct platform_device *pdev)
 	adata->flag = chip->flag;
 
 	dev_set_drvdata(dev, adata);
-	acp_enable_interrupts(adata);
+	ret = acp_hw_en_interrupts(chip);
+	if (ret) {
+		dev_err(dev, "ACP en-interrupts failed\n");
+		return ret;
+	}
 	acp_platform_register(dev);
 
 	pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
@@ -164,9 +169,13 @@  static int renoir_audio_probe(struct platform_device *pdev)
 static void renoir_audio_remove(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct acp_dev_data *adata = dev_get_drvdata(dev);
+	struct acp_chip_info *chip = dev_get_platdata(dev);
+	int ret;
+
+	ret = acp_hw_dis_interrupts(chip);
+	if (ret)
+		dev_err(dev, "ACP dis-interrupts failed\n");
 
-	acp_disable_interrupts(adata);
 	acp_platform_unregister(dev);
 }
 
diff --git a/sound/soc/amd/acp/acp63.c b/sound/soc/amd/acp/acp63.c
index 76a26b82e3ad..e38ad9f7fb48 100644
--- a/sound/soc/amd/acp/acp63.c
+++ b/sound/soc/amd/acp/acp63.c
@@ -243,6 +243,7 @@  static int acp63_audio_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	chip->rsrc = &rsrc;
 	adata->i2s_irq = res->start;
 	adata->dev = dev;
 	adata->dai_driver = acp63_dai;
@@ -258,7 +259,11 @@  static int acp63_audio_probe(struct platform_device *pdev)
 		if (ret)
 			return ret;
 	}
-	acp_enable_interrupts(adata);
+	ret = acp_hw_en_interrupts(chip);
+	if (ret) {
+		dev_err(dev, "ACP en-interrupts failed\n");
+		return ret;
+	}
 	acp_platform_register(dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
 	pm_runtime_use_autosuspend(&pdev->dev);
@@ -271,9 +276,13 @@  static int acp63_audio_probe(struct platform_device *pdev)
 static void acp63_audio_remove(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct acp_dev_data *adata = dev_get_drvdata(dev);
+	struct acp_chip_info *chip = dev_get_platdata(dev);
+	int ret;
+
+	ret = acp_hw_dis_interrupts(chip);
+	if (ret)
+		dev_err(dev, "ACP dis-interrupts failed\n");
 
-	acp_disable_interrupts(adata);
 	acp_platform_unregister(dev);
 	pm_runtime_disable(&pdev->dev);
 }
diff --git a/sound/soc/amd/acp/acp70.c b/sound/soc/amd/acp/acp70.c
index 3e603c5f736a..be4302a5a584 100644
--- a/sound/soc/amd/acp/acp70.c
+++ b/sound/soc/amd/acp/acp70.c
@@ -174,6 +174,7 @@  static int acp_acp70_audio_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	chip->rsrc = &rsrc;
 	adata->i2s_irq = res->start;
 	adata->dev = dev;
 	adata->dai_driver = acp70_dai;
@@ -190,7 +191,11 @@  static int acp_acp70_audio_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Failed to set I2S master clock as 196.608MHz\n");
 		return ret;
 	}
-	acp_enable_interrupts(adata);
+	ret = acp_hw_en_interrupts(chip);
+	if (ret) {
+		dev_err(dev, "ACP en-interrupts failed\n");
+		return ret;
+	}
 	acp_platform_register(dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
 	pm_runtime_use_autosuspend(&pdev->dev);
@@ -203,9 +208,13 @@  static int acp_acp70_audio_probe(struct platform_device *pdev)
 static void acp_acp70_audio_remove(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct acp_dev_data *adata = dev_get_drvdata(dev);
+	struct acp_chip_info *chip = dev_get_platdata(dev);
+	int ret;
+
+	ret = acp_hw_dis_interrupts(chip);
+	if (ret)
+		dev_err(dev, "ACP dis-interrupts failed\n");
 
-	acp_disable_interrupts(adata);
 	acp_platform_unregister(dev);
 	pm_runtime_disable(&pdev->dev);
 }
diff --git a/sound/soc/amd/acp/amd.h b/sound/soc/amd/acp/amd.h
index b7a1b4aa8fef..4beaa9cae352 100644
--- a/sound/soc/amd/acp/amd.h
+++ b/sound/soc/amd/acp/amd.h
@@ -147,10 +147,12 @@  struct acp_chip_info {
 	struct snd_acp_hw_ops *acp_hw_ops;
 	int (*acp_hw_ops_init)(struct acp_chip_info *chip);
 	struct platform_device *chip_pdev;
+	struct acp_resource *rsrc; /* Platform specific resources*/
 	struct platform_device *dmic_codec_dev;
 	struct platform_device *acp_plat_dev;
 	struct platform_device *mach_dev;
 	struct snd_soc_acpi_mach *machines;
+	struct acp_dev_data *adata;
 	u32 addr;
 	unsigned int flag;	/* Distinguish b/w Legacy or Only PDM */
 	bool is_pdm_dev;	/* flag set to true when ACP PDM controller exists */
@@ -215,11 +217,19 @@  struct acp_dev_data {
  * struct snd_acp_hw_ops - ACP PCI driver platform specific ops
  * @acp_init: ACP initialization
  * @acp_deinit: ACP de-initialization
+ * @irq: ACP irq handler
+ * @en_interrupts: ACP enable interrupts
+ * @dis_interrupts: ACP disable interrupts
  */
 struct snd_acp_hw_ops {
 	/* ACP hardware initilizations */
 	int (*acp_init)(struct acp_chip_info *chip);
 	int (*acp_deinit)(struct acp_chip_info *chip);
+
+	/* ACP Interrupts*/
+	irqreturn_t (*irq)(int irq, void *data);
+	int (*en_interrupts)(struct acp_chip_info *chip);
+	int (*dis_interrupts)(struct acp_chip_info *chip);
 };
 
 enum acp_config {
@@ -332,8 +342,9 @@  int acp_machine_select(struct acp_chip_info *chip);
 
 int acp_init(struct acp_chip_info *chip);
 int acp_deinit(struct acp_chip_info *chip);
-void acp_enable_interrupts(struct acp_dev_data *adata);
-void acp_disable_interrupts(struct acp_dev_data *adata);
+int acp_enable_interrupts(struct acp_chip_info *chip);
+int acp_disable_interrupts(struct acp_chip_info *chip);
+irqreturn_t acp_irq_handler(int irq, void *data);
 
 extern struct snd_acp_hw_ops acp31_common_hw_ops;
 extern struct snd_acp_hw_ops acp6x_common_hw_ops;
@@ -370,6 +381,20 @@  static inline int acp_hw_deinit(struct acp_chip_info *chip)
 	return -EOPNOTSUPP;
 }
 
+static inline int acp_hw_en_interrupts(struct acp_chip_info *chip)
+{
+	if (chip && chip->acp_hw_ops && chip->acp_hw_ops->en_interrupts)
+		return chip->acp_hw_ops->en_interrupts(chip);
+	return -EOPNOTSUPP;
+}
+
+static inline int acp_hw_dis_interrupts(struct acp_chip_info *chip)
+{
+	if (chip && chip->acp_hw_ops && chip->acp_hw_ops->dis_interrupts)
+		chip->acp_hw_ops->dis_interrupts(chip);
+	return -EOPNOTSUPP;
+}
+
 static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction)
 {
 	u64 byte_count = 0, low = 0, high = 0;
diff --git a/sound/soc/amd/acp/chip_offset_byte.h b/sound/soc/amd/acp/chip_offset_byte.h
index 117ea63e85c6..82275c9de53a 100644
--- a/sound/soc/amd/acp/chip_offset_byte.h
+++ b/sound/soc/amd/acp/chip_offset_byte.h
@@ -29,13 +29,13 @@ 
 #define ACP_PIN_CONFIG				0x1440
 #define ACP3X_PIN_CONFIG			0x1400
 
-#define ACP_EXTERNAL_INTR_REG_ADDR(adata, offset, ctrl) \
-	(adata->acp_base + adata->rsrc->irq_reg_offset + offset + (ctrl * 0x04))
+#define ACP_EXTERNAL_INTR_REG_ADDR(chip, offset, ctrl) \
+	(chip->base + chip->rsrc->irq_reg_offset + offset + (ctrl * 0x04))
 
-#define ACP_EXTERNAL_INTR_ENB(adata) ACP_EXTERNAL_INTR_REG_ADDR(adata, 0x0, 0x0)
-#define ACP_EXTERNAL_INTR_CNTL(adata, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(adata, 0x4, ctrl)
-#define ACP_EXTERNAL_INTR_STAT(adata, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(adata, \
-	(0x4 + (adata->rsrc->no_of_ctrls * 0x04)), ctrl)
+#define ACP_EXTERNAL_INTR_ENB(chip) ACP_EXTERNAL_INTR_REG_ADDR(chip, 0x0, 0x0)
+#define ACP_EXTERNAL_INTR_CNTL(chip, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(chip, 0x4, ctrl)
+#define ACP_EXTERNAL_INTR_STAT(chip, ctrl) ACP_EXTERNAL_INTR_REG_ADDR(chip, \
+	(0x4 + (chip->rsrc->no_of_ctrls * 0x04)), ctrl)
 
 /* Registers from ACP_AUDIO_BUFFERS block */