* [RFC] Generic CPU save/restore PM support
@ 2011-02-06 19:11 Russell King - ARM Linux
2011-02-06 19:12 ` [PATCH 1/5] ARM: move cache/processor/fault glue to separate include files Russell King - ARM Linux
` (5 more replies)
0 siblings, 6 replies; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-06 19:11 UTC (permalink / raw)
To: linux-arm-kernel
The following patch series implements infrastructure to save/restore
CPU state on suspend/resume PM events, and updates SA11x0, PXA and
Samsung platforms to use this.
Not all CPU support files are updated with the necessary changes -
currently only ARM920, ARM926, SA11x0, XScale, XScale3, V6 and V7
CPUs are supported.
I've build-tested this for Assabet, PXA, and S3C2410, but not boot
tested it yet.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 1/5] ARM: move cache/processor/fault glue to separate include files
2011-02-06 19:11 [RFC] Generic CPU save/restore PM support Russell King - ARM Linux
@ 2011-02-06 19:12 ` Russell King - ARM Linux
2011-02-06 19:12 ` [PATCH 2/5] ARM: pm: add generic CPU suspend/resume support Russell King - ARM Linux
` (4 subsequent siblings)
5 siblings, 0 replies; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-06 19:12 UTC (permalink / raw)
To: linux-arm-kernel
This allows the cache/processor/fault glue to be more easily used
from assembler code.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/include/asm/cacheflush.h | 133 +----------------
arch/arm/include/asm/cpu-multi32.h | 69 --------
arch/arm/include/asm/cpu-single.h | 44 ------
arch/arm/include/asm/glue-cache.h | 146 ++++++++++++++++++
arch/arm/include/asm/glue-df.h | 110 +++++++++++++
arch/arm/include/asm/glue-pf.h | 57 +++++++
arch/arm/include/asm/glue-proc.h | 261 +++++++++++++++++++++++++++++++
arch/arm/include/asm/glue.h | 138 -----------------
arch/arm/include/asm/proc-fns.h | 299 ++++++++----------------------------
arch/arm/kernel/asm-offsets.c | 2 +
arch/arm/kernel/entry-armv.S | 3 +-
11 files changed, 644 insertions(+), 618 deletions(-)
delete mode 100644 arch/arm/include/asm/cpu-multi32.h
delete mode 100644 arch/arm/include/asm/cpu-single.h
create mode 100644 arch/arm/include/asm/glue-cache.h
create mode 100644 arch/arm/include/asm/glue-df.h
create mode 100644 arch/arm/include/asm/glue-pf.h
create mode 100644 arch/arm/include/asm/glue-proc.h
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 3acd8fa..18a5664 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -12,7 +12,7 @@
#include <linux/mm.h>
-#include <asm/glue.h>
+#include <asm/glue-cache.h>
#include <asm/shmparam.h>
#include <asm/cachetype.h>
#include <asm/outercache.h>
@@ -20,123 +20,6 @@
#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
/*
- * Cache Model
- * ===========
- */
-#undef _CACHE
-#undef MULTI_CACHE
-
-#if defined(CONFIG_CPU_CACHE_V3)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE v3
-# endif
-#endif
-
-#if defined(CONFIG_CPU_CACHE_V4)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE v4
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
- defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \
- defined(CONFIG_CPU_ARM1026)
-# define MULTI_CACHE 1
-#endif
-
-#if defined(CONFIG_CPU_FA526)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE fa
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM926T)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE arm926
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM940T)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE arm940
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM946E)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE arm946
-# endif
-#endif
-
-#if defined(CONFIG_CPU_CACHE_V4WB)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE v4wb
-# endif
-#endif
-
-#if defined(CONFIG_CPU_XSCALE)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE xscale
-# endif
-#endif
-
-#if defined(CONFIG_CPU_XSC3)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE xsc3
-# endif
-#endif
-
-#if defined(CONFIG_CPU_MOHAWK)
-# ifdef _CACHE
-# define MULTI_CACHE 1
-# else
-# define _CACHE mohawk
-# endif
-#endif
-
-#if defined(CONFIG_CPU_FEROCEON)
-# define MULTI_CACHE 1
-#endif
-
-#if defined(CONFIG_CPU_V6)
-//# ifdef _CACHE
-# define MULTI_CACHE 1
-//# else
-//# define _CACHE v6
-//# endif
-#endif
-
-#if defined(CONFIG_CPU_V7)
-//# ifdef _CACHE
-# define MULTI_CACHE 1
-//# else
-//# define _CACHE v7
-//# endif
-#endif
-
-#if !defined(_CACHE) && !defined(MULTI_CACHE)
-#error Unknown cache maintainence model
-#endif
-
-/*
* This flag is used to indicate that the page pointed to by a pte is clean
* and does not require cleaning before returning it to the user.
*/
@@ -249,19 +132,11 @@ extern struct cpu_cache_fns cpu_cache;
* visible to the CPU.
*/
#define dmac_map_area cpu_cache.dma_map_area
-#define dmac_unmap_area cpu_cache.dma_unmap_area
+#define dmac_unmap_area cpu_cache.dma_unmap_area
#define dmac_flush_range cpu_cache.dma_flush_range
#else
-#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
-#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
-#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
-#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
-#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
-#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
-#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area)
-
extern void __cpuc_flush_icache_all(void);
extern void __cpuc_flush_kern_all(void);
extern void __cpuc_flush_user_all(void);
@@ -276,10 +151,6 @@ extern void __cpuc_flush_dcache_area(void *, size_t);
* is visible to DMA, or data written by DMA to system memory is
* visible to the CPU.
*/
-#define dmac_map_area __glue(_CACHE,_dma_map_area)
-#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area)
-#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
-
extern void dmac_map_area(const void *, size_t, int);
extern void dmac_unmap_area(const void *, size_t, int);
extern void dmac_flush_range(const void *, const void *);
diff --git a/arch/arm/include/asm/cpu-multi32.h b/arch/arm/include/asm/cpu-multi32.h
deleted file mode 100644
index e2b5b0b..0000000
--- a/arch/arm/include/asm/cpu-multi32.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * arch/arm/include/asm/cpu-multi32.h
- *
- * Copyright (C) 2000 Russell King
- *
- * 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 <asm/page.h>
-
-struct mm_struct;
-
-/*
- * Don't change this structure - ASM code
- * relies on it.
- */
-extern struct processor {
- /* MISC
- * get data abort address/flags
- */
- void (*_data_abort)(unsigned long pc);
- /*
- * Retrieve prefetch fault address
- */
- unsigned long (*_prefetch_abort)(unsigned long lr);
- /*
- * Set up any processor specifics
- */
- void (*_proc_init)(void);
- /*
- * Disable any processor specifics
- */
- void (*_proc_fin)(void);
- /*
- * Special stuff for a reset
- */
- void (*reset)(unsigned long addr) __attribute__((noreturn));
- /*
- * Idle the processor
- */
- int (*_do_idle)(void);
- /*
- * Processor architecture specific
- */
- /*
- * clean a virtual address range from the
- * D-cache without flushing the cache.
- */
- void (*dcache_clean_area)(void *addr, int size);
-
- /*
- * Set the page table
- */
- void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
- /*
- * Set a possibly extended PTE. Non-extended PTEs should
- * ignore 'ext'.
- */
- void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
-} processor;
-
-#define cpu_proc_init() processor._proc_init()
-#define cpu_proc_fin() processor._proc_fin()
-#define cpu_reset(addr) processor.reset(addr)
-#define cpu_do_idle() processor._do_idle()
-#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
-#define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext)
-#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
diff --git a/arch/arm/include/asm/cpu-single.h b/arch/arm/include/asm/cpu-single.h
deleted file mode 100644
index f073a6d..0000000
--- a/arch/arm/include/asm/cpu-single.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * arch/arm/include/asm/cpu-single.h
- *
- * Copyright (C) 2000 Russell King
- *
- * 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.
- */
-/*
- * Single CPU
- */
-#ifdef __STDC__
-#define __catify_fn(name,x) name##x
-#else
-#define __catify_fn(name,x) name/**/x
-#endif
-#define __cpu_fn(name,x) __catify_fn(name,x)
-
-/*
- * If we are supporting multiple CPUs, then we must use a table of
- * function pointers for this lot. Otherwise, we can optimise the
- * table away.
- */
-#define cpu_proc_init __cpu_fn(CPU_NAME,_proc_init)
-#define cpu_proc_fin __cpu_fn(CPU_NAME,_proc_fin)
-#define cpu_reset __cpu_fn(CPU_NAME,_reset)
-#define cpu_do_idle __cpu_fn(CPU_NAME,_do_idle)
-#define cpu_dcache_clean_area __cpu_fn(CPU_NAME,_dcache_clean_area)
-#define cpu_do_switch_mm __cpu_fn(CPU_NAME,_switch_mm)
-#define cpu_set_pte_ext __cpu_fn(CPU_NAME,_set_pte_ext)
-
-#include <asm/page.h>
-
-struct mm_struct;
-
-/* declare all the functions as extern */
-extern void cpu_proc_init(void);
-extern void cpu_proc_fin(void);
-extern int cpu_do_idle(void);
-extern void cpu_dcache_clean_area(void *, int);
-extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
-extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
-extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
new file mode 100644
index 0000000..0591d35
--- /dev/null
+++ b/arch/arm/include/asm/glue-cache.h
@@ -0,0 +1,146 @@
+/*
+ * arch/arm/include/asm/glue-cache.h
+ *
+ * Copyright (C) 1999-2002 Russell King
+ *
+ * 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 ASM_GLUE_CACHE_H
+#define ASM_GLUE_CACHE_H
+
+#include <asm/glue.h>
+
+/*
+ * Cache Model
+ * ===========
+ */
+#undef _CACHE
+#undef MULTI_CACHE
+
+#if defined(CONFIG_CPU_CACHE_V3)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE v3
+# endif
+#endif
+
+#if defined(CONFIG_CPU_CACHE_V4)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE v4
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+ defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \
+ defined(CONFIG_CPU_ARM1026)
+# define MULTI_CACHE 1
+#endif
+
+#if defined(CONFIG_CPU_FA526)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE fa
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM926T)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE arm926
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM940T)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE arm940
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM946E)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE arm946
+# endif
+#endif
+
+#if defined(CONFIG_CPU_CACHE_V4WB)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE v4wb
+# endif
+#endif
+
+#if defined(CONFIG_CPU_XSCALE)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE xscale
+# endif
+#endif
+
+#if defined(CONFIG_CPU_XSC3)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE xsc3
+# endif
+#endif
+
+#if defined(CONFIG_CPU_MOHAWK)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE mohawk
+# endif
+#endif
+
+#if defined(CONFIG_CPU_FEROCEON)
+# define MULTI_CACHE 1
+#endif
+
+#if defined(CONFIG_CPU_V6)
+//# ifdef _CACHE
+# define MULTI_CACHE 1
+//# else
+//# define _CACHE v6
+//# endif
+#endif
+
+#if defined(CONFIG_CPU_V7)
+//# ifdef _CACHE
+# define MULTI_CACHE 1
+//# else
+//# define _CACHE v7
+//# endif
+#endif
+
+#if !defined(_CACHE) && !defined(MULTI_CACHE)
+#error Unknown cache maintainence model
+#endif
+
+#ifndef MULTI_CACHE
+#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
+#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
+#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
+#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
+#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
+#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
+#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area)
+
+#define dmac_map_area __glue(_CACHE,_dma_map_area)
+#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area)
+#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue-df.h b/arch/arm/include/asm/glue-df.h
new file mode 100644
index 0000000..354d571
--- /dev/null
+++ b/arch/arm/include/asm/glue-df.h
@@ -0,0 +1,110 @@
+/*
+ * arch/arm/include/asm/glue-df.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2000-2002 Deep Blue Solutions Ltd.
+ *
+ * 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 ASM_GLUE_DF_H
+#define ASM_GLUE_DF_H
+
+#include <asm/glue.h>
+
+/*
+ * Data Abort Model
+ * ================
+ *
+ * We have the following to choose from:
+ * arm6 - ARM6 style
+ * arm7 - ARM7 style
+ * v4_early - ARMv4 without Thumb early abort handler
+ * v4t_late - ARMv4 with Thumb late abort handler
+ * v4t_early - ARMv4 with Thumb early abort handler
+ * v5tej_early - ARMv5 with Thumb and Java early abort handler
+ * xscale - ARMv5 with Thumb with Xscale extensions
+ * v6_early - ARMv6 generic early abort handler
+ * v7_early - ARMv7 generic early abort handler
+ */
+#undef CPU_DABORT_HANDLER
+#undef MULTI_DABORT
+
+#if defined(CONFIG_CPU_ARM610)
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER cpu_arm6_data_abort
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM710)
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER cpu_arm7_data_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_LV4T
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v4t_late_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV4
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v4_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV4T
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v4t_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV5TJ
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v5tj_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV5T
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v5t_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV6
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v6_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV7
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v7_early_abort
+# endif
+#endif
+
+#ifndef CPU_DABORT_HANDLER
+#error Unknown data abort handler type
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue-pf.h b/arch/arm/include/asm/glue-pf.h
new file mode 100644
index 0000000..d385f37
--- /dev/null
+++ b/arch/arm/include/asm/glue-pf.h
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/include/asm/glue-pf.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2000-2002 Deep Blue Solutions Ltd.
+ *
+ * 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 ASM_GLUE_PF_H
+#define ASM_GLUE_PF_H
+
+#include <asm/glue.h>
+
+/*
+ * Prefetch Abort Model
+ * ================
+ *
+ * We have the following to choose from:
+ * legacy - no IFSR, no IFAR
+ * v6 - ARMv6: IFSR, no IFAR
+ * v7 - ARMv7: IFSR and IFAR
+ */
+
+#undef CPU_PABORT_HANDLER
+#undef MULTI_PABORT
+
+#ifdef CONFIG_CPU_PABRT_LEGACY
+# ifdef CPU_PABORT_HANDLER
+# define MULTI_PABORT 1
+# else
+# define CPU_PABORT_HANDLER legacy_pabort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PABRT_V6
+# ifdef CPU_PABORT_HANDLER
+# define MULTI_PABORT 1
+# else
+# define CPU_PABORT_HANDLER v6_pabort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PABRT_V7
+# ifdef CPU_PABORT_HANDLER
+# define MULTI_PABORT 1
+# else
+# define CPU_PABORT_HANDLER v7_pabort
+# endif
+#endif
+
+#ifndef CPU_PABORT_HANDLER
+#error Unknown prefetch abort handler type
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
new file mode 100644
index 0000000..e3bf443
--- /dev/null
+++ b/arch/arm/include/asm/glue-proc.h
@@ -0,0 +1,261 @@
+/*
+ * arch/arm/include/asm/glue-proc.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * 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 ASM_GLUE_PROC_H
+#define ASM_GLUE_PROC_H
+
+#include <asm/glue.h>
+
+/*
+ * Work out if we need multiple CPU support
+ */
+#undef MULTI_CPU
+#undef CPU_NAME
+
+/*
+ * CPU_NAME - the prefix for CPU related functions
+ */
+
+#ifdef CONFIG_CPU_ARM610
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm6
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM7TDMI
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm7tdmi
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM710
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm7
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM720T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm720
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM740T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm740
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM9TDMI
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm9tdmi
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM920T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm920
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM922T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm922
+# endif
+#endif
+
+#ifdef CONFIG_CPU_FA526
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_fa526
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM925T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm925
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM926T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm926
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM940T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm940
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM946E
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm946
+# endif
+#endif
+
+#ifdef CONFIG_CPU_SA110
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_sa110
+# endif
+#endif
+
+#ifdef CONFIG_CPU_SA1100
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_sa1100
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1020
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm1020
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1020E
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm1020e
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1022
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm1022
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1026
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm1026
+# endif
+#endif
+
+#ifdef CONFIG_CPU_XSCALE
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_xscale
+# endif
+#endif
+
+#ifdef CONFIG_CPU_XSC3
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_xsc3
+# endif
+#endif
+
+#ifdef CONFIG_CPU_MOHAWK
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_mohawk
+# endif
+#endif
+
+#ifdef CONFIG_CPU_FEROCEON
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_feroceon
+# endif
+#endif
+
+#ifdef CONFIG_CPU_V6
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_v6
+# endif
+#endif
+
+#ifdef CONFIG_CPU_V7
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_v7
+# endif
+#endif
+
+#ifndef MULTI_CPU
+#define cpu_proc_init __glue(CPU_NAME,_proc_init)
+#define cpu_proc_fin __glue(CPU_NAME,_proc_fin)
+#define cpu_reset __glue(CPU_NAME,_reset)
+#define cpu_do_idle __glue(CPU_NAME,_do_idle)
+#define cpu_dcache_clean_area __glue(CPU_NAME,_dcache_clean_area)
+#define cpu_do_switch_mm __glue(CPU_NAME,_switch_mm)
+#define cpu_set_pte_ext __glue(CPU_NAME,_set_pte_ext)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h
index 234a3fc..0ec35d1 100644
--- a/arch/arm/include/asm/glue.h
+++ b/arch/arm/include/asm/glue.h
@@ -15,7 +15,6 @@
*/
#ifdef __KERNEL__
-
#ifdef __STDC__
#define ____glue(name,fn) name##fn
#else
@@ -23,141 +22,4 @@
#endif
#define __glue(name,fn) ____glue(name,fn)
-
-
-/*
- * Data Abort Model
- * ================
- *
- * We have the following to choose from:
- * arm6 - ARM6 style
- * arm7 - ARM7 style
- * v4_early - ARMv4 without Thumb early abort handler
- * v4t_late - ARMv4 with Thumb late abort handler
- * v4t_early - ARMv4 with Thumb early abort handler
- * v5tej_early - ARMv5 with Thumb and Java early abort handler
- * xscale - ARMv5 with Thumb with Xscale extensions
- * v6_early - ARMv6 generic early abort handler
- * v7_early - ARMv7 generic early abort handler
- */
-#undef CPU_DABORT_HANDLER
-#undef MULTI_DABORT
-
-#if defined(CONFIG_CPU_ARM610)
-# ifdef CPU_DABORT_HANDLER
-# define MULTI_DABORT 1
-# else
-# define CPU_DABORT_HANDLER cpu_arm6_data_abort
-# endif
-#endif
-
-#if defined(CONFIG_CPU_ARM710)
-# ifdef CPU_DABORT_HANDLER
-# define MULTI_DABORT 1
-# else
-# define CPU_DABORT_HANDLER cpu_arm7_data_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_LV4T
-# ifdef CPU_DABORT_HANDLER
-# define MULTI_DABORT 1
-# else
-# define CPU_DABORT_HANDLER v4t_late_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV4
-# ifdef CPU_DABORT_HANDLER
-# define MULTI_DABORT 1
-# else
-# define CPU_DABORT_HANDLER v4_early_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV4T
-# ifdef CPU_DABORT_HANDLER
-# define MULTI_DABORT 1
-# else
-# define CPU_DABORT_HANDLER v4t_early_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV5TJ
-# ifdef CPU_DABORT_HANDLER
-# define MULTI_DABORT 1
-# else
-# define CPU_DABORT_HANDLER v5tj_early_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV5T
-# ifdef CPU_DABORT_HANDLER
-# define MULTI_DABORT 1
-# else
-# define CPU_DABORT_HANDLER v5t_early_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV6
-# ifdef CPU_DABORT_HANDLER
-# define MULTI_DABORT 1
-# else
-# define CPU_DABORT_HANDLER v6_early_abort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ABRT_EV7
-# ifdef CPU_DABORT_HANDLER
-# define MULTI_DABORT 1
-# else
-# define CPU_DABORT_HANDLER v7_early_abort
-# endif
-#endif
-
-#ifndef CPU_DABORT_HANDLER
-#error Unknown data abort handler type
-#endif
-
-/*
- * Prefetch Abort Model
- * ================
- *
- * We have the following to choose from:
- * legacy - no IFSR, no IFAR
- * v6 - ARMv6: IFSR, no IFAR
- * v7 - ARMv7: IFSR and IFAR
- */
-
-#undef CPU_PABORT_HANDLER
-#undef MULTI_PABORT
-
-#ifdef CONFIG_CPU_PABRT_LEGACY
-# ifdef CPU_PABORT_HANDLER
-# define MULTI_PABORT 1
-# else
-# define CPU_PABORT_HANDLER legacy_pabort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_PABRT_V6
-# ifdef CPU_PABORT_HANDLER
-# define MULTI_PABORT 1
-# else
-# define CPU_PABORT_HANDLER v6_pabort
-# endif
-#endif
-
-#ifdef CONFIG_CPU_PABRT_V7
-# ifdef CPU_PABORT_HANDLER
-# define MULTI_PABORT 1
-# else
-# define CPU_PABORT_HANDLER v7_pabort
-# endif
-#endif
-
-#ifndef CPU_PABORT_HANDLER
-#error Unknown prefetch abort handler type
-#endif
-
#endif
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 8fdae9b..6980215 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -13,248 +13,77 @@
#ifdef __KERNEL__
+#include <asm/glue-proc.h>
+#include <asm/page.h>
-/*
- * Work out if we need multiple CPU support
- */
-#undef MULTI_CPU
-#undef CPU_NAME
+#ifndef __ASSEMBLY__
+
+struct mm_struct;
/*
- * CPU_NAME - the prefix for CPU related functions
+ * Don't change this structure - ASM code relies on it.
*/
-
-#ifdef CONFIG_CPU_ARM610
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm6
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM7TDMI
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm7tdmi
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM710
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm7
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM720T
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm720
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM740T
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm740
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM9TDMI
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm9tdmi
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM920T
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm920
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM922T
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm922
-# endif
-#endif
-
-#ifdef CONFIG_CPU_FA526
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_fa526
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM925T
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm925
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM926T
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm926
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM940T
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm940
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM946E
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm946
-# endif
-#endif
-
-#ifdef CONFIG_CPU_SA110
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_sa110
-# endif
-#endif
-
-#ifdef CONFIG_CPU_SA1100
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_sa1100
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM1020
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm1020
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM1020E
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm1020e
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM1022
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm1022
-# endif
-#endif
-
-#ifdef CONFIG_CPU_ARM1026
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_arm1026
-# endif
-#endif
-
-#ifdef CONFIG_CPU_XSCALE
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_xscale
-# endif
-#endif
-
-#ifdef CONFIG_CPU_XSC3
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_xsc3
-# endif
-#endif
-
-#ifdef CONFIG_CPU_MOHAWK
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_mohawk
-# endif
-#endif
-
-#ifdef CONFIG_CPU_FEROCEON
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_feroceon
-# endif
-#endif
-
-#ifdef CONFIG_CPU_V6
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_v6
-# endif
-#endif
-
-#ifdef CONFIG_CPU_V7
-# ifdef CPU_NAME
-# undef MULTI_CPU
-# define MULTI_CPU
-# else
-# define CPU_NAME cpu_v7
-# endif
-#endif
-
-#ifndef __ASSEMBLY__
+extern struct processor {
+ /* MISC
+ * get data abort address/flags
+ */
+ void (*_data_abort)(unsigned long pc);
+ /*
+ * Retrieve prefetch fault address
+ */
+ unsigned long (*_prefetch_abort)(unsigned long lr);
+ /*
+ * Set up any processor specifics
+ */
+ void (*_proc_init)(void);
+ /*
+ * Disable any processor specifics
+ */
+ void (*_proc_fin)(void);
+ /*
+ * Special stuff for a reset
+ */
+ void (*reset)(unsigned long addr) __attribute__((noreturn));
+ /*
+ * Idle the processor
+ */
+ int (*_do_idle)(void);
+ /*
+ * Processor architecture specific
+ */
+ /*
+ * clean a virtual address range from the
+ * D-cache without flushing the cache.
+ */
+ void (*dcache_clean_area)(void *addr, int size);
+
+ /*
+ * Set the page table
+ */
+ void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
+ /*
+ * Set a possibly extended PTE. Non-extended PTEs should
+ * ignore 'ext'.
+ */
+ void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
+} processor;
#ifndef MULTI_CPU
-#include <asm/cpu-single.h>
+extern void cpu_proc_init(void);
+extern void cpu_proc_fin(void);
+extern int cpu_do_idle(void);
+extern void cpu_dcache_clean_area(void *, int);
+extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
+extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
#else
-#include <asm/cpu-multi32.h>
+#define cpu_proc_init() processor._proc_init()
+#define cpu_proc_fin() processor._proc_fin()
+#define cpu_reset(addr) processor.reset(addr)
+#define cpu_do_idle() processor._do_idle()
+#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
+#define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext)
+#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
#endif
#include <asm/memory.h>
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 82da661..5302a91 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -13,6 +13,8 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
+#include <asm/glue-df.h>
+#include <asm/glue-pf.h>
#include <asm/mach/arch.h>
#include <asm/thread_info.h>
#include <asm/memory.h>
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 2b46fea..e8d8856 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -16,7 +16,8 @@
*/
#include <asm/memory.h>
-#include <asm/glue.h>
+#include <asm/glue-df.h>
+#include <asm/glue-pf.h>
#include <asm/vfpmacros.h>
#include <mach/entry-macro.S>
#include <asm/thread_notify.h>
--
1.6.2.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-06 19:11 [RFC] Generic CPU save/restore PM support Russell King - ARM Linux
2011-02-06 19:12 ` [PATCH 1/5] ARM: move cache/processor/fault glue to separate include files Russell King - ARM Linux
@ 2011-02-06 19:12 ` Russell King - ARM Linux
2011-02-07 12:01 ` [PATCH v2 " Russell King - ARM Linux
2011-02-06 19:13 ` [PATCH 3/5] ARM: pm: convert PXA to generic " Russell King - ARM Linux
` (3 subsequent siblings)
5 siblings, 1 reply; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-06 19:12 UTC (permalink / raw)
To: linux-arm-kernel
This adds core support for saving and restoring CPU coprocessor
registers for suspend/resume support. This contains support for suspend
with ARM920, ARM926, SA11x0, PXA25x, PXA27x, PXA3xx and V6 CPUs.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/include/asm/glue-proc.h | 3 +
arch/arm/include/asm/proc-fns.h | 7 ++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/asm-offsets.c | 9 +++
arch/arm/kernel/sleep.S | 76 +++++++++++++++++++++++
arch/arm/mm/proc-arm1020.S | 3 +
arch/arm/mm/proc-arm1020e.S | 3 +
arch/arm/mm/proc-arm1022.S | 3 +
arch/arm/mm/proc-arm1026.S | 3 +
arch/arm/mm/proc-arm6_7.S | 6 ++
arch/arm/mm/proc-arm720.S | 3 +
arch/arm/mm/proc-arm740.S | 3 +
arch/arm/mm/proc-arm7tdmi.S | 3 +
arch/arm/mm/proc-arm920.S | 34 ++++++++++
arch/arm/mm/proc-arm922.S | 3 +
arch/arm/mm/proc-arm925.S | 3 +
arch/arm/mm/proc-arm926.S | 34 ++++++++++
arch/arm/mm/proc-arm940.S | 3 +
arch/arm/mm/proc-arm946.S | 3 +
arch/arm/mm/proc-arm9tdmi.S | 3 +
arch/arm/mm/proc-fa526.S | 3 +
arch/arm/mm/proc-feroceon.S | 3 +
arch/arm/mm/proc-mohawk.S | 3 +
arch/arm/mm/proc-sa110.S | 3 +
arch/arm/mm/proc-sa1100.S | 43 +++++++++++++
arch/arm/mm/proc-v6.S | 43 +++++++++++++
arch/arm/mm/proc-v7.S | 124 ++++++++++++++++++++++++++++---------
arch/arm/mm/proc-xsc3.S | 78 +++++++++++++++++++++++-
arch/arm/mm/proc-xscale.S | 51 +++++++++++++++-
29 files changed, 524 insertions(+), 33 deletions(-)
create mode 100644 arch/arm/kernel/sleep.S
diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
index e3bf443..6469521 100644
--- a/arch/arm/include/asm/glue-proc.h
+++ b/arch/arm/include/asm/glue-proc.h
@@ -256,6 +256,9 @@
#define cpu_dcache_clean_area __glue(CPU_NAME,_dcache_clean_area)
#define cpu_do_switch_mm __glue(CPU_NAME,_switch_mm)
#define cpu_set_pte_ext __glue(CPU_NAME,_set_pte_ext)
+#define cpu_suspend_size __glue(CPU_NAME,_suspend_size)
+#define cpu_do_suspend __glue(CPU_NAME,_do_suspend)
+#define cpu_do_resume __glue(CPU_NAME,_do_resume)
#endif
#endif
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 6980215..8ec535e 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -66,6 +66,11 @@ extern struct processor {
* ignore 'ext'.
*/
void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
+
+ /* Suspend/resume */
+ unsigned int suspend_size;
+ void (*do_suspend)(void *);
+ void (*do_resume)(void *);
} processor;
#ifndef MULTI_CPU
@@ -86,6 +91,8 @@ extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
#endif
+extern void cpu_resume(void);
+
#include <asm/memory.h>
#ifdef CONFIG_MMU
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 185ee82..74554f1 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o isa.o
+obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 5302a91..927522c 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
#include <asm/glue-df.h>
#include <asm/glue-pf.h>
#include <asm/mach/arch.h>
@@ -116,6 +117,14 @@ int main(void)
#ifdef MULTI_PABORT
DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort));
#endif
+#ifdef MULTI_CPU
+ DEFINE(CPU_SLEEP_SIZE, offsetof(struct processor, suspend_size));
+ DEFINE(CPU_DO_SUSPEND, offsetof(struct processor, do_suspend));
+ DEFINE(CPU_DO_RESUME, offsetof(struct processor, do_resume));
+#endif
+#ifdef MULTI_CACHE
+ DEFINE(CACHE_FLUSH_KERN_ALL, offsetof(struct cpu_cache_fns, flush_kern_all));
+#endif
BLANK();
DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
new file mode 100644
index 0000000..02c9d83
--- /dev/null
+++ b/arch/arm/kernel/sleep.S
@@ -0,0 +1,76 @@
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+#include <asm/glue-cache.h>
+#include <asm/glue-proc.h>
+ .text
+
+/*
+ * Save CPU state for a suspend
+ * r1 = v:p offset
+ * r3 = virtual return function
+ * Note: sp is decremented to allocate space for CPU state on stack
+ * r0-r3,r9,r10,lr corrupted
+ */
+ENTRY(cpu_suspend)
+ mov r9, lr
+#ifdef MULTI_CPU
+ ldr r10, =processor
+ mov r2, sp @ current virtual SP
+ ldr r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+ ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
+ sub sp, sp, r0 @ allocate CPU state on stack
+ mov r0, sp @ save pointer
+ add ip, ip, r1 @ convert resume fn to phys
+ stmfd sp!, {r2, r3, ip} @ save virt SP + phys resume fn
+ ldr r3, =sleep_save_sp
+ add r2, sp, r1 @ convert SP to phys
+ str r2, [r3] @ save phys SP
+ mov lr, pc
+ ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
+#else
+ mov r2, sp @ current virtual SP
+ ldr r0, =cpu_suspend_size
+ sub sp, sp, r0 @ allocate CPU state on stack
+ mov r0, sp @ save pointer
+ stmfd sp!, {r2, r3}
+ ldr r3, =sleep_save_sp
+ add r2, sp, r1 @ convert SP to phys
+ str r2, [r3] @ save phys SP
+ bl cpu_do_suspend
+#endif
+
+ @ clean data cache
+#ifdef MULTI_CACHE
+ ldr r10, =cpu_cache
+ mov lr, r9
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ mov lr, r9
+ b __cpuc_flush_kern_all
+#endif
+ENDPROC(cpu_suspend)
+ .ltorg
+
+/*
+ * Note: Yes, part of the following code is located into the .data section.
+ * This is to allow sleep_save_sp to be accessed with a relative load
+ * while we can't rely on any MMU translation. We could have put
+ * sleep_save_sp in the .text section as well, but some setups might
+ * insist on it to be truly read-only.
+ */
+ .data
+ .align
+ENTRY(cpu_resume)
+ ldr r0, sleep_save_sp @ stack phys addr
+ msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
+#ifdef MULTI_CPU
+ ldmia r0!, {sp, lr, pc} @ load stack + return fn + resume fn
+#else
+ ldmia r0!, {sp, lr} @ load stack + return fn
+ b cpu_do_resume
+#endif
+ENDPROC(cpu_resume)
+
+sleep_save_sp:
+ .word 0 @ preserve stack phys ptr here
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index bcf748d..226e3d8 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -493,6 +493,9 @@ arm1020_processor_functions:
.word cpu_arm1020_dcache_clean_area
.word cpu_arm1020_switch_mm
.word cpu_arm1020_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1020_processor_functions, . - arm1020_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index ab7ec26..86d9c2c 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -474,6 +474,9 @@ arm1020e_processor_functions:
.word cpu_arm1020e_dcache_clean_area
.word cpu_arm1020e_switch_mm
.word cpu_arm1020e_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1020e_processor_functions, . - arm1020e_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 831c5e5..83d3dd3 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -457,6 +457,9 @@ arm1022_processor_functions:
.word cpu_arm1022_dcache_clean_area
.word cpu_arm1022_switch_mm
.word cpu_arm1022_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1022_processor_functions, . - arm1022_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index e3f7e9a..686043e 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -452,6 +452,9 @@ arm1026_processor_functions:
.word cpu_arm1026_dcache_clean_area
.word cpu_arm1026_switch_mm
.word cpu_arm1026_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1026_processor_functions, . - arm1026_processor_functions
.section .rodata
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 6a7be18..5f79dc4 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -284,6 +284,9 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_dcache_clean_area
.word cpu_arm6_switch_mm
.word cpu_arm6_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm6_processor_functions, . - arm6_processor_functions
/*
@@ -301,6 +304,9 @@ ENTRY(arm7_processor_functions)
.word cpu_arm7_dcache_clean_area
.word cpu_arm7_switch_mm
.word cpu_arm7_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm7_processor_functions, . - arm7_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index c285395..665266d 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -185,6 +185,9 @@ ENTRY(arm720_processor_functions)
.word cpu_arm720_dcache_clean_area
.word cpu_arm720_switch_mm
.word cpu_arm720_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm720_processor_functions, . - arm720_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 38b27dc..6f9d12e 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -130,6 +130,9 @@ ENTRY(arm740_processor_functions)
.word cpu_arm740_dcache_clean_area
.word cpu_arm740_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm740_processor_functions, . - arm740_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 0c9786d..e4c165c 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -70,6 +70,9 @@ ENTRY(arm7tdmi_processor_functions)
.word cpu_arm7tdmi_dcache_clean_area
.word cpu_arm7tdmi_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 6109f27..b5946ff 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -387,6 +387,37 @@ ENTRY(cpu_arm920_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl arm920_suspend_size
+.equ arm920_suspend_size, 4 * 3
+#ifdef CONFIG_PM
+ENTRY(arm920_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(arm920_do_suspend)
+
+ENTRY(arm920_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
+ ldmia r0, {r4 - r7}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mcr p15, 0, r7, c1, c0, 0 @ Control register
+ nop
+ mov pc, lr
+ENDPROC(arm920_do_resume)
+#else
+#define arm920_do_suspend 0
+#define arm920_do_resume 0
+#endif
+
__CPUINIT
.type __arm920_setup, #function
@@ -432,6 +463,9 @@ arm920_processor_functions:
.word cpu_arm920_dcache_clean_area
.word cpu_arm920_switch_mm
.word cpu_arm920_set_pte_ext
+ .word arm920_suspend_size
+ .word arm920_do_suspend
+ .word arm920_do_resume
.size arm920_processor_functions, . - arm920_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index bb2f0f4..36154b1 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -436,6 +436,9 @@ arm922_processor_functions:
.word cpu_arm922_dcache_clean_area
.word cpu_arm922_switch_mm
.word cpu_arm922_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm922_processor_functions, . - arm922_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index c13e01a..89c5e00 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -503,6 +503,9 @@ arm925_processor_functions:
.word cpu_arm925_dcache_clean_area
.word cpu_arm925_switch_mm
.word cpu_arm925_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm925_processor_functions, . - arm925_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 42eb431..97095e9 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -401,6 +401,37 @@ ENTRY(cpu_arm926_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl arm926_suspend_size
+.equ arm926_suspend_size, 4 * 3
+#ifdef CONFIG_PM
+ENTRY(arm926_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(arm926_do_suspend)
+
+ENTRY(arm926_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
+ ldmia r0, {r4 - r7}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mcr p15, 0, r7, c1, c0, 0 @ Control register
+ nop
+ mov pc, lr
+ENDPROC(arm926_do_resume)
+#else
+#define arm926_do_suspend 0
+#define arm926_do_resume 0
+#endif
+
__CPUINIT
.type __arm926_setup, #function
@@ -456,6 +487,9 @@ arm926_processor_functions:
.word cpu_arm926_dcache_clean_area
.word cpu_arm926_switch_mm
.word cpu_arm926_set_pte_ext
+ .word arm926_suspend_size
+ .word arm926_do_suspend
+ .word arm926_do_resume
.size arm926_processor_functions, . - arm926_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index 7b11cdb..26aea3f 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -363,6 +363,9 @@ ENTRY(arm940_processor_functions)
.word cpu_arm940_dcache_clean_area
.word cpu_arm940_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm940_processor_functions, . - arm940_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 1a5bbf0..8063345 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -419,6 +419,9 @@ ENTRY(arm946_processor_functions)
.word cpu_arm946_dcache_clean_area
.word cpu_arm946_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm946_processor_functions, . - arm946_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index db67e31..7b7ebd4 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -70,6 +70,9 @@ ENTRY(arm9tdmi_processor_functions)
.word cpu_arm9tdmi_dcache_clean_area
.word cpu_arm9tdmi_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 7c9ad62..fc2a4ae 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -195,6 +195,9 @@ fa526_processor_functions:
.word cpu_fa526_dcache_clean_area
.word cpu_fa526_switch_mm
.word cpu_fa526_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size fa526_processor_functions, . - fa526_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index b4597ed..d3883ee 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -554,6 +554,9 @@ feroceon_processor_functions:
.word cpu_feroceon_dcache_clean_area
.word cpu_feroceon_switch_mm
.word cpu_feroceon_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size feroceon_processor_functions, . - feroceon_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 4458ee6..9d4f2ae 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -388,6 +388,9 @@ mohawk_processor_functions:
.word cpu_mohawk_dcache_clean_area
.word cpu_mohawk_switch_mm
.word cpu_mohawk_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size mohawk_processor_functions, . - mohawk_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 5aa8d59..46f09ed 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -203,6 +203,9 @@ ENTRY(sa110_processor_functions)
.word cpu_sa110_dcache_clean_area
.word cpu_sa110_switch_mm
.word cpu_sa110_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size sa110_processor_functions, . - sa110_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 2ac4e6f..37e5361 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -169,6 +169,46 @@ ENTRY(cpu_sa1100_set_pte_ext)
#endif
mov pc, lr
+.globl cpu_sa1100_suspend_size
+.equ cpu_sa1100_suspend_size, 4*4
+#ifdef CONFIG_PM
+ENTRY(cpu_sa1100_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c3, c0, 0 @ domain ID
+ mrc p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c1, c0, 0 @ control reg
+ stmia r0, {r4 - r7} @ store cp regs
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(cpu_sa1100_do_suspend)
+
+ENTRY(cpu_sa1100_do_resume)
+ ldmia r0, {r4 - r7} @ load cp regs
+ mov r1, #0
+ mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs
+ mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache
+ mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
+ mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB
+
+ mcr p15, 0, r4, c3, c0, 0 @ domain ID
+ mcr p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ b cpu_sa1100_turn_mmu_on
+ENDPROC(cpu_sa1100_do_resume)
+ .align 5
+cpu_sa1100_turn_mmu_on:
+ mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, caches, etc.
+ nop
+ mov pc, lr @ jump to virtual addr
+ nop
+ nop
+ nop
+ENDPROC(cpu_sa1100_turn_mmu_on)
+#else
+#define cpu_sa1100_do_suspend 0
+#define cpu_sa1100_do_resume 0
+#endif
+
__CPUINIT
.type __sa1100_setup, #function
@@ -218,6 +258,9 @@ ENTRY(sa1100_processor_functions)
.word cpu_sa1100_dcache_clean_area
.word cpu_sa1100_switch_mm
.word cpu_sa1100_set_pte_ext
+ .word cpu_sa1100_suspend_size
+ .word cpu_sa1100_do_suspend
+ .word cpu_sa1100_do_resume
.size sa1100_processor_functions, . - sa1100_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 59a7e1f..838b031 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -121,6 +121,46 @@ ENTRY(cpu_v6_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
+.globl cpu_v6_suspend_size
+.equ cpu_v6_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_v6_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ Translation table base 0
+ mrc p15, 0, r7, c2, c0, 1 @ Translation table base 1
+ mrc p15, 0, r8, c1, c0, 1 @ auxillary control register
+ mrc p15, 0, r9, c1, c0, 2 @ co-processor access control
+ mrc p15, 0, r10, c1, c0, 0 @ control register
+ stmia r0, {r4 - r10}
+ ldmfd sp!, {r4- r10, pc}
+ENDPROC(cpu_v6_do_suspend)
+
+ENTRY(cpu_v6_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c14, 0 @ clean+invalidate D cache
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
+ ldmia r0, {r4 - r10}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ Translation table base 0
+ mcr p15, 0, r7, c2, c0, 1 @ Translation table base 1
+ mcr p15, 0, r8, c1, c0, 1 @ auxillary control register
+ mcr p15, 0, r9, c1, c0, 2 @ co-processor access control
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+ mcr p15, 0, ip, c7, c5, 4 @ ISB
+ mcr p15, 0, r10, c1, c0, 0 @ turn MMU back on
+ nop
+ mov pc, lr @ jump to return fn
+ENDPROC(cpu_v6_do_resume)
+#else
+#define cpu_v6_do_suspend 0
+#define cpu_v6_do_resume 0
+#endif
.type cpu_v6_name, #object
@@ -206,6 +246,9 @@ ENTRY(v6_processor_functions)
.word cpu_v6_dcache_clean_area
.word cpu_v6_switch_mm
.word cpu_v6_set_pte_ext
+ .word cpu_v6_suspend_size
+ .word cpu_v6_do_suspend
+ .word cpu_v6_do_resume
.size v6_processor_functions, . - v6_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 0c1172b..17dfb12 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -171,6 +171,95 @@ cpu_v7_name:
.ascii "ARMv7 Processor"
.align
+ /*
+ * Memory region attributes with SCTLR.TRE=1
+ *
+ * n = TEX[0],C,B
+ * TR = PRRR[2n+1:2n] - memory type
+ * IR = NMRR[2n+1:2n] - inner cacheable property
+ * OR = NMRR[2n+17:2n+16] - outer cacheable property
+ *
+ * n TR IR OR
+ * UNCACHED 000 00
+ * BUFFERABLE 001 10 00 00
+ * WRITETHROUGH 010 10 10 10
+ * WRITEBACK 011 10 11 11
+ * reserved 110
+ * WRITEALLOC 111 10 01 01
+ * DEV_SHARED 100 01
+ * DEV_NONSHARED 100 01
+ * DEV_WC 001 10
+ * DEV_CACHED 011 10
+ *
+ * Other attributes:
+ *
+ * DS0 = PRRR[16] = 0 - device shareable property
+ * DS1 = PRRR[17] = 1 - device shareable property
+ * NS0 = PRRR[18] = 0 - normal shareable property
+ * NS1 = PRRR[19] = 1 - normal shareable property
+ * NOS = PRRR[24+n] = 1 - not outer shareable
+ */
+.equ PRRR, 0xff0a81a8
+.equ NMRR, 0x40e040e0
+
+.globl cpu_v7_suspend_size
+.equ cpu_v7_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_v7_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB 0
+ mrc p15, 0, r7, c2, c0, 1 @ TTB 1
+ mrc p15, 0, r8, c1, c0, 0 @ Control register
+ mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control
+ stmia r0, {r4 - r10}
+ ldmfd sp!, {r4 - r10, pc}
+ENDPROC(cpu_v7_do_suspend)
+
+ENTRY(cpu_v7_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ ldmia r0, {r4 - r10}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB 0
+ mcr p15, 0, r7, c2, c0, 1 @ TTB 1
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+ mcr p15, 0, r9, c1, c0, 1 @ Auxillary control register
+ mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control
+ ldr r4, =PRRR @ PRRR
+ ldr r5, =NMRR @ NMRR
+ mcr p15, 0, r4, c10, c2, 0 @ write PRRR
+ mcr p15, 0, r5, c10, c2, 1 @ write NMRR
+ isb
+
+ mov r6, r6, lsr #14 @ get TTB0 base
+ mov r6, r6, lsl #14
+ ldr r2, =0x40e
+
+ adr r4, cpu_v7_turn_mmu_on
+ mov r4, r4, lsr #20
+ orr r3, r2, r4, lsl #20 @ phys addr
+ ldr r5, [r6, r4, lsl #2] @ save old translation
+ str r3, [r6, r4, lsl #2] @ virt index
+
+ ldr r2, =cpu_v7_resume_after_mmu
+ b cpu_v7_turn_mmu_on
+ENDPROC(cpu_v7_do_resume)
+ .align 3
+cpu_v7_turn_mmu_on:
+ mcr p15, 0, r8, c1, c0, 0 @ turn on MMU, etc
+ dsb
+ mov pc, r2
+ENDPROC(cpu_v7_turn_mmu_on)
+cpu_v7_resume_after_mmu:
+ str r5, [r6, r4, lsl #2] @ restore old translation
+ mov pc, lr
+ENDPROC(cpu_v7_resume_after_mmu)
+
__CPUINIT
/*
@@ -276,36 +365,8 @@ __v7_setup:
ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
- /*
- * Memory region attributes with SCTLR.TRE=1
- *
- * n = TEX[0],C,B
- * TR = PRRR[2n+1:2n] - memory type
- * IR = NMRR[2n+1:2n] - inner cacheable property
- * OR = NMRR[2n+17:2n+16] - outer cacheable property
- *
- * n TR IR OR
- * UNCACHED 000 00
- * BUFFERABLE 001 10 00 00
- * WRITETHROUGH 010 10 10 10
- * WRITEBACK 011 10 11 11
- * reserved 110
- * WRITEALLOC 111 10 01 01
- * DEV_SHARED 100 01
- * DEV_NONSHARED 100 01
- * DEV_WC 001 10
- * DEV_CACHED 011 10
- *
- * Other attributes:
- *
- * DS0 = PRRR[16] = 0 - device shareable property
- * DS1 = PRRR[17] = 1 - device shareable property
- * NS0 = PRRR[18] = 0 - normal shareable property
- * NS1 = PRRR[19] = 1 - normal shareable property
- * NOS = PRRR[24+n] = 1 - not outer shareable
- */
- ldr r5, =0xff0a81a8 @ PRRR
- ldr r6, =0x40e040e0 @ NMRR
+ ldr r5, =PRRR @ PRRR
+ ldr r6, =NMRR @ NMRR
mcr p15, 0, r5, c10, c2, 0 @ write PRRR
mcr p15, 0, r6, c10, c2, 1 @ write NMRR
#endif
@@ -351,6 +412,9 @@ ENTRY(v7_processor_functions)
.word cpu_v7_dcache_clean_area
.word cpu_v7_switch_mm
.word cpu_v7_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size v7_processor_functions, . - v7_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index ec26355..054c1e8 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -413,9 +413,82 @@ ENTRY(cpu_xsc3_set_pte_ext)
mov pc, lr
.ltorg
-
.align
+.globl cpu_xsc3_suspend_size
+.equ cpu_xsc3_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_xsc3_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+ mrc p15, 0, r5, c15, c1, 0 @ CP access reg
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c3, c0, 0 @ domain ID
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r4 - r10} @ store cp regs
+ ldmia sp!, {r4 - r10, pc}
+ENDPROC(cpu_xsc3_do_suspend)
+
+ENTRY(cpu_xsc3_do_resume)
+ ldmia r0, {r4 - r10} @ load cp regs
+ mov r1, #0
+ mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p15, 0, r1, c7, c10, 4 @ drain write (&fill) buffer
+ mcr p15, 0, r1, c7, c5, 4 @ flush prefetch buffer
+ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
+ mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
+ mcr p15, 0, r5, c15, c1, 0 @ CP access reg
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mcr p15, 0, r7, c3, c0, 0 @ domain ID
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+
+ @ temporarily map resume_turn_on_mmu into the page table,
+ @ otherwise prefetch abort occurs after MMU is turned on
+ mov r8, r8, lsr #14
+ mov r8, r8, lsl #14
+ ldr r2, =0x542e
+
+ adr r4, cpu_xsc3_turn_on_mmu
+ mov r4, r4, lsr #20
+ orr r3, r2, r4, lsl #20
+ ldr r5, [r8, r4, lsl #2]
+ str r3, [r8, r4, lsl #2]
+
+ @ Mapping page table address in the page table
+ mov r6, r8, lsr #20
+ orr r3, r2, r6, lsl #20
+ ldr r7, [r8, r6, lsl #2]
+ str r3, [r8, r6, lsl #2]
+
+ ldr r2, =cpu_xsc3_resume_after_mmu @ absolute virtual address
+ b cpu_xsc3_turn_on_mmu @ cache align execution
+ENDPROC(cpu_xsc3_do_resume)
+ .align 5
+cpu_xsc3_turn_on_mmu:
+ mcr p15, 0, r10, c1, c0, 0 @ turn on MMU, caches, etc.
+ @ Let us ensure we jump to resume_after_mmu only when the mcr above
+ @ actually took effect. They call it the "cpwait" operation.
+ mrc p15, 0, r0, c2, c0, 0 @ queue a dependency on CP15
+ sub pc, r2, r0, lsr #32 @ jump to virtual addr
+ nop
+ nop
+ nop
+ENDPROC(cpu_xsc3_mmu_on)
+cpu_xsc3_resume_after_mmu:
+ /* restore the temporary mapping */
+ str r5, [r8, r4, lsl #2]
+ str r7, [r8, r6, lsl #2]
+ mov pc, lr
+ENDPROC(cpu_xsc3_resume_after_mmu)
+#else
+#define cpu_xsc3_do_suspend 0
+#define cpu_xsc3_do_resume 0
+#endif
+
__CPUINIT
.type __xsc3_setup, #function
@@ -476,6 +549,9 @@ ENTRY(xsc3_processor_functions)
.word cpu_xsc3_dcache_clean_area
.word cpu_xsc3_switch_mm
.word cpu_xsc3_set_pte_ext
+ .word cpu_xsc3_suspend_size
+ .word cpu_xsc3_do_suspend
+ .word cpu_xsc3_do_resume
.size xsc3_processor_functions, . - xsc3_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 5a37c5e..0cdf3cf 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -513,11 +513,55 @@ ENTRY(cpu_xscale_set_pte_ext)
xscale_set_pte_ext_epilogue
mov pc, lr
-
.ltorg
-
.align
+.globl cpu_xscale_suspend_size
+.equ cpu_xscale_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_xscale_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+ mrc p15, 0, r5, c15, c1, 0 @ CP access reg
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c3, c0, 0 @ domain ID
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r4 - r10} @ store cp regs
+ ldmfd sp!, {r4 - r10, pc}
+ENDPROC(cpu_xscale_do_suspend)
+
+ENTRY(cpu_xscale_do_resume)
+ ldmia r0, {r4 - r10} @ load cp regs
+ mov r1, #0
+ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
+ mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
+ mcr p15, 0, r5, c15, c1, 0 @ CP access reg
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mcr p15, 0, r7, c3, c0, 0 @ domain ID
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ b cpu_xscale_mmu_on
+ENDPROC(cpu_xscale_do_resume)
+ .align 5
+cpu_xscale_mmu_on:
+ mcr p15, 0, r10, c1, c0, 0 @ turn on MMU, caches, etc.
+ @ Let us ensure we jump to resume_after_mmu only when the mcr above
+ @ actually took effect. They call it the "cpwait" operation.
+ mrc p15, 0, r0, c2, c0, 0 @ queue a dependency on CP15
+ sub pc, lr, r0, lsr #32 @ jump to virtual addr
+ nop
+ nop
+ nop
+ENDPROC(cpu_xscale_mmu_on)
+#else
+#define cpu_xscale_do_suspend 0
+#define cpu_xscale_do_resume 0
+#endif
+
__CPUINIT
.type __xscale_setup, #function
@@ -565,6 +609,9 @@ ENTRY(xscale_processor_functions)
.word cpu_xscale_dcache_clean_area
.word cpu_xscale_switch_mm
.word cpu_xscale_set_pte_ext
+ .word cpu_xscale_suspend_size
+ .word cpu_xscale_do_suspend
+ .word cpu_xscale_do_resume
.size xscale_processor_functions, . - xscale_processor_functions
.section ".rodata"
--
1.6.2.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 3/5] ARM: pm: convert PXA to generic suspend/resume support
2011-02-06 19:11 [RFC] Generic CPU save/restore PM support Russell King - ARM Linux
2011-02-06 19:12 ` [PATCH 1/5] ARM: move cache/processor/fault glue to separate include files Russell King - ARM Linux
2011-02-06 19:12 ` [PATCH 2/5] ARM: pm: add generic CPU suspend/resume support Russell King - ARM Linux
@ 2011-02-06 19:13 ` Russell King - ARM Linux
2011-02-06 19:13 ` [PATCH 4/5] ARM: pm: convert sa11x0 " Russell King - ARM Linux
` (2 subsequent siblings)
5 siblings, 0 replies; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-06 19:13 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mach-pxa/include/mach/pm.h | 5 +-
arch/arm/mach-pxa/palmz72.c | 2 +-
arch/arm/mach-pxa/pm.c | 5 -
arch/arm/mach-pxa/pxa25x.c | 4 +-
arch/arm/mach-pxa/pxa27x.c | 4 +-
arch/arm/mach-pxa/pxa3xx.c | 7 +-
arch/arm/mach-pxa/sleep.S | 184 +++--------------------------------
arch/arm/mach-pxa/zeus.c | 2 +-
8 files changed, 24 insertions(+), 189 deletions(-)
diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/include/mach/pm.h
index fd8360c..f15afe0 100644
--- a/arch/arm/mach-pxa/include/mach/pm.h
+++ b/arch/arm/mach-pxa/include/mach/pm.h
@@ -22,9 +22,8 @@ struct pxa_cpu_pm_fns {
extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
/* sleep.S */
-extern void pxa25x_cpu_suspend(unsigned int);
-extern void pxa27x_cpu_suspend(unsigned int);
-extern void pxa_cpu_resume(void);
+extern void pxa25x_cpu_suspend(unsigned int, long);
+extern void pxa27x_cpu_suspend(unsigned int, long);
extern int pxa_pm_enter(suspend_state_t state);
extern int pxa_pm_prepare(void);
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index 7bf4017..3010193 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -212,7 +212,7 @@ static unsigned long store_ptr;
static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg)
{
/* setup the resume_info struct for the original bootloader */
- palmz72_resume_info.resume_addr = (u32) pxa_cpu_resume;
+ palmz72_resume_info.resume_addr = (u32) cpu_resume;
/* Storing memory touched by ROM */
store_ptr = *PALMZ72_SAVE_DWORD;
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index 978e1b2..f377f0d 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -67,11 +67,6 @@ int pxa_pm_enter(suspend_state_t state)
EXPORT_SYMBOL_GPL(pxa_pm_enter);
-unsigned long sleep_phys_sp(void *sp)
-{
- return virt_to_phys(sp);
-}
-
static int pxa_pm_valid(suspend_state_t state)
{
if (pxa_cpu_pm_fns)
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index fbc5b77..0727e48 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -244,7 +244,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state)
switch (state) {
case PM_SUSPEND_MEM:
- pxa25x_cpu_suspend(PWRMODE_SLEEP);
+ pxa25x_cpu_suspend(PWRMODE_SLEEP, PHYS_OFFSET - PAGE_OFFSET);
break;
}
}
@@ -252,7 +252,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state)
static int pxa25x_cpu_pm_prepare(void)
{
/* set resume return address */
- PSPR = virt_to_phys(pxa_cpu_resume);
+ PSPR = virt_to_phys(cpu_resume);
return 0;
}
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 987301f..28b11be 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -300,7 +300,7 @@ void pxa27x_cpu_pm_enter(suspend_state_t state)
pxa_cpu_standby();
break;
case PM_SUSPEND_MEM:
- pxa27x_cpu_suspend(pwrmode);
+ pxa27x_cpu_suspend(pwrmode, PHYS_OFFSET - PAGE_OFFSET);
break;
}
}
@@ -313,7 +313,7 @@ static int pxa27x_cpu_pm_valid(suspend_state_t state)
static int pxa27x_cpu_pm_prepare(void)
{
/* set resume return address */
- PSPR = virt_to_phys(pxa_cpu_resume);
+ PSPR = virt_to_phys(cpu_resume);
return 0;
}
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index a7a19e1..1230343 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -142,8 +142,7 @@ static void pxa3xx_cpu_pm_suspend(void)
volatile unsigned long *p = (volatile void *)0xc0000000;
unsigned long saved_data = *p;
- extern void pxa3xx_cpu_suspend(void);
- extern void pxa3xx_cpu_resume(void);
+ extern void pxa3xx_cpu_suspend(long);
/* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */
CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM);
@@ -161,9 +160,9 @@ static void pxa3xx_cpu_pm_suspend(void)
PSPR = 0x5c014000;
/* overwrite with the resume address */
- *p = virt_to_phys(pxa3xx_cpu_resume);
+ *p = virt_to_phys(cpu_resume);
- pxa3xx_cpu_suspend();
+ pxa3xx_cpu_suspend(PHYS_OFFSET - PAGE_OFFSET);
*p = saved_data;
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
index c551da8..24822b0 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -22,33 +22,6 @@
.text
-pxa_cpu_save_cp:
- @ get coprocessor registers
- mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode
- mrc p15, 0, r4, c15, c1, 0 @ CP access reg
- mrc p15, 0, r5, c13, c0, 0 @ PID
- mrc p15, 0, r6, c3, c0, 0 @ domain ID
- mrc p15, 0, r7, c2, c0, 0 @ translation table base addr
- mrc p15, 0, r8, c1, c1, 0 @ auxiliary control reg
- mrc p15, 0, r9, c1, c0, 0 @ control reg
-
- bic r3, r3, #2 @ clear frequency change bit
-
- @ store them plus current virtual stack ptr on stack
- mov r10, sp
- stmfd sp!, {r3 - r10}
-
- mov pc, lr
-
-pxa_cpu_save_sp:
- @ preserve phys address of stack
- mov r0, sp
- str lr, [sp, #-4]!
- bl sleep_phys_sp
- ldr r1, =sleep_save_sp
- str r0, [r1]
- ldr pc, [sp], #4
-
#ifdef CONFIG_PXA3xx
/*
* pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4)
@@ -64,91 +37,14 @@ ENTRY(pxa3xx_cpu_suspend)
mra r2, r3, acc0
#endif
stmfd sp!, {r2 - r12, lr} @ save registers on stack
-
- mrc p14, 0, r3, c6, c0, 0 @ clock configuration, for turbo mode
- mrc p15, 0, r4, c15, c1, 0 @ CP access reg
- mrc p15, 0, r5, c13, c0, 0 @ PID
- mrc p15, 0, r6, c3, c0, 0 @ domain ID
- mrc p15, 0, r7, c2, c0, 0 @ translation table base addr
- mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg
- mrc p15, 0, r9, c1, c0, 0 @ control reg
-
- bic r3, r3, #2 @ clear frequency change bit
-
- @ store them plus current virtual stack ptr on stack
- mov r10, sp
- stmfd sp!, {r3 - r10}
-
- @ store physical address of stack pointer
- mov r0, sp
- bl sleep_phys_sp
- ldr r1, =sleep_save_sp
- str r0, [r1]
-
- @ clean data cache
- bl xsc3_flush_kern_cache_all
+ mov r1, r0
+ ldr r3, =pxa_cpu_resume @ resume function
+ bl cpu_suspend
mov r0, #0x06 @ S2D3C4 mode
mcr p14, 0, r0, c7, c0, 0 @ enter sleep
20: b 20b @ waiting for sleep
-
- .data
- .align 5
-/*
- * pxa3xx_cpu_resume
- */
-
-ENTRY(pxa3xx_cpu_resume)
-
- mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
- msr cpsr_c, r0
-
- ldr r0, sleep_save_sp @ stack phys addr
- ldmfd r0, {r3 - r9, sp} @ CP regs + virt stack ptr
-
- mov r1, #0
- mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB
- mcr p15, 0, r1, c7, c10, 4 @ drain write (&fill) buffer
- mcr p15, 0, r1, c7, c5, 4 @ flush prefetch buffer
- mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
-
- mcr p14, 0, r3, c6, c0, 0 @ clock configuration, turbo mode.
- mcr p15, 0, r4, c15, c1, 0 @ CP access reg
- mcr p15, 0, r5, c13, c0, 0 @ PID
- mcr p15, 0, r6, c3, c0, 0 @ domain ID
- mcr p15, 0, r7, c2, c0, 0 @ translation table base addr
- mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg
-
- @ temporarily map resume_turn_on_mmu into the page table,
- @ otherwise prefetch abort occurs after MMU is turned on
- mov r1, r7
- bic r1, r1, #0x00ff
- bic r1, r1, #0x3f00
- ldr r2, =0x542e
-
- adr r3, resume_turn_on_mmu
- mov r3, r3, lsr #20
- orr r4, r2, r3, lsl #20
- ldr r5, [r1, r3, lsl #2]
- str r4, [r1, r3, lsl #2]
-
- @ Mapping page table address in the page table
- mov r6, r1, lsr #20
- orr r7, r2, r6, lsl #20
- ldr r8, [r1, r6, lsl #2]
- str r7, [r1, r6, lsl #2]
-
- ldr r2, =pxa3xx_resume_after_mmu @ absolute virtual address
- b resume_turn_on_mmu @ cache align execution
-
- .text
-pxa3xx_resume_after_mmu:
- /* restore the temporary mapping */
- str r5, [r1, r3, lsl #2]
- str r8, [r1, r6, lsl #2]
- b resume_after_mmu
-
#endif /* CONFIG_PXA3xx */
#ifdef CONFIG_PXA27x
@@ -166,20 +62,15 @@ ENTRY(pxa27x_cpu_suspend)
mra r2, r3, acc0
#endif
stmfd sp!, {r2 - r12, lr} @ save registers on stack
-
- bl pxa_cpu_save_cp
-
- mov r5, r0 @ save sleep mode
- bl pxa_cpu_save_sp
-
- @ clean data cache
- bl xscale_flush_kern_cache_all
+ mov r4, r0 @ save sleep mode
+ ldr r3, =pxa_cpu_resume @ resume function
+ bl cpu_suspend
@ Put the processor to sleep
@ (also workaround for sighting 28071)
@ prepare value for sleep mode
- mov r1, r5 @ sleep mode
+ mov r1, r4 @ sleep mode
@ prepare pointer to physical address 0 (virtual mapping in generic.c)
mov r2, #UNCACHED_PHYS_0
@@ -216,21 +107,16 @@ ENTRY(pxa27x_cpu_suspend)
* Forces CPU into sleep state.
*
* r0 = value for PWRMODE M field for desired sleep state
+ * r1 = v:p offset
*/
ENTRY(pxa25x_cpu_suspend)
stmfd sp!, {r2 - r12, lr} @ save registers on stack
-
- bl pxa_cpu_save_cp
-
- mov r5, r0 @ save sleep mode
- bl pxa_cpu_save_sp
-
- @ clean data cache
- bl xscale_flush_kern_cache_all
-
+ mov r4, r0 @ save sleep mode
+ ldr r3, =pxa_cpu_resume @ resume function
+ bl cpu_suspend
@ prepare value for sleep mode
- mov r1, r5 @ sleep mode
+ mov r1, r4 @ sleep mode
@ prepare pointer to physical address 0 (virtual mapping in generic.c)
mov r2, #UNCACHED_PHYS_0
@@ -317,53 +203,9 @@ pxa_cpu_do_suspend:
* pxa_cpu_resume()
*
* entry point from bootloader into kernel during resume
- *
- * Note: Yes, part of the following code is located into the .data section.
- * This is to allow sleep_save_sp to be accessed with a relative load
- * while we can't rely on any MMU translation. We could have put
- * sleep_save_sp in the .text section as well, but some setups might
- * insist on it to be truly read-only.
*/
-
- .data
- .align 5
-ENTRY(pxa_cpu_resume)
- mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
- msr cpsr_c, r0
-
- ldr r0, sleep_save_sp @ stack phys addr
- ldr r2, =resume_after_mmu @ its absolute virtual address
- ldmfd r0, {r3 - r9, sp} @ CP regs + virt stack ptr
-
- mov r1, #0
- mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
- mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB
-
- mcr p14, 0, r3, c6, c0, 0 @ clock configuration, turbo mode.
- mcr p15, 0, r4, c15, c1, 0 @ CP access reg
- mcr p15, 0, r5, c13, c0, 0 @ PID
- mcr p15, 0, r6, c3, c0, 0 @ domain ID
- mcr p15, 0, r7, c2, c0, 0 @ translation table base addr
- mcr p15, 0, r8, c1, c1, 0 @ auxiliary control reg
- b resume_turn_on_mmu @ cache align execution
-
.align 5
-resume_turn_on_mmu:
- mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, caches, etc.
-
- @ Let us ensure we jump to resume_after_mmu only when the mcr above
- @ actually took effect. They call it the "cpwait" operation.
- mrc p15, 0, r0, c2, c0, 0 @ queue a dependency on CP15
- sub pc, r2, r0, lsr #32 @ jump to virtual addr
- nop
- nop
- nop
-
-sleep_save_sp:
- .word 0 @ preserve stack phys ptr here
-
- .text
-resume_after_mmu:
+pxa_cpu_resume:
ldmfd sp!, {r2, r3}
#ifndef CONFIG_IWMMXT
mar acc0, r2, r3
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index f4b053b..b92aa3b 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -676,7 +676,7 @@ static struct pxa2xx_udc_mach_info zeus_udc_info = {
static void zeus_power_off(void)
{
local_irq_disable();
- pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP);
+ pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP, PHYS_OFFSET - PAGE_OFFSET);
}
#else
#define zeus_power_off NULL
--
1.6.2.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 4/5] ARM: pm: convert sa11x0 to generic suspend/resume support
2011-02-06 19:11 [RFC] Generic CPU save/restore PM support Russell King - ARM Linux
` (2 preceding siblings ...)
2011-02-06 19:13 ` [PATCH 3/5] ARM: pm: convert PXA to generic " Russell King - ARM Linux
@ 2011-02-06 19:13 ` Russell King - ARM Linux
2011-02-07 18:11 ` Russell King - ARM Linux
2011-02-06 19:13 ` [PATCH 5/5] ARM: pm: convert samsung platforms " Russell King - ARM Linux
2011-02-07 5:42 ` [RFC] Generic CPU save/restore PM support Kukjin Kim
5 siblings, 1 reply; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-06 19:13 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mach-sa1100/pm.c | 12 ++-----
arch/arm/mach-sa1100/sleep.S | 72 ++---------------------------------------
2 files changed, 7 insertions(+), 77 deletions(-)
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index ab9fc44..c4661aa 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -32,8 +32,7 @@
#include <asm/system.h>
#include <asm/mach/time.h>
-extern void sa1100_cpu_suspend(void);
-extern void sa1100_cpu_resume(void);
+extern void sa1100_cpu_suspend(long);
#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
@@ -73,10 +72,10 @@ static int sa11x0_pm_enter(suspend_state_t state)
RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
/* set resume return address */
- PSPR = virt_to_phys(sa1100_cpu_resume);
+ PSPR = virt_to_phys(cpu_resume);
/* go zzz */
- sa1100_cpu_suspend();
+ sa1100_cpu_suspend(PHYS_OFFSET - PAGE_OFFSET);
cpu_init();
@@ -115,11 +114,6 @@ static int sa11x0_pm_enter(suspend_state_t state)
return 0;
}
-unsigned long sleep_phys_sp(void *sp)
-{
- return virt_to_phys(sp);
-}
-
static const struct platform_suspend_ops sa11x0_pm_ops = {
.enter = sa11x0_pm_enter,
.valid = suspend_valid_only_mem,
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S
index 80f31ba..04f2a61 100644
--- a/arch/arm/mach-sa1100/sleep.S
+++ b/arch/arm/mach-sa1100/sleep.S
@@ -20,12 +20,7 @@
#include <asm/assembler.h>
#include <mach/hardware.h>
-
-
.text
-
-
-
/*
* sa1100_cpu_suspend()
*
@@ -34,27 +29,10 @@
*/
ENTRY(sa1100_cpu_suspend)
-
stmfd sp!, {r4 - r12, lr} @ save registers on stack
-
- @ get coprocessor registers
- mrc p15, 0, r4, c3, c0, 0 @ domain ID
- mrc p15, 0, r5, c2, c0, 0 @ translation table base addr
- mrc p15, 0, r6, c13, c0, 0 @ PID
- mrc p15, 0, r7, c1, c0, 0 @ control reg
-
- @ store them plus current virtual stack ptr on stack
- mov r8, sp
- stmfd sp!, {r4 - r8}
-
- @ preserve phys address of stack
- mov r0, sp
- bl sleep_phys_sp
- ldr r1, =sleep_save_sp
- str r0, [r1]
-
- @ clean data cache and invalidate WB
- bl v4wb_flush_kern_cache_all
+ mov r1, r0
+ ldr r3, =sa1100_cpu_resume @ return function
+ bl cpu_suspend
@ disable clock switching
mcr p15, 0, r1, c15, c2, 2
@@ -166,50 +144,8 @@ sa1110_sdram_controller_fix:
* cpu_sa1100_resume()
*
* entry point from bootloader into kernel during resume
- *
- * Note: Yes, part of the following code is located into the .data section.
- * This is to allow sleep_save_sp to be accessed with a relative load
- * while we can't rely on any MMU translation. We could have put
- * sleep_save_sp in the .text section as well, but some setups might
- * insist on it to be truly read-only.
*/
-
- .data
- .align 5
-ENTRY(sa1100_cpu_resume)
- mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
- msr cpsr_c, r0 @ set SVC, irqs off
-
- ldr r0, sleep_save_sp @ stack phys addr
- ldr r2, =resume_after_mmu @ its absolute virtual address
- ldmfd r0, {r4 - r7, sp} @ CP regs + virt stack ptr
-
- mov r1, #0
- mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs
- mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache
- mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
- mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB
-
- mcr p15, 0, r4, c3, c0, 0 @ domain ID
- mcr p15, 0, r5, c2, c0, 0 @ translation table base addr
- mcr p15, 0, r6, c13, c0, 0 @ PID
- b resume_turn_on_mmu @ cache align execution
-
.align 5
-resume_turn_on_mmu:
- mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, caches, etc.
- nop
- mov pc, r2 @ jump to virtual addr
- nop
- nop
- nop
-
-sleep_save_sp:
- .word 0 @ preserve stack phys ptr here
-
- .text
-resume_after_mmu:
+sa1100_cpu_resume:
mcr p15, 0, r1, c15, c1, 2 @ enable clock switching
ldmfd sp!, {r4 - r12, pc} @ return to caller
-
-
--
1.6.2.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH 5/5] ARM: pm: convert samsung platforms to generic suspend/resume support
2011-02-06 19:11 [RFC] Generic CPU save/restore PM support Russell King - ARM Linux
` (3 preceding siblings ...)
2011-02-06 19:13 ` [PATCH 4/5] ARM: pm: convert sa11x0 " Russell King - ARM Linux
@ 2011-02-06 19:13 ` Russell King - ARM Linux
2011-02-07 5:42 ` [RFC] Generic CPU save/restore PM support Kukjin Kim
5 siblings, 0 replies; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-06 19:13 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/mach-s3c64xx/sleep.S | 63 +-----------------
arch/arm/mach-s5pv210/sleep.S | 104 +------------------------------
arch/arm/plat-s3c24xx/sleep.S | 57 +----------------
arch/arm/plat-samsung/include/plat/pm.h | 12 +---
arch/arm/plat-samsung/pm.c | 16 +-----
5 files changed, 13 insertions(+), 239 deletions(-)
diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S
index b2ef443..afe5a76 100644
--- a/arch/arm/mach-s3c64xx/sleep.S
+++ b/arch/arm/mach-s3c64xx/sleep.S
@@ -32,25 +32,13 @@
* code after resume.
*
* entry:
- * r0 = pointer to the save block
+ * r1 = v:p offset
*/
ENTRY(s3c_cpu_save)
stmfd sp!, { r4 - r12, lr }
-
- mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mrc p15, 0, r5, c3, c0, 0 @ Domain ID
- mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
- mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
- mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
- mrc p15, 0, r9, c1, c0, 0 @ Control register
- mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
- mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
-
- stmia r0, { r4 - r13 } @ Save CP registers and SP
-
- @@ save our state to ram
- bl s3c_pm_cb_flushcache
+ ldr r3, =resume_with_mmu
+ bl cpu_suspend
@@ call final suspend code
ldr r0, =pm_cpu_sleep
@@ -61,18 +49,6 @@ ENTRY(s3c_cpu_save)
resume_with_mmu:
ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save
- .data
-
- /* the next bit is code, but it requires easy access to the
- * s3c_sleep_save_phys data before the MMU is switched on, so
- * we store the code that needs this variable in the .data where
- * the value can be written to (the .text segment is RO).
- */
-
- .global s3c_sleep_save_phys
-s3c_sleep_save_phys:
- .word 0
-
/* Sleep magic, the word before the resume entry point so that the
* bootloader can check for a resumeable image. */
@@ -110,35 +86,4 @@ ENTRY(s3c_cpu_resume)
orr r0, r0, #1 << 15 @ GPN15
str r0, [ r3, #S3C64XX_GPNDAT ]
#endif
-
- /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
- * are thoroughly cleaned just in case the bootloader didn't do it
- * for us. */
- mov r0, #0
- mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
- mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
- mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
- @@mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
- @@mcr p15, 0, r0, c7, c7, 0 @ Invalidate I + D caches
-
- ldr r0, s3c_sleep_save_phys
- ldmia r0, { r4 - r13 }
-
- mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mcr p15, 0, r5, c3, c0, 0 @ Domain ID
- mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
- mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
- mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
- mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
-
- mov r0, #0 @ restore copro access controls
- mcr p15, 0, r11, c1, c0, 2 @ Co-processor access controls
- mcr p15, 0, r0, c7, c5, 4
-
- ldr r2, =resume_with_mmu
- mcr p15, 0, r9, c1, c0, 0 /* turn mmu back on */
- nop
- mov pc, r2 /* jump back */
-
- .end
+ b cpu_resume
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
index d4d222b..ef4bd2a 100644
--- a/arch/arm/mach-s5pv210/sleep.S
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -35,50 +35,23 @@
/* s3c_cpu_save
*
* entry:
- * r0 = save address (virtual addr of s3c_sleep_save_phys)
+ * r1 = v:p offset
*/
ENTRY(s3c_cpu_save)
stmfd sp!, { r3 - r12, lr }
-
- mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mrc p15, 0, r5, c3, c0, 0 @ Domain ID
- mrc p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
- mrc p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
- mrc p15, 0, r8, c2, c0, 2 @ Translation Table Control
- mrc p15, 0, r9, c1, c0, 0 @ Control register
- mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
- mrc p15, 0, r11, c1, c0, 2 @ Co-processor access controls
- mrc p15, 0, r12, c10, c2, 0 @ Read PRRR
- mrc p15, 0, r3, c10, c2, 1 @ READ NMRR
-
- stmia r0, { r3 - r13 }
-
- bl s3c_pm_cb_flushcache
+ bl cpu_suspend
ldr r0, =pm_cpu_sleep
ldr r0, [ r0 ]
mov pc, r0
resume_with_mmu:
- /*
- * After MMU is turned on, restore the previous MMU table.
- */
- ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET)
- add r4, r4, r9
- str r12, [r4]
-
ldmfd sp!, { r3 - r12, pc }
.ltorg
- .data
-
- .global s3c_sleep_save_phys
-s3c_sleep_save_phys:
- .word 0
-
/* sleep magic, to allow the bootloader to check for an valid
* image to resume to. Must be the first word before the
* s3c_cpu_resume entry.
@@ -96,75 +69,4 @@ s3c_sleep_save_phys:
*/
ENTRY(s3c_cpu_resume)
- mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
- msr cpsr_c, r0
-
- mov r1, #0
- mcr p15, 0, r1, c8, c7, 0 @ invalidate TLBs
- mcr p15, 0, r1, c7, c5, 0 @ invalidate I Cache
-
- ldr r0, s3c_sleep_save_phys @ address of restore block
- ldmia r0, { r3 - r13 }
-
- mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
- mcr p15, 0, r5, c3, c0, 0 @ Domain ID
-
- mcr p15, 0, r8, c2, c0, 2 @ Translation Table Control
- mcr p15, 0, r7, c2, c0, 1 @ Translation Table BASE1
- mcr p15, 0, r6, c2, c0, 0 @ Translation Table BASE0
-
- mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
-
- mov r0, #0
- mcr p15, 0, r0, c8, c7, 0 @ Invalidate I & D TLB
-
- mov r0, #0 @ restore copro access
- mcr p15, 0, r11, c1, c0, 2 @ Co-processor access
- mcr p15, 0, r0, c7, c5, 4
-
- mcr p15, 0, r12, c10, c2, 0 @ write PRRR
- mcr p15, 0, r3, c10, c2, 1 @ write NMRR
-
- /*
- * In Cortex-A8, when MMU is turned on, the pipeline is flushed.
- * And there are no valid entries in the MMU table@this point.
- * So before turning on the MMU, the MMU entry for the DRAM address
- * range is added. After the MMU is turned on, the other entries
- * in the MMU table will be restored.
- */
-
- /* r6 = Translation Table BASE0 */
- mov r4, r6
- mov r4, r4, LSR #14
- mov r4, r4, LSL #14
-
- /* Load address for adding to MMU table list */
- ldr r11, =0xE010F000 @ INFORM0 reg.
- ldr r10, [r11, #0]
- mov r10, r10, LSR #18
- bic r10, r10, #0x3
- orr r4, r4, r10
-
- /* Calculate MMU table entry */
- mov r10, r10, LSL #18
- ldr r5, =0x40E
- orr r10, r10, r5
-
- /* Back up originally data */
- ldr r12, [r4]
-
- /* Add calculated MMU table entry into MMU table list */
- str r10, [r4]
-
- ldr r2, =resume_with_mmu
- mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, etc
-
- nop
- nop
- nop
- nop
- nop @ second-to-last before mmu
-
- mov pc, r2 @ go back to virtual address
-
- .ltorg
+ b cpu_resume
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
index e73e3b6..fd7032f 100644
--- a/arch/arm/plat-s3c24xx/sleep.S
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -44,23 +44,13 @@
/* s3c_cpu_save
*
* entry:
- * r0 = save address (virtual addr of s3c_sleep_save_phys)
+ * r1 = v:p offset
*/
ENTRY(s3c_cpu_save)
stmfd sp!, { r4 - r12, lr }
-
- @@ store co-processor registers
-
- mrc p15, 0, r4, c13, c0, 0 @ PID
- mrc p15, 0, r5, c3, c0, 0 @ Domain ID
- mrc p15, 0, r6, c2, c0, 0 @ translation table base address
- mrc p15, 0, r7, c1, c0, 0 @ control register
-
- stmia r0, { r4 - r13 }
-
- @@ write our state back to RAM
- bl s3c_pm_cb_flushcache
+ ldr r3, =resume_with_mmu
+ bl cpu_suspend
@@ jump to final code to send system to sleep
ldr r0, =pm_cpu_sleep
@@ -76,20 +66,6 @@ resume_with_mmu:
.ltorg
- @@ the next bits sit in the .data segment, even though they
- @@ happen to be code... the s3c_sleep_save_phys needs to be
- @@ accessed by the resume code before it can restore the MMU.
- @@ This means that the variable has to be close enough for the
- @@ code to read it... since the .text segment needs to be RO,
- @@ the data segment can be the only place to put this code.
-
- .data
-
- .global s3c_sleep_save_phys
-s3c_sleep_save_phys:
- .word 0
-
-
/* sleep magic, to allow the bootloader to check for an valid
* image to resume to. Must be the first word before the
* s3c_cpu_resume entry.
@@ -100,10 +76,6 @@ s3c_sleep_save_phys:
/* s3c_cpu_resume
*
* resume code entry for bootloader to call
- *
- * we must put this code here in the data segment as we have no
- * other way of restoring the stack pointer after sleep, and we
- * must not write to the code segment (code is read-only)
*/
ENTRY(s3c_cpu_resume)
@@ -134,25 +106,4 @@ ENTRY(s3c_cpu_resume)
beq 1001b
#endif /* CONFIG_DEBUG_RESUME */
- mov r1, #0
- mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs
- mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches
-
- ldr r0, s3c_sleep_save_phys @ address of restore block
- ldmia r0, { r4 - r13 }
-
- mcr p15, 0, r4, c13, c0, 0 @ PID
- mcr p15, 0, r5, c3, c0, 0 @ Domain ID
- mcr p15, 0, r6, c2, c0, 0 @ translation table base
-
-#ifdef CONFIG_DEBUG_RESUME
- mov r3, #'R'
- strb r3, [ r2, #S3C2410_UTXH ]
-#endif
-
- ldr r2, =resume_with_mmu
- mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, etc
- nop @ second-to-last before mmu
- mov pc, r2 @ go back to virtual address
-
- .ltorg
+ b cpu_resume
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index d9025e3..4aa697d 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -50,13 +50,11 @@ extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */
/* from sleep.S */
-extern int s3c_cpu_save(unsigned long *saveblk);
+extern int s3c_cpu_save(unsigned long *saveblk, long);
extern void s3c_cpu_resume(void);
extern void s3c2410_cpu_suspend(void);
-extern unsigned long s3c_sleep_save_phys;
-
/* sleep save info */
/**
@@ -179,13 +177,5 @@ extern void s3c_pm_restore_gpios(void);
*/
extern void s3c_pm_save_gpios(void);
-/**
- * s3c_pm_cb_flushcache - callback for assembly code
- *
- * Callback to issue flush_cache_all() as this call is
- * not a directly callable object.
- */
-extern void s3c_pm_cb_flushcache(void);
-
extern void s3c_pm_save_core(void);
extern void s3c_pm_restore_core(void);
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index 02d531f..d5b58d3 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -241,8 +241,6 @@ void (*pm_cpu_sleep)(void);
static int s3c_pm_enter(suspend_state_t state)
{
- static unsigned long regs_save[16];
-
/* ensure the debug is initialised (if enabled) */
s3c_pm_debug_init();
@@ -266,12 +264,6 @@ static int s3c_pm_enter(suspend_state_t state)
return -EINVAL;
}
- /* store the physical address of the register recovery block */
-
- s3c_sleep_save_phys = virt_to_phys(regs_save);
-
- S3C_PMDBG("s3c_sleep_save_phys=0x%08lx\n", s3c_sleep_save_phys);
-
/* save all necessary core registers not covered by the drivers */
s3c_pm_save_gpios();
@@ -305,7 +297,7 @@ static int s3c_pm_enter(suspend_state_t state)
* we resume as it saves its own register state and restores it
* during the resume. */
- s3c_cpu_save(regs_save);
+ s3c_cpu_save(0, PHYS_OFFSET - PAGE_OFFSET);
/* restore the cpu state using the kernel's cpu init code. */
@@ -336,12 +328,6 @@ static int s3c_pm_enter(suspend_state_t state)
return 0;
}
-/* callback from assembly code */
-void s3c_pm_cb_flushcache(void)
-{
- flush_cache_all();
-}
-
static int s3c_pm_prepare(void)
{
/* prepare check area if configured */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [RFC] Generic CPU save/restore PM support
2011-02-06 19:11 [RFC] Generic CPU save/restore PM support Russell King - ARM Linux
` (4 preceding siblings ...)
2011-02-06 19:13 ` [PATCH 5/5] ARM: pm: convert samsung platforms " Russell King - ARM Linux
@ 2011-02-07 5:42 ` Kukjin Kim
2011-02-07 10:44 ` Russell King - ARM Linux
5 siblings, 1 reply; 33+ messages in thread
From: Kukjin Kim @ 2011-02-07 5:42 UTC (permalink / raw)
To: linux-arm-kernel
Russell King - ARM Linux wrote:
>
> The following patch series implements infrastructure to save/restore
> CPU state on suspend/resume PM events, and updates SA11x0, PXA and
> Samsung platforms to use this.
>
> Not all CPU support files are updated with the necessary changes -
> currently only ARM920, ARM926, SA11x0, XScale, XScale3, V6 and V7
> CPUs are supported.
>
> I've build-tested this for Assabet, PXA, and S3C2410, but not boot
> tested it yet.
>
Hi Russell,
Occurs following build error with s5pv210_defconfig.
(I applied your patches into my some branch which is based on 38-rc3 for
test)
arch/arm/mm/proc-v7.S:207: error: unterminated #ifdef
Let you know the test result on my board after fixing it.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [RFC] Generic CPU save/restore PM support
2011-02-07 5:42 ` [RFC] Generic CPU save/restore PM support Kukjin Kim
@ 2011-02-07 10:44 ` Russell King - ARM Linux
0 siblings, 0 replies; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-07 10:44 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 07, 2011 at 02:42:15PM +0900, Kukjin Kim wrote:
> Russell King - ARM Linux wrote:
> >
> > The following patch series implements infrastructure to save/restore
> > CPU state on suspend/resume PM events, and updates SA11x0, PXA and
> > Samsung platforms to use this.
> >
> > Not all CPU support files are updated with the necessary changes -
> > currently only ARM920, ARM926, SA11x0, XScale, XScale3, V6 and V7
> > CPUs are supported.
> >
> > I've build-tested this for Assabet, PXA, and S3C2410, but not boot
> > tested it yet.
> >
> Hi Russell,
>
> Occurs following build error with s5pv210_defconfig.
> (I applied your patches into my some branch which is based on 38-rc3 for
> test)
>
> arch/arm/mm/proc-v7.S:207: error: unterminated #ifdef
>
> Let you know the test result on my board after fixing it.
There is an issue here which I missed when pulling the code out of
s5pv210, so you'll also need this. This also fixes Xscale3 to operate
in the same manner.
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index abffa81..45d1024 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -203,7 +203,7 @@ cpu_v7_name:
.equ NMRR, 0x40e040e0
.globl cpu_v7_suspend_size
-.equ cpu_v7_suspend_size, 4 * 7
+.equ cpu_v7_suspend_size, 4 * 8
#ifdef CONFIG_PM
ENTRY(cpu_v7_do_suspend)
stmfd sp!, {r4 - r10, lr}
@@ -214,7 +214,7 @@ ENTRY(cpu_v7_do_suspend)
mrc p15, 0, r8, c1, c0, 0 @ Control register
mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register
mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control
- stmia r0, {r4 - r10}
+ stmia r0, {r1, r4 - r10}
ldmfd sp!, {r4 - r10, pc}
ENDPROC(cpu_v7_do_suspend)
@@ -222,7 +222,7 @@ ENTRY(cpu_v7_do_resume)
mov ip, #0
mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
- ldmia r0, {r4 - r10}
+ ldmia r0, {r1, r4 - r10}
mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
mcr p15, 0, r5, c3, c0, 0 @ Domain ID
mcr p15, 0, r6, c2, c0, 0 @ TTB 0
@@ -245,6 +245,7 @@ ENTRY(cpu_v7_do_resume)
orr r3, r2, r4, lsl #20 @ phys addr
ldr r5, [r6, r4, lsl #2] @ save old translation
str r3, [r6, r4, lsl #2] @ virt index
+ sub r6, r6, r1 @ convert to virt translation base
ldr r2, =cpu_v7_resume_after_mmu
b cpu_v7_turn_mmu_on
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 054c1e8..9b3a0bf 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -416,7 +416,7 @@ ENTRY(cpu_xsc3_set_pte_ext)
.align
.globl cpu_xsc3_suspend_size
-.equ cpu_xsc3_suspend_size, 4 * 7
+.equ cpu_xsc3_suspend_size, 4 * 8
#ifdef CONFIG_PM
ENTRY(cpu_xsc3_do_suspend)
stmfd sp!, {r4 - r10, lr}
@@ -428,17 +428,17 @@ ENTRY(cpu_xsc3_do_suspend)
mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg
mrc p15, 0, r10, c1, c0, 0 @ control reg
bic r4, r4, #2 @ clear frequency change bit
- stmia r0, {r4 - r10} @ store cp regs
+ stmia r0, {r1, r4 - r10} @ store v:p offset + cp regs
ldmia sp!, {r4 - r10, pc}
ENDPROC(cpu_xsc3_do_suspend)
ENTRY(cpu_xsc3_do_resume)
- ldmia r0, {r4 - r10} @ load cp regs
- mov r1, #0
- mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB
- mcr p15, 0, r1, c7, c10, 4 @ drain write (&fill) buffer
- mcr p15, 0, r1, c7, c5, 4 @ flush prefetch buffer
- mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
+ ldmia r0, {r1, r4 - r10} @ load v:p offset + cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer
+ mcr p15, 0, ip, c7, c5, 4 @ flush prefetch buffer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
mcr p15, 0, r5, c15, c1, 0 @ CP access reg
mcr p15, 0, r6, c13, c0, 0 @ PID
@@ -457,12 +457,7 @@ ENTRY(cpu_xsc3_do_resume)
orr r3, r2, r4, lsl #20
ldr r5, [r8, r4, lsl #2]
str r3, [r8, r4, lsl #2]
-
- @ Mapping page table address in the page table
- mov r6, r8, lsr #20
- orr r3, r2, r6, lsl #20
- ldr r7, [r8, r6, lsl #2]
- str r3, [r8, r6, lsl #2]
+ sub r8, r8, r1 @ convert to virt table base
ldr r2, =cpu_xsc3_resume_after_mmu @ absolute virtual address
b cpu_xsc3_turn_on_mmu @ cache align execution
@@ -481,7 +476,6 @@ ENDPROC(cpu_xsc3_mmu_on)
cpu_xsc3_resume_after_mmu:
/* restore the temporary mapping */
str r5, [r8, r4, lsl #2]
- str r7, [r8, r6, lsl #2]
mov pc, lr
ENDPROC(cpu_xsc3_resume_after_mmu)
#else
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v2 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-06 19:12 ` [PATCH 2/5] ARM: pm: add generic CPU suspend/resume support Russell King - ARM Linux
@ 2011-02-07 12:01 ` Russell King - ARM Linux
2011-02-07 12:10 ` [PATCH v3 " Russell King - ARM Linux
0 siblings, 1 reply; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-07 12:01 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Feb 06, 2011 at 07:12:28PM +0000, Russell King - ARM Linux wrote:
> This adds core support for saving and restoring CPU coprocessor
> registers for suspend/resume support. This contains support for suspend
> with ARM920, ARM926, SA11x0, PXA25x, PXA27x, PXA3xx and V6 CPUs.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
Here's v2 of this patch. I've moved the MMU handling code into
arch/arm/kernel/sleep.S, so everyone can benefit from having this handled
in the same way, much like we do in head.S. I've also added a full
cache flush after the MMU is turned on to ensure that we don't leak
any cache lines into userspace for the MMU resume code. This should
make things a little more robust.
arch/arm/include/asm/glue-proc.h | 3 +
arch/arm/include/asm/proc-fns.h | 7 ++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/asm-offsets.c | 9 +++
arch/arm/kernel/sleep.S | 109 ++++++++++++++++++++++++++++++++++++
arch/arm/mm/proc-arm1020.S | 3 +
arch/arm/mm/proc-arm1020e.S | 3 +
arch/arm/mm/proc-arm1022.S | 3 +
arch/arm/mm/proc-arm1026.S | 3 +
arch/arm/mm/proc-arm6_7.S | 6 ++
arch/arm/mm/proc-arm720.S | 3 +
arch/arm/mm/proc-arm740.S | 3 +
arch/arm/mm/proc-arm7tdmi.S | 3 +
arch/arm/mm/proc-arm920.S | 37 ++++++++++++
arch/arm/mm/proc-arm922.S | 3 +
arch/arm/mm/proc-arm925.S | 3 +
arch/arm/mm/proc-arm926.S | 37 ++++++++++++
arch/arm/mm/proc-arm940.S | 3 +
arch/arm/mm/proc-arm946.S | 3 +
arch/arm/mm/proc-arm9tdmi.S | 3 +
arch/arm/mm/proc-fa526.S | 3 +
arch/arm/mm/proc-feroceon.S | 3 +
arch/arm/mm/proc-mohawk.S | 3 +
arch/arm/mm/proc-sa110.S | 3 +
arch/arm/mm/proc-sa1100.S | 39 +++++++++++++
arch/arm/mm/proc-v6.S | 48 ++++++++++++++++
arch/arm/mm/proc-v7.S | 114 ++++++++++++++++++++++++++++----------
arch/arm/mm/proc-xsc3.S | 48 ++++++++++++++++-
arch/arm/mm/proc-xscale.S | 45 ++++++++++++++-
29 files changed, 518 insertions(+), 33 deletions(-)
diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
index e3bf443..6469521 100644
--- a/arch/arm/include/asm/glue-proc.h
+++ b/arch/arm/include/asm/glue-proc.h
@@ -256,6 +256,9 @@
#define cpu_dcache_clean_area __glue(CPU_NAME,_dcache_clean_area)
#define cpu_do_switch_mm __glue(CPU_NAME,_switch_mm)
#define cpu_set_pte_ext __glue(CPU_NAME,_set_pte_ext)
+#define cpu_suspend_size __glue(CPU_NAME,_suspend_size)
+#define cpu_do_suspend __glue(CPU_NAME,_do_suspend)
+#define cpu_do_resume __glue(CPU_NAME,_do_resume)
#endif
#endif
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 6980215..8ec535e 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -66,6 +66,11 @@ extern struct processor {
* ignore 'ext'.
*/
void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
+
+ /* Suspend/resume */
+ unsigned int suspend_size;
+ void (*do_suspend)(void *);
+ void (*do_resume)(void *);
} processor;
#ifndef MULTI_CPU
@@ -86,6 +91,8 @@ extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
#endif
+extern void cpu_resume(void);
+
#include <asm/memory.h>
#ifdef CONFIG_MMU
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 185ee82..74554f1 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o isa.o
+obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 5302a91..927522c 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
#include <asm/glue-df.h>
#include <asm/glue-pf.h>
#include <asm/mach/arch.h>
@@ -116,6 +117,14 @@ int main(void)
#ifdef MULTI_PABORT
DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort));
#endif
+#ifdef MULTI_CPU
+ DEFINE(CPU_SLEEP_SIZE, offsetof(struct processor, suspend_size));
+ DEFINE(CPU_DO_SUSPEND, offsetof(struct processor, do_suspend));
+ DEFINE(CPU_DO_RESUME, offsetof(struct processor, do_resume));
+#endif
+#ifdef MULTI_CACHE
+ DEFINE(CACHE_FLUSH_KERN_ALL, offsetof(struct cpu_cache_fns, flush_kern_all));
+#endif
BLANK();
DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
new file mode 100644
index 0000000..ebe9ee8
--- /dev/null
+++ b/arch/arm/kernel/sleep.S
@@ -0,0 +1,109 @@
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+#include <asm/glue-cache.h>
+#include <asm/glue-proc.h>
+ .text
+
+/*
+ * Save CPU state for a suspend
+ * r1 = v:p offset
+ * r3 = virtual return function
+ * Note: sp is decremented to allocate space for CPU state on stack
+ * r0-r3,r9,r10,lr corrupted
+ */
+ENTRY(cpu_suspend)
+ mov r9, lr
+#ifdef MULTI_CPU
+ ldr r10, =processor
+ mov r2, sp @ current virtual SP
+ ldr r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+ ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
+ sub sp, sp, r0 @ allocate CPU state on stack
+ mov r0, sp @ save pointer
+ add ip, ip, r1 @ convert resume fn to phys
+ stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn
+ ldr r3, =sleep_save_sp
+ add r2, sp, r1 @ convert SP to phys
+ str r2, [r3] @ save phys SP
+ mov lr, pc
+ ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
+#else
+ mov r2, sp @ current virtual SP
+ ldr r0, =cpu_suspend_size
+ sub sp, sp, r0 @ allocate CPU state on stack
+ mov r0, sp @ save pointer
+ stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn
+ ldr r3, =sleep_save_sp
+ add r2, sp, r1 @ convert SP to phys
+ str r2, [r3] @ save phys SP
+ bl cpu_do_suspend
+#endif
+
+ @ flush data cache
+#ifdef MULTI_CACHE
+ ldr r10, =cpu_cache
+ mov lr, r9
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ mov lr, r9
+ b __cpuc_flush_kern_all
+#endif
+ENDPROC(cpu_suspend)
+ .ltorg
+
+/*
+ * r0 = control register value
+ * r1 = v:p offset (preserved by cpu_do_resume)
+ * r2 = phys page table base
+ * r3 = L1 section flags
+ */
+ENTRY(cpu_resume_mmu)
+ adr r4, cpu_resume_turn_mmu_on
+ mov r4, r4, lsr #20
+ orr r3, r3, r4, lsl #20
+ ldr r5, [r2, r4, lsl #2] @ save old mapping
+ str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code
+ sub r2, r2, r1
+ ldr r3, =cpu_resume_after_mmu
+ b cpu_resume_turn_mmu_on
+ENDPROC(cpu_resume_mmu)
+ .align 5
+cpu_resume_turn_mmu_on:
+ mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, caches, etc
+ mrc p15, 0, r0, c0, c0, 0 @ read id reg
+ mov r0, r0
+ mov r0, r0
+ sub pc, r3 @ jump to virtual address
+ENDPROC(cpu_resume_turn_mmu_on)
+cpu_resume_after_mmu:
+ str r5, [r2, r4, lsl #2] @ restore old mapping
+#ifdef MULTI_CACHE
+ ldr r10, =cpu_cache
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ b __cpuc_flush_kern_all
+#endif
+
+/*
+ * Note: Yes, part of the following code is located into the .data section.
+ * This is to allow sleep_save_sp to be accessed with a relative load
+ * while we can't rely on any MMU translation. We could have put
+ * sleep_save_sp in the .text section as well, but some setups might
+ * insist on it to be truly read-only.
+ */
+ .data
+ .align
+ENTRY(cpu_resume)
+ ldr r0, sleep_save_sp @ stack phys addr
+ msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
+#ifdef MULTI_CPU
+ ldmia r0!, {r1, sp, lr, pc} @ load v:p, stack, return fn, resume fn
+#else
+ ldmia r0!, {r1, sp, lr} @ load v:p, stack, return fn
+ b cpu_do_resume
+#endif
+ENDPROC(cpu_resume)
+
+sleep_save_sp:
+ .word 0 @ preserve stack phys ptr here
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index bcf748d..226e3d8 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -493,6 +493,9 @@ arm1020_processor_functions:
.word cpu_arm1020_dcache_clean_area
.word cpu_arm1020_switch_mm
.word cpu_arm1020_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1020_processor_functions, . - arm1020_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index ab7ec26..86d9c2c 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -474,6 +474,9 @@ arm1020e_processor_functions:
.word cpu_arm1020e_dcache_clean_area
.word cpu_arm1020e_switch_mm
.word cpu_arm1020e_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1020e_processor_functions, . - arm1020e_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 831c5e5..83d3dd3 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -457,6 +457,9 @@ arm1022_processor_functions:
.word cpu_arm1022_dcache_clean_area
.word cpu_arm1022_switch_mm
.word cpu_arm1022_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1022_processor_functions, . - arm1022_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index e3f7e9a..686043e 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -452,6 +452,9 @@ arm1026_processor_functions:
.word cpu_arm1026_dcache_clean_area
.word cpu_arm1026_switch_mm
.word cpu_arm1026_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1026_processor_functions, . - arm1026_processor_functions
.section .rodata
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 6a7be18..5f79dc4 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -284,6 +284,9 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_dcache_clean_area
.word cpu_arm6_switch_mm
.word cpu_arm6_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm6_processor_functions, . - arm6_processor_functions
/*
@@ -301,6 +304,9 @@ ENTRY(arm7_processor_functions)
.word cpu_arm7_dcache_clean_area
.word cpu_arm7_switch_mm
.word cpu_arm7_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm7_processor_functions, . - arm7_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index c285395..665266d 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -185,6 +185,9 @@ ENTRY(arm720_processor_functions)
.word cpu_arm720_dcache_clean_area
.word cpu_arm720_switch_mm
.word cpu_arm720_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm720_processor_functions, . - arm720_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 38b27dc..6f9d12e 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -130,6 +130,9 @@ ENTRY(arm740_processor_functions)
.word cpu_arm740_dcache_clean_area
.word cpu_arm740_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm740_processor_functions, . - arm740_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 0c9786d..e4c165c 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -70,6 +70,9 @@ ENTRY(arm7tdmi_processor_functions)
.word cpu_arm7tdmi_dcache_clean_area
.word cpu_arm7tdmi_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 6109f27..b2705de 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -387,6 +387,40 @@ ENTRY(cpu_arm920_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl arm920_suspend_size
+.equ arm920_suspend_size, 4 * 3
+#ifdef CONFIG_PM
+ENTRY(arm920_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(arm920_do_suspend)
+
+ENTRY(arm920_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
+ ldmia r0, {r4 - r7}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mov r0, r7 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(arm920_do_resume)
+#else
+#define arm920_do_suspend 0
+#define arm920_do_resume 0
+#endif
+
__CPUINIT
.type __arm920_setup, #function
@@ -432,6 +466,9 @@ arm920_processor_functions:
.word cpu_arm920_dcache_clean_area
.word cpu_arm920_switch_mm
.word cpu_arm920_set_pte_ext
+ .word arm920_suspend_size
+ .word arm920_do_suspend
+ .word arm920_do_resume
.size arm920_processor_functions, . - arm920_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index bb2f0f4..36154b1 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -436,6 +436,9 @@ arm922_processor_functions:
.word cpu_arm922_dcache_clean_area
.word cpu_arm922_switch_mm
.word cpu_arm922_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm922_processor_functions, . - arm922_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index c13e01a..89c5e00 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -503,6 +503,9 @@ arm925_processor_functions:
.word cpu_arm925_dcache_clean_area
.word cpu_arm925_switch_mm
.word cpu_arm925_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm925_processor_functions, . - arm925_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 42eb431..3beb784 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -401,6 +401,40 @@ ENTRY(cpu_arm926_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl arm926_suspend_size
+.equ arm926_suspend_size, 4 * 3
+#ifdef CONFIG_PM
+ENTRY(arm926_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(arm926_do_suspend)
+
+ENTRY(arm926_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
+ ldmia r0, {r4 - r7}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mov r0, r7 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(arm926_do_resume)
+#else
+#define arm926_do_suspend 0
+#define arm926_do_resume 0
+#endif
+
__CPUINIT
.type __arm926_setup, #function
@@ -456,6 +490,9 @@ arm926_processor_functions:
.word cpu_arm926_dcache_clean_area
.word cpu_arm926_switch_mm
.word cpu_arm926_set_pte_ext
+ .word arm926_suspend_size
+ .word arm926_do_suspend
+ .word arm926_do_resume
.size arm926_processor_functions, . - arm926_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index 7b11cdb..26aea3f 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -363,6 +363,9 @@ ENTRY(arm940_processor_functions)
.word cpu_arm940_dcache_clean_area
.word cpu_arm940_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm940_processor_functions, . - arm940_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 1a5bbf0..8063345 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -419,6 +419,9 @@ ENTRY(arm946_processor_functions)
.word cpu_arm946_dcache_clean_area
.word cpu_arm946_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm946_processor_functions, . - arm946_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index db67e31..7b7ebd4 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -70,6 +70,9 @@ ENTRY(arm9tdmi_processor_functions)
.word cpu_arm9tdmi_dcache_clean_area
.word cpu_arm9tdmi_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 7c9ad62..fc2a4ae 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -195,6 +195,9 @@ fa526_processor_functions:
.word cpu_fa526_dcache_clean_area
.word cpu_fa526_switch_mm
.word cpu_fa526_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size fa526_processor_functions, . - fa526_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index b4597ed..d3883ee 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -554,6 +554,9 @@ feroceon_processor_functions:
.word cpu_feroceon_dcache_clean_area
.word cpu_feroceon_switch_mm
.word cpu_feroceon_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size feroceon_processor_functions, . - feroceon_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 4458ee6..9d4f2ae 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -388,6 +388,9 @@ mohawk_processor_functions:
.word cpu_mohawk_dcache_clean_area
.word cpu_mohawk_switch_mm
.word cpu_mohawk_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size mohawk_processor_functions, . - mohawk_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 5aa8d59..46f09ed 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -203,6 +203,9 @@ ENTRY(sa110_processor_functions)
.word cpu_sa110_dcache_clean_area
.word cpu_sa110_switch_mm
.word cpu_sa110_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size sa110_processor_functions, . - sa110_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 2ac4e6f..74483d1 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -169,6 +169,42 @@ ENTRY(cpu_sa1100_set_pte_ext)
#endif
mov pc, lr
+.globl cpu_sa1100_suspend_size
+.equ cpu_sa1100_suspend_size, 4*4
+#ifdef CONFIG_PM
+ENTRY(cpu_sa1100_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c3, c0, 0 @ domain ID
+ mrc p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c1, c0, 0 @ control reg
+ stmia r0, {r4 - r7} @ store cp regs
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(cpu_sa1100_do_suspend)
+
+ENTRY(cpu_sa1100_do_resume)
+ ldmia r0, {r4 - r7} @ load cp regs
+ mov r1, #0
+ mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs
+ mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache
+ mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
+ mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB
+
+ mcr p15, 0, r4, c3, c0, 0 @ domain ID
+ mcr p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mov r0, r7 @ control register
+ mov r2, r5, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(cpu_sa1100_do_resume)
+#else
+#define cpu_sa1100_do_suspend 0
+#define cpu_sa1100_do_resume 0
+#endif
+
__CPUINIT
.type __sa1100_setup, #function
@@ -218,6 +254,9 @@ ENTRY(sa1100_processor_functions)
.word cpu_sa1100_dcache_clean_area
.word cpu_sa1100_switch_mm
.word cpu_sa1100_set_pte_ext
+ .word cpu_sa1100_suspend_size
+ .word cpu_sa1100_do_suspend
+ .word cpu_sa1100_do_resume
.size sa1100_processor_functions, . - sa1100_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 59a7e1f..c86f451 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -121,6 +121,51 @@ ENTRY(cpu_v6_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
+.globl cpu_v6_suspend_size
+.equ cpu_v6_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_v6_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ Translation table base 0
+ mrc p15, 0, r7, c2, c0, 1 @ Translation table base 1
+ mrc p15, 0, r8, c1, c0, 1 @ auxillary control register
+ mrc p15, 0, r9, c1, c0, 2 @ co-processor access control
+ mrc p15, 0, r10, c1, c0, 0 @ control register
+ stmia r0, {r4 - r10}
+ ldmfd sp!, {r4- r10, pc}
+ENDPROC(cpu_v6_do_suspend)
+
+ENTRY(cpu_v6_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c14, 0 @ clean+invalidate D cache
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
+ ldmia r0, {r4 - r10}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ Translation table base 0
+ mcr p15, 0, r7, c2, c0, 1 @ Translation table base 1
+ mcr p15, 0, r8, c1, c0, 1 @ auxillary control register
+ mcr p15, 0, r9, c1, c0, 2 @ co-processor access control
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+ mcr p15, 0, ip, c7, c5, 4 @ ISB
+ mov r0, r10 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, cpu_resume_l1_flags
+ b cpu_resume_mmu
+ENDPROC(cpu_v6_do_resume)
+cpu_resume_l1_flags:
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v6_do_suspend 0
+#define cpu_v6_do_resume 0
+#endif
.type cpu_v6_name, #object
@@ -206,6 +251,9 @@ ENTRY(v6_processor_functions)
.word cpu_v6_dcache_clean_area
.word cpu_v6_switch_mm
.word cpu_v6_set_pte_ext
+ .word cpu_v6_suspend_size
+ .word cpu_v6_do_suspend
+ .word cpu_v6_do_resume
.size v6_processor_functions, . - v6_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 0c1172b..8e6142d 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -171,6 +171,85 @@ cpu_v7_name:
.ascii "ARMv7 Processor"
.align
+ /*
+ * Memory region attributes with SCTLR.TRE=1
+ *
+ * n = TEX[0],C,B
+ * TR = PRRR[2n+1:2n] - memory type
+ * IR = NMRR[2n+1:2n] - inner cacheable property
+ * OR = NMRR[2n+17:2n+16] - outer cacheable property
+ *
+ * n TR IR OR
+ * UNCACHED 000 00
+ * BUFFERABLE 001 10 00 00
+ * WRITETHROUGH 010 10 10 10
+ * WRITEBACK 011 10 11 11
+ * reserved 110
+ * WRITEALLOC 111 10 01 01
+ * DEV_SHARED 100 01
+ * DEV_NONSHARED 100 01
+ * DEV_WC 001 10
+ * DEV_CACHED 011 10
+ *
+ * Other attributes:
+ *
+ * DS0 = PRRR[16] = 0 - device shareable property
+ * DS1 = PRRR[17] = 1 - device shareable property
+ * NS0 = PRRR[18] = 0 - normal shareable property
+ * NS1 = PRRR[19] = 1 - normal shareable property
+ * NOS = PRRR[24+n] = 1 - not outer shareable
+ */
+.equ PRRR, 0xff0a81a8
+.equ NMRR, 0x40e040e0
+
+/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
+.globl cpu_v7_suspend_size
+.equ cpu_v7_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_v7_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB 0
+ mrc p15, 0, r7, c2, c0, 1 @ TTB 1
+ mrc p15, 0, r8, c1, c0, 0 @ Control register
+ mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control
+ stmia r0, {r4 - r10}
+ ldmfd sp!, {r4 - r10, pc}
+ENDPROC(cpu_v7_do_suspend)
+
+ENTRY(cpu_v7_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ ldmia r0, {r4 - r10}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB 0
+ mcr p15, 0, r7, c2, c0, 1 @ TTB 1
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+ mcr p15, 0, r9, c1, c0, 1 @ Auxillary control register
+ mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control
+ ldr r4, =PRRR @ PRRR
+ ldr r5, =NMRR @ NMRR
+ mcr p15, 0, r4, c10, c2, 0 @ write PRRR
+ mcr p15, 0, r5, c10, c2, 1 @ write NMRR
+ isb
+ mov r0, r8 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, cpu_resume_l1_flags
+ b cpu_resume_mmu
+ENDPROC(cpu_v7_do_resume)
+cpu_resume_l1_flags:
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v7_do_suspend 0
+#define cpu_v7_do_resume 0
+#endif
+
__CPUINIT
/*
@@ -276,36 +355,8 @@ __v7_setup:
ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
- /*
- * Memory region attributes with SCTLR.TRE=1
- *
- * n = TEX[0],C,B
- * TR = PRRR[2n+1:2n] - memory type
- * IR = NMRR[2n+1:2n] - inner cacheable property
- * OR = NMRR[2n+17:2n+16] - outer cacheable property
- *
- * n TR IR OR
- * UNCACHED 000 00
- * BUFFERABLE 001 10 00 00
- * WRITETHROUGH 010 10 10 10
- * WRITEBACK 011 10 11 11
- * reserved 110
- * WRITEALLOC 111 10 01 01
- * DEV_SHARED 100 01
- * DEV_NONSHARED 100 01
- * DEV_WC 001 10
- * DEV_CACHED 011 10
- *
- * Other attributes:
- *
- * DS0 = PRRR[16] = 0 - device shareable property
- * DS1 = PRRR[17] = 1 - device shareable property
- * NS0 = PRRR[18] = 0 - normal shareable property
- * NS1 = PRRR[19] = 1 - normal shareable property
- * NOS = PRRR[24+n] = 1 - not outer shareable
- */
- ldr r5, =0xff0a81a8 @ PRRR
- ldr r6, =0x40e040e0 @ NMRR
+ ldr r5, =PRRR @ PRRR
+ ldr r6, =NMRR @ NMRR
mcr p15, 0, r5, c10, c2, 0 @ write PRRR
mcr p15, 0, r6, c10, c2, 1 @ write NMRR
#endif
@@ -351,6 +402,9 @@ ENTRY(v7_processor_functions)
.word cpu_v7_dcache_clean_area
.word cpu_v7_switch_mm
.word cpu_v7_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size v7_processor_functions, . - v7_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index ec26355..63d8b20 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -413,9 +413,52 @@ ENTRY(cpu_xsc3_set_pte_ext)
mov pc, lr
.ltorg
-
.align
+.globl cpu_xsc3_suspend_size
+.equ cpu_xsc3_suspend_size, 4 * 8
+#ifdef CONFIG_PM
+ENTRY(cpu_xsc3_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+ mrc p15, 0, r5, c15, c1, 0 @ CP access reg
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c3, c0, 0 @ domain ID
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r1, r4 - r10} @ store v:p offset + cp regs
+ ldmia sp!, {r4 - r10, pc}
+ENDPROC(cpu_xsc3_do_suspend)
+
+ENTRY(cpu_xsc3_do_resume)
+ ldmia r0, {r1, r4 - r10} @ load v:p offset + cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer
+ mcr p15, 0, ip, c7, c5, 4 @ flush prefetch buffer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
+ mcr p15, 0, r5, c15, c1, 0 @ CP access reg
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mcr p15, 0, r7, c3, c0, 0 @ domain ID
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+
+ @ temporarily map resume_turn_on_mmu into the page table,
+ @ otherwise prefetch abort occurs after MMU is turned on
+ mov r0, r10 @ control register
+ mov r2, r8, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =0x542e @ section flags
+ b cpu_resume_mmu
+ENDPROC(cpu_xsc3_do_resume)
+#else
+#define cpu_xsc3_do_suspend 0
+#define cpu_xsc3_do_resume 0
+#endif
+
__CPUINIT
.type __xsc3_setup, #function
@@ -476,6 +519,9 @@ ENTRY(xsc3_processor_functions)
.word cpu_xsc3_dcache_clean_area
.word cpu_xsc3_switch_mm
.word cpu_xsc3_set_pte_ext
+ .word cpu_xsc3_suspend_size
+ .word cpu_xsc3_do_suspend
+ .word cpu_xsc3_do_resume
.size xsc3_processor_functions, . - xsc3_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 5a37c5e..086038c 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -513,11 +513,49 @@ ENTRY(cpu_xscale_set_pte_ext)
xscale_set_pte_ext_epilogue
mov pc, lr
-
.ltorg
-
.align
+.globl cpu_xscale_suspend_size
+.equ cpu_xscale_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_xscale_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+ mrc p15, 0, r5, c15, c1, 0 @ CP access reg
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c3, c0, 0 @ domain ID
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r4 - r10} @ store cp regs
+ ldmfd sp!, {r4 - r10, pc}
+ENDPROC(cpu_xscale_do_suspend)
+
+ENTRY(cpu_xscale_do_resume)
+ ldmia r0, {r4 - r10} @ load cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
+ mcr p15, 0, r5, c15, c1, 0 @ CP access reg
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mcr p15, 0, r7, c3, c0, 0 @ domain ID
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mov r0, r10 @ control register
+ mov r2, r8, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(cpu_xscale_do_resume)
+#else
+#define cpu_xscale_do_suspend 0
+#define cpu_xscale_do_resume 0
+#endif
+
__CPUINIT
.type __xscale_setup, #function
@@ -565,6 +603,9 @@ ENTRY(xscale_processor_functions)
.word cpu_xscale_dcache_clean_area
.word cpu_xscale_switch_mm
.word cpu_xscale_set_pte_ext
+ .word cpu_xscale_suspend_size
+ .word cpu_xscale_do_suspend
+ .word cpu_xscale_do_resume
.size xscale_processor_functions, . - xscale_processor_functions
.section ".rodata"
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 12:01 ` [PATCH v2 " Russell King - ARM Linux
@ 2011-02-07 12:10 ` Russell King - ARM Linux
2011-02-07 13:21 ` saeed bishara
0 siblings, 1 reply; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-07 12:10 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 07, 2011 at 12:01:04PM +0000, Russell King - ARM Linux wrote:
> On Sun, Feb 06, 2011 at 07:12:28PM +0000, Russell King - ARM Linux wrote:
> > This adds core support for saving and restoring CPU coprocessor
> > registers for suspend/resume support. This contains support for suspend
> > with ARM920, ARM926, SA11x0, PXA25x, PXA27x, PXA3xx and V6 CPUs.
> >
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > ---
Gah. No sooner than v2, than there's a v3 of this patch, replacing a
typo'd sub rather than mov instruction, and adding a .ltorg to avoid
.text wastage.
arch/arm/include/asm/glue-proc.h | 3 +
arch/arm/include/asm/proc-fns.h | 7 ++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/asm-offsets.c | 9 +++
arch/arm/kernel/sleep.S | 110 ++++++++++++++++++++++++++++++++++++
arch/arm/mm/proc-arm1020.S | 3 +
arch/arm/mm/proc-arm1020e.S | 3 +
arch/arm/mm/proc-arm1022.S | 3 +
arch/arm/mm/proc-arm1026.S | 3 +
arch/arm/mm/proc-arm6_7.S | 6 ++
arch/arm/mm/proc-arm720.S | 3 +
arch/arm/mm/proc-arm740.S | 3 +
arch/arm/mm/proc-arm7tdmi.S | 3 +
arch/arm/mm/proc-arm920.S | 37 ++++++++++++
arch/arm/mm/proc-arm922.S | 3 +
arch/arm/mm/proc-arm925.S | 3 +
arch/arm/mm/proc-arm926.S | 37 ++++++++++++
arch/arm/mm/proc-arm940.S | 3 +
arch/arm/mm/proc-arm946.S | 3 +
arch/arm/mm/proc-arm9tdmi.S | 3 +
arch/arm/mm/proc-fa526.S | 3 +
arch/arm/mm/proc-feroceon.S | 3 +
arch/arm/mm/proc-mohawk.S | 3 +
arch/arm/mm/proc-sa110.S | 3 +
arch/arm/mm/proc-sa1100.S | 39 +++++++++++++
arch/arm/mm/proc-v6.S | 48 ++++++++++++++++
arch/arm/mm/proc-v7.S | 114 ++++++++++++++++++++++++++++----------
arch/arm/mm/proc-xsc3.S | 48 ++++++++++++++++-
arch/arm/mm/proc-xscale.S | 45 ++++++++++++++-
29 files changed, 519 insertions(+), 33 deletions(-)
diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
index e3bf443..6469521 100644
--- a/arch/arm/include/asm/glue-proc.h
+++ b/arch/arm/include/asm/glue-proc.h
@@ -256,6 +256,9 @@
#define cpu_dcache_clean_area __glue(CPU_NAME,_dcache_clean_area)
#define cpu_do_switch_mm __glue(CPU_NAME,_switch_mm)
#define cpu_set_pte_ext __glue(CPU_NAME,_set_pte_ext)
+#define cpu_suspend_size __glue(CPU_NAME,_suspend_size)
+#define cpu_do_suspend __glue(CPU_NAME,_do_suspend)
+#define cpu_do_resume __glue(CPU_NAME,_do_resume)
#endif
#endif
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 6980215..8ec535e 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -66,6 +66,11 @@ extern struct processor {
* ignore 'ext'.
*/
void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
+
+ /* Suspend/resume */
+ unsigned int suspend_size;
+ void (*do_suspend)(void *);
+ void (*do_resume)(void *);
} processor;
#ifndef MULTI_CPU
@@ -86,6 +91,8 @@ extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
#endif
+extern void cpu_resume(void);
+
#include <asm/memory.h>
#ifdef CONFIG_MMU
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 185ee82..74554f1 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o isa.o
+obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 5302a91..927522c 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
#include <asm/glue-df.h>
#include <asm/glue-pf.h>
#include <asm/mach/arch.h>
@@ -116,6 +117,14 @@ int main(void)
#ifdef MULTI_PABORT
DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort));
#endif
+#ifdef MULTI_CPU
+ DEFINE(CPU_SLEEP_SIZE, offsetof(struct processor, suspend_size));
+ DEFINE(CPU_DO_SUSPEND, offsetof(struct processor, do_suspend));
+ DEFINE(CPU_DO_RESUME, offsetof(struct processor, do_resume));
+#endif
+#ifdef MULTI_CACHE
+ DEFINE(CACHE_FLUSH_KERN_ALL, offsetof(struct cpu_cache_fns, flush_kern_all));
+#endif
BLANK();
DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
new file mode 100644
index 0000000..9f106fa
--- /dev/null
+++ b/arch/arm/kernel/sleep.S
@@ -0,0 +1,110 @@
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+#include <asm/glue-cache.h>
+#include <asm/glue-proc.h>
+ .text
+
+/*
+ * Save CPU state for a suspend
+ * r1 = v:p offset
+ * r3 = virtual return function
+ * Note: sp is decremented to allocate space for CPU state on stack
+ * r0-r3,r9,r10,lr corrupted
+ */
+ENTRY(cpu_suspend)
+ mov r9, lr
+#ifdef MULTI_CPU
+ ldr r10, =processor
+ mov r2, sp @ current virtual SP
+ ldr r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+ ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
+ sub sp, sp, r0 @ allocate CPU state on stack
+ mov r0, sp @ save pointer
+ add ip, ip, r1 @ convert resume fn to phys
+ stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn
+ ldr r3, =sleep_save_sp
+ add r2, sp, r1 @ convert SP to phys
+ str r2, [r3] @ save phys SP
+ mov lr, pc
+ ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
+#else
+ mov r2, sp @ current virtual SP
+ ldr r0, =cpu_suspend_size
+ sub sp, sp, r0 @ allocate CPU state on stack
+ mov r0, sp @ save pointer
+ stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn
+ ldr r3, =sleep_save_sp
+ add r2, sp, r1 @ convert SP to phys
+ str r2, [r3] @ save phys SP
+ bl cpu_do_suspend
+#endif
+
+ @ flush data cache
+#ifdef MULTI_CACHE
+ ldr r10, =cpu_cache
+ mov lr, r9
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ mov lr, r9
+ b __cpuc_flush_kern_all
+#endif
+ENDPROC(cpu_suspend)
+ .ltorg
+
+/*
+ * r0 = control register value
+ * r1 = v:p offset (preserved by cpu_do_resume)
+ * r2 = phys page table base
+ * r3 = L1 section flags
+ */
+ENTRY(cpu_resume_mmu)
+ adr r4, cpu_resume_turn_mmu_on
+ mov r4, r4, lsr #20
+ orr r3, r3, r4, lsl #20
+ ldr r5, [r2, r4, lsl #2] @ save old mapping
+ str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code
+ sub r2, r2, r1
+ ldr r3, =cpu_resume_after_mmu
+ b cpu_resume_turn_mmu_on
+ENDPROC(cpu_resume_mmu)
+ .ltorg
+ .align 5
+cpu_resume_turn_mmu_on:
+ mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, caches, etc
+ mrc p15, 0, r0, c0, c0, 0 @ read id reg
+ mov r0, r0
+ mov r0, r0
+ mov pc, r3 @ jump to virtual address
+ENDPROC(cpu_resume_turn_mmu_on)
+cpu_resume_after_mmu:
+ str r5, [r2, r4, lsl #2] @ restore old mapping
+#ifdef MULTI_CACHE
+ ldr r10, =cpu_cache
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ b __cpuc_flush_kern_all
+#endif
+
+/*
+ * Note: Yes, part of the following code is located into the .data section.
+ * This is to allow sleep_save_sp to be accessed with a relative load
+ * while we can't rely on any MMU translation. We could have put
+ * sleep_save_sp in the .text section as well, but some setups might
+ * insist on it to be truly read-only.
+ */
+ .data
+ .align
+ENTRY(cpu_resume)
+ ldr r0, sleep_save_sp @ stack phys addr
+ msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
+#ifdef MULTI_CPU
+ ldmia r0!, {r1, sp, lr, pc} @ load v:p, stack, return fn, resume fn
+#else
+ ldmia r0!, {r1, sp, lr} @ load v:p, stack, return fn
+ b cpu_do_resume
+#endif
+ENDPROC(cpu_resume)
+
+sleep_save_sp:
+ .word 0 @ preserve stack phys ptr here
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index bcf748d..226e3d8 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -493,6 +493,9 @@ arm1020_processor_functions:
.word cpu_arm1020_dcache_clean_area
.word cpu_arm1020_switch_mm
.word cpu_arm1020_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1020_processor_functions, . - arm1020_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index ab7ec26..86d9c2c 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -474,6 +474,9 @@ arm1020e_processor_functions:
.word cpu_arm1020e_dcache_clean_area
.word cpu_arm1020e_switch_mm
.word cpu_arm1020e_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1020e_processor_functions, . - arm1020e_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 831c5e5..83d3dd3 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -457,6 +457,9 @@ arm1022_processor_functions:
.word cpu_arm1022_dcache_clean_area
.word cpu_arm1022_switch_mm
.word cpu_arm1022_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1022_processor_functions, . - arm1022_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index e3f7e9a..686043e 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -452,6 +452,9 @@ arm1026_processor_functions:
.word cpu_arm1026_dcache_clean_area
.word cpu_arm1026_switch_mm
.word cpu_arm1026_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1026_processor_functions, . - arm1026_processor_functions
.section .rodata
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 6a7be18..5f79dc4 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -284,6 +284,9 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_dcache_clean_area
.word cpu_arm6_switch_mm
.word cpu_arm6_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm6_processor_functions, . - arm6_processor_functions
/*
@@ -301,6 +304,9 @@ ENTRY(arm7_processor_functions)
.word cpu_arm7_dcache_clean_area
.word cpu_arm7_switch_mm
.word cpu_arm7_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm7_processor_functions, . - arm7_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index c285395..665266d 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -185,6 +185,9 @@ ENTRY(arm720_processor_functions)
.word cpu_arm720_dcache_clean_area
.word cpu_arm720_switch_mm
.word cpu_arm720_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm720_processor_functions, . - arm720_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 38b27dc..6f9d12e 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -130,6 +130,9 @@ ENTRY(arm740_processor_functions)
.word cpu_arm740_dcache_clean_area
.word cpu_arm740_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm740_processor_functions, . - arm740_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 0c9786d..e4c165c 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -70,6 +70,9 @@ ENTRY(arm7tdmi_processor_functions)
.word cpu_arm7tdmi_dcache_clean_area
.word cpu_arm7tdmi_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 6109f27..b2705de 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -387,6 +387,40 @@ ENTRY(cpu_arm920_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl arm920_suspend_size
+.equ arm920_suspend_size, 4 * 3
+#ifdef CONFIG_PM
+ENTRY(arm920_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(arm920_do_suspend)
+
+ENTRY(arm920_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
+ ldmia r0, {r4 - r7}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mov r0, r7 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(arm920_do_resume)
+#else
+#define arm920_do_suspend 0
+#define arm920_do_resume 0
+#endif
+
__CPUINIT
.type __arm920_setup, #function
@@ -432,6 +466,9 @@ arm920_processor_functions:
.word cpu_arm920_dcache_clean_area
.word cpu_arm920_switch_mm
.word cpu_arm920_set_pte_ext
+ .word arm920_suspend_size
+ .word arm920_do_suspend
+ .word arm920_do_resume
.size arm920_processor_functions, . - arm920_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index bb2f0f4..36154b1 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -436,6 +436,9 @@ arm922_processor_functions:
.word cpu_arm922_dcache_clean_area
.word cpu_arm922_switch_mm
.word cpu_arm922_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm922_processor_functions, . - arm922_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index c13e01a..89c5e00 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -503,6 +503,9 @@ arm925_processor_functions:
.word cpu_arm925_dcache_clean_area
.word cpu_arm925_switch_mm
.word cpu_arm925_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm925_processor_functions, . - arm925_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 42eb431..3beb784 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -401,6 +401,40 @@ ENTRY(cpu_arm926_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl arm926_suspend_size
+.equ arm926_suspend_size, 4 * 3
+#ifdef CONFIG_PM
+ENTRY(arm926_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(arm926_do_suspend)
+
+ENTRY(arm926_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
+ ldmia r0, {r4 - r7}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mov r0, r7 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(arm926_do_resume)
+#else
+#define arm926_do_suspend 0
+#define arm926_do_resume 0
+#endif
+
__CPUINIT
.type __arm926_setup, #function
@@ -456,6 +490,9 @@ arm926_processor_functions:
.word cpu_arm926_dcache_clean_area
.word cpu_arm926_switch_mm
.word cpu_arm926_set_pte_ext
+ .word arm926_suspend_size
+ .word arm926_do_suspend
+ .word arm926_do_resume
.size arm926_processor_functions, . - arm926_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index 7b11cdb..26aea3f 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -363,6 +363,9 @@ ENTRY(arm940_processor_functions)
.word cpu_arm940_dcache_clean_area
.word cpu_arm940_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm940_processor_functions, . - arm940_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 1a5bbf0..8063345 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -419,6 +419,9 @@ ENTRY(arm946_processor_functions)
.word cpu_arm946_dcache_clean_area
.word cpu_arm946_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm946_processor_functions, . - arm946_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index db67e31..7b7ebd4 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -70,6 +70,9 @@ ENTRY(arm9tdmi_processor_functions)
.word cpu_arm9tdmi_dcache_clean_area
.word cpu_arm9tdmi_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 7c9ad62..fc2a4ae 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -195,6 +195,9 @@ fa526_processor_functions:
.word cpu_fa526_dcache_clean_area
.word cpu_fa526_switch_mm
.word cpu_fa526_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size fa526_processor_functions, . - fa526_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index b4597ed..d3883ee 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -554,6 +554,9 @@ feroceon_processor_functions:
.word cpu_feroceon_dcache_clean_area
.word cpu_feroceon_switch_mm
.word cpu_feroceon_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size feroceon_processor_functions, . - feroceon_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 4458ee6..9d4f2ae 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -388,6 +388,9 @@ mohawk_processor_functions:
.word cpu_mohawk_dcache_clean_area
.word cpu_mohawk_switch_mm
.word cpu_mohawk_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size mohawk_processor_functions, . - mohawk_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 5aa8d59..46f09ed 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -203,6 +203,9 @@ ENTRY(sa110_processor_functions)
.word cpu_sa110_dcache_clean_area
.word cpu_sa110_switch_mm
.word cpu_sa110_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size sa110_processor_functions, . - sa110_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 2ac4e6f..74483d1 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -169,6 +169,42 @@ ENTRY(cpu_sa1100_set_pte_ext)
#endif
mov pc, lr
+.globl cpu_sa1100_suspend_size
+.equ cpu_sa1100_suspend_size, 4*4
+#ifdef CONFIG_PM
+ENTRY(cpu_sa1100_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c3, c0, 0 @ domain ID
+ mrc p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c1, c0, 0 @ control reg
+ stmia r0, {r4 - r7} @ store cp regs
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(cpu_sa1100_do_suspend)
+
+ENTRY(cpu_sa1100_do_resume)
+ ldmia r0, {r4 - r7} @ load cp regs
+ mov r1, #0
+ mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs
+ mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache
+ mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
+ mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB
+
+ mcr p15, 0, r4, c3, c0, 0 @ domain ID
+ mcr p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mov r0, r7 @ control register
+ mov r2, r5, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(cpu_sa1100_do_resume)
+#else
+#define cpu_sa1100_do_suspend 0
+#define cpu_sa1100_do_resume 0
+#endif
+
__CPUINIT
.type __sa1100_setup, #function
@@ -218,6 +254,9 @@ ENTRY(sa1100_processor_functions)
.word cpu_sa1100_dcache_clean_area
.word cpu_sa1100_switch_mm
.word cpu_sa1100_set_pte_ext
+ .word cpu_sa1100_suspend_size
+ .word cpu_sa1100_do_suspend
+ .word cpu_sa1100_do_resume
.size sa1100_processor_functions, . - sa1100_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 59a7e1f..c86f451 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -121,6 +121,51 @@ ENTRY(cpu_v6_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
+.globl cpu_v6_suspend_size
+.equ cpu_v6_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_v6_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ Translation table base 0
+ mrc p15, 0, r7, c2, c0, 1 @ Translation table base 1
+ mrc p15, 0, r8, c1, c0, 1 @ auxillary control register
+ mrc p15, 0, r9, c1, c0, 2 @ co-processor access control
+ mrc p15, 0, r10, c1, c0, 0 @ control register
+ stmia r0, {r4 - r10}
+ ldmfd sp!, {r4- r10, pc}
+ENDPROC(cpu_v6_do_suspend)
+
+ENTRY(cpu_v6_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c14, 0 @ clean+invalidate D cache
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
+ ldmia r0, {r4 - r10}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ Translation table base 0
+ mcr p15, 0, r7, c2, c0, 1 @ Translation table base 1
+ mcr p15, 0, r8, c1, c0, 1 @ auxillary control register
+ mcr p15, 0, r9, c1, c0, 2 @ co-processor access control
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+ mcr p15, 0, ip, c7, c5, 4 @ ISB
+ mov r0, r10 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, cpu_resume_l1_flags
+ b cpu_resume_mmu
+ENDPROC(cpu_v6_do_resume)
+cpu_resume_l1_flags:
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v6_do_suspend 0
+#define cpu_v6_do_resume 0
+#endif
.type cpu_v6_name, #object
@@ -206,6 +251,9 @@ ENTRY(v6_processor_functions)
.word cpu_v6_dcache_clean_area
.word cpu_v6_switch_mm
.word cpu_v6_set_pte_ext
+ .word cpu_v6_suspend_size
+ .word cpu_v6_do_suspend
+ .word cpu_v6_do_resume
.size v6_processor_functions, . - v6_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 0c1172b..8e6142d 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -171,6 +171,85 @@ cpu_v7_name:
.ascii "ARMv7 Processor"
.align
+ /*
+ * Memory region attributes with SCTLR.TRE=1
+ *
+ * n = TEX[0],C,B
+ * TR = PRRR[2n+1:2n] - memory type
+ * IR = NMRR[2n+1:2n] - inner cacheable property
+ * OR = NMRR[2n+17:2n+16] - outer cacheable property
+ *
+ * n TR IR OR
+ * UNCACHED 000 00
+ * BUFFERABLE 001 10 00 00
+ * WRITETHROUGH 010 10 10 10
+ * WRITEBACK 011 10 11 11
+ * reserved 110
+ * WRITEALLOC 111 10 01 01
+ * DEV_SHARED 100 01
+ * DEV_NONSHARED 100 01
+ * DEV_WC 001 10
+ * DEV_CACHED 011 10
+ *
+ * Other attributes:
+ *
+ * DS0 = PRRR[16] = 0 - device shareable property
+ * DS1 = PRRR[17] = 1 - device shareable property
+ * NS0 = PRRR[18] = 0 - normal shareable property
+ * NS1 = PRRR[19] = 1 - normal shareable property
+ * NOS = PRRR[24+n] = 1 - not outer shareable
+ */
+.equ PRRR, 0xff0a81a8
+.equ NMRR, 0x40e040e0
+
+/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
+.globl cpu_v7_suspend_size
+.equ cpu_v7_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_v7_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB 0
+ mrc p15, 0, r7, c2, c0, 1 @ TTB 1
+ mrc p15, 0, r8, c1, c0, 0 @ Control register
+ mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control
+ stmia r0, {r4 - r10}
+ ldmfd sp!, {r4 - r10, pc}
+ENDPROC(cpu_v7_do_suspend)
+
+ENTRY(cpu_v7_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ ldmia r0, {r4 - r10}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB 0
+ mcr p15, 0, r7, c2, c0, 1 @ TTB 1
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+ mcr p15, 0, r9, c1, c0, 1 @ Auxillary control register
+ mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control
+ ldr r4, =PRRR @ PRRR
+ ldr r5, =NMRR @ NMRR
+ mcr p15, 0, r4, c10, c2, 0 @ write PRRR
+ mcr p15, 0, r5, c10, c2, 1 @ write NMRR
+ isb
+ mov r0, r8 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, cpu_resume_l1_flags
+ b cpu_resume_mmu
+ENDPROC(cpu_v7_do_resume)
+cpu_resume_l1_flags:
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v7_do_suspend 0
+#define cpu_v7_do_resume 0
+#endif
+
__CPUINIT
/*
@@ -276,36 +355,8 @@ __v7_setup:
ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
- /*
- * Memory region attributes with SCTLR.TRE=1
- *
- * n = TEX[0],C,B
- * TR = PRRR[2n+1:2n] - memory type
- * IR = NMRR[2n+1:2n] - inner cacheable property
- * OR = NMRR[2n+17:2n+16] - outer cacheable property
- *
- * n TR IR OR
- * UNCACHED 000 00
- * BUFFERABLE 001 10 00 00
- * WRITETHROUGH 010 10 10 10
- * WRITEBACK 011 10 11 11
- * reserved 110
- * WRITEALLOC 111 10 01 01
- * DEV_SHARED 100 01
- * DEV_NONSHARED 100 01
- * DEV_WC 001 10
- * DEV_CACHED 011 10
- *
- * Other attributes:
- *
- * DS0 = PRRR[16] = 0 - device shareable property
- * DS1 = PRRR[17] = 1 - device shareable property
- * NS0 = PRRR[18] = 0 - normal shareable property
- * NS1 = PRRR[19] = 1 - normal shareable property
- * NOS = PRRR[24+n] = 1 - not outer shareable
- */
- ldr r5, =0xff0a81a8 @ PRRR
- ldr r6, =0x40e040e0 @ NMRR
+ ldr r5, =PRRR @ PRRR
+ ldr r6, =NMRR @ NMRR
mcr p15, 0, r5, c10, c2, 0 @ write PRRR
mcr p15, 0, r6, c10, c2, 1 @ write NMRR
#endif
@@ -351,6 +402,9 @@ ENTRY(v7_processor_functions)
.word cpu_v7_dcache_clean_area
.word cpu_v7_switch_mm
.word cpu_v7_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size v7_processor_functions, . - v7_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index ec26355..63d8b20 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -413,9 +413,52 @@ ENTRY(cpu_xsc3_set_pte_ext)
mov pc, lr
.ltorg
-
.align
+.globl cpu_xsc3_suspend_size
+.equ cpu_xsc3_suspend_size, 4 * 8
+#ifdef CONFIG_PM
+ENTRY(cpu_xsc3_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+ mrc p15, 0, r5, c15, c1, 0 @ CP access reg
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c3, c0, 0 @ domain ID
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r1, r4 - r10} @ store v:p offset + cp regs
+ ldmia sp!, {r4 - r10, pc}
+ENDPROC(cpu_xsc3_do_suspend)
+
+ENTRY(cpu_xsc3_do_resume)
+ ldmia r0, {r1, r4 - r10} @ load v:p offset + cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer
+ mcr p15, 0, ip, c7, c5, 4 @ flush prefetch buffer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
+ mcr p15, 0, r5, c15, c1, 0 @ CP access reg
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mcr p15, 0, r7, c3, c0, 0 @ domain ID
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+
+ @ temporarily map resume_turn_on_mmu into the page table,
+ @ otherwise prefetch abort occurs after MMU is turned on
+ mov r0, r10 @ control register
+ mov r2, r8, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =0x542e @ section flags
+ b cpu_resume_mmu
+ENDPROC(cpu_xsc3_do_resume)
+#else
+#define cpu_xsc3_do_suspend 0
+#define cpu_xsc3_do_resume 0
+#endif
+
__CPUINIT
.type __xsc3_setup, #function
@@ -476,6 +519,9 @@ ENTRY(xsc3_processor_functions)
.word cpu_xsc3_dcache_clean_area
.word cpu_xsc3_switch_mm
.word cpu_xsc3_set_pte_ext
+ .word cpu_xsc3_suspend_size
+ .word cpu_xsc3_do_suspend
+ .word cpu_xsc3_do_resume
.size xsc3_processor_functions, . - xsc3_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 5a37c5e..086038c 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -513,11 +513,49 @@ ENTRY(cpu_xscale_set_pte_ext)
xscale_set_pte_ext_epilogue
mov pc, lr
-
.ltorg
-
.align
+.globl cpu_xscale_suspend_size
+.equ cpu_xscale_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_xscale_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+ mrc p15, 0, r5, c15, c1, 0 @ CP access reg
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c3, c0, 0 @ domain ID
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r4 - r10} @ store cp regs
+ ldmfd sp!, {r4 - r10, pc}
+ENDPROC(cpu_xscale_do_suspend)
+
+ENTRY(cpu_xscale_do_resume)
+ ldmia r0, {r4 - r10} @ load cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
+ mcr p15, 0, r5, c15, c1, 0 @ CP access reg
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mcr p15, 0, r7, c3, c0, 0 @ domain ID
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mov r0, r10 @ control register
+ mov r2, r8, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(cpu_xscale_do_resume)
+#else
+#define cpu_xscale_do_suspend 0
+#define cpu_xscale_do_resume 0
+#endif
+
__CPUINIT
.type __xscale_setup, #function
@@ -565,6 +603,9 @@ ENTRY(xscale_processor_functions)
.word cpu_xscale_dcache_clean_area
.word cpu_xscale_switch_mm
.word cpu_xscale_set_pte_ext
+ .word cpu_xscale_suspend_size
+ .word cpu_xscale_do_suspend
+ .word cpu_xscale_do_resume
.size xscale_processor_functions, . - xscale_processor_functions
.section ".rodata"
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 12:10 ` [PATCH v3 " Russell King - ARM Linux
@ 2011-02-07 13:21 ` saeed bishara
2011-02-07 13:34 ` Russell King - ARM Linux
0 siblings, 1 reply; 33+ messages in thread
From: saeed bishara @ 2011-02-07 13:21 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 7, 2011 at 2:10 PM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Mon, Feb 07, 2011 at 12:01:04PM +0000, Russell King - ARM Linux wrote:
>> On Sun, Feb 06, 2011 at 07:12:28PM +0000, Russell King - ARM Linux wrote:
>> > This adds core support for saving and restoring CPU coprocessor
>> > registers for suspend/resume support. ?This contains support for suspend
>> > with ARM920, ARM926, SA11x0, PXA25x, PXA27x, PXA3xx and V6 CPUs.
>> >
>> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
>> > ---
>
> Gah. ?No sooner than v2, than there's a v3 of this patch, replacing a
> typo'd sub rather than mov instruction, and adding a .ltorg to avoid
> .text wastage.
>
> ?arch/arm/include/asm/glue-proc.h | ? ?3 +
> ?arch/arm/include/asm/proc-fns.h ?| ? ?7 ++
> ?arch/arm/kernel/Makefile ? ? ? ? | ? ?1 +
> ?arch/arm/kernel/asm-offsets.c ? ?| ? ?9 +++
> ?arch/arm/kernel/sleep.S ? ? ? ? ?| ?110 ++++++++++++++++++++++++++++++++++++
> ?arch/arm/mm/proc-arm1020.S ? ? ? | ? ?3 +
> ?arch/arm/mm/proc-arm1020e.S ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-arm1022.S ? ? ? | ? ?3 +
> ?arch/arm/mm/proc-arm1026.S ? ? ? | ? ?3 +
> ?arch/arm/mm/proc-arm6_7.S ? ? ? ?| ? ?6 ++
> ?arch/arm/mm/proc-arm720.S ? ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-arm740.S ? ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-arm7tdmi.S ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-arm920.S ? ? ? ?| ? 37 ++++++++++++
> ?arch/arm/mm/proc-arm922.S ? ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-arm925.S ? ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-arm926.S ? ? ? ?| ? 37 ++++++++++++
> ?arch/arm/mm/proc-arm940.S ? ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-arm946.S ? ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-arm9tdmi.S ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-fa526.S ? ? ? ? | ? ?3 +
> ?arch/arm/mm/proc-feroceon.S ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-mohawk.S ? ? ? ?| ? ?3 +
> ?arch/arm/mm/proc-sa110.S ? ? ? ? | ? ?3 +
> ?arch/arm/mm/proc-sa1100.S ? ? ? ?| ? 39 +++++++++++++
> ?arch/arm/mm/proc-v6.S ? ? ? ? ? ?| ? 48 ++++++++++++++++
> ?arch/arm/mm/proc-v7.S ? ? ? ? ? ?| ?114 ++++++++++++++++++++++++++++----------
> ?arch/arm/mm/proc-xsc3.S ? ? ? ? ?| ? 48 ++++++++++++++++-
> ?arch/arm/mm/proc-xscale.S ? ? ? ?| ? 45 ++++++++++++++-
> ?29 files changed, 519 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
> index e3bf443..6469521 100644
> --- a/arch/arm/include/asm/glue-proc.h
> +++ b/arch/arm/include/asm/glue-proc.h
> @@ -256,6 +256,9 @@
> ?#define cpu_dcache_clean_area ? ? ? ? ?__glue(CPU_NAME,_dcache_clean_area)
> ?#define cpu_do_switch_mm ? ? ? ? ? ? ? __glue(CPU_NAME,_switch_mm)
> ?#define cpu_set_pte_ext ? ? ? ? ? ? ? ? ? ? ? ?__glue(CPU_NAME,_set_pte_ext)
> +#define cpu_suspend_size ? ? ? ? ? ? ? __glue(CPU_NAME,_suspend_size)
> +#define cpu_do_suspend ? ? ? ? ? ? ? ? __glue(CPU_NAME,_do_suspend)
> +#define cpu_do_resume ? ? ? ? ? ? ? ? ?__glue(CPU_NAME,_do_resume)
> ?#endif
>
> ?#endif
> diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
> index 6980215..8ec535e 100644
> --- a/arch/arm/include/asm/proc-fns.h
> +++ b/arch/arm/include/asm/proc-fns.h
> @@ -66,6 +66,11 @@ extern struct processor {
> ? ? ? ? * ignore 'ext'.
> ? ? ? ? */
> ? ? ? ?void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
> +
> + ? ? ? /* Suspend/resume */
> + ? ? ? unsigned int suspend_size;
> + ? ? ? void (*do_suspend)(void *);
> + ? ? ? void (*do_resume)(void *);
> ?} processor;
>
> ?#ifndef MULTI_CPU
> @@ -86,6 +91,8 @@ extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
> ?#define cpu_do_switch_mm(pgd,mm) ? ? ? processor.switch_mm(pgd,mm)
> ?#endif
>
> +extern void cpu_resume(void);
> +
> ?#include <asm/memory.h>
>
> ?#ifdef CONFIG_MMU
> diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
> index 185ee82..74554f1 100644
> --- a/arch/arm/kernel/Makefile
> +++ b/arch/arm/kernel/Makefile
> @@ -29,6 +29,7 @@ obj-$(CONFIG_MODULES) ? ? ? ? += armksyms.o module.o
> ?obj-$(CONFIG_ARTHUR) ? ? ? ? ? += arthur.o
> ?obj-$(CONFIG_ISA_DMA) ? ? ? ? ?+= dma-isa.o
> ?obj-$(CONFIG_PCI) ? ? ? ? ? ? ?+= bios32.o isa.o
> +obj-$(CONFIG_PM) ? ? ? ? ? ? ? += sleep.o
> ?obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
> ?obj-$(CONFIG_SMP) ? ? ? ? ? ? ?+= smp.o smp_tlb.o
> ?obj-$(CONFIG_HAVE_ARM_SCU) ? ? += smp_scu.o
> diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
> index 5302a91..927522c 100644
> --- a/arch/arm/kernel/asm-offsets.c
> +++ b/arch/arm/kernel/asm-offsets.c
> @@ -13,6 +13,7 @@
> ?#include <linux/sched.h>
> ?#include <linux/mm.h>
> ?#include <linux/dma-mapping.h>
> +#include <asm/cacheflush.h>
> ?#include <asm/glue-df.h>
> ?#include <asm/glue-pf.h>
> ?#include <asm/mach/arch.h>
> @@ -116,6 +117,14 @@ int main(void)
> ?#ifdef MULTI_PABORT
> ? DEFINE(PROCESSOR_PABT_FUNC, ?offsetof(struct processor, _prefetch_abort));
> ?#endif
> +#ifdef MULTI_CPU
> + ?DEFINE(CPU_SLEEP_SIZE, ? ? ? offsetof(struct processor, suspend_size));
> + ?DEFINE(CPU_DO_SUSPEND, ? ? ? offsetof(struct processor, do_suspend));
> + ?DEFINE(CPU_DO_RESUME, ? ? ? ? ? ? ? ?offsetof(struct processor, do_resume));
> +#endif
> +#ifdef MULTI_CACHE
> + ?DEFINE(CACHE_FLUSH_KERN_ALL, offsetof(struct cpu_cache_fns, flush_kern_all));
> +#endif
> ? BLANK();
> ? DEFINE(DMA_BIDIRECTIONAL, ? ?DMA_BIDIRECTIONAL);
> ? DEFINE(DMA_TO_DEVICE, ? ? ? ? ? ? ? ?DMA_TO_DEVICE);
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> new file mode 100644
> index 0000000..9f106fa
> --- /dev/null
> +++ b/arch/arm/kernel/sleep.S
> @@ -0,0 +1,110 @@
> +#include <linux/linkage.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/assembler.h>
> +#include <asm/glue-cache.h>
> +#include <asm/glue-proc.h>
> + ? ? ? .text
> +
> +/*
> + * Save CPU state for a suspend
> + * ?r1 = v:p offset
> + * ?r3 = virtual return function
> + * Note: sp is decremented to allocate space for CPU state on stack
> + * r0-r3,r9,r10,lr corrupted
> + */
> +ENTRY(cpu_suspend)
> + ? ? ? mov ? ? r9, lr
> +#ifdef MULTI_CPU
> + ? ? ? ldr ? ? r10, =processor
> + ? ? ? mov ? ? r2, sp ? ? ? ? ? ? ? ? ?@ current virtual SP
> + ? ? ? ldr ? ? r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
> + ? ? ? ldr ? ? ip, [r10, #CPU_DO_RESUME] @ virtual resume function
> + ? ? ? sub ? ? sp, sp, r0 ? ? ? ? ? ? ?@ allocate CPU state on stack
> + ? ? ? mov ? ? r0, sp ? ? ? ? ? ? ? ? ?@ save pointer
> + ? ? ? add ? ? ip, ip, r1 ? ? ? ? ? ? ?@ convert resume fn to phys
> + ? ? ? stmfd ? sp!, {r1, r2, r3, ip} ? @ save v:p, virt SP, retfn, phys resume fn
> + ? ? ? ldr ? ? r3, =sleep_save_sp
> + ? ? ? add ? ? r2, sp, r1 ? ? ? ? ? ? ?@ convert SP to phys
> + ? ? ? str ? ? r2, [r3] ? ? ? ? ? ? ? ?@ save phys SP
> + ? ? ? mov ? ? lr, pc
> + ? ? ? ldr ? ? pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
> +#else
> + ? ? ? mov ? ? r2, sp ? ? ? ? ? ? ? ? ?@ current virtual SP
> + ? ? ? ldr ? ? r0, =cpu_suspend_size
> + ? ? ? sub ? ? sp, sp, r0 ? ? ? ? ? ? ?@ allocate CPU state on stack
> + ? ? ? mov ? ? r0, sp ? ? ? ? ? ? ? ? ?@ save pointer
> + ? ? ? stmfd ? sp!, {r1, r2, r3} ? ? ? @ save v:p, virt SP, return fn
> + ? ? ? ldr ? ? r3, =sleep_save_sp
> + ? ? ? add ? ? r2, sp, r1 ? ? ? ? ? ? ?@ convert SP to phys
> + ? ? ? str ? ? r2, [r3] ? ? ? ? ? ? ? ?@ save phys SP
> + ? ? ? bl ? ? ?cpu_do_suspend
> +#endif
> +
> + ? ? ? @ flush data cache
> +#ifdef MULTI_CACHE
> + ? ? ? ldr ? ? r10, =cpu_cache
> + ? ? ? mov ? ? lr, r9
> + ? ? ? ldr ? ? pc, [r10, #CACHE_FLUSH_KERN_ALL]
> +#else
> + ? ? ? mov ? ? lr, r9
> + ? ? ? b ? ? ? __cpuc_flush_kern_all
> +#endif
> +ENDPROC(cpu_suspend)
> + ? ? ? .ltorg
> +
> +/*
> + * r0 = control register value
> + * r1 = v:p offset (preserved by cpu_do_resume)
> + * r2 = phys page table base
> + * r3 = L1 section flags
> + */
> +ENTRY(cpu_resume_mmu)
> + ? ? ? adr ? ? r4, cpu_resume_turn_mmu_on
> + ? ? ? mov ? ? r4, r4, lsr #20
> + ? ? ? orr ? ? r3, r3, r4, lsl #20
> + ? ? ? ldr ? ? r5, [r2, r4, lsl #2] ? ?@ save old mapping
> + ? ? ? str ? ? r3, [r2, r4, lsl #2] ? ?@ setup 1:1 mapping for mmu code
this code doesn't look smp save, it modifies page table that could be
used by another cpu. I suggest to create (at boot time) identity page
table and use it in order to do mmu on.
saeed
> + ? ? ? sub ? ? r2, r2, r1
> + ? ? ? ldr ? ? r3, =cpu_resume_after_mmu
> + ? ? ? b ? ? ? cpu_resume_turn_mmu_on
> +ENDPROC(cpu_resume_mmu)
> + ? ? ? .ltorg
> + ? ? ? .align ?5
> +cpu_resume_turn_mmu_on:
> + ? ? ? mcr ? ? p15, 0, r0, c1, c0, 0 ? @ turn on MMU, caches, etc
> + ? ? ? mrc ? ? p15, 0, r0, c0, c0, 0 ? @ read id reg
> + ? ? ? mov ? ? r0, r0
> + ? ? ? mov ? ? r0, r0
> + ? ? ? mov ? ? pc, r3 ? ? ? ? ? ? ? ? ?@ jump to virtual address
> +ENDPROC(cpu_resume_turn_mmu_on)
> +cpu_resume_after_mmu:
> + ? ? ? str ? ? r5, [r2, r4, lsl #2] ? ?@ restore old mapping
> +#ifdef MULTI_CACHE
> + ? ? ? ldr ? ? r10, =cpu_cache
> + ? ? ? ldr ? ? pc, [r10, #CACHE_FLUSH_KERN_ALL]
> +#else
> + ? ? ? b ? ? ? __cpuc_flush_kern_all
> +#endif
> +
> +/*
> + * Note: Yes, part of the following code is located into the .data section.
> + * ? ? ? This is to allow sleep_save_sp to be accessed with a relative load
> + * ? ? ? while we can't rely on any MMU translation. ?We could have put
> + * ? ? ? sleep_save_sp in the .text section as well, but some setups might
> + * ? ? ? insist on it to be truly read-only.
> + */
> + ? ? ? .data
> + ? ? ? .align
> +ENTRY(cpu_resume)
> + ? ? ? ldr ? ? r0, sleep_save_sp ? ? ? @ stack phys addr
> + ? ? ? msr ? ? cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
> +#ifdef MULTI_CPU
> + ? ? ? ldmia ? r0!, {r1, sp, lr, pc} ? @ load v:p, stack, return fn, resume fn
> +#else
> + ? ? ? ldmia ? r0!, {r1, sp, lr} ? ? ? @ load v:p, stack, return fn
> + ? ? ? b ? ? ? cpu_do_resume
> +#endif
> +ENDPROC(cpu_resume)
> +
> +sleep_save_sp:
> + ? ? ? .word ? 0 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @ preserve stack phys ptr here
> diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
> index bcf748d..226e3d8 100644
> --- a/arch/arm/mm/proc-arm1020.S
> +++ b/arch/arm/mm/proc-arm1020.S
> @@ -493,6 +493,9 @@ arm1020_processor_functions:
> ? ? ? ?.word ? cpu_arm1020_dcache_clean_area
> ? ? ? ?.word ? cpu_arm1020_switch_mm
> ? ? ? ?.word ? cpu_arm1020_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? arm1020_processor_functions, . - arm1020_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
> index ab7ec26..86d9c2c 100644
> --- a/arch/arm/mm/proc-arm1020e.S
> +++ b/arch/arm/mm/proc-arm1020e.S
> @@ -474,6 +474,9 @@ arm1020e_processor_functions:
> ? ? ? ?.word ? cpu_arm1020e_dcache_clean_area
> ? ? ? ?.word ? cpu_arm1020e_switch_mm
> ? ? ? ?.word ? cpu_arm1020e_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? arm1020e_processor_functions, . - arm1020e_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
> index 831c5e5..83d3dd3 100644
> --- a/arch/arm/mm/proc-arm1022.S
> +++ b/arch/arm/mm/proc-arm1022.S
> @@ -457,6 +457,9 @@ arm1022_processor_functions:
> ? ? ? ?.word ? cpu_arm1022_dcache_clean_area
> ? ? ? ?.word ? cpu_arm1022_switch_mm
> ? ? ? ?.word ? cpu_arm1022_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? arm1022_processor_functions, . - arm1022_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
> index e3f7e9a..686043e 100644
> --- a/arch/arm/mm/proc-arm1026.S
> +++ b/arch/arm/mm/proc-arm1026.S
> @@ -452,6 +452,9 @@ arm1026_processor_functions:
> ? ? ? ?.word ? cpu_arm1026_dcache_clean_area
> ? ? ? ?.word ? cpu_arm1026_switch_mm
> ? ? ? ?.word ? cpu_arm1026_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? arm1026_processor_functions, . - arm1026_processor_functions
>
> ? ? ? ?.section .rodata
> diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
> index 6a7be18..5f79dc4 100644
> --- a/arch/arm/mm/proc-arm6_7.S
> +++ b/arch/arm/mm/proc-arm6_7.S
> @@ -284,6 +284,9 @@ ENTRY(arm6_processor_functions)
> ? ? ? ? ? ? ? ?.word ? cpu_arm6_dcache_clean_area
> ? ? ? ? ? ? ? ?.word ? cpu_arm6_switch_mm
> ? ? ? ? ? ? ? ?.word ? cpu_arm6_set_pte_ext
> + ? ? ? ? ? ? ? .word ? 0
> + ? ? ? ? ? ? ? .word ? 0
> + ? ? ? ? ? ? ? .word ? 0
> ? ? ? ? ? ? ? ?.size ? arm6_processor_functions, . - arm6_processor_functions
>
> ?/*
> @@ -301,6 +304,9 @@ ENTRY(arm7_processor_functions)
> ? ? ? ? ? ? ? ?.word ? cpu_arm7_dcache_clean_area
> ? ? ? ? ? ? ? ?.word ? cpu_arm7_switch_mm
> ? ? ? ? ? ? ? ?.word ? cpu_arm7_set_pte_ext
> + ? ? ? ? ? ? ? .word ? 0
> + ? ? ? ? ? ? ? .word ? 0
> + ? ? ? ? ? ? ? .word ? 0
> ? ? ? ? ? ? ? ?.size ? arm7_processor_functions, . - arm7_processor_functions
>
> ? ? ? ? ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
> index c285395..665266d 100644
> --- a/arch/arm/mm/proc-arm720.S
> +++ b/arch/arm/mm/proc-arm720.S
> @@ -185,6 +185,9 @@ ENTRY(arm720_processor_functions)
> ? ? ? ? ? ? ? ?.word ? cpu_arm720_dcache_clean_area
> ? ? ? ? ? ? ? ?.word ? cpu_arm720_switch_mm
> ? ? ? ? ? ? ? ?.word ? cpu_arm720_set_pte_ext
> + ? ? ? ? ? ? ? .word ? 0
> + ? ? ? ? ? ? ? .word ? 0
> + ? ? ? ? ? ? ? .word ? 0
> ? ? ? ? ? ? ? ?.size ? arm720_processor_functions, . - arm720_processor_functions
>
> ? ? ? ? ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
> index 38b27dc..6f9d12e 100644
> --- a/arch/arm/mm/proc-arm740.S
> +++ b/arch/arm/mm/proc-arm740.S
> @@ -130,6 +130,9 @@ ENTRY(arm740_processor_functions)
> ? ? ? ?.word ? cpu_arm740_dcache_clean_area
> ? ? ? ?.word ? cpu_arm740_switch_mm
> ? ? ? ?.word ? 0 ? ? ? ? ? ? ? ? ? ? ? @ cpu_*_set_pte
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? arm740_processor_functions, . - arm740_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
> index 0c9786d..e4c165c 100644
> --- a/arch/arm/mm/proc-arm7tdmi.S
> +++ b/arch/arm/mm/proc-arm7tdmi.S
> @@ -70,6 +70,9 @@ ENTRY(arm7tdmi_processor_functions)
> ? ? ? ? ? ? ? ?.word ? cpu_arm7tdmi_dcache_clean_area
> ? ? ? ? ? ? ? ?.word ? cpu_arm7tdmi_switch_mm
> ? ? ? ? ? ? ? ?.word ? 0 ? ? ? ? ? ? ? @ cpu_*_set_pte
> + ? ? ? ? ? ? ? .word ? 0
> + ? ? ? ? ? ? ? .word ? 0
> + ? ? ? ? ? ? ? .word ? 0
> ? ? ? ? ? ? ? ?.size ? arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
>
> ? ? ? ? ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
> index 6109f27..b2705de 100644
> --- a/arch/arm/mm/proc-arm920.S
> +++ b/arch/arm/mm/proc-arm920.S
> @@ -387,6 +387,40 @@ ENTRY(cpu_arm920_set_pte_ext)
> ?#endif
> ? ? ? ?mov ? ? pc, lr
>
> +/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
> +.globl arm920_suspend_size
> +.equ ? arm920_suspend_size, 4 * 3
> +#ifdef CONFIG_PM
> +ENTRY(arm920_do_suspend)
> + ? ? ? stmfd ? sp!, {r4 - r7, lr}
> + ? ? ? mrc ? ? p15, 0, r4, c13, c0, 0 ?@ PID
> + ? ? ? mrc ? ? p15, 0, r5, c3, c0, 0 ? @ Domain ID
> + ? ? ? mrc ? ? p15, 0, r6, c2, c0, 0 ? @ TTB address
> + ? ? ? mrc ? ? p15, 0, r7, c1, c0, 0 ? @ Control register
> + ? ? ? stmia ? r0, {r4 - r7}
> + ? ? ? ldmfd ? sp!, {r4 - r7, pc}
> +ENDPROC(arm920_do_suspend)
> +
> +ENTRY(arm920_do_resume)
> + ? ? ? mov ? ? ip, #0
> + ? ? ? mcr ? ? p15, 0, ip, c8, c7, 0 ? @ invalidate I+D TLBs
> + ? ? ? mcr ? ? p15, 0, ip, c7, c7, 0 ? @ invalidate I+D caches
> + ? ? ? ldmia ? r0, {r4 - r7}
> + ? ? ? mcr ? ? p15, 0, r4, c13, c0, 0 ?@ PID
> + ? ? ? mcr ? ? p15, 0, r5, c3, c0, 0 ? @ Domain ID
> + ? ? ? mcr ? ? p15, 0, r6, c2, c0, 0 ? @ TTB address
> + ? ? ? mov ? ? r0, r7 ? ? ? ? ? ? ? ? ?@ control register
> + ? ? ? mov ? ? r2, r6, lsr #14 ? ? ? ? @ get TTB0 base
> + ? ? ? mov ? ? r2, r2, lsl #14
> + ? ? ? ldr ? ? r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
> + ? ? ? ? ? ? ? ? ? ?PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
> + ? ? ? b ? ? ? cpu_resume_mmu
> +ENDPROC(arm920_do_resume)
> +#else
> +#define arm920_do_suspend ? ? ?0
> +#define arm920_do_resume ? ? ? 0
> +#endif
> +
> ? ? ? ?__CPUINIT
>
> ? ? ? ?.type ? __arm920_setup, #function
> @@ -432,6 +466,9 @@ arm920_processor_functions:
> ? ? ? ?.word ? cpu_arm920_dcache_clean_area
> ? ? ? ?.word ? cpu_arm920_switch_mm
> ? ? ? ?.word ? cpu_arm920_set_pte_ext
> + ? ? ? .word ? arm920_suspend_size
> + ? ? ? .word ? arm920_do_suspend
> + ? ? ? .word ? arm920_do_resume
> ? ? ? ?.size ? arm920_processor_functions, . - arm920_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
> index bb2f0f4..36154b1 100644
> --- a/arch/arm/mm/proc-arm922.S
> +++ b/arch/arm/mm/proc-arm922.S
> @@ -436,6 +436,9 @@ arm922_processor_functions:
> ? ? ? ?.word ? cpu_arm922_dcache_clean_area
> ? ? ? ?.word ? cpu_arm922_switch_mm
> ? ? ? ?.word ? cpu_arm922_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? arm922_processor_functions, . - arm922_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
> index c13e01a..89c5e00 100644
> --- a/arch/arm/mm/proc-arm925.S
> +++ b/arch/arm/mm/proc-arm925.S
> @@ -503,6 +503,9 @@ arm925_processor_functions:
> ? ? ? ?.word ? cpu_arm925_dcache_clean_area
> ? ? ? ?.word ? cpu_arm925_switch_mm
> ? ? ? ?.word ? cpu_arm925_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? arm925_processor_functions, . - arm925_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
> index 42eb431..3beb784 100644
> --- a/arch/arm/mm/proc-arm926.S
> +++ b/arch/arm/mm/proc-arm926.S
> @@ -401,6 +401,40 @@ ENTRY(cpu_arm926_set_pte_ext)
> ?#endif
> ? ? ? ?mov ? ? pc, lr
>
> +/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
> +.globl arm926_suspend_size
> +.equ ? arm926_suspend_size, 4 * 3
> +#ifdef CONFIG_PM
> +ENTRY(arm926_do_suspend)
> + ? ? ? stmfd ? sp!, {r4 - r7, lr}
> + ? ? ? mrc ? ? p15, 0, r4, c13, c0, 0 ?@ PID
> + ? ? ? mrc ? ? p15, 0, r5, c3, c0, 0 ? @ Domain ID
> + ? ? ? mrc ? ? p15, 0, r6, c2, c0, 0 ? @ TTB address
> + ? ? ? mrc ? ? p15, 0, r7, c1, c0, 0 ? @ Control register
> + ? ? ? stmia ? r0, {r4 - r7}
> + ? ? ? ldmfd ? sp!, {r4 - r7, pc}
> +ENDPROC(arm926_do_suspend)
> +
> +ENTRY(arm926_do_resume)
> + ? ? ? mov ? ? ip, #0
> + ? ? ? mcr ? ? p15, 0, ip, c8, c7, 0 ? @ invalidate I+D TLBs
> + ? ? ? mcr ? ? p15, 0, ip, c7, c7, 0 ? @ invalidate I+D caches
> + ? ? ? ldmia ? r0, {r4 - r7}
> + ? ? ? mcr ? ? p15, 0, r4, c13, c0, 0 ?@ PID
> + ? ? ? mcr ? ? p15, 0, r5, c3, c0, 0 ? @ Domain ID
> + ? ? ? mcr ? ? p15, 0, r6, c2, c0, 0 ? @ TTB address
> + ? ? ? mov ? ? r0, r7 ? ? ? ? ? ? ? ? ?@ control register
> + ? ? ? mov ? ? r2, r6, lsr #14 ? ? ? ? @ get TTB0 base
> + ? ? ? mov ? ? r2, r2, lsl #14
> + ? ? ? ldr ? ? r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
> + ? ? ? ? ? ? ? ? ? ?PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
> + ? ? ? b ? ? ? cpu_resume_mmu
> +ENDPROC(arm926_do_resume)
> +#else
> +#define arm926_do_suspend ? ? ?0
> +#define arm926_do_resume ? ? ? 0
> +#endif
> +
> ? ? ? ?__CPUINIT
>
> ? ? ? ?.type ? __arm926_setup, #function
> @@ -456,6 +490,9 @@ arm926_processor_functions:
> ? ? ? ?.word ? cpu_arm926_dcache_clean_area
> ? ? ? ?.word ? cpu_arm926_switch_mm
> ? ? ? ?.word ? cpu_arm926_set_pte_ext
> + ? ? ? .word ? arm926_suspend_size
> + ? ? ? .word ? arm926_do_suspend
> + ? ? ? .word ? arm926_do_resume
> ? ? ? ?.size ? arm926_processor_functions, . - arm926_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
> index 7b11cdb..26aea3f 100644
> --- a/arch/arm/mm/proc-arm940.S
> +++ b/arch/arm/mm/proc-arm940.S
> @@ -363,6 +363,9 @@ ENTRY(arm940_processor_functions)
> ? ? ? ?.word ? cpu_arm940_dcache_clean_area
> ? ? ? ?.word ? cpu_arm940_switch_mm
> ? ? ? ?.word ? 0 ? ? ? ? ? ? ? @ cpu_*_set_pte
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? arm940_processor_functions, . - arm940_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
> index 1a5bbf0..8063345 100644
> --- a/arch/arm/mm/proc-arm946.S
> +++ b/arch/arm/mm/proc-arm946.S
> @@ -419,6 +419,9 @@ ENTRY(arm946_processor_functions)
> ? ? ? ?.word ? cpu_arm946_dcache_clean_area
> ? ? ? ?.word ? cpu_arm946_switch_mm
> ? ? ? ?.word ? 0 ? ? ? ? ? ? ? @ cpu_*_set_pte
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? arm946_processor_functions, . - arm946_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
> index db67e31..7b7ebd4 100644
> --- a/arch/arm/mm/proc-arm9tdmi.S
> +++ b/arch/arm/mm/proc-arm9tdmi.S
> @@ -70,6 +70,9 @@ ENTRY(arm9tdmi_processor_functions)
> ? ? ? ? ? ? ? ?.word ? cpu_arm9tdmi_dcache_clean_area
> ? ? ? ? ? ? ? ?.word ? cpu_arm9tdmi_switch_mm
> ? ? ? ? ? ? ? ?.word ? 0 ? ? ? ? ? ? ? @ cpu_*_set_pte
> + ? ? ? ? ? ? ? .word ? 0
> + ? ? ? ? ? ? ? .word ? 0
> + ? ? ? ? ? ? ? .word ? 0
> ? ? ? ? ? ? ? ?.size ? arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
>
> ? ? ? ? ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
> index 7c9ad62..fc2a4ae 100644
> --- a/arch/arm/mm/proc-fa526.S
> +++ b/arch/arm/mm/proc-fa526.S
> @@ -195,6 +195,9 @@ fa526_processor_functions:
> ? ? ? ?.word ? cpu_fa526_dcache_clean_area
> ? ? ? ?.word ? cpu_fa526_switch_mm
> ? ? ? ?.word ? cpu_fa526_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? fa526_processor_functions, . - fa526_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
> index b4597ed..d3883ee 100644
> --- a/arch/arm/mm/proc-feroceon.S
> +++ b/arch/arm/mm/proc-feroceon.S
> @@ -554,6 +554,9 @@ feroceon_processor_functions:
> ? ? ? ?.word ? cpu_feroceon_dcache_clean_area
> ? ? ? ?.word ? cpu_feroceon_switch_mm
> ? ? ? ?.word ? cpu_feroceon_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? feroceon_processor_functions, . - feroceon_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
> index 4458ee6..9d4f2ae 100644
> --- a/arch/arm/mm/proc-mohawk.S
> +++ b/arch/arm/mm/proc-mohawk.S
> @@ -388,6 +388,9 @@ mohawk_processor_functions:
> ? ? ? ?.word ? cpu_mohawk_dcache_clean_area
> ? ? ? ?.word ? cpu_mohawk_switch_mm
> ? ? ? ?.word ? cpu_mohawk_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? mohawk_processor_functions, . - mohawk_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
> index 5aa8d59..46f09ed 100644
> --- a/arch/arm/mm/proc-sa110.S
> +++ b/arch/arm/mm/proc-sa110.S
> @@ -203,6 +203,9 @@ ENTRY(sa110_processor_functions)
> ? ? ? ?.word ? cpu_sa110_dcache_clean_area
> ? ? ? ?.word ? cpu_sa110_switch_mm
> ? ? ? ?.word ? cpu_sa110_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? sa110_processor_functions, . - sa110_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
> index 2ac4e6f..74483d1 100644
> --- a/arch/arm/mm/proc-sa1100.S
> +++ b/arch/arm/mm/proc-sa1100.S
> @@ -169,6 +169,42 @@ ENTRY(cpu_sa1100_set_pte_ext)
> ?#endif
> ? ? ? ?mov ? ? pc, lr
>
> +.globl cpu_sa1100_suspend_size
> +.equ ? cpu_sa1100_suspend_size, 4*4
> +#ifdef CONFIG_PM
> +ENTRY(cpu_sa1100_do_suspend)
> + ? ? ? stmfd ? sp!, {r4 - r7, lr}
> + ? ? ? mrc ? ? p15, 0, r4, c3, c0, 0 ? ? ? ? ? @ domain ID
> + ? ? ? mrc ? ? p15, 0, r5, c2, c0, 0 ? ? ? ? ? @ translation table base addr
> + ? ? ? mrc ? ? p15, 0, r6, c13, c0, 0 ? ? ? ? ?@ PID
> + ? ? ? mrc ? ? p15, 0, r7, c1, c0, 0 ? ? ? ? ? @ control reg
> + ? ? ? stmia ? r0, {r4 - r7} ? ? ? ? ? ? ? ? ? @ store cp regs
> + ? ? ? ldmfd ? sp!, {r4 - r7, pc}
> +ENDPROC(cpu_sa1100_do_suspend)
> +
> +ENTRY(cpu_sa1100_do_resume)
> + ? ? ? ldmia ? r0, {r4 - r7} ? ? ? ? ? ? ? ? ? @ load cp regs
> + ? ? ? mov ? ? r1, #0
> + ? ? ? mcr ? ? p15, 0, r1, c8, c7, 0 ? ? ? ? ? @ flush I+D TLBs
> + ? ? ? mcr ? ? p15, 0, r1, c7, c7, 0 ? ? ? ? ? @ flush I&D cache
> + ? ? ? mcr ? ? p15, 0, r1, c9, c0, 0 ? ? ? ? ? @ invalidate RB
> + ? ? ? mcr ? ? p15, 0, r1, c9, c0, 5 ? ? ? ? ? @ allow user space to use RB
> +
> + ? ? ? mcr ? ? p15, 0, r4, c3, c0, 0 ? ? ? ? ? @ domain ID
> + ? ? ? mcr ? ? p15, 0, r5, c2, c0, 0 ? ? ? ? ? @ translation table base addr
> + ? ? ? mcr ? ? p15, 0, r6, c13, c0, 0 ? ? ? ? ?@ PID
> + ? ? ? mov ? ? r0, r7 ? ? ? ? ? ? ? ? ? ? ? ? ?@ control register
> + ? ? ? mov ? ? r2, r5, lsr #14 ? ? ? ? ? ? ? ? @ get TTB0 base
> + ? ? ? mov ? ? r2, r2, lsl #14
> + ? ? ? ldr ? ? r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
> + ? ? ? ? ? ? ? ? ? ?PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
> + ? ? ? b ? ? ? cpu_resume_mmu
> +ENDPROC(cpu_sa1100_do_resume)
> +#else
> +#define cpu_sa1100_do_suspend ?0
> +#define cpu_sa1100_do_resume ? 0
> +#endif
> +
> ? ? ? ?__CPUINIT
>
> ? ? ? ?.type ? __sa1100_setup, #function
> @@ -218,6 +254,9 @@ ENTRY(sa1100_processor_functions)
> ? ? ? ?.word ? cpu_sa1100_dcache_clean_area
> ? ? ? ?.word ? cpu_sa1100_switch_mm
> ? ? ? ?.word ? cpu_sa1100_set_pte_ext
> + ? ? ? .word ? cpu_sa1100_suspend_size
> + ? ? ? .word ? cpu_sa1100_do_suspend
> + ? ? ? .word ? cpu_sa1100_do_resume
> ? ? ? ?.size ? sa1100_processor_functions, . - sa1100_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
> index 59a7e1f..c86f451 100644
> --- a/arch/arm/mm/proc-v6.S
> +++ b/arch/arm/mm/proc-v6.S
> @@ -121,6 +121,51 @@ ENTRY(cpu_v6_set_pte_ext)
> ?#endif
> ? ? ? ?mov ? ? pc, lr
>
> +/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
> +.globl cpu_v6_suspend_size
> +.equ ? cpu_v6_suspend_size, 4 * 7
> +#ifdef CONFIG_PM
> +ENTRY(cpu_v6_do_suspend)
> + ? ? ? stmfd ? sp!, {r4 - r10, lr}
> + ? ? ? mrc ? ? p15, 0, r4, c13, c0, 0 ?@ FCSE/PID
> + ? ? ? mrc ? ? p15, 0, r5, c3, c0, 0 ? @ Domain ID
> + ? ? ? mrc ? ? p15, 0, r6, c2, c0, 0 ? @ Translation table base 0
> + ? ? ? mrc ? ? p15, 0, r7, c2, c0, 1 ? @ Translation table base 1
> + ? ? ? mrc ? ? p15, 0, r8, c1, c0, 1 ? @ auxillary control register
> + ? ? ? mrc ? ? p15, 0, r9, c1, c0, 2 ? @ co-processor access control
> + ? ? ? mrc ? ? p15, 0, r10, c1, c0, 0 ?@ control register
> + ? ? ? stmia ? r0, {r4 - r10}
> + ? ? ? ldmfd ? sp!, {r4- r10, pc}
> +ENDPROC(cpu_v6_do_suspend)
> +
> +ENTRY(cpu_v6_do_resume)
> + ? ? ? mov ? ? ip, #0
> + ? ? ? mcr ? ? p15, 0, ip, c7, c14, 0 ?@ clean+invalidate D cache
> + ? ? ? mcr ? ? p15, 0, ip, c7, c5, 0 ? @ invalidate I cache
> + ? ? ? mcr ? ? p15, 0, ip, c7, c15, 0 ?@ clean+invalidate cache
> + ? ? ? mcr ? ? p15, 0, ip, c7, c10, 4 ?@ drain write buffer
> + ? ? ? ldmia ? r0, {r4 - r10}
> + ? ? ? mcr ? ? p15, 0, r4, c13, c0, 0 ?@ FCSE/PID
> + ? ? ? mcr ? ? p15, 0, r5, c3, c0, 0 ? @ Domain ID
> + ? ? ? mcr ? ? p15, 0, r6, c2, c0, 0 ? @ Translation table base 0
> + ? ? ? mcr ? ? p15, 0, r7, c2, c0, 1 ? @ Translation table base 1
> + ? ? ? mcr ? ? p15, 0, r8, c1, c0, 1 ? @ auxillary control register
> + ? ? ? mcr ? ? p15, 0, r9, c1, c0, 2 ? @ co-processor access control
> + ? ? ? mcr ? ? p15, 0, ip, c2, c0, 2 ? @ TTB control register
> + ? ? ? mcr ? ? p15, 0, ip, c7, c5, 4 ? @ ISB
> + ? ? ? mov ? ? r0, r10 ? ? ? ? ? ? ? ? @ control register
> + ? ? ? mov ? ? r2, r6, lsr #14 ? ? ? ? @ get TTB0 base
> + ? ? ? mov ? ? r2, r2, lsl #14
> + ? ? ? ldr ? ? r3, cpu_resume_l1_flags
> + ? ? ? b ? ? ? cpu_resume_mmu
> +ENDPROC(cpu_v6_do_resume)
> +cpu_resume_l1_flags:
> + ? ? ? ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
> + ? ? ? ALT_UP(.long ?PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
> +#else
> +#define cpu_v6_do_suspend 0
> +#define cpu_v6_do_resume 0
> +#endif
>
>
> ? ? ? ?.type ? cpu_v6_name, #object
> @@ -206,6 +251,9 @@ ENTRY(v6_processor_functions)
> ? ? ? ?.word ? cpu_v6_dcache_clean_area
> ? ? ? ?.word ? cpu_v6_switch_mm
> ? ? ? ?.word ? cpu_v6_set_pte_ext
> + ? ? ? .word ? cpu_v6_suspend_size
> + ? ? ? .word ? cpu_v6_do_suspend
> + ? ? ? .word ? cpu_v6_do_resume
> ? ? ? ?.size ? v6_processor_functions, . - v6_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index 0c1172b..8e6142d 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -171,6 +171,85 @@ cpu_v7_name:
> ? ? ? ?.ascii ?"ARMv7 Processor"
> ? ? ? ?.align
>
> + ? ? ? /*
> + ? ? ? ?* Memory region attributes with SCTLR.TRE=1
> + ? ? ? ?*
> + ? ? ? ?* ? n = TEX[0],C,B
> + ? ? ? ?* ? TR = PRRR[2n+1:2n] ? ? ? ? - memory type
> + ? ? ? ?* ? IR = NMRR[2n+1:2n] ? ? ? ? - inner cacheable property
> + ? ? ? ?* ? OR = NMRR[2n+17:2n+16] ? ? - outer cacheable property
> + ? ? ? ?*
> + ? ? ? ?* ? ? ? ? ? ? ? ? ? ? ?n ? ? ? TR ? ? ?IR ? ? ?OR
> + ? ? ? ?* ? UNCACHED ? ? ? ? ? 000 ? ? 00
> + ? ? ? ?* ? BUFFERABLE ? ? ? ? 001 ? ? 10 ? ? ?00 ? ? ?00
> + ? ? ? ?* ? WRITETHROUGH ? ? ? 010 ? ? 10 ? ? ?10 ? ? ?10
> + ? ? ? ?* ? WRITEBACK ? ? ? ? ?011 ? ? 10 ? ? ?11 ? ? ?11
> + ? ? ? ?* ? reserved ? ? ? ? ? 110
> + ? ? ? ?* ? WRITEALLOC ? ? ? ? 111 ? ? 10 ? ? ?01 ? ? ?01
> + ? ? ? ?* ? DEV_SHARED ? ? ? ? 100 ? ? 01
> + ? ? ? ?* ? DEV_NONSHARED ? ? ?100 ? ? 01
> + ? ? ? ?* ? DEV_WC ? ? ? ? ? ? 001 ? ? 10
> + ? ? ? ?* ? DEV_CACHED ? ? ? ? 011 ? ? 10
> + ? ? ? ?*
> + ? ? ? ?* Other attributes:
> + ? ? ? ?*
> + ? ? ? ?* ? DS0 = PRRR[16] = 0 ? ? ? ? - device shareable property
> + ? ? ? ?* ? DS1 = PRRR[17] = 1 ? ? ? ? - device shareable property
> + ? ? ? ?* ? NS0 = PRRR[18] = 0 ? ? ? ? - normal shareable property
> + ? ? ? ?* ? NS1 = PRRR[19] = 1 ? ? ? ? - normal shareable property
> + ? ? ? ?* ? NOS = PRRR[24+n] = 1 ? ? ? - not outer shareable
> + ? ? ? ?*/
> +.equ ? PRRR, ? 0xff0a81a8
> +.equ ? NMRR, ? 0x40e040e0
> +
> +/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
> +.globl cpu_v7_suspend_size
> +.equ ? cpu_v7_suspend_size, 4 * 7
> +#ifdef CONFIG_PM
> +ENTRY(cpu_v7_do_suspend)
> + ? ? ? stmfd ? sp!, {r4 - r10, lr}
> + ? ? ? mrc ? ? p15, 0, r4, c13, c0, 0 ?@ FCSE/PID
> + ? ? ? mrc ? ? p15, 0, r5, c3, c0, 0 ? @ Domain ID
> + ? ? ? mrc ? ? p15, 0, r6, c2, c0, 0 ? @ TTB 0
> + ? ? ? mrc ? ? p15, 0, r7, c2, c0, 1 ? @ TTB 1
> + ? ? ? mrc ? ? p15, 0, r8, c1, c0, 0 ? @ Control register
> + ? ? ? mrc ? ? p15, 0, r9, c1, c0, 1 ? @ Auxiliary control register
> + ? ? ? mrc ? ? p15, 0, r10, c1, c0, 2 ?@ Co-processor access control
> + ? ? ? stmia ? r0, {r4 - r10}
> + ? ? ? ldmfd ? sp!, {r4 - r10, pc}
> +ENDPROC(cpu_v7_do_suspend)
> +
> +ENTRY(cpu_v7_do_resume)
> + ? ? ? mov ? ? ip, #0
> + ? ? ? mcr ? ? p15, 0, ip, c8, c7, 0 ? @ invalidate TLBs
> + ? ? ? mcr ? ? p15, 0, ip, c7, c5, 0 ? @ invalidate I cache
> + ? ? ? ldmia ? r0, {r4 - r10}
> + ? ? ? mcr ? ? p15, 0, r4, c13, c0, 0 ?@ FCSE/PID
> + ? ? ? mcr ? ? p15, 0, r5, c3, c0, 0 ? @ Domain ID
> + ? ? ? mcr ? ? p15, 0, r6, c2, c0, 0 ? @ TTB 0
> + ? ? ? mcr ? ? p15, 0, r7, c2, c0, 1 ? @ TTB 1
> + ? ? ? mcr ? ? p15, 0, ip, c2, c0, 2 ? @ TTB control register
> + ? ? ? mcr ? ? p15, 0, r9, c1, c0, 1 ? @ Auxillary control register
> + ? ? ? mcr ? ? p15, 0, r10, c1, c0, 2 ?@ Co-processor access control
> + ? ? ? ldr ? ? r4, =PRRR ? ? ? ? ? ? ? @ PRRR
> + ? ? ? ldr ? ? r5, =NMRR ? ? ? ? ? ? ? @ NMRR
> + ? ? ? mcr ? ? p15, 0, r4, c10, c2, 0 ?@ write PRRR
> + ? ? ? mcr ? ? p15, 0, r5, c10, c2, 1 ?@ write NMRR
> + ? ? ? isb
> + ? ? ? mov ? ? r0, r8 ? ? ? ? ? ? ? ? ?@ control register
> + ? ? ? mov ? ? r2, r6, lsr #14 ? ? ? ? @ get TTB0 base
> + ? ? ? mov ? ? r2, r2, lsl #14
> + ? ? ? ldr ? ? r3, cpu_resume_l1_flags
> + ? ? ? b ? ? ? cpu_resume_mmu
> +ENDPROC(cpu_v7_do_resume)
> +cpu_resume_l1_flags:
> + ? ? ? ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
> + ? ? ? ALT_UP(.long ?PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
> +#else
> +#define cpu_v7_do_suspend ? ? ?0
> +#define cpu_v7_do_resume ? ? ? 0
> +#endif
> +
> ? ? ? ?__CPUINIT
>
> ?/*
> @@ -276,36 +355,8 @@ __v7_setup:
> ? ? ? ?ALT_SMP(orr ? ? r4, r4, #TTB_FLAGS_SMP)
> ? ? ? ?ALT_UP(orr ? ? ?r4, r4, #TTB_FLAGS_UP)
> ? ? ? ?mcr ? ? p15, 0, r4, c2, c0, 1 ? ? ? ? ? @ load TTB1
> - ? ? ? /*
> - ? ? ? ?* Memory region attributes with SCTLR.TRE=1
> - ? ? ? ?*
> - ? ? ? ?* ? n = TEX[0],C,B
> - ? ? ? ?* ? TR = PRRR[2n+1:2n] ? ? ? ? - memory type
> - ? ? ? ?* ? IR = NMRR[2n+1:2n] ? ? ? ? - inner cacheable property
> - ? ? ? ?* ? OR = NMRR[2n+17:2n+16] ? ? - outer cacheable property
> - ? ? ? ?*
> - ? ? ? ?* ? ? ? ? ? ? ? ? ? ? ?n ? ? ? TR ? ? ?IR ? ? ?OR
> - ? ? ? ?* ? UNCACHED ? ? ? ? ? 000 ? ? 00
> - ? ? ? ?* ? BUFFERABLE ? ? ? ? 001 ? ? 10 ? ? ?00 ? ? ?00
> - ? ? ? ?* ? WRITETHROUGH ? ? ? 010 ? ? 10 ? ? ?10 ? ? ?10
> - ? ? ? ?* ? WRITEBACK ? ? ? ? ?011 ? ? 10 ? ? ?11 ? ? ?11
> - ? ? ? ?* ? reserved ? ? ? ? ? 110
> - ? ? ? ?* ? WRITEALLOC ? ? ? ? 111 ? ? 10 ? ? ?01 ? ? ?01
> - ? ? ? ?* ? DEV_SHARED ? ? ? ? 100 ? ? 01
> - ? ? ? ?* ? DEV_NONSHARED ? ? ?100 ? ? 01
> - ? ? ? ?* ? DEV_WC ? ? ? ? ? ? 001 ? ? 10
> - ? ? ? ?* ? DEV_CACHED ? ? ? ? 011 ? ? 10
> - ? ? ? ?*
> - ? ? ? ?* Other attributes:
> - ? ? ? ?*
> - ? ? ? ?* ? DS0 = PRRR[16] = 0 ? ? ? ? - device shareable property
> - ? ? ? ?* ? DS1 = PRRR[17] = 1 ? ? ? ? - device shareable property
> - ? ? ? ?* ? NS0 = PRRR[18] = 0 ? ? ? ? - normal shareable property
> - ? ? ? ?* ? NS1 = PRRR[19] = 1 ? ? ? ? - normal shareable property
> - ? ? ? ?* ? NOS = PRRR[24+n] = 1 ? ? ? - not outer shareable
> - ? ? ? ?*/
> - ? ? ? ldr ? ? r5, =0xff0a81a8 ? ? ? ? ? ? ? ? @ PRRR
> - ? ? ? ldr ? ? r6, =0x40e040e0 ? ? ? ? ? ? ? ? @ NMRR
> + ? ? ? ldr ? ? r5, =PRRR ? ? ? ? ? ? ? ? ? ? ? @ PRRR
> + ? ? ? ldr ? ? r6, =NMRR ? ? ? ? ? ? ? ? ? ? ? @ NMRR
> ? ? ? ?mcr ? ? p15, 0, r5, c10, c2, 0 ? ? ? ? ?@ write PRRR
> ? ? ? ?mcr ? ? p15, 0, r6, c10, c2, 1 ? ? ? ? ?@ write NMRR
> ?#endif
> @@ -351,6 +402,9 @@ ENTRY(v7_processor_functions)
> ? ? ? ?.word ? cpu_v7_dcache_clean_area
> ? ? ? ?.word ? cpu_v7_switch_mm
> ? ? ? ?.word ? cpu_v7_set_pte_ext
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> + ? ? ? .word ? 0
> ? ? ? ?.size ? v7_processor_functions, . - v7_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
> index ec26355..63d8b20 100644
> --- a/arch/arm/mm/proc-xsc3.S
> +++ b/arch/arm/mm/proc-xsc3.S
> @@ -413,9 +413,52 @@ ENTRY(cpu_xsc3_set_pte_ext)
> ? ? ? ?mov ? ? pc, lr
>
> ? ? ? ?.ltorg
> -
> ? ? ? ?.align
>
> +.globl cpu_xsc3_suspend_size
> +.equ ? cpu_xsc3_suspend_size, 4 * 8
> +#ifdef CONFIG_PM
> +ENTRY(cpu_xsc3_do_suspend)
> + ? ? ? stmfd ? sp!, {r4 - r10, lr}
> + ? ? ? mrc ? ? p14, 0, r4, c6, c0, 0 ? @ clock configuration, for turbo mode
> + ? ? ? mrc ? ? p15, 0, r5, c15, c1, 0 ?@ CP access reg
> + ? ? ? mrc ? ? p15, 0, r6, c13, c0, 0 ?@ PID
> + ? ? ? mrc ? ? p15, 0, r7, c3, c0, 0 ? @ domain ID
> + ? ? ? mrc ? ? p15, 0, r8, c2, c0, 0 ? @ translation table base addr
> + ? ? ? mrc ? ? p15, 0, r9, c1, c0, 1 ? @ auxiliary control reg
> + ? ? ? mrc ? ? p15, 0, r10, c1, c0, 0 ?@ control reg
> + ? ? ? bic ? ? r4, r4, #2 ? ? ? ? ? ? ?@ clear frequency change bit
> + ? ? ? stmia ? r0, {r1, r4 - r10} ? ? ?@ store v:p offset + cp regs
> + ? ? ? ldmia ? sp!, {r4 - r10, pc}
> +ENDPROC(cpu_xsc3_do_suspend)
> +
> +ENTRY(cpu_xsc3_do_resume)
> + ? ? ? ldmia ? r0, {r1, r4 - r10} ? ? ?@ load v:p offset + cp regs
> + ? ? ? mov ? ? ip, #0
> + ? ? ? mcr ? ? p15, 0, ip, c7, c7, 0 ? @ invalidate I & D caches, BTB
> + ? ? ? mcr ? ? p15, 0, ip, c7, c10, 4 ?@ drain write (&fill) buffer
> + ? ? ? mcr ? ? p15, 0, ip, c7, c5, 4 ? @ flush prefetch buffer
> + ? ? ? mcr ? ? p15, 0, ip, c8, c7, 0 ? @ invalidate I & D TLBs
> + ? ? ? mcr ? ? p14, 0, r4, c6, c0, 0 ? @ clock configuration, turbo mode.
> + ? ? ? mcr ? ? p15, 0, r5, c15, c1, 0 ?@ CP access reg
> + ? ? ? mcr ? ? p15, 0, r6, c13, c0, 0 ?@ PID
> + ? ? ? mcr ? ? p15, 0, r7, c3, c0, 0 ? @ domain ID
> + ? ? ? mcr ? ? p15, 0, r8, c2, c0, 0 ? @ translation table base addr
> + ? ? ? mcr ? ? p15, 0, r9, c1, c0, 1 ? @ auxiliary control reg
> +
> + ? ? ? @ temporarily map resume_turn_on_mmu into the page table,
> + ? ? ? @ otherwise prefetch abort occurs after MMU is turned on
> + ? ? ? mov ? ? r0, r10 ? ? ? ? ? ? ? ? @ control register
> + ? ? ? mov ? ? r2, r8, lsr #14 ? ? ? ? @ get TTB0 base
> + ? ? ? mov ? ? r2, r2, lsl #14
> + ? ? ? ldr ? ? r3, =0x542e ? ? ? ? ? ? @ section flags
> + ? ? ? b ? ? ? cpu_resume_mmu
> +ENDPROC(cpu_xsc3_do_resume)
> +#else
> +#define cpu_xsc3_do_suspend ? ?0
> +#define cpu_xsc3_do_resume ? ? 0
> +#endif
> +
> ? ? ? ?__CPUINIT
>
> ? ? ? ?.type ? __xsc3_setup, #function
> @@ -476,6 +519,9 @@ ENTRY(xsc3_processor_functions)
> ? ? ? ?.word ? cpu_xsc3_dcache_clean_area
> ? ? ? ?.word ? cpu_xsc3_switch_mm
> ? ? ? ?.word ? cpu_xsc3_set_pte_ext
> + ? ? ? .word ? cpu_xsc3_suspend_size
> + ? ? ? .word ? cpu_xsc3_do_suspend
> + ? ? ? .word ? cpu_xsc3_do_resume
> ? ? ? ?.size ? xsc3_processor_functions, . - xsc3_processor_functions
>
> ? ? ? ?.section ".rodata"
> diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
> index 5a37c5e..086038c 100644
> --- a/arch/arm/mm/proc-xscale.S
> +++ b/arch/arm/mm/proc-xscale.S
> @@ -513,11 +513,49 @@ ENTRY(cpu_xscale_set_pte_ext)
> ? ? ? ?xscale_set_pte_ext_epilogue
> ? ? ? ?mov ? ? pc, lr
>
> -
> ? ? ? ?.ltorg
> -
> ? ? ? ?.align
>
> +.globl cpu_xscale_suspend_size
> +.equ ? cpu_xscale_suspend_size, 4 * 7
> +#ifdef CONFIG_PM
> +ENTRY(cpu_xscale_do_suspend)
> + ? ? ? stmfd ? sp!, {r4 - r10, lr}
> + ? ? ? mrc ? ? p14, 0, r4, c6, c0, 0 ? @ clock configuration, for turbo mode
> + ? ? ? mrc ? ? p15, 0, r5, c15, c1, 0 ?@ CP access reg
> + ? ? ? mrc ? ? p15, 0, r6, c13, c0, 0 ?@ PID
> + ? ? ? mrc ? ? p15, 0, r7, c3, c0, 0 ? @ domain ID
> + ? ? ? mrc ? ? p15, 0, r8, c2, c0, 0 ? @ translation table base addr
> + ? ? ? mrc ? ? p15, 0, r9, c1, c1, 0 ? @ auxiliary control reg
> + ? ? ? mrc ? ? p15, 0, r10, c1, c0, 0 ?@ control reg
> + ? ? ? bic ? ? r4, r4, #2 ? ? ? ? ? ? ?@ clear frequency change bit
> + ? ? ? stmia ? r0, {r4 - r10} ? ? ? ? ?@ store cp regs
> + ? ? ? ldmfd ? sp!, {r4 - r10, pc}
> +ENDPROC(cpu_xscale_do_suspend)
> +
> +ENTRY(cpu_xscale_do_resume)
> + ? ? ? ldmia ? r0, {r4 - r10} ? ? ? ? ?@ load cp regs
> + ? ? ? mov ? ? ip, #0
> + ? ? ? mcr ? ? p15, 0, ip, c8, c7, 0 ? @ invalidate I & D TLBs
> + ? ? ? mcr ? ? p15, 0, ip, c7, c7, 0 ? @ invalidate I & D caches, BTB
> + ? ? ? mcr ? ? p14, 0, r4, c6, c0, 0 ? @ clock configuration, turbo mode.
> + ? ? ? mcr ? ? p15, 0, r5, c15, c1, 0 ?@ CP access reg
> + ? ? ? mcr ? ? p15, 0, r6, c13, c0, 0 ?@ PID
> + ? ? ? mcr ? ? p15, 0, r7, c3, c0, 0 ? @ domain ID
> + ? ? ? mcr ? ? p15, 0, r8, c2, c0, 0 ? @ translation table base addr
> + ? ? ? mcr ? ? p15, 0, r9, c1, c1, 0 ? @ auxiliary control reg
> + ? ? ? mov ? ? r0, r10 ? ? ? ? ? ? ? ? @ control register
> + ? ? ? mov ? ? r2, r8, lsr #14 ? ? ? ? @ get TTB0 base
> + ? ? ? mov ? ? r2, r2, lsl #14
> + ? ? ? ldr ? ? r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
> + ? ? ? ? ? ? ? ? ? ?PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
> + ? ? ? b ? ? ? cpu_resume_mmu
> +ENDPROC(cpu_xscale_do_resume)
> +#else
> +#define cpu_xscale_do_suspend ?0
> +#define cpu_xscale_do_resume ? 0
> +#endif
> +
> ? ? ? ?__CPUINIT
>
> ? ? ? ?.type ? __xscale_setup, #function
> @@ -565,6 +603,9 @@ ENTRY(xscale_processor_functions)
> ? ? ? ?.word ? cpu_xscale_dcache_clean_area
> ? ? ? ?.word ? cpu_xscale_switch_mm
> ? ? ? ?.word ? cpu_xscale_set_pte_ext
> + ? ? ? .word ? cpu_xscale_suspend_size
> + ? ? ? .word ? cpu_xscale_do_suspend
> + ? ? ? .word ? cpu_xscale_do_resume
> ? ? ? ?.size ? xscale_processor_functions, . - xscale_processor_functions
>
> ? ? ? ?.section ".rodata"
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 13:21 ` saeed bishara
@ 2011-02-07 13:34 ` Russell King - ARM Linux
2011-02-07 14:04 ` saeed bishara
0 siblings, 1 reply; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-07 13:34 UTC (permalink / raw)
To: linux-arm-kernel
http://en.wikipedia.org/wiki/Posting_style#Trimming_and_reformatting
It's really not nice to page down and down and down to find out the one
or two lines that actually contain something useful - or in my case
scroll through the first three pages, then go to the bottom and start
scrolling up. It wastes time.
Please *always* trim the quoted text down to the context that's relevant
for your reply, like this:
On Mon, Feb 07, 2011 at 03:21:51PM +0200, saeed bishara wrote:
> On Mon, Feb 7, 2011 at 2:10 PM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > +ENTRY(cpu_resume_mmu)
> > + ? ? ? adr ? ? r4, cpu_resume_turn_mmu_on
> > + ? ? ? mov ? ? r4, r4, lsr #20
> > + ? ? ? orr ? ? r3, r3, r4, lsl #20
> > + ? ? ? ldr ? ? r5, [r2, r4, lsl #2] ? ?@ save old mapping
> > + ? ? ? str ? ? r3, [r2, r4, lsl #2] ? ?@ setup 1:1 mapping for mmu code
> this code doesn't look smp save, it modifies page table that could be
> used by another cpu. I suggest to create (at boot time) identity page
> table and use it in order to do mmu on.
When you suspend/resume, the other CPUs will be hot-unplugged before
suspend, and hot-plugged after resume. SMP issues really don't come
in here, and there's not really many other ways to solve the inherent
races involved with turning on the MMU.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 13:34 ` Russell King - ARM Linux
@ 2011-02-07 14:04 ` saeed bishara
2011-02-07 14:17 ` Russell King - ARM Linux
0 siblings, 1 reply; 33+ messages in thread
From: saeed bishara @ 2011-02-07 14:04 UTC (permalink / raw)
To: linux-arm-kernel
> It's really not nice to page down and down and down to find out the one
> or two lines that actually contain something useful - or in my case
> scroll through the first three pages, then go to the bottom and start
> scrolling up. ?It wastes time.
sorry
>
>> this code doesn't look smp save, it modifies page table that could be
>> used by another cpu. I suggest to create (at ?boot time) identity page
>> table and use it in order to do mmu on.
>
> When you suspend/resume, the other CPUs will be hot-unplugged before
> suspend, and hot-plugged after resume. ?SMP issues really don't come
> in here, and there's not really many other ways to solve the inherent
> races involved with turning on the MMU.
that's right, but in the future this code can be used also for
cpuidle, so please take that into account.
also, I think cpu_resume_after_mmu needs to invalidates the TLB
after restoring the old mapping.
one more comment, don't you need to restore the context ID cp15 register?
saeed
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 14:04 ` saeed bishara
@ 2011-02-07 14:17 ` Russell King - ARM Linux
2011-02-07 14:27 ` saeed bishara
` (2 more replies)
0 siblings, 3 replies; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-07 14:17 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 07, 2011 at 04:04:09PM +0200, saeed bishara wrote:
> > It's really not nice to page down and down and down to find out the one
> > or two lines that actually contain something useful - or in my case
> > scroll through the first three pages, then go to the bottom and start
> > scrolling up. ?It wastes time.
> sorry
> >
> >> this code doesn't look smp save, it modifies page table that could be
> >> used by another cpu. I suggest to create (at ?boot time) identity page
> >> table and use it in order to do mmu on.
> >
> > When you suspend/resume, the other CPUs will be hot-unplugged before
> > suspend, and hot-plugged after resume. ?SMP issues really don't come
> > in here, and there's not really many other ways to solve the inherent
> > races involved with turning on the MMU.
> that's right, but in the future this code can be used also for
> cpuidle, so please take that into account.
As I've said, there's not much other choice here. We _have_ to have an
identity mapping in place to bring the MMU back online, or we'll crash.
That's non-optional. So if this is a problem for cpuidle, cpuidle needs
to ensure that a page table switch has happened prior to the CPU going
down which _can_ be safely modified.
> also, I think cpu_resume_after_mmu needs to invalidates the TLB
> after restoring the old mapping.
Probably - and that's not going to be soo easy to work into this...
I'll see later this afternoon about adding that.
> one more comment, don't you need to restore the context ID cp15 register?
Yes it does, and I wonder why the Samsung folk aren't doing so. Here's
v4 with that added.
arch/arm/include/asm/glue-proc.h | 3 +
arch/arm/include/asm/proc-fns.h | 7 ++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/asm-offsets.c | 9 +++
arch/arm/kernel/sleep.S | 110 ++++++++++++++++++++++++++++++++++++
arch/arm/mm/proc-arm1020.S | 3 +
arch/arm/mm/proc-arm1020e.S | 3 +
arch/arm/mm/proc-arm1022.S | 3 +
arch/arm/mm/proc-arm1026.S | 3 +
arch/arm/mm/proc-arm6_7.S | 6 ++
arch/arm/mm/proc-arm720.S | 3 +
arch/arm/mm/proc-arm740.S | 3 +
arch/arm/mm/proc-arm7tdmi.S | 3 +
arch/arm/mm/proc-arm920.S | 37 ++++++++++++
arch/arm/mm/proc-arm922.S | 3 +
arch/arm/mm/proc-arm925.S | 3 +
arch/arm/mm/proc-arm926.S | 37 ++++++++++++
arch/arm/mm/proc-arm940.S | 3 +
arch/arm/mm/proc-arm946.S | 3 +
arch/arm/mm/proc-arm9tdmi.S | 3 +
arch/arm/mm/proc-fa526.S | 3 +
arch/arm/mm/proc-feroceon.S | 3 +
arch/arm/mm/proc-mohawk.S | 3 +
arch/arm/mm/proc-sa110.S | 3 +
arch/arm/mm/proc-sa1100.S | 39 +++++++++++++
arch/arm/mm/proc-v6.S | 50 ++++++++++++++++
arch/arm/mm/proc-v7.S | 116 ++++++++++++++++++++++++++++----------
arch/arm/mm/proc-xsc3.S | 48 +++++++++++++++-
arch/arm/mm/proc-xscale.S | 45 ++++++++++++++-
29 files changed, 523 insertions(+), 33 deletions(-)
diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
index e3bf443..6469521 100644
--- a/arch/arm/include/asm/glue-proc.h
+++ b/arch/arm/include/asm/glue-proc.h
@@ -256,6 +256,9 @@
#define cpu_dcache_clean_area __glue(CPU_NAME,_dcache_clean_area)
#define cpu_do_switch_mm __glue(CPU_NAME,_switch_mm)
#define cpu_set_pte_ext __glue(CPU_NAME,_set_pte_ext)
+#define cpu_suspend_size __glue(CPU_NAME,_suspend_size)
+#define cpu_do_suspend __glue(CPU_NAME,_do_suspend)
+#define cpu_do_resume __glue(CPU_NAME,_do_resume)
#endif
#endif
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 6980215..8ec535e 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -66,6 +66,11 @@ extern struct processor {
* ignore 'ext'.
*/
void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
+
+ /* Suspend/resume */
+ unsigned int suspend_size;
+ void (*do_suspend)(void *);
+ void (*do_resume)(void *);
} processor;
#ifndef MULTI_CPU
@@ -86,6 +91,8 @@ extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
#endif
+extern void cpu_resume(void);
+
#include <asm/memory.h>
#ifdef CONFIG_MMU
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 185ee82..74554f1 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o
obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
obj-$(CONFIG_PCI) += bios32.o isa.o
+obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 5302a91..927522c 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -13,6 +13,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
#include <asm/glue-df.h>
#include <asm/glue-pf.h>
#include <asm/mach/arch.h>
@@ -116,6 +117,14 @@ int main(void)
#ifdef MULTI_PABORT
DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort));
#endif
+#ifdef MULTI_CPU
+ DEFINE(CPU_SLEEP_SIZE, offsetof(struct processor, suspend_size));
+ DEFINE(CPU_DO_SUSPEND, offsetof(struct processor, do_suspend));
+ DEFINE(CPU_DO_RESUME, offsetof(struct processor, do_resume));
+#endif
+#ifdef MULTI_CACHE
+ DEFINE(CACHE_FLUSH_KERN_ALL, offsetof(struct cpu_cache_fns, flush_kern_all));
+#endif
BLANK();
DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
new file mode 100644
index 0000000..9f106fa
--- /dev/null
+++ b/arch/arm/kernel/sleep.S
@@ -0,0 +1,110 @@
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+#include <asm/glue-cache.h>
+#include <asm/glue-proc.h>
+ .text
+
+/*
+ * Save CPU state for a suspend
+ * r1 = v:p offset
+ * r3 = virtual return function
+ * Note: sp is decremented to allocate space for CPU state on stack
+ * r0-r3,r9,r10,lr corrupted
+ */
+ENTRY(cpu_suspend)
+ mov r9, lr
+#ifdef MULTI_CPU
+ ldr r10, =processor
+ mov r2, sp @ current virtual SP
+ ldr r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+ ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
+ sub sp, sp, r0 @ allocate CPU state on stack
+ mov r0, sp @ save pointer
+ add ip, ip, r1 @ convert resume fn to phys
+ stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn
+ ldr r3, =sleep_save_sp
+ add r2, sp, r1 @ convert SP to phys
+ str r2, [r3] @ save phys SP
+ mov lr, pc
+ ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
+#else
+ mov r2, sp @ current virtual SP
+ ldr r0, =cpu_suspend_size
+ sub sp, sp, r0 @ allocate CPU state on stack
+ mov r0, sp @ save pointer
+ stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn
+ ldr r3, =sleep_save_sp
+ add r2, sp, r1 @ convert SP to phys
+ str r2, [r3] @ save phys SP
+ bl cpu_do_suspend
+#endif
+
+ @ flush data cache
+#ifdef MULTI_CACHE
+ ldr r10, =cpu_cache
+ mov lr, r9
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ mov lr, r9
+ b __cpuc_flush_kern_all
+#endif
+ENDPROC(cpu_suspend)
+ .ltorg
+
+/*
+ * r0 = control register value
+ * r1 = v:p offset (preserved by cpu_do_resume)
+ * r2 = phys page table base
+ * r3 = L1 section flags
+ */
+ENTRY(cpu_resume_mmu)
+ adr r4, cpu_resume_turn_mmu_on
+ mov r4, r4, lsr #20
+ orr r3, r3, r4, lsl #20
+ ldr r5, [r2, r4, lsl #2] @ save old mapping
+ str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code
+ sub r2, r2, r1
+ ldr r3, =cpu_resume_after_mmu
+ b cpu_resume_turn_mmu_on
+ENDPROC(cpu_resume_mmu)
+ .ltorg
+ .align 5
+cpu_resume_turn_mmu_on:
+ mcr p15, 0, r0, c1, c0, 0 @ turn on MMU, caches, etc
+ mrc p15, 0, r0, c0, c0, 0 @ read id reg
+ mov r0, r0
+ mov r0, r0
+ mov pc, r3 @ jump to virtual address
+ENDPROC(cpu_resume_turn_mmu_on)
+cpu_resume_after_mmu:
+ str r5, [r2, r4, lsl #2] @ restore old mapping
+#ifdef MULTI_CACHE
+ ldr r10, =cpu_cache
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ b __cpuc_flush_kern_all
+#endif
+
+/*
+ * Note: Yes, part of the following code is located into the .data section.
+ * This is to allow sleep_save_sp to be accessed with a relative load
+ * while we can't rely on any MMU translation. We could have put
+ * sleep_save_sp in the .text section as well, but some setups might
+ * insist on it to be truly read-only.
+ */
+ .data
+ .align
+ENTRY(cpu_resume)
+ ldr r0, sleep_save_sp @ stack phys addr
+ msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
+#ifdef MULTI_CPU
+ ldmia r0!, {r1, sp, lr, pc} @ load v:p, stack, return fn, resume fn
+#else
+ ldmia r0!, {r1, sp, lr} @ load v:p, stack, return fn
+ b cpu_do_resume
+#endif
+ENDPROC(cpu_resume)
+
+sleep_save_sp:
+ .word 0 @ preserve stack phys ptr here
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index bcf748d..226e3d8 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -493,6 +493,9 @@ arm1020_processor_functions:
.word cpu_arm1020_dcache_clean_area
.word cpu_arm1020_switch_mm
.word cpu_arm1020_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1020_processor_functions, . - arm1020_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index ab7ec26..86d9c2c 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -474,6 +474,9 @@ arm1020e_processor_functions:
.word cpu_arm1020e_dcache_clean_area
.word cpu_arm1020e_switch_mm
.word cpu_arm1020e_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1020e_processor_functions, . - arm1020e_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 831c5e5..83d3dd3 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -457,6 +457,9 @@ arm1022_processor_functions:
.word cpu_arm1022_dcache_clean_area
.word cpu_arm1022_switch_mm
.word cpu_arm1022_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1022_processor_functions, . - arm1022_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index e3f7e9a..686043e 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -452,6 +452,9 @@ arm1026_processor_functions:
.word cpu_arm1026_dcache_clean_area
.word cpu_arm1026_switch_mm
.word cpu_arm1026_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm1026_processor_functions, . - arm1026_processor_functions
.section .rodata
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 6a7be18..5f79dc4 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -284,6 +284,9 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_dcache_clean_area
.word cpu_arm6_switch_mm
.word cpu_arm6_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm6_processor_functions, . - arm6_processor_functions
/*
@@ -301,6 +304,9 @@ ENTRY(arm7_processor_functions)
.word cpu_arm7_dcache_clean_area
.word cpu_arm7_switch_mm
.word cpu_arm7_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm7_processor_functions, . - arm7_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index c285395..665266d 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -185,6 +185,9 @@ ENTRY(arm720_processor_functions)
.word cpu_arm720_dcache_clean_area
.word cpu_arm720_switch_mm
.word cpu_arm720_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm720_processor_functions, . - arm720_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 38b27dc..6f9d12e 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -130,6 +130,9 @@ ENTRY(arm740_processor_functions)
.word cpu_arm740_dcache_clean_area
.word cpu_arm740_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm740_processor_functions, . - arm740_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 0c9786d..e4c165c 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -70,6 +70,9 @@ ENTRY(arm7tdmi_processor_functions)
.word cpu_arm7tdmi_dcache_clean_area
.word cpu_arm7tdmi_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 6109f27..b2705de 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -387,6 +387,40 @@ ENTRY(cpu_arm920_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl arm920_suspend_size
+.equ arm920_suspend_size, 4 * 3
+#ifdef CONFIG_PM
+ENTRY(arm920_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(arm920_do_suspend)
+
+ENTRY(arm920_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
+ ldmia r0, {r4 - r7}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mov r0, r7 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(arm920_do_resume)
+#else
+#define arm920_do_suspend 0
+#define arm920_do_resume 0
+#endif
+
__CPUINIT
.type __arm920_setup, #function
@@ -432,6 +466,9 @@ arm920_processor_functions:
.word cpu_arm920_dcache_clean_area
.word cpu_arm920_switch_mm
.word cpu_arm920_set_pte_ext
+ .word arm920_suspend_size
+ .word arm920_do_suspend
+ .word arm920_do_resume
.size arm920_processor_functions, . - arm920_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index bb2f0f4..36154b1 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -436,6 +436,9 @@ arm922_processor_functions:
.word cpu_arm922_dcache_clean_area
.word cpu_arm922_switch_mm
.word cpu_arm922_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm922_processor_functions, . - arm922_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index c13e01a..89c5e00 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -503,6 +503,9 @@ arm925_processor_functions:
.word cpu_arm925_dcache_clean_area
.word cpu_arm925_switch_mm
.word cpu_arm925_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size arm925_processor_functions, . - arm925_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 42eb431..3beb784 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -401,6 +401,40 @@ ENTRY(cpu_arm926_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl arm926_suspend_size
+.equ arm926_suspend_size, 4 * 3
+#ifdef CONFIG_PM
+ENTRY(arm926_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(arm926_do_suspend)
+
+ENTRY(arm926_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
+ ldmia r0, {r4 - r7}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mov r0, r7 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(arm926_do_resume)
+#else
+#define arm926_do_suspend 0
+#define arm926_do_resume 0
+#endif
+
__CPUINIT
.type __arm926_setup, #function
@@ -456,6 +490,9 @@ arm926_processor_functions:
.word cpu_arm926_dcache_clean_area
.word cpu_arm926_switch_mm
.word cpu_arm926_set_pte_ext
+ .word arm926_suspend_size
+ .word arm926_do_suspend
+ .word arm926_do_resume
.size arm926_processor_functions, . - arm926_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index 7b11cdb..26aea3f 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -363,6 +363,9 @@ ENTRY(arm940_processor_functions)
.word cpu_arm940_dcache_clean_area
.word cpu_arm940_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm940_processor_functions, . - arm940_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 1a5bbf0..8063345 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -419,6 +419,9 @@ ENTRY(arm946_processor_functions)
.word cpu_arm946_dcache_clean_area
.word cpu_arm946_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm946_processor_functions, . - arm946_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index db67e31..7b7ebd4 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -70,6 +70,9 @@ ENTRY(arm9tdmi_processor_functions)
.word cpu_arm9tdmi_dcache_clean_area
.word cpu_arm9tdmi_switch_mm
.word 0 @ cpu_*_set_pte
+ .word 0
+ .word 0
+ .word 0
.size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 7c9ad62..fc2a4ae 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -195,6 +195,9 @@ fa526_processor_functions:
.word cpu_fa526_dcache_clean_area
.word cpu_fa526_switch_mm
.word cpu_fa526_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size fa526_processor_functions, . - fa526_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index b4597ed..d3883ee 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -554,6 +554,9 @@ feroceon_processor_functions:
.word cpu_feroceon_dcache_clean_area
.word cpu_feroceon_switch_mm
.word cpu_feroceon_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size feroceon_processor_functions, . - feroceon_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 4458ee6..9d4f2ae 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -388,6 +388,9 @@ mohawk_processor_functions:
.word cpu_mohawk_dcache_clean_area
.word cpu_mohawk_switch_mm
.word cpu_mohawk_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size mohawk_processor_functions, . - mohawk_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 5aa8d59..46f09ed 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -203,6 +203,9 @@ ENTRY(sa110_processor_functions)
.word cpu_sa110_dcache_clean_area
.word cpu_sa110_switch_mm
.word cpu_sa110_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size sa110_processor_functions, . - sa110_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 2ac4e6f..74483d1 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -169,6 +169,42 @@ ENTRY(cpu_sa1100_set_pte_ext)
#endif
mov pc, lr
+.globl cpu_sa1100_suspend_size
+.equ cpu_sa1100_suspend_size, 4*4
+#ifdef CONFIG_PM
+ENTRY(cpu_sa1100_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c3, c0, 0 @ domain ID
+ mrc p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c1, c0, 0 @ control reg
+ stmia r0, {r4 - r7} @ store cp regs
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(cpu_sa1100_do_suspend)
+
+ENTRY(cpu_sa1100_do_resume)
+ ldmia r0, {r4 - r7} @ load cp regs
+ mov r1, #0
+ mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs
+ mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache
+ mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
+ mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB
+
+ mcr p15, 0, r4, c3, c0, 0 @ domain ID
+ mcr p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mov r0, r7 @ control register
+ mov r2, r5, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(cpu_sa1100_do_resume)
+#else
+#define cpu_sa1100_do_suspend 0
+#define cpu_sa1100_do_resume 0
+#endif
+
__CPUINIT
.type __sa1100_setup, #function
@@ -218,6 +254,9 @@ ENTRY(sa1100_processor_functions)
.word cpu_sa1100_dcache_clean_area
.word cpu_sa1100_switch_mm
.word cpu_sa1100_set_pte_ext
+ .word cpu_sa1100_suspend_size
+ .word cpu_sa1100_do_suspend
+ .word cpu_sa1100_do_resume
.size sa1100_processor_functions, . - sa1100_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 59a7e1f..832b6bd 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -121,6 +121,53 @@ ENTRY(cpu_v6_set_pte_ext)
#endif
mov pc, lr
+/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
+.globl cpu_v6_suspend_size
+.equ cpu_v6_suspend_size, 4 * 8
+#ifdef CONFIG_PM
+ENTRY(cpu_v6_do_suspend)
+ stmfd sp!, {r4 - r11, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c13, c0, 1 @ Context ID
+ mrc p15, 0, r6, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r7, c2, c0, 0 @ Translation table base 0
+ mrc p15, 0, r8, c2, c0, 1 @ Translation table base 1
+ mrc p15, 0, r9, c1, c0, 1 @ auxillary control register
+ mrc p15, 0, r10, c1, c0, 2 @ co-processor access control
+ mrc p15, 0, r11, c1, c0, 0 @ control register
+ stmia r0, {r4 - r11}
+ ldmfd sp!, {r4- r11, pc}
+ENDPROC(cpu_v6_do_suspend)
+
+ENTRY(cpu_v6_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c14, 0 @ clean+invalidate D cache
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
+ ldmia r0, {r4 - r11}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c13, c0, 1 @ Context ID
+ mcr p15, 0, r6, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r7, c2, c0, 0 @ Translation table base 0
+ mcr p15, 0, r8, c2, c0, 1 @ Translation table base 1
+ mcr p15, 0, r9, c1, c0, 1 @ auxillary control register
+ mcr p15, 0, r10, c1, c0, 2 @ co-processor access control
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+ mcr p15, 0, ip, c7, c5, 4 @ ISB
+ mov r0, r11 @ control register
+ mov r2, r7, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, cpu_resume_l1_flags
+ b cpu_resume_mmu
+ENDPROC(cpu_v6_do_resume)
+cpu_resume_l1_flags:
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v6_do_suspend 0
+#define cpu_v6_do_resume 0
+#endif
.type cpu_v6_name, #object
@@ -206,6 +253,9 @@ ENTRY(v6_processor_functions)
.word cpu_v6_dcache_clean_area
.word cpu_v6_switch_mm
.word cpu_v6_set_pte_ext
+ .word cpu_v6_suspend_size
+ .word cpu_v6_do_suspend
+ .word cpu_v6_do_resume
.size v6_processor_functions, . - v6_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 0c1172b..a5187dd 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -171,6 +171,87 @@ cpu_v7_name:
.ascii "ARMv7 Processor"
.align
+ /*
+ * Memory region attributes with SCTLR.TRE=1
+ *
+ * n = TEX[0],C,B
+ * TR = PRRR[2n+1:2n] - memory type
+ * IR = NMRR[2n+1:2n] - inner cacheable property
+ * OR = NMRR[2n+17:2n+16] - outer cacheable property
+ *
+ * n TR IR OR
+ * UNCACHED 000 00
+ * BUFFERABLE 001 10 00 00
+ * WRITETHROUGH 010 10 10 10
+ * WRITEBACK 011 10 11 11
+ * reserved 110
+ * WRITEALLOC 111 10 01 01
+ * DEV_SHARED 100 01
+ * DEV_NONSHARED 100 01
+ * DEV_WC 001 10
+ * DEV_CACHED 011 10
+ *
+ * Other attributes:
+ *
+ * DS0 = PRRR[16] = 0 - device shareable property
+ * DS1 = PRRR[17] = 1 - device shareable property
+ * NS0 = PRRR[18] = 0 - normal shareable property
+ * NS1 = PRRR[19] = 1 - normal shareable property
+ * NOS = PRRR[24+n] = 1 - not outer shareable
+ */
+.equ PRRR, 0xff0a81a8
+.equ NMRR, 0x40e040e0
+
+/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
+.globl cpu_v7_suspend_size
+.equ cpu_v7_suspend_size, 4 * 8
+#ifdef CONFIG_PM
+ENTRY(cpu_v7_do_suspend)
+ stmfd sp!, {r4 - r11, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c13, c0, 1 @ Context ID
+ mrc p15, 0, r6, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r7, c2, c0, 0 @ TTB 0
+ mrc p15, 0, r8, c2, c0, 1 @ TTB 1
+ mrc p15, 0, r9, c1, c0, 0 @ Control register
+ mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r11, c1, c0, 2 @ Co-processor access control
+ stmia r0, {r4 - r11}
+ ldmfd sp!, {r4 - r11, pc}
+ENDPROC(cpu_v7_do_suspend)
+
+ENTRY(cpu_v7_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ ldmia r0, {r4 - r11}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c13, c0, 1 @ Context ID
+ mcr p15, 0, r6, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r7, c2, c0, 0 @ TTB 0
+ mcr p15, 0, r8, c2, c0, 1 @ TTB 1
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+ mcr p15, 0, r10, c1, c0, 1 @ Auxillary control register
+ mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control
+ ldr r4, =PRRR @ PRRR
+ ldr r5, =NMRR @ NMRR
+ mcr p15, 0, r4, c10, c2, 0 @ write PRRR
+ mcr p15, 0, r5, c10, c2, 1 @ write NMRR
+ isb
+ mov r0, r9 @ control register
+ mov r2, r7, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, cpu_resume_l1_flags
+ b cpu_resume_mmu
+ENDPROC(cpu_v7_do_resume)
+cpu_resume_l1_flags:
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v7_do_suspend 0
+#define cpu_v7_do_resume 0
+#endif
+
__CPUINIT
/*
@@ -276,36 +357,8 @@ __v7_setup:
ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
- /*
- * Memory region attributes with SCTLR.TRE=1
- *
- * n = TEX[0],C,B
- * TR = PRRR[2n+1:2n] - memory type
- * IR = NMRR[2n+1:2n] - inner cacheable property
- * OR = NMRR[2n+17:2n+16] - outer cacheable property
- *
- * n TR IR OR
- * UNCACHED 000 00
- * BUFFERABLE 001 10 00 00
- * WRITETHROUGH 010 10 10 10
- * WRITEBACK 011 10 11 11
- * reserved 110
- * WRITEALLOC 111 10 01 01
- * DEV_SHARED 100 01
- * DEV_NONSHARED 100 01
- * DEV_WC 001 10
- * DEV_CACHED 011 10
- *
- * Other attributes:
- *
- * DS0 = PRRR[16] = 0 - device shareable property
- * DS1 = PRRR[17] = 1 - device shareable property
- * NS0 = PRRR[18] = 0 - normal shareable property
- * NS1 = PRRR[19] = 1 - normal shareable property
- * NOS = PRRR[24+n] = 1 - not outer shareable
- */
- ldr r5, =0xff0a81a8 @ PRRR
- ldr r6, =0x40e040e0 @ NMRR
+ ldr r5, =PRRR @ PRRR
+ ldr r6, =NMRR @ NMRR
mcr p15, 0, r5, c10, c2, 0 @ write PRRR
mcr p15, 0, r6, c10, c2, 1 @ write NMRR
#endif
@@ -351,6 +404,9 @@ ENTRY(v7_processor_functions)
.word cpu_v7_dcache_clean_area
.word cpu_v7_switch_mm
.word cpu_v7_set_pte_ext
+ .word 0
+ .word 0
+ .word 0
.size v7_processor_functions, . - v7_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index ec26355..63d8b20 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -413,9 +413,52 @@ ENTRY(cpu_xsc3_set_pte_ext)
mov pc, lr
.ltorg
-
.align
+.globl cpu_xsc3_suspend_size
+.equ cpu_xsc3_suspend_size, 4 * 8
+#ifdef CONFIG_PM
+ENTRY(cpu_xsc3_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+ mrc p15, 0, r5, c15, c1, 0 @ CP access reg
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c3, c0, 0 @ domain ID
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r1, r4 - r10} @ store v:p offset + cp regs
+ ldmia sp!, {r4 - r10, pc}
+ENDPROC(cpu_xsc3_do_suspend)
+
+ENTRY(cpu_xsc3_do_resume)
+ ldmia r0, {r1, r4 - r10} @ load v:p offset + cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer
+ mcr p15, 0, ip, c7, c5, 4 @ flush prefetch buffer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
+ mcr p15, 0, r5, c15, c1, 0 @ CP access reg
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mcr p15, 0, r7, c3, c0, 0 @ domain ID
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+
+ @ temporarily map resume_turn_on_mmu into the page table,
+ @ otherwise prefetch abort occurs after MMU is turned on
+ mov r0, r10 @ control register
+ mov r2, r8, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =0x542e @ section flags
+ b cpu_resume_mmu
+ENDPROC(cpu_xsc3_do_resume)
+#else
+#define cpu_xsc3_do_suspend 0
+#define cpu_xsc3_do_resume 0
+#endif
+
__CPUINIT
.type __xsc3_setup, #function
@@ -476,6 +519,9 @@ ENTRY(xsc3_processor_functions)
.word cpu_xsc3_dcache_clean_area
.word cpu_xsc3_switch_mm
.word cpu_xsc3_set_pte_ext
+ .word cpu_xsc3_suspend_size
+ .word cpu_xsc3_do_suspend
+ .word cpu_xsc3_do_resume
.size xsc3_processor_functions, . - xsc3_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 5a37c5e..086038c 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -513,11 +513,49 @@ ENTRY(cpu_xscale_set_pte_ext)
xscale_set_pte_ext_epilogue
mov pc, lr
-
.ltorg
-
.align
+.globl cpu_xscale_suspend_size
+.equ cpu_xscale_suspend_size, 4 * 7
+#ifdef CONFIG_PM
+ENTRY(cpu_xscale_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+ mrc p15, 0, r5, c15, c1, 0 @ CP access reg
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c3, c0, 0 @ domain ID
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r4 - r10} @ store cp regs
+ ldmfd sp!, {r4 - r10, pc}
+ENDPROC(cpu_xscale_do_suspend)
+
+ENTRY(cpu_xscale_do_resume)
+ ldmia r0, {r4 - r10} @ load cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
+ mcr p15, 0, r5, c15, c1, 0 @ CP access reg
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mcr p15, 0, r7, c3, c0, 0 @ domain ID
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mov r0, r10 @ control register
+ mov r2, r8, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(cpu_xscale_do_resume)
+#else
+#define cpu_xscale_do_suspend 0
+#define cpu_xscale_do_resume 0
+#endif
+
__CPUINIT
.type __xscale_setup, #function
@@ -565,6 +603,9 @@ ENTRY(xscale_processor_functions)
.word cpu_xscale_dcache_clean_area
.word cpu_xscale_switch_mm
.word cpu_xscale_set_pte_ext
+ .word cpu_xscale_suspend_size
+ .word cpu_xscale_do_suspend
+ .word cpu_xscale_do_resume
.size xscale_processor_functions, . - xscale_processor_functions
.section ".rodata"
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 14:17 ` Russell King - ARM Linux
@ 2011-02-07 14:27 ` saeed bishara
2011-02-07 14:33 ` Russell King - ARM Linux
2011-02-08 8:08 ` Colin Cross
2011-02-10 3:15 ` Colin Cross
2 siblings, 1 reply; 33+ messages in thread
From: saeed bishara @ 2011-02-07 14:27 UTC (permalink / raw)
To: linux-arm-kernel
> As I've said, there's not much other choice here. ?We _have_ to have an
> identity mapping in place to bring the MMU back online, or we'll crash.
> That's non-optional. ?So if this is a problem for cpuidle, cpuidle needs
> to ensure that a page table switch has happened prior to the CPU going
> down which _can_ be safely modified.
I fully agree with you, but what I was suggesting is to create
temporary identity page table at boot time, the resume code will load
that page table (Context ID will be loaded with unique ASID), enable
mmu, then the original page table and Context ID will be restored.
saeed
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 14:27 ` saeed bishara
@ 2011-02-07 14:33 ` Russell King - ARM Linux
2011-02-07 14:58 ` saeed bishara
0 siblings, 1 reply; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-07 14:33 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 07, 2011 at 04:27:34PM +0200, saeed bishara wrote:
> > As I've said, there's not much other choice here. ?We _have_ to have an
> > identity mapping in place to bring the MMU back online, or we'll crash.
> > That's non-optional. ?So if this is a problem for cpuidle, cpuidle needs
> > to ensure that a page table switch has happened prior to the CPU going
> > down which _can_ be safely modified.
> I fully agree with you, but what I was suggesting is to create
> temporary identity page table at boot time, the resume code will load
> that page table (Context ID will be loaded with unique ASID), enable
> mmu, then the original page table and Context ID will be restored.
That's much easier to do in C code than in the assembly code. Let's
keep the assembly code as simple as possible...
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 14:33 ` Russell King - ARM Linux
@ 2011-02-07 14:58 ` saeed bishara
2011-02-07 15:02 ` Russell King - ARM Linux
0 siblings, 1 reply; 33+ messages in thread
From: saeed bishara @ 2011-02-07 14:58 UTC (permalink / raw)
To: linux-arm-kernel
>> I fully agree with you, but what I was suggesting is to create
>> temporary identity page table at boot time, the resume code will load
>> that page table (Context ID will be loaded with unique ASID), enable
>> mmu, then the original page table and Context ID will be restored.
>
> That's much easier to do in C code than in the assembly code. ?Let's
> keep the assembly code as simple as possible...
well, the allocation of the identity page table doesn't need to be
done in assembly code. this is the similar to what you did in
__cpu_up.
for example, this allocation can be done in arch/arm/kernel/setup.c.
the assembly code only need to know the offset of this page table.
looks that there are several usages for the identity page table (smp
boot, kexec, pm), maybe all those clients can share the same one.
you may also consider loading this identity page table before calling
suspend flow, thus saving all the v:p stuff, and the resume code will
take care for restoring the original page table after enabling the
mmu.
saeed
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 14:58 ` saeed bishara
@ 2011-02-07 15:02 ` Russell King - ARM Linux
2011-02-08 10:21 ` Lorenzo Pieralisi
0 siblings, 1 reply; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-07 15:02 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 07, 2011 at 04:58:05PM +0200, saeed bishara wrote:
> well, the allocation of the identity page table doesn't need to be
> done in assembly code. this is the similar to what you did in
> __cpu_up.
> for example, this allocation can be done in arch/arm/kernel/setup.c.
> the assembly code only need to know the offset of this page table.
> looks that there are several usages for the identity page table (smp
> boot, kexec, pm), maybe all those clients can share the same one.
We don't want to allocate this at boot time, because it will require
additional maintainence when L1 page tables are added for ioremap() etc.
I feel that it's best to leave it as-is, as this is the method everyone
has been using to date. When it becomes a problem, we can then look at
resolving it.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH 4/5] ARM: pm: convert sa11x0 to generic suspend/resume support
2011-02-06 19:13 ` [PATCH 4/5] ARM: pm: convert sa11x0 " Russell King - ARM Linux
@ 2011-02-07 18:11 ` Russell King - ARM Linux
0 siblings, 0 replies; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-07 18:11 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Feb 06, 2011 at 07:13:25PM +0000, Russell King - ARM Linux wrote:
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Now tested this on Assabet, and it works fine there.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 14:17 ` Russell King - ARM Linux
2011-02-07 14:27 ` saeed bishara
@ 2011-02-08 8:08 ` Colin Cross
2011-02-10 3:15 ` Colin Cross
2 siblings, 0 replies; 33+ messages in thread
From: Colin Cross @ 2011-02-08 8:08 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 7, 2011 at 8:17 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
<snip>
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> new file mode 100644
> index 0000000..9f106fa
> --- /dev/null
> +++ b/arch/arm/kernel/sleep.S
> @@ -0,0 +1,110 @@
> +#include <linux/linkage.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/assembler.h>
> +#include <asm/glue-cache.h>
> +#include <asm/glue-proc.h>
> + ? ? ? .text
> +
> +/*
> + * Save CPU state for a suspend
> + * ?r1 = v:p offset
> + * ?r3 = virtual return function
> + * Note: sp is decremented to allocate space for CPU state on stack
> + * r0-r3,r9,r10,lr corrupted
> + */
> +ENTRY(cpu_suspend)
> + ? ? ? mov ? ? r9, lr
> +#ifdef MULTI_CPU
> + ? ? ? ldr ? ? r10, =processor
> + ? ? ? mov ? ? r2, sp ? ? ? ? ? ? ? ? ?@ current virtual SP
> + ? ? ? ldr ? ? r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
> + ? ? ? ldr ? ? ip, [r10, #CPU_DO_RESUME] @ virtual resume function
> + ? ? ? sub ? ? sp, sp, r0 ? ? ? ? ? ? ?@ allocate CPU state on stack
> + ? ? ? mov ? ? r0, sp ? ? ? ? ? ? ? ? ?@ save pointer
> + ? ? ? add ? ? ip, ip, r1 ? ? ? ? ? ? ?@ convert resume fn to phys
> + ? ? ? stmfd ? sp!, {r1, r2, r3, ip} ? @ save v:p, virt SP, retfn, phys resume fn
> + ? ? ? ldr ? ? r3, =sleep_save_sp
The global variable will prevent using this function to save the state
of multiple CPUs during idle.
<snip>
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index 0c1172b..a5187dd 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
<snip>
> +/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
> +.globl cpu_v7_suspend_size
> +.equ ? cpu_v7_suspend_size, 4 * 8
> +#ifdef CONFIG_PM
> +ENTRY(cpu_v7_do_suspend)
> + ? ? ? stmfd ? sp!, {r4 - r11, lr}
> + ? ? ? mrc ? ? p15, 0, r4, c13, c0, 0 ?@ FCSE/PID
> + ? ? ? mrc ? ? p15, 0, r5, c13, c0, 1 ?@ Context ID
> + ? ? ? mrc ? ? p15, 0, r6, c3, c0, 0 ? @ Domain ID
> + ? ? ? mrc ? ? p15, 0, r7, c2, c0, 0 ? @ TTB 0
> + ? ? ? mrc ? ? p15, 0, r8, c2, c0, 1 ? @ TTB 1
> + ? ? ? mrc ? ? p15, 0, r9, c1, c0, 0 ? @ Control register
> + ? ? ? mrc ? ? p15, 0, r10, c1, c0, 1 ?@ Auxiliary control register
> + ? ? ? mrc ? ? p15, 0, r11, c1, c0, 2 ?@ Co-processor access control
> + ? ? ? stmia ? r0, {r4 - r11}
> + ? ? ? ldmfd ? sp!, {r4 - r11, pc}
> +ENDPROC(cpu_v7_do_suspend)
Should the FIQ banked registers be saved in here, or by the driver
that set them?
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 15:02 ` Russell King - ARM Linux
@ 2011-02-08 10:21 ` Lorenzo Pieralisi
2011-02-08 11:23 ` Russell King - ARM Linux
0 siblings, 1 reply; 33+ messages in thread
From: Lorenzo Pieralisi @ 2011-02-08 10:21 UTC (permalink / raw)
To: linux-arm-kernel
Hi Russell,
On Mon, 2011-02-07 at 15:02 +0000, Russell King - ARM Linux wrote:
> On Mon, Feb 07, 2011 at 04:58:05PM +0200, saeed bishara wrote:
> > well, the allocation of the identity page table doesn't need to be
> > done in assembly code. this is the similar to what you did in
> > __cpu_up.
> > for example, this allocation can be done in arch/arm/kernel/setup.c.
> > the assembly code only need to know the offset of this page table.
> > looks that there are several usages for the identity page table (smp
> > boot, kexec, pm), maybe all those clients can share the same one.
>
> We don't want to allocate this at boot time, because it will require
> additional maintainence when L1 page tables are added for ioremap() etc.
>
> I feel that it's best to leave it as-is, as this is the method everyone
> has been using to date. When it becomes a problem, we can then look at
> resolving it.
>
For v7 MP cpuidle it is already critical, we do need to have a page
table copy for the resume path to be MP safe. The same goes for the
stack pointer global variable which should be per cpu.
Maybe we can just provide an API to pass the page table pointer, then
see how to allocate it and when.
In which branch do these patches live in order to test them and
provide feedback ?
Many thanks,
Lorenzo
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-08 10:21 ` Lorenzo Pieralisi
@ 2011-02-08 11:23 ` Russell King - ARM Linux
2011-02-08 12:33 ` Russell King - ARM Linux
0 siblings, 1 reply; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-08 11:23 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Feb 08, 2011 at 10:21:52AM +0000, Lorenzo Pieralisi wrote:
> Hi Russell,
>
> On Mon, 2011-02-07 at 15:02 +0000, Russell King - ARM Linux wrote:
> > On Mon, Feb 07, 2011 at 04:58:05PM +0200, saeed bishara wrote:
> > > well, the allocation of the identity page table doesn't need to be
> > > done in assembly code. this is the similar to what you did in
> > > __cpu_up.
> > > for example, this allocation can be done in arch/arm/kernel/setup.c.
> > > the assembly code only need to know the offset of this page table.
> > > looks that there are several usages for the identity page table (smp
> > > boot, kexec, pm), maybe all those clients can share the same one.
> >
> > We don't want to allocate this at boot time, because it will require
> > additional maintainence when L1 page tables are added for ioremap() etc.
> >
> > I feel that it's best to leave it as-is, as this is the method everyone
> > has been using to date. When it becomes a problem, we can then look at
> > resolving it.
> >
>
> For v7 MP cpuidle it is already critical, we do need to have a page
> table copy for the resume path to be MP safe.
> Maybe we can just provide an API to pass the page table pointer, then
> see how to allocate it and when.
As I already said - allocate a page table before hand and switch to it,
free it afterwards. This code does not need to have the complexities
of page table allocation mixed into it.
> The same goes for the stack pointer global variable which should be
> per cpu.
Yes, but this is what is currently done, so at the present time I'm
just sorting out what's already in the kernel. If we need further
changes, then that needs to be built on top of this.
> In which branch do these patches live in order to test them and
> provide feedback ?
They're not published yet as I'm waiting for feedback on them, etc.
They're still receiving the odd tweak as comments are received.
Let's get this so that the current suspend/resume code can use it, and
has been tested with it, and then think about adding other uses to it.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-08 11:23 ` Russell King - ARM Linux
@ 2011-02-08 12:33 ` Russell King - ARM Linux
2011-02-08 14:25 ` Lorenzo Pieralisi
0 siblings, 1 reply; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-08 12:33 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Feb 08, 2011 at 11:23:23AM +0000, Russell King - ARM Linux wrote:
> > The same goes for the stack pointer global variable which should be
> > per cpu.
>
> Yes, but this is what is currently done, so at the present time I'm
> just sorting out what's already in the kernel. If we need further
> changes, then that needs to be built on top of this.
Like this:
arch/arm/kernel/sleep.S | 26 +++++++++++++++++++++++++-
1 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 9f106fa..e10618f 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -25,7 +25,14 @@ ENTRY(cpu_suspend)
stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn
ldr r3, =sleep_save_sp
add r2, sp, r1 @ convert SP to phys
+#ifdef CONFIG_SMP
+ ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
+ ALT_UP(mov lr, #0)
+ and lr, lr, #15
+ str r2, [r3, lr, lsl #2] @ save phys SP
+#else
str r2, [r3] @ save phys SP
+#endif
mov lr, pc
ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
#else
@@ -36,7 +43,14 @@ ENTRY(cpu_suspend)
stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn
ldr r3, =sleep_save_sp
add r2, sp, r1 @ convert SP to phys
+#ifdef CONFIG_SMP
+ ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
+ ALT_UP(mov lr, #0)
+ and lr, lr, #15
+ str r2, [r3, lr, lsl #2] @ save phys SP
+#else
str r2, [r3] @ save phys SP
+#endif
bl cpu_do_suspend
#endif
@@ -96,7 +110,15 @@ cpu_resume_after_mmu:
.data
.align
ENTRY(cpu_resume)
+#ifdef CONFIG_SMP
+ adr r0, sleep_save_sp
+ ALT_SMP(mrc p15, 0, r1, c0, c0, 5)
+ ALT_UP(mov r1, #0)
+ and r1, r1, #15
+ ldr r0, [r0, r1, lsl #2] @ stack phys addr
+#else
ldr r0, sleep_save_sp @ stack phys addr
+#endif
msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
#ifdef MULTI_CPU
ldmia r0!, {r1, sp, lr, pc} @ load v:p, stack, return fn, resume fn
@@ -107,4 +129,6 @@ ENTRY(cpu_resume)
ENDPROC(cpu_resume)
sleep_save_sp:
- .word 0 @ preserve stack phys ptr here
+ .rept CONFIG_NR_CPUS
+ .long 0 @ preserve stack phys ptr here
+ .endr
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-08 12:33 ` Russell King - ARM Linux
@ 2011-02-08 14:25 ` Lorenzo Pieralisi
0 siblings, 0 replies; 33+ messages in thread
From: Lorenzo Pieralisi @ 2011-02-08 14:25 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, 2011-02-08 at 12:33 +0000, Russell King - ARM Linux wrote:
<snip>
> > Yes, but this is what is currently done, so at the present time I'm
> > just sorting out what's already in the kernel. If we need further
> > changes, then that needs to be built on top of this.
>
> Like this:
>
> arch/arm/kernel/sleep.S | 26 +++++++++++++++++++++++++-
> 1 files changed, 25 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> index 9f106fa..e10618f 100644
> --- a/arch/arm/kernel/sleep.S
> +++ b/arch/arm/kernel/sleep.S
> @@ -25,7 +25,14 @@ ENTRY(cpu_suspend)
> stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn
> ldr r3, =sleep_save_sp
> add r2, sp, r1 @ convert SP to phys
> +#ifdef CONFIG_SMP
> + ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
> + ALT_UP(mov lr, #0)
> + and lr, lr, #15
> + str r2, [r3, lr, lsl #2] @ save phys SP
> +#else
> str r2, [r3] @ save phys SP
> +#endif
<snip>
> sleep_save_sp:
> - .word 0 @ preserve stack phys ptr here
> + .rept CONFIG_NR_CPUS
> + .long 0 @ preserve stack phys ptr here
> + .endr
>
Yes Russell, thanks that's what we are currently doing for MP, it looks
ok. As for the page tables, I know you already replied and I took your
point. It is on the cpuidle path so page tables should be created in C,
beforehand as you pointed out (with the 1:1 map required), once for all.
I just wanted to say, maybe we can save the pgd pointer (with the
required 1:1 for MMU on) in a pc-relative addressable location that you
can retrieve on resume, eliminating the code changing the original page
table and replacing it with pgd switching.
But again it is just a suggestion, I understand your point, no need to
comment further.
Many thanks,
Lorenzo
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-07 14:17 ` Russell King - ARM Linux
2011-02-07 14:27 ` saeed bishara
2011-02-08 8:08 ` Colin Cross
@ 2011-02-10 3:15 ` Colin Cross
2011-02-11 11:58 ` Russell King - ARM Linux
2 siblings, 1 reply; 33+ messages in thread
From: Colin Cross @ 2011-02-10 3:15 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 7, 2011 at 6:17 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index 0c1172b..a5187dd 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> +ENTRY(cpu_v7_do_suspend)
> + ? ? ? stmfd ? sp!, {r4 - r11, lr}
> + ? ? ? mrc ? ? p15, 0, r4, c13, c0, 0 ?@ FCSE/PID
> + ? ? ? mrc ? ? p15, 0, r5, c13, c0, 1 ?@ Context ID
> + ? ? ? mrc ? ? p15, 0, r6, c3, c0, 0 ? @ Domain ID
> + ? ? ? mrc ? ? p15, 0, r7, c2, c0, 0 ? @ TTB 0
> + ? ? ? mrc ? ? p15, 0, r8, c2, c0, 1 ? @ TTB 1
> + ? ? ? mrc ? ? p15, 0, r9, c1, c0, 0 ? @ Control register
> + ? ? ? mrc ? ? p15, 0, r10, c1, c0, 1 ?@ Auxiliary control register
> + ? ? ? mrc ? ? p15, 0, r11, c1, c0, 2 ?@ Co-processor access control
The diagnostic register also needs to be saved to keep the errata bits
set in __v7_setup.
> + ? ? ? stmia ? r0, {r4 - r11}
> + ? ? ? ldmfd ? sp!, {r4 - r11, pc}
> +ENDPROC(cpu_v7_do_suspend)
> +
> +ENTRY(cpu_v7_do_resume)
> + ? ? ? mov ? ? ip, #0
> + ? ? ? mcr ? ? p15, 0, ip, c8, c7, 0 ? @ invalidate TLBs
> + ? ? ? mcr ? ? p15, 0, ip, c7, c5, 0 ? @ invalidate I cache
Does this need the same ALT_SMP/ALT_UP combo as v7_flush_icache_all?
<snip>
Tegra2 suspend and cpuidle works on top of this patch and the patch
that adds SMP support to sleep_save_sp. Tegra seems to need to
invalidate the entire l1 data cache before enabling it, so I'm using a
custom reset vector that branches to cpu_resume, and I'm handling the
TLB invalidate in the function cpu_resume returns to.
Tested-by: Colin Cross <ccross@android.com>
Are you targeting 2.6.39 with these patches? They replace a few
hundred lines of code in the Tegra2 suspend, hotplug, and idle
patches, so I'd like to wait until this is in before pushing mine.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-10 3:15 ` Colin Cross
@ 2011-02-11 11:58 ` Russell King - ARM Linux
2011-02-11 12:07 ` Santosh Shilimkar
2011-02-14 0:27 ` Kukjin Kim
0 siblings, 2 replies; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 11:58 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Feb 09, 2011 at 07:15:25PM -0800, Colin Cross wrote:
> The diagnostic register also needs to be saved to keep the errata bits
> set in __v7_setup.
Saving I've no problem with. Restoring gets hairy with kernels running
in non-secure mode, as we can't just write the register - we don't know
whether we are running in secure or non-secure mode. A write to the
register in NS mode will crash.
Santosh: is the diagnostic register on OMAP4 re-initialized by the secure
code on OMAP?
> > + ? ? ? stmia ? r0, {r4 - r11}
> > + ? ? ? ldmfd ? sp!, {r4 - r11, pc}
> > +ENDPROC(cpu_v7_do_suspend)
> > +
> > +ENTRY(cpu_v7_do_resume)
> > + ? ? ? mov ? ? ip, #0
> > + ? ? ? mcr ? ? p15, 0, ip, c8, c7, 0 ? @ invalidate TLBs
> > + ? ? ? mcr ? ? p15, 0, ip, c7, c5, 0 ? @ invalidate I cache
>
> Does this need the same ALT_SMP/ALT_UP combo as v7_flush_icache_all?
That depends whether you the CPU which is resuming is part of a coherent
SMP system at that point. This instruction will invalidate the I-cache
for the local CPU only, whereas the c7, c1 variant will invalidate the
instruction caches of all CPUs within the inner sharable domain.
Has anything changed in the other CPUs as a result of this CPU resuming
at this point? I don't think so, so I think we just need to ensure that
the local CPU instruction cache is invalidated at this point.
> Tegra2 suspend and cpuidle works on top of this patch and the patch
> that adds SMP support to sleep_save_sp. Tegra seems to need to
> invalidate the entire l1 data cache before enabling it,
As it's undefined what state the data cache is in on resume, I'm surprised
the s5pv210 code doesn't also need a D-cache invalidate too. Maybe Samsung
folk can answer that.
> so I'm using a
> custom reset vector that branches to cpu_resume, and I'm handling the
> TLB invalidate in the function cpu_resume returns to.
>
> Tested-by: Colin Cross <ccross@android.com>
>
> Are you targeting 2.6.39 with these patches? They replace a few
> hundred lines of code in the Tegra2 suspend, hotplug, and idle
> patches, so I'd like to wait until this is in before pushing mine.
Undecided at the moment. It's great that you've tested it, and I've
also tested it on Assabet, but PXA and Samsung stuff hasn't been
tested yet. I guess I could just push the generic and sa1100 bits for
2.6.39, unless the remainder gets tested.
Once the above issues have answers, I'll see about posting a new set of
patches.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-11 11:58 ` Russell King - ARM Linux
@ 2011-02-11 12:07 ` Santosh Shilimkar
2011-02-12 14:50 ` Russell King - ARM Linux
2011-02-14 0:27 ` Kukjin Kim
1 sibling, 1 reply; 33+ messages in thread
From: Santosh Shilimkar @ 2011-02-11 12:07 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-
> arm-kernel-bounces at lists.infradead.org] On Behalf Of Russell King -
> ARM Linux
> Sent: Friday, February 11, 2011 5:29 PM
> To: Colin Cross; Santosh Shilimkar; Kukjin Kim
> Cc: saeed bishara; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume
> support
>
> On Wed, Feb 09, 2011 at 07:15:25PM -0800, Colin Cross wrote:
> > The diagnostic register also needs to be saved to keep the errata
> bits
> > set in __v7_setup.
>
> Saving I've no problem with. Restoring gets hairy with kernels
> running
> in non-secure mode, as we can't just write the register - we don't
> know
> whether we are running in secure or non-secure mode. A write to the
> register in NS mode will crash.
>
> Santosh: is the diagnostic register on OMAP4 re-initialized by the
> secure code on OMAP?
>
There is a Monitor secure API, needs to be called from non-secure
software to set this diagnostic registers in resume path.
Regards,
Santosh
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-11 12:07 ` Santosh Shilimkar
@ 2011-02-12 14:50 ` Russell King - ARM Linux
2011-02-12 15:09 ` Santosh Shilimkar
0 siblings, 1 reply; 33+ messages in thread
From: Russell King - ARM Linux @ 2011-02-12 14:50 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Feb 11, 2011 at 05:37:04PM +0530, Santosh Shilimkar wrote:
> There is a Monitor secure API, needs to be called from non-secure
> software to set this diagnostic registers in resume path.
It would be an idea to get the OMAP sleep code up to date so that I can
look at OMAPs requirements for this to be useful.
As the current code stands, I don't see any reason why the sleep34xx code
can't use this infrastructure, but I'm loathed to start modifying that if
there's outstanding code changes in that area.
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-12 14:50 ` Russell King - ARM Linux
@ 2011-02-12 15:09 ` Santosh Shilimkar
2011-02-28 18:17 ` Santosh Shilimkar
2011-02-28 18:21 ` Jean Pihet
0 siblings, 2 replies; 33+ messages in thread
From: Santosh Shilimkar @ 2011-02-12 15:09 UTC (permalink / raw)
To: linux-arm-kernel
> -----Original Message-----
> From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> Sent: Saturday, February 12, 2011 8:20 PM
> To: Santosh Shilimkar
> Cc: Colin Cross; Kukjin Kim; saeed bishara; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume
> support
>
> On Fri, Feb 11, 2011 at 05:37:04PM +0530, Santosh Shilimkar wrote:
> > There is a Monitor secure API, needs to be called from non-secure
> > software to set this diagnostic registers in resume path.
>
> It would be an idea to get the OMAP sleep code up to date so that I
> can
> look at OMAPs requirements for this to be useful.
>
> As the current code stands, I don't see any reason why the sleep34xx
> code
> can't use this infrastructure, but I'm loathed to start modifying
> that if there's outstanding code changes in that area.
Yep. There are few issues out there with sleep34xx code.
- Secure APIs
- Current code needs to be cleaned up to remove
unwanted registers save restore
- Some part of the code on OMAP3 must be run from
SRAM. It can't run from DDR
- AUXCTLR, Diagnostic registers aren't accessible
in secure mode.
- L2 cache needs to be handled with secure APIs.
- Code sequence needs to handle errata's handling
which accesses OMAP PM registers.
Few of the above are getting addressed for this merge window.
So my plan was to take a look at generic suspend after the
merge window. By that time your generic stuff and omap
cleanup would have got merged hopefully.
Regards,
Santosh
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-11 11:58 ` Russell King - ARM Linux
2011-02-11 12:07 ` Santosh Shilimkar
@ 2011-02-14 0:27 ` Kukjin Kim
1 sibling, 0 replies; 33+ messages in thread
From: Kukjin Kim @ 2011-02-14 0:27 UTC (permalink / raw)
To: linux-arm-kernel
Russell King - ARM Linux wrote:
>
> On Wed, Feb 09, 2011 at 07:15:25PM -0800, Colin Cross wrote:
> > The diagnostic register also needs to be saved to keep the errata bits
> > set in __v7_setup.
>
> Saving I've no problem with. Restoring gets hairy with kernels running
> in non-secure mode, as we can't just write the register - we don't know
> whether we are running in secure or non-secure mode. A write to the
> register in NS mode will crash.
>
> Santosh: is the diagnostic register on OMAP4 re-initialized by the secure
> code on OMAP?
>
> > > + stmia r0, {r4 - r11}
> > > + ldmfd sp!, {r4 - r11, pc}
> > > +ENDPROC(cpu_v7_do_suspend)
> > > +
> > > +ENTRY(cpu_v7_do_resume)
> > > + mov ip, #0
> > > + mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
> > > + mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
> >
> > Does this need the same ALT_SMP/ALT_UP combo as v7_flush_icache_all?
>
> That depends whether you the CPU which is resuming is part of a coherent
> SMP system at that point. This instruction will invalidate the I-cache
> for the local CPU only, whereas the c7, c1 variant will invalidate the
> instruction caches of all CPUs within the inner sharable domain.
>
> Has anything changed in the other CPUs as a result of this CPU resuming
> at this point? I don't think so, so I think we just need to ensure that
> the local CPU instruction cache is invalidated at this point.
>
> > Tegra2 suspend and cpuidle works on top of this patch and the patch
> > that adds SMP support to sleep_save_sp. Tegra seems to need to
> > invalidate the entire l1 data cache before enabling it,
>
> As it's undefined what state the data cache is in on resume, I'm surprised
> the s5pv210 code doesn't also need a D-cache invalidate too. Maybe Samsung
> folk can answer that.
>
Now, it works fine with omission D-cache invalidate on S5PV210. Basically, Samsung S5P SoCs have some kind of hardware initialization code. So I'm not sure it has something for it, will/need to check it to hardware guys soon :) Then let you know about that ;)
As a note, I will test your updated generic CPU suspend/resume support on Samsung SoCs also, if any available branch which has p2v patches for it, please let me know. Anyway sorry for late testing on board.
Have a nice weekend.
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply [flat|nested] 33+ messages in thread
* RE: [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-12 15:09 ` Santosh Shilimkar
@ 2011-02-28 18:17 ` Santosh Shilimkar
2011-02-28 18:21 ` Jean Pihet
1 sibling, 0 replies; 33+ messages in thread
From: Santosh Shilimkar @ 2011-02-28 18:17 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Colin Cross, Kukjin Kim, saeed bishara, linux-arm-kernel, linux-omap
+ linux-omap on this thread.
> -----Original Message-----
> From: Santosh Shilimkar [mailto:santosh.shilimkar@ti.com]
> Sent: Saturday, February 12, 2011 8:40 PM
> To: Russell King - ARM Linux
> Cc: Colin Cross; Kukjin Kim; saeed bishara; linux-arm-
> kernel@lists.infradead.org
> Subject: RE: [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume
> support
>
> > -----Original Message-----
> > From: Russell King - ARM Linux [mailto:linux@arm.linux.org.uk]
> > Sent: Saturday, February 12, 2011 8:20 PM
> > To: Santosh Shilimkar
> > Cc: Colin Cross; Kukjin Kim; saeed bishara; linux-arm-
> > kernel@lists.infradead.org
> > Subject: Re: [PATCH v3 2/5] ARM: pm: add generic CPU
> suspend/resume
> > support
> >
> > On Fri, Feb 11, 2011 at 05:37:04PM +0530, Santosh Shilimkar wrote:
> > > There is a Monitor secure API, needs to be called from non-
> secure
> > > software to set this diagnostic registers in resume path.
> >
> > It would be an idea to get the OMAP sleep code up to date so that
> I
> > can
> > look at OMAPs requirements for this to be useful.
> >
> > As the current code stands, I don't see any reason why the
> sleep34xx
> > code
> > can't use this infrastructure, but I'm loathed to start modifying
> > that if there's outstanding code changes in that area.
>
> Yep. There are few issues out there with sleep34xx code.
> - Secure APIs
> - Current code needs to be cleaned up to remove
> unwanted registers save restore
> - Some part of the code on OMAP3 must be run from
> SRAM. It can't run from DDR
> - AUXCTLR, Diagnostic registers aren't accessible
> in secure mode.
> - L2 cache needs to be handled with secure APIs.
> - Code sequence needs to handle errata's handling
> which accesses OMAP PM registers.
>
> Few of the above are getting addressed for this merge window.
>
> So my plan was to take a look at generic suspend after the
> merge window. By that time your generic stuff and omap
> cleanup would have got merged hopefully.
>
> Regards,
> Santosh
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-28 18:17 ` Santosh Shilimkar
0 siblings, 0 replies; 33+ messages in thread
From: Santosh Shilimkar @ 2011-02-28 18:17 UTC (permalink / raw)
To: linux-arm-kernel
+ linux-omap on this thread.
> -----Original Message-----
> From: Santosh Shilimkar [mailto:santosh.shilimkar at ti.com]
> Sent: Saturday, February 12, 2011 8:40 PM
> To: Russell King - ARM Linux
> Cc: Colin Cross; Kukjin Kim; saeed bishara; linux-arm-
> kernel at lists.infradead.org
> Subject: RE: [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume
> support
>
> > -----Original Message-----
> > From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> > Sent: Saturday, February 12, 2011 8:20 PM
> > To: Santosh Shilimkar
> > Cc: Colin Cross; Kukjin Kim; saeed bishara; linux-arm-
> > kernel at lists.infradead.org
> > Subject: Re: [PATCH v3 2/5] ARM: pm: add generic CPU
> suspend/resume
> > support
> >
> > On Fri, Feb 11, 2011 at 05:37:04PM +0530, Santosh Shilimkar wrote:
> > > There is a Monitor secure API, needs to be called from non-
> secure
> > > software to set this diagnostic registers in resume path.
> >
> > It would be an idea to get the OMAP sleep code up to date so that
> I
> > can
> > look at OMAPs requirements for this to be useful.
> >
> > As the current code stands, I don't see any reason why the
> sleep34xx
> > code
> > can't use this infrastructure, but I'm loathed to start modifying
> > that if there's outstanding code changes in that area.
>
> Yep. There are few issues out there with sleep34xx code.
> - Secure APIs
> - Current code needs to be cleaned up to remove
> unwanted registers save restore
> - Some part of the code on OMAP3 must be run from
> SRAM. It can't run from DDR
> - AUXCTLR, Diagnostic registers aren't accessible
> in secure mode.
> - L2 cache needs to be handled with secure APIs.
> - Code sequence needs to handle errata's handling
> which accesses OMAP PM registers.
>
> Few of the above are getting addressed for this merge window.
>
> So my plan was to take a look at generic suspend after the
> merge window. By that time your generic stuff and omap
> cleanup would have got merged hopefully.
>
> Regards,
> Santosh
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume support
2011-02-12 15:09 ` Santosh Shilimkar
2011-02-28 18:17 ` Santosh Shilimkar
@ 2011-02-28 18:21 ` Jean Pihet
1 sibling, 0 replies; 33+ messages in thread
From: Jean Pihet @ 2011-02-28 18:21 UTC (permalink / raw)
To: linux-arm-kernel
On Sat, Feb 12, 2011 at 4:09 PM, Santosh Shilimkar
<santosh.shilimkar@ti.com> wrote:
>> -----Original Message-----
>> From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
>> Sent: Saturday, February 12, 2011 8:20 PM
>> To: Santosh Shilimkar
>> Cc: Colin Cross; Kukjin Kim; saeed bishara; linux-arm-
>> kernel at lists.infradead.org
>> Subject: Re: [PATCH v3 2/5] ARM: pm: add generic CPU suspend/resume
>> support
>>
>> On Fri, Feb 11, 2011 at 05:37:04PM +0530, Santosh Shilimkar wrote:
>> > There is a Monitor secure API, needs to be called from non-secure
>> > software to set this diagnostic registers in resume path.
>>
>> It would be an idea to get the OMAP sleep code up to date so that I
>> can
>> look at OMAPs requirements for this to be useful.
>>
>> As the current code stands, I don't see any reason why the sleep34xx
>> code
>> can't use this infrastructure, but I'm loathed to start modifying
>> that if there's outstanding code changes in that area.
>
> Yep. There are few issues out there with sleep34xx code.
> ? ? ? ?- Secure APIs
> ? ? ? ?- Current code needs to be cleaned up to remove
> ? ? ? ?unwanted registers save restore
> ? ? ? ?- Some part of the code on OMAP3 must be run from
> ? ? ? ?SRAM. It can't run from DDR
This is not the highest priority for now, I will have to come back
later on this.
> ? ? ? ?- AUXCTLR, Diagnostic registers aren't accessible
> ? ? ? ?in secure mode.
> ? ? ? ?- L2 cache needs to be handled with secure APIs.
> ? ? ? ?- Code sequence needs to handle errata's handling
> ? ? ? ?which accesses OMAP PM registers.
Also there is some on-going work to support Thumb-2, adding Dave.
>
> Few of the above are getting addressed for this merge window.
>
> So my plan was to take a look at generic suspend after the
> merge window. By that time your generic stuff and omap
> cleanup would have got merged hopefully.
Agree!
>
> Regards,
> Santosh
Regards,
Jean
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2011-02-28 18:21 UTC | newest]
Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-06 19:11 [RFC] Generic CPU save/restore PM support Russell King - ARM Linux
2011-02-06 19:12 ` [PATCH 1/5] ARM: move cache/processor/fault glue to separate include files Russell King - ARM Linux
2011-02-06 19:12 ` [PATCH 2/5] ARM: pm: add generic CPU suspend/resume support Russell King - ARM Linux
2011-02-07 12:01 ` [PATCH v2 " Russell King - ARM Linux
2011-02-07 12:10 ` [PATCH v3 " Russell King - ARM Linux
2011-02-07 13:21 ` saeed bishara
2011-02-07 13:34 ` Russell King - ARM Linux
2011-02-07 14:04 ` saeed bishara
2011-02-07 14:17 ` Russell King - ARM Linux
2011-02-07 14:27 ` saeed bishara
2011-02-07 14:33 ` Russell King - ARM Linux
2011-02-07 14:58 ` saeed bishara
2011-02-07 15:02 ` Russell King - ARM Linux
2011-02-08 10:21 ` Lorenzo Pieralisi
2011-02-08 11:23 ` Russell King - ARM Linux
2011-02-08 12:33 ` Russell King - ARM Linux
2011-02-08 14:25 ` Lorenzo Pieralisi
2011-02-08 8:08 ` Colin Cross
2011-02-10 3:15 ` Colin Cross
2011-02-11 11:58 ` Russell King - ARM Linux
2011-02-11 12:07 ` Santosh Shilimkar
2011-02-12 14:50 ` Russell King - ARM Linux
2011-02-12 15:09 ` Santosh Shilimkar
2011-02-28 18:17 ` Santosh Shilimkar
2011-02-28 18:17 ` Santosh Shilimkar
2011-02-28 18:21 ` Jean Pihet
2011-02-14 0:27 ` Kukjin Kim
2011-02-06 19:13 ` [PATCH 3/5] ARM: pm: convert PXA to generic " Russell King - ARM Linux
2011-02-06 19:13 ` [PATCH 4/5] ARM: pm: convert sa11x0 " Russell King - ARM Linux
2011-02-07 18:11 ` Russell King - ARM Linux
2011-02-06 19:13 ` [PATCH 5/5] ARM: pm: convert samsung platforms " Russell King - ARM Linux
2011-02-07 5:42 ` [RFC] Generic CPU save/restore PM support Kukjin Kim
2011-02-07 10:44 ` Russell King - ARM Linux
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.