* [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.