b43: Use a threaded IRQ handler

Use a threaded IRQ handler to allow locking the mutex and
sleeping while executing an interrupt.
This removes usage of the irq_lock spinlock, but introduces
a new hardirq_lock, which is _only_ used for the PCI/SSB lowlevel
hard-irq handler. Sleeping busses (SDIO) will use mutex instead.

Signed-off-by: Michael Buesch <mb@bu3sch.de>
Tested-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 45e3d6a..bf23a3a 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -46,8 +46,6 @@
 	struct file_operations fops;
 	/* Offset of struct b43_dfs_file in struct b43_dfsentry */
 	size_t file_struct_offset;
-	/* Take wl->irq_lock before calling read/write? */
-	bool take_irqlock;
 };
 
 static inline
@@ -372,14 +370,12 @@
 {
 	struct b43_txstatus_log *log = &dev->dfsentry->txstatlog;
 	ssize_t count = 0;
-	unsigned long flags;
 	int i, idx;
 	struct b43_txstatus *stat;
 
-	spin_lock_irqsave(&log->lock, flags);
 	if (log->end < 0) {
 		fappend("Nothing transmitted, yet\n");
-		goto out_unlock;
+		goto out;
 	}
 	fappend("b43 TX status reports:\n\n"
 		"index | cookie | seq | phy_stat | frame_count | "
@@ -409,13 +405,11 @@
 			break;
 		i++;
 	}
-out_unlock:
-	spin_unlock_irqrestore(&log->lock, flags);
+out:
 
 	return count;
 }
 
-/* wl->irq_lock is locked */
 static int restart_write_file(struct b43_wldev *dev,
 			      const char *buf, size_t count)
 {
@@ -556,12 +550,7 @@
 			goto out_unlock;
 		}
 		memset(buf, 0, bufsize);
-		if (dfops->take_irqlock) {
-			spin_lock_irq(&dev->wl->irq_lock);
-			ret = dfops->read(dev, buf, bufsize);
-			spin_unlock_irq(&dev->wl->irq_lock);
-		} else
-			ret = dfops->read(dev, buf, bufsize);
+		ret = dfops->read(dev, buf, bufsize);
 		if (ret <= 0) {
 			free_pages((unsigned long)buf, buforder);
 			err = ret;
@@ -623,12 +612,7 @@
 		err = -EFAULT;
 		goto out_freepage;
 	}
-	if (dfops->take_irqlock) {
-		spin_lock_irq(&dev->wl->irq_lock);
-		err = dfops->write(dev, buf, count);
-		spin_unlock_irq(&dev->wl->irq_lock);
-	} else
-		err = dfops->write(dev, buf, count);
+	err = dfops->write(dev, buf, count);
 	if (err)
 		goto out_freepage;
 
@@ -641,7 +625,7 @@
 }
 
 
-#define B43_DEBUGFS_FOPS(name, _read, _write, _take_irqlock)	\
+#define B43_DEBUGFS_FOPS(name, _read, _write)			\
 	static struct b43_debugfs_fops fops_##name = {		\
 		.read	= _read,				\
 		.write	= _write,				\
@@ -652,20 +636,19 @@
 		},						\
 		.file_struct_offset = offsetof(struct b43_dfsentry, \
 					       file_##name),	\
-		.take_irqlock	= _take_irqlock,		\
 	}
 
-B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1);
-B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1);
-B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1);
-B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1);
-B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
-B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
-B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
-B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
-B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
-B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
-B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0);
+B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file);
+B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file);
+B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file);
+B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file);
+B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file);
+B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file);
+B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file);
+B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file);
+B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL);
+B43_DEBUGFS_FOPS(restart, NULL, restart_write_file);
+B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL);
 
 
 bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
@@ -738,7 +721,6 @@
 		return;
 	}
 	log->end = -1;
-	spin_lock_init(&log->lock);
 
 	dev->dfsentry = e;
 
@@ -822,7 +804,6 @@
 	kfree(e);
 }
 
-/* Called with IRQs disabled. */
 void b43_debugfs_log_txstat(struct b43_wldev *dev,
 			    const struct b43_txstatus *status)
 {
@@ -834,14 +815,12 @@
 	if (!e)
 		return;
 	log = &e->txstatlog;
-	spin_lock(&log->lock); /* IRQs are already disabled. */
 	i = log->end + 1;
 	if (i == B43_NR_LOGGED_TXSTATUS)
 		i = 0;
 	log->end = i;
 	cur = &(log->log[i]);
 	memcpy(cur, status, sizeof(*cur));
-	spin_unlock(&log->lock);
 }
 
 void b43_debugfs_init(void)