Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 646a4da5 authored by Mark Lord's avatar Mark Lord Committed by Jeff Garzik
Browse files

sata_mv ncq Mask transient IRQs



The chips can handle many transient errors internally without a software IRQ.
We now mask/ignore those interrupts here.  This is necessary for NCQ, later on.

Signed-off-by: default avatarMark Lord <mlord@pobox.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 3606a380
Loading
Loading
Loading
Loading
+28 −8
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ enum {

	PCIE_IRQ_CAUSE_OFS	= 0x1900,
	PCIE_IRQ_MASK_OFS	= 0x1910,
	PCIE_UNMASK_ALL_IRQS	= 0x70a,	/* assorted bits */
	PCIE_UNMASK_ALL_IRQS	= 0x40a,	/* assorted bits */

	HC_MAIN_IRQ_CAUSE_OFS	= 0x1d60,
	HC_MAIN_IRQ_MASK_OFS	= 0x1d64,
@@ -244,14 +244,33 @@ enum {
	EDMA_ERR_CRPB_PAR	= (1 << 10),	/* CRPB parity error */
	EDMA_ERR_INTRL_PAR	= (1 << 11),	/* internal parity error */
	EDMA_ERR_IORDY		= (1 << 12),	/* IORdy timeout */

	EDMA_ERR_LNK_CTRL_RX	= (0xf << 13),	/* link ctrl rx error */
	EDMA_ERR_LNK_CTRL_RX_2	= (1 << 15),
	EDMA_ERR_LNK_CTRL_RX_0	= (1 << 13),	/* transient: CRC err */
	EDMA_ERR_LNK_CTRL_RX_1	= (1 << 14),	/* transient: FIFO err */
	EDMA_ERR_LNK_CTRL_RX_2	= (1 << 15),	/* fatal: caught SYNC */
	EDMA_ERR_LNK_CTRL_RX_3	= (1 << 16),	/* transient: FIS rx err */

	EDMA_ERR_LNK_DATA_RX	= (0xf << 17),	/* link data rx error */

	EDMA_ERR_LNK_CTRL_TX	= (0x1f << 21),	/* link ctrl tx error */
	EDMA_ERR_LNK_CTRL_TX_0	= (1 << 21),	/* transient: CRC err */
	EDMA_ERR_LNK_CTRL_TX_1	= (1 << 22),	/* transient: FIFO err */
	EDMA_ERR_LNK_CTRL_TX_2	= (1 << 23),	/* transient: caught SYNC */
	EDMA_ERR_LNK_CTRL_TX_3	= (1 << 24),	/* transient: caught DMAT */
	EDMA_ERR_LNK_CTRL_TX_4	= (1 << 25),	/* transient: FIS collision */

	EDMA_ERR_LNK_DATA_TX	= (0x1f << 26),	/* link data tx error */

	EDMA_ERR_TRANS_PROTO	= (1 << 31),	/* transport protocol error */
	EDMA_ERR_OVERRUN_5	= (1 << 5),
	EDMA_ERR_UNDERRUN_5	= (1 << 6),

	EDMA_ERR_IRQ_TRANSIENT  = EDMA_ERR_LNK_CTRL_RX_0 |
				  EDMA_ERR_LNK_CTRL_RX_1 |
				  EDMA_ERR_LNK_CTRL_RX_3 |
				  EDMA_ERR_LNK_CTRL_TX,

	EDMA_EH_FREEZE		= EDMA_ERR_D_PAR |
				  EDMA_ERR_PRD_PAR |
				  EDMA_ERR_DEV_DCON |
@@ -1716,18 +1735,19 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
	struct ata_host *host = dev_instance;
	unsigned int hc, handled = 0, n_hcs;
	void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
	u32 irq_stat;
	u32 irq_stat, irq_mask;

	spin_lock(&host->lock);
	irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS);
	irq_mask = readl(mmio + HC_MAIN_IRQ_MASK_OFS);

	/* check the cases where we either have nothing pending or have read
	 * a bogus register value which can indicate HW removal or PCI fault
	 */
	if (!irq_stat || (0xffffffffU == irq_stat))
		return IRQ_NONE;
	if (!(irq_stat & irq_mask) || (0xffffffffU == irq_stat))
		goto out_unlock;

	n_hcs = mv_get_hc_count(host->ports[0]->flags);
	spin_lock(&host->lock);

	if (unlikely(irq_stat & PCI_ERR)) {
		mv_pci_error(host, mmio);
@@ -2428,8 +2448,8 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
	writelfl(readl(port_mmio + serr_ofs), port_mmio + serr_ofs);
	writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);

	/* unmask all EDMA error interrupts */
	writelfl(~0, port_mmio + EDMA_ERR_IRQ_MASK_OFS);
	/* unmask all non-transient EDMA error interrupts */
	writelfl(~EDMA_ERR_IRQ_TRANSIENT, port_mmio + EDMA_ERR_IRQ_MASK_OFS);

	VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n",
		readl(port_mmio + EDMA_CFG_OFS),