Commit feea1db26e5babbedf1f4f36223e21b2f2d6f499
Committed by
Jeff Garzik
1 parent
16b110c3fd
Exists in
master
and in
7 other branches
[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
drivers/net/defxx.c
... | ... | @@ -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 | /* |