aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/ahci.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index b6263b3996ab..146dc0b8ec61 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1331,6 +1331,44 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host)
1331{} 1331{}
1332#endif 1332#endif
1333 1333
1334#ifdef CONFIG_ARM64
1335/*
1336 * Due to ERRATA#22536, ThunderX needs to handle HOST_IRQ_STAT differently.
1337 * Workaround is to make sure all pending IRQs are served before leaving
1338 * handler.
1339 */
1340static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
1341{
1342 struct ata_host *host = dev_instance;
1343 struct ahci_host_priv *hpriv;
1344 unsigned int rc = 0;
1345 void __iomem *mmio;
1346 u32 irq_stat, irq_masked;
1347 unsigned int handled = 1;
1348
1349 VPRINTK("ENTER\n");
1350 hpriv = host->private_data;
1351 mmio = hpriv->mmio;
1352 irq_stat = readl(mmio + HOST_IRQ_STAT);
1353 if (!irq_stat)
1354 return IRQ_NONE;
1355
1356 do {
1357 irq_masked = irq_stat & hpriv->port_map;
1358 spin_lock(&host->lock);
1359 rc = ahci_handle_port_intr(host, irq_masked);
1360 if (!rc)
1361 handled = 0;
1362 writel(irq_stat, mmio + HOST_IRQ_STAT);
1363 irq_stat = readl(mmio + HOST_IRQ_STAT);
1364 spin_unlock(&host->lock);
1365 } while (irq_stat);
1366 VPRINTK("EXIT\n");
1367
1368 return IRQ_RETVAL(handled);
1369}
1370#endif
1371
1334/* 1372/*
1335 * ahci_init_msix() - optionally enable per-port MSI-X otherwise defer 1373 * ahci_init_msix() - optionally enable per-port MSI-X otherwise defer
1336 * to single msi. 1374 * to single msi.
@@ -1566,6 +1604,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1566 if (ahci_broken_devslp(pdev)) 1604 if (ahci_broken_devslp(pdev))
1567 hpriv->flags |= AHCI_HFLAG_NO_DEVSLP; 1605 hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
1568 1606
1607#ifdef CONFIG_ARM64
1608 if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
1609 hpriv->irq_handler = ahci_thunderx_irq_handler;
1610#endif
1611
1569 /* save initial config */ 1612 /* save initial config */
1570 ahci_pci_save_initial_config(pdev, hpriv); 1613 ahci_pci_save_initial_config(pdev, hpriv);
1571 1614