All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Generic CPU save/restore PM support
@ 2011-02-11 16:16 ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:16 UTC (permalink / raw)
  To: Eric Miao, Kukjin Kim; +Cc: linux-arm-kernel, linux-omap

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.

Only only ARM920, ARM926, SA11x0, XScale, XScale3, V6 and V7 CPUs are
supported.

I've build-tested this for Assabet, PXA, and S3C2410, and boot tested
on Assabet.

Please send your acks/tested bys etc.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH] Generic CPU save/restore PM support
@ 2011-02-11 16:16 ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:16 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.

Only only ARM920, ARM926, SA11x0, XScale, XScale3, V6 and V7 CPUs are
supported.

I've build-tested this for Assabet, PXA, and S3C2410, and boot tested
on Assabet.

Please send your acks/tested bys etc.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 1/6] ARM: move cache/processor/fault glue to separate include files
  2011-02-11 16:16 ` Russell King - ARM Linux
@ 2011-02-11 16:17   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:17 UTC (permalink / raw)
  To: Eric Miao, Kukjin Kim; +Cc: linux-arm-kernel, linux-omap

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] 65+ messages in thread

* [PATCH 1/6] ARM: move cache/processor/fault glue to separate include files
@ 2011-02-11 16:17   ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:17 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] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-11 16:16 ` Russell King - ARM Linux
@ 2011-02-11 16:17   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:17 UTC (permalink / raw)
  To: Eric Miao, Kukjin Kim; +Cc: linux-arm-kernel, linux-omap

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, V6 and V7 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          |  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(-)
 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..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"
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-11 16:17   ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:17 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, V6 and V7 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          |  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(-)
 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..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"
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 3/6] ARM: pm: convert PXA to generic suspend/resume support
  2011-02-11 16:16 ` Russell King - ARM Linux
@ 2011-02-11 16:18   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:18 UTC (permalink / raw)
  To: Eric Miao, Kukjin Kim; +Cc: linux-arm-kernel, linux-omap

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           |  191 +++--------------------------------
 arch/arm/mach-pxa/zeus.c            |    2 +-
 8 files changed, 26 insertions(+), 194 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, PLAT_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, PLAT_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(PLAT_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..6f53688 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -22,133 +22,26 @@
 
 		.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)
  *
- * NOTE:  unfortunately, pxa_cpu_save_cp can not be reused here since
- * the auxiliary control register address is different between pxa3xx
- * and pxa{25x,27x}
+ * r0 = v:p offset
  */
-
 ENTRY(pxa3xx_cpu_suspend)
 
 #ifndef CONFIG_IWMMXT
 	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
@@ -158,28 +51,23 @@ pxa3xx_resume_after_mmu:
  * Forces CPU into sleep state.
  *
  * r0 = value for PWRMODE M field for desired sleep state
+ * r1 = v:p offset
  */
-
 ENTRY(pxa27x_cpu_suspend)
 
 #ifndef CONFIG_IWMMXT
 	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 +104,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 +200,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, PLAT_PHYS_OFFSET - PAGE_OFFSET);
 }
 #else
 #define zeus_power_off   NULL
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 3/6] ARM: pm: convert PXA to generic suspend/resume support
@ 2011-02-11 16:18   ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:18 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           |  191 +++--------------------------------
 arch/arm/mach-pxa/zeus.c            |    2 +-
 8 files changed, 26 insertions(+), 194 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, PLAT_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, PLAT_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(PLAT_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..6f53688 100644
--- a/arch/arm/mach-pxa/sleep.S
+++ b/arch/arm/mach-pxa/sleep.S
@@ -22,133 +22,26 @@
 
 		.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)
  *
- * NOTE:  unfortunately, pxa_cpu_save_cp can not be reused here since
- * the auxiliary control register address is different between pxa3xx
- * and pxa{25x,27x}
+ * r0 = v:p offset
  */
-
 ENTRY(pxa3xx_cpu_suspend)
 
 #ifndef CONFIG_IWMMXT
 	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
@@ -158,28 +51,23 @@ pxa3xx_resume_after_mmu:
  * Forces CPU into sleep state.
  *
  * r0 = value for PWRMODE M field for desired sleep state
+ * r1 = v:p offset
  */
-
 ENTRY(pxa27x_cpu_suspend)
 
 #ifndef CONFIG_IWMMXT
 	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 +104,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 +200,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, PLAT_PHYS_OFFSET - PAGE_OFFSET);
 }
 #else
 #define zeus_power_off   NULL
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 4/6] ARM: pm: convert sa11x0 to generic suspend/resume support
  2011-02-11 16:16 ` Russell King - ARM Linux
@ 2011-02-11 16:18   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:18 UTC (permalink / raw)
  To: Eric Miao, Kukjin Kim; +Cc: linux-arm-kernel, linux-omap

Convert sa11x0 to use the generic CPU suspend/resume support, rather
than implementing its own version.  Tested on Assabet.

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(PLAT_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] 65+ messages in thread

* [PATCH 4/6] ARM: pm: convert sa11x0 to generic suspend/resume support
@ 2011-02-11 16:18   ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:18 UTC (permalink / raw)
  To: linux-arm-kernel

Convert sa11x0 to use the generic CPU suspend/resume support, rather
than implementing its own version.  Tested on Assabet.

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(PLAT_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] 65+ messages in thread

* [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
  2011-02-11 16:16 ` Russell King - ARM Linux
@ 2011-02-11 16:18   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:18 UTC (permalink / raw)
  To: Eric Miao, Kukjin Kim; +Cc: linux-arm-kernel, linux-omap

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 at 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, PLAT_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] 65+ messages in thread

* [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
@ 2011-02-11 16:18   ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:18 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, PLAT_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] 65+ messages in thread

* [PATCH 6/6] ARM: pm: allow generic sleep code to be used with SMP CPU idle
  2011-02-11 16:16 ` Russell King - ARM Linux
@ 2011-02-11 16:19   ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:19 UTC (permalink / raw)
  To: Eric Miao, Kukjin Kim; +Cc: linux-arm-kernel, linux-omap

Allow the generic sleep code to be used with SMP CPU idle by storing
N CPU stack pointers rather than just one.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 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
-- 
1.6.2.5


^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 6/6] ARM: pm: allow generic sleep code to be used with SMP CPU idle
@ 2011-02-11 16:19   ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-11 16:19 UTC (permalink / raw)
  To: linux-arm-kernel

Allow the generic sleep code to be used with SMP CPU idle by storing
N CPU stack pointers rather than just one.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 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
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-11 16:17   ` Russell King - ARM Linux
@ 2011-02-12  2:50     ` Colin Cross
  -1 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-12  2:50 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Fri, Feb 11, 2011 at 8:17 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> 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, V6 and V7 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          |  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(-)
>  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..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"
> --
> 1.6.2.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

Acked-by: Colin Cross <ccross@android.com>

Tested with idle and suspend on Tegra 2.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-12  2:50     ` Colin Cross
  0 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-12  2:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 11, 2011 at 8:17 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> 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, V6 and V7 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 ? ? ? ? ?| ?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(-)
> ?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..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"
> --
> 1.6.2.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

Acked-by: Colin Cross <ccross@android.com>

Tested with idle and suspend on Tegra 2.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 1/6] ARM: move cache/processor/fault glue to separate include files
  2011-02-11 16:17   ` Russell King - ARM Linux
@ 2011-02-12  2:52     ` Colin Cross
  -1 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-12  2:52 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Fri, Feb 11, 2011 at 8:17 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> 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

Acked-by: Colin Cross <ccross@android.com>

Tested on Tegra 2.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 1/6] ARM: move cache/processor/fault glue to separate include files
@ 2011-02-12  2:52     ` Colin Cross
  0 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-12  2:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 11, 2011 at 8:17 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> 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

Acked-by: Colin Cross <ccross@android.com>

Tested on Tegra 2.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 6/6] ARM: pm: allow generic sleep code to be used with SMP CPU idle
  2011-02-11 16:19   ` Russell King - ARM Linux
@ 2011-02-12  2:52     ` Colin Cross
  -1 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-12  2:52 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Fri, Feb 11, 2011 at 8:19 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Allow the generic sleep code to be used with SMP CPU idle by storing
> N CPU stack pointers rather than just one.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  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
> --
> 1.6.2.5

Acked-by: Colin Cross <ccross@android.com>

Tested with idle and suspend on Tegra 2.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 6/6] ARM: pm: allow generic sleep code to be used with SMP CPU idle
@ 2011-02-12  2:52     ` Colin Cross
  0 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-12  2:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 11, 2011 at 8:19 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Allow the generic sleep code to be used with SMP CPU idle by storing
> N CPU stack pointers rather than just one.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
> ?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
> --
> 1.6.2.5

Acked-by: Colin Cross <ccross@android.com>

Tested with idle and suspend on Tegra 2.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 1/6] ARM: move cache/processor/fault glue to separate include files
  2011-02-12  2:52     ` Colin Cross
@ 2011-02-12  9:48       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-12  9:48 UTC (permalink / raw)
  To: Colin Cross; +Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Fri, Feb 11, 2011 at 06:52:14PM -0800, Colin Cross wrote:
> Acked-by: Colin Cross <ccross@android.com>
> 
> Tested on Tegra 2.

