aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/if_sdio.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2009-02-20 12:27:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-27 14:52:51 -0500
commit9b02f419a7dbd956b2c293e5cb1790b6b687f367 (patch)
tree63fb91f39f5fc43a64728cfe18fc89f1a77c28e5 /drivers/net/wireless/libertas/if_sdio.c
parent25d3ef59a2112d50e145500e1bc764f9e8fd4896 (diff)
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 {
95 95
96 spinlock_t lock; 96 spinlock_t lock;
97 struct if_sdio_packet *packets; 97 struct if_sdio_packet *packets;
98
99 struct workqueue_struct *workqueue;
98 struct work_struct packet_worker; 100 struct work_struct packet_worker;
99}; 101};
100 102
@@ -746,7 +748,7 @@ static int if_sdio_host_to_card(struct lbs_private *priv,
746 748
747 spin_unlock_irqrestore(&card->lock, flags); 749 spin_unlock_irqrestore(&card->lock, flags);
748 750
749 schedule_work(&card->packet_worker); 751 queue_work(card->workqueue, &card->packet_worker);
750 752
751 ret = 0; 753 ret = 0;
752 754
@@ -836,6 +838,7 @@ static int if_sdio_probe(struct sdio_func *func,
836 card->func = func; 838 card->func = func;
837 card->model = model; 839 card->model = model;
838 spin_lock_init(&card->lock); 840 spin_lock_init(&card->lock);
841 card->workqueue = create_workqueue("libertas_sdio");
839 INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); 842 INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
840 843
841 for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) { 844 for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
@@ -933,9 +936,8 @@ out:
933 return ret; 936 return ret;
934 937
935err_activate_card: 938err_activate_card:
936 flush_scheduled_work(); 939 flush_workqueue(card->workqueue);
937 free_netdev(priv->dev); 940 lbs_remove_card(priv);
938 kfree(priv);
939reclaim: 941reclaim:
940 sdio_claim_host(func); 942 sdio_claim_host(func);
941release_int: 943release_int:
@@ -945,6 +947,7 @@ disable:
945release: 947release:
946 sdio_release_host(func); 948 sdio_release_host(func);
947free: 949free:
950 destroy_workqueue(card->workqueue);
948 while (card->packets) { 951 while (card->packets) {
949 packet = card->packets; 952 packet = card->packets;
950 card->packets = card->packets->next; 953 card->packets = card->packets->next;
@@ -971,7 +974,8 @@ static void if_sdio_remove(struct sdio_func *func)
971 lbs_stop_card(card->priv); 974 lbs_stop_card(card->priv);
972 lbs_remove_card(card->priv); 975 lbs_remove_card(card->priv);
973 976
974 flush_scheduled_work(); 977 flush_workqueue(card->workqueue);
978 destroy_workqueue(card->workqueue);
975 979
976 sdio_claim_host(func); 980 sdio_claim_host(func);
977 sdio_release_irq(func); 981 sdio_release_irq(func);