aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Buesch <mbuesch@freenet.de>2006-03-19 15:43:40 -0500
committerJohn W. Linville <linville@tuxdriver.com>2006-03-27 11:19:42 -0500
commit0ac59daee5f7fbaab25784a643edede669b5419e (patch)
tree7e415dbd5dc7aee5eab28f18de1388e2e77f0f9e /drivers
parent6ab5b8e670c4bb7ac0035ec3c6d6a161fae12009 (diff)
[PATCH] bcm43xx: some IRQ handler cleanups.
Signed-off-by: Michael Buesch <mbuesch@freenet.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c65
1 files changed, 30 insertions, 35 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index a85176325e92..12c93d274ae5 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -1785,10 +1785,6 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1785 bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS); 1785 bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS);
1786 } 1786 }
1787 1787
1788 /* We get spurious IRQs, althought they are masked.
1789 * Assume they are void and ignore them.
1790 */
1791 bcmirq_handled(~(bcm->irq_savedstate));
1792 /* IRQ_PIO_WORKAROUND is handled in the top-half. */ 1788 /* IRQ_PIO_WORKAROUND is handled in the top-half. */
1793 bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND); 1789 bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND);
1794#ifdef CONFIG_BCM43XX_DEBUG 1790#ifdef CONFIG_BCM43XX_DEBUG
@@ -1809,41 +1805,31 @@ static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1809 bcm43xx_unlock_mmio(bcm, flags); 1805 bcm43xx_unlock_mmio(bcm, flags);
1810} 1806}
1811 1807
1812static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, 1808static void pio_irq_workaround(struct bcm43xx_private *bcm,
1813 u32 reason, u32 mask) 1809 u16 base, int queueidx)
1814{ 1810{
1815 bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON) 1811 u16 rxctl;
1816 & 0x0001dc00; 1812
1817 bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON) 1813 rxctl = bcm43xx_read16(bcm, base + BCM43xx_PIO_RXCTL);
1818 & 0x0000dc00; 1814 if (rxctl & BCM43xx_PIO_RXCTL_DATAAVAILABLE)
1819 bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON) 1815 bcm->dma_reason[queueidx] |= BCM43xx_DMAIRQ_RX_DONE;
1820 & 0x0000dc00; 1816 else
1821 bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON) 1817 bcm->dma_reason[queueidx] &= ~BCM43xx_DMAIRQ_RX_DONE;
1822 & 0x0001dc00; 1818}
1823 1819
1820static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason)
1821{
1824 if (bcm43xx_using_pio(bcm) && 1822 if (bcm43xx_using_pio(bcm) &&
1825 (bcm->current_core->rev < 3) && 1823 (bcm->current_core->rev < 3) &&
1826 (!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) { 1824 (!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) {
1827 /* Apply a PIO specific workaround to the dma_reasons */ 1825 /* Apply a PIO specific workaround to the dma_reasons */
1828 1826 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO1_BASE, 0);
1829#define apply_pio_workaround(BASE, QNUM) \ 1827 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO2_BASE, 1);
1830 do { \ 1828 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO3_BASE, 2);
1831 if (bcm43xx_read16(bcm, BASE + BCM43xx_PIO_RXCTL) & BCM43xx_PIO_RXCTL_DATAAVAILABLE) \ 1829 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO4_BASE, 3);
1832 bcm->dma_reason[QNUM] |= 0x00010000; \
1833 else \
1834 bcm->dma_reason[QNUM] &= ~0x00010000; \
1835 } while (0)
1836
1837 apply_pio_workaround(BCM43xx_MMIO_PIO1_BASE, 0);
1838 apply_pio_workaround(BCM43xx_MMIO_PIO2_BASE, 1);
1839 apply_pio_workaround(BCM43xx_MMIO_PIO3_BASE, 2);
1840 apply_pio_workaround(BCM43xx_MMIO_PIO4_BASE, 3);
1841
1842#undef apply_pio_workaround
1843 } 1830 }
1844 1831
1845 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 1832 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
1846 reason & mask);
1847 1833
1848 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON, 1834 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
1849 bcm->dma_reason[0]); 1835 bcm->dma_reason[0]);
@@ -1860,7 +1846,7 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
1860{ 1846{
1861 irqreturn_t ret = IRQ_HANDLED; 1847 irqreturn_t ret = IRQ_HANDLED;
1862 struct bcm43xx_private *bcm = dev_id; 1848 struct bcm43xx_private *bcm = dev_id;
1863 u32 reason, mask; 1849 u32 reason;
1864 1850
1865 if (!bcm) 1851 if (!bcm)
1866 return IRQ_NONE; 1852 return IRQ_NONE;
@@ -1873,11 +1859,20 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re
1873 ret = IRQ_NONE; 1859 ret = IRQ_NONE;
1874 goto out; 1860 goto out;
1875 } 1861 }
1876 mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); 1862 reason &= bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
1877 if (!(reason & mask)) 1863 if (!reason)
1878 goto out; 1864 goto out;
1879 1865
1880 bcm43xx_interrupt_ack(bcm, reason, mask); 1866 bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
1867 & 0x0001dc00;
1868 bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
1869 & 0x0000dc00;
1870 bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
1871 & 0x0000dc00;
1872 bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
1873 & 0x0001dc00;
1874
1875 bcm43xx_interrupt_ack(bcm, reason);
1881 1876
1882 /* Only accept IRQs, if we are initialized properly. 1877 /* Only accept IRQs, if we are initialized properly.
1883 * This avoids an RX race while initializing. 1878 * This avoids an RX race while initializing.