diff options
-rw-r--r-- | drivers/ata/sata_mv.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 5dd969e10302..576e0cc19e25 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -170,7 +170,7 @@ enum { | |||
170 | 170 | ||
171 | PCIE_IRQ_CAUSE_OFS = 0x1900, | 171 | PCIE_IRQ_CAUSE_OFS = 0x1900, |
172 | PCIE_IRQ_MASK_OFS = 0x1910, | 172 | PCIE_IRQ_MASK_OFS = 0x1910, |
173 | PCIE_UNMASK_ALL_IRQS = 0x70a, /* assorted bits */ | 173 | PCIE_UNMASK_ALL_IRQS = 0x40a, /* assorted bits */ |
174 | 174 | ||
175 | HC_MAIN_IRQ_CAUSE_OFS = 0x1d60, | 175 | HC_MAIN_IRQ_CAUSE_OFS = 0x1d60, |
176 | HC_MAIN_IRQ_MASK_OFS = 0x1d64, | 176 | HC_MAIN_IRQ_MASK_OFS = 0x1d64, |
@@ -244,14 +244,33 @@ enum { | |||
244 | EDMA_ERR_CRPB_PAR = (1 << 10), /* CRPB parity error */ | 244 | EDMA_ERR_CRPB_PAR = (1 << 10), /* CRPB parity error */ |
245 | EDMA_ERR_INTRL_PAR = (1 << 11), /* internal parity error */ | 245 | EDMA_ERR_INTRL_PAR = (1 << 11), /* internal parity error */ |
246 | EDMA_ERR_IORDY = (1 << 12), /* IORdy timeout */ | 246 | EDMA_ERR_IORDY = (1 << 12), /* IORdy timeout */ |
247 | |||
247 | EDMA_ERR_LNK_CTRL_RX = (0xf << 13), /* link ctrl rx error */ | 248 | EDMA_ERR_LNK_CTRL_RX = (0xf << 13), /* link ctrl rx error */ |
248 | EDMA_ERR_LNK_CTRL_RX_2 = (1 << 15), | 249 | EDMA_ERR_LNK_CTRL_RX_0 = (1 << 13), /* transient: CRC err */ |
250 | EDMA_ERR_LNK_CTRL_RX_1 = (1 << 14), /* transient: FIFO err */ | ||
251 | EDMA_ERR_LNK_CTRL_RX_2 = (1 << 15), /* fatal: caught SYNC */ | ||
252 | EDMA_ERR_LNK_CTRL_RX_3 = (1 << 16), /* transient: FIS rx err */ | ||
253 | |||
249 | EDMA_ERR_LNK_DATA_RX = (0xf << 17), /* link data rx error */ | 254 | EDMA_ERR_LNK_DATA_RX = (0xf << 17), /* link data rx error */ |
255 | |||
250 | EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), /* link ctrl tx error */ | 256 | EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), /* link ctrl tx error */ |
257 | EDMA_ERR_LNK_CTRL_TX_0 = (1 << 21), /* transient: CRC err */ | ||
258 | EDMA_ERR_LNK_CTRL_TX_1 = (1 << 22), /* transient: FIFO err */ | ||
259 | EDMA_ERR_LNK_CTRL_TX_2 = (1 << 23), /* transient: caught SYNC */ | ||
260 | EDMA_ERR_LNK_CTRL_TX_3 = (1 << 24), /* transient: caught DMAT */ | ||
261 | EDMA_ERR_LNK_CTRL_TX_4 = (1 << 25), /* transient: FIS collision */ | ||
262 | |||
251 | EDMA_ERR_LNK_DATA_TX = (0x1f << 26), /* link data tx error */ | 263 | EDMA_ERR_LNK_DATA_TX = (0x1f << 26), /* link data tx error */ |
264 | |||
252 | EDMA_ERR_TRANS_PROTO = (1 << 31), /* transport protocol error */ | 265 | EDMA_ERR_TRANS_PROTO = (1 << 31), /* transport protocol error */ |
253 | EDMA_ERR_OVERRUN_5 = (1 << 5), | 266 | EDMA_ERR_OVERRUN_5 = (1 << 5), |
254 | EDMA_ERR_UNDERRUN_5 = (1 << 6), | 267 | EDMA_ERR_UNDERRUN_5 = (1 << 6), |
268 | |||
269 | EDMA_ERR_IRQ_TRANSIENT = EDMA_ERR_LNK_CTRL_RX_0 | | ||
270 | EDMA_ERR_LNK_CTRL_RX_1 | | ||
271 | EDMA_ERR_LNK_CTRL_RX_3 | | ||
272 | EDMA_ERR_LNK_CTRL_TX, | ||
273 | |||
255 | EDMA_EH_FREEZE = EDMA_ERR_D_PAR | | 274 | EDMA_EH_FREEZE = EDMA_ERR_D_PAR | |
256 | EDMA_ERR_PRD_PAR | | 275 | EDMA_ERR_PRD_PAR | |
257 | EDMA_ERR_DEV_DCON | | 276 | EDMA_ERR_DEV_DCON | |
@@ -1716,18 +1735,19 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance) | |||
1716 | struct ata_host *host = dev_instance; | 1735 | struct ata_host *host = dev_instance; |
1717 | unsigned int hc, handled = 0, n_hcs; | 1736 | unsigned int hc, handled = 0, n_hcs; |
1718 | void __iomem *mmio = host->iomap[MV_PRIMARY_BAR]; | 1737 | void __iomem *mmio = host->iomap[MV_PRIMARY_BAR]; |
1719 | u32 irq_stat; | 1738 | u32 irq_stat, irq_mask; |
1720 | 1739 | ||
1740 | spin_lock(&host->lock); | ||
1721 | irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS); | 1741 | irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS); |
1742 | irq_mask = readl(mmio + HC_MAIN_IRQ_MASK_OFS); | ||
1722 | 1743 | ||
1723 | /* check the cases where we either have nothing pending or have read | 1744 | /* check the cases where we either have nothing pending or have read |
1724 | * a bogus register value which can indicate HW removal or PCI fault | 1745 | * a bogus register value which can indicate HW removal or PCI fault |
1725 | */ | 1746 | */ |
1726 | if (!irq_stat || (0xffffffffU == irq_stat)) | 1747 | if (!(irq_stat & irq_mask) || (0xffffffffU == irq_stat)) |
1727 | return IRQ_NONE; | 1748 | goto out_unlock; |
1728 | 1749 | ||
1729 | n_hcs = mv_get_hc_count(host->ports[0]->flags); | 1750 | n_hcs = mv_get_hc_count(host->ports[0]->flags); |
1730 | spin_lock(&host->lock); | ||
1731 | 1751 | ||
1732 | if (unlikely(irq_stat & PCI_ERR)) { | 1752 | if (unlikely(irq_stat & PCI_ERR)) { |
1733 | mv_pci_error(host, mmio); | 1753 | mv_pci_error(host, mmio); |
@@ -2428,8 +2448,8 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) | |||
2428 | writelfl(readl(port_mmio + serr_ofs), port_mmio + serr_ofs); | 2448 | writelfl(readl(port_mmio + serr_ofs), port_mmio + serr_ofs); |
2429 | writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); | 2449 | writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); |
2430 | 2450 | ||
2431 | /* unmask all EDMA error interrupts */ | 2451 | /* unmask all non-transient EDMA error interrupts */ |
2432 | writelfl(~0, port_mmio + EDMA_ERR_IRQ_MASK_OFS); | 2452 | writelfl(~EDMA_ERR_IRQ_TRANSIENT, port_mmio + EDMA_ERR_IRQ_MASK_OFS); |
2433 | 2453 | ||
2434 | VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n", | 2454 | VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n", |
2435 | readl(port_mmio + EDMA_CFG_OFS), | 2455 | readl(port_mmio + EDMA_CFG_OFS), |