Commit feea1db26e5babbedf1f4f36223e21b2f2d6f499

Authored by Maciej W. Rozycki
Committed by Jeff Garzik
1 parent 16b110c3fd

[PATCH] defxx: Use irqreturn_t for the interrupt handler

This is a fix for the interrupt handler in the defxx driver to use
irqreturn_t.  Beside the obvious fix of returning a proper status at all,
it actually checks board registers as appropriate for determining if an
interrupt has been recorded in the bus-specific interface logic.

The patch also includes an obvious one-line fix for SET_NETDEV_DEV needed
for the EISA variation, for which I've decided there is no point in sending
separately.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Cc: Jeff Garzik <jgarzik@pobox.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>

Showing 1 changed file with 51 additions and 37 deletions Side-by-side Diff

... ... @@ -191,6 +191,7 @@
191 191 * Feb 2001 davej PCI enable cleanups.
192 192 * 04 Aug 2003 macro Converted to the DMA API.
193 193 * 14 Aug 2004 macro Fix device names reported.
  194 + * 14 Jun 2005 macro Use irqreturn_t.
194 195 */
195 196  
196 197 /* Include files */
... ... @@ -217,8 +218,8 @@
217 218  
218 219 /* Version information string should be updated prior to each new release! */
219 220 #define DRV_NAME "defxx"
220   -#define DRV_VERSION "v1.07"
221   -#define DRV_RELDATE "2004/08/14"
  221 +#define DRV_VERSION "v1.08"
  222 +#define DRV_RELDATE "2005/06/14"
222 223  
223 224 static char version[] __devinitdata =
224 225 DRV_NAME ": " DRV_VERSION " " DRV_RELDATE
... ... @@ -247,7 +248,8 @@
247 248 static void dfx_int_pr_halt_id(DFX_board_t *bp);
248 249 static void dfx_int_type_0_process(DFX_board_t *bp);
249 250 static void dfx_int_common(struct net_device *dev);
250   -static void dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs);
  251 +static irqreturn_t dfx_interrupt(int irq, void *dev_id,
  252 + struct pt_regs *regs);
251 253  
252 254 static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev);
253 255 static void dfx_ctl_set_multicast_list(struct net_device *dev);
... ... @@ -437,7 +439,8 @@
437 439 }
438 440  
439 441 SET_MODULE_OWNER(dev);
440   - SET_NETDEV_DEV(dev, &pdev->dev);
  442 + if (pdev != NULL)
  443 + SET_NETDEV_DEV(dev, &pdev->dev);
441 444  
442 445 bp = dev->priv;
443 446  
... ... @@ -1225,7 +1228,7 @@
1225 1228  
1226 1229 /* Register IRQ - support shared interrupts by passing device ptr */
1227 1230  
1228   - ret = request_irq(dev->irq, (void *)dfx_interrupt, SA_SHIRQ, dev->name, dev);
  1231 + ret = request_irq(dev->irq, dfx_interrupt, SA_SHIRQ, dev->name, dev);
