lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250120100130.3710412-18-Vijendar.Mukunda@amd.com>
Date: Mon, 20 Jan 2025 15:31:24 +0530
From: Vijendar Mukunda <Vijendar.Mukunda@....com>
To: <broonie@...nel.org>
CC: <alsa-devel@...a-project.org>, <lgirdwood@...il.com>, <perex@...ex.cz>,
	<tiwai@...e.com>, <Basavaraj.Hiregoudar@....com>,
	<Sunil-kumar.Dommati@....com>, <venkataprasad.potturu@....com>,
	<Mario.Limonciello@....com>, <linux-sound@...r.kernel.org>,
	<linux-kernel@...r.kernel.org>, Vijendar Mukunda <Vijendar.Mukunda@....com>
Subject: [PATCH V2 17/23] ASoC: amd: acp70: add soundwire wake interrupt handling

For Soundwire wake event, SoundWire Host wake interrupt will be asserted
when ACP is in D0 state and SoundWire manager instance is in D3 state and
PME status is set when ACP is in D3 state and SoundWire manager instance
is in D3 state.

Add code to handle SoundWire PME status and host wake interrupts in
ACP7.0 interrupt handler.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@....com>
---
 sound/soc/amd/acp70/acp70.h     |  8 ++++++
 sound/soc/amd/acp70/pci-acp70.c | 51 +++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/sound/soc/amd/acp70/acp70.h b/sound/soc/amd/acp70/acp70.h
index c3b3b6c38902..ab4d6a5c1cd2 100644
--- a/sound/soc/amd/acp70/acp70.h
+++ b/sound/soc/amd/acp70/acp70.h
@@ -60,6 +60,10 @@
 
 #define ACP_SDW0_STAT			BIT(21)
 #define ACP_SDW1_STAT			BIT(2)
+#define ACP_SDW0_HOST_WAKE_STAT		BIT(24)
+#define ACP_SDW1_HOST_WAKE_STAT		BIT(25)
+#define ACP_SDW0_PME_STAT		BIT(26)
+#define ACP_SDW1_PME_STAT		BIT(27)
 #define ACP_ERROR_IRQ			BIT(29)
 
 #define ACP_AUDIO0_TX_THRESHOLD		0x1c
@@ -248,6 +252,8 @@ struct sdw_dma_dev_data {
  * @is_pdm_config: flat set to true when PDM configuration is selected from BIOS
  * @is_sdw_config: flag set to true when SDW configuration is selected from BIOS
  * @sdw_en_stat: flag set to true when any one of the SoundWire manager instance is enabled
+ * @sdw0_wake_event: flag set to true when wake irq asserted for SW0 instance
+ * @sdw1_wake_event: flag set to true when wake irq asserted for SW1 instance
  */
 
 struct acp70_dev_data {
@@ -270,6 +276,8 @@ struct acp70_dev_data {
 	bool is_pdm_config;
 	bool is_sdw_config;
 	bool sdw_en_stat;
+	bool sdw0_wake_event;
+	bool sdw1_wake_event;
 };
 
 int snd_amd_acp_find_config(struct pci_dev *pci);
diff --git a/sound/soc/amd/acp70/pci-acp70.c b/sound/soc/amd/acp70/pci-acp70.c
index 1e22be4f11bd..ff03fd493e98 100644
--- a/sound/soc/amd/acp70/pci-acp70.c
+++ b/sound/soc/amd/acp70/pci-acp70.c
@@ -99,6 +99,25 @@ static int acp70_deinit(void __iomem *acp_base, struct device *dev)
 	return 0;
 }
 
+static void handle_acp70_sdw_wake_event(struct acp70_dev_data *adata)
+{
+	struct amd_sdw_manager *amd_manager;
+
+	if (adata->sdw0_wake_event) {
+		amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
+		if (amd_manager && pm_runtime_suspended(amd_manager->dev))
+			pm_request_resume(amd_manager->dev);
+		adata->sdw0_wake_event = 0;
+	}
+
+	if (adata->sdw1_wake_event) {
+		amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
+		if (amd_manager && pm_runtime_suspended(amd_manager->dev))
+			pm_request_resume(amd_manager->dev);
+		adata->sdw1_wake_event = 0;
+	}
+}
+
 static irqreturn_t acp70_irq_thread(int irq, void *context)
 {
 	struct sdw_dma_dev_data *sdw_dma_data;
@@ -133,6 +152,7 @@ static irqreturn_t acp70_irq_handler(int irq, void *dev_id)
 	u32 stream_id = 0;
 	u16 irq_flag = 0;
 	u16 sdw_dma_irq_flag = 0;
+	bool sdw_wake_irq = false;
 	u16 index;
 
 	adata = dev_id;
@@ -169,6 +189,37 @@ static irqreturn_t acp70_irq_handler(int irq, void *dev_id)
 		irq_flag = 1;
 	}
 
+	if (ext_intr_stat1 & ACP_SDW0_HOST_WAKE_STAT) {
+		writel(ACP_SDW0_HOST_WAKE_STAT, adata->acp70_base + ACP_EXTERNAL_INTR_STAT1);
+		adata->sdw0_wake_event = true;
+		sdw_wake_irq = true;
+	}
+
+	if (ext_intr_stat1 & ACP_SDW1_HOST_WAKE_STAT) {
+		writel(ACP_SDW1_HOST_WAKE_STAT, adata->acp70_base + ACP_EXTERNAL_INTR_STAT1);
+		adata->sdw1_wake_event = true;
+		sdw_wake_irq = true;
+	}
+
+	if (ext_intr_stat1 & ACP_SDW0_PME_STAT) {
+		writel(0, adata->acp70_base + ACP_SW0_WAKE_EN);
+		writel(ACP_SDW0_PME_STAT, adata->acp70_base + ACP_EXTERNAL_INTR_STAT1);
+		adata->sdw0_wake_event = true;
+		sdw_wake_irq = true;
+	}
+
+	if (ext_intr_stat1 & ACP_SDW1_PME_STAT) {
+		writel(0, adata->acp70_base + ACP_SW1_WAKE_EN);
+		writel(ACP_SDW1_PME_STAT, adata->acp70_base + ACP_EXTERNAL_INTR_STAT1);
+		adata->sdw1_wake_event = true;
+		sdw_wake_irq = true;
+	}
+
+	if (sdw_wake_irq) {
+		handle_acp70_sdw_wake_event(adata);
+		irq_flag = 1;
+	}
+
 	if (ext_intr_stat & BIT(PDM_DMA_STAT)) {
 		ps_pdm_data = dev_get_drvdata(&adata->pdm_dev->dev);
 		writel(BIT(PDM_DMA_STAT), adata->acp70_base + ACP_EXTERNAL_INTR_STAT);
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