Search Linux Wireless

[PATCH] b43: Remove unnecessary MMIO in interrupt hotpath

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This removes unnecessary MMIO accesses in the interrupt hotpath.

Signed-off-by: Michael Buesch <mb@xxxxxxxxx>

---

John, please queue for the next feature round.

Index: compat-wireless-2009-03-31/drivers/net/wireless/b43/b43.h
===================================================================
--- compat-wireless-2009-03-31.orig/drivers/net/wireless/b43/b43.h	2009-04-08 20:27:37.000000000 +0200
+++ compat-wireless-2009-03-31/drivers/net/wireless/b43/b43.h	2009-04-08 20:28:14.000000000 +0200
@@ -778,8 +778,8 @@ struct b43_wldev {
 	/* Reason code of the last interrupt. */
 	u32 irq_reason;
 	u32 dma_reason[6];
-	/* saved irq enable/disable state bitfield. */
-	u32 irq_savedstate;
+	/* The currently active generic-interrupt mask. */
+	u32 irq_mask;
 	/* Link Quality calculation context. */
 	struct b43_noise_calculation noisecalc;
 	/* if > 0 MAC is suspended. if == 0 MAC is enabled. */
Index: compat-wireless-2009-03-31/drivers/net/wireless/b43/main.c
===================================================================
--- compat-wireless-2009-03-31.orig/drivers/net/wireless/b43/main.c	2009-04-08 20:22:24.000000000 +0200
+++ compat-wireless-2009-03-31/drivers/net/wireless/b43/main.c	2009-04-08 20:41:43.000000000 +0200
@@ -673,32 +673,6 @@ static void b43_short_slot_timing_disabl
 	b43_set_slot_time(dev, 20);
 }
 
-/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43_interrupt_enable(struct b43_wldev *dev, u32 mask)
-{
-	u32 old_mask;
-
-	old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
-	b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask | mask);
-
-	return old_mask;
-}
-
-/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43_interrupt_disable(struct b43_wldev *dev, u32 mask)
-{
-	u32 old_mask;
-
-	old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
-	b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
-
-	return old_mask;
-}
-
 /* Synchronize IRQ top- and bottom-half.
  * IRQs must be masked before calling this.
  * This must not be called with the irq_lock held.
@@ -1593,7 +1567,7 @@ static void handle_irq_beacon(struct b43
 	/* This is the bottom half of the asynchronous beacon update. */
 
 	/* Ignore interrupt in the future. */
-	dev->irq_savedstate &= ~B43_IRQ_BEACON;
+	dev->irq_mask &= ~B43_IRQ_BEACON;
 
 	cmd = b43_read32(dev, B43_MMIO_MACCMD);
 	beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID);
@@ -1602,7 +1576,7 @@ static void handle_irq_beacon(struct b43
 	/* Schedule interrupt manually, if busy. */
 	if (beacon0_valid && beacon1_valid) {
 		b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON);
-		dev->irq_savedstate |= B43_IRQ_BEACON;
+		dev->irq_mask |= B43_IRQ_BEACON;
 		return;
 	}
 
@@ -1641,11 +1615,9 @@ static void b43_beacon_update_trigger_wo
 	if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
 		spin_lock_irq(&wl->irq_lock);
 		/* update beacon right away or defer to irq */
-		dev->irq_savedstate = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
 		handle_irq_beacon(dev);
 		/* The handler might have updated the IRQ mask. */
-		b43_write32(dev, B43_MMIO_GEN_IRQ_MASK,
-			    dev->irq_savedstate);
+		b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
 		mmiowb();
 		spin_unlock_irq(&wl->irq_lock);
 	}
@@ -1879,7 +1851,7 @@ static void b43_interrupt_tasklet(struct
 	if (reason & B43_IRQ_TX_OK)
 		handle_irq_transmit_status(dev);
 
-	b43_interrupt_enable(dev, dev->irq_savedstate);
+	b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
 	mmiowb();
 	spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
 }
@@ -1893,7 +1865,9 @@ static void b43_interrupt_ack(struct b43
 	b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
 	b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
 	b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
+/* Unused ring
 	b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
+*/
 }
 
 /* Interrupt handler top-half */
@@ -1903,18 +1877,19 @@ static irqreturn_t b43_interrupt_handler
 	struct b43_wldev *dev = dev_id;
 	u32 reason;
 
-	if (!dev)
-		return IRQ_NONE;
+	B43_WARN_ON(!dev);
 
 	spin_lock(&dev->wl->irq_lock);
 
-	if (b43_status(dev) < B43_STAT_STARTED)
+	if (unlikely(b43_status(dev) < B43_STAT_STARTED)) {
+		/* This can only happen on shared IRQ lines. */
 		goto out;
+	}
 	reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
 	if (reason == 0xffffffff)	/* shared IRQ */
 		goto out;
 	ret = IRQ_HANDLED;
-	reason &= b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
+	reason &= dev->irq_mask;
 	if (!reason)
 		goto out;
 
@@ -1928,16 +1903,18 @@ static irqreturn_t b43_interrupt_handler
 	    & 0x0001DC00;
 	dev->dma_reason[4] = b43_read32(dev, B43_MMIO_DMA4_REASON)
 	    & 0x0000DC00;
+/* Unused ring
 	dev->dma_reason[5] = b43_read32(dev, B43_MMIO_DMA5_REASON)
 	    & 0x0000DC00;
+*/
 
 	b43_interrupt_ack(dev, reason);
 	/* disable all IRQs. They are enabled again in the bottom half. */
-	dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
+	b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
 	/* save the reason code and call our bottom half. */
 	dev->irq_reason = reason;
 	tasklet_schedule(&dev->isr_tasklet);
-      out:
+out:
 	mmiowb();
 	spin_unlock(&dev->wl->irq_lock);
 
@@ -3799,7 +3776,7 @@ static void b43_wireless_core_stop(struc
 	 * setting the status to INITIALIZED, as the interrupt handler
 	 * won't care about IRQs then. */
 	spin_lock_irqsave(&wl->irq_lock, flags);
-	dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
+	b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
 	b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);	/* flush */
 	spin_unlock_irqrestore(&wl->irq_lock, flags);
 	b43_synchronize_irq(dev);
@@ -3840,7 +3817,7 @@ static int b43_wireless_core_start(struc
 
 	/* Start data flow (TX/RX). */
 	b43_mac_enable(dev);
-	b43_interrupt_enable(dev, dev->irq_savedstate);
+	b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
 
 	/* Start maintainance work */
 	b43_periodic_tasks_setup(dev);
@@ -3998,9 +3975,9 @@ static void setup_struct_wldev_for_init(
 	/* IRQ related flags */
 	dev->irq_reason = 0;
 	memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
-	dev->irq_savedstate = B43_IRQ_MASKTEMPLATE;
+	dev->irq_mask = B43_IRQ_MASKTEMPLATE;
 	if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
-		dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR;
+		dev->irq_mask &= ~B43_IRQ_PHY_TXERR;
 
 	dev->mac_suspended = 1;
 

-- 
Greetings, Michael.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux