diff options
| -rw-r--r-- | Documentation/devicetree/bindings/ata/sata_rcar.txt | 6 | ||||
| -rw-r--r-- | drivers/ata/ahci.c | 28 | ||||
| -rw-r--r-- | drivers/ata/libahci.c | 78 | ||||
| -rw-r--r-- | drivers/ata/sata_rcar.c | 15 |
4 files changed, 55 insertions, 72 deletions
diff --git a/Documentation/devicetree/bindings/ata/sata_rcar.txt b/Documentation/devicetree/bindings/ata/sata_rcar.txt index 1e6111333fa8..80ae87a0784b 100644 --- a/Documentation/devicetree/bindings/ata/sata_rcar.txt +++ b/Documentation/devicetree/bindings/ata/sata_rcar.txt | |||
| @@ -3,8 +3,10 @@ | |||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible : should contain one of the following: | 4 | - compatible : should contain one of the following: |
| 5 | - "renesas,sata-r8a7779" for R-Car H1 | 5 | - "renesas,sata-r8a7779" for R-Car H1 |
| 6 | - "renesas,sata-r8a7790" for R-Car H2 | 6 | - "renesas,sata-r8a7790-es1" for R-Car H2 ES1 |
| 7 | - "renesas,sata-r8a7791" for R-Car M2 | 7 | - "renesas,sata-r8a7790" for R-Car H2 other than ES1 |
| 8 | - "renesas,sata-r8a7791" for R-Car M2-W | ||
| 9 | - "renesas,sata-r8a7793" for R-Car M2-N | ||
| 8 | - reg : address and length of the SATA registers; | 10 | - reg : address and length of the SATA registers; |
| 9 | - interrupts : must consist of one interrupt specifier. | 11 | - interrupts : must consist of one interrupt specifier. |
| 10 | 12 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5f039f191067..e45f83789809 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
| @@ -60,6 +60,7 @@ enum board_ids { | |||
| 60 | /* board IDs by feature in alphabetical order */ | 60 | /* board IDs by feature in alphabetical order */ |
| 61 | board_ahci, | 61 | board_ahci, |
| 62 | board_ahci_ign_iferr, | 62 | board_ahci_ign_iferr, |
| 63 | board_ahci_nomsi, | ||
| 63 | board_ahci_noncq, | 64 | board_ahci_noncq, |
| 64 | board_ahci_nosntf, | 65 | board_ahci_nosntf, |
| 65 | board_ahci_yes_fbs, | 66 | board_ahci_yes_fbs, |
| @@ -121,6 +122,13 @@ static const struct ata_port_info ahci_port_info[] = { | |||
| 121 | .udma_mask = ATA_UDMA6, | 122 | .udma_mask = ATA_UDMA6, |
| 122 | .port_ops = &ahci_ops, | 123 | .port_ops = &ahci_ops, |
| 123 | }, | 124 | }, |
| 125 | [board_ahci_nomsi] = { | ||
| 126 | AHCI_HFLAGS (AHCI_HFLAG_NO_MSI), | ||
| 127 | .flags = AHCI_FLAG_COMMON, | ||
| 128 | .pio_mask = ATA_PIO4, | ||
| 129 | .udma_mask = ATA_UDMA6, | ||
| 130 | .port_ops = &ahci_ops, | ||
| 131 | }, | ||
| 124 | [board_ahci_noncq] = { | 132 | [board_ahci_noncq] = { |
| 125 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ), | 133 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ), |
| 126 | .flags = AHCI_FLAG_COMMON, | 134 | .flags = AHCI_FLAG_COMMON, |
| @@ -313,6 +321,11 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
| 313 | { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */ | 321 | { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */ |
| 314 | { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ | 322 | { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ |
| 315 | { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */ | 323 | { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */ |
| 324 | { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ | ||
| 325 | { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */ | ||
| 326 | { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ | ||
| 327 | { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ | ||
| 328 | { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ | ||
| 316 | 329 | ||
| 317 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 330 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
| 318 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 331 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
| @@ -475,10 +488,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
| 475 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ | 488 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ |
| 476 | 489 | ||
| 477 | /* | 490 | /* |
| 478 | * Samsung SSDs found on some macbooks. NCQ times out. | 491 | * Samsung SSDs found on some macbooks. NCQ times out if MSI is |
| 479 | * https://bugzilla.kernel.org/show_bug.cgi?id=60731 | 492 | * enabled. https://bugzilla.kernel.org/show_bug.cgi?id=60731 |
| 480 | */ | 493 | */ |
| 481 | { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq }, | 494 | { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi }, |
| 482 | 495 | ||
| 483 | /* Enmotus */ | 496 | /* Enmotus */ |
| 484 | { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, | 497 | { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, |
| @@ -514,12 +527,9 @@ MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)"); | |||
| 514 | static void ahci_pci_save_initial_config(struct pci_dev *pdev, | 527 | static void ahci_pci_save_initial_config(struct pci_dev *pdev, |
| 515 | struct ahci_host_priv *hpriv) | 528 | struct ahci_host_priv *hpriv) |
| 516 | { | 529 | { |
| 517 | unsigned int force_port_map = 0; | ||
| 518 | unsigned int mask_port_map = 0; | ||
| 519 | |||
| 520 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { | 530 | if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { |
| 521 | dev_info(&pdev->dev, "JMB361 has only one port\n"); | 531 | dev_info(&pdev->dev, "JMB361 has only one port\n"); |
| 522 | force_port_map = 1; | 532 | hpriv->force_port_map = 1; |
| 523 | } | 533 | } |
| 524 | 534 | ||
| 525 | /* | 535 | /* |
| @@ -529,9 +539,9 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev, | |||
| 529 | */ | 539 | */ |
| 530 | if (hpriv->flags & AHCI_HFLAG_MV_PATA) { | 540 | if (hpriv->flags & AHCI_HFLAG_MV_PATA) { |
| 531 | if (pdev->device == 0x6121) | 541 | if (pdev->device == 0x6121) |
| 532 | mask_port_map = 0x3; | 542 | hpriv->mask_port_map = 0x3; |
| 533 | else | 543 | else |
| 534 | mask_port_map = 0xf; | 544 | hpriv->mask_port_map = 0xf; |
| 535 | dev_info(&pdev->dev, | 545 | dev_info(&pdev->dev, |
| 536 | "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n"); | 546 | "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n"); |
| 537 | } | 547 | } |
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 5eb61c9e63da..97683e45ab04 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
| @@ -1778,16 +1778,15 @@ static void ahci_handle_port_interrupt(struct ata_port *ap, | |||
| 1778 | } | 1778 | } |
| 1779 | } | 1779 | } |
| 1780 | 1780 | ||
| 1781 | static void ahci_update_intr_status(struct ata_port *ap) | 1781 | static void ahci_port_intr(struct ata_port *ap) |
| 1782 | { | 1782 | { |
| 1783 | void __iomem *port_mmio = ahci_port_base(ap); | 1783 | void __iomem *port_mmio = ahci_port_base(ap); |
| 1784 | struct ahci_port_priv *pp = ap->private_data; | ||
| 1785 | u32 status; | 1784 | u32 status; |
| 1786 | 1785 | ||
| 1787 | status = readl(port_mmio + PORT_IRQ_STAT); | 1786 | status = readl(port_mmio + PORT_IRQ_STAT); |
| 1788 | writel(status, port_mmio + PORT_IRQ_STAT); | 1787 | writel(status, port_mmio + PORT_IRQ_STAT); |
| 1789 | 1788 | ||
| 1790 | atomic_or(status, &pp->intr_status); | 1789 | ahci_handle_port_interrupt(ap, port_mmio, status); |
| 1791 | } | 1790 | } |
| 1792 | 1791 | ||
| 1793 | static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance) | 1792 | static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance) |
| @@ -1808,34 +1807,6 @@ static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance) | |||
| 1808 | return IRQ_HANDLED; | 1807 | return IRQ_HANDLED; |
| 1809 | } | 1808 | } |
| 1810 | 1809 | ||
| 1811 | irqreturn_t ahci_thread_fn(int irq, void *dev_instance) | ||
| 1812 | { | ||
| 1813 | struct ata_host *host = dev_instance; | ||
| 1814 | struct ahci_host_priv *hpriv = host->private_data; | ||
| 1815 | u32 irq_masked = hpriv->port_map; | ||
| 1816 | unsigned int i; | ||
| 1817 | |||
| 1818 | for (i = 0; i < host->n_ports; i++) { | ||
| 1819 | struct ata_port *ap; | ||
| 1820 | |||
| 1821 | if (!(irq_masked & (1 << i))) | ||
| 1822 | continue; | ||
| 1823 | |||
| 1824 | ap = host->ports[i]; | ||
| 1825 | if (ap) { | ||
| 1826 | ahci_port_thread_fn(irq, ap); | ||
| 1827 | VPRINTK("port %u\n", i); | ||
| 1828 | } else { | ||
| 1829 | VPRINTK("port %u (no irq)\n", i); | ||
| 1830 | if (ata_ratelimit()) | ||
| 1831 | dev_warn(host->dev, | ||
| 1832 | "interrupt on disabled port %u\n", i); | ||
| 1833 | } | ||
| 1834 | } | ||
| 1835 | |||
| 1836 | return IRQ_HANDLED; | ||
| 1837 | } | ||
| 1838 | |||
| 1839 | static irqreturn_t ahci_multi_irqs_intr(int irq, void *dev_instance) | 1810 | static irqreturn_t ahci_multi_irqs_intr(int irq, void *dev_instance) |
| 1840 | { | 1811 | { |
| 1841 | struct ata_port *ap = dev_instance; | 1812 | struct ata_port *ap = dev_instance; |
| @@ -1875,6 +1846,8 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance) | |||
| 1875 | 1846 | ||
| 1876 | irq_masked = irq_stat & hpriv->port_map; | 1847 | irq_masked = irq_stat & hpriv->port_map; |
| 1877 | 1848 | ||
| 1849 | spin_lock(&host->lock); | ||
| 1850 | |||
| 1878 | for (i = 0; i < host->n_ports; i++) { | 1851 | for (i = 0; i < host->n_ports; i++) { |
| 1879 | struct ata_port *ap; | 1852 | struct ata_port *ap; |
| 1880 | 1853 | ||
| @@ -1883,7 +1856,7 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance) | |||
| 1883 | 1856 | ||
| 1884 | ap = host->ports[i]; | 1857 | ap = host->ports[i]; |
| 1885 | if (ap) { | 1858 | if (ap) { |
| 1886 | ahci_update_intr_status(ap); | 1859 | ahci_port_intr(ap); |
| 1887 | VPRINTK("port %u\n", i); | 1860 | VPRINTK("port %u\n", i); |
| 1888 | } else { | 1861 | } else { |
| 1889 | VPRINTK("port %u (no irq)\n", i); | 1862 | VPRINTK("port %u (no irq)\n", i); |
| @@ -1906,9 +1879,11 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance) | |||
| 1906 | */ | 1879 | */ |
| 1907 | writel(irq_stat, mmio + HOST_IRQ_STAT); | 1880 | writel(irq_stat, mmio + HOST_IRQ_STAT); |
| 1908 | 1881 | ||
| 1882 | spin_unlock(&host->lock); | ||
| 1883 | |||
| 1909 | VPRINTK("EXIT\n"); | 1884 | VPRINTK("EXIT\n"); |
| 1910 | 1885 | ||
| 1911 | return handled ? IRQ_WAKE_THREAD : IRQ_NONE; | 1886 | return IRQ_RETVAL(handled); |
| 1912 | } | 1887 | } |
| 1913 | 1888 | ||
| 1914 | unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) | 1889 | unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) |
| @@ -2320,8 +2295,13 @@ static int ahci_port_start(struct ata_port *ap) | |||
| 2320 | */ | 2295 | */ |
| 2321 | pp->intr_mask = DEF_PORT_IRQ; | 2296 | pp->intr_mask = DEF_PORT_IRQ; |
| 2322 | 2297 | ||
| 2323 | spin_lock_init(&pp->lock); | 2298 | /* |
| 2324 | ap->lock = &pp->lock; | 2299 | * Switch to per-port locking in case each port has its own MSI vector. |
| 2300 | */ | ||
| 2301 | if ((hpriv->flags & AHCI_HFLAG_MULTI_MSI)) { | ||
| 2302 | spin_lock_init(&pp->lock); | ||
| 2303 | ap->lock = &pp->lock; | ||
| 2304 | } | ||
| 2325 | 2305 | ||
| 2326 | ap->private_data = pp; | 2306 | ap->private_data = pp; |
| 2327 | 2307 | ||
| @@ -2482,31 +2462,6 @@ out_free_irqs: | |||
| 2482 | return rc; | 2462 | return rc; |
| 2483 | } | 2463 | } |
| 2484 | 2464 | ||
| 2485 | static int ahci_host_activate_single_irq(struct ata_host *host, int irq, | ||
| 2486 | struct scsi_host_template *sht) | ||
| 2487 | { | ||
| 2488 | int i, rc; | ||
| 2489 | |||
| 2490 | rc = ata_host_start(host); | ||
| 2491 | if (rc) | ||
| 2492 | return rc; | ||
| 2493 | |||
| 2494 | rc = devm_request_threaded_irq(host->dev, irq, ahci_single_irq_intr, | ||
| 2495 | ahci_thread_fn, IRQF_SHARED, | ||
| 2496 | dev_driver_string(host->dev), host); | ||
| 2497 | if (rc) | ||
| 2498 | return rc; | ||
| 2499 | |||
| 2500 | for (i = 0; i < host->n_ports; i++) | ||
| 2501 | ata_port_desc(host->ports[i], "irq %d", irq); | ||
| 2502 | |||
| 2503 | rc = ata_host_register(host, sht); | ||
| 2504 | if (rc) | ||
| 2505 | devm_free_irq(host->dev, irq, host); | ||
| 2506 | |||
| 2507 | return rc; | ||
| 2508 | } | ||
| 2509 | |||
| 2510 | /** | 2465 | /** |
| 2511 | * ahci_host_activate - start AHCI host, request IRQs and register it | 2466 | * ahci_host_activate - start AHCI host, request IRQs and register it |
| 2512 | * @host: target ATA host | 2467 | * @host: target ATA host |
| @@ -2532,7 +2487,8 @@ int ahci_host_activate(struct ata_host *host, int irq, | |||
| 2532 | if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) | 2487 | if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) |
| 2533 | rc = ahci_host_activate_multi_irqs(host, irq, sht); | 2488 | rc = ahci_host_activate_multi_irqs(host, irq, sht); |
| 2534 | else | 2489 | else |
| 2535 | rc = ahci_host_activate_single_irq(host, irq, sht); | 2490 | rc = ata_host_activate(host, irq, ahci_single_irq_intr, |
| 2491 | IRQF_SHARED, sht); | ||
| 2536 | return rc; | 2492 | return rc; |
| 2537 | } | 2493 | } |
| 2538 | EXPORT_SYMBOL_GPL(ahci_host_activate); | 2494 | EXPORT_SYMBOL_GPL(ahci_host_activate); |
diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 61eb6d77dac7..ea1fbc1d4c5f 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c | |||
| @@ -146,6 +146,7 @@ | |||
| 146 | enum sata_rcar_type { | 146 | enum sata_rcar_type { |
| 147 | RCAR_GEN1_SATA, | 147 | RCAR_GEN1_SATA, |
| 148 | RCAR_GEN2_SATA, | 148 | RCAR_GEN2_SATA, |
| 149 | RCAR_R8A7790_ES1_SATA, | ||
| 149 | }; | 150 | }; |
| 150 | 151 | ||
| 151 | struct sata_rcar_priv { | 152 | struct sata_rcar_priv { |
| @@ -763,6 +764,9 @@ static void sata_rcar_setup_port(struct ata_host *host) | |||
| 763 | ap->udma_mask = ATA_UDMA6; | 764 | ap->udma_mask = ATA_UDMA6; |
| 764 | ap->flags |= ATA_FLAG_SATA; | 765 | ap->flags |= ATA_FLAG_SATA; |
| 765 | 766 | ||
| 767 | if (priv->type == RCAR_R8A7790_ES1_SATA) | ||
| 768 | ap->flags |= ATA_FLAG_NO_DIPM; | ||
| 769 | |||
| 766 | ioaddr->cmd_addr = base + SDATA_REG; | 770 | ioaddr->cmd_addr = base + SDATA_REG; |
| 767 | ioaddr->ctl_addr = base + SSDEVCON_REG; | 771 | ioaddr->ctl_addr = base + SSDEVCON_REG; |
| 768 | ioaddr->scr_addr = base + SCRSSTS_REG; | 772 | ioaddr->scr_addr = base + SCRSSTS_REG; |
| @@ -792,6 +796,7 @@ static void sata_rcar_init_controller(struct ata_host *host) | |||
| 792 | sata_rcar_gen1_phy_init(priv); | 796 | sata_rcar_gen1_phy_init(priv); |
| 793 | break; | 797 | break; |
| 794 | case RCAR_GEN2_SATA: | 798 | case RCAR_GEN2_SATA: |
| 799 | case RCAR_R8A7790_ES1_SATA: | ||
| 795 | sata_rcar_gen2_phy_init(priv); | 800 | sata_rcar_gen2_phy_init(priv); |
| 796 | break; | 801 | break; |
| 797 | default: | 802 | default: |
| @@ -838,9 +843,17 @@ static struct of_device_id sata_rcar_match[] = { | |||
| 838 | .data = (void *)RCAR_GEN2_SATA | 843 | .data = (void *)RCAR_GEN2_SATA |
| 839 | }, | 844 | }, |
| 840 | { | 845 | { |
| 846 | .compatible = "renesas,sata-r8a7790-es1", | ||
| 847 | .data = (void *)RCAR_R8A7790_ES1_SATA | ||
| 848 | }, | ||
| 849 | { | ||
| 841 | .compatible = "renesas,sata-r8a7791", | 850 | .compatible = "renesas,sata-r8a7791", |
| 842 | .data = (void *)RCAR_GEN2_SATA | 851 | .data = (void *)RCAR_GEN2_SATA |
| 843 | }, | 852 | }, |
| 853 | { | ||
| 854 | .compatible = "renesas,sata-r8a7793", | ||
| 855 | .data = (void *)RCAR_GEN2_SATA | ||
| 856 | }, | ||
| 844 | { }, | 857 | { }, |
| 845 | }; | 858 | }; |
| 846 | MODULE_DEVICE_TABLE(of, sata_rcar_match); | 859 | MODULE_DEVICE_TABLE(of, sata_rcar_match); |
| @@ -849,7 +862,9 @@ static const struct platform_device_id sata_rcar_id_table[] = { | |||
| 849 | { "sata_rcar", RCAR_GEN1_SATA }, /* Deprecated by "sata-r8a7779" */ | 862 | { "sata_rcar", RCAR_GEN1_SATA }, /* Deprecated by "sata-r8a7779" */ |
| 850 | { "sata-r8a7779", RCAR_GEN1_SATA }, | 863 | { "sata-r8a7779", RCAR_GEN1_SATA }, |
| 851 | { "sata-r8a7790", RCAR_GEN2_SATA }, | 864 | { "sata-r8a7790", RCAR_GEN2_SATA }, |
| 865 | { "sata-r8a7790-es1", RCAR_R8A7790_ES1_SATA }, | ||
| 852 | { "sata-r8a7791", RCAR_GEN2_SATA }, | 866 | { "sata-r8a7791", RCAR_GEN2_SATA }, |
| 867 | { "sata-r8a7793", RCAR_GEN2_SATA }, | ||
| 853 | { }, | 868 | { }, |
| 854 | }; | 869 | }; |
| 855 | MODULE_DEVICE_TABLE(platform, sata_rcar_id_table); | 870 | MODULE_DEVICE_TABLE(platform, sata_rcar_id_table); |
