aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-samsung
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-03-28 21:02:56 -0400
committerArnd Bergmann <arnd@arndb.de>2014-03-28 21:02:56 -0400
commit2c793fa3493d4e7b7f6cc3392458ef9d94884dac (patch)
treef8718b2203759197fc93b8c321e51580336e0174 /arch/arm/plat-samsung
parentc441ab93d2b0ffec1852c1fd2186d262c2031d16 (diff)
parent8dec067dc9c59f9fdcaf4357c22994cde3647eb8 (diff)
Merge tag 'samsung-pm-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into next/cleanup3
Merge "Samsung PM related 2nd updates for v3.15" from Kukjin Kim: From Tomasz Figa <t.figa@samsung.com>: Current Samsung PM code is heavily unprepared for multiplatform systems. The design implies accessing functions and global variables defined in particular mach- subdirectory from common code in plat-, which is not allowed when building ARCH_MULTIPLATFORM. In addition there is a lot of forced code unification, which makes common function handle any possible quirks of all supported SoCs. In the end this design turned out to not work too well, ending with a lot of empty functions exported from mach-, just because code in common pm.c calls them. Moreover, recent trend of moving lower level suspend/resume code to proper drivers, like pinctrl or clk, made a lot of code there redundant, especially on DT-only platforms like Exynos. Note that this branch is based on previous tags/samsung-pm-1 and merge tags/samsung-cleanup-2 because of fix build error from recent changes of <linux/serial_s3c.h> * tag 'samsung-pm-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung: ARM: EXYNOS: Fix compilation error in cpuidle.c ARM: S5P64X0: Explicitly include linux/serial_s3c.h in mach/pm-core.h ARM: S3C64XX: Fix build for implicit serial_s3c.h inclusion serial: s3c: Fix build of header without serial_core.h preinclusion ARM: EXYNOS: Allow wake-up using GIC interrupts ARM: EXYNOS: Stop using legacy Samsung PM code ARM: EXYNOS: Remove PM initcalls and useless indirection ARM: EXYNOS: Fix abuse of CONFIG_PM ARM: SAMSUNG: Move s3c_pm_check_* prototypes to plat/pm-common.h ARM: SAMSUNG: Move common save/restore helpers to separate file ARM: SAMSUNG: Move Samsung PM debug code into separate file ARM: SAMSUNG: Consolidate PM debug functions ARM: SAMSUNG: Use debug_ll_addr() to get UART base address ARM: SAMSUNG: Save UART DIVSLOT register based on SoC type ARM: SAMSUNG: Add soc_is_s3c2410() helper ARM: EXYNOS: Do not resume l2x0 if not enabled before suspend Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/plat-samsung')
-rw-r--r--arch/arm/plat-samsung/Makefile2
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/pm-common.h110
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h80
-rw-r--r--arch/arm/plat-samsung/pm-check.c2
-rw-r--r--arch/arm/plat-samsung/pm-common.c75
-rw-r--r--arch/arm/plat-samsung/pm-debug.c97
-rw-r--r--arch/arm/plat-samsung/pm.c144
-rw-r--r--arch/arm/plat-samsung/s5p-sleep.S43
9 files changed, 292 insertions, 267 deletions
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 9267d29549b4..25c826ed3b65 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -47,9 +47,11 @@ obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o
47 47
48# PM support 48# PM support
49 49
50obj-$(CONFIG_PM_SLEEP) += pm-common.o
50obj-$(CONFIG_SAMSUNG_PM) += pm.o 51obj-$(CONFIG_SAMSUNG_PM) += pm.o
51obj-$(CONFIG_SAMSUNG_PM_GPIO) += pm-gpio.o 52obj-$(CONFIG_SAMSUNG_PM_GPIO) += pm-gpio.o
52obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o 53obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
54obj-$(CONFIG_SAMSUNG_PM_DEBUG) += pm-debug.o
53 55
54obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o 56obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
55obj-$(CONFIG_SAMSUNG_WDT_RESET) += watchdog-reset.o 57obj-$(CONFIG_SAMSUNG_WDT_RESET) += watchdog-reset.o
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index 31164b34d4c4..d762533b856f 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -20,6 +20,9 @@
20 20
21extern unsigned long samsung_cpu_id; 21extern unsigned long samsung_cpu_id;
22 22
23#define S3C2410_CPU_ID 0x32410000
24#define S3C2410_CPU_MASK 0xFFFFFFFF
25
23#define S3C24XX_CPU_ID 0x32400000 26#define S3C24XX_CPU_ID 0x32400000
24#define S3C24XX_CPU_MASK 0xFFF00000 27#define S3C24XX_CPU_MASK 0xFFF00000
25 28
@@ -56,6 +59,7 @@ static inline int is_samsung_##name(void) \
56 return ((samsung_cpu_id & mask) == (id & mask)); \ 59 return ((samsung_cpu_id & mask) == (id & mask)); \
57} 60}
58 61
62IS_SAMSUNG_CPU(s3c2410, S3C2410_CPU_ID, S3C2410_CPU_MASK)
59IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK) 63IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
60IS_SAMSUNG_CPU(s3c2412, S3C2412_CPU_ID, S3C2412_CPU_MASK) 64IS_SAMSUNG_CPU(s3c2412, S3C2412_CPU_ID, S3C2412_CPU_MASK)
61IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK) 65IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK)
@@ -76,8 +80,10 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
76 defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \ 80 defined(CONFIG_CPU_S3C2442) || defined(CONFIG_CPU_S3C244X) || \
77 defined(CONFIG_CPU_S3C2443) 81 defined(CONFIG_CPU_S3C2443)
78# define soc_is_s3c24xx() is_samsung_s3c24xx() 82# define soc_is_s3c24xx() is_samsung_s3c24xx()
83# define soc_is_s3c2410() is_samsung_s3c2410()
79#else 84#else
80# define soc_is_s3c24xx() 0 85# define soc_is_s3c24xx() 0
86# define soc_is_s3c2410() 0
81#endif 87#endif
82 88
83#if defined(CONFIG_CPU_S3C2412) 89#if defined(CONFIG_CPU_S3C2412)
diff --git a/arch/arm/plat-samsung/include/plat/pm-common.h b/arch/arm/plat-samsung/include/plat/pm-common.h
new file mode 100644
index 000000000000..8705f9e0e288
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pm-common.h
@@ -0,0 +1,110 @@
1/*
2 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
3 * Tomasz Figa <t.figa@samsung.com>
4 * Copyright (c) 2004 Simtec Electronics
5 * http://armlinux.simtec.co.uk/
6 * Written by Ben Dooks, <ben@simtec.co.uk>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __PLAT_SAMSUNG_PM_COMMON_H
14#define __PLAT_SAMSUNG_PM_COMMON_H __FILE__
15
16#include <linux/irq.h>
17
18/* sleep save info */
19
20/**
21 * struct sleep_save - save information for shared peripherals.
22 * @reg: Pointer to the register to save.
23 * @val: Holder for the value saved from reg.
24 *
25 * This describes a list of registers which is used by the pm core and
26 * other subsystem to save and restore register values over suspend.
27 */
28struct sleep_save {
29 void __iomem *reg;
30 unsigned long val;
31};
32
33#define SAVE_ITEM(x) \
34 { .reg = (x) }
35
36/* helper functions to save/restore lists of registers. */
37
38extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
39extern void s3c_pm_do_restore(const struct sleep_save *ptr, int count);
40extern void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count);
41
42/* PM debug functions */
43
44/**
45 * struct pm_uart_save - save block for core UART
46 * @ulcon: Save value for S3C2410_ULCON
47 * @ucon: Save value for S3C2410_UCON
48 * @ufcon: Save value for S3C2410_UFCON
49 * @umcon: Save value for S3C2410_UMCON
50 * @ubrdiv: Save value for S3C2410_UBRDIV
51 *
52 * Save block for UART registers to be held over sleep and restored if they
53 * are needed (say by debug).
54*/
55struct pm_uart_save {
56 u32 ulcon;
57 u32 ucon;
58 u32 ufcon;
59 u32 umcon;
60 u32 ubrdiv;
61 u32 udivslot;
62};
63
64#ifdef CONFIG_SAMSUNG_PM_DEBUG
65/**
66 * s3c_pm_dbg() - low level debug function for use in suspend/resume.
67 * @msg: The message to print.
68 *
69 * This function is used mainly to debug the resume process before the system
70 * can rely on printk/console output. It uses the low-level debugging output
71 * routine printascii() to do its work.
72 */
73extern void s3c_pm_dbg(const char *msg, ...);
74
75/**
76 * s3c_pm_debug_init() - suspend/resume low level debug initialization.
77 * @base: Virtual base of UART to use for suspend/resume debugging.
78 *
79 * This function needs to be called before S3C_PMDBG() can be used, to set up
80 * UART port base address and configuration.
81 */
82extern void s3c_pm_debug_init(void);
83
84#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
85
86extern void s3c_pm_save_uarts(void);
87extern void s3c_pm_restore_uarts(void);
88#else
89#define S3C_PMDBG(fmt...) pr_debug(fmt)
90#define s3c_pm_debug_init() do { } while (0)
91
92static inline void s3c_pm_save_uarts(void) { }
93static inline void s3c_pm_restore_uarts(void) { }
94#endif
95
96/* suspend memory checking */
97
98#ifdef CONFIG_SAMSUNG_PM_CHECK
99extern void s3c_pm_check_prepare(void);
100extern void s3c_pm_check_restore(void);
101extern void s3c_pm_check_cleanup(void);
102extern void s3c_pm_check_store(void);
103#else
104#define s3c_pm_check_prepare() do { } while (0)
105#define s3c_pm_check_restore() do { } while (0)
106#define s3c_pm_check_cleanup() do { } while (0)
107#define s3c_pm_check_store() do { } while (0)
108#endif
109
110#endif
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index ff6063f0d5ea..e17d871b934c 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -15,7 +15,7 @@
15 * management 15 * management
16*/ 16*/
17 17
18#include <linux/irq.h> 18#include <plat/pm-common.h>
19 19
20struct device; 20struct device;
21 21
@@ -54,56 +54,10 @@ extern int (*pm_cpu_sleep)(unsigned long);
54 54
55extern unsigned long s3c_pm_flags; 55extern unsigned long s3c_pm_flags;
56 56
57extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */
58
59/* from sleep.S */ 57/* from sleep.S */
60 58
61extern int s3c2410_cpu_suspend(unsigned long); 59extern int s3c2410_cpu_suspend(unsigned long);
62 60
63/* sleep save info */
64
65/**
66 * struct sleep_save - save information for shared peripherals.
67 * @reg: Pointer to the register to save.
68 * @val: Holder for the value saved from reg.
69 *
70 * This describes a list of registers which is used by the pm core and
71 * other subsystem to save and restore register values over suspend.
72 */
73struct sleep_save {
74 void __iomem *reg;
75 unsigned long val;
76};
77
78#define SAVE_ITEM(x) \
79 { .reg = (x) }
80
81/**
82 * struct pm_uart_save - save block for core UART
83 * @ulcon: Save value for S3C2410_ULCON
84 * @ucon: Save value for S3C2410_UCON
85 * @ufcon: Save value for S3C2410_UFCON
86 * @umcon: Save value for S3C2410_UMCON
87 * @ubrdiv: Save value for S3C2410_UBRDIV
88 *
89 * Save block for UART registers to be held over sleep and restored if they
90 * are needed (say by debug).
91*/
92struct pm_uart_save {
93 u32 ulcon;
94 u32 ucon;
95 u32 ufcon;
96 u32 umcon;
97 u32 ubrdiv;
98 u32 udivslot;
99};
100
101/* helper functions to save/restore lists of registers. */
102
103extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
104extern void s3c_pm_do_restore(const struct sleep_save *ptr, int count);
105extern void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count);
106
107#ifdef CONFIG_SAMSUNG_PM 61#ifdef CONFIG_SAMSUNG_PM
108extern int s3c_irq_wake(struct irq_data *data, unsigned int state); 62extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
109extern int s3c_irqext_wake(struct irq_data *data, unsigned int state); 63extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
@@ -114,24 +68,6 @@ extern void s3c_cpu_resume(void);
114#define s3c_cpu_resume NULL 68#define s3c_cpu_resume NULL
115#endif 69#endif
116 70
117/* PM debug functions */
118
119#ifdef CONFIG_SAMSUNG_PM_DEBUG
120/**
121 * s3c_pm_dbg() - low level debug function for use in suspend/resume.
122 * @msg: The message to print.
123 *
124 * This function is used mainly to debug the resume process before the system
125 * can rely on printk/console output. It uses the low-level debugging output
126 * routine printascii() to do its work.
127 */
128extern void s3c_pm_dbg(const char *msg, ...);
129
130#define S3C_PMDBG(fmt...) s3c_pm_dbg(fmt)
131#else
132#define S3C_PMDBG(fmt...) printk(KERN_DEBUG fmt)
133#endif
134
135#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK 71#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
136/** 72/**
137 * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs 73 * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs
@@ -144,20 +80,6 @@ extern void s3c_pm_debug_smdkled(u32 set, u32 clear);
144static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { } 80static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { }
145#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */ 81#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */
146 82
147/* suspend memory checking */
148
149#ifdef CONFIG_SAMSUNG_PM_CHECK
150extern void s3c_pm_check_prepare(void);
151extern void s3c_pm_check_restore(void);
152extern void s3c_pm_check_cleanup(void);
153extern void s3c_pm_check_store(void);
154#else
155#define s3c_pm_check_prepare() do { } while(0)
156#define s3c_pm_check_restore() do { } while(0)
157#define s3c_pm_check_cleanup() do { } while(0)
158#define s3c_pm_check_store() do { } while(0)
159#endif
160
161/** 83/**
162 * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ 84 * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ
163 * 85 *
diff --git a/arch/arm/plat-samsung/pm-check.c b/arch/arm/plat-samsung/pm-check.c
index 3cbd62666b1e..04aff2c31b46 100644
--- a/arch/arm/plat-samsung/pm-check.c
+++ b/arch/arm/plat-samsung/pm-check.c
@@ -19,7 +19,7 @@
19#include <linux/ioport.h> 19#include <linux/ioport.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21 21
22#include <plat/pm.h> 22#include <plat/pm-common.h>
23 23
24#if CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE < 1 24#if CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE < 1
25#error CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE must be a positive non-zero value 25#error CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE must be a positive non-zero value
diff --git a/arch/arm/plat-samsung/pm-common.c b/arch/arm/plat-samsung/pm-common.c
new file mode 100644
index 000000000000..515cd53372bd
--- /dev/null
+++ b/arch/arm/plat-samsung/pm-common.c
@@ -0,0 +1,75 @@
1/*
2 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
3 * Tomasz Figa <t.figa@samsung.com>
4 * Copyright (C) 2008 Openmoko, Inc.
5 * Copyright (C) 2004-2008 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 * http://armlinux.simtec.co.uk/
8 *
9 * Samsung common power management helper functions.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/io.h>
17#include <linux/kernel.h>
18
19#include <plat/pm-common.h>
20
21/* helper functions to save and restore register state */
22
23/**
24 * s3c_pm_do_save() - save a set of registers for restoration on resume.
25 * @ptr: Pointer to an array of registers.
26 * @count: Size of the ptr array.
27 *
28 * Run through the list of registers given, saving their contents in the
29 * array for later restoration when we wakeup.
30 */
31void s3c_pm_do_save(struct sleep_save *ptr, int count)
32{
33 for (; count > 0; count--, ptr++) {
34 ptr->val = __raw_readl(ptr->reg);
35 S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val);
36 }
37}
38
39/**
40 * s3c_pm_do_restore() - restore register values from the save list.
41 * @ptr: Pointer to an array of registers.
42 * @count: Size of the ptr array.
43 *
44 * Restore the register values saved from s3c_pm_do_save().
45 *
46 * Note, we do not use S3C_PMDBG() in here, as the system may not have
47 * restore the UARTs state yet
48*/
49
50void s3c_pm_do_restore(const struct sleep_save *ptr, int count)
51{
52 for (; count > 0; count--, ptr++) {
53 pr_debug("restore %p (restore %08lx, was %08x)\n",
54 ptr->reg, ptr->val, __raw_readl(ptr->reg));
55
56 __raw_writel(ptr->val, ptr->reg);
57 }
58}
59
60/**
61 * s3c_pm_do_restore_core() - early restore register values from save list.
62 *
63 * This is similar to s3c_pm_do_restore() except we try and minimise the
64 * side effects of the function in case registers that hardware might need
65 * to work has been restored.
66 *
67 * WARNING: Do not put any debug in here that may effect memory or use
68 * peripherals, as things may be changing!
69*/
70
71void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count)
72{
73 for (; count > 0; count--, ptr++)
74 __raw_writel(ptr->val, ptr->reg);
75}
diff --git a/arch/arm/plat-samsung/pm-debug.c b/arch/arm/plat-samsung/pm-debug.c
new file mode 100644
index 000000000000..8f19f66388dd
--- /dev/null
+++ b/arch/arm/plat-samsung/pm-debug.c
@@ -0,0 +1,97 @@
1/*
2 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
3 * Tomasz Figa <t.figa@samsung.com>
4 * Copyright (C) 2008 Openmoko, Inc.
5 * Copyright (C) 2004-2008 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 * http://armlinux.simtec.co.uk/
8 *
9 * Samsung common power management (suspend to RAM) debug support
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/serial_core.h>
17#include <linux/io.h>
18
19#include <asm/mach/map.h>
20
21#include <plat/cpu.h>
22#include <plat/pm-common.h>
23
24#ifdef CONFIG_SAMSUNG_ATAGS
25#include <mach/pm-core.h>
26#else
27static inline void s3c_pm_debug_init_uart(void) {}
28static inline void s3c_pm_arch_update_uart(void __iomem *regs,
29 struct pm_uart_save *save) {}
30#endif
31
32static struct pm_uart_save uart_save;
33
34extern void printascii(const char *);
35
36void s3c_pm_dbg(const char *fmt, ...)
37{
38 va_list va;
39 char buff[256];
40
41 va_start(va, fmt);
42 vsnprintf(buff, sizeof(buff), fmt, va);
43 va_end(va);
44
45 printascii(buff);
46}
47
48void s3c_pm_debug_init(void)
49{
50 /* restart uart clocks so we can use them to output */
51 s3c_pm_debug_init_uart();
52}
53
54static inline void __iomem *s3c_pm_uart_base(void)
55{
56 unsigned long paddr;
57 unsigned long vaddr;
58
59 debug_ll_addr(&paddr, &vaddr);
60
61 return (void __iomem *)vaddr;
62}
63
64void s3c_pm_save_uarts(void)
65{
66 void __iomem *regs = s3c_pm_uart_base();
67 struct pm_uart_save *save = &uart_save;
68
69 save->ulcon = __raw_readl(regs + S3C2410_ULCON);
70 save->ucon = __raw_readl(regs + S3C2410_UCON);
71 save->ufcon = __raw_readl(regs + S3C2410_UFCON);
72 save->umcon = __raw_readl(regs + S3C2410_UMCON);
73 save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
74
75 if (!soc_is_s3c2410())
76 save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
77
78 S3C_PMDBG("UART[%p]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
79 regs, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
80}
81
82void s3c_pm_restore_uarts(void)
83{
84 void __iomem *regs = s3c_pm_uart_base();
85 struct pm_uart_save *save = &uart_save;
86
87 s3c_pm_arch_update_uart(regs, save);
88
89 __raw_writel(save->ulcon, regs + S3C2410_ULCON);
90 __raw_writel(save->ucon, regs + S3C2410_UCON);
91 __raw_writel(save->ufcon, regs + S3C2410_UFCON);
92 __raw_writel(save->umcon, regs + S3C2410_UMCON);
93 __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
94
95 if (!soc_is_s3c2410())
96 __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
97}
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
index d438e77fbf7b..f8c0f9797dcf 100644
--- a/arch/arm/plat-samsung/pm.c
+++ b/arch/arm/plat-samsung/pm.c
@@ -17,7 +17,6 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/serial_core.h>
21#include <linux/serial_s3c.h> 20#include <linux/serial_s3c.h>
22#include <linux/io.h> 21#include <linux/io.h>
23 22
@@ -42,93 +41,6 @@
42 41
43unsigned long s3c_pm_flags; 42unsigned long s3c_pm_flags;
44 43
45/* Debug code:
46 *
47 * This code supports debug output to the low level UARTs for use on
48 * resume before the console layer is available.
49*/
50
51#ifdef CONFIG_SAMSUNG_PM_DEBUG
52extern void printascii(const char *);
53
54void s3c_pm_dbg(const char *fmt, ...)
55{
56 va_list va;
57 char buff[256];
58
59 va_start(va, fmt);
60 vsnprintf(buff, sizeof(buff), fmt, va);
61 va_end(va);
62
63 printascii(buff);
64}
65
66static inline void s3c_pm_debug_init(void)
67{
68 /* restart uart clocks so we can use them to output */
69 s3c_pm_debug_init_uart();
70}
71
72#else
73#define s3c_pm_debug_init() do { } while(0)
74
75#endif /* CONFIG_SAMSUNG_PM_DEBUG */
76
77/* Save the UART configurations if we are configured for debug. */
78
79unsigned char pm_uart_udivslot;
80
81#ifdef CONFIG_SAMSUNG_PM_DEBUG
82
83static struct pm_uart_save uart_save;
84
85static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
86{
87 void __iomem *regs = S3C_VA_UARTx(uart);
88
89 save->ulcon = __raw_readl(regs + S3C2410_ULCON);
90 save->ucon = __raw_readl(regs + S3C2410_UCON);
91 save->ufcon = __raw_readl(regs + S3C2410_UFCON);
92 save->umcon = __raw_readl(regs + S3C2410_UMCON);
93 save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
94
95 if (pm_uart_udivslot)
96 save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
97
98 S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
99 uart, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
100}
101
102static void s3c_pm_save_uarts(void)
103{
104 s3c_pm_save_uart(CONFIG_DEBUG_S3C_UART, &uart_save);
105}
106
107static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save)
108{
109 void __iomem *regs = S3C_VA_UARTx(uart);
110
111 s3c_pm_arch_update_uart(regs, save);
112
113 __raw_writel(save->ulcon, regs + S3C2410_ULCON);
114 __raw_writel(save->ucon, regs + S3C2410_UCON);
115 __raw_writel(save->ufcon, regs + S3C2410_UFCON);
116 __raw_writel(save->umcon, regs + S3C2410_UMCON);
117 __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
118
119 if (pm_uart_udivslot)
120 __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
121}
122
123static void s3c_pm_restore_uarts(void)
124{
125 s3c_pm_restore_uart(CONFIG_DEBUG_S3C_UART, &uart_save);
126}
127#else
128static void s3c_pm_save_uarts(void) { }
129static void s3c_pm_restore_uarts(void) { }
130#endif
131
132/* The IRQ ext-int code goes here, it is too small to currently bother 44/* The IRQ ext-int code goes here, it is too small to currently bother
133 * with its own file. */ 45 * with its own file. */
134 46
@@ -153,62 +65,6 @@ int s3c_irqext_wake(struct irq_data *data, unsigned int state)
153 return 0; 65 return 0;
154} 66}
155 67
156/* helper functions to save and restore register state */
157
158/**
159 * s3c_pm_do_save() - save a set of registers for restoration on resume.
160 * @ptr: Pointer to an array of registers.
161 * @count: Size of the ptr array.
162 *
163 * Run through the list of registers given, saving their contents in the
164 * array for later restoration when we wakeup.
165 */
166void s3c_pm_do_save(struct sleep_save *ptr, int count)
167{
168 for (; count > 0; count--, ptr++) {
169 ptr->val = __raw_readl(ptr->reg);
170 S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val);
171 }
172}
173
174/**
175 * s3c_pm_do_restore() - restore register values from the save list.
176 * @ptr: Pointer to an array of registers.
177 * @count: Size of the ptr array.
178 *
179 * Restore the register values saved from s3c_pm_do_save().
180 *
181 * Note, we do not use S3C_PMDBG() in here, as the system may not have
182 * restore the UARTs state yet
183*/
184
185void s3c_pm_do_restore(const struct sleep_save *ptr, int count)
186{
187 for (; count > 0; count--, ptr++) {
188 printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
189 ptr->reg, ptr->val, __raw_readl(ptr->reg));
190
191 __raw_writel(ptr->val, ptr->reg);
192 }
193}
194
195/**
196 * s3c_pm_do_restore_core() - early restore register values from save list.
197 *
198 * This is similar to s3c_pm_do_restore() except we try and minimise the
199 * side effects of the function in case registers that hardware might need
200 * to work has been restored.
201 *
202 * WARNING: Do not put any debug in here that may effect memory or use
203 * peripherals, as things may be changing!
204*/
205
206void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count)
207{
208 for (; count > 0; count--, ptr++)
209 __raw_writel(ptr->val, ptr->reg);
210}
211
212/* s3c2410_pm_show_resume_irqs 68/* s3c2410_pm_show_resume_irqs
213 * 69 *
214 * print any IRQs asserted at resume time (ie, we woke from) 70 * print any IRQs asserted at resume time (ie, we woke from)
diff --git a/arch/arm/plat-samsung/s5p-sleep.S b/arch/arm/plat-samsung/s5p-sleep.S
index a030e7301da8..c5001659bdf8 100644
--- a/arch/arm/plat-samsung/s5p-sleep.S
+++ b/arch/arm/plat-samsung/s5p-sleep.S
@@ -23,18 +23,7 @@
23 23
24#include <linux/linkage.h> 24#include <linux/linkage.h>
25#include <asm/asm-offsets.h> 25#include <asm/asm-offsets.h>
26#include <asm/hardware/cache-l2x0.h>
27 26
28#define CPU_MASK 0xff0ffff0
29#define CPU_CORTEX_A9 0x410fc090
30
31/*
32 * The following code is located into the .data section. This is to
33 * allow l2x0_regs_phys to be accessed with a relative load while we
34 * can't rely on any MMU translation. We could have put l2x0_regs_phys
35 * in the .text section as well, but some setups might insist on it to
36 * be truly read-only. (Reference from: arch/arm/kernel/sleep.S)
37 */
38 .data 27 .data
39 .align 28 .align
40 29
@@ -53,37 +42,5 @@
53 */ 42 */
54 43
55ENTRY(s3c_cpu_resume) 44ENTRY(s3c_cpu_resume)
56#ifdef CONFIG_CACHE_L2X0
57 mrc p15, 0, r0, c0, c0, 0
58 ldr r1, =CPU_MASK
59 and r0, r0, r1
60 ldr r1, =CPU_CORTEX_A9
61 cmp r0, r1
62 bne resume_l2on
63 adr r0, l2x0_regs_phys
64 ldr r0, [r0]
65 ldr r1, [r0, #L2X0_R_PHY_BASE]
66 ldr r2, [r1, #L2X0_CTRL]
67 tst r2, #0x1
68 bne resume_l2on
69 ldr r2, [r0, #L2X0_R_AUX_CTRL]
70 str r2, [r1, #L2X0_AUX_CTRL]
71 ldr r2, [r0, #L2X0_R_TAG_LATENCY]
72 str r2, [r1, #L2X0_TAG_LATENCY_CTRL]
73 ldr r2, [r0, #L2X0_R_DATA_LATENCY]
74 str r2, [r1, #L2X0_DATA_LATENCY_CTRL]
75 ldr r2, [r0, #L2X0_R_PREFETCH_CTRL]
76 str r2, [r1, #L2X0_PREFETCH_CTRL]
77 ldr r2, [r0, #L2X0_R_PWR_CTRL]
78 str r2, [r1, #L2X0_POWER_CTRL]
79 mov r2, #1
80 str r2, [r1, #L2X0_CTRL]
81resume_l2on:
82#endif
83 b cpu_resume 45 b cpu_resume
84ENDPROC(s3c_cpu_resume) 46ENDPROC(s3c_cpu_resume)
85#ifdef CONFIG_CACHE_L2X0
86 .globl l2x0_regs_phys
87l2x0_regs_phys:
88 .long 0
89#endif