Thanks, I'll take these as Tested-by's.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 1/6] ARM: move cache/processor/fault glue to separate include files
@ 2011-02-12  9:48       ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-12  9:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 11, 2011 at 06:52:14PM -0800, Colin Cross wrote:
> Acked-by: Colin Cross <ccross@android.com>
> 
> Tested on Tegra 2.

Thanks, I'll take these as Tested-by's.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 6/6] ARM: pm: allow generic sleep code to be used with SMP CPU idle
  2011-02-11 16:19   ` Russell King - ARM Linux
@ 2011-02-13 21:59     ` Colin Cross
  -1 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-13 21:59 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Fri, Feb 11, 2011 at 8:19 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Allow the generic sleep code to be used with SMP CPU idle by storing
> N CPU stack pointers rather than just one.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  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

<snip>

> @@ -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

This doesn't compile on CONFIG_SMP=n, CONFIG_NR_CPUS is undefined.
Including linux/threads.h will provide a default definition.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 6/6] ARM: pm: allow generic sleep code to be used with SMP CPU idle
@ 2011-02-13 21:59     ` Colin Cross
  0 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-13 21:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 11, 2011 at 8:19 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> Allow the generic sleep code to be used with SMP CPU idle by storing
> N CPU stack pointers rather than just one.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
> ?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

<snip>

> @@ -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

This doesn't compile on CONFIG_SMP=n, CONFIG_NR_CPUS is undefined.
Including linux/threads.h will provide a default definition.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 6/6] ARM: pm: allow generic sleep code to be used with SMP CPU idle
  2011-02-13 21:59     ` Colin Cross
@ 2011-02-14 16:01       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-14 16:01 UTC (permalink / raw)
  To: Colin Cross; +Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Sun, Feb 13, 2011 at 01:59:54PM -0800, Colin Cross wrote:
> On Fri, Feb 11, 2011 at 8:19 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > Allow the generic sleep code to be used with SMP CPU idle by storing
> > N CPU stack pointers rather than just one.
> >
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > ---
> >  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
> 
> <snip>
> 
> > @@ -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
> 
> This doesn't compile on CONFIG_SMP=n, CONFIG_NR_CPUS is undefined.
> Including linux/threads.h will provide a default definition.

Added, thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 6/6] ARM: pm: allow generic sleep code to be used with SMP CPU idle
@ 2011-02-14 16:01       ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-14 16:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Feb 13, 2011 at 01:59:54PM -0800, Colin Cross wrote:
> On Fri, Feb 11, 2011 at 8:19 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > Allow the generic sleep code to be used with SMP CPU idle by storing
> > N CPU stack pointers rather than just one.
> >
> > Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> > ---
> > ?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
> 
> <snip>
> 
> > @@ -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
> 
> This doesn't compile on CONFIG_SMP=n, CONFIG_NR_CPUS is undefined.
> Including linux/threads.h will provide a default definition.

Added, thanks.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-11 16:17   ` Russell King - ARM Linux
@ 2011-02-15  1:21     ` Colin Cross
  -1 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-15  1:21 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Fri, Feb 11, 2011 at 8:17 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> 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, V6 and V7 CPUs.

I would like to use cpu_suspend in a case where the L2 is still
enabled.  When cpu_resume is called, the MMU and cache bits in SCTLR
are disabled, so the reads skip the L2 cache, and the data that was
saved (sleep_save_sp and *sleep_save_sp) is not read back.

Is it possible to call the outer_cache functions from cpu_suspend to
flush sleep_save_sp and the saved data?
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-15  1:21     ` Colin Cross
  0 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-15  1:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 11, 2011 at 8:17 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> 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, V6 and V7 CPUs.

I would like to use cpu_suspend in a case where the L2 is still
enabled.  When cpu_resume is called, the MMU and cache bits in SCTLR
are disabled, so the reads skip the L2 cache, and the data that was
saved (sleep_save_sp and *sleep_save_sp) is not read back.

Is it possible to call the outer_cache functions from cpu_suspend to
flush sleep_save_sp and the saved data?

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-15  1:21     ` Colin Cross
@ 2011-02-15  4:11       ` Colin Cross
  -1 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-15  4:11 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Mon, Feb 14, 2011 at 5:21 PM, Colin Cross <ccross@google.com> wrote:
> On Fri, Feb 11, 2011 at 8:17 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> 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, V6 and V7 CPUs.
>
> I would like to use cpu_suspend in a case where the L2 is still
> enabled.  When cpu_resume is called, the MMU and cache bits in SCTLR
> are disabled, so the reads skip the L2 cache, and the data that was
> saved (sleep_save_sp and *sleep_save_sp) is not read back.
>
> Is it possible to call the outer_cache functions from cpu_suspend to
> flush sleep_save_sp and the saved data?

Even with a cache flush, cpu_resume_turn_on_mmu fails because the page
table modification, done with the cache off, ends up in memory, but
the L2 contains the old value.  When the MMU and cache are enabled,
the 1:1 mapping disappears.  The page table would need to be
invalidated during suspend.

I can avoid the problem entirely by leaving the MMU on and skipping
cpu_resume when the CPU does not go through reset.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-15  4:11       ` Colin Cross
  0 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-15  4:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Feb 14, 2011 at 5:21 PM, Colin Cross <ccross@google.com> wrote:
> On Fri, Feb 11, 2011 at 8:17 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> 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, V6 and V7 CPUs.
>
> I would like to use cpu_suspend in a case where the L2 is still
> enabled. ?When cpu_resume is called, the MMU and cache bits in SCTLR
> are disabled, so the reads skip the L2 cache, and the data that was
> saved (sleep_save_sp and *sleep_save_sp) is not read back.
>
> Is it possible to call the outer_cache functions from cpu_suspend to
> flush sleep_save_sp and the saved data?

Even with a cache flush, cpu_resume_turn_on_mmu fails because the page
table modification, done with the cache off, ends up in memory, but
the L2 contains the old value.  When the MMU and cache are enabled,
the 1:1 mapping disappears.  The page table would need to be
invalidated during suspend.

I can avoid the problem entirely by leaving the MMU on and skipping
cpu_resume when the CPU does not go through reset.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-15  4:11       ` Colin Cross
@ 2011-02-15 10:50         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-15 10:50 UTC (permalink / raw)
  To: Colin Cross; +Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Mon, Feb 14, 2011 at 08:11:23PM -0800, Colin Cross wrote:
> Even with a cache flush, cpu_resume_turn_on_mmu fails because the page
> table modification, done with the cache off, ends up in memory, but
> the L2 contains the old value.  When the MMU and cache are enabled,
> the 1:1 mapping disappears.  The page table would need to be
> invalidated during suspend.
> 
> I can avoid the problem entirely by leaving the MMU on and skipping
> cpu_resume when the CPU does not go through reset.

If you're not losing CPU state, what's the point in calling the suspend
function?  It's purpose is to save CPU state ready for the CPU going to
sleep and losing power, and restoring that state when the CPU wakes up
sometime later.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-15 10:50         ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-15 10:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Feb 14, 2011 at 08:11:23PM -0800, Colin Cross wrote:
> Even with a cache flush, cpu_resume_turn_on_mmu fails because the page
> table modification, done with the cache off, ends up in memory, but
> the L2 contains the old value.  When the MMU and cache are enabled,
> the 1:1 mapping disappears.  The page table would need to be
> invalidated during suspend.
> 
> I can avoid the problem entirely by leaving the MMU on and skipping
> cpu_resume when the CPU does not go through reset.

If you're not losing CPU state, what's the point in calling the suspend
function?  It's purpose is to save CPU state ready for the CPU going to
sleep and losing power, and restoring that state when the CPU wakes up
sometime later.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-12  2:50     ` Colin Cross
@ 2011-02-15 11:04       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-15 11:04 UTC (permalink / raw)
  To: Colin Cross; +Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
> > +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

I think we can eliminate this cache flush by delaying the cache enable
as below.  Could you see whether Tegra 2 survives this please?
Thanks.

diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index bed1876..193be5f 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -4,6 +4,7 @@
 #include <asm/assembler.h>
 #include <asm/glue-cache.h>
 #include <asm/glue-proc.h>
