diff options
Diffstat (limited to 'drivers/mmc/host/sdhci-of-esdhc.c')
-rw-r--r-- | drivers/mmc/host/sdhci-of-esdhc.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 5d876ff86f3..f8eb1fb0c92 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -1,7 +1,7 @@ /* * Freescale eSDHC controller driver. * - * Copyright (c) 2007, 2010 Freescale Semiconductor, Inc. + * Copyright (c) 2007, 2010, 2012 Freescale Semiconductor, Inc. * Copyright (c) 2009 MontaVista Software, Inc. * * Authors: Xiaobo Xie <X.Xie@freescale.com> @@ -14,6 +14,7 @@ */ #include <linux/io.h> +#include <linux/of.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/mmc/host.h> @@ -114,6 +115,34 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host) return pltfm_host->clock / 256 / 16; } +static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock) +{ + /* Workaround to reduce the clock frequency for p1010 esdhc */ + if (of_find_compatible_node(NULL, NULL, "fsl,p1010-esdhc")) { + if (clock > 20000000) + clock -= 5000000; + if (clock > 40000000) + clock -= 5000000; + } + + /* Set the clock */ + esdhc_set_clock(host, clock); +} + +#ifdef CONFIG_PM +static u32 esdhc_proctl; +static void esdhc_of_suspend(struct sdhci_host *host) +{ + esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL); +} + +static void esdhc_of_resume(struct sdhci_host *host) +{ + esdhc_of_enable_dma(host); + sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL); +} +#endif + static struct sdhci_ops sdhci_esdhc_ops = { .read_l = sdhci_be32bs_readl, .read_w = esdhc_readw, @@ -121,10 +150,14 @@ static struct sdhci_ops sdhci_esdhc_ops = { .write_l = sdhci_be32bs_writel, .write_w = esdhc_writew, .write_b = esdhc_writeb, - .set_clock = esdhc_set_clock, + .set_clock = esdhc_of_set_clock, .enable_dma = esdhc_of_enable_dma, .get_max_clock = esdhc_of_get_max_clock, .get_min_clock = esdhc_of_get_min_clock, +#ifdef CONFIG_PM + .platform_suspend = esdhc_of_suspend, + .platform_resume = esdhc_of_resume, +#endif }; static struct sdhci_pltfm_data sdhci_esdhc_pdata = { |