/* 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;
        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.
 
        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);
 }
 
 
        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);
 }
 
        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);