diff options
author | Michael Buesch <mb@bu3sch.de> | 2009-04-08 15:26:27 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-04-22 16:54:45 -0400 |
commit | 137907287789607f2a2586ad625e7b8c646b3425 (patch) | |
tree | 8786619967253e58b84645e20b5f2a276fe569c1 /drivers | |
parent | a2caba6b5fc4e046edfefb1db82f52b939b526a5 (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.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 61 |
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 | */ | ||
679 | static 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 | */ | ||
692 | static 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: | 1917 | out: |
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 | ||