[PATCHv3 5/5] ata: sata_dwc_460ex: disable SATA interrupts on device removal

Rosen Penev <[email protected]> Wed, 8 Jul 2026 19:32:02 -0700
Newsgroups gmane.linux.ide,gmane.linux.kernel
Message-ID <[email protected]>
sata_dwc_remove() fails to mask the controller's INTMR and ERRMR
registers before tearing down the host.  If the hardware asserts an
interrupt during teardown (after ata_host_detach() but before the
IRQ handler is unregistered by devres), this can trigger an unhandled
interrupt storm and potentially lock up the system.

Add sata_dwc_disable_interrupts() and call it at the beginning of
sata_dwc_remove(), before ata_host_detach().

Fixes: 62936009f35a ("[libata] Add 460EX on-chip SATA driver, sata_dwc_460ex"
Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <[email protected]>
---
 drivers/ata/sata_dwc_460ex.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c
index 08d40e287bac..381ace5d33e1 100644
--- a/drivers/ata/sata_dwc_460ex.c
+++ b/drivers/ata/sata_dwc_460ex.c
@@ -752,6 +752,14 @@ static int sata_dwc_qc_complete(struct ata_port *ap, struct ata_queued_cmd *qc)
 	return 0;
 }
 
+static void sata_dwc_disable_interrupts(struct sata_dwc_device *hsdev)
+{
+	sata_dwc_writel(&hsdev->sata_dwc_regs->intmr, 0);
+	sata_dwc_writel(&hsdev->sata_dwc_regs->errmr, 0);
+	/* Flush posted writes */
+	sata_dwc_readl(&hsdev->sata_dwc_regs->intpr);
+}
+
 static void sata_dwc_enable_interrupts(struct sata_dwc_device *hsdev)
 {
 	/* Enable selective interrupts by setting the interrupt maskregister*/
@@ -1203,6 +1211,8 @@ static void sata_dwc_remove(struct platform_device *ofdev)
 	struct ata_host *host = dev_get_drvdata(dev);
 	struct sata_dwc_device *hsdev = host->private_data;
 
+	sata_dwc_disable_interrupts(hsdev);
+
 	ata_host_detach(host);
 
 	phy_exit(hsdev->phy);
-- 
2.55.0