Added pm runtime protection for suspend/resume and add/remove functions.
When these functions called, pm runtime may have suspended.

Signed-off-by: Jialing Fu <[email protected]>
Signed-off-by: Kevin Liu <[email protected]>
---
 drivers/mmc/host/sdhci.c |   22 ++++++++++++++++++----
 1 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 6f0bfc0..ec7da59 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2460,6 +2460,7 @@ int sdhci_suspend_host(struct sdhci_host *host)
 {
        int ret;
 
+       sdhci_runtime_pm_get(host);
        if (host->ops->platform_suspend)
                host->ops->platform_suspend(host);
 
@@ -2480,12 +2481,13 @@ int sdhci_suspend_host(struct sdhci_host *host)
                }
 
                sdhci_enable_card_detection(host);
-
+               sdhci_runtime_pm_put(host);
                return ret;
        }
 
        free_irq(host->irq, host);
 
+       sdhci_runtime_pm_put(host);
        return ret;
 }
 
@@ -2495,6 +2497,7 @@ int sdhci_resume_host(struct sdhci_host *host)
 {
        int ret;
 
+       sdhci_runtime_pm_get(host);
        if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
                if (host->ops->enable_dma)
                        host->ops->enable_dma(host);
@@ -2502,8 +2505,10 @@ int sdhci_resume_host(struct sdhci_host *host)
 
        ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
                          mmc_hostname(host->mmc), host);
-       if (ret)
+       if (ret) {
+               sdhci_runtime_pm_put(host);
                return ret;
+       }
 
        if ((host->mmc->pm_flags & MMC_PM_KEEP_POWER) &&
            (host->quirks2 & SDHCI_QUIRK2_HOST_OFF_CARD_ON)) {
@@ -2527,6 +2532,7 @@ int sdhci_resume_host(struct sdhci_host *host)
        if (host->flags & SDHCI_USING_RETUNING_TIMER)
                host->flags |= SDHCI_NEEDS_RETUNING;
 
+       sdhci_runtime_pm_put(host);
        return ret;
 }
 
@@ -2664,6 +2670,7 @@ int sdhci_add_host(struct sdhci_host *host)
        if (host == NULL)
                return -EINVAL;
 
+       sdhci_runtime_pm_get(host);
        mmc = host->mmc;
 
        if (debug_quirks)
@@ -2766,6 +2773,7 @@ int sdhci_add_host(struct sdhci_host *host)
                if (!host->ops->get_max_clock) {
                        pr_err("%s: Hardware doesn't specify base clock "
                               "frequency.\n", mmc_hostname(mmc));
+                       sdhci_runtime_pm_put(host);
                        return -ENODEV;
                }
                host->max_clk = host->ops->get_max_clock(host);
@@ -2812,6 +2820,7 @@ int sdhci_add_host(struct sdhci_host *host)
                                SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
                        pr_err("%s: Hardware doesn't specify timeout clock "
                               "frequency.\n", mmc_hostname(mmc));
+                       sdhci_runtime_pm_put(host);
                        return -ENODEV;
                }
        }
@@ -3015,6 +3024,7 @@ int sdhci_add_host(struct sdhci_host *host)
        if (mmc->ocr_avail == 0) {
                pr_err("%s: Hardware doesn't report any "
                        "support voltages.\n", mmc_hostname(mmc));
+               sdhci_runtime_pm_put(host);
                return -ENODEV;
        }
 
@@ -3133,7 +3143,7 @@ int sdhci_add_host(struct sdhci_host *host)
                (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO");
 
        sdhci_enable_card_detection(host);
-
+       sdhci_runtime_pm_put(host);
        return 0;
 
 #ifdef SDHCI_USE_LEDS_CLASS
@@ -3144,7 +3154,7 @@ reset:
 untasklet:
        tasklet_kill(&host->card_tasklet);
        tasklet_kill(&host->finish_tasklet);
-
+       sdhci_runtime_pm_put(host);
        return ret;
 }
 
@@ -3154,6 +3164,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 {
        unsigned long flags;
 
+       sdhci_runtime_pm_get(host);
+
        if (dead) {
                spin_lock_irqsave(&host->lock, flags);
 
@@ -3203,6 +3215,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
 
        host->adma_desc = NULL;
        host->align_buffer = NULL;
+
+       sdhci_runtime_pm_put(host);
 }
 
 EXPORT_SYMBOL_GPL(sdhci_remove_host);
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to