Merge tag 'locks-v3.16-2' of git://git.samba.org/jlayton/linux
[cascardo/linux.git] / drivers / mmc / core / sdio_irq.c
index aaa9046..5cc13c8 100644 (file)
@@ -90,6 +90,15 @@ static int process_sdio_pending_irqs(struct mmc_host *host)
        return ret;
 }
 
+void sdio_run_irqs(struct mmc_host *host)
+{
+       mmc_claim_host(host);
+       host->sdio_irq_pending = true;
+       process_sdio_pending_irqs(host);
+       mmc_release_host(host);
+}
+EXPORT_SYMBOL_GPL(sdio_run_irqs);
+
 static int sdio_irq_thread(void *_host)
 {
        struct mmc_host *host = _host;
@@ -189,14 +198,20 @@ static int sdio_card_irq_get(struct mmc_card *card)
        WARN_ON(!host->claimed);
 
        if (!host->sdio_irqs++) {
-               atomic_set(&host->sdio_irq_thread_abort, 0);
-               host->sdio_irq_thread =
-                       kthread_run(sdio_irq_thread, host, "ksdioirqd/%s",
-                               mmc_hostname(host));
-               if (IS_ERR(host->sdio_irq_thread)) {
-                       int err = PTR_ERR(host->sdio_irq_thread);
-                       host->sdio_irqs--;
-                       return err;
+               if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) {
+                       atomic_set(&host->sdio_irq_thread_abort, 0);
+                       host->sdio_irq_thread =
+                               kthread_run(sdio_irq_thread, host,
+                                           "ksdioirqd/%s", mmc_hostname(host));
+                       if (IS_ERR(host->sdio_irq_thread)) {
+                               int err = PTR_ERR(host->sdio_irq_thread);
+                               host->sdio_irqs--;
+                               return err;
+                       }
+               } else {
+                       mmc_host_clk_hold(host);
+                       host->ops->enable_sdio_irq(host, 1);
+                       mmc_host_clk_release(host);
                }
        }
 
@@ -211,8 +226,14 @@ static int sdio_card_irq_put(struct mmc_card *card)
        BUG_ON(host->sdio_irqs < 1);
 
        if (!--host->sdio_irqs) {
-               atomic_set(&host->sdio_irq_thread_abort, 1);
-               kthread_stop(host->sdio_irq_thread);
+               if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD)) {
+                       atomic_set(&host->sdio_irq_thread_abort, 1);
+                       kthread_stop(host->sdio_irq_thread);
+               } else {
+                       mmc_host_clk_hold(host);
+                       host->ops->enable_sdio_irq(host, 0);
+                       mmc_host_clk_release(host);
+               }
        }
 
        return 0;