summaryrefslogtreecommitdiffstats
path: root/drivers/staging/ks7010/ks7010_sdio.c
diff options
context:
space:
mode:
authorWolfram Sang <wsa+renesas@sang-engineering.com>2016-05-31 12:56:18 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-06-07 22:42:53 -0700
commite8593a8abf8cc35073b1c26bb0492f7e361b6ac1 (patch)
tree2a22ec66063bb9e91822d7596b91d3068b367b27 /drivers/staging/ks7010/ks7010_sdio.c
parent72bf750007297c33fe2331d2125118d4885367c2 (diff)
downloadop-kernel-dev-e8593a8abf8cc35073b1c26bb0492f7e361b6ac1.zip
op-kernel-dev-e8593a8abf8cc35073b1c26bb0492f7e361b6ac1.tar.gz
staging: ks7010: avoid workqueue races
My Spectec SDW823 card oopsed when it was already inserted during boot. When debugging this, I noticed that the card init was done in a seperate workqueue which was only activated once in probe. After removing the workqueue and calling the card init directly from probe, the OOPS went away. It turned out this is the same OOPS which happened when removing the card, so this seems possible now. Note: There is still a not-understood card-removed event during boot, but at least it doesn't crash anymore and the card will be re-probed right away. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/ks7010/ks7010_sdio.c')
-rw-r--r--drivers/staging/ks7010/ks7010_sdio.c28
1 files changed, 2 insertions, 26 deletions
diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c
index 9300658..5b78522 100644
--- a/drivers/staging/ks7010/ks7010_sdio.c
+++ b/drivers/staging/ks7010/ks7010_sdio.c
@@ -817,14 +817,8 @@ static int ks79xx_upload_firmware(ks_wlan_private *priv, struct ks_sdio_card *ca
return rc;
}
-static void card_init_task(struct work_struct *work)
+static void ks7010_card_init(struct ks_wlan_private *priv)
{
- struct hw_info_t *hw;
- struct ks_wlan_private *priv;
-
- hw = container_of(work, struct hw_info_t, init_task);
- priv = container_of(hw, struct ks_wlan_private, ks_wlan_hw);
-
DPRINTK(5,"\ncard_init_task()\n");
/* init_waitqueue_head(&priv->confirm_wait); */
@@ -1052,23 +1046,11 @@ static int ks7910_sdio_probe(struct sdio_func *func, const struct sdio_device_id
goto error_free_read_buf;
}
- priv->ks_wlan_hw.ks7010sdio_init = create_singlethread_workqueue("ks7010sdio_init");
- if(!priv->ks_wlan_hw.ks7010sdio_init){
- DPRINTK(1, "create_workqueue failed !!\n");
- goto error_free_sdio_wq;
- }
-
- INIT_WORK(&priv->ks_wlan_hw.init_task, card_init_task);
INIT_DELAYED_WORK(&priv->ks_wlan_hw.rw_wq, ks7010_rw_function);
-
- queue_work(priv->ks_wlan_hw.ks7010sdio_init, &priv->ks_wlan_hw.init_task);
+ ks7010_card_init(priv);
return 0;
-error_free_sdio_wq:
- flush_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);
- destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);
- priv->ks_wlan_hw.ks7010sdio_wq = NULL;
error_free_read_buf:
kfree(priv->ks_wlan_hw.read_buf);
priv->ks_wlan_hw.read_buf = NULL;
@@ -1139,12 +1121,6 @@ static void ks7910_sdio_remove(struct sdio_func *func)
}
DPRINTK(1, "destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);\n");
- if(priv->ks_wlan_hw.ks7010sdio_init){
- flush_workqueue(priv->ks_wlan_hw.ks7010sdio_init);
- destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_init);
- }
- DPRINTK(1, "destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_init);\n");
-
hostif_exit(priv);
DPRINTK(1, "hostif_exit\n");
OpenPOWER on IntegriCloud