+#include <asm/system.h>
 	.text
 
 /*
@@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
 	str	r3, [r2, r4, lsl #2]	@ setup 1:1 mapping for mmu code
 	sub	r2, r2, r1
 	ldr	r3, =cpu_resume_after_mmu
+	bic	r1, r0, #CR_C		@ ensure D-cache is disabled
 	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
+	mcr	p15, 0, r1, c1, c0, 0	@ turn on MMU, I-cache, etc
+	mrc	p15, 0, r1, c0, c0, 0	@ read id reg
+	mov	r1, r1
+	mov	r1, r1
 	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
+	mcr	p15, 0, r0, c1, c0, 0	@ turn on D-cache
+	mov	pc, lr
 
 /*
  * Note: Yes, part of the following code is located into the .data section.

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-15 11:04       ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-15 11:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
> > +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

I think we can eliminate this cache flush by delaying the cache enable
as below.  Could you see whether Tegra 2 survives this please?
Thanks.

diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index bed1876..193be5f 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -4,6 +4,7 @@
 #include <asm/assembler.h>
 #include <asm/glue-cache.h>
 #include <asm/glue-proc.h>
+#include <asm/system.h>
 	.text
 
 /*
@@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
 	str	r3, [r2, r4, lsl #2]	@ setup 1:1 mapping for mmu code
 	sub	r2, r2, r1
 	ldr	r3, =cpu_resume_after_mmu
+	bic	r1, r0, #CR_C		@ ensure D-cache is disabled
 	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
+	mcr	p15, 0, r1, c1, c0, 0	@ turn on MMU, I-cache, etc
+	mrc	p15, 0, r1, c0, c0, 0	@ read id reg
+	mov	r1, r1
+	mov	r1, r1
 	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
+	mcr	p15, 0, r0, c1, c0, 0	@ turn on D-cache
+	mov	pc, lr
 
 /*
  * Note: Yes, part of the following code is located into the .data section.

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-15 10:50         ` Russell King - ARM Linux
@ 2011-02-15 18:20           ` Colin Cross
  -1 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-15 18:20 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Eric Miao, Kukjin Kim, linux-omap, linux-arm-kernel

On Tue, Feb 15, 2011 at 2:50 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Mon, Feb 14, 2011 at 08:11:23PM -0800, Colin Cross wrote:
>> Even with a cache flush, cpu_resume_turn_on_mmu fails because the page
>> table modification, done with the cache off, ends up in memory, but
>> the L2 contains the old value.  When the MMU and cache are enabled,
>> the 1:1 mapping disappears.  The page table would need to be
>> invalidated during suspend.
>>
>> I can avoid the problem entirely by leaving the MMU on and skipping
>> cpu_resume when the CPU does not go through reset.
>
> If you're not losing CPU state, what's the point in calling the suspend
> function?  It's purpose is to save CPU state ready for the CPU going to
> sleep and losing power, and restoring that state when the CPU wakes up
> sometime later.

The CPU is going to a state where it may lose power (if the other CPU
enters the same state), or it may get an interrupt before the other
CPU powers down and wake back up again.  In the second case, it has
already called cpu_suspend, so it either needs to return without
calling cpu_resume (which I have working), or cpu_suspend/cpu_resume
needs to work with the L2 cache enabled.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-15 18:20           ` Colin Cross
  0 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-15 18:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 15, 2011 at 2:50 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Mon, Feb 14, 2011 at 08:11:23PM -0800, Colin Cross wrote:
>> Even with a cache flush, cpu_resume_turn_on_mmu fails because the page
>> table modification, done with the cache off, ends up in memory, but
>> the L2 contains the old value. ?When the MMU and cache are enabled,
>> the 1:1 mapping disappears. ?The page table would need to be
>> invalidated during suspend.
>>
>> I can avoid the problem entirely by leaving the MMU on and skipping
>> cpu_resume when the CPU does not go through reset.
>
> If you're not losing CPU state, what's the point in calling the suspend
> function? ?It's purpose is to save CPU state ready for the CPU going to
> sleep and losing power, and restoring that state when the CPU wakes up
> sometime later.

The CPU is going to a state where it may lose power (if the other CPU
enters the same state), or it may get an interrupt before the other
CPU powers down and wake back up again.  In the second case, it has
already called cpu_suspend, so it either needs to return without
calling cpu_resume (which I have working), or cpu_suspend/cpu_resume
needs to work with the L2 cache enabled.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-15 11:04       ` Russell King - ARM Linux
@ 2011-02-16  0:26         ` Colin Cross
  -1 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-16  0:26 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: linux-omap, Kukjin Kim, Eric Miao, linux-arm-kernel

On Tue, Feb 15, 2011 at 3:04 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
>> > +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
>
> I think we can eliminate this cache flush by delaying the cache enable
> as below.  Could you see whether Tegra 2 survives this please?
> Thanks.
>
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> index bed1876..193be5f 100644
> --- a/arch/arm/kernel/sleep.S
> +++ b/arch/arm/kernel/sleep.S
> @@ -4,6 +4,7 @@
>  #include <asm/assembler.h>
>  #include <asm/glue-cache.h>
>  #include <asm/glue-proc.h>
> +#include <asm/system.h>
>        .text
>
>  /*
> @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
>        str     r3, [r2, r4, lsl #2]    @ setup 1:1 mapping for mmu code
>        sub     r2, r2, r1
>        ldr     r3, =cpu_resume_after_mmu
> +       bic     r1, r0, #CR_C           @ ensure D-cache is disabled
>        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
> +       mcr     p15, 0, r1, c1, c0, 0   @ turn on MMU, I-cache, etc
> +       mrc     p15, 0, r1, c0, c0, 0   @ read id reg
> +       mov     r1, r1
> +       mov     r1, r1
>        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
> +       mcr     p15, 0, r0, c1, c0, 0   @ turn on D-cache
> +       mov     pc, lr
>
>  /*
>  * Note: Yes, part of the following code is located into the .data section.
>
>

Tested-by: Colin Cross <ccross@android.com>

Works for Tegra 2 cpuidle and suspend.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-16  0:26         ` Colin Cross
  0 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-16  0:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 15, 2011 at 3:04 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
>> > +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
>
> I think we can eliminate this cache flush by delaying the cache enable
> as below. ?Could you see whether Tegra 2 survives this please?
> Thanks.
>
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> index bed1876..193be5f 100644
> --- a/arch/arm/kernel/sleep.S
> +++ b/arch/arm/kernel/sleep.S
> @@ -4,6 +4,7 @@
> ?#include <asm/assembler.h>
> ?#include <asm/glue-cache.h>
> ?#include <asm/glue-proc.h>
> +#include <asm/system.h>
> ? ? ? ?.text
>
> ?/*
> @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
> ? ? ? ?str ? ? r3, [r2, r4, lsl #2] ? ?@ setup 1:1 mapping for mmu code
> ? ? ? ?sub ? ? r2, r2, r1
> ? ? ? ?ldr ? ? r3, =cpu_resume_after_mmu
> + ? ? ? bic ? ? r1, r0, #CR_C ? ? ? ? ? @ ensure D-cache is disabled
> ? ? ? ?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
> + ? ? ? mcr ? ? p15, 0, r1, c1, c0, 0 ? @ turn on MMU, I-cache, etc
> + ? ? ? mrc ? ? p15, 0, r1, c0, c0, 0 ? @ read id reg
> + ? ? ? mov ? ? r1, r1
> + ? ? ? mov ? ? r1, r1
> ? ? ? ?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
> + ? ? ? mcr ? ? p15, 0, r0, c1, c0, 0 ? @ turn on D-cache
> + ? ? ? mov ? ? pc, lr
>
> ?/*
> ?* Note: Yes, part of the following code is located into the .data section.
>
>

Tested-by: Colin Cross <ccross@android.com>

Works for Tegra 2 cpuidle and suspend.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-16  0:26         ` Colin Cross
@ 2011-02-17 10:41           ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 65+ messages in thread
From: Lorenzo Pieralisi @ 2011-02-17 10:41 UTC (permalink / raw)
  To: Colin Cross
  Cc: Russell King - ARM Linux, linux-omap, Kukjin Kim, Eric Miao,
	linux-arm-kernel

Colin,

On Tue, 2011-02-15 at 16:26 -0800, Colin Cross wrote:
> On Tue, Feb 15, 2011 at 3:04 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
> >> > +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
> >
> > I think we can eliminate this cache flush by delaying the cache enable
> > as below.  Could you see whether Tegra 2 survives this please?
> > Thanks.
> >
> > diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> > index bed1876..193be5f 100644
> > --- a/arch/arm/kernel/sleep.S
> > +++ b/arch/arm/kernel/sleep.S
> > @@ -4,6 +4,7 @@
> >  #include <asm/assembler.h>
> >  #include <asm/glue-cache.h>
> >  #include <asm/glue-proc.h>
> > +#include <asm/system.h>
> >        .text
> >
> >  /*
> > @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
> >        str     r3, [r2, r4, lsl #2]    @ setup 1:1 mapping for mmu code
> >        sub     r2, r2, r1
> >        ldr     r3, =cpu_resume_after_mmu
> > +       bic     r1, r0, #CR_C           @ ensure D-cache is disabled
> >        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
> > +       mcr     p15, 0, r1, c1, c0, 0   @ turn on MMU, I-cache, etc
> > +       mrc     p15, 0, r1, c0, c0, 0   @ read id reg
> > +       mov     r1, r1
> > +       mov     r1, r1
> >        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
> > +       mcr     p15, 0, r0, c1, c0, 0   @ turn on D-cache
> > +       mov     pc, lr
> >
> >  /*
> >  * Note: Yes, part of the following code is located into the .data section.
> >
> >
> 
> Tested-by: Colin Cross <ccross@android.com>
> 
> Works for Tegra 2 cpuidle and suspend.
> 

When calling suspend from cpuidle, do you flush the stack (ie CPU
context) from L2 using outer_cache functions ? This has to be done when
one CPU is shut down with L2 enabled for the MMU off resume path to work
properly.
I think that on resume you invalidate L1 in the reset vector before
jumping to cpu_resume, correct ?

Many thanks,
Lorenzo



^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-17 10:41           ` Lorenzo Pieralisi
  0 siblings, 0 replies; 65+ messages in thread
From: Lorenzo Pieralisi @ 2011-02-17 10:41 UTC (permalink / raw)
  To: linux-arm-kernel

Colin,

On Tue, 2011-02-15 at 16:26 -0800, Colin Cross wrote:
> On Tue, Feb 15, 2011 at 3:04 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
> >> > +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
> >
> > I think we can eliminate this cache flush by delaying the cache enable
> > as below.  Could you see whether Tegra 2 survives this please?
> > Thanks.
> >
> > diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> > index bed1876..193be5f 100644
> > --- a/arch/arm/kernel/sleep.S
> > +++ b/arch/arm/kernel/sleep.S
> > @@ -4,6 +4,7 @@
> >  #include <asm/assembler.h>
> >  #include <asm/glue-cache.h>
> >  #include <asm/glue-proc.h>
> > +#include <asm/system.h>
> >        .text
> >
> >  /*
> > @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
> >        str     r3, [r2, r4, lsl #2]    @ setup 1:1 mapping for mmu code
> >        sub     r2, r2, r1
> >        ldr     r3, =cpu_resume_after_mmu
> > +       bic     r1, r0, #CR_C           @ ensure D-cache is disabled
> >        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
> > +       mcr     p15, 0, r1, c1, c0, 0   @ turn on MMU, I-cache, etc
> > +       mrc     p15, 0, r1, c0, c0, 0   @ read id reg
> > +       mov     r1, r1
> > +       mov     r1, r1
> >        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
> > +       mcr     p15, 0, r0, c1, c0, 0   @ turn on D-cache
> > +       mov     pc, lr
> >
> >  /*
> >  * Note: Yes, part of the following code is located into the .data section.
> >
> >
> 
> Tested-by: Colin Cross <ccross@android.com>
> 
> Works for Tegra 2 cpuidle and suspend.
> 

When calling suspend from cpuidle, do you flush the stack (ie CPU
context) from L2 using outer_cache functions ? This has to be done when
one CPU is shut down with L2 enabled for the MMU off resume path to work
properly.
I think that on resume you invalidate L1 in the reset vector before
jumping to cpu_resume, correct ?

Many thanks,
Lorenzo

^ permalink raw reply	[flat|nested] 65+ messages in thread

* RE: [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
  2011-02-11 16:18   ` Russell King - ARM Linux
@ 2011-02-17 12:09     ` Kukjin Kim
  -1 siblings, 0 replies; 65+ messages in thread
From: Kukjin Kim @ 2011-02-17 12:09 UTC (permalink / raw)
  To: 'Russell King - ARM Linux', 'Eric Miao'
  Cc: linux-arm-kernel, linux-omap

Russell King - ARM Linux wrote:
> 
> 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 at 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, PLAT_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

Hi Russell,

I tested on SMDKV210(S5PV210) and SMDKC110(S5PC110).

Firstly, looks like suspend working is fine.
But had some problem during resume :( unfortunately, didn't find fundamental
reason of it.

Shortly, the problem is that r14 has always unexpected value, 0x4 on #113
line, "cpy pc, r14" of v7_flush_cache_all.
So happened abort. I will debugging tomorrow then let you know.

As a note, I tested it based on your devel-stable branch.
If missed some stuff, please let me know :)

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] 65+ messages in thread

* [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
@ 2011-02-17 12:09     ` Kukjin Kim
  0 siblings, 0 replies; 65+ messages in thread
From: Kukjin Kim @ 2011-02-17 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux wrote:
> 
> 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 at 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, PLAT_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

Hi Russell,

I tested on SMDKV210(S5PV210) and SMDKC110(S5PC110).

Firstly, looks like suspend working is fine.
But had some problem during resume :( unfortunately, didn't find fundamental
reason of it.

Shortly, the problem is that r14 has always unexpected value, 0x4 on #113
line, "cpy pc, r14" of v7_flush_cache_all.
So happened abort. I will debugging tomorrow then let you know.

As a note, I tested it based on your devel-stable branch.
If missed some stuff, please let me know :)

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] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-17 10:41           ` Lorenzo Pieralisi
@ 2011-02-17 13:59             ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-17 13:59 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Colin Cross, linux-omap, Kukjin Kim, Eric Miao, linux-arm-kernel

On Thu, Feb 17, 2011 at 10:41:52AM +0000, Lorenzo Pieralisi wrote:
> When calling suspend from cpuidle, do you flush the stack (ie CPU
> context) from L2 using outer_cache functions ? This has to be done when
> one CPU is shut down with L2 enabled for the MMU off resume path to work
> properly.
> I think that on resume you invalidate L1 in the reset vector before
> jumping to cpu_resume, correct ?

Let's forget cpuidle using this code for the time being - the issues
there appear to be more complex than the suspend-to-ram which this code
is currently being used for.  What I'm saying is that cpuidle using
this is an enhancement over and above its current use.

Once we have the S2R stuff working and tested, then we can go back to
cpuidle stuff.

I fear that trying to get this to work for cpuidle will result in the
entire thing being thrown away.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-17 13:59             ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-17 13:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 17, 2011 at 10:41:52AM +0000, Lorenzo Pieralisi wrote:
> When calling suspend from cpuidle, do you flush the stack (ie CPU
> context) from L2 using outer_cache functions ? This has to be done when
> one CPU is shut down with L2 enabled for the MMU off resume path to work
> properly.
> I think that on resume you invalidate L1 in the reset vector before
> jumping to cpu_resume, correct ?

Let's forget cpuidle using this code for the time being - the issues
there appear to be more complex than the suspend-to-ram which this code
is currently being used for.  What I'm saying is that cpuidle using
this is an enhancement over and above its current use.

Once we have the S2R stuff working and tested, then we can go back to
cpuidle stuff.

I fear that trying to get this to work for cpuidle will result in the
entire thing being thrown away.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
  2011-02-17 12:09     ` Kukjin Kim
@ 2011-02-17 14:06       ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-17 14:06 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: 'Eric Miao', linux-arm-kernel, linux-omap

On Thu, Feb 17, 2011 at 09:09:02PM +0900, Kukjin Kim wrote:
> Hi Russell,
> 
> I tested on SMDKV210(S5PV210) and SMDKC110(S5PC110).

Thanks for testing.  It looks like I'm missing a load for r3 in the
s5pv210 code.  The replacement patch below should resolve this.

 arch/arm/mach-s3c64xx/sleep.S           |   63 +-----------------
 arch/arm/mach-s5pv210/sleep.S           |  105 +-----------------------------
 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, 14 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..a3d6494 100644
--- a/arch/arm/mach-s5pv210/sleep.S
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -35,50 +35,24 @@
 	/* 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
+	ldr	r3, =resume_with_mmu
+	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 +70,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 at 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, PLAT_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 */

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
@ 2011-02-17 14:06       ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-17 14:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 17, 2011 at 09:09:02PM +0900, Kukjin Kim wrote:
> Hi Russell,
> 
> I tested on SMDKV210(S5PV210) and SMDKC110(S5PC110).

