@@ -56,6 +56,7 @@ static int acp63_reset(void __iomem *acp_base)
5656static void acp63_enable_interrupts (void __iomem * acp_base )
5757{
5858 writel (1 , acp_base + ACP_EXTERNAL_INTR_ENB );
59+ writel (ACP_ERROR_IRQ , acp_base + ACP_EXTERNAL_INTR_CNTL );
5960}
6061
6162static void acp63_disable_interrupts (void __iomem * acp_base )
@@ -102,23 +103,60 @@ static irqreturn_t acp63_irq_handler(int irq, void *dev_id)
102103{
103104 struct acp63_dev_data * adata ;
104105 struct pdm_dev_data * ps_pdm_data ;
105- u32 val ;
106+ struct amd_sdw_manager * amd_manager ;
107+ u32 ext_intr_stat , ext_intr_stat1 ;
108+ u16 irq_flag = 0 ;
106109 u16 pdev_index ;
107110
108111 adata = dev_id ;
109112 if (!adata )
110113 return IRQ_NONE ;
114+ /* ACP interrupts will be cleared by reading particular bit and writing
115+ * same value to the status register. writing zero's doesn't have any
116+ * effect.
117+ * Bit by bit checking of IRQ field is implemented.
118+ */
119+ ext_intr_stat = readl (adata -> acp63_base + ACP_EXTERNAL_INTR_STAT );
120+ if (ext_intr_stat & ACP_SDW0_STAT ) {
121+ writel (ACP_SDW0_STAT , adata -> acp63_base + ACP_EXTERNAL_INTR_STAT );
122+ pdev_index = adata -> sdw0_dev_index ;
123+ amd_manager = dev_get_drvdata (& adata -> pdev [pdev_index ]-> dev );
124+ if (amd_manager )
125+ schedule_work (& amd_manager -> amd_sdw_irq_thread );
126+ irq_flag = 1 ;
127+ }
128+
129+ ext_intr_stat1 = readl (adata -> acp63_base + ACP_EXTERNAL_INTR_STAT1 );
130+ if (ext_intr_stat1 & ACP_SDW1_STAT ) {
131+ writel (ACP_SDW1_STAT , adata -> acp63_base + ACP_EXTERNAL_INTR_STAT1 );
132+ pdev_index = adata -> sdw1_dev_index ;
133+ amd_manager = dev_get_drvdata (& adata -> pdev [pdev_index ]-> dev );
134+ if (amd_manager )
135+ schedule_work (& amd_manager -> amd_sdw_irq_thread );
136+ irq_flag = 1 ;
137+ }
111138
112- val = readl (adata -> acp63_base + ACP_EXTERNAL_INTR_STAT );
113- if (val & BIT (PDM_DMA_STAT )) {
139+ if (ext_intr_stat & ACP_ERROR_IRQ ) {
140+ writel (ACP_ERROR_IRQ , adata -> acp63_base + ACP_EXTERNAL_INTR_STAT );
141+ /* TODO: Report SoundWire Manager instance errors */
142+ writel (0 , adata -> acp63_base + ACP_SW0_I2S_ERROR_REASON );
143+ writel (0 , adata -> acp63_base + ACP_SW1_I2S_ERROR_REASON );
144+ writel (0 , adata -> acp63_base + ACP_ERROR_STATUS );
145+ irq_flag = 1 ;
146+ }
147+
148+ if (ext_intr_stat & BIT (PDM_DMA_STAT )) {
114149 pdev_index = adata -> pdm_dev_index ;
115150 ps_pdm_data = dev_get_drvdata (& adata -> pdev [pdev_index ]-> dev );
116151 writel (BIT (PDM_DMA_STAT ), adata -> acp63_base + ACP_EXTERNAL_INTR_STAT );
117152 if (ps_pdm_data -> capture_stream )
118153 snd_pcm_period_elapsed (ps_pdm_data -> capture_stream );
119- return IRQ_HANDLED ;
154+ irq_flag = 1 ;
120155 }
121- return IRQ_NONE ;
156+ if (irq_flag )
157+ return IRQ_HANDLED ;
158+ else
159+ return IRQ_NONE ;
122160}
123161
124162static int sdw_amd_scan_controller (struct device * dev )
0 commit comments