aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2009-04-08 15:26:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-04-22 16:54:45 -0400
commit137907287789607f2a2586ad625e7b8c646b3425 (patch)
tree8786619967253e58b84645e20b5f2a276fe569c1 /drivers
parenta2caba6b5fc4e046edfefb1db82f52b939b526a5 (diff)
b43: Remove unnecessary MMIO in interrupt hotpath
This removes unnecessary MMIO accesses in the interrupt hotpath. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/b43/b43.h4
-rw-r--r--drivers/net/wireless/b43/main.c61
2 files changed, 21 insertions, 44 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index cc1db7e5c664..4e8ad841c3c5 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -778,8 +778,8 @@ struct b43_wldev {
778 /* Reason code of the last interrupt. */ 778 /* Reason code of the last interrupt. */
779 u32 irq_reason; 779 u32 irq_reason;
780 u32 dma_reason[6]; 780 u32 dma_reason[6];
781 /* saved irq enable/disable state bitfield. */ 781 /* The currently active generic-interrupt mask. */
782 u32 irq_savedstate; 782 u32 irq_mask;
783 /* Link Quality calculation context. */ 783 /* Link Quality calculation context. */
784 struct b43_noise_calculation noisecalc; 784 struct b43_noise_calculation noisecalc;
785 /* if > 0 MAC is suspended. if == 0 MAC is enabled. */ 785 /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 09e0c60d96df..a97c6ff0f12e 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -673,32 +673,6 @@ static void b43_short_slot_timing_disable(struct b43_wldev *dev)
673 b43_set_slot_time(dev, 20); 673 b43_set_slot_time(dev, 20);
674} 674}
675 675
676/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
677 * Returns the _previously_ enabled IRQ mask.
678 */
679static inline u32 b43_interrupt_enable(struct b43_wldev *dev, u32 mask)
680{
681 u32 old_mask;
682
683 old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
684 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask | mask);
685
686 return old_mask;
687}
688
689/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
690 * Returns the _previously_ enabled IRQ mask.
691 */
692static inline u32 b43_interrupt_disable(struct b43_wldev *dev, u32 mask)
693{
694 u32 old_mask;
695
696 old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
697 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
698
699 return old_mask;
700}
701
702/* Synchronize IRQ top- and bottom-half. 676/* Synchronize IRQ top- and bottom-half.
703 * IRQs must be masked before calling this. 677 * IRQs must be masked before calling this.
704 * This must not be called with the irq_lock held. 678 * This must not be called with the irq_lock held.
@@ -1593,7 +1567,7 @@ static void handle_irq_beacon(struct b43_wldev *dev)
1593 /* This is the bottom half of the asynchronous beacon update. */ 1567 /* This is the bottom half of the asynchronous beacon update. */
1594 1568
1595 /* Ignore interrupt in the future. */ 1569 /* Ignore interrupt in the future. */
1596 dev->irq_savedstate &= ~B43_IRQ_BEACON; 1570 dev->irq_mask &= ~B43_IRQ_BEACON;
1597 1571
1598 cmd = b43_read32(dev, B43_MMIO_MACCMD); 1572 cmd = b43_read32(dev, B43_MMIO_MACCMD);
1599 beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID); 1573 beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID);
@@ -1602,7 +1576,7 @@ static void handle_irq_beacon(struct b43_wldev *dev)
1602 /* Schedule interrupt manually, if busy. */ 1576 /* Schedule interrupt manually, if busy. */
1603 if (beacon0_valid && beacon1_valid) { 1577 if (beacon0_valid && beacon1_valid) {
1604 b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON); 1578 b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON);
1605 dev->irq_savedstate |= B43_IRQ_BEACON; 1579 dev->irq_mask |= B43_IRQ_BEACON;
1606 return; 1580 return;
1607 } 1581 }
1608 1582
@@ -1641,11 +1615,9 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
1641 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { 1615 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
1642 spin_lock_irq(&wl->irq_lock); 1616 spin_lock_irq(&wl->irq_lock);
1643 /* update beacon right away or defer to irq */ 1617 /* update beacon right away or defer to irq */
1644 dev->irq_savedstate = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
1645 handle_irq_beacon(dev); 1618 handle_irq_beacon(dev);
1646 /* The handler might have updated the IRQ mask. */ 1619 /* The handler might have updated the IRQ mask. */
1647 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 1620 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
1648 dev->irq_savedstate);
1649 mmiowb(); 1621 mmiowb();
1650 spin_unlock_irq(&wl->irq_lock); 1622 spin_unlock_irq(&wl->irq_lock);
1651 } 1623 }
@@ -1879,7 +1851,7 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
1879 if (reason & B43_IRQ_TX_OK) 1851 if (reason & B43_IRQ_TX_OK)
1880 handle_irq_transmit_status(dev); 1852 handle_irq_transmit_status(dev);
1881 1853
1882 b43_interrupt_enable(dev, dev->irq_savedstate); 1854 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
1883 mmiowb(); 1855 mmiowb();
1884 spin_unlock_irqrestore(&dev->wl->irq_lock, flags); 1856 spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
1885} 1857}
@@ -1893,7 +1865,9 @@ static void b43_interrupt_ack(struct b43_wldev *dev, u32 reason)
1893 b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]); 1865 b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
1894 b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]); 1866 b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
1895 b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]); 1867 b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
1868/* Unused ring
1896 b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]); 1869 b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
1870*/
1897} 1871}
1898 1872
1899/* Interrupt handler top-half */ 1873/* Interrupt handler top-half */
@@ -1903,18 +1877,19 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1903 struct b43_wldev *dev = dev_id; 1877 struct b43_wldev *dev = dev_id;
1904 u32 reason; 1878 u32 reason;
1905 1879
1906 if (!dev) 1880 B43_WARN_ON(!dev);
1907 return IRQ_NONE;
1908 1881
1909 spin_lock(&dev->wl->irq_lock); 1882 spin_lock(&dev->wl->irq_lock);
1910 1883
1911 if (b43_status(dev) < B43_STAT_STARTED) 1884 if (unlikely(b43_status(dev) < B43_STAT_STARTED)) {
1885 /* This can only happen on shared IRQ lines. */
1912 goto out; 1886 goto out;
1887 }
1913 reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON); 1888 reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
1914 if (reason == 0xffffffff) /* shared IRQ */ 1889 if (reason == 0xffffffff) /* shared IRQ */
1915 goto out; 1890 goto out;
1916 ret = IRQ_HANDLED; 1891 ret = IRQ_HANDLED;
1917 reason &= b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); 1892 reason &= dev->irq_mask;
1918 if (!reason) 1893 if (!reason)
1919 goto out; 1894 goto out;
1920 1895
@@ -1928,16 +1903,18 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1928 & 0x0001DC00; 1903 & 0x0001DC00;
1929 dev->dma_reason[4] = b43_read32(dev, B43_MMIO_DMA4_REASON) 1904 dev->dma_reason[4] = b43_read32(dev, B43_MMIO_DMA4_REASON)
1930 & 0x0000DC00; 1905 & 0x0000DC00;
1906/* Unused ring
1931 dev->dma_reason[5] = b43_read32(dev, B43_MMIO_DMA5_REASON) 1907 dev->dma_reason[5] = b43_read32(dev, B43_MMIO_DMA5_REASON)
1932 & 0x0000DC00; 1908 & 0x0000DC00;
1909*/
1933 1910
1934 b43_interrupt_ack(dev, reason); 1911 b43_interrupt_ack(dev, reason);
1935 /* disable all IRQs. They are enabled again in the bottom half. */ 1912 /* disable all IRQs. They are enabled again in the bottom half. */
1936 dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL); 1913 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
1937 /* save the reason code and call our bottom half. */ 1914 /* save the reason code and call our bottom half. */
1938 dev->irq_reason = reason; 1915 dev->irq_reason = reason;
1939 tasklet_schedule(&dev->isr_tasklet); 1916 tasklet_schedule(&dev->isr_tasklet);
1940 out: 1917out:
1941 mmiowb(); 1918 mmiowb();
1942 spin_unlock(&dev->wl->irq_lock); 1919 spin_unlock(&dev->wl->irq_lock);
1943 1920
@@ -3799,7 +3776,7 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
3799 * setting the status to INITIALIZED, as the interrupt handler 3776 * setting the status to INITIALIZED, as the interrupt handler
3800 * won't care about IRQs then. */ 3777 * won't care about IRQs then. */
3801 spin_lock_irqsave(&wl->irq_lock, flags); 3778 spin_lock_irqsave(&wl->irq_lock, flags);
3802 dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL); 3779 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
3803 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */ 3780 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
3804 spin_unlock_irqrestore(&wl->irq_lock, flags); 3781 spin_unlock_irqrestore(&wl->irq_lock, flags);
3805 b43_synchronize_irq(dev); 3782 b43_synchronize_irq(dev);
@@ -3840,7 +3817,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
3840 3817
3841 /* Start data flow (TX/RX). */ 3818 /* Start data flow (TX/RX). */
3842 b43_mac_enable(dev); 3819 b43_mac_enable(dev);
3843 b43_interrupt_enable(dev, dev->irq_savedstate); 3820 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
3844 3821
3845 /* Start maintainance work */ 3822 /* Start maintainance work */
3846 b43_periodic_tasks_setup(dev); 3823 b43_periodic_tasks_setup(dev);
@@ -4003,9 +3980,9 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)
4003 /* IRQ related flags */ 3980 /* IRQ related flags */
4004 dev->irq_reason = 0; 3981 dev->irq_reason = 0;
4005 memset(dev->dma_reason, 0, sizeof(dev->dma_reason)); 3982 memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
4006 dev->irq_savedstate = B43_IRQ_MASKTEMPLATE; 3983 dev->irq_mask = B43_IRQ_MASKTEMPLATE;
4007 if (b43_modparam_verbose < B43_VERBOSITY_DEBUG) 3984 if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
4008 dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR; 3985 dev->irq_mask &= ~B43_IRQ_PHY_TXERR;
4009 3986
4010 dev->mac_suspended = 1; 3987 dev->mac_suspended = 1;
4011 3988