1229 1232 if (ret) {
1230 1233 printk(KERN_ERR "%s: Requested IRQ %d is busy\n", dev->name, dev->irq);
1231 1234 return ret;
1232 1235  
1233 1236  
... ... @@ -1680,13 +1683,13 @@
1680 1683 * =================
1681 1684 * = dfx_interrupt =
1682 1685 * =================
1683   - *
  1686 + *
1684 1687 * Overview:
1685 1688 * Interrupt processing routine
1686   - *
  1689 + *
1687 1690 * Returns:
1688   - * None
1689   - *
  1691 + * Whether a valid interrupt was seen.
  1692 + *
1690 1693 * Arguments:
1691 1694 * irq - interrupt vector
1692 1695 * dev_id - pointer to device information
... ... @@ -1699,7 +1702,8 @@
1699 1702 * structure context.
1700 1703 *
1701 1704 * Return Codes:
1702   - * None
  1705 + * IRQ_HANDLED - an IRQ was handled.
  1706 + * IRQ_NONE - no IRQ was handled.
1703 1707 *
1704 1708 * Assumptions:
1705 1709 * The interrupt acknowledgement at the hardware level (eg. ACKing the PIC
1706 1710  
1707 1711  
1708 1712  
1709 1713  
1710 1714  
1711 1715  
1712 1716  
1713 1717  
1714 1718  
1715 1719  
1716 1720  
1717 1721  
1718 1722  
1719 1723  
... ... @@ -1712,59 +1716,69 @@
1712 1716 * Interrupts are disabled, then reenabled at the adapter.
1713 1717 */
1714 1718  
1715   -static void dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1716   - {
  1719 +static irqreturn_t dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  1720 +{
1717 1721 struct net_device *dev = dev_id;
1718 1722 DFX_board_t *bp; /* private board structure pointer */
1719   - u8 tmp; /* used for disabling/enabling ints */
1720 1723  
1721 1724 /* Get board pointer only if device structure is valid */
1722 1725  
1723 1726 bp = dev->priv;
1724 1727  
1725   - spin_lock(&bp->lock);
1726   -
1727 1728 /* See if we're already servicing an interrupt */
1728 1729  
1729 1730 /* Service adapter interrupts */
1730 1731  
1731   - if (bp->bus_type == DFX_BUS_TYPE_PCI)
1732   - {
1733   - /* Disable PDQ-PFI interrupts at PFI */
  1732 + if (bp->bus_type == DFX_BUS_TYPE_PCI) {
  1733 + u32 status;
1734 1734  
1735   - dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, PFI_MODE_M_DMA_ENB);
  1735 + dfx_port_read_long(bp, PFI_K_REG_STATUS, &status);
  1736 + if (!(status & PFI_STATUS_M_PDQ_INT))
  1737 + return IRQ_NONE;
1736 1738  
1737   - /* Call interrupt service routine for this adapter */
  1739 + spin_lock(&bp->lock);
1738 1740  
  1741 + /* Disable PDQ-PFI interrupts at PFI */
  1742 + dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL,
  1743 + PFI_MODE_M_DMA_ENB);
  1744 +
  1745 + /* Call interrupt service routine for this adapter */
1739 1746 dfx_int_common(dev);
1740 1747  
1741 1748 /* Clear PDQ interrupt status bit and reenable interrupts */
1742   -
1743   - dfx_port_write_long(bp, PFI_K_REG_STATUS, PFI_STATUS_M_PDQ_INT);
  1749 + dfx_port_write_long(bp, PFI_K_REG_STATUS,
  1750 + PFI_STATUS_M_PDQ_INT);
1744 1751 dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL,
1745   - (PFI_MODE_M_PDQ_INT_ENB + PFI_MODE_M_DMA_ENB));
1746   - }
1747   - else
1748   - {
1749   - /* Disable interrupts at the ESIC */
  1752 + (PFI_MODE_M_PDQ_INT_ENB |
  1753 + PFI_MODE_M_DMA_ENB));
1750 1754  
1751   - dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &tmp);
1752   - tmp &= ~PI_CONFIG_STAT_0_M_INT_ENB;
1753   - dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, tmp);
  1755 + spin_unlock(&bp->lock);
  1756 + } else {
  1757 + u8 status;
1754 1758  
1755   - /* Call interrupt service routine for this adapter */
  1759 + dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &status);
  1760 + if (!(status & PI_CONFIG_STAT_0_M_PEND))
  1761 + return IRQ_NONE;
1756 1762  
  1763 + spin_lock(&bp->lock);
  1764 +
  1765 + /* Disable interrupts at the ESIC */
  1766 + status &= ~PI_CONFIG_STAT_0_M_INT_ENB;
  1767 + dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, status);
  1768 +
  1769 + /* Call interrupt service routine for this adapter */
1757 1770 dfx_int_common(dev);
1758 1771  
1759 1772 /* Reenable interrupts at the ESIC */
  1773 + dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &status);
  1774 + status |= PI_CONFIG_STAT_0_M_INT_ENB;
  1775 + dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, status);
1760 1776  
1761   - dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &tmp);
1762   - tmp |= PI_CONFIG_STAT_0_M_INT_ENB;
1763   - dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, tmp);
1764   - }
1765   -
1766   - spin_unlock(&bp->lock);
  1777 + spin_unlock(&bp->lock);
1767 1778 }
  1779 +
  1780 + return IRQ_HANDLED;
  1781 +}
1768 1782  
1769 1783  
1770 1784 /*