mirror of
https://github.com/torvalds/linux.git
synced 2024-12-19 17:41:29 +00:00
ath6kl: Use a mutex_lock to avoid race in diabling and handling irq
Currently this race is handled but in a messy way an atomic variable is being checked in a loop which sleeps upto ms in every iteration. Remove this logic and use a mutex to make sure irq is not disabled when irq handling is in progress. Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
982767b8c9
commit
9d82682d45
@ -49,11 +49,13 @@ struct ath6kl_sdio {
|
||||
/* scatter request list head */
|
||||
struct list_head scat_req;
|
||||
|
||||
/* Avoids disabling irq while the interrupts being handled */
|
||||
struct mutex mtx_irq;
|
||||
|
||||
spinlock_t scat_lock;
|
||||
bool scatter_enabled;
|
||||
|
||||
bool is_disabled;
|
||||
atomic_t irq_handling;
|
||||
const struct sdio_device_id *id;
|
||||
struct work_struct wr_async_work;
|
||||
struct list_head wr_asyncq;
|
||||
@ -460,8 +462,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
|
||||
ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n");
|
||||
|
||||
ar_sdio = sdio_get_drvdata(func);
|
||||
atomic_set(&ar_sdio->irq_handling, 1);
|
||||
|
||||
mutex_lock(&ar_sdio->mtx_irq);
|
||||
/*
|
||||
* Release the host during interrups so we can pick it back up when
|
||||
* we process commands.
|
||||
@ -470,7 +471,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func)
|
||||
|
||||
status = ath6kl_hif_intr_bh_handler(ar_sdio->ar);
|
||||
sdio_claim_host(ar_sdio->func);
|
||||
atomic_set(&ar_sdio->irq_handling, 0);
|
||||
mutex_unlock(&ar_sdio->mtx_irq);
|
||||
WARN_ON(status && status != -ECANCELED);
|
||||
}
|
||||
|
||||
@ -578,17 +579,14 @@ static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
|
||||
|
||||
sdio_claim_host(ar_sdio->func);
|
||||
|
||||
/* Mask our function IRQ */
|
||||
while (atomic_read(&ar_sdio->irq_handling)) {
|
||||
sdio_release_host(ar_sdio->func);
|
||||
schedule_timeout(HZ / 10);
|
||||
sdio_claim_host(ar_sdio->func);
|
||||
}
|
||||
mutex_lock(&ar_sdio->mtx_irq);
|
||||
|
||||
ret = sdio_release_irq(ar_sdio->func);
|
||||
if (ret)
|
||||
ath6kl_err("Failed to release sdio irq: %d\n", ret);
|
||||
|
||||
mutex_unlock(&ar_sdio->mtx_irq);
|
||||
|
||||
sdio_release_host(ar_sdio->func);
|
||||
}
|
||||
|
||||
@ -1253,6 +1251,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
|
||||
spin_lock_init(&ar_sdio->scat_lock);
|
||||
spin_lock_init(&ar_sdio->wr_async_lock);
|
||||
mutex_init(&ar_sdio->dma_buffer_mutex);
|
||||
mutex_init(&ar_sdio->mtx_irq);
|
||||
|
||||
INIT_LIST_HEAD(&ar_sdio->scat_req);
|
||||
INIT_LIST_HEAD(&ar_sdio->bus_req_freeq);
|
||||
|
Loading…
Reference in New Issue
Block a user