diff options
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 594fcabd22cd..146dc0b8ec61 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -264,6 +264,26 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
264 | { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ | 264 | { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ |
265 | { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ | 265 | { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */ |
266 | { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ | 266 | { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ |
267 | { PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */ | ||
268 | { PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */ | ||
269 | { PCI_VDEVICE(INTEL, 0x19b2), board_ahci }, /* DNV AHCI */ | ||
270 | { PCI_VDEVICE(INTEL, 0x19b3), board_ahci }, /* DNV AHCI */ | ||
271 | { PCI_VDEVICE(INTEL, 0x19b4), board_ahci }, /* DNV AHCI */ | ||
272 | { PCI_VDEVICE(INTEL, 0x19b5), board_ahci }, /* DNV AHCI */ | ||
273 | { PCI_VDEVICE(INTEL, 0x19b6), board_ahci }, /* DNV AHCI */ | ||
274 | { PCI_VDEVICE(INTEL, 0x19b7), board_ahci }, /* DNV AHCI */ | ||
275 | { PCI_VDEVICE(INTEL, 0x19bE), board_ahci }, /* DNV AHCI */ | ||
276 | { PCI_VDEVICE(INTEL, 0x19bF), board_ahci }, /* DNV AHCI */ | ||
277 | { PCI_VDEVICE(INTEL, 0x19c0), board_ahci }, /* DNV AHCI */ | ||
278 | { PCI_VDEVICE(INTEL, 0x19c1), board_ahci }, /* DNV AHCI */ | ||
279 | { PCI_VDEVICE(INTEL, 0x19c2), board_ahci }, /* DNV AHCI */ | ||
280 | { PCI_VDEVICE(INTEL, 0x19c3), board_ahci }, /* DNV AHCI */ | ||
281 | { PCI_VDEVICE(INTEL, 0x19c4), board_ahci }, /* DNV AHCI */ | ||
282 | { PCI_VDEVICE(INTEL, 0x19c5), board_ahci }, /* DNV AHCI */ | ||
283 | { PCI_VDEVICE(INTEL, 0x19c6), board_ahci }, /* DNV AHCI */ | ||
284 | { PCI_VDEVICE(INTEL, 0x19c7), board_ahci }, /* DNV AHCI */ | ||
285 | { PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */ | ||
286 | { PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */ | ||
267 | { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ | 287 | { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ |
268 | { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */ | 288 | { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */ |
269 | { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ | 289 | { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ |
@@ -347,15 +367,21 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
347 | { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ | 367 | { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ |
348 | { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ | 368 | { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ |
349 | { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/ | 369 | { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/ |
370 | { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/ | ||
350 | { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/ | 371 | { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/ |
372 | { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/ | ||
351 | { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/ | 373 | { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/ |
352 | { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/ | 374 | { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/ |
353 | { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/ | 375 | { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/ |
354 | { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/ | 376 | { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/ |
377 | { PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/ | ||
378 | { PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/ | ||
355 | { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/ | 379 | { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/ |
356 | { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/ | 380 | { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/ |
357 | { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/ | 381 | { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/ |
358 | { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/ | 382 | { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/ |
383 | { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/ | ||
384 | { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ | ||
359 | 385 | ||
360 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 386 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
361 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 387 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
@@ -1305,6 +1331,44 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) | |||
1305 | {} | 1331 | {} |
1306 | #endif | 1332 | #endif |
1307 | 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 | */ | ||
1340 | static 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 | |||
1308 | /* | 1372 | /* |
1309 | * ahci_init_msix() - optionally enable per-port MSI-X otherwise defer | 1373 | * ahci_init_msix() - optionally enable per-port MSI-X otherwise defer |
1310 | * to single msi. | 1374 | * to single msi. |
@@ -1540,6 +1604,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1540 | if (ahci_broken_devslp(pdev)) | 1604 | if (ahci_broken_devslp(pdev)) |
1541 | hpriv->flags |= AHCI_HFLAG_NO_DEVSLP; | 1605 | hpriv->flags |= AHCI_HFLAG_NO_DEVSLP; |
1542 | 1606 | ||
1607 | #ifdef CONFIG_ARM64 | ||
1608 | if (pdev->vendor == 0x177d && pdev->device == 0xa01c) | ||
1609 | hpriv->irq_handler = ahci_thunderx_irq_handler; | ||
1610 | #endif | ||
1611 | |||
1543 | /* save initial config */ | 1612 | /* save initial config */ |
1544 | ahci_pci_save_initial_config(pdev, hpriv); | 1613 | ahci_pci_save_initial_config(pdev, hpriv); |
1545 | 1614 | ||