From 7fe20f9744e7dd70231fcc73ce60f1508cb5b0e1 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Fri, 22 May 2015 14:56:11 +0800 Subject: [PATCH] mmc: rk_sdmmc: disable controller int before enter deepsleep Generally when machine enter deepsleep, with no cirrcumstance, host can interact with slavery devices. So disbale our int generater ourself. By occasionly, we find reset controller will trigger an unexpected SEB int. It exists a race condition for reset and IO timing before switched to gpio and confuse state machine. Signed-off-by: Shawn Lin Tested-and-Reviewed-by: Xiao yao --- drivers/mmc/host/rk_sdmmc.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/host/rk_sdmmc.c b/drivers/mmc/host/rk_sdmmc.c index 62e8c12ec0ee..10e358434072 100755 --- a/drivers/mmc/host/rk_sdmmc.c +++ b/drivers/mmc/host/rk_sdmmc.c @@ -4226,16 +4226,18 @@ int dw_mci_suspend(struct dw_mci *host) { int present = dw_mci_get_cd(host->mmc); - if((host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO) && - (get_wifi_chip_type() == WIFI_ESP8089 || get_wifi_chip_type() > WIFI_AP6XXX_SERIES)) + if((host->mmc->restrict_caps & + RESTRICT_CARD_TYPE_SDIO) && + (get_wifi_chip_type() == WIFI_ESP8089 || + get_wifi_chip_type() > WIFI_AP6XXX_SERIES)) return 0; - if(host->vmmc) - regulator_disable(host->vmmc); + if(host->vmmc) + regulator_disable(host->vmmc); - /*only for sdmmc controller*/ - if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) { - disable_irq(host->irq); + /* Only for sdmmc controller */ + if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) { + disable_irq(host->irq); if (present) { if (pinctrl_select_state(host->pinctrl, host->pins_idle) < 0) MMC_DBG_ERR_FUNC(host->mmc, @@ -4243,10 +4245,6 @@ int dw_mci_suspend(struct dw_mci *host) mmc_hostname(host->mmc)); } - mci_writel(host, RINTSTS, 0xFFFFFFFF); - mci_writel(host, INTMASK, 0x00); - mci_writel(host, CTRL, 0x00); - /* Soc rk3126/3036 already in gpio_cd mode */ if (!soc_is_rk3126() && !soc_is_rk3126b() && !soc_is_rk3036()) { dw_mci_of_get_cd_gpio(host->dev, 0, host->mmc); @@ -4254,6 +4252,10 @@ int dw_mci_suspend(struct dw_mci *host) } } + mci_writel(host, RINTSTS, 0xFFFFFFFF); + mci_writel(host, INTMASK, 0x00); + mci_writel(host, CTRL, 0x00); + if (host->rst_ops && host->rst_ops->pre_suspend) host->rst_ops->pre_suspend(host); @@ -4353,12 +4355,15 @@ int dw_mci_resume(struct dw_mci *host) mci_writel(host, TMOUT, 0xFFFFFFFF); mci_writel(host, RINTSTS, 0xFFFFFFFF); - regs = SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | SDMMC_INT_TXDR | SDMMC_INT_RXDR | SDMMC_INT_VSI | - DW_MCI_ERROR_FLAGS; + regs = SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | SDMMC_INT_TXDR | + SDMMC_INT_RXDR | SDMMC_INT_VSI | DW_MCI_ERROR_FLAGS; + if(!(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO)) - regs |= SDMMC_INT_CD; + regs |= SDMMC_INT_CD; + mci_writel(host, INTMASK, regs); mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); + /*only for sdmmc controller*/ if((host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)){ enable_irq(host->irq); -- 2.34.1