Re: [RFC] Save HSMMC registers if core is powered off

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Apr 11, 2009 at 12:32 AM, Russ Dill <russ.dill@xxxxxxxxx> 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux