aspeed-g7: linux: Prevent processing stale DMA

Tested:
please see https://b.corp.google.com/issues/396553585#comment14
no abnormal postcode found
Fusion-Link:
fusion2/fe868348-8eff-3b4f-8f00-7dd80661d642
fusion2/21090ba3-8dd9-354d-8b18-1fac4f574a51
fusion2/cb4f927d-0adc-3e5e-b333-ff8851794ed3
fusion2/73e20adc-811b-3d80-b30a-36036c408f78
fusion2/c42daa4c-4c14-3c55-9bbf-a42c16ff60e8
Google-Bug-Id: 405060742
Change-Id: I8fe3be9ffc9d1a33a8491a7137b05d4707f2eb7f
Signed-off-by: Anh Phan <anhphan@google.com>
diff --git a/recipes-kernel/linux/files/0011-Prevent-processing-stale-DMA-data-on-spurious-interr.patch b/recipes-kernel/linux/files/0011-Prevent-processing-stale-DMA-data-on-spurious-interr.patch
new file mode 100644
index 0000000..9fd2fec
--- /dev/null
+++ b/recipes-kernel/linux/files/0011-Prevent-processing-stale-DMA-data-on-spurious-interr.patch
@@ -0,0 +1,51 @@
+From d1e33a9f806288794fbf10f04edf2d90ee937de0 Mon Sep 17 00:00:00 2001
+From: Cloud Hsu <cloudhsu@google.com>
+Date: Tue, 22 Apr 2025 13:04:41 +0800
+Subject: [PATCH 1/1] Prevent processing stale DMA data on spurious interrupt
+
+The do...while loop processing DMA data could incorrectly handle
+spurious interrupts where no new data was available (wptr == rptr). The
+loop would still execute once, incrementing rptr, causing it to process
+the entire buffer as stale data and cause the kfifo overflow to drop
+data. We have observed this issue on the AMD platform. Replace
+do...while loop with while loop to avoid this issue. The drawback of
+this fix is that it cannot handle the (wptr == rptr) situation. However,
+it is unlikely to happen with a DMA buffer size of 256K Bytes.
+
+The following log shows when the problem occurs.
+aspeed_pcc_dma_isr > postcode_cnt: 7773564
+aspeed_pcc_dma_isr > kfifo size: 262144
+aspeed_pcc_dma_isr > wptr: 29d7c, rptr: 29d7c
+aspeed_pcc_dma_isr > spurious interrupt
+aspeed_pcc_dma_isr > postcode_cnt: 8035708
+aspeed_pcc_dma_isr > kfifo size: 262144
+
+Signed-off-by: Cloud Hsu <cloudhsu@google.com>
+---
+ drivers/soc/aspeed/aspeed-lpc-pcc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/aspeed/aspeed-lpc-pcc.c b/drivers/soc/aspeed/aspeed-lpc-pcc.c
+index 038fad83fa76..433e2b80c5cf 100644
+--- a/drivers/soc/aspeed/aspeed-lpc-pcc.c
++++ b/drivers/soc/aspeed/aspeed-lpc-pcc.c
+@@ -178,14 +178,14 @@ static irqreturn_t aspeed_pcc_dma_isr(int irq, void *arg)
+ 	wptr = (reg & PCCR6_DMA_CUR_ADDR) - (pcc->dma.addr & PCCR6_DMA_CUR_ADDR);
+ 	rptr = pcc->dma.rptr;
+ 
+-	do {
++	while (rptr != wptr) {
+ 		if (kfifo_is_full(fifo))
+ 			kfifo_skip(fifo);
+ 
+ 		kfifo_put(fifo, pcc->dma.virt[rptr]);
+ 
+ 		rptr = (rptr + 1) % pcc->dma.size;
+-	} while (rptr != wptr);
++	}
+ 
+ 	pcc->dma.rptr = rptr;
+ 
+-- 
+2.49.0.805.g082f7c87e0-goog
+
diff --git a/recipes-kernel/linux/linux-gbmc_aspeedg7.bb b/recipes-kernel/linux/linux-gbmc_aspeedg7.bb
index 09e39aa..115c87a 100644
--- a/recipes-kernel/linux/linux-gbmc_aspeedg7.bb
+++ b/recipes-kernel/linux/linux-gbmc_aspeedg7.bb
@@ -72,6 +72,7 @@
     file://0006-i3c-hub-Fix-compilation-error.patch \
     file://0009-mipi-i3c-hci-disable-DMA-experimental.patch \
     file://0010-Fix-the-i3c-hub-node-mismatch-issue.patch \
+    file://0011-Prevent-processing-stale-DMA-data-on-spurious-interr.patch \
     file://i3c-hub.cfg \
 "