On Sat, Apr 11, 2009 at 12:32 AM, Russ Dill <[email protected]> wrote:
> I've noticed that if the core power domain gets powered off during
> suspend, the MMC registers get reset. Which, among other things causes
> the MMC host controller code to turn on VMMC1 even if no MMC card is
> present.
>
> I'm not sure if this is the right place to put this code. It also
> doesn't work. If any of the __raw_readl commands execute, the board will
> hang on a suspend attempt (assuming the core domain will be powered
> off.) Strangely, the __raw_writel commands don't cause problems (other
> than writing 0s to all the MMC registers.)
That would be because omap_mmc_suspend disables the interface clock.
The suspend method is a more logical place to save these registers,
but I'm not sure how to tell from the suspend method if the domain is
going to be turned off or not.
> My platform is an OMAP3430 on a rev B7 Beagleboard. The patch is against
> omap/pm.
> ---
> arch/arm/mach-omap2/Makefile | 1 +
> arch/arm/mach-omap2/hsmmc.c | 73
> +++++++++++++++++++++++++++++++
> arch/arm/mach-omap2/pm34xx.c | 5 ++
> arch/arm/plat-omap/include/mach/hsmmc.h | 15 ++++++
> 4 files changed, 94 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-omap2/hsmmc.c
> create mode 100644 arch/arm/plat-omap/include/mach/hsmmc.h
>
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index c58bab4..4dd8ec0 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -24,6 +24,7 @@ obj-y += pm.o
> obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
> obj-$(CONFIG_ARCH_OMAP24XX) += sleep24xx.o
> obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o
> +obj-$(CONFIG_ARCH_OMAP3) += hsmmc.o
> obj-$(CONFIG_PM_DEBUG) += pm-debug.o
> endif
>
> diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
> new file mode 100644
> index 0000000..9ac6f91
> --- /dev/null
> +++ b/arch/arm/mach-omap2/hsmmc.c
> @@ -0,0 +1,73 @@
> +/*
> + * HSMMC context save/restore functions
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/kernel.h>
> +
> +#include <asm/io.h>
> +
> +#include <mach/mmc.h>
> +
> +#define HSMMC_SYSCONFIG 0x0010
> +#define HSMMC_CON 0x002c
> +#define HSMMC_HCTL 0x0128
> +#define HSMMC_SYSCTL 0x012c
> +#define HSMMC_IE 0x0134
> +#define HSMMC_ISE 0x0138
> +
> +static const void __iomem *instances[] = {
> + OMAP2_IO_ADDRESS(OMAP2_MMC1_BASE),
> + OMAP2_IO_ADDRESS(OMAP2_MMC2_BASE),
> + OMAP2_IO_ADDRESS(OMAP3_MMC3_BASE),
> +};
> +
> +struct omap3_hsmmc_regs {
> + u32 sysconfig;
> + u32 con;
> + u32 hctl;
> + u32 sysctl;
> + u32 ie;
> + u32 ise;
> +};
> +
> +static struct omap3_hsmmc_regs hsmmc_context[ARRAY_SIZE(instances)];
> +
> +static void hsmmc_write_reg(int id, int idx, u32 val)
> +{
> + __raw_writel(val, instances[id] + idx);
> +}
> +
> +static u32 hsmmc_read_reg(int id, int idx)
> +{
> + return 0;//__raw_readl(instances[id] + idx);
> +}
> +
> +void omap3_hsmmc_save_context(void)
> +{
> + int i;
> + for (i = 0; i < ARRAY_SIZE(instances); i++) {
> + hsmmc_context[i].sysconfig = hsmmc_read_reg(i,
> HSMMC_SYSCONFIG);
> + hsmmc_context[i].con = hsmmc_read_reg(i, HSMMC_CON);
> + hsmmc_context[i].hctl = hsmmc_read_reg(i, HSMMC_HCTL);
> + hsmmc_context[i].sysctl = hsmmc_read_reg(i, HSMMC_SYSCTL);
> + hsmmc_context[i].ie = hsmmc_read_reg(i, HSMMC_IE);
> + hsmmc_context[i].ise = hsmmc_read_reg(i, HSMMC_ISE);
> + }
> +}
> +
> +void omap3_hsmmc_restore_context(void)
> +{
> + int i;
> + for (i = 0; i < ARRAY_SIZE(instances); i++) {
> + hsmmc_write_reg(i, HSMMC_SYSCONFIG,
> hsmmc_context[i].sysconfig);
> + hsmmc_write_reg(i, HSMMC_CON, hsmmc_context[i].con);
> + hsmmc_write_reg(i, HSMMC_HCTL, hsmmc_context[i].hctl);
> + hsmmc_write_reg(i, HSMMC_SYSCTL, hsmmc_context[i].sysctl);
> + hsmmc_write_reg(i, HSMMC_IE, hsmmc_context[i].ie);
> + hsmmc_write_reg(i, HSMMC_ISE, hsmmc_context[i].ise);
> + }
> +}
> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
> index 7474cfa..b2393c5 100644
> --- a/arch/arm/mach-omap2/pm34xx.c
> +++ b/arch/arm/mach-omap2/pm34xx.c
> @@ -41,6 +41,7 @@
> #include <mach/sdrc.h>
> #include <mach/dma.h>
> #include <mach/gpmc.h>
> +#include <mach/hsmmc.h>
> #include <mach/dma.h>
> #include <asm/tlbflush.h>
>
> @@ -148,6 +149,8 @@ static void omap3_core_save_context(void)
> omap3_intc_save_context();
> /* Save the GPMC context */
> omap3_gpmc_save_context();
> + /* Save the HSMMC context */
> + omap3_hsmmc_save_context();
> /* Save the system control module context, padconf already save above*/
> omap3_control_save_context();
> omap_dma_global_context_save();
> @@ -159,6 +162,8 @@ static void omap3_core_restore_context(void)
> omap3_control_restore_context();
> /* Restore the GPMC context */
> omap3_gpmc_restore_context();
> + /* Restore the HSMMC context */
> + omap3_hsmmc_restore_context();
> /* Restore the interrupt controller context */
> omap3_intc_restore_context();
> omap_dma_global_context_restore();
> diff --git a/arch/arm/plat-omap/include/mach/hsmmc.h
> b/arch/arm/plat-omap/include/mach/hsmmc.h
> new file mode 100644
> index 0000000..ae3caee
> --- /dev/null
> +++ b/arch/arm/plat-omap/include/mach/hsmmc.h
> @@ -0,0 +1,15 @@
> +/*
> + * HSMMC save/restore logic for OMAP3
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __OMAP3_HSMMC_H
> +#define __OMAP3_HSMMC_H
> +
> +extern void omap3_hsmmc_save_context(void);
> +extern void omap3_hsmmc_restore_context(void);
> +
> +#endif
> --
> 1.6.0.4
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html