Thanks for testing.  It looks like I'm missing a load for r3 in the
s5pv210 code.  The replacement patch below should resolve this.

 arch/arm/mach-s3c64xx/sleep.S           |   63 +-----------------
 arch/arm/mach-s5pv210/sleep.S           |  105 +-----------------------------
 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, 14 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..a3d6494 100644
--- a/arch/arm/mach-s5pv210/sleep.S
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -35,50 +35,24 @@
 	/* 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
+	ldr	r3, =resume_with_mmu
+	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 +70,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, PLAT_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 */

^ permalink raw reply related	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-17 10:41           ` Lorenzo Pieralisi
@ 2011-02-17 20:05             ` Colin Cross
  -1 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-17 20:05 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: Russell King - ARM Linux, linux-omap, Kukjin Kim, Eric Miao,
	linux-arm-kernel

On Thu, Feb 17, 2011 at 2:41 AM, Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
> Colin,
>
> On Tue, 2011-02-15 at 16:26 -0800, Colin Cross wrote:
>> On Tue, Feb 15, 2011 at 3:04 AM, Russell King - ARM Linux
>> <linux@arm.linux.org.uk> wrote:
>> > On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
>> >> > +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
>> >
>> > I think we can eliminate this cache flush by delaying the cache enable
>> > as below.  Could you see whether Tegra 2 survives this please?
>> > Thanks.
>> >
>> > diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
>> > index bed1876..193be5f 100644
>> > --- a/arch/arm/kernel/sleep.S
>> > +++ b/arch/arm/kernel/sleep.S
>> > @@ -4,6 +4,7 @@
>> >  #include <asm/assembler.h>
>> >  #include <asm/glue-cache.h>
>> >  #include <asm/glue-proc.h>
>> > +#include <asm/system.h>
>> >        .text
>> >
>> >  /*
>> > @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
>> >        str     r3, [r2, r4, lsl #2]    @ setup 1:1 mapping for mmu code
>> >        sub     r2, r2, r1
>> >        ldr     r3, =cpu_resume_after_mmu
>> > +       bic     r1, r0, #CR_C           @ ensure D-cache is disabled
>> >        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
>> > +       mcr     p15, 0, r1, c1, c0, 0   @ turn on MMU, I-cache, etc
>> > +       mrc     p15, 0, r1, c0, c0, 0   @ read id reg
>> > +       mov     r1, r1
>> > +       mov     r1, r1
>> >        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
>> > +       mcr     p15, 0, r0, c1, c0, 0   @ turn on D-cache
>> > +       mov     pc, lr
>> >
>> >  /*
>> >  * Note: Yes, part of the following code is located into the .data section.
>> >
>> >
>>
>> Tested-by: Colin Cross <ccross@android.com>
>>
>> Works for Tegra 2 cpuidle and suspend.
>>
>
> When calling suspend from cpuidle, do you flush the stack (ie CPU
> context) from L2 using outer_cache functions ? This has to be done when
> one CPU is shut down with L2 enabled for the MMU off resume path to work
> properly.
Tegra2 has the power rails of the two cpus tied together, so the cpu
that suspends first only needs to go through cpu_resume if the other
cpu has also suspended and flushed the entire L2 cache.  On platforms
that can power gate the cpus individually you will need to flush the
stack and stack pointer in cpu_suspend.  I have a patch that does the
flushes in cpu_suspend, but it failed on the way back up because the
page table modifications got lost behind the L2, and I haven't retried
it since Russell fixed that.

> I think that on resume you invalidate L1 in the reset vector before
> jumping to cpu_resume, correct ?
I manually invalidate the L1 Dcache, but not the Icache.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-17 20:05             ` Colin Cross
  0 siblings, 0 replies; 65+ messages in thread
From: Colin Cross @ 2011-02-17 20:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 17, 2011 at 2:41 AM, Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
> Colin,
>
> On Tue, 2011-02-15 at 16:26 -0800, Colin Cross wrote:
>> On Tue, Feb 15, 2011 at 3:04 AM, Russell King - ARM Linux
>> <linux@arm.linux.org.uk> wrote:
>> > On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
>> >> > +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
>> >
>> > I think we can eliminate this cache flush by delaying the cache enable
>> > as below. ?Could you see whether Tegra 2 survives this please?
>> > Thanks.
>> >
>> > diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
>> > index bed1876..193be5f 100644
>> > --- a/arch/arm/kernel/sleep.S
>> > +++ b/arch/arm/kernel/sleep.S
>> > @@ -4,6 +4,7 @@
>> > ?#include <asm/assembler.h>
>> > ?#include <asm/glue-cache.h>
>> > ?#include <asm/glue-proc.h>
>> > +#include <asm/system.h>
>> > ? ? ? ?.text
>> >
>> > ?/*
>> > @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
>> > ? ? ? ?str ? ? r3, [r2, r4, lsl #2] ? ?@ setup 1:1 mapping for mmu code
>> > ? ? ? ?sub ? ? r2, r2, r1
>> > ? ? ? ?ldr ? ? r3, =cpu_resume_after_mmu
>> > + ? ? ? bic ? ? r1, r0, #CR_C ? ? ? ? ? @ ensure D-cache is disabled
>> > ? ? ? ?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
>> > + ? ? ? mcr ? ? p15, 0, r1, c1, c0, 0 ? @ turn on MMU, I-cache, etc
>> > + ? ? ? mrc ? ? p15, 0, r1, c0, c0, 0 ? @ read id reg
>> > + ? ? ? mov ? ? r1, r1
>> > + ? ? ? mov ? ? r1, r1
>> > ? ? ? ?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
>> > + ? ? ? mcr ? ? p15, 0, r0, c1, c0, 0 ? @ turn on D-cache
>> > + ? ? ? mov ? ? pc, lr
>> >
>> > ?/*
>> > ?* Note: Yes, part of the following code is located into the .data section.
>> >
>> >
>>
>> Tested-by: Colin Cross <ccross@android.com>
>>
>> Works for Tegra 2 cpuidle and suspend.
>>
>
> When calling suspend from cpuidle, do you flush the stack (ie CPU
> context) from L2 using outer_cache functions ? This has to be done when
> one CPU is shut down with L2 enabled for the MMU off resume path to work
> properly.
Tegra2 has the power rails of the two cpus tied together, so the cpu
that suspends first only needs to go through cpu_resume if the other
cpu has also suspended and flushed the entire L2 cache.  On platforms
that can power gate the cpus individually you will need to flush the
stack and stack pointer in cpu_suspend.  I have a patch that does the
flushes in cpu_suspend, but it failed on the way back up because the
page table modifications got lost behind the L2, and I haven't retried
it since Russell fixed that.

> I think that on resume you invalidate L1 in the reset vector before
> jumping to cpu_resume, correct ?
I manually invalidate the L1 Dcache, but not the Icache.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* RE: [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
  2011-02-17 14:06       ` Russell King - ARM Linux
@ 2011-02-17 23:05         ` Kukjin Kim
  -1 siblings, 0 replies; 65+ messages in thread
From: Kukjin Kim @ 2011-02-17 23:05 UTC (permalink / raw)
  To: 'Russell King - ARM Linux'
  Cc: 'Eric Miao', linux-arm-kernel, linux-omap

Russell King - ARM Linux wrote:
> 
> On Thu, Feb 17, 2011 at 09:09:02PM +0900, Kukjin Kim wrote:
> > Hi Russell,
> >
> > I tested on SMDKV210(S5PV210) and SMDKC110(S5PC110).
> 
> Thanks for testing.  It looks like I'm missing a load for r3 in the
> s5pv210 code.  The replacement patch below should resolve this.
> 

Hooray, it works fine ;)

Tested-by: Kukjin Kim <kgene.kim@samsung.com>

Good night.
Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.


>  arch/arm/mach-s3c64xx/sleep.S           |   63 +-----------------
>  arch/arm/mach-s5pv210/sleep.S           |  105
+----------------------------
> -
>  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, 14 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..a3d6494 100644
> --- a/arch/arm/mach-s5pv210/sleep.S
> +++ b/arch/arm/mach-s5pv210/sleep.S
> @@ -35,50 +35,24 @@
>  	/* 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
> +	ldr	r3, =resume_with_mmu
> +	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 +70,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 at 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, PLAT_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 */


