diff --git a/drivers/net/wimax/i2400m/i2400m-sdio.h b/drivers/net/wimax/i2400m/i2400m-sdio.h
index b9c4bed3b457cf52087d3848040153ee325e108c..360d4fb195f475aff73e9880d64bc1c212c0fb9f 100644
--- a/drivers/net/wimax/i2400m/i2400m-sdio.h
+++ b/drivers/net/wimax/i2400m/i2400m-sdio.h
@@ -99,7 +99,10 @@ enum {
  *
  * @tx_workqueue: workqeueue used for data TX; we don't use the
  *     system's workqueue as that might cause deadlocks with code in
- *     the bus-generic driver.
+ *     the bus-generic driver. The read/write operation to the queue
+ *     is protected with spinlock (tx_lock in struct i2400m) to avoid
+ *     the queue being destroyed in the middle of a the queue read/write
+ *     operation.
  *
  * @debugfs_dentry: dentry for the SDIO specific debugfs files
  *
diff --git a/drivers/net/wimax/i2400m/sdio-tx.c b/drivers/net/wimax/i2400m/sdio-tx.c
index de66d068c9cbf2717a54c15254dfcfa96ffaac26..412b6a8eaef2983028360e862102c2bdd0d40237 100644
--- a/drivers/net/wimax/i2400m/sdio-tx.c
+++ b/drivers/net/wimax/i2400m/sdio-tx.c
@@ -114,13 +114,17 @@ void i2400ms_bus_tx_kick(struct i2400m *i2400m)
 {
 	struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
 	struct device *dev = &i2400ms->func->dev;
+	unsigned long flags;
 
 	d_fnstart(3, dev, "(i2400m %p) = void\n", i2400m);
 
 	/* schedule tx work, this is because tx may block, therefore
 	 * it has to run in a thread context.
 	 */
-	queue_work(i2400ms->tx_workqueue, &i2400ms->tx_worker);
+	spin_lock_irqsave(&i2400m->tx_lock, flags);
+	if (i2400ms->tx_workqueue != NULL)
+		queue_work(i2400ms->tx_workqueue, &i2400ms->tx_worker);
+	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
 
 	d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
 }
@@ -130,27 +134,40 @@ int i2400ms_tx_setup(struct i2400ms *i2400ms)
 	int result;
 	struct device *dev = &i2400ms->func->dev;
 	struct i2400m *i2400m = &i2400ms->i2400m;
+	struct workqueue_struct *tx_workqueue;
+	unsigned long flags;
 
 	d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);
 
 	INIT_WORK(&i2400ms->tx_worker, i2400ms_tx_submit);
 	snprintf(i2400ms->tx_wq_name, sizeof(i2400ms->tx_wq_name),
 		 "%s-tx", i2400m->wimax_dev.name);
-	i2400ms->tx_workqueue =
+	tx_workqueue =
 		create_singlethread_workqueue(i2400ms->tx_wq_name);
-	if (NULL == i2400ms->tx_workqueue) {
+	if (tx_workqueue == NULL) {
 		dev_err(dev, "TX: failed to create workqueue\n");
 		result = -ENOMEM;
 	} else
 		result = 0;
+	spin_lock_irqsave(&i2400m->tx_lock, flags);
+	i2400ms->tx_workqueue = tx_workqueue;
+	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
 	d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result);
 	return result;
 }
 
 void i2400ms_tx_release(struct i2400ms *i2400ms)
 {
-	if (i2400ms->tx_workqueue) {
-		destroy_workqueue(i2400ms->tx_workqueue);
-		i2400ms->tx_workqueue = NULL;
-	}
+	struct i2400m *i2400m = &i2400ms->i2400m;
+	struct workqueue_struct *tx_workqueue;
+	unsigned long flags;
+
+	tx_workqueue = i2400ms->tx_workqueue;
+
+	spin_lock_irqsave(&i2400m->tx_lock, flags);
+	i2400ms->tx_workqueue = NULL;
+	spin_unlock_irqrestore(&i2400m->tx_lock, flags);
+
+	if (tx_workqueue)
+		destroy_workqueue(tx_workqueue);
 }