]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00170929 [MX6Q MMC]might sleep in atomic context
authorTony Lin <tony.lin@freescale.com>
Mon, 26 Dec 2011 05:44:20 +0000 (13:44 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:33:42 +0000 (08:33 +0200)
call clk_enable/clk_disable in atomic is forbidden.
move all the calls out of atomic context.

Signed-off-by: Tony Lin <tony.lin@freescale.com>
drivers/mmc/host/sdhci.c

index 62a9bb662faa899ad56a114489585dbbea892e0c..e350f03424c2204096e734c94d667a7f96f3e13d 100755 (executable)
@@ -57,10 +57,8 @@ static void sdhci_clk_worker(struct work_struct *work)
        struct sdhci_host *host =
                container_of(work, struct sdhci_host, clk_worker.work);
 
-       spin_lock_irqsave(&host->lock, flags);
        if (host->ops->platform_clk_ctrl && host->clk_status)
                host->ops->platform_clk_ctrl(host, false);
-       spin_unlock_irqrestore(&host->lock, flags);
 }
 
 static inline bool sdhci_is_sdio_attached(struct sdhci_host *host)
@@ -292,16 +290,16 @@ static void sdhci_led_control(struct led_classdev *led,
        struct sdhci_host *host = container_of(led, struct sdhci_host, led);
        unsigned long flags;
 
-       spin_lock_irqsave(&host->lock, flags);
        sdhci_enable_clk(host);
+       spin_lock_irqsave(&host->lock, flags);
 
        if (brightness == LED_OFF)
                sdhci_deactivate_led(host);
        else
                sdhci_activate_led(host);
 
-       sdhci_disable_clk(host, CLK_TIMEOUT);
        spin_unlock_irqrestore(&host->lock, flags);
+       sdhci_disable_clk(host, CLK_TIMEOUT);
 }
 #endif
 
@@ -1256,6 +1254,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
        host = mmc_priv(mmc);
 
+       sdhci_enable_clk(host);
        spin_lock_irqsave(&host->lock, flags);
 
        WARN_ON(host->mrq != NULL);
@@ -1276,7 +1275,6 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
        }
 
        host->mrq = mrq;
-       sdhci_enable_clk(host);
 
        /* If polling, assume that the card is always present. */
        if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
@@ -1325,8 +1323,8 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
        host = mmc_priv(mmc);
 
-       spin_lock_irqsave(&host->lock, flags);
        sdhci_enable_clk(host);
+       spin_lock_irqsave(&host->lock, flags);
 
        if (host->flags & SDHCI_DEVICE_DEAD)
                goto out;
@@ -1477,10 +1475,10 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
 out:
        mmiowb();
+       spin_unlock_irqrestore(&host->lock, flags);
+
        if (ios->power_mode == MMC_POWER_OFF)
                sdhci_disable_clk(host, 0);
-
-       spin_unlock_irqrestore(&host->lock, flags);
 }
 
 static int check_ro(struct sdhci_host *host)
@@ -1488,8 +1486,8 @@ static int check_ro(struct sdhci_host *host)
        unsigned long flags;
        int is_readonly;
 
-       spin_lock_irqsave(&host->lock, flags);
        sdhci_enable_clk(host);
+       spin_lock_irqsave(&host->lock, flags);
 
        if (host->flags & SDHCI_DEVICE_DEAD)
                is_readonly = 0;
@@ -1500,6 +1498,7 @@ static int check_ro(struct sdhci_host *host)
                                & SDHCI_WRITE_PROTECT);
 
        spin_unlock_irqrestore(&host->lock, flags);
+       sdhci_disable_clk(host, CLK_TIMEOUT);
 
        /* This quirk needs to be replaced by a callback-function later */
        return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
@@ -1536,8 +1535,8 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
 
        host = mmc_priv(mmc);
 
-       spin_lock_irqsave(&host->lock, flags);
        sdhci_enable_clk(host);
+       spin_lock_irqsave(&host->lock, flags);
 
        if (host->flags & SDHCI_DEVICE_DEAD)
                goto out;
@@ -1964,8 +1963,8 @@ static void sdhci_tasklet_finish(unsigned long param)
 #endif
 
        mmiowb();
-       sdhci_disable_clk(host, CLK_TIMEOUT);
        spin_unlock_irqrestore(&host->lock, flags);
+       sdhci_disable_clk(host, CLK_TIMEOUT);
 
        mmc_request_done(host->mmc, mrq);
 }
@@ -2865,6 +2864,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 {
        unsigned long flags;
 
+       sdhci_enable_clk(host);
+
        if (dead) {
                spin_lock_irqsave(&host->lock, flags);
 
@@ -2875,7 +2876,6 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
                                " transfer!\n", mmc_hostname(host->mmc));
 
                        host->mrq->cmd->error = -ENOMEDIUM;
-                       sdhci_enable_clk(host);
                        tasklet_schedule(&host->finish_tasklet);
                }