summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/if_sdio.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2009-02-20 18:27:38 +0100
committerJohn W. Linville <linville@tuxdriver.com>2009-02-27 20:52:51 +0100
commit9b02f419a7dbd956b2c293e5cb1790b6b687f367 (patch)
tree63fb91f39f5fc43a64728cfe18fc89f1a77c28e5 /drivers/net/wireless/libertas/if_sdio.c
parentb43: Implement sw scan callbacks (diff)
downloadlinux-9b02f419a7dbd956b2c293e5cb1790b6b687f367.tar.xz
linux-9b02f419a7dbd956b2c293e5cb1790b6b687f367.zip
libertas: use private SDIO workqueue to avoid scheduling latency
The libertas SDIO interface scheduled the packet worker, resulting in unwanted latency for every data packet or command sent to the firmware. Fix a bug on the SDIO probe error path too. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/if_sdio.c')
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 987836865ea5..76f4c653d641 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -95,6 +95,8 @@ struct if_sdio_card {
spinlock_t lock;
struct if_sdio_packet *packets;
+
+ struct workqueue_struct *workqueue;
struct work_struct packet_worker;
};
@@ -746,7 +748,7 @@ static int if_sdio_host_to_card(struct lbs_private *priv,
spin_unlock_irqrestore(&card->lock, flags);
- schedule_work(&card->packet_worker);
+ queue_work(card->workqueue, &card->packet_worker);
ret = 0;
@@ -836,6 +838,7 @@ static int if_sdio_probe(struct sdio_func *func,
card->func = func;
card->model = model;
spin_lock_init(&card->lock);
+ card->workqueue = create_workqueue("libertas_sdio");
INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
@@ -933,9 +936,8 @@ out:
return ret;
err_activate_card:
- flush_scheduled_work();
- free_netdev(priv->dev);
- kfree(priv);
+ flush_workqueue(card->workqueue);
+ lbs_remove_card(priv);
reclaim:
sdio_claim_host(func);
release_int:
@@ -945,6 +947,7 @@ disable:
release:
sdio_release_host(func);
free:
+ destroy_workqueue(card->workqueue);
while (card->packets) {
packet = card->packets;
card->packets = card->packets->next;
@@ -971,7 +974,8 @@ static void if_sdio_remove(struct sdio_func *func)
lbs_stop_card(card->priv);
lbs_remove_card(card->priv);
- flush_scheduled_work();
+ flush_workqueue(card->workqueue);
+ destroy_workqueue(card->workqueue);
sdio_claim_host(func);
sdio_release_irq(func);