sata_mv.c (fcfb1f77cea81f74d865b4d33f2e452ffa1973e8) sata_mv.c (a3718c1f230240361ed92d3e53342df0ff7efa8c)
1/*
2 * sata_mv.c - Marvell SATA support
3 *
4 * Copyright 2008: Marvell Corporation, all rights reserved.
5 * Copyright 2005: EMC Corporation, all rights reserved.
6 * Copyright 2005 Red Hat, Inc. All rights reserved.
7 *
8 * Please ALWAYS copy linux-ide@vger.kernel.org on emails.

--- 1679 unchanged lines hidden (view full) ---

1688 * success ints are reported in the HC interrupt status reg, the
1689 * port error ints are reported in the higher level main
1690 * interrupt status register and thus are passed in via the
1691 * 'relevant' argument.
1692 *
1693 * LOCKING:
1694 * Inherited from caller.
1695 */
1/*
2 * sata_mv.c - Marvell SATA support
3 *
4 * Copyright 2008: Marvell Corporation, all rights reserved.
5 * Copyright 2005: EMC Corporation, all rights reserved.
6 * Copyright 2005 Red Hat, Inc. All rights reserved.
7 *
8 * Please ALWAYS copy linux-ide@vger.kernel.org on emails.

--- 1679 unchanged lines hidden (view full) ---

1688 * success ints are reported in the HC interrupt status reg, the
1689 * port error ints are reported in the higher level main
1690 * interrupt status register and thus are passed in via the
1691 * 'relevant' argument.
1692 *
1693 * LOCKING:
1694 * Inherited from caller.
1695 */
1696static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
1696static int mv_host_intr(struct ata_host *host, u32 main_cause)
1697{
1698 struct mv_host_priv *hpriv = host->private_data;
1697{
1698 struct mv_host_priv *hpriv = host->private_data;
1699 void __iomem *mmio = hpriv->base;
1700 void __iomem *hc_mmio = mv_hc_base(mmio, hc);
1701 u32 hc_irq_cause;
1702 int port, port0, last_port;
1699 void __iomem *mmio = hpriv->base, *hc_mmio = NULL;
1700 u32 hc_irq_cause = 0;
1701 unsigned int handled = 0, port;
1703
1702
1704 if (hc == 0)
1705 port0 = 0;
1706 else
1707 port0 = MV_PORTS_PER_HC;
1708
1709 if (HAS_PCI(host))
1710 last_port = port0 + MV_PORTS_PER_HC;
1711 else
1712 last_port = port0 + hpriv->n_ports;
1713 /* we'll need the HC success int register in most cases */
1714 hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
1715 if (!hc_irq_cause)
1716 return;
1717
1718 writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
1719
1720 VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n",
1721 hc, relevant, hc_irq_cause);
1722
1723 for (port = port0; port < last_port; port++) {
1703 for (port = 0; port < hpriv->n_ports; port++) {
1724 struct ata_port *ap = host->ports[port];
1725 struct mv_port_priv *pp;
1704 struct ata_port *ap = host->ports[port];
1705 struct mv_port_priv *pp;
1726 int have_err_bits, hardport, shift;
1727
1728 if ((!ap) || (ap->flags & ATA_FLAG_DISABLED))
1706 unsigned int shift, hardport, port_cause;
1707 /*
1708 * When we move to the second hc, flag our cached
1709 * copies of hc_mmio (and hc_irq_cause) as invalid again.
1710 */
1711 if (port == MV_PORTS_PER_HC)
1712 hc_mmio = NULL;
1713 /*
1714 * Do nothing if port is not interrupting or is disabled:
1715 */
1716 MV_PORT_TO_SHIFT_AND_HARDPORT(port, shift, hardport);
1717 port_cause = (main_cause >> shift) & (DONE_IRQ | ERR_IRQ);
1718 if (!port_cause || !ap || (ap->flags & ATA_FLAG_DISABLED))
1729 continue;
1719 continue;
1720 /*
1721 * Each hc within the host has its own hc_irq_cause register.
1722 * We defer reading it until we know we need it, right now:
1723 *
1724 * FIXME later: we don't really need to read this register
1725 * (some logic changes required below if we go that way),
1726 * because it doesn't tell us anything new. But we do need
1727 * to write to it, outside the top of this loop,
1728 * to reset the interrupt triggers for next time.
1729 */
1730 if (!hc_mmio) {
1731 hc_mmio = mv_hc_base_from_port(mmio, port);
1732 hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
1733 writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
1734 handled = 1;
1735 }
1730
1736
1731 pp = ap->private_data;
1732
1733 shift = port << 1; /* (port * 2) */
1734 if (port >= MV_PORTS_PER_HC)
1735 shift++; /* skip bit 8 in the HC Main IRQ reg */
1736
1737 have_err_bits = ((ERR_IRQ << shift) & relevant);
1738
1739 if (unlikely(have_err_bits)) {
1737 if (unlikely(port_cause & ERR_IRQ)) {
1740 struct ata_queued_cmd *qc;
1741
1742 qc = ata_qc_from_tag(ap, ap->link.active_tag);
1743 if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
1744 continue;
1745
1746 mv_err_intr(ap, qc);
1747 continue;
1748 }
1749
1738 struct ata_queued_cmd *qc;
1739
1740 qc = ata_qc_from_tag(ap, ap->link.active_tag);
1741 if (qc && (qc->tf.flags & ATA_TFLAG_POLLING))
1742 continue;
1743
1744 mv_err_intr(ap, qc);
1745 continue;
1746 }
1747
1750 hardport = mv_hardport_from_port(port); /* range 0..3 */
1751
1748 pp = ap->private_data;
1752 if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
1753 if ((DMA_IRQ << hardport) & hc_irq_cause)
1754 mv_process_crpb_entries(ap, pp);
1755 } else {
1756 if ((DEV_IRQ << hardport) & hc_irq_cause)
1757 mv_intr_pio(ap);
1758 }
1759 }
1749 if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
1750 if ((DMA_IRQ << hardport) & hc_irq_cause)
1751 mv_process_crpb_entries(ap, pp);
1752 } else {
1753 if ((DEV_IRQ << hardport) & hc_irq_cause)
1754 mv_intr_pio(ap);
1755 }
1756 }
1760 VPRINTK("EXIT\n");
1757 return handled;
1761}
1762
1758}
1759
1763static void mv_pci_error(struct ata_host *host, void __iomem *mmio)
1760static int mv_pci_error(struct ata_host *host, void __iomem *mmio)
1764{
1765 struct mv_host_priv *hpriv = host->private_data;
1766 struct ata_port *ap;
1767 struct ata_queued_cmd *qc;
1768 struct ata_eh_info *ehi;
1769 unsigned int i, err_mask, printed = 0;
1770 u32 err_cause;
1771

--- 21 unchanged lines hidden (view full) ---

1793 if (qc)
1794 qc->err_mask |= err_mask;
1795 else
1796 ehi->err_mask |= err_mask;
1797
1798 ata_port_freeze(ap);
1799 }
1800 }
1761{
1762 struct mv_host_priv *hpriv = host->private_data;
1763 struct ata_port *ap;
1764 struct ata_queued_cmd *qc;
1765 struct ata_eh_info *ehi;
1766 unsigned int i, err_mask, printed = 0;
1767 u32 err_cause;
1768

--- 21 unchanged lines hidden (view full) ---

1790 if (qc)
1791 qc->err_mask |= err_mask;
1792 else
1793 ehi->err_mask |= err_mask;
1794
1795 ata_port_freeze(ap);
1796 }
1797 }
1798 return 1; /* handled */
1801}
1802
1803/**
1804 * mv_interrupt - Main interrupt event handler
1805 * @irq: unused
1806 * @dev_instance: private data; in this case the host structure
1807 *
1808 * Read the read only register to determine if any host

--- 4 unchanged lines hidden (view full) ---

1813 * LOCKING:
1814 * This routine holds the host lock while processing pending
1815 * interrupts.
1816 */
1817static irqreturn_t mv_interrupt(int irq, void *dev_instance)
1818{
1819 struct ata_host *host = dev_instance;
1820 struct mv_host_priv *hpriv = host->private_data;
1799}
1800
1801/**
1802 * mv_interrupt - Main interrupt event handler
1803 * @irq: unused
1804 * @dev_instance: private data; in this case the host structure
1805 *
1806 * Read the read only register to determine if any host

--- 4 unchanged lines hidden (view full) ---

1811 * LOCKING:
1812 * This routine holds the host lock while processing pending
1813 * interrupts.
1814 */
1815static irqreturn_t mv_interrupt(int irq, void *dev_instance)
1816{
1817 struct ata_host *host = dev_instance;
1818 struct mv_host_priv *hpriv = host->private_data;
1821 unsigned int hc, handled = 0, n_hcs;
1822 void __iomem *mmio = hpriv->base;
1819 unsigned int handled = 0;
1823 u32 main_cause, main_mask;
1824
1825 spin_lock(&host->lock);
1826 main_cause = readl(hpriv->main_cause_reg_addr);
1827 main_mask = readl(hpriv->main_mask_reg_addr);
1828 /*
1829 * Deal with cases where we either have nothing pending, or have read
1830 * a bogus register value which can indicate HW removal or PCI fault.
1831 */
1820 u32 main_cause, main_mask;
1821
1822 spin_lock(&host->lock);
1823 main_cause = readl(hpriv->main_cause_reg_addr);
1824 main_mask = readl(hpriv->main_mask_reg_addr);
1825 /*
1826 * Deal with cases where we either have nothing pending, or have read
1827 * a bogus register value which can indicate HW removal or PCI fault.
1828 */
1832 if (!(main_cause & main_mask) || (main_cause == 0xffffffffU))
1833 goto out_unlock;
1834
1835 n_hcs = mv_get_hc_count(host->ports[0]->flags);
1836
1837 if (unlikely((main_cause & PCI_ERR) && HAS_PCI(host))) {
1838 mv_pci_error(host, mmio);
1839 handled = 1;
1840 goto out_unlock; /* skip all other HC irq handling */
1829 if ((main_cause & main_mask) && (main_cause != 0xffffffffU)) {
1830 if (unlikely((main_cause & PCI_ERR) && HAS_PCI(host)))
1831 handled = mv_pci_error(host, hpriv->base);
1832 else
1833 handled = mv_host_intr(host, main_cause);
1841 }
1834 }
1842
1843 for (hc = 0; hc < n_hcs; hc++) {
1844 u32 relevant = main_cause & (HC0_IRQ_PEND << (hc * HC_SHIFT));
1845 if (relevant) {
1846 mv_host_intr(host, relevant, hc);
1847 handled = 1;
1848 }
1849 }
1850
1851out_unlock:
1852 spin_unlock(&host->lock);
1853 return IRQ_RETVAL(handled);
1854}
1855
1856static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
1857{
1858 unsigned int ofs;
1859

--- 1258 unchanged lines hidden ---
1835 spin_unlock(&host->lock);
1836 return IRQ_RETVAL(handled);
1837}
1838
1839static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
1840{
1841 unsigned int ofs;
1842

--- 1258 unchanged lines hidden ---