^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
@ 2011-02-17 23:05         ` Kukjin Kim
  0 siblings, 0 replies; 65+ messages in thread
From: Kukjin Kim @ 2011-02-17 23:05 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux wrote:
> 
> On Thu, Feb 17, 2011 at 09:09:02PM +0900, Kukjin Kim wrote:
> > Hi Russell,
> >
> > I tested on SMDKV210(S5PV210) and SMDKC110(S5PC110).
> 
> Thanks for testing.  It looks like I'm missing a load for r3 in the
> s5pv210 code.  The replacement patch below should resolve this.
> 

Hooray, it works fine ;)

Tested-by: Kukjin Kim <kgene.kim@samsung.com>

Good night.
Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.


>  arch/arm/mach-s3c64xx/sleep.S           |   63 +-----------------
>  arch/arm/mach-s5pv210/sleep.S           |  105
+----------------------------
> -
>  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, 14 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..a3d6494 100644
> --- a/arch/arm/mach-s5pv210/sleep.S
> +++ b/arch/arm/mach-s5pv210/sleep.S
> @@ -35,50 +35,24 @@
>  	/* 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
> +	ldr	r3, =resume_with_mmu
> +	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 +70,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 at 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, PLAT_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 */

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
  2011-02-17 23:05         ` Kukjin Kim
@ 2011-02-17 23:29           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-17 23:29 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: 'Eric Miao', linux-arm-kernel, linux-omap

On Fri, Feb 18, 2011 at 08:05:57AM +0900, Kukjin Kim wrote:
> Russell King - ARM Linux wrote:
> > 
> > On Thu, Feb 17, 2011 at 09:09:02PM +0900, Kukjin Kim wrote:
> > > Hi Russell,
> > >
> > > I tested on SMDKV210(S5PV210) and SMDKC110(S5PC110).
> > 
> > Thanks for testing.  It looks like I'm missing a load for r3 in the
> > s5pv210 code.  The replacement patch below should resolve this.
> > 
> 
> Hooray, it works fine ;)
> 
> Tested-by: Kukjin Kim <kgene.kim@samsung.com>

Thanks.  I'm assuming that applies to:

"ARM: pm: add generic CPU suspend/resume support"

too as you can't test this without that patch.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
@ 2011-02-17 23:29           ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-17 23:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Feb 18, 2011 at 08:05:57AM +0900, Kukjin Kim wrote:
> Russell King - ARM Linux wrote:
> > 
> > On Thu, Feb 17, 2011 at 09:09:02PM +0900, Kukjin Kim wrote:
> > > Hi Russell,
> > >
> > > I tested on SMDKV210(S5PV210) and SMDKC110(S5PC110).
> > 
> > Thanks for testing.  It looks like I'm missing a load for r3 in the
> > s5pv210 code.  The replacement patch below should resolve this.
> > 
> 
> Hooray, it works fine ;)
> 
> Tested-by: Kukjin Kim <kgene.kim@samsung.com>

Thanks.  I'm assuming that applies to:

"ARM: pm: add generic CPU suspend/resume support"

too as you can't test this without that patch.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-17 20:05             ` Colin Cross
@ 2011-02-17 23:36               ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-17 23:36 UTC (permalink / raw)
  To: Colin Cross
  Cc: Lorenzo Pieralisi, linux-omap, Kukjin Kim, Eric Miao, linux-arm-kernel

On Thu, Feb 17, 2011 at 12:05:59PM -0800, Colin Cross wrote:
> On Thu, Feb 17, 2011 at 2:41 AM, Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> wrote:
> > I think that on resume you invalidate L1 in the reset vector before
> > jumping to cpu_resume, correct ?
>
> I manually invalidate the L1 Dcache, but not the Icache.

Well...
ARMv5 and older invalidates the L1 Dcache.
ARMv6 cleans and invalidates the L1 Dcache.
ARMv7 does nothing with the L1 Dcache.

That's rather inconsistent, but that's what people are doing with their
current suspend/resume paths.  We really ought to have this well-defined.

I don't see any reason why there should be any dirty data in the Dcache,
so I think the safe thing we should be doing in every case is a L1 Dcache
invalidate on resume.

That's a separate change though.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-17 23:36               ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-17 23:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Feb 17, 2011 at 12:05:59PM -0800, Colin Cross wrote:
> On Thu, Feb 17, 2011 at 2:41 AM, Lorenzo Pieralisi
> <lorenzo.pieralisi@arm.com> wrote:
> > I think that on resume you invalidate L1 in the reset vector before
> > jumping to cpu_resume, correct ?
>
> I manually invalidate the L1 Dcache, but not the Icache.

Well...
ARMv5 and older invalidates the L1 Dcache.
ARMv6 cleans and invalidates the L1 Dcache.
ARMv7 does nothing with the L1 Dcache.

That's rather inconsistent, but that's what people are doing with their
current suspend/resume paths.  We really ought to have this well-defined.

I don't see any reason why there should be any dirty data in the Dcache,
so I think the safe thing we should be doing in every case is a L1 Dcache
invalidate on resume.

That's a separate change though.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* RE: [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
  2011-02-17 23:29           ` Russell King - ARM Linux
@ 2011-02-17 23:46             ` Kukjin Kim
  -1 siblings, 0 replies; 65+ messages in thread
From: Kukjin Kim @ 2011-02-17 23:46 UTC (permalink / raw)
  To: 'Russell King - ARM Linux'
  Cc: 'Eric Miao', linux-arm-kernel, linux-omap

Russell King - ARM Linux wrote:
> 
> On Fri, Feb 18, 2011 at 08:05:57AM +0900, Kukjin Kim wrote:
> > Russell King - ARM Linux wrote:
> > >
> > > On Thu, Feb 17, 2011 at 09:09:02PM +0900, Kukjin Kim wrote:
> > > > Hi Russell,
> > > >
> > > > I tested on SMDKV210(S5PV210) and SMDKC110(S5PC110).
> > >
> > > Thanks for testing.  It looks like I'm missing a load for r3 in the
> > > s5pv210 code.  The replacement patch below should resolve this.
> > >
> >
> > Hooray, it works fine ;)
> >
> > Tested-by: Kukjin Kim <kgene.kim@samsung.com>
> 
> Thanks.  I'm assuming that applies to:
> 
> "ARM: pm: add generic CPU suspend/resume support"
> 
> too as you can't test this without that patch.

Yeah, it's ok to me :)

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] 65+ messages in thread

* [PATCH 5/6] ARM: pm: convert samsung platforms to generic suspend/resume support
@ 2011-02-17 23:46             ` Kukjin Kim
  0 siblings, 0 replies; 65+ messages in thread
From: Kukjin Kim @ 2011-02-17 23:46 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux wrote:
> 
> On Fri, Feb 18, 2011 at 08:05:57AM +0900, Kukjin Kim wrote:
> > Russell King - ARM Linux wrote:
> > >
> > > On Thu, Feb 17, 2011 at 09:09:02PM +0900, Kukjin Kim wrote:
> > > > Hi Russell,
> > > >
> > > > I tested on SMDKV210(S5PV210) and SMDKC110(S5PC110).
> > >
> > > Thanks for testing.  It looks like I'm missing a load for r3 in the
> > > s5pv210 code.  The replacement patch below should resolve this.
> > >
> >
> > Hooray, it works fine ;)
> >
> > Tested-by: Kukjin Kim <kgene.kim@samsung.com>
> 
> Thanks.  I'm assuming that applies to:
> 
> "ARM: pm: add generic CPU suspend/resume support"
> 
> too as you can't test this without that patch.

Yeah, it's ok to me :)

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] 65+ messages in thread

* SAMSUNG: any example code for soc_camera, tv output, etc...?
  2011-02-17 23:05         ` Kukjin Kim
  (?)
  (?)
@ 2011-02-17 23:58         ` Nick Pelling
  2011-02-22 14:00           ` 余谨智
  -1 siblings, 1 reply; 65+ messages in thread
From: Nick Pelling @ 2011-02-17 23:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi everyone,

I've just gone through a lot of Samsung platform setup files in 
arch/arm/ , but haven't yet found any Samsung-SoC-based boards 
pre-plumbed into V4L2, nor any that connect up to a TV out (rather 
than to an LCD screen). Is there a repository out there containing 
Samsung Linux source code for these kinds of useful things, or even 
brief documentation on how to do this kind of basic video plumbing?

