mmc: omap_hsmmc: use threaded irq handler for card-detect.
authorNeilBrown <neilb@suse.de>
Fri, 30 Dec 2011 01:35:13 +0000 (12:35 +1100)
committerGrazvydas Ignotas <notasas@gmail.com>
Fri, 13 Jan 2012 15:09:47 +0000 (17:09 +0200)
As the card-detect irq handler just schedules work to be done by a
thread, we can use request_threaded_irq to do much of the work for
us.  This means that interrupts which arrive by handle_nested_irq
actually work.

Reviewed-by: Felipe Balbi <balbi@ti.com>
Tested-by: Grazvydas Ignotas <notasas@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Acked-by: Kishore Kadiyala <kishorek.kadiyala@gmail.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
drivers/mmc/host/omap_hsmmc.c

index d5fe43d..56f6cfc 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_device.h>
-#include <linux/workqueue.h>
 #include <linux/timer.h>
 #include <linux/clk.h>
 #include <linux/mmc/host.h>
@@ -163,7 +162,6 @@ struct omap_hsmmc_host {
         */
        struct  regulator       *vcc;
        struct  regulator       *vcc_aux;
-       struct  work_struct     mmc_carddetect_work;
        void    __iomem         *base;
        resource_size_t         mapbase;
        spinlock_t              irq_lock; /* Prevent races with irq handler */
@@ -1280,17 +1278,16 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host)
 }
 
 /*
- * Work Item to notify the core about card insertion/removal
+ * irq handler to notify the core about card insertion/removal
  */
-static void omap_hsmmc_detect(struct work_struct *work)
+static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
 {
-       struct omap_hsmmc_host *host =
-               container_of(work, struct omap_hsmmc_host, mmc_carddetect_work);
+       struct omap_hsmmc_host *host = dev_id;
        struct omap_mmc_slot_data *slot = &mmc_slot(host);
        int carddetect;
 
        if (host->suspended)
-               return;
+               return IRQ_HANDLED;
 
        sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
 
@@ -1305,19 +1302,6 @@ static void omap_hsmmc_detect(struct work_struct *work)
                mmc_detect_change(host->mmc, (HZ * 200) / 1000);
        else
                mmc_detect_change(host->mmc, (HZ * 50) / 1000);
-}
-
-/*
- * ISR for handling card insertion and removal
- */
-static irqreturn_t omap_hsmmc_cd_handler(int irq, void *dev_id)
-{
-       struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)dev_id;
-
-       if (host->suspended)
-               return IRQ_HANDLED;
-       schedule_work(&host->mmc_carddetect_work);
-
        return IRQ_HANDLED;
 }
 
@@ -1919,7 +1903,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
        host->next_data.cookie = 1;
 
        platform_set_drvdata(pdev, host);
-       INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect);
 
        mmc->ops        = &omap_hsmmc_ops;
 
@@ -2047,10 +2030,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
 
        /* Request IRQ for card detect */
        if ((mmc_slot(host).card_detect_irq)) {
-               ret = request_irq(mmc_slot(host).card_detect_irq,
-                                 omap_hsmmc_cd_handler,
-                                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-                                 mmc_hostname(mmc), host);
+               ret = request_threaded_irq(mmc_slot(host).card_detect_irq,
+                                          NULL,
+                                          omap_hsmmc_detect,
+                                          IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+                                          mmc_hostname(mmc), host);
                if (ret) {
                        dev_dbg(mmc_dev(host->mmc),
                                "Unable to grab MMC CD IRQ\n");
@@ -2129,7 +2113,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
                free_irq(host->irq, host);
                if (mmc_slot(host).card_detect_irq)
                        free_irq(mmc_slot(host).card_detect_irq, host);
-               flush_work_sync(&host->mmc_carddetect_work);
 
                pm_runtime_put_sync(host->dev);
                pm_runtime_disable(host->dev);
@@ -2176,7 +2159,6 @@ static int omap_hsmmc_suspend(struct device *dev)
                                return ret;
                        }
                }
-               cancel_work_sync(&host->mmc_carddetect_work);
                ret = mmc_suspend_host(host->mmc);
 
                if (ret == 0) {