mmc: Delay the card_event callback into the mmc_rescan worker
authorMarkus Mayer <markus.mayer@linaro.org>
Tue, 8 Apr 2014 22:19:43 +0000 (15:19 -0700)
committerChris Ball <chris@printf.net>
Tue, 22 Apr 2014 11:06:36 +0000 (07:06 -0400)
This change removes the callback from atomic context which it doesn't
need to be in, and puts it in line with the debounced rescan.

This code is based on these e-mail threads with Christian Daudt:

  https://lkml.org/lkml/2013/8/19/539
  https://lkml.org/lkml/2014/3/19/79

Signed-off-by: Markus Mayer <markus.mayer@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <chris@printf.net>
drivers/mmc/core/core.c
drivers/mmc/core/slot-gpio.c
include/linux/mmc/host.h

index acbc3f2aaaf9e3adff743de7081e1e6508b6b03c..f396d1bb4ac47955982a69f77e5aa5fc90052e9e 100644 (file)
@@ -2403,6 +2403,11 @@ void mmc_rescan(struct work_struct *work)
                container_of(work, struct mmc_host, detect.work);
        int i;
 
+       if (host->trigger_card_event && host->ops->card_event) {
+               host->ops->card_event(host);
+               host->trigger_card_event = false;
+       }
+
        if (host->rescan_disable)
                return;
 
index f7650b899e3d426fbce08e8b636784adf0d0cdf0..5f89cb83d5f00008aa3c98f550f9ff962c0306c0 100644 (file)
@@ -32,9 +32,7 @@ static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id)
        /* Schedule a card detection after a debounce timeout */
        struct mmc_host *host = dev_id;
 
-       if (host->ops->card_event)
-               host->ops->card_event(host);
-
+       host->trigger_card_event = true;
        mmc_detect_change(host, msecs_to_jiffies(200));
 
        return IRQ_HANDLED;
index 35354207e71f19a1125a2c11777f279217c9d6fe..0cf705c839985a9bb0595fa3a044e307912138a6 100644 (file)
@@ -319,6 +319,8 @@ struct mmc_host {
        int                     rescan_disable; /* disable card detection */
        int                     rescan_entered; /* used with nonremovable devices */
 
+       bool                    trigger_card_event; /* card_event necessary */
+
        struct mmc_card         *card;          /* device attached to this host */
 
        wait_queue_head_t       wq;