[PATCHv2 6/8] ata: sata_dwc_460ex: disable SATA interrupts on device removal
Rosen Penev <[email protected]>
| Newsgroups | org.kernel.vger.linux-ide,org.kernel.vger.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(). Assisted-by: opencode:big-pickle Signed-off-by: Rosen Penev <[email protected]> --- drivers/ata/sata_dwc_460ex.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 4c54c3ecd18e..f26220cac130 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -759,6 +759,12 @@ 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); +} + static void sata_dwc_enable_interrupts(struct sata_dwc_device *hsdev) { /* Enable selective interrupts by setting the interrupt maskregister*/ @@ -1210,6 +1216,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