diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index f7607a73880a..36abd920a991 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -2292,6 +2292,9 @@ static void sdhci_msm_cfg_sdiowakeup_gpio_irq(struct sdhci_host *host, static irqreturn_t sdhci_msm_sdiowakeup_irq(int irq, void *data) { struct sdhci_host *host = (struct sdhci_host *)data; + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_msm_host *msm_host = pltfm_host->priv; + unsigned long flags; pr_debug("%s: irq (%d) received\n", __func__, irq); @@ -2299,6 +2302,7 @@ static irqreturn_t sdhci_msm_sdiowakeup_irq(int irq, void *data) spin_lock_irqsave(&host->lock, flags); sdhci_msm_cfg_sdiowakeup_gpio_irq(host, false); spin_unlock_irqrestore(&host->lock, flags); + msm_host->sdio_pending_processing = true; return IRQ_HANDLED; } @@ -4264,9 +4268,9 @@ static int sdhci_msm_probe(struct platform_device *pdev) msm_host->pdata->sdiowakeup_irq = platform_get_irq_byname(pdev, "sdiowakeup_irq"); - dev_info(&pdev->dev, "%s: sdiowakeup_irq = %d\n", __func__, - msm_host->pdata->sdiowakeup_irq); if (sdhci_is_valid_gpio_wakeup_int(msm_host)) { + dev_info(&pdev->dev, "%s: sdiowakeup_irq = %d\n", __func__, + msm_host->pdata->sdiowakeup_irq); msm_host->is_sdiowakeup_enabled = true; ret = request_irq(msm_host->pdata->sdiowakeup_irq, sdhci_msm_sdiowakeup_irq, @@ -4421,6 +4425,7 @@ static int sdhci_msm_cfg_sdio_wakeup(struct sdhci_host *host, bool enable) if (enable) { /* configure DAT1 gpio if applicable */ if (sdhci_is_valid_gpio_wakeup_int(msm_host)) { + msm_host->sdio_pending_processing = false; ret = enable_irq_wake(msm_host->pdata->sdiowakeup_irq); if (!ret) sdhci_msm_cfg_sdiowakeup_gpio_irq(host, true); @@ -4433,6 +4438,7 @@ static int sdhci_msm_cfg_sdio_wakeup(struct sdhci_host *host, bool enable) if (sdhci_is_valid_gpio_wakeup_int(msm_host)) { ret = disable_irq_wake(msm_host->pdata->sdiowakeup_irq); sdhci_msm_cfg_sdiowakeup_gpio_irq(host, false); + msm_host->sdio_pending_processing = false; } else { pr_err("%s: sdiowakeup_irq(%d)invalid\n", mmc_hostname(host->mmc), enable); @@ -4601,6 +4607,10 @@ static int sdhci_msm_suspend_noirq(struct device *dev) ret = -EAGAIN; } + if (host->mmc->card && mmc_card_sdio(host->mmc->card)) + if (msm_host->sdio_pending_processing) + ret = -EBUSY; + return ret; } diff --git a/drivers/mmc/host/sdhci-msm.h b/drivers/mmc/host/sdhci-msm.h index 09949465d0cb..00785765a1ec 100644 --- a/drivers/mmc/host/sdhci-msm.h +++ b/drivers/mmc/host/sdhci-msm.h @@ -197,6 +197,7 @@ struct sdhci_msm_host { bool en_auto_cmd21; struct device_attribute auto_cmd21_attr; bool is_sdiowakeup_enabled; + bool sdio_pending_processing; atomic_t controller_clock; bool use_cdclp533; bool use_updated_dll_reset;