mmc: sdhci-omap: Fix context restore
[ Upstream commit d806e334d0390502cd2a820ad33d65d7f9bba618 ]
We need to restore context in a specified order with HCTL set in two
phases. This is similar to what omap_hsmmc_context_restore() is doing.
Otherwise SDIO can stop working on resume.
And for PM runtime and SDIO cards, we need to also save SYSCTL, IE and
ISE.
This should not be a problem currently, and these patches can be applied
whenever suitable.
Fixes: ee0f309263
("mmc: sdhci-omap: Add Support for Suspend/Resume")
Signed-off-by: Tony Lindgren <tony@atomide.com>
Link: https://lore.kernel.org/r/20210921110029.21944-3-tony@atomide.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
2fd26ec36e
commit
72de92d33f
@@ -62,6 +62,8 @@
|
|||||||
#define SDHCI_OMAP_IE 0x234
|
#define SDHCI_OMAP_IE 0x234
|
||||||
#define INT_CC_EN BIT(0)
|
#define INT_CC_EN BIT(0)
|
||||||
|
|
||||||
|
#define SDHCI_OMAP_ISE 0x238
|
||||||
|
|
||||||
#define SDHCI_OMAP_AC12 0x23c
|
#define SDHCI_OMAP_AC12 0x23c
|
||||||
#define AC12_V1V8_SIGEN BIT(19)
|
#define AC12_V1V8_SIGEN BIT(19)
|
||||||
#define AC12_SCLK_SEL BIT(23)
|
#define AC12_SCLK_SEL BIT(23)
|
||||||
@@ -113,6 +115,8 @@ struct sdhci_omap_host {
|
|||||||
u32 hctl;
|
u32 hctl;
|
||||||
u32 sysctl;
|
u32 sysctl;
|
||||||
u32 capa;
|
u32 capa;
|
||||||
|
u32 ie;
|
||||||
|
u32 ise;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host);
|
static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host);
|
||||||
@@ -1246,14 +1250,23 @@ static void sdhci_omap_context_save(struct sdhci_omap_host *omap_host)
|
|||||||
{
|
{
|
||||||
omap_host->con = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
|
omap_host->con = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
|
||||||
omap_host->hctl = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
|
omap_host->hctl = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
|
||||||
|
omap_host->sysctl = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
|
||||||
omap_host->capa = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
|
omap_host->capa = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
|
||||||
|
omap_host->ie = sdhci_omap_readl(omap_host, SDHCI_OMAP_IE);
|
||||||
|
omap_host->ise = sdhci_omap_readl(omap_host, SDHCI_OMAP_ISE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Order matters here, HCTL must be restored in two phases */
|
||||||
static void sdhci_omap_context_restore(struct sdhci_omap_host *omap_host)
|
static void sdhci_omap_context_restore(struct sdhci_omap_host *omap_host)
|
||||||
{
|
{
|
||||||
sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, omap_host->con);
|
|
||||||
sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, omap_host->hctl);
|
sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, omap_host->hctl);
|
||||||
sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, omap_host->capa);
|
sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, omap_host->capa);
|
||||||
|
sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, omap_host->hctl);
|
||||||
|
|
||||||
|
sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, omap_host->sysctl);
|
||||||
|
sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, omap_host->con);
|
||||||
|
sdhci_omap_writel(omap_host, SDHCI_OMAP_IE, omap_host->ie);
|
||||||
|
sdhci_omap_writel(omap_host, SDHCI_OMAP_ISE, omap_host->ise);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __maybe_unused sdhci_omap_suspend(struct device *dev)
|
static int __maybe_unused sdhci_omap_suspend(struct device *dev)
|
||||||
|
Reference in New Issue
Block a user