diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-05-29 10:05:05 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-05-29 10:05:05 -0400 |
commit | 6715930654e06c4d2e66e718ea159079f71838f4 (patch) | |
tree | 6a0a19fb62f3e99cb5f6bf6c34ae541f7c30fb42 /drivers/ata/sata_mv.c | |
parent | ea3f01f8afd3bc5daff915cc4ea5cc5ea9e7d427 (diff) | |
parent | e490517a039a99d692cb3a5561941b0a5f576172 (diff) |
Merge commit 'linus/master' into sched-fixes-for-linus
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 163 |
1 files changed, 93 insertions, 70 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index bb73b2222627..fb81f0c7a8c2 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -72,7 +72,7 @@ | |||
72 | #include <linux/libata.h> | 72 | #include <linux/libata.h> |
73 | 73 | ||
74 | #define DRV_NAME "sata_mv" | 74 | #define DRV_NAME "sata_mv" |
75 | #define DRV_VERSION "1.20" | 75 | #define DRV_VERSION "1.21" |
76 | 76 | ||
77 | enum { | 77 | enum { |
78 | /* BAR's are enumerated in terms of pci_resource_start() terms */ | 78 | /* BAR's are enumerated in terms of pci_resource_start() terms */ |
@@ -128,8 +128,13 @@ enum { | |||
128 | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 128 | MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
129 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | | 129 | ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | |
130 | ATA_FLAG_PIO_POLLING, | 130 | ATA_FLAG_PIO_POLLING, |
131 | |||
131 | MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, | 132 | MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, |
132 | 133 | ||
134 | MV_GENIIE_FLAGS = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | ||
135 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
136 | ATA_FLAG_NCQ | ATA_FLAG_AN, | ||
137 | |||
133 | CRQB_FLAG_READ = (1 << 0), | 138 | CRQB_FLAG_READ = (1 << 0), |
134 | CRQB_TAG_SHIFT = 1, | 139 | CRQB_TAG_SHIFT = 1, |
135 | CRQB_IOID_SHIFT = 6, /* CRQB Gen-II/IIE IO Id shift */ | 140 | CRQB_IOID_SHIFT = 6, /* CRQB Gen-II/IIE IO Id shift */ |
@@ -197,13 +202,6 @@ enum { | |||
197 | HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ | 202 | HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ |
198 | HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */ | 203 | HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */ |
199 | HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */ | 204 | HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */ |
200 | HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | | ||
201 | PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | | ||
202 | PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT | | ||
203 | HC_MAIN_RSVD), | ||
204 | HC_MAIN_MASKED_IRQS_5 = (PORTS_0_3_COAL_DONE | PORTS_4_7_COAL_DONE | | ||
205 | HC_MAIN_RSVD_5), | ||
206 | HC_MAIN_MASKED_IRQS_SOC = (PORTS_0_3_COAL_DONE | HC_MAIN_RSVD_SOC), | ||
207 | 205 | ||
208 | /* SATAHC registers */ | 206 | /* SATAHC registers */ |
209 | HC_CFG_OFS = 0, | 207 | HC_CFG_OFS = 0, |
@@ -221,6 +219,7 @@ enum { | |||
221 | SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ | 219 | SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ |
222 | SATA_ACTIVE_OFS = 0x350, | 220 | SATA_ACTIVE_OFS = 0x350, |
223 | SATA_FIS_IRQ_CAUSE_OFS = 0x364, | 221 | SATA_FIS_IRQ_CAUSE_OFS = 0x364, |
222 | SATA_FIS_IRQ_AN = (1 << 9), /* async notification */ | ||
224 | 223 | ||
225 | LTMODE_OFS = 0x30c, | 224 | LTMODE_OFS = 0x30c, |
226 | LTMODE_BIT8 = (1 << 8), /* unknown, but necessary */ | 225 | LTMODE_BIT8 = (1 << 8), /* unknown, but necessary */ |
@@ -459,6 +458,7 @@ struct mv_port_signal { | |||
459 | 458 | ||
460 | struct mv_host_priv { | 459 | struct mv_host_priv { |
461 | u32 hp_flags; | 460 | u32 hp_flags; |
461 | u32 main_irq_mask; | ||
462 | struct mv_port_signal signal[8]; | 462 | struct mv_port_signal signal[8]; |
463 | const struct mv_hw_ops *ops; | 463 | const struct mv_hw_ops *ops; |
464 | int n_ports; | 464 | int n_ports; |
@@ -640,25 +640,19 @@ static const struct ata_port_info mv_port_info[] = { | |||
640 | .port_ops = &mv6_ops, | 640 | .port_ops = &mv6_ops, |
641 | }, | 641 | }, |
642 | { /* chip_6042 */ | 642 | { /* chip_6042 */ |
643 | .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 643 | .flags = MV_GENIIE_FLAGS, |
644 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
645 | ATA_FLAG_NCQ, | ||
646 | .pio_mask = 0x1f, /* pio0-4 */ | 644 | .pio_mask = 0x1f, /* pio0-4 */ |
647 | .udma_mask = ATA_UDMA6, | 645 | .udma_mask = ATA_UDMA6, |
648 | .port_ops = &mv_iie_ops, | 646 | .port_ops = &mv_iie_ops, |
649 | }, | 647 | }, |
650 | { /* chip_7042 */ | 648 | { /* chip_7042 */ |
651 | .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 649 | .flags = MV_GENIIE_FLAGS, |
652 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
653 | ATA_FLAG_NCQ, | ||
654 | .pio_mask = 0x1f, /* pio0-4 */ | 650 | .pio_mask = 0x1f, /* pio0-4 */ |
655 | .udma_mask = ATA_UDMA6, | 651 | .udma_mask = ATA_UDMA6, |
656 | .port_ops = &mv_iie_ops, | 652 | .port_ops = &mv_iie_ops, |
657 | }, | 653 | }, |
658 | { /* chip_soc */ | 654 | { /* chip_soc */ |
659 | .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS | | 655 | .flags = MV_GENIIE_FLAGS | MV_FLAG_SOC, |
660 | ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA | | ||
661 | ATA_FLAG_NCQ | MV_FLAG_SOC, | ||
662 | .pio_mask = 0x1f, /* pio0-4 */ | 656 | .pio_mask = 0x1f, /* pio0-4 */ |
663 | .udma_mask = ATA_UDMA6, | 657 | .udma_mask = ATA_UDMA6, |
664 | .port_ops = &mv_iie_ops, | 658 | .port_ops = &mv_iie_ops, |
@@ -844,6 +838,33 @@ static void mv_set_edma_ptrs(void __iomem *port_mmio, | |||
844 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); | 838 | port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); |
845 | } | 839 | } |
846 | 840 | ||
841 | static void mv_set_main_irq_mask(struct ata_host *host, | ||
842 | u32 disable_bits, u32 enable_bits) | ||
843 | { | ||
844 | struct mv_host_priv *hpriv = host->private_data; | ||
845 | u32 old_mask, new_mask; | ||
846 | |||
847 | old_mask = hpriv->main_irq_mask; | ||
848 | new_mask = (old_mask & ~disable_bits) | enable_bits; | ||
849 | if (new_mask != old_mask) { | ||
850 | hpriv->main_irq_mask = new_mask; | ||
851 | writelfl(new_mask, hpriv->main_irq_mask_addr); | ||
852 | } | ||
853 | } | ||
854 | |||
855 | static void mv_enable_port_irqs(struct ata_port *ap, | ||
856 | unsigned int port_bits) | ||
857 | { | ||
858 | unsigned int shift, hardport, port = ap->port_no; | ||
859 | u32 disable_bits, enable_bits; | ||
860 | |||
861 | MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); | ||
862 | |||
863 | disable_bits = (DONE_IRQ | ERR_IRQ) << shift; | ||
864 | enable_bits = port_bits << shift; | ||
865 | mv_set_main_irq_mask(ap->host, disable_bits, enable_bits); | ||
866 | } | ||
867 | |||
847 | /** | 868 | /** |
848 | * mv_start_dma - Enable eDMA engine | 869 | * mv_start_dma - Enable eDMA engine |
849 | * @base: port base address | 870 | * @base: port base address |
@@ -886,9 +907,11 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio, | |||
886 | mv_edma_cfg(ap, want_ncq); | 907 | mv_edma_cfg(ap, want_ncq); |
887 | 908 | ||
888 | /* clear FIS IRQ Cause */ | 909 | /* clear FIS IRQ Cause */ |
889 | writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | 910 | if (IS_GEN_IIE(hpriv)) |
911 | writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
890 | 912 | ||
891 | mv_set_edma_ptrs(port_mmio, hpriv, pp); | 913 | mv_set_edma_ptrs(port_mmio, hpriv, pp); |
914 | mv_enable_port_irqs(ap, DONE_IRQ|ERR_IRQ); | ||
892 | 915 | ||
893 | writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); | 916 | writelfl(EDMA_EN, port_mmio + EDMA_CMD_OFS); |
894 | pp->pp_flags |= MV_PP_FLAG_EDMA_EN; | 917 | pp->pp_flags |= MV_PP_FLAG_EDMA_EN; |
@@ -1341,6 +1364,7 @@ out_port_free_dma_mem: | |||
1341 | static void mv_port_stop(struct ata_port *ap) | 1364 | static void mv_port_stop(struct ata_port *ap) |
1342 | { | 1365 | { |
1343 | mv_stop_edma(ap); | 1366 | mv_stop_edma(ap); |
1367 | mv_enable_port_irqs(ap, 0); | ||
1344 | mv_port_free_dma_mem(ap); | 1368 | mv_port_free_dma_mem(ap); |
1345 | } | 1369 | } |
1346 | 1370 | ||
@@ -1582,6 +1606,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | |||
1582 | * shadow block, etc registers. | 1606 | * shadow block, etc registers. |
1583 | */ | 1607 | */ |
1584 | mv_stop_edma(ap); | 1608 | mv_stop_edma(ap); |
1609 | mv_enable_port_irqs(ap, ERR_IRQ); | ||
1585 | mv_pmp_select(ap, qc->dev->link->pmp); | 1610 | mv_pmp_select(ap, qc->dev->link->pmp); |
1586 | return ata_sff_qc_issue(qc); | 1611 | return ata_sff_qc_issue(qc); |
1587 | } | 1612 | } |
@@ -1670,6 +1695,18 @@ static void mv_pmp_eh_prep(struct ata_port *ap, unsigned int pmp_map) | |||
1670 | } | 1695 | } |
1671 | } | 1696 | } |
1672 | 1697 | ||
1698 | static int mv_req_q_empty(struct ata_port *ap) | ||
1699 | { | ||
1700 | void __iomem *port_mmio = mv_ap_base(ap); | ||
1701 | u32 in_ptr, out_ptr; | ||
1702 | |||
1703 | in_ptr = (readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS) | ||
1704 | >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; | ||
1705 | out_ptr = (readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) | ||
1706 | >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK; | ||
1707 | return (in_ptr == out_ptr); /* 1 == queue_is_empty */ | ||
1708 | } | ||
1709 | |||
1673 | static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) | 1710 | static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) |
1674 | { | 1711 | { |
1675 | struct mv_port_priv *pp = ap->private_data; | 1712 | struct mv_port_priv *pp = ap->private_data; |
@@ -1703,7 +1740,7 @@ static int mv_handle_fbs_ncq_dev_err(struct ata_port *ap) | |||
1703 | ap->qc_active, failed_links, | 1740 | ap->qc_active, failed_links, |
1704 | ap->nr_active_links); | 1741 | ap->nr_active_links); |
1705 | 1742 | ||
1706 | if (ap->nr_active_links <= failed_links) { | 1743 | if (ap->nr_active_links <= failed_links && mv_req_q_empty(ap)) { |
1707 | mv_process_crpb_entries(ap, pp); | 1744 | mv_process_crpb_entries(ap, pp); |
1708 | mv_stop_edma(ap); | 1745 | mv_stop_edma(ap); |
1709 | mv_eh_freeze(ap); | 1746 | mv_eh_freeze(ap); |
@@ -1812,6 +1849,7 @@ static void mv_err_intr(struct ata_port *ap) | |||
1812 | { | 1849 | { |
1813 | void __iomem *port_mmio = mv_ap_base(ap); | 1850 | void __iomem *port_mmio = mv_ap_base(ap); |
1814 | u32 edma_err_cause, eh_freeze_mask, serr = 0; | 1851 | u32 edma_err_cause, eh_freeze_mask, serr = 0; |
1852 | u32 fis_cause = 0; | ||
1815 | struct mv_port_priv *pp = ap->private_data; | 1853 | struct mv_port_priv *pp = ap->private_data; |
1816 | struct mv_host_priv *hpriv = ap->host->private_data; | 1854 | struct mv_host_priv *hpriv = ap->host->private_data; |
1817 | unsigned int action = 0, err_mask = 0; | 1855 | unsigned int action = 0, err_mask = 0; |
@@ -1821,16 +1859,19 @@ static void mv_err_intr(struct ata_port *ap) | |||
1821 | 1859 | ||
1822 | /* | 1860 | /* |
1823 | * Read and clear the SError and err_cause bits. | 1861 | * Read and clear the SError and err_cause bits. |
1862 | * For GenIIe, if EDMA_ERR_TRANS_IRQ_7 is set, we also must read/clear | ||
1863 | * the FIS_IRQ_CAUSE register before clearing edma_err_cause. | ||
1824 | */ | 1864 | */ |
1825 | sata_scr_read(&ap->link, SCR_ERROR, &serr); | 1865 | sata_scr_read(&ap->link, SCR_ERROR, &serr); |
1826 | sata_scr_write_flush(&ap->link, SCR_ERROR, serr); | 1866 | sata_scr_write_flush(&ap->link, SCR_ERROR, serr); |
1827 | 1867 | ||
1828 | edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | 1868 | edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); |
1869 | if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) { | ||
1870 | fis_cause = readl(port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
1871 | writelfl(~fis_cause, port_mmio + SATA_FIS_IRQ_CAUSE_OFS); | ||
1872 | } | ||
1829 | writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | 1873 | writelfl(~edma_err_cause, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); |
1830 | 1874 | ||
1831 | ata_port_printk(ap, KERN_INFO, "%s: err_cause=%08x pp_flags=0x%x\n", | ||
1832 | __func__, edma_err_cause, pp->pp_flags); | ||
1833 | |||
1834 | if (edma_err_cause & EDMA_ERR_DEV) { | 1875 | if (edma_err_cause & EDMA_ERR_DEV) { |
1835 | /* | 1876 | /* |
1836 | * Device errors during FIS-based switching operation | 1877 | * Device errors during FIS-based switching operation |
@@ -1844,6 +1885,18 @@ static void mv_err_intr(struct ata_port *ap) | |||
1844 | ata_ehi_clear_desc(ehi); | 1885 | ata_ehi_clear_desc(ehi); |
1845 | ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x", | 1886 | ata_ehi_push_desc(ehi, "edma_err_cause=%08x pp_flags=%08x", |
1846 | edma_err_cause, pp->pp_flags); | 1887 | edma_err_cause, pp->pp_flags); |
1888 | |||
1889 | if (IS_GEN_IIE(hpriv) && (edma_err_cause & EDMA_ERR_TRANS_IRQ_7)) { | ||
1890 | ata_ehi_push_desc(ehi, "fis_cause=%08x", fis_cause); | ||
1891 | if (fis_cause & SATA_FIS_IRQ_AN) { | ||
1892 | u32 ec = edma_err_cause & | ||
1893 | ~(EDMA_ERR_TRANS_IRQ_7 | EDMA_ERR_IRQ_TRANSIENT); | ||
1894 | sata_async_notification(ap); | ||
1895 | if (!ec) | ||
1896 | return; /* Just an AN; no need for the nukes */ | ||
1897 | ata_ehi_push_desc(ehi, "SDB notify"); | ||
1898 | } | ||
1899 | } | ||
1847 | /* | 1900 | /* |
1848 | * All generations share these EDMA error cause bits: | 1901 | * All generations share these EDMA error cause bits: |
1849 | */ | 1902 | */ |
@@ -2162,20 +2215,20 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
2162 | struct ata_host *host = dev_instance; | 2215 | struct ata_host *host = dev_instance; |
2163 | struct mv_host_priv *hpriv = host->private_data; | 2216 | struct mv_host_priv *hpriv = host->private_data; |
2164 | unsigned int handled = 0; | 2217 | unsigned int handled = 0; |
2165 | u32 main_irq_cause, main_irq_mask; | 2218 | u32 main_irq_cause, pending_irqs; |
2166 | 2219 | ||
2167 | spin_lock(&host->lock); | 2220 | spin_lock(&host->lock); |
2168 | main_irq_cause = readl(hpriv->main_irq_cause_addr); | 2221 | main_irq_cause = readl(hpriv->main_irq_cause_addr); |
2169 | main_irq_mask = readl(hpriv->main_irq_mask_addr); | 2222 | pending_irqs = main_irq_cause & hpriv->main_irq_mask; |
2170 | /* | 2223 | /* |
2171 | * Deal with cases where we either have nothing pending, or have read | 2224 | * Deal with cases where we either have nothing pending, or have read |
2172 | * a bogus register value which can indicate HW removal or PCI fault. | 2225 | * a bogus register value which can indicate HW removal or PCI fault. |
2173 | */ | 2226 | */ |
2174 | if ((main_irq_cause & main_irq_mask) && (main_irq_cause != 0xffffffffU)) { | 2227 | if (pending_irqs && main_irq_cause != 0xffffffffU) { |
2175 | if (unlikely((main_irq_cause & PCI_ERR) && HAS_PCI(host))) | 2228 | if (unlikely((pending_irqs & PCI_ERR) && HAS_PCI(host))) |
2176 | handled = mv_pci_error(host, hpriv->base); | 2229 | handled = mv_pci_error(host, hpriv->base); |
2177 | else | 2230 | else |
2178 | handled = mv_host_intr(host, main_irq_cause); | 2231 | handled = mv_host_intr(host, pending_irqs); |
2179 | } | 2232 | } |
2180 | spin_unlock(&host->lock); | 2233 | spin_unlock(&host->lock); |
2181 | return IRQ_RETVAL(handled); | 2234 | return IRQ_RETVAL(handled); |
@@ -2373,7 +2426,6 @@ static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio) | |||
2373 | ZERO(MV_PCI_DISC_TIMER); | 2426 | ZERO(MV_PCI_DISC_TIMER); |
2374 | ZERO(MV_PCI_MSI_TRIGGER); | 2427 | ZERO(MV_PCI_MSI_TRIGGER); |
2375 | writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS); | 2428 | writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT_OFS); |
2376 | ZERO(PCI_HC_MAIN_IRQ_MASK_OFS); | ||
2377 | ZERO(MV_PCI_SERR_MASK); | 2429 | ZERO(MV_PCI_SERR_MASK); |
2378 | ZERO(hpriv->irq_cause_ofs); | 2430 | ZERO(hpriv->irq_cause_ofs); |
2379 | ZERO(hpriv->irq_mask_ofs); | 2431 | ZERO(hpriv->irq_mask_ofs); |
@@ -2728,6 +2780,7 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, | |||
2728 | 2780 | ||
2729 | rc = sata_link_hardreset(link, timing, deadline + extra, | 2781 | rc = sata_link_hardreset(link, timing, deadline + extra, |
2730 | &online, NULL); | 2782 | &online, NULL); |
2783 | rc = online ? -EAGAIN : rc; | ||
2731 | if (rc) | 2784 | if (rc) |
2732 | return rc; | 2785 | return rc; |
2733 | sata_scr_read(link, SCR_STATUS, &sstatus); | 2786 | sata_scr_read(link, SCR_STATUS, &sstatus); |
@@ -2744,32 +2797,18 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class, | |||
2744 | 2797 | ||
2745 | static void mv_eh_freeze(struct ata_port *ap) | 2798 | static void mv_eh_freeze(struct ata_port *ap) |
2746 | { | 2799 | { |
2747 | struct mv_host_priv *hpriv = ap->host->private_data; | ||
2748 | unsigned int shift, hardport, port = ap->port_no; | ||
2749 | u32 main_irq_mask; | ||
2750 | |||
2751 | /* FIXME: handle coalescing completion events properly */ | ||
2752 | |||
2753 | mv_stop_edma(ap); | 2800 | mv_stop_edma(ap); |
2754 | MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); | 2801 | mv_enable_port_irqs(ap, 0); |
2755 | |||
2756 | /* disable assertion of portN err, done events */ | ||
2757 | main_irq_mask = readl(hpriv->main_irq_mask_addr); | ||
2758 | main_irq_mask &= ~((DONE_IRQ | ERR_IRQ) << shift); | ||
2759 | writelfl(main_irq_mask, hpriv->main_irq_mask_addr); | ||
2760 | } | 2802 | } |
2761 | 2803 | ||
2762 | static void mv_eh_thaw(struct ata_port *ap) | 2804 | static void mv_eh_thaw(struct ata_port *ap) |
2763 | { | 2805 | { |
2764 | struct mv_host_priv *hpriv = ap->host->private_data; | 2806 | struct mv_host_priv *hpriv = ap->host->private_data; |
2765 | unsigned int shift, hardport, port = ap->port_no; | 2807 | unsigned int port = ap->port_no; |
2808 | unsigned int hardport = mv_hardport_from_port(port); | ||
2766 | void __iomem *hc_mmio = mv_hc_base_from_port(hpriv->base, port); | 2809 | void __iomem *hc_mmio = mv_hc_base_from_port(hpriv->base, port); |
2767 | void __iomem *port_mmio = mv_ap_base(ap); | 2810 | void __iomem *port_mmio = mv_ap_base(ap); |
2768 | u32 main_irq_mask, hc_irq_cause; | 2811 | u32 hc_irq_cause; |
2769 | |||
2770 | /* FIXME: handle coalescing completion events properly */ | ||
2771 | |||
2772 | MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport); | ||
2773 | 2812 | ||
2774 | /* clear EDMA errors on this port */ | 2813 | /* clear EDMA errors on this port */ |
2775 | writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | 2814 | writel(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); |
@@ -2779,10 +2818,7 @@ static void mv_eh_thaw(struct ata_port *ap) | |||
2779 | hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport); | 2818 | hc_irq_cause &= ~((DEV_IRQ | DMA_IRQ) << hardport); |
2780 | writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); | 2819 | writelfl(hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS); |
2781 | 2820 | ||
2782 | /* enable assertion of portN err, done events */ | 2821 | mv_enable_port_irqs(ap, ERR_IRQ); |
2783 | main_irq_mask = readl(hpriv->main_irq_mask_addr); | ||
2784 | main_irq_mask |= ((DONE_IRQ | ERR_IRQ) << shift); | ||
2785 | writelfl(main_irq_mask, hpriv->main_irq_mask_addr); | ||
2786 | } | 2822 | } |
2787 | 2823 | ||
2788 | /** | 2824 | /** |
@@ -3035,7 +3071,7 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3035 | } | 3071 | } |
3036 | 3072 | ||
3037 | /* global interrupt mask: 0 == mask everything */ | 3073 | /* global interrupt mask: 0 == mask everything */ |
3038 | writel(0, hpriv->main_irq_mask_addr); | 3074 | mv_set_main_irq_mask(host, ~0, 0); |
3039 | 3075 | ||
3040 | n_hc = mv_get_hc_count(host->ports[0]->flags); | 3076 | n_hc = mv_get_hc_count(host->ports[0]->flags); |
3041 | 3077 | ||
@@ -3083,25 +3119,12 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
3083 | 3119 | ||
3084 | /* and unmask interrupt generation for host regs */ | 3120 | /* and unmask interrupt generation for host regs */ |
3085 | writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); | 3121 | writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); |
3086 | if (IS_GEN_I(hpriv)) | 3122 | |
3087 | writelfl(~HC_MAIN_MASKED_IRQS_5, | 3123 | /* |
3088 | hpriv->main_irq_mask_addr); | 3124 | * enable only global host interrupts for now. |
3089 | else | 3125 | * The per-port interrupts get done later as ports are set up. |
3090 | writelfl(~HC_MAIN_MASKED_IRQS, | 3126 | */ |
3091 | hpriv->main_irq_mask_addr); | 3127 | mv_set_main_irq_mask(host, 0, PCI_ERR); |
3092 | |||
3093 | VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x " | ||
3094 | "PCI int cause/mask=0x%08x/0x%08x\n", | ||
3095 | readl(hpriv->main_irq_cause_addr), | ||
3096 | readl(hpriv->main_irq_mask_addr), | ||
3097 | readl(mmio + hpriv->irq_cause_ofs), | ||
3098 | readl(mmio + hpriv->irq_mask_ofs)); | ||
3099 | } else { | ||
3100 | writelfl(~HC_MAIN_MASKED_IRQS_SOC, | ||
3101 | hpriv->main_irq_mask_addr); | ||
3102 | VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x\n", | ||
3103 | readl(hpriv->main_irq_cause_addr), | ||
3104 | readl(hpriv->main_irq_mask_addr)); | ||
3105 | } | 3128 | } |
3106 | done: | 3129 | done: |
3107 | return rc; | 3130 | return rc; |