Jiri Slaby 3de804
From: =?UTF-8?q?Martin=20Povi=C5=A1er?= <povik+lin@cutebit.org>
Jiri Slaby 3de804
Date: Fri, 24 Feb 2023 16:22:20 +0100
Jiri Slaby 3de804
Subject: [PATCH] dmaengine: apple-admac: Handle 'global' interrupt flags
Jiri Slaby 3de804
MIME-Version: 1.0
Jiri Slaby 3de804
Content-Type: text/plain; charset=UTF-8
Jiri Slaby 3de804
Content-Transfer-Encoding: 8bit
Jiri Slaby 3de804
References: bsc#1012628
Jiri Slaby 3de804
Patch-mainline: 6.2.12
Jiri Slaby 3de804
Git-commit: a288fd158fbf85c06a9ac01cecabf97ac5d962e7
Jiri Slaby 3de804
Jiri Slaby 3de804
[ Upstream commit a288fd158fbf85c06a9ac01cecabf97ac5d962e7 ]
Jiri Slaby 3de804
Jiri Slaby 3de804
In addition to TX channel and RX channel interrupt flags there's
Jiri Slaby 3de804
another class of 'global' interrupt flags with unknown semantics. Those
Jiri Slaby 3de804
weren't being handled up to now, and they are the suspected cause of
Jiri Slaby 3de804
stuck IRQ states that have been sporadically occurring. Check the global
Jiri Slaby 3de804
flags and clear them if raised.
Jiri Slaby 3de804
Jiri Slaby 3de804
Fixes: b127315d9a78 ("dmaengine: apple-admac: Add Apple ADMAC driver")
Jiri Slaby 3de804
Signed-off-by: Martin PoviĊĦer <povik+lin@cutebit.org>
Jiri Slaby 3de804
Link: https://lore.kernel.org/r/20230224152222.26732-1-povik+lin@cutebit.org
Jiri Slaby 3de804
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Jiri Slaby 3de804
Signed-off-by: Sasha Levin <sashal@kernel.org>
Jiri Slaby 3de804
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby 3de804
---
Jiri Slaby 3de804
 drivers/dma/apple-admac.c | 12 ++++++++++--
Jiri Slaby 3de804
 1 file changed, 10 insertions(+), 2 deletions(-)
Jiri Slaby 3de804
Jiri Slaby 3de804
diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c
Jiri Slaby 3de804
index 90f28bda..00cbfafe 100644
Jiri Slaby 3de804
--- a/drivers/dma/apple-admac.c
Jiri Slaby 3de804
+++ b/drivers/dma/apple-admac.c
Jiri Slaby 3de804
@@ -75,6 +75,7 @@
Jiri Slaby 3de804
 
Jiri Slaby 3de804
 #define REG_TX_INTSTATE(idx)		(0x0030 + (idx) * 4)
Jiri Slaby 3de804
 #define REG_RX_INTSTATE(idx)		(0x0040 + (idx) * 4)
Jiri Slaby 3de804
+#define REG_GLOBAL_INTSTATE(idx)	(0x0050 + (idx) * 4)
Jiri Slaby 3de804
 #define REG_CHAN_INTSTATUS(ch, idx)	(0x8010 + (ch) * 0x200 + (idx) * 4)
Jiri Slaby 3de804
 #define REG_CHAN_INTMASK(ch, idx)	(0x8020 + (ch) * 0x200 + (idx) * 4)
Jiri Slaby 3de804
 
Jiri Slaby 3de804
@@ -672,13 +673,14 @@ static void admac_handle_chan_int(struct admac_data *ad, int no)
Jiri Slaby 3de804
 static irqreturn_t admac_interrupt(int irq, void *devid)
Jiri Slaby 3de804
 {
Jiri Slaby 3de804
 	struct admac_data *ad = devid;
Jiri Slaby 3de804
-	u32 rx_intstate, tx_intstate;
Jiri Slaby 3de804
+	u32 rx_intstate, tx_intstate, global_intstate;
Jiri Slaby 3de804
 	int i;
Jiri Slaby 3de804
 
Jiri Slaby 3de804
 	rx_intstate = readl_relaxed(ad->base + REG_RX_INTSTATE(ad->irq_index));
Jiri Slaby 3de804
 	tx_intstate = readl_relaxed(ad->base + REG_TX_INTSTATE(ad->irq_index));
Jiri Slaby 3de804
+	global_intstate = readl_relaxed(ad->base + REG_GLOBAL_INTSTATE(ad->irq_index));
Jiri Slaby 3de804
 
Jiri Slaby 3de804
-	if (!tx_intstate && !rx_intstate)
Jiri Slaby 3de804
+	if (!tx_intstate && !rx_intstate && !global_intstate)
Jiri Slaby 3de804
 		return IRQ_NONE;
Jiri Slaby 3de804
 
Jiri Slaby 3de804
 	for (i = 0; i < ad->nchannels; i += 2) {
Jiri Slaby 3de804
@@ -693,6 +695,12 @@ static irqreturn_t admac_interrupt(int irq, void *devid)
Jiri Slaby 3de804
 		rx_intstate >>= 1;
Jiri Slaby 3de804
 	}
Jiri Slaby 3de804
 
Jiri Slaby 3de804
+	if (global_intstate) {
Jiri Slaby 3de804
+		dev_warn(ad->dev, "clearing unknown global interrupt flag: %x\n",
Jiri Slaby 3de804
+			 global_intstate);
Jiri Slaby 3de804
+		writel_relaxed(~(u32) 0, ad->base + REG_GLOBAL_INTSTATE(ad->irq_index));
Jiri Slaby 3de804
+	}
Jiri Slaby 3de804
+
Jiri Slaby 3de804
 	return IRQ_HANDLED;
Jiri Slaby 3de804
 }
Jiri Slaby 3de804
 
Jiri Slaby 3de804
-- 
Jiri Slaby 3de804
2.35.3
Jiri Slaby 3de804