Even though I'm working on the S5PC100, information about hooking 
sensors into other Samsung SoC platforms would probably be 
sufficient. Alternatively, please say if you know which specific 
file(s) I should be asking Samsung tech support for under NDA (via my 
distributor's tech support).

Thanks, ....Nick Pelling.... // Nanodome Ltd

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-15 11:04       ` Russell King - ARM Linux
@ 2011-02-20 12:00         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-20 12:00 UTC (permalink / raw)
  To: Colin Cross; +Cc: linux-omap, Kukjin Kim, Eric Miao, linux-arm-kernel

Kukjin, could you test this update as well please?

Thanks.

On Tue, Feb 15, 2011 at 11:04:53AM +0000, Russell King - ARM Linux wrote:
> On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
> > > +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
> 
> I think we can eliminate this cache flush by delaying the cache enable
> as below.  Could you see whether Tegra 2 survives this please?
> Thanks.
> 
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> index bed1876..193be5f 100644
> --- a/arch/arm/kernel/sleep.S
> +++ b/arch/arm/kernel/sleep.S
> @@ -4,6 +4,7 @@
>  #include <asm/assembler.h>
>  #include <asm/glue-cache.h>
>  #include <asm/glue-proc.h>
> +#include <asm/system.h>
>  	.text
>  
>  /*
> @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
>  	str	r3, [r2, r4, lsl #2]	@ setup 1:1 mapping for mmu code
>  	sub	r2, r2, r1
>  	ldr	r3, =cpu_resume_after_mmu
> +	bic	r1, r0, #CR_C		@ ensure D-cache is disabled
>  	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
> +	mcr	p15, 0, r1, c1, c0, 0	@ turn on MMU, I-cache, etc
> +	mrc	p15, 0, r1, c0, c0, 0	@ read id reg
> +	mov	r1, r1
> +	mov	r1, r1
>  	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
> +	mcr	p15, 0, r0, c1, c0, 0	@ turn on D-cache
> +	mov	pc, lr
>  
>  /*
>   * Note: Yes, part of the following code is located into the .data section.
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-20 12:00         ` Russell King - ARM Linux
  0 siblings, 0 replies; 65+ messages in thread
From: Russell King - ARM Linux @ 2011-02-20 12:00 UTC (permalink / raw)
  To: linux-arm-kernel

Kukjin, could you test this update as well please?

Thanks.

On Tue, Feb 15, 2011 at 11:04:53AM +0000, Russell King - ARM Linux wrote:
> On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
> > > +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
> 
> I think we can eliminate this cache flush by delaying the cache enable
> as below.  Could you see whether Tegra 2 survives this please?
> Thanks.
> 
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> index bed1876..193be5f 100644
> --- a/arch/arm/kernel/sleep.S
> +++ b/arch/arm/kernel/sleep.S
> @@ -4,6 +4,7 @@
>  #include <asm/assembler.h>
>  #include <asm/glue-cache.h>
>  #include <asm/glue-proc.h>
> +#include <asm/system.h>
>  	.text
>  
>  /*
> @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
>  	str	r3, [r2, r4, lsl #2]	@ setup 1:1 mapping for mmu code
>  	sub	r2, r2, r1
>  	ldr	r3, =cpu_resume_after_mmu
> +	bic	r1, r0, #CR_C		@ ensure D-cache is disabled
>  	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
> +	mcr	p15, 0, r1, c1, c0, 0	@ turn on MMU, I-cache, etc
> +	mrc	p15, 0, r1, c0, c0, 0	@ read id reg
> +	mov	r1, r1
> +	mov	r1, r1
>  	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
> +	mcr	p15, 0, r0, c1, c0, 0	@ turn on D-cache
> +	mov	pc, lr
>  
>  /*
>   * Note: Yes, part of the following code is located into the .data section.
> 
> 
> _______________________________________________
> 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] 65+ messages in thread

* RE: [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
  2011-02-20 12:00         ` Russell King - ARM Linux
@ 2011-02-21  9:58           ` Kukjin Kim
  -1 siblings, 0 replies; 65+ messages in thread
From: Kukjin Kim @ 2011-02-21  9:58 UTC (permalink / raw)
  To: 'Russell King - ARM Linux', 'Colin Cross'
  Cc: linux-omap, 'Eric Miao', linux-arm-kernel

Russell King - ARM Linux wrote:
> 
> Kukjin, could you test this update as well please?
> 
No problem :)

It works fine with following.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

> Thanks.
> 
> On Tue, Feb 15, 2011 at 11:04:53AM +0000, Russell King - ARM Linux wrote:
> > On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
> > > > +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
> >
> > I think we can eliminate this cache flush by delaying the cache enable
> > as below.  Could you see whether Tegra 2 survives this please?
> > Thanks.
> >
> > diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> > index bed1876..193be5f 100644
> > --- a/arch/arm/kernel/sleep.S
> > +++ b/arch/arm/kernel/sleep.S
> > @@ -4,6 +4,7 @@
> >  #include <asm/assembler.h>
> >  #include <asm/glue-cache.h>
> >  #include <asm/glue-proc.h>
> > +#include <asm/system.h>
> >  	.text
> >
> >  /*
> > @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
> >  	str	r3, [r2, r4, lsl #2]	@ setup 1:1 mapping for mmu code
> >  	sub	r2, r2, r1
> >  	ldr	r3, =cpu_resume_after_mmu
> > +	bic	r1, r0, #CR_C		@ ensure D-cache is disabled
> >  	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
> > +	mcr	p15, 0, r1, c1, c0, 0	@ turn on MMU, I-cache, etc
> > +	mrc	p15, 0, r1, c0, c0, 0	@ read id reg
> > +	mov	r1, r1
> > +	mov	r1, r1
> >  	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
> > +	mcr	p15, 0, r0, c1, c0, 0	@ turn on D-cache
> > +	mov	pc, lr
> >
> >  /*
> >   * Note: Yes, part of the following code is located into the .data
section.

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support
@ 2011-02-21  9:58           ` Kukjin Kim
  0 siblings, 0 replies; 65+ messages in thread
From: Kukjin Kim @ 2011-02-21  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

Russell King - ARM Linux wrote:
> 
> Kukjin, could you test this update as well please?
> 
No problem :)

It works fine with following.

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

> Thanks.
> 
> On Tue, Feb 15, 2011 at 11:04:53AM +0000, Russell King - ARM Linux wrote:
> > On Fri, Feb 11, 2011 at 06:50:57PM -0800, Colin Cross wrote:
> > > > +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
> >
> > I think we can eliminate this cache flush by delaying the cache enable
> > as below.  Could you see whether Tegra 2 survives this please?
> > Thanks.
> >
> > diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> > index bed1876..193be5f 100644
> > --- a/arch/arm/kernel/sleep.S
> > +++ b/arch/arm/kernel/sleep.S
> > @@ -4,6 +4,7 @@
> >  #include <asm/assembler.h>
> >  #include <asm/glue-cache.h>
> >  #include <asm/glue-proc.h>
> > +#include <asm/system.h>
> >  	.text
> >
> >  /*
> > @@ -81,25 +82,22 @@ ENTRY(cpu_resume_mmu)
> >  	str	r3, [r2, r4, lsl #2]	@ setup 1:1 mapping for mmu code
> >  	sub	r2, r2, r1
> >  	ldr	r3, =cpu_resume_after_mmu
> > +	bic	r1, r0, #CR_C		@ ensure D-cache is disabled
> >  	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
> > +	mcr	p15, 0, r1, c1, c0, 0	@ turn on MMU, I-cache, etc
> > +	mrc	p15, 0, r1, c0, c0, 0	@ read id reg
> > +	mov	r1, r1
> > +	mov	r1, r1
> >  	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
> > +	mcr	p15, 0, r0, c1, c0, 0	@ turn on D-cache
> > +	mov	pc, lr
> >
> >  /*
> >   * Note: Yes, part of the following code is located into the .data
section.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* SAMSUNG: any example code for soc_camera, tv output, etc...?
  2011-02-17 23:58         ` SAMSUNG: any example code for soc_camera, tv output, etc...? Nick Pelling
@ 2011-02-22 14:00           ` 余谨智
       [not found]             ` <AANLkTin0PR3VQLruade+w6GbCMoW9pXy4Kvn-sBZ+LBM@mail.gmail.c om>
  0 siblings, 1 reply; 65+ messages in thread
From: 余谨智 @ 2011-02-22 14:00 UTC (permalink / raw)
  To: linux-arm-kernel

> I've just gone through a lot of Samsung platform setup files in arch/arm/ , but >haven't yet found any Samsung-SoC-based boards pre-plumbed into V4L2, nor >any that connect up to a TV out (rather than to an LCD screen).

I have port a embeded linux system on my board based on EP9315, with
support for usb video capture device, V4L2. Do you need V4L2 based on
usb video capture device or other video/FM/AM controller on your
board? If conveniently, can you provide more details about your
project?

>Alternatively, please say if you know which specific file(s) I should be asking >Samsung tech support for under NDA (via my distributor's tech support).

You MUST need the datasheet of S5PC100 on your board, and other
peripheral device's datasheet, like dm9000 ethernet controller if not
integrated in SoC, and schematic diagrams of your board.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* SAMSUNG: any example code for soc_camera, tv output, etc...?
       [not found]             ` <AANLkTin0PR3VQLruade+w6GbCMoW9pXy4Kvn-sBZ+LBM@mail.gmail.c om>
@ 2011-02-22 22:54               ` Nick Pelling
  2011-02-23 11:03                   ` Sylwester Nawrocki
  0 siblings, 1 reply; 65+ messages in thread
From: Nick Pelling @ 2011-02-22 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hi yujinzhi,

At 22:00 22/02/2011 +0800, =?GB2312?B?0+C999bH?= wrote:
>I have port a embeded linux system on my board based on EP9315, with
>support for usb video capture device, V4L2. Do you need V4L2 based on
>usb video capture device or other video/FM/AM controller on your
>board? If conveniently, can you provide more details about your
>project?

It's a tiny S5PC100 board with an Aptina MT9M131 (1.3MP) sensor and 
video out for some security camera projects I'm working on. I've just 
brought up another embedded V4L2-based Linux camera, so V4L2 would be 
nice - in fact, there's already some Samsung s5p fimc code checked 
into the main tree, but it's far from clear (to me, at least) how to 
go about integrating image sensors with that to get V4L2 working.

>You MUST need the datasheet of S5PC100 on your board, and other
>peripheral device's datasheet, like dm9000 ethernet controller if not
>integrated in SoC, and schematic diagrams of your board.

Hardware datasheets I have plenty of, it's the supporting 
documentation on the s3c fb / s5p fimc devices / v4l2 host stuff that 
I'm missing. Not a lot in the Documentation/arm/Samsung* directories, 
for example. :-(

Cheers, ....Nick Pelling.... 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: SAMSUNG: any example code for soc_camera, tv output,  etc...?
  2011-02-22 22:54               ` Nick Pelling
@ 2011-02-23 11:03                   ` Sylwester Nawrocki
  0 siblings, 0 replies; 65+ messages in thread
From: Sylwester Nawrocki @ 2011-02-23 11:03 UTC (permalink / raw)
  To: Nick Pelling
  Cc: linux-arm-kernel, 余谨智,
	kgene.kim, ben-linux, inki.dae, kyungmin.park, m.szyprowski,
	linux-media

Hi Nick,

On 02/22/2011 11:54 PM, Nick Pelling wrote:
> Hi yujinzhi,
> 
> At 22:00 22/02/2011 +0800, =?GB2312?B?0+C999bH?= wrote:
>> I have port a embeded linux system on my board based on EP9315, with
>> support for usb video capture device, V4L2. Do you need V4L2 based on
>> usb video capture device or other video/FM/AM controller on your
>> board? If conveniently, can you provide more details about your
>> project?
> 
> It's a tiny S5PC100 board with an Aptina MT9M131 (1.3MP) sensor and video out
> for some security camera projects I'm working on. I've just brought up another
> embedded V4L2-based Linux camera, so V4L2 would be nice - in fact, there's
> already some Samsung s5p fimc code checked into the main tree, but it's far
> from clear (to me, at least) how to go about integrating image sensors with
> that to get V4L2 working.

Currently there is no a board in mainstream kernel that would have essential
S5P SoC multimedia device drivers hooked into it. I expect first reference
board with complete camera support to appear in kernel 2.6.39-rc1.

The bad news is that your sensor driver is compatible with the soc_camera
framework whereas s5p fimc driver exports a regular V4L2 video capture node.
And they won't work together out of the box. You might want to look at
noon010pc30 and sr010pc30 sensor drivers, those were tested with s5p fimc.
All you have to do is to define an instance of struct s5p_fimc_isp_info
and set it with s3c_set_platdata helper function in your board file.
For more details please check file include/media/s5p_fimc.h

There are ongoing efforts to make soc_camera sensors work with not soc_camera
host driver. But I'm really not sure about the schedule.

S5PC100 has no IOMMU and its multimedia devices require physically contiguous
memory. We have been developing the Contiguous Memory Allocator (CMA)
to efficiently manage system memory among graphics devices.
Unfortunately due to some memory remapping constraints in newer
ARM architectures, emerging during development, the CMA is still not
in mainline kernel.
You can still use the videobuf2 dma-contig allocator with s5p fimc as it done
in mainline kernel but it is not realiable on long running system.

Another solution would be to use physically contiguous memory reserved
by other device, e.g. framebuffer and pass it as USERPTR memory to the
camera driver.

You can find latest Samsung System LSI linux kernel development tree at
http://git.kernel.org/?p=linux/kernel/git/kki_ap/linux-2.6-samsung.git

For most recent status of the S5P SoC graphics drivers you might want
to follow posting on linux-media ML (http://linuxtv.org/lists.php).

>> You MUST need the datasheet of S5PC100 on your board, and other
>> peripheral device's datasheet, like dm9000 ethernet controller if not
>> integrated in SoC, and schematic diagrams of your board.
> 
> Hardware datasheets I have plenty of, it's the supporting documentation on the
> s3c fb / s5p fimc devices / v4l2 host stuff that I'm missing. Not a lot in the
> Documentation/arm/Samsung* directories, for example. :-(

s3c-fb IMO is not different from other frambuffers. For basic setup you might
want to look at arch/arm/mach-s5pv210/mach-goni.c

Regards,
-- 
Sylwester Nawrocki
Samsung Poland R&D Center

> 
> Cheers, ....Nick Pelling....
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* SAMSUNG: any example code for soc_camera, tv output,  etc...?
@ 2011-02-23 11:03                   ` Sylwester Nawrocki
  0 siblings, 0 replies; 65+ messages in thread
From: Sylwester Nawrocki @ 2011-02-23 11:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Nick,

On 02/22/2011 11:54 PM, Nick Pelling wrote:
> Hi yujinzhi,
> 
> At 22:00 22/02/2011 +0800, =?GB2312?B?0+C999bH?= wrote:
>> I have port a embeded linux system on my board based on EP9315, with
>> support for usb video capture device, V4L2. Do you need V4L2 based on
>> usb video capture device or other video/FM/AM controller on your
>> board? If conveniently, can you provide more details about your
>> project?
> 
> It's a tiny S5PC100 board with an Aptina MT9M131 (1.3MP) sensor and video out
> for some security camera projects I'm working on. I've just brought up another
> embedded V4L2-based Linux camera, so V4L2 would be nice - in fact, there's
> already some Samsung s5p fimc code checked into the main tree, but it's far
> from clear (to me, at least) how to go about integrating image sensors with
> that to get V4L2 working.

Currently there is no a board in mainstream kernel that would have essential
S5P SoC multimedia device drivers hooked into it. I expect first reference
board with complete camera support to appear in kernel 2.6.39-rc1.

The bad news is that your sensor driver is compatible with the soc_camera
framework whereas s5p fimc driver exports a regular V4L2 video capture node.
And they won't work together out of the box. You might want to look at
noon010pc30 and sr010pc30 sensor drivers, those were tested with s5p fimc.
All you have to do is to define an instance of struct s5p_fimc_isp_info
and set it with s3c_set_platdata helper function in your board file.
For more details please check file include/media/s5p_fimc.h

There are ongoing efforts to make soc_camera sensors work with not soc_camera
host driver. But I'm really not sure about the schedule.

S5PC100 has no IOMMU and its multimedia devices require physically contiguous
memory. We have been developing the Contiguous Memory Allocator (CMA)
to efficiently manage system memory among graphics devices.
Unfortunately due to some memory remapping constraints in newer
ARM architectures, emerging during development, the CMA is still not
in mainline kernel.
You can still use the videobuf2 dma-contig allocator with s5p fimc as it done
in mainline kernel but it is not realiable on long running system.

Another solution would be to use physically contiguous memory reserved
by other device, e.g. framebuffer and pass it as USERPTR memory to the
camera driver.

You can find latest Samsung System LSI linux kernel development tree at
http://git.kernel.org/?p=linux/kernel/git/kki_ap/linux-2.6-samsung.git

For most recent status of the S5P SoC graphics drivers you might want
to follow posting on linux-media ML (http://linuxtv.org/lists.php).

>> You MUST need the datasheet of S5PC100 on your board, and other
>> peripheral device's datasheet, like dm9000 ethernet controller if not
>> integrated in SoC, and schematic diagrams of your board.
> 
> Hardware datasheets I have plenty of, it's the supporting documentation on the
> s3c fb / s5p fimc devices / v4l2 host stuff that I'm missing. Not a lot in the
> Documentation/arm/Samsung* directories, for example. :-(

s3c-fb IMO is not different from other frambuffers. For basic setup you might
want to look at arch/arm/mach-s5pv210/mach-goni.c

Regards,
-- 
Sylwester Nawrocki
Samsung Poland R&D Center

> 
> Cheers, ....Nick Pelling....
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2011-02-23 11:04 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-11 16:16 [PATCH] Generic CPU save/restore PM support Russell King - ARM Linux
2011-02-11 16:16 ` Russell King - ARM Linux
2011-02-11 16:17 ` [PATCH 1/6] ARM: move cache/processor/fault glue to separate include files Russell King - ARM Linux
2011-02-11 16:17   ` Russell King - ARM Linux
2011-02-12  2:52   ` Colin Cross
2011-02-12  2:52     ` Colin Cross
2011-02-12  9:48     ` Russell King - ARM Linux
2011-02-12  9:48       ` Russell King - ARM Linux
2011-02-11 16:17 ` [PATCH 2/6] ARM: pm: add generic CPU suspend/resume support Russell King - ARM Linux
2011-02-11 16:17   ` Russell King - ARM Linux
2011-02-12  2:50   ` Colin Cross
2011-02-12  2:50     ` Colin Cross
2011-02-15 11:04     ` Russell King - ARM Linux
2011-02-15 11:04       ` Russell King - ARM Linux
2011-02-16  0:26       ` Colin Cross
2011-02-16  0:26         ` Colin Cross
2011-02-17 10:41         ` Lorenzo Pieralisi
2011-02-17 10:41           ` Lorenzo Pieralisi
2011-02-17 13:59           ` Russell King - ARM Linux
2011-02-17 13:59             ` Russell King - ARM Linux
2011-02-17 20:05           ` Colin Cross
2011-02-17 20:05             ` Colin Cross
2011-02-17 23:36             ` Russell King - ARM Linux
2011-02-17 23:36               ` Russell King - ARM Linux
2011-02-20 12:00       ` Russell King - ARM Linux
2011-02-20 12:00         ` Russell King - ARM Linux
2011-02-21  9:58         ` Kukjin Kim
2011-02-21  9:58           ` Kukjin Kim
2011-02-15  1:21   ` Colin Cross
2011-02-15  1:21     ` Colin Cross
2011-02-15  4:11     ` Colin Cross
2011-02-15  4:11       ` Colin Cross
2011-02-15 10:50       ` Russell King - ARM Linux
2011-02-15 10:50         ` Russell King - ARM Linux
2011-02-15 18:20         ` Colin Cross
2011-02-15 18:20           ` Colin Cross
2011-02-11 16:18 ` [PATCH 3/6] ARM: pm: convert PXA to generic " Russell King - ARM Linux
2011-02-11 16:18   ` Russell King - ARM Linux
2011-02-11 16:18 ` [PATCH 4/6] ARM: pm: convert sa11x0 " Russell King - ARM Linux
2011-02-11 16:18   ` Russell King - ARM Linux
2011-02-11 16:18 ` [PATCH 5/6] ARM: pm: convert samsung platforms " Russell King - ARM Linux
2011-02-11 16:18   ` Russell King - ARM Linux
2011-02-17 12:09   ` Kukjin Kim
2011-02-17 12:09     ` Kukjin Kim
2011-02-17 14:06     ` Russell King - ARM Linux
2011-02-17 14:06       ` Russell King - ARM Linux
2011-02-17 23:05       ` Kukjin Kim
2011-02-17 23:05         ` Kukjin Kim
2011-02-17 23:29         ` Russell King - ARM Linux
2011-02-17 23:29           ` Russell King - ARM Linux
2011-02-17 23:46           ` Kukjin Kim
2011-02-17 23:46             ` Kukjin Kim
2011-02-17 23:58         ` SAMSUNG: any example code for soc_camera, tv output, etc...? Nick Pelling
2011-02-22 14:00           ` 余谨智
     [not found]             ` <AANLkTin0PR3VQLruade+w6GbCMoW9pXy4Kvn-sBZ+LBM@mail.gmail.c om>
2011-02-22 22:54               ` Nick Pelling
2011-02-23 11:03                 ` Sylwester Nawrocki
2011-02-23 11:03                   ` Sylwester Nawrocki
2011-02-11 16:19 ` [PATCH 6/6] ARM: pm: allow generic sleep code to be used with SMP CPU idle Russell King - ARM Linux
2011-02-11 16:19   ` Russell King - ARM Linux
2011-02-12  2:52   ` Colin Cross
2011-02-12  2:52     ` Colin Cross
2011-02-13 21:59   ` Colin Cross
2011-02-13 21:59     ` Colin Cross
2011-02-14 16:01     ` Russell King - ARM Linux
2011-02-14 16:01       ` 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.