Commit 9b02f419 authored by Dan Williams's avatar Dan Williams Committed by John W. Linville

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: default avatarDan Williams <dcbw@redhat.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 25d3ef59
...@@ -95,6 +95,8 @@ struct if_sdio_card { ...@@ -95,6 +95,8 @@ struct if_sdio_card {
spinlock_t lock; spinlock_t lock;
struct if_sdio_packet *packets; struct if_sdio_packet *packets;
struct workqueue_struct *workqueue;
struct work_struct packet_worker; struct work_struct packet_worker;
}; };
...@@ -746,7 +748,7 @@ static int if_sdio_host_to_card(struct lbs_private *priv, ...@@ -746,7 +748,7 @@ static int if_sdio_host_to_card(struct lbs_private *priv,
spin_unlock_irqrestore(&card->lock, flags); spin_unlock_irqrestore(&card->lock, flags);
schedule_work(&card->packet_worker); queue_work(card->workqueue, &card->packet_worker);
ret = 0; ret = 0;
...@@ -836,6 +838,7 @@ static int if_sdio_probe(struct sdio_func *func, ...@@ -836,6 +838,7 @@ static int if_sdio_probe(struct sdio_func *func,
card->func = func; card->func = func;
card->model = model; card->model = model;
spin_lock_init(&card->lock); spin_lock_init(&card->lock);
card->workqueue = create_workqueue("libertas_sdio");
INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) { for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
...@@ -933,9 +936,8 @@ static int if_sdio_probe(struct sdio_func *func, ...@@ -933,9 +936,8 @@ static int if_sdio_probe(struct sdio_func *func,
return ret; return ret;
err_activate_card: err_activate_card:
flush_scheduled_work(); flush_workqueue(card->workqueue);
free_netdev(priv->dev); lbs_remove_card(priv);
kfree(priv);
reclaim: reclaim:
sdio_claim_host(func); sdio_claim_host(func);
release_int: release_int:
...@@ -945,6 +947,7 @@ static int if_sdio_probe(struct sdio_func *func, ...@@ -945,6 +947,7 @@ static int if_sdio_probe(struct sdio_func *func,
release: release:
sdio_release_host(func); sdio_release_host(func);
free: free:
destroy_workqueue(card->workqueue);
while (card->packets) { while (card->packets) {
packet = card->packets; packet = card->packets;
card->packets = card->packets->next; card->packets = card->packets->next;
...@@ -971,7 +974,8 @@ static void if_sdio_remove(struct sdio_func *func) ...@@ -971,7 +974,8 @@ static void if_sdio_remove(struct sdio_func *func)
lbs_stop_card(card->priv); lbs_stop_card(card->priv);
lbs_remove_card(card->priv); lbs_remove_card(card->priv);
flush_scheduled_work(); flush_workqueue(card->workqueue);
destroy_workqueue(card->workqueue);
sdio_claim_host(func); sdio_claim_host(func);
sdio_release_irq(func); sdio_release_irq(func);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment