aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-samsung
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 15:31:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 15:31:18 -0400
commit6fa52ed33bea997374a88dbacbba5bf8c7ac4fef (patch)
treea0904b78d66c9b99d6acf944cf58bcaa0cffc511 /arch/arm/plat-samsung
parent1db772216f48978d5146b858586f6178433aad38 (diff)
parentbc8fd900c4d460b4e4bf785bb48bfced0ac9941b (diff)
Merge tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver changes from Olof Johansson: "This is a rather large set of patches for device drivers that for one reason or another the subsystem maintainer preferred to get merged through the arm-soc tree. There are both new drivers as well as existing drivers that are getting converted from platform-specific code into standalone drivers using the appropriate subsystem specific interfaces. In particular, we can now have pinctrl, clk, clksource and irqchip drivers in one file per driver, without the need to call into platform specific interface, or to get called from platform specific code, as long as all information about the hardware is provided through a device tree. Most of the drivers we touch this time are for clocksource. Since now most of them are part of drivers/clocksource, I expect that we won't have to touch these again from arm-soc and can let the clocksource maintainers take care of these in the future. Another larger part of this series is specific to the exynos platform, which is seeing some significant effort in upstreaming and modernization of its device drivers this time around, which unfortunately is also the cause for the churn and a lot of the merge conflicts. There is one new subsystem that gets merged as part of this series: the reset controller interface, which is a very simple interface for taking devices on the SoC out of reset or back into reset. Patches to use this interface on i.MX follow later in this merge window, and we are going to have other platforms (at least tegra and sirf) get converted in 3.11. This will let us get rid of platform specific callbacks in a number of platform independent device drivers." * tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (256 commits) irqchip: s3c24xx: add missing __init annotations ARM: dts: Disable the RTC by default on exynos5 clk: exynos5250: Fix parent clock for sclk_mmc{0,1,2,3} ARM: exynos: restore mach/regs-clock.h for exynos5 clocksource: exynos_mct: fix build error on non-DT pinctrl: vt8500: wmt: Fix checking return value of pinctrl_register() irqchip: vt8500: Convert arch-vt8500 to new irqchip infrastructure reset: NULL deref on allocation failure reset: Add reset controller API dt: describe base reset signal binding ARM: EXYNOS: Add arm-pmu DT binding for exynos421x ARM: EXYNOS: Add arm-pmu DT binding for exynos5250 ARM: EXYNOS: Enable PMUs for exynos4 irqchip: exynos-combiner: Correct combined IRQs for exynos4 irqchip: exynos-combiner: Add set_irq_affinity function for combiner_irq ARM: EXYNOS: fix compilation error introduced due to common clock migration clk: exynos5250: Fix divider values for sclk_mmc{0,1,2,3} clk: exynos4: export clocks required for fimc-is clk: samsung: Fix compilation error clk: tegra: fix enum tegra114_clk to match binding ...
Diffstat (limited to 'arch/arm/plat-samsung')
-rw-r--r--arch/arm/plat-samsung/Kconfig6
-rw-r--r--arch/arm/plat-samsung/Makefile3
-rw-r--r--arch/arm/plat-samsung/devs.c2
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h15
-rw-r--r--arch/arm/plat-samsung/include/plat/s5p-time.h40
-rw-r--r--arch/arm/plat-samsung/include/plat/samsung-time.h53
-rw-r--r--arch/arm/plat-samsung/samsung-time.c (renamed from arch/arm/plat-samsung/s5p-time.c)138
-rw-r--r--arch/arm/plat-samsung/time.c287
8 files changed, 137 insertions, 407 deletions
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 91c2d72e689b..54d186106f9f 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -25,7 +25,7 @@ config PLAT_S5P
25 select PLAT_SAMSUNG 25 select PLAT_SAMSUNG
26 select S3C_GPIO_TRACK 26 select S3C_GPIO_TRACK
27 select S5P_GPIO_DRVSTR 27 select S5P_GPIO_DRVSTR
28 select SAMSUNG_CLKSRC 28 select SAMSUNG_CLKSRC if !COMMON_CLK
29 select SAMSUNG_GPIOLIB_4BIT 29 select SAMSUNG_GPIOLIB_4BIT
30 select SAMSUNG_IRQ_VIC_TIMER 30 select SAMSUNG_IRQ_VIC_TIMER
31 help 31 help
@@ -62,7 +62,7 @@ config S3C_LOWLEVEL_UART_PORT
62 62
63# timer options 63# timer options
64 64
65config S5P_HRT 65config SAMSUNG_HRT
66 bool 66 bool
67 select SAMSUNG_DEV_PWM 67 select SAMSUNG_DEV_PWM
68 help 68 help
@@ -81,7 +81,7 @@ config SAMSUNG_CLKSRC
81 used by newer systems such as the S3C64XX. 81 used by newer systems such as the S3C64XX.
82 82
83config S5P_CLOCK 83config S5P_CLOCK
84 def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) 84 def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
85 help 85 help
86 Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs 86 Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs
87 87
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 3a7c64d1814a..a23c460299a1 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -12,8 +12,7 @@ obj- :=
12# Objects we always build independent of SoC choice 12# Objects we always build independent of SoC choice
13 13
14obj-y += init.o cpu.o 14obj-y += init.o cpu.o
15obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o 15obj-$(CONFIG_SAMSUNG_HRT) += samsung-time.o
16obj-$(CONFIG_S5P_HRT) += s5p-time.o
17 16
18obj-$(CONFIG_SAMSUNG_CLOCK) += clock.o 17obj-$(CONFIG_SAMSUNG_CLOCK) += clock.o
19obj-$(CONFIG_SAMSUNG_CLOCK) += pwm-clock.o 18obj-$(CONFIG_SAMSUNG_CLOCK) += pwm-clock.o
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 33ad3f32c2b9..30c2fe243f76 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1074,7 +1074,7 @@ struct platform_device s5p_device_onenand = {
1074 1074
1075/* PMU */ 1075/* PMU */
1076 1076
1077#ifdef CONFIG_PLAT_S5P 1077#if defined(CONFIG_PLAT_S5P) && !defined(CONFIG_ARCH_EXYNOS)
1078static struct resource s5p_pmu_resource[] = { 1078static struct resource s5p_pmu_resource[] = {
1079 DEFINE_RES_IRQ(IRQ_PMU) 1079 DEFINE_RES_IRQ(IRQ_PMU)
1080}; 1080};
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index 37703ef6dfc7..989fefe18be6 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -23,6 +23,9 @@ extern unsigned long samsung_cpu_id;
23#define S3C24XX_CPU_ID 0x32400000 23#define S3C24XX_CPU_ID 0x32400000
24#define S3C24XX_CPU_MASK 0xFFF00000 24#define S3C24XX_CPU_MASK 0xFFF00000
25 25
26#define S3C2412_CPU_ID 0x32412000
27#define S3C2412_CPU_MASK 0xFFFFF000
28
26#define S3C6400_CPU_ID 0x36400000 29#define S3C6400_CPU_ID 0x36400000
27#define S3C6410_CPU_ID 0x36410000 30#define S3C6410_CPU_ID 0x36410000
28#define S3C64XX_CPU_MASK 0xFFFFF000 31#define S3C64XX_CPU_MASK 0xFFFFF000
@@ -53,6 +56,7 @@ static inline int is_samsung_##name(void) \
53} 56}
54 57
55IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK) 58IS_SAMSUNG_CPU(s3c24xx, S3C24XX_CPU_ID, S3C24XX_CPU_MASK)
59IS_SAMSUNG_CPU(s3c2412, S3C2412_CPU_ID, S3C2412_CPU_MASK)
56IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK) 60IS_SAMSUNG_CPU(s3c6400, S3C6400_CPU_ID, S3C64XX_CPU_MASK)
57IS_SAMSUNG_CPU(s3c6410, S3C6410_CPU_ID, S3C64XX_CPU_MASK) 61IS_SAMSUNG_CPU(s3c6410, S3C6410_CPU_ID, S3C64XX_CPU_MASK)
58IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK) 62IS_SAMSUNG_CPU(s5p6440, S5P6440_CPU_ID, S5P64XX_CPU_MASK)
@@ -74,6 +78,12 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
74# define soc_is_s3c24xx() 0 78# define soc_is_s3c24xx() 0
75#endif 79#endif
76 80
81#if defined(CONFIG_CPU_S3C2412)
82# define soc_is_s3c2412() is_samsung_s3c2412()
83#else
84# define soc_is_s3c2412() 0
85#endif
86
77#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) 87#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410)
78# define soc_is_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410()) 88# define soc_is_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410())
79#else 89#else
@@ -173,7 +183,6 @@ extern void s3c_init_cpu(unsigned long idcode,
173 183
174/* core initialisation functions */ 184/* core initialisation functions */
175 185
176extern void s3c24xx_init_irq(void);
177extern void s5p_init_irq(u32 *vic, u32 num_vic); 186extern void s5p_init_irq(u32 *vic, u32 num_vic);
178 187
179extern void s3c24xx_init_io(struct map_desc *mach_desc, int size); 188extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
@@ -192,10 +201,6 @@ extern void s3c24xx_init_uartdevs(char *name,
192 struct s3c24xx_uart_resources *res, 201 struct s3c24xx_uart_resources *res,
193 struct s3c2410_uartcfg *cfg, int no); 202 struct s3c2410_uartcfg *cfg, int no);
194 203
195/* timer for 2410/2440 */
196
197extern void s3c24xx_timer_init(void);
198
199extern struct syscore_ops s3c2410_pm_syscore_ops; 204extern struct syscore_ops s3c2410_pm_syscore_ops;
200extern struct syscore_ops s3c2412_pm_syscore_ops; 205extern struct syscore_ops s3c2412_pm_syscore_ops;
201extern struct syscore_ops s3c2416_pm_syscore_ops; 206extern struct syscore_ops s3c2416_pm_syscore_ops;
diff --git a/arch/arm/plat-samsung/include/plat/s5p-time.h b/arch/arm/plat-samsung/include/plat/s5p-time.h
deleted file mode 100644
index 9c96f3586ce0..000000000000
--- a/arch/arm/plat-samsung/include/plat/s5p-time.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/* linux/arch/arm/plat-samsung/include/plat/s5p-time.h
2 *
3 * Copyright 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Header file for s5p time support
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 __ASM_PLAT_S5P_TIME_H
14#define __ASM_PLAT_S5P_TIME_H __FILE__
15
16/* S5P HR-Timer Clock mode */
17enum s5p_timer_mode {
18 S5P_PWM0,
19 S5P_PWM1,
20 S5P_PWM2,
21 S5P_PWM3,
22 S5P_PWM4,
23};
24
25struct s5p_timer_source {
26 unsigned int event_id;
27 unsigned int source_id;
28};
29
30/* Be able to sleep for atleast 4 seconds (usually more) */
31#define S5PTIMER_MIN_RANGE 4
32
33#define TCNT_MAX 0xffffffff
34#define NON_PERIODIC 0
35#define PERIODIC 1
36
37extern void __init s5p_set_timer_source(enum s5p_timer_mode event,
38 enum s5p_timer_mode source);
39extern void s5p_timer_init(void);
40#endif /* __ASM_PLAT_S5P_TIME_H */
diff --git a/arch/arm/plat-samsung/include/plat/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h
new file mode 100644
index 000000000000..4cc99bb1f176
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/samsung-time.h
@@ -0,0 +1,53 @@
1/* linux/arch/arm/plat-samsung/include/plat/samsung-time.h
2 *
3 * Copyright 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Header file for samsung s3c and s5p time support
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 __ASM_PLAT_SAMSUNG_TIME_H
14#define __ASM_PLAT_SAMSUNG_TIME_H __FILE__
15
16/* SAMSUNG HR-Timer Clock mode */
17enum samsung_timer_mode {
18 SAMSUNG_PWM0,
19 SAMSUNG_PWM1,
20 SAMSUNG_PWM2,
21 SAMSUNG_PWM3,
22 SAMSUNG_PWM4,
23};
24
25struct samsung_timer_source {
26 unsigned int event_id;
27 unsigned int source_id;
28};
29
30/* Be able to sleep for atleast 4 seconds (usually more) */
31#define SAMSUNG_TIMER_MIN_RANGE 4
32
33#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S5PC100)
34#define TCNT_MAX 0xffff
35#define TSCALER_DIV 25
36#define TDIV 50
37#define TSIZE 16
38#else
39#define TCNT_MAX 0xffffffff
40#define TSCALER_DIV 2
41#define TDIV 2
42#define TSIZE 32
43#endif
44
45#define NON_PERIODIC 0
46#define PERIODIC 1
47
48extern void __init samsung_set_timer_source(enum samsung_timer_mode event,
49 enum samsung_timer_mode source);
50
51extern void __init samsung_timer_init(void);
52
53#endif /* __ASM_PLAT_SAMSUNG_TIME_H */
diff --git a/arch/arm/plat-samsung/s5p-time.c b/arch/arm/plat-samsung/samsung-time.c
index e92510cf82ee..f899cbc9b288 100644
--- a/arch/arm/plat-samsung/s5p-time.c
+++ b/arch/arm/plat-samsung/samsung-time.c
@@ -2,7 +2,7 @@
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/ 3 * http://www.samsung.com/
4 * 4 *
5 * S5P - Common hr-timer support 5 * samsung - Common hr-timer support (s3c and s5p)
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -25,41 +25,41 @@
25#include <mach/map.h> 25#include <mach/map.h>
26#include <plat/devs.h> 26#include <plat/devs.h>
27#include <plat/regs-timer.h> 27#include <plat/regs-timer.h>
28#include <plat/s5p-time.h> 28#include <plat/samsung-time.h>
29 29
30static struct clk *tin_event; 30static struct clk *tin_event;
31static struct clk *tin_source; 31static struct clk *tin_source;
32static struct clk *tdiv_event; 32static struct clk *tdiv_event;
33static struct clk *tdiv_source; 33static struct clk *tdiv_source;
34static struct clk *timerclk; 34static struct clk *timerclk;
35static struct s5p_timer_source timer_source; 35static struct samsung_timer_source timer_source;
36static unsigned long clock_count_per_tick; 36static unsigned long clock_count_per_tick;
37static void s5p_timer_resume(void); 37static void samsung_timer_resume(void);
38 38
39static void s5p_time_stop(enum s5p_timer_mode mode) 39static void samsung_time_stop(enum samsung_timer_mode mode)
40{ 40{
41 unsigned long tcon; 41 unsigned long tcon;
42 42
43 tcon = __raw_readl(S3C2410_TCON); 43 tcon = __raw_readl(S3C2410_TCON);
44 44
45 switch (mode) { 45 switch (mode) {
46 case S5P_PWM0: 46 case SAMSUNG_PWM0:
47 tcon &= ~S3C2410_TCON_T0START; 47 tcon &= ~S3C2410_TCON_T0START;
48 break; 48 break;
49 49
50 case S5P_PWM1: 50 case SAMSUNG_PWM1:
51 tcon &= ~S3C2410_TCON_T1START; 51 tcon &= ~S3C2410_TCON_T1START;
52 break; 52 break;
53 53
54 case S5P_PWM2: 54 case SAMSUNG_PWM2:
55 tcon &= ~S3C2410_TCON_T2START; 55 tcon &= ~S3C2410_TCON_T2START;
56 break; 56 break;
57 57
58 case S5P_PWM3: 58 case SAMSUNG_PWM3:
59 tcon &= ~S3C2410_TCON_T3START; 59 tcon &= ~S3C2410_TCON_T3START;
60 break; 60 break;
61 61
62 case S5P_PWM4: 62 case SAMSUNG_PWM4:
63 tcon &= ~S3C2410_TCON_T4START; 63 tcon &= ~S3C2410_TCON_T4START;
64 break; 64 break;
65 65
@@ -70,7 +70,7 @@ static void s5p_time_stop(enum s5p_timer_mode mode)
70 __raw_writel(tcon, S3C2410_TCON); 70 __raw_writel(tcon, S3C2410_TCON);
71} 71}
72 72
73static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt) 73static void samsung_time_setup(enum samsung_timer_mode mode, unsigned long tcnt)
74{ 74{
75 unsigned long tcon; 75 unsigned long tcon;
76 76
@@ -79,27 +79,27 @@ static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt)
79 tcnt--; 79 tcnt--;
80 80
81 switch (mode) { 81 switch (mode) {
82 case S5P_PWM0: 82 case SAMSUNG_PWM0:
83 tcon &= ~(0x0f << 0); 83 tcon &= ~(0x0f << 0);
84 tcon |= S3C2410_TCON_T0MANUALUPD; 84 tcon |= S3C2410_TCON_T0MANUALUPD;
85 break; 85 break;
86 86
87 case S5P_PWM1: 87 case SAMSUNG_PWM1:
88 tcon &= ~(0x0f << 8); 88 tcon &= ~(0x0f << 8);
89 tcon |= S3C2410_TCON_T1MANUALUPD; 89 tcon |= S3C2410_TCON_T1MANUALUPD;
90 break; 90 break;
91 91
92 case S5P_PWM2: 92 case SAMSUNG_PWM2:
93 tcon &= ~(0x0f << 12); 93 tcon &= ~(0x0f << 12);
94 tcon |= S3C2410_TCON_T2MANUALUPD; 94 tcon |= S3C2410_TCON_T2MANUALUPD;
95 break; 95 break;
96 96
97 case S5P_PWM3: 97 case SAMSUNG_PWM3:
98 tcon &= ~(0x0f << 16); 98 tcon &= ~(0x0f << 16);
99 tcon |= S3C2410_TCON_T3MANUALUPD; 99 tcon |= S3C2410_TCON_T3MANUALUPD;
100 break; 100 break;
101 101
102 case S5P_PWM4: 102 case SAMSUNG_PWM4:
103 tcon &= ~(0x07 << 20); 103 tcon &= ~(0x07 << 20);
104 tcon |= S3C2410_TCON_T4MANUALUPD; 104 tcon |= S3C2410_TCON_T4MANUALUPD;
105 break; 105 break;
@@ -114,14 +114,14 @@ static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt)
114 __raw_writel(tcon, S3C2410_TCON); 114 __raw_writel(tcon, S3C2410_TCON);
115} 115}
116 116
117static void s5p_time_start(enum s5p_timer_mode mode, bool periodic) 117static void samsung_time_start(enum samsung_timer_mode mode, bool periodic)
118{ 118{
119 unsigned long tcon; 119 unsigned long tcon;
120 120
121 tcon = __raw_readl(S3C2410_TCON); 121 tcon = __raw_readl(S3C2410_TCON);
122 122
123 switch (mode) { 123 switch (mode) {
124 case S5P_PWM0: 124 case SAMSUNG_PWM0:
125 tcon |= S3C2410_TCON_T0START; 125 tcon |= S3C2410_TCON_T0START;
126 tcon &= ~S3C2410_TCON_T0MANUALUPD; 126 tcon &= ~S3C2410_TCON_T0MANUALUPD;
127 127
@@ -131,7 +131,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
131 tcon &= ~S3C2410_TCON_T0RELOAD; 131 tcon &= ~S3C2410_TCON_T0RELOAD;
132 break; 132 break;
133 133
134 case S5P_PWM1: 134 case SAMSUNG_PWM1:
135 tcon |= S3C2410_TCON_T1START; 135 tcon |= S3C2410_TCON_T1START;
136 tcon &= ~S3C2410_TCON_T1MANUALUPD; 136 tcon &= ~S3C2410_TCON_T1MANUALUPD;
137 137
@@ -141,7 +141,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
141 tcon &= ~S3C2410_TCON_T1RELOAD; 141 tcon &= ~S3C2410_TCON_T1RELOAD;
142 break; 142 break;
143 143
144 case S5P_PWM2: 144 case SAMSUNG_PWM2:
145 tcon |= S3C2410_TCON_T2START; 145 tcon |= S3C2410_TCON_T2START;
146 tcon &= ~S3C2410_TCON_T2MANUALUPD; 146 tcon &= ~S3C2410_TCON_T2MANUALUPD;
147 147
@@ -151,7 +151,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
151 tcon &= ~S3C2410_TCON_T2RELOAD; 151 tcon &= ~S3C2410_TCON_T2RELOAD;
152 break; 152 break;
153 153
154 case S5P_PWM3: 154 case SAMSUNG_PWM3:
155 tcon |= S3C2410_TCON_T3START; 155 tcon |= S3C2410_TCON_T3START;
156 tcon &= ~S3C2410_TCON_T3MANUALUPD; 156 tcon &= ~S3C2410_TCON_T3MANUALUPD;
157 157
@@ -161,7 +161,7 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
161 tcon &= ~S3C2410_TCON_T3RELOAD; 161 tcon &= ~S3C2410_TCON_T3RELOAD;
162 break; 162 break;
163 163
164 case S5P_PWM4: 164 case SAMSUNG_PWM4:
165 tcon |= S3C2410_TCON_T4START; 165 tcon |= S3C2410_TCON_T4START;
166 tcon &= ~S3C2410_TCON_T4MANUALUPD; 166 tcon &= ~S3C2410_TCON_T4MANUALUPD;
167 167
@@ -178,24 +178,24 @@ static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
178 __raw_writel(tcon, S3C2410_TCON); 178 __raw_writel(tcon, S3C2410_TCON);
179} 179}
180 180
181static int s5p_set_next_event(unsigned long cycles, 181static int samsung_set_next_event(unsigned long cycles,
182 struct clock_event_device *evt) 182 struct clock_event_device *evt)
183{ 183{
184 s5p_time_setup(timer_source.event_id, cycles); 184 samsung_time_setup(timer_source.event_id, cycles);
185 s5p_time_start(timer_source.event_id, NON_PERIODIC); 185 samsung_time_start(timer_source.event_id, NON_PERIODIC);
186 186
187 return 0; 187 return 0;
188} 188}
189 189
190static void s5p_set_mode(enum clock_event_mode mode, 190static void samsung_set_mode(enum clock_event_mode mode,
191 struct clock_event_device *evt) 191 struct clock_event_device *evt)
192{ 192{
193 s5p_time_stop(timer_source.event_id); 193 samsung_time_stop(timer_source.event_id);
194 194
195 switch (mode) { 195 switch (mode) {
196 case CLOCK_EVT_MODE_PERIODIC: 196 case CLOCK_EVT_MODE_PERIODIC:
197 s5p_time_setup(timer_source.event_id, clock_count_per_tick); 197 samsung_time_setup(timer_source.event_id, clock_count_per_tick);
198 s5p_time_start(timer_source.event_id, PERIODIC); 198 samsung_time_start(timer_source.event_id, PERIODIC);
199 break; 199 break;
200 200
201 case CLOCK_EVT_MODE_ONESHOT: 201 case CLOCK_EVT_MODE_ONESHOT:
@@ -206,24 +206,24 @@ static void s5p_set_mode(enum clock_event_mode mode,
206 break; 206 break;
207 207
208 case CLOCK_EVT_MODE_RESUME: 208 case CLOCK_EVT_MODE_RESUME:
209 s5p_timer_resume(); 209 samsung_timer_resume();
210 break; 210 break;
211 } 211 }
212} 212}
213 213
214static void s5p_timer_resume(void) 214static void samsung_timer_resume(void)
215{ 215{
216 /* event timer restart */ 216 /* event timer restart */
217 s5p_time_setup(timer_source.event_id, clock_count_per_tick); 217 samsung_time_setup(timer_source.event_id, clock_count_per_tick);
218 s5p_time_start(timer_source.event_id, PERIODIC); 218 samsung_time_start(timer_source.event_id, PERIODIC);
219 219
220 /* source timer restart */ 220 /* source timer restart */
221 s5p_time_setup(timer_source.source_id, TCNT_MAX); 221 samsung_time_setup(timer_source.source_id, TCNT_MAX);
222 s5p_time_start(timer_source.source_id, PERIODIC); 222 samsung_time_start(timer_source.source_id, PERIODIC);
223} 223}
224 224
225void __init s5p_set_timer_source(enum s5p_timer_mode event, 225void __init samsung_set_timer_source(enum samsung_timer_mode event,
226 enum s5p_timer_mode source) 226 enum samsung_timer_mode source)
227{ 227{
228 s3c_device_timer[event].dev.bus = &platform_bus_type; 228 s3c_device_timer[event].dev.bus = &platform_bus_type;
229 s3c_device_timer[source].dev.bus = &platform_bus_type; 229 s3c_device_timer[source].dev.bus = &platform_bus_type;
@@ -233,14 +233,14 @@ void __init s5p_set_timer_source(enum s5p_timer_mode event,
233} 233}
234 234
235static struct clock_event_device time_event_device = { 235static struct clock_event_device time_event_device = {
236 .name = "s5p_event_timer", 236 .name = "samsung_event_timer",
237 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 237 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
238 .rating = 200, 238 .rating = 200,
239 .set_next_event = s5p_set_next_event, 239 .set_next_event = samsung_set_next_event,
240 .set_mode = s5p_set_mode, 240 .set_mode = samsung_set_mode,
241}; 241};
242 242
243static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id) 243static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id)
244{ 244{
245 struct clock_event_device *evt = dev_id; 245 struct clock_event_device *evt = dev_id;
246 246
@@ -249,14 +249,14 @@ static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
249 return IRQ_HANDLED; 249 return IRQ_HANDLED;
250} 250}
251 251
252static struct irqaction s5p_clock_event_irq = { 252static struct irqaction samsung_clock_event_irq = {
253 .name = "s5p_time_irq", 253 .name = "samsung_time_irq",
254 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 254 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
255 .handler = s5p_clock_event_isr, 255 .handler = samsung_clock_event_isr,
256 .dev_id = &time_event_device, 256 .dev_id = &time_event_device,
257}; 257};
258 258
259static void __init s5p_clockevent_init(void) 259static void __init samsung_clockevent_init(void)
260{ 260{
261 unsigned long pclk; 261 unsigned long pclk;
262 unsigned long clock_rate; 262 unsigned long clock_rate;
@@ -267,8 +267,8 @@ static void __init s5p_clockevent_init(void)
267 267
268 tscaler = clk_get_parent(tdiv_event); 268 tscaler = clk_get_parent(tdiv_event);
269 269
270 clk_set_rate(tscaler, pclk / 2); 270 clk_set_rate(tscaler, pclk / TSCALER_DIV);
271 clk_set_rate(tdiv_event, pclk / 2); 271 clk_set_rate(tdiv_event, pclk / TDIV);
272 clk_set_parent(tin_event, tdiv_event); 272 clk_set_parent(tin_event, tdiv_event);
273 273
274 clock_rate = clk_get_rate(tin_event); 274 clock_rate = clk_get_rate(tin_event);
@@ -278,22 +278,22 @@ static void __init s5p_clockevent_init(void)
278 clockevents_config_and_register(&time_event_device, clock_rate, 1, -1); 278 clockevents_config_and_register(&time_event_device, clock_rate, 1, -1);
279 279
280 irq_number = timer_source.event_id + IRQ_TIMER0; 280 irq_number = timer_source.event_id + IRQ_TIMER0;
281 setup_irq(irq_number, &s5p_clock_event_irq); 281 setup_irq(irq_number, &samsung_clock_event_irq);
282} 282}
283 283
284static void __iomem *s5p_timer_reg(void) 284static void __iomem *samsung_timer_reg(void)
285{ 285{
286 unsigned long offset = 0; 286 unsigned long offset = 0;
287 287
288 switch (timer_source.source_id) { 288 switch (timer_source.source_id) {
289 case S5P_PWM0: 289 case SAMSUNG_PWM0:
290 case S5P_PWM1: 290 case SAMSUNG_PWM1:
291 case S5P_PWM2: 291 case SAMSUNG_PWM2:
292 case S5P_PWM3: 292 case SAMSUNG_PWM3:
293 offset = (timer_source.source_id * 0x0c) + 0x14; 293 offset = (timer_source.source_id * 0x0c) + 0x14;
294 break; 294 break;
295 295
296 case S5P_PWM4: 296 case SAMSUNG_PWM4:
297 offset = 0x40; 297 offset = 0x40;
298 break; 298 break;
299 299
@@ -312,9 +312,9 @@ static void __iomem *s5p_timer_reg(void)
312 * this wraps around for now, since it is just a relative time 312 * this wraps around for now, since it is just a relative time
313 * stamp. (Inspired by U300 implementation.) 313 * stamp. (Inspired by U300 implementation.)
314 */ 314 */
315static u32 notrace s5p_read_sched_clock(void) 315static u32 notrace samsung_read_sched_clock(void)
316{ 316{
317 void __iomem *reg = s5p_timer_reg(); 317 void __iomem *reg = samsung_timer_reg();
318 318
319 if (!reg) 319 if (!reg)
320 return 0; 320 return 0;
@@ -322,29 +322,29 @@ static u32 notrace s5p_read_sched_clock(void)
322 return ~__raw_readl(reg); 322 return ~__raw_readl(reg);
323} 323}
324 324
325static void __init s5p_clocksource_init(void) 325static void __init samsung_clocksource_init(void)
326{ 326{
327 unsigned long pclk; 327 unsigned long pclk;
328 unsigned long clock_rate; 328 unsigned long clock_rate;
329 329
330 pclk = clk_get_rate(timerclk); 330 pclk = clk_get_rate(timerclk);
331 331
332 clk_set_rate(tdiv_source, pclk / 2); 332 clk_set_rate(tdiv_source, pclk / TDIV);
333 clk_set_parent(tin_source, tdiv_source); 333 clk_set_parent(tin_source, tdiv_source);
334 334
335 clock_rate = clk_get_rate(tin_source); 335 clock_rate = clk_get_rate(tin_source);
336 336
337 s5p_time_setup(timer_source.source_id, TCNT_MAX); 337 samsung_time_setup(timer_source.source_id, TCNT_MAX);
338 s5p_time_start(timer_source.source_id, PERIODIC); 338 samsung_time_start(timer_source.source_id, PERIODIC);
339 339
340 setup_sched_clock(s5p_read_sched_clock, 32, clock_rate); 340 setup_sched_clock(samsung_read_sched_clock, TSIZE, clock_rate);
341 341
342 if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer", 342 if (clocksource_mmio_init(samsung_timer_reg(), "samsung_clocksource_timer",
343 clock_rate, 250, 32, clocksource_mmio_readl_down)) 343 clock_rate, 250, TSIZE, clocksource_mmio_readl_down))
344 panic("s5p_clocksource_timer: can't register clocksource\n"); 344 panic("samsung_clocksource_timer: can't register clocksource\n");
345} 345}
346 346
347static void __init s5p_timer_resources(void) 347static void __init samsung_timer_resources(void)
348{ 348{
349 349
350 unsigned long event_id = timer_source.event_id; 350 unsigned long event_id = timer_source.event_id;
@@ -386,9 +386,9 @@ static void __init s5p_timer_resources(void)
386 clk_enable(tin_source); 386 clk_enable(tin_source);
387} 387}
388 388
389void __init s5p_timer_init(void) 389void __init samsung_timer_init(void)
390{ 390{
391 s5p_timer_resources(); 391 samsung_timer_resources();
392 s5p_clockevent_init(); 392 samsung_clockevent_init();
393 s5p_clocksource_init(); 393 samsung_clocksource_init();
394} 394}
diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c
deleted file mode 100644
index 73defd00c3e4..000000000000
--- a/arch/arm/plat-samsung/time.c
+++ /dev/null
@@ -1,287 +0,0 @@
1/* linux/arch/arm/plat-samsung/time.c
2 *
3 * Copyright (C) 2003-2005 Simtec Electronics
4 * Ben Dooks, <ben@simtec.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/sched.h>
23#include <linux/init.h>
24#include <linux/interrupt.h>
25#include <linux/irq.h>
26#include <linux/err.h>
27#include <linux/clk.h>
28#include <linux/io.h>
29#include <linux/platform_device.h>
30#include <linux/syscore_ops.h>
31
32#include <asm/mach-types.h>
33
34#include <asm/irq.h>
35#include <mach/map.h>
36#include <plat/regs-timer.h>
37#include <mach/regs-irq.h>
38#include <asm/mach/time.h>
39#include <mach/tick.h>
40
41#include <plat/clock.h>
42#include <plat/cpu.h>
43
44static unsigned long timer_startval;
45static unsigned long timer_usec_ticks;
46
47#ifndef TICK_MAX
48#define TICK_MAX (0xffff)
49#endif
50
51#define TIMER_USEC_SHIFT 16
52
53/* we use the shifted arithmetic to work out the ratio of timer ticks
54 * to usecs, as often the peripheral clock is not a nice even multiple
55 * of 1MHz.
56 *
57 * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok
58 * for the current HZ value of 200 without producing overflows.
59 *
60 * Original patch by Dimitry Andric, updated by Ben Dooks
61*/
62
63
64/* timer_mask_usec_ticks
65 *
66 * given a clock and divisor, make the value to pass into timer_ticks_to_usec
67 * to scale the ticks into usecs
68*/
69
70static inline unsigned long
71timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk)
72{
73 unsigned long den = pclk / 1000;
74
75 return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den;
76}
77
78/* timer_ticks_to_usec
79 *
80 * convert timer ticks to usec.
81*/
82
83static inline unsigned long timer_ticks_to_usec(unsigned long ticks)
84{
85 unsigned long res;
86
87 res = ticks * timer_usec_ticks;
88 res += 1 << (TIMER_USEC_SHIFT - 4); /* round up slightly */
89
90 return res >> TIMER_USEC_SHIFT;
91}
92
93/***
94 * Returns microsecond since last clock interrupt. Note that interrupts
95 * will have been disabled by do_gettimeoffset()
96 * IRQs are disabled before entering here from do_gettimeofday()
97 */
98
99static u32 s3c2410_gettimeoffset(void)
100{
101 unsigned long tdone;
102 unsigned long tval;
103
104 /* work out how many ticks have gone since last timer interrupt */
105
106 tval = __raw_readl(S3C2410_TCNTO(4));
107 tdone = timer_startval - tval;
108
109 /* check to see if there is an interrupt pending */
110
111 if (s3c24xx_ostimer_pending()) {
112 /* re-read the timer, and try and fix up for the missed
113 * interrupt. Note, the interrupt may go off before the
114 * timer has re-loaded from wrapping.
115 */
116
117 tval = __raw_readl(S3C2410_TCNTO(4));
118 tdone = timer_startval - tval;
119
120 if (tval != 0)
121 tdone += timer_startval;
122 }
123
124 return timer_ticks_to_usec(tdone) * 1000;
125}
126
127
128/*
129 * IRQ handler for the timer
130 */
131static irqreturn_t
132s3c2410_timer_interrupt(int irq, void *dev_id)
133{
134 timer_tick();
135 return IRQ_HANDLED;
136}
137
138static struct irqaction s3c2410_timer_irq = {
139 .name = "S3C2410 Timer Tick",
140 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
141 .handler = s3c2410_timer_interrupt,
142};
143
144#define use_tclk1_12() ( \
145 machine_is_bast() || \
146 machine_is_vr1000() || \
147 machine_is_anubis() || \
148 machine_is_osiris())
149
150static struct clk *tin;
151static struct clk *tdiv;
152static struct clk *timerclk;
153
154/*
155 * Set up timer interrupt, and return the current time in seconds.
156 *
157 * Currently we only use timer4, as it is the only timer which has no
158 * other function that can be exploited externally
159 */
160static void s3c2410_timer_setup (void)
161{
162 unsigned long tcon;
163 unsigned long tcnt;
164 unsigned long tcfg1;
165 unsigned long tcfg0;
166
167 tcnt = TICK_MAX; /* default value for tcnt */
168
169 /* configure the system for whichever machine is in use */
170
171 if (use_tclk1_12()) {
172 /* timer is at 12MHz, scaler is 1 */
173 timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
174 tcnt = 12000000 / HZ;
175
176 tcfg1 = __raw_readl(S3C2410_TCFG1);
177 tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
178 tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
179 __raw_writel(tcfg1, S3C2410_TCFG1);
180 } else {
181 unsigned long pclk;
182 struct clk *tscaler;
183
184 /* for the h1940 (and others), we use the pclk from the core
185 * to generate the timer values. since values around 50 to
186 * 70MHz are not values we can directly generate the timer
187 * value from, we need to pre-scale and divide before using it.
188 *
189 * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz
190 * (8.45 ticks per usec)
191 */
192
193 pclk = clk_get_rate(timerclk);
194
195 /* configure clock tick */
196
197 timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
198
199 tscaler = clk_get_parent(tdiv);
200
201 clk_set_rate(tscaler, pclk / 3);
202 clk_set_rate(tdiv, pclk / 6);
203 clk_set_parent(tin, tdiv);
204
205 tcnt = clk_get_rate(tin) / HZ;
206 }
207
208 tcon = __raw_readl(S3C2410_TCON);
209 tcfg0 = __raw_readl(S3C2410_TCFG0);
210 tcfg1 = __raw_readl(S3C2410_TCFG1);
211
212 /* timers reload after counting zero, so reduce the count by 1 */
213
214 tcnt--;
215
216 printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n",
217 tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
218
219 /* check to see if timer is within 16bit range... */
220 if (tcnt > TICK_MAX) {
221 panic("setup_timer: HZ is too small, cannot configure timer!");
222 return;
223 }
224
225 __raw_writel(tcfg1, S3C2410_TCFG1);
226 __raw_writel(tcfg0, S3C2410_TCFG0);
227
228 timer_startval = tcnt;
229 __raw_writel(tcnt, S3C2410_TCNTB(4));
230
231 /* ensure timer is stopped... */
232
233 tcon &= ~(7<<20);
234 tcon |= S3C2410_TCON_T4RELOAD;
235 tcon |= S3C2410_TCON_T4MANUALUPD;
236
237 __raw_writel(tcon, S3C2410_TCON);
238 __raw_writel(tcnt, S3C2410_TCNTB(4));
239 __raw_writel(tcnt, S3C2410_TCMPB(4));
240
241 /* start the timer running */
242 tcon |= S3C2410_TCON_T4START;
243 tcon &= ~S3C2410_TCON_T4MANUALUPD;
244 __raw_writel(tcon, S3C2410_TCON);
245}
246
247static void __init s3c2410_timer_resources(void)
248{
249 struct platform_device tmpdev;
250
251 tmpdev.dev.bus = &platform_bus_type;
252 tmpdev.id = 4;
253
254 timerclk = clk_get(NULL, "timers");
255 if (IS_ERR(timerclk))
256 panic("failed to get clock for system timer");
257
258 clk_enable(timerclk);
259
260 if (!use_tclk1_12()) {
261 tmpdev.id = 4;
262 tmpdev.dev.init_name = "s3c24xx-pwm.4";
263 tin = clk_get(&tmpdev.dev, "pwm-tin");
264 if (IS_ERR(tin))
265 panic("failed to get pwm-tin clock for system timer");
266
267 tdiv = clk_get(&tmpdev.dev, "pwm-tdiv");
268 if (IS_ERR(tdiv))
269 panic("failed to get pwm-tdiv clock for system timer");
270 }
271
272 clk_enable(tin);
273}
274
275static struct syscore_ops s3c24xx_syscore_ops = {
276 .resume = s3c2410_timer_setup,
277};
278
279void __init s3c24xx_timer_init(void)
280{
281 arch_gettimeoffset = s3c2410_gettimeoffset;
282
283 s3c2410_timer_resources();
284 s3c2410_timer_setup();
285 setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
286 register_syscore_ops(&s3c24xx_syscore_ops);
287}