aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/altera/socfpga-reset.txt11
-rw-r--r--Documentation/devicetree/bindings/arm/altera/socfpga-system.txt11
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi27
-rw-r--r--arch/arm/boot/dts/socfpga.dtsi10
-rw-r--r--arch/arm/configs/socfpga_defconfig3
-rw-r--r--arch/arm/mach-exynos/clock-exynos5.c28
-rw-r--r--arch/arm/mach-exynos/cpuidle.c36
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-clock.h19
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-pmu.h3
-rw-r--r--arch/arm/mach-exynos/mach-exynos5-dt.c25
-rw-r--r--arch/arm/mach-exynos/pm.c9
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c20
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h2
-rw-r--r--arch/arm/mach-shmobile/smp-emev2.c22
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7779.c25
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c23
-rw-r--r--arch/arm/mach-socfpga/Kconfig1
-rw-r--r--arch/arm/mach-socfpga/Makefile1
-rw-r--r--arch/arm/mach-socfpga/core.h34
-rw-r--r--arch/arm/mach-socfpga/headsmp.S25
-rw-r--r--arch/arm/mach-socfpga/platsmp.c116
-rw-r--r--arch/arm/mach-socfpga/socfpga.c54
-rw-r--r--arch/arm/plat-samsung/clock.c75
-rw-r--r--drivers/sh/clk/cpg.c1
24 files changed, 544 insertions, 37 deletions
diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-reset.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-reset.txt
new file mode 100644
index 000000000000..ecdb57d69dbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/altera/socfpga-reset.txt
@@ -0,0 +1,11 @@
1Altera SOCFPGA Reset Manager
2
3Required properties:
4- compatible : "altr,rst-mgr"
5- reg : Should contain 1 register ranges(address and length)
6
7Example:
8 rstmgr@ffd05000 {
9 compatible = "altr,rst-mgr";
10 reg = <0xffd05000 0x1000>;
11 };
diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
new file mode 100644
index 000000000000..07c65e3cdcbe
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
@@ -0,0 +1,11 @@
1Altera SOCFPGA System Manager
2
3Required properties:
4- compatible : "altr,sys-mgr"
5- reg : Should contain 1 register ranges(address and length)
6
7Example:
8 sysmgr@ffd08000 {
9 compatible = "altr,sys-mgr";
10 reg = <0xffd08000 0x1000>;
11 };
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 36d8246ea50e..2e3b6efaf1a2 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -35,6 +35,15 @@
35 mshc1 = &dwmmc_1; 35 mshc1 = &dwmmc_1;
36 mshc2 = &dwmmc_2; 36 mshc2 = &dwmmc_2;
37 mshc3 = &dwmmc_3; 37 mshc3 = &dwmmc_3;
38 i2c0 = &i2c_0;
39 i2c1 = &i2c_1;
40 i2c2 = &i2c_2;
41 i2c3 = &i2c_3;
42 i2c4 = &i2c_4;
43 i2c5 = &i2c_5;
44 i2c6 = &i2c_6;
45 i2c7 = &i2c_7;
46 i2c8 = &i2c_8;
38 }; 47 };
39 48
40 gic:interrupt-controller@10481000 { 49 gic:interrupt-controller@10481000 {
@@ -119,7 +128,7 @@
119 reg = <0x12170000 0x1ff>; 128 reg = <0x12170000 0x1ff>;
120 }; 129 };
121 130
122 i2c@12C60000 { 131 i2c_0: i2c@12C60000 {
123 compatible = "samsung,s3c2440-i2c"; 132 compatible = "samsung,s3c2440-i2c";
124 reg = <0x12C60000 0x100>; 133 reg = <0x12C60000 0x100>;
125 interrupts = <0 56 0>; 134 interrupts = <0 56 0>;
@@ -127,7 +136,7 @@
127 #size-cells = <0>; 136 #size-cells = <0>;
128 }; 137 };
129 138
130 i2c@12C70000 { 139 i2c_1: i2c@12C70000 {
131 compatible = "samsung,s3c2440-i2c"; 140 compatible = "samsung,s3c2440-i2c";
132 reg = <0x12C70000 0x100>; 141 reg = <0x12C70000 0x100>;
133 interrupts = <0 57 0>; 142 interrupts = <0 57 0>;
@@ -135,7 +144,7 @@
135 #size-cells = <0>; 144 #size-cells = <0>;
136 }; 145 };
137 146
138 i2c@12C80000 { 147 i2c_2: i2c@12C80000 {
139 compatible = "samsung,s3c2440-i2c"; 148 compatible = "samsung,s3c2440-i2c";
140 reg = <0x12C80000 0x100>; 149 reg = <0x12C80000 0x100>;
141 interrupts = <0 58 0>; 150 interrupts = <0 58 0>;
@@ -143,7 +152,7 @@
143 #size-cells = <0>; 152 #size-cells = <0>;
144 }; 153 };
145 154
146 i2c@12C90000 { 155 i2c_3: i2c@12C90000 {
147 compatible = "samsung,s3c2440-i2c"; 156 compatible = "samsung,s3c2440-i2c";
148 reg = <0x12C90000 0x100>; 157 reg = <0x12C90000 0x100>;
149 interrupts = <0 59 0>; 158 interrupts = <0 59 0>;
@@ -151,7 +160,7 @@
151 #size-cells = <0>; 160 #size-cells = <0>;
152 }; 161 };
153 162
154 i2c@12CA0000 { 163 i2c_4: i2c@12CA0000 {
155 compatible = "samsung,s3c2440-i2c"; 164 compatible = "samsung,s3c2440-i2c";
156 reg = <0x12CA0000 0x100>; 165 reg = <0x12CA0000 0x100>;
157 interrupts = <0 60 0>; 166 interrupts = <0 60 0>;
@@ -159,7 +168,7 @@
159 #size-cells = <0>; 168 #size-cells = <0>;
160 }; 169 };
161 170
162 i2c@12CB0000 { 171 i2c_5: i2c@12CB0000 {
163 compatible = "samsung,s3c2440-i2c"; 172 compatible = "samsung,s3c2440-i2c";
164 reg = <0x12CB0000 0x100>; 173 reg = <0x12CB0000 0x100>;
165 interrupts = <0 61 0>; 174 interrupts = <0 61 0>;
@@ -167,7 +176,7 @@
167 #size-cells = <0>; 176 #size-cells = <0>;
168 }; 177 };
169 178
170 i2c@12CC0000 { 179 i2c_6: i2c@12CC0000 {
171 compatible = "samsung,s3c2440-i2c"; 180 compatible = "samsung,s3c2440-i2c";
172 reg = <0x12CC0000 0x100>; 181 reg = <0x12CC0000 0x100>;
173 interrupts = <0 62 0>; 182 interrupts = <0 62 0>;
@@ -175,7 +184,7 @@
175 #size-cells = <0>; 184 #size-cells = <0>;
176 }; 185 };
177 186
178 i2c@12CD0000 { 187 i2c_7: i2c@12CD0000 {
179 compatible = "samsung,s3c2440-i2c"; 188 compatible = "samsung,s3c2440-i2c";
180 reg = <0x12CD0000 0x100>; 189 reg = <0x12CD0000 0x100>;
181 interrupts = <0 63 0>; 190 interrupts = <0 63 0>;
@@ -183,7 +192,7 @@
183 #size-cells = <0>; 192 #size-cells = <0>;
184 }; 193 };
185 194
186 i2c@12CE0000 { 195 i2c_8: i2c@12CE0000 {
187 compatible = "samsung,s3c2440-hdmiphy-i2c"; 196 compatible = "samsung,s3c2440-hdmiphy-i2c";
188 reg = <0x12CE0000 0x1000>; 197 reg = <0x12CE0000 0x1000>;
189 interrupts = <0 64 0>; 198 interrupts = <0 64 0>;
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 0772f5739f59..19aec421bb26 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -143,5 +143,15 @@
143 reg-shift = <2>; 143 reg-shift = <2>;
144 reg-io-width = <4>; 144 reg-io-width = <4>;
145 }; 145 };
146
147 rstmgr@ffd05000 {
148 compatible = "altr,rst-mgr";
149 reg = <0xffd05000 0x1000>;
150 };
151
152 sysmgr@ffd08000 {
153 compatible = "altr,sys-mgr";
154 reg = <0xffd08000 0x4000>;
155 };
146 }; 156 };
147}; 157};
diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig
index 0ac1293dba10..4e1ce211d43f 100644
--- a/arch/arm/configs/socfpga_defconfig
+++ b/arch/arm/configs/socfpga_defconfig
@@ -18,9 +18,10 @@ CONFIG_MODULE_UNLOAD=y
18CONFIG_ARCH_SOCFPGA=y 18CONFIG_ARCH_SOCFPGA=y
19CONFIG_MACH_SOCFPGA_CYCLONE5=y 19CONFIG_MACH_SOCFPGA_CYCLONE5=y
20CONFIG_ARM_THUMBEE=y 20CONFIG_ARM_THUMBEE=y
21# CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA is not set
21# CONFIG_CACHE_L2X0 is not set 22# CONFIG_CACHE_L2X0 is not set
22CONFIG_HIGH_RES_TIMERS=y 23CONFIG_HIGH_RES_TIMERS=y
23CONFIG_VMSPLIT_2G=y 24CONFIG_SMP=y
24CONFIG_NR_CPUS=2 25CONFIG_NR_CPUS=2
25CONFIG_AEABI=y 26CONFIG_AEABI=y
26CONFIG_ZBOOT_ROM_TEXT=0x0 27CONFIG_ZBOOT_ROM_TEXT=0x0
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c
index 7652f5d78a56..e9d7b80bae49 100644
--- a/arch/arm/mach-exynos/clock-exynos5.c
+++ b/arch/arm/mach-exynos/clock-exynos5.c
@@ -80,6 +80,8 @@ static struct sleep_save exynos5_clock_save[] = {
80 SAVE_ITEM(EXYNOS5_VPLL_CON0), 80 SAVE_ITEM(EXYNOS5_VPLL_CON0),
81 SAVE_ITEM(EXYNOS5_VPLL_CON1), 81 SAVE_ITEM(EXYNOS5_VPLL_CON1),
82 SAVE_ITEM(EXYNOS5_VPLL_CON2), 82 SAVE_ITEM(EXYNOS5_VPLL_CON2),
83 SAVE_ITEM(EXYNOS5_PWR_CTRL1),
84 SAVE_ITEM(EXYNOS5_PWR_CTRL2),
83}; 85};
84#endif 86#endif
85 87
@@ -661,15 +663,20 @@ static struct clk exynos5_init_clocks_off[] = {
661 .ctrlbit = (1 << 15), 663 .ctrlbit = (1 << 15),
662 }, { 664 }, {
663 .name = "sata", 665 .name = "sata",
664 .devname = "ahci", 666 .devname = "exynos5-sata",
667 .parent = &exynos5_clk_aclk_200.clk,
665 .enable = exynos5_clk_ip_fsys_ctrl, 668 .enable = exynos5_clk_ip_fsys_ctrl,
666 .ctrlbit = (1 << 6), 669 .ctrlbit = (1 << 6),
667 }, { 670 }, {
668 .name = "sata_phy", 671 .name = "sata-phy",
672 .devname = "exynos5-sata-phy",
673 .parent = &exynos5_clk_aclk_200.clk,
669 .enable = exynos5_clk_ip_fsys_ctrl, 674 .enable = exynos5_clk_ip_fsys_ctrl,
670 .ctrlbit = (1 << 24), 675 .ctrlbit = (1 << 24),
671 }, { 676 }, {
672 .name = "sata_phy_i2c", 677 .name = "i2c",
678 .devname = "exynos5-sata-phy-i2c",
679 .parent = &exynos5_clk_aclk_200.clk,
673 .enable = exynos5_clk_ip_fsys_ctrl, 680 .enable = exynos5_clk_ip_fsys_ctrl,
674 .ctrlbit = (1 << 25), 681 .ctrlbit = (1 << 25),
675 }, { 682 }, {
@@ -693,6 +700,11 @@ static struct clk exynos5_init_clocks_off[] = {
693 .enable = exynos5_clk_ip_disp1_ctrl, 700 .enable = exynos5_clk_ip_disp1_ctrl,
694 .ctrlbit = (1 << 5), 701 .ctrlbit = (1 << 5),
695 }, { 702 }, {
703 .name = "dp",
704 .devname = "exynos-dp",
705 .enable = exynos5_clk_ip_disp1_ctrl,
706 .ctrlbit = (1 << 4),
707 }, {
696 .name = "jpeg", 708 .name = "jpeg",
697 .enable = exynos5_clk_ip_gen_ctrl, 709 .enable = exynos5_clk_ip_gen_ctrl,
698 .ctrlbit = (1 << 2), 710 .ctrlbit = (1 << 2),
@@ -1241,6 +1253,16 @@ static struct clksrc_clk exynos5_clksrcs[] = {
1241 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 }, 1253 .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
1242 }, { 1254 }, {
1243 .clk = { 1255 .clk = {
1256 .name = "sclk_sata",
1257 .devname = "exynos5-sata",
1258 .enable = exynos5_clksrc_mask_fsys_ctrl,
1259 .ctrlbit = (1 << 24),
1260 },
1261 .sources = &exynos5_clkset_aclk,
1262 .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 24, .size = 1 },
1263 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS0, .shift = 20, .size = 4 },
1264 }, {
1265 .clk = {
1244 .name = "sclk_gscl_wrap", 1266 .name = "sclk_gscl_wrap",
1245 .devname = "s5p-mipi-csis.0", 1267 .devname = "s5p-mipi-csis.0",
1246 .enable = exynos5_clksrc_mask_gscl_ctrl, 1268 .enable = exynos5_clksrc_mask_gscl_ctrl,
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c
index 8e4ec21ef2cf..050924152776 100644
--- a/arch/arm/mach-exynos/cpuidle.c
+++ b/arch/arm/mach-exynos/cpuidle.c
@@ -21,6 +21,7 @@
21#include <asm/suspend.h> 21#include <asm/suspend.h>
22#include <asm/unified.h> 22#include <asm/unified.h>
23#include <asm/cpuidle.h> 23#include <asm/cpuidle.h>
24#include <mach/regs-clock.h>
24#include <mach/regs-pmu.h> 25#include <mach/regs-pmu.h>
25#include <mach/pmu.h> 26#include <mach/pmu.h>
26 27
@@ -157,12 +158,47 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev,
157 return exynos4_enter_core0_aftr(dev, drv, new_index); 158 return exynos4_enter_core0_aftr(dev, drv, new_index);
158} 159}
159 160
161static void __init exynos5_core_down_clk(void)
162{
163 unsigned int tmp;
164
165 /*
166 * Enable arm clock down (in idle) and set arm divider
167 * ratios in WFI/WFE state.
168 */
169 tmp = PWR_CTRL1_CORE2_DOWN_RATIO | \
170 PWR_CTRL1_CORE1_DOWN_RATIO | \
171 PWR_CTRL1_DIV2_DOWN_EN | \
172 PWR_CTRL1_DIV1_DOWN_EN | \
173 PWR_CTRL1_USE_CORE1_WFE | \
174 PWR_CTRL1_USE_CORE0_WFE | \
175 PWR_CTRL1_USE_CORE1_WFI | \
176 PWR_CTRL1_USE_CORE0_WFI;
177 __raw_writel(tmp, EXYNOS5_PWR_CTRL1);
178
179 /*
180 * Enable arm clock up (on exiting idle). Set arm divider
181 * ratios when not in idle along with the standby duration
182 * ratios.
183 */
184 tmp = PWR_CTRL2_DIV2_UP_EN | \
185 PWR_CTRL2_DIV1_UP_EN | \
186 PWR_CTRL2_DUR_STANDBY2_VAL | \
187 PWR_CTRL2_DUR_STANDBY1_VAL | \
188 PWR_CTRL2_CORE2_UP_RATIO | \
189 PWR_CTRL2_CORE1_UP_RATIO;
190 __raw_writel(tmp, EXYNOS5_PWR_CTRL2);
191}
192
160static int __init exynos4_init_cpuidle(void) 193static int __init exynos4_init_cpuidle(void)
161{ 194{
162 int i, max_cpuidle_state, cpu_id; 195 int i, max_cpuidle_state, cpu_id;
163 struct cpuidle_device *device; 196 struct cpuidle_device *device;
164 struct cpuidle_driver *drv = &exynos4_idle_driver; 197 struct cpuidle_driver *drv = &exynos4_idle_driver;
165 198
199 if (soc_is_exynos5250())
200 exynos5_core_down_clk();
201
166 /* Setup cpuidle driver */ 202 /* Setup cpuidle driver */
167 drv->state_count = (sizeof(exynos4_cpuidle_set) / 203 drv->state_count = (sizeof(exynos4_cpuidle_set) /
168 sizeof(struct cpuidle_state)); 204 sizeof(struct cpuidle_state));
diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h
index 8c9b38c9c504..d36ad76ad6a4 100644
--- a/arch/arm/mach-exynos/include/mach/regs-clock.h
+++ b/arch/arm/mach-exynos/include/mach/regs-clock.h
@@ -267,6 +267,9 @@
267#define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600) 267#define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600)
268#define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604) 268#define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604)
269 269
270#define EXYNOS5_PWR_CTRL1 EXYNOS_CLKREG(0x01020)
271#define EXYNOS5_PWR_CTRL2 EXYNOS_CLKREG(0x01024)
272
270#define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100) 273#define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100)
271#define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204) 274#define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204)
272 275
@@ -344,6 +347,22 @@
344 347
345#define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) 348#define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29)
346 349
350#define PWR_CTRL1_CORE2_DOWN_RATIO (7 << 28)
351#define PWR_CTRL1_CORE1_DOWN_RATIO (7 << 16)
352#define PWR_CTRL1_DIV2_DOWN_EN (1 << 9)
353#define PWR_CTRL1_DIV1_DOWN_EN (1 << 8)
354#define PWR_CTRL1_USE_CORE1_WFE (1 << 5)
355#define PWR_CTRL1_USE_CORE0_WFE (1 << 4)
356#define PWR_CTRL1_USE_CORE1_WFI (1 << 1)
357#define PWR_CTRL1_USE_CORE0_WFI (1 << 0)
358
359#define PWR_CTRL2_DIV2_UP_EN (1 << 25)
360#define PWR_CTRL2_DIV1_UP_EN (1 << 24)
361#define PWR_CTRL2_DUR_STANDBY2_VAL (1 << 16)
362#define PWR_CTRL2_DUR_STANDBY1_VAL (1 << 8)
363#define PWR_CTRL2_CORE2_UP_RATIO (1 << 4)
364#define PWR_CTRL2_CORE1_UP_RATIO (1 << 0)
365
347/* Compatibility defines and inclusion */ 366/* Compatibility defines and inclusion */
348 367
349#include <mach/regs-pmu.h> 368#include <mach/regs-pmu.h>
diff --git a/arch/arm/mach-exynos/include/mach/regs-pmu.h b/arch/arm/mach-exynos/include/mach/regs-pmu.h
index 84428e72cf5e..3f30aa1ae354 100644
--- a/arch/arm/mach-exynos/include/mach/regs-pmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-pmu.h
@@ -15,6 +15,7 @@
15#include <mach/map.h> 15#include <mach/map.h>
16 16
17#define S5P_PMUREG(x) (S5P_VA_PMU + (x)) 17#define S5P_PMUREG(x) (S5P_VA_PMU + (x))
18#define S5P_SYSREG(x) (S3C_VA_SYS + (x))
18 19
19#define S5P_CENTRAL_SEQ_CONFIGURATION S5P_PMUREG(0x0200) 20#define S5P_CENTRAL_SEQ_CONFIGURATION S5P_PMUREG(0x0200)
20 21
@@ -231,6 +232,8 @@
231 232
232/* For EXYNOS5 */ 233/* For EXYNOS5 */
233 234
235#define EXYNOS5_SYS_I2C_CFG S5P_SYSREG(0x0234)
236
234#define EXYNOS5_AUTO_WDTRESET_DISABLE S5P_PMUREG(0x0408) 237#define EXYNOS5_AUTO_WDTRESET_DISABLE S5P_PMUREG(0x0408)
235#define EXYNOS5_MASK_WDTRESET_REQUEST S5P_PMUREG(0x040C) 238#define EXYNOS5_MASK_WDTRESET_REQUEST S5P_PMUREG(0x040C)
236 239
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index 929de766d490..f038c8cadca4 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -13,11 +13,12 @@
13#include <linux/of_fdt.h> 13#include <linux/of_fdt.h>
14#include <linux/serial_core.h> 14#include <linux/serial_core.h>
15#include <linux/memblock.h> 15#include <linux/memblock.h>
16#include <linux/of_fdt.h> 16#include <linux/io.h>
17 17
18#include <asm/mach/arch.h> 18#include <asm/mach/arch.h>
19#include <asm/hardware/gic.h> 19#include <asm/hardware/gic.h>
20#include <mach/map.h> 20#include <mach/map.h>
21#include <mach/regs-pmu.h>
21 22
22#include <plat/cpu.h> 23#include <plat/cpu.h>
23#include <plat/regs-serial.h> 24#include <plat/regs-serial.h>
@@ -124,6 +125,28 @@ static void __init exynos5_dt_map_io(void)
124 125
125static void __init exynos5_dt_machine_init(void) 126static void __init exynos5_dt_machine_init(void)
126{ 127{
128 struct device_node *i2c_np;
129 const char *i2c_compat = "samsung,s3c2440-i2c";
130 unsigned int tmp;
131
132 /*
133 * Exynos5's legacy i2c controller and new high speed i2c
134 * controller have muxed interrupt sources. By default the
135 * interrupts for 4-channel HS-I2C controller are enabled.
136 * If node for first four channels of legacy i2c controller
137 * are available then re-configure the interrupts via the
138 * system register.
139 */
140 for_each_compatible_node(i2c_np, NULL, i2c_compat) {
141 if (of_device_is_available(i2c_np)) {
142 if (of_alias_get_id(i2c_np, "i2c") < 4) {
143 tmp = readl(EXYNOS5_SYS_I2C_CFG);
144 writel(tmp & ~(0x1 << of_alias_get_id(i2c_np, "i2c")),
145 EXYNOS5_SYS_I2C_CFG);
146 }
147 }
148 }
149
127 if (of_machine_is_compatible("samsung,exynos5250")) 150 if (of_machine_is_compatible("samsung,exynos5250"))
128 of_platform_populate(NULL, of_default_bus_match_table, 151 of_platform_populate(NULL, of_default_bus_match_table,
129 exynos5250_auxdata_lookup, NULL); 152 exynos5250_auxdata_lookup, NULL);
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 8df6ec547f78..b9b539cac81e 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -62,6 +62,10 @@ static struct sleep_save exynos4_vpll_save[] = {
62 SAVE_ITEM(EXYNOS4_VPLL_CON1), 62 SAVE_ITEM(EXYNOS4_VPLL_CON1),
63}; 63};
64 64
65static struct sleep_save exynos5_sys_save[] = {
66 SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
67};
68
65static struct sleep_save exynos_core_save[] = { 69static struct sleep_save exynos_core_save[] = {
66 /* SROM side */ 70 /* SROM side */
67 SAVE_ITEM(S5P_SROM_BW), 71 SAVE_ITEM(S5P_SROM_BW),
@@ -101,6 +105,7 @@ static void exynos_pm_prepare(void)
101 s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save)); 105 s3c_pm_do_save(exynos4_epll_save, ARRAY_SIZE(exynos4_epll_save));
102 s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save)); 106 s3c_pm_do_save(exynos4_vpll_save, ARRAY_SIZE(exynos4_vpll_save));
103 } else { 107 } else {
108 s3c_pm_do_save(exynos5_sys_save, ARRAY_SIZE(exynos5_sys_save));
104 /* Disable USE_RETENTION of JPEG_MEM_OPTION */ 109 /* Disable USE_RETENTION of JPEG_MEM_OPTION */
105 tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION); 110 tmp = __raw_readl(EXYNOS5_JPEG_MEM_OPTION);
106 tmp &= ~EXYNOS5_OPTION_USE_RETENTION; 111 tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
@@ -304,6 +309,10 @@ static void exynos_pm_resume(void)
304 __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION); 309 __raw_writel((1 << 28), S5P_PAD_RET_EBIA_OPTION);
305 __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION); 310 __raw_writel((1 << 28), S5P_PAD_RET_EBIB_OPTION);
306 311
312 if (soc_is_exynos5250())
313 s3c_pm_do_restore(exynos5_sys_save,
314 ARRAY_SIZE(exynos5_sys_save));
315
307 s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); 316 s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
308 317
309 if (!soc_is_exynos5250()) { 318 if (!soc_is_exynos5250()) {
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 4d57e342537b..3ca6757b129a 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -295,10 +295,10 @@ struct clk sh7372_pllc2_clk = {
295}; 295};
296 296
297/* External input clock (pin name: FSIACK/FSIBCK ) */ 297/* External input clock (pin name: FSIACK/FSIBCK ) */
298struct clk sh7372_fsiack_clk = { 298static struct clk fsiack_clk = {
299}; 299};
300 300
301struct clk sh7372_fsibck_clk = { 301static struct clk fsibck_clk = {
302}; 302};
303 303
304static struct clk *main_clks[] = { 304static struct clk *main_clks[] = {
@@ -314,8 +314,8 @@ static struct clk *main_clks[] = {
314 &pllc1_clk, 314 &pllc1_clk,
315 &pllc1_div2_clk, 315 &pllc1_div2_clk,
316 &sh7372_pllc2_clk, 316 &sh7372_pllc2_clk,
317 &sh7372_fsiack_clk, 317 &fsiack_clk,
318 &sh7372_fsibck_clk, 318 &fsibck_clk,
319}; 319};
320 320
321static void div4_kick(struct clk *clk) 321static void div4_kick(struct clk *clk)
@@ -399,14 +399,14 @@ static struct clk *hdmi_parent[] = {
399static struct clk *fsiackcr_parent[] = { 399static struct clk *fsiackcr_parent[] = {
400 [0] = &pllc1_div2_clk, 400 [0] = &pllc1_div2_clk,
401 [1] = &sh7372_pllc2_clk, 401 [1] = &sh7372_pllc2_clk,
402 [2] = &sh7372_fsiack_clk, /* external input for FSI A */ 402 [2] = &fsiack_clk, /* external input for FSI A */
403 [3] = NULL, /* setting prohibited */ 403 [3] = NULL, /* setting prohibited */
404}; 404};
405 405
406static struct clk *fsibckcr_parent[] = { 406static struct clk *fsibckcr_parent[] = {
407 [0] = &pllc1_div2_clk, 407 [0] = &pllc1_div2_clk,
408 [1] = &sh7372_pllc2_clk, 408 [1] = &sh7372_pllc2_clk,
409 [2] = &sh7372_fsibck_clk, /* external input for FSI B */ 409 [2] = &fsibck_clk, /* external input for FSI B */
410 [3] = NULL, /* setting prohibited */ 410 [3] = NULL, /* setting prohibited */
411}; 411};
412 412
@@ -507,8 +507,8 @@ static struct clk_lookup lookups[] = {
507 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), 507 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
508 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), 508 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
509 CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk), 509 CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
510 CLKDEV_CON_ID("fsidiva", &fsidivs[FSIDIV_A]), 510 CLKDEV_CON_ID("fsiack", &fsiack_clk),
511 CLKDEV_CON_ID("fsidivb", &fsidivs[FSIDIV_B]), 511 CLKDEV_CON_ID("fsibck", &fsibck_clk),
512 512
513 /* DIV4 clocks */ 513 /* DIV4 clocks */
514 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), 514 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
@@ -606,8 +606,8 @@ static struct clk_lookup lookups[] = {
606 CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]), 606 CLKDEV_ICK_ID("spu2", "sh_fsi2", &mstp_clks[MSTP223]),
607 CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]), 607 CLKDEV_ICK_ID("diva", "sh_fsi2", &fsidivs[FSIDIV_A]),
608 CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]), 608 CLKDEV_ICK_ID("divb", "sh_fsi2", &fsidivs[FSIDIV_B]),
609 CLKDEV_ICK_ID("xcka", "sh_fsi2", &sh7372_fsiack_clk), 609 CLKDEV_ICK_ID("xcka", "sh_fsi2", &fsiack_clk),
610 CLKDEV_ICK_ID("xckb", "sh_fsi2", &sh7372_fsibck_clk), 610 CLKDEV_ICK_ID("xckb", "sh_fsi2", &fsibck_clk),
611}; 611};
612 612
613void __init sh7372_clock_init(void) 613void __init sh7372_clock_init(void)
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index 26cd1016fad8..b582facc1cf6 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -477,8 +477,6 @@ extern struct clk sh7372_extal2_clk;
477extern struct clk sh7372_dv_clki_clk; 477extern struct clk sh7372_dv_clki_clk;
478extern struct clk sh7372_dv_clki_div2_clk; 478extern struct clk sh7372_dv_clki_div2_clk;
479extern struct clk sh7372_pllc2_clk; 479extern struct clk sh7372_pllc2_clk;
480extern struct clk sh7372_fsiack_clk;
481extern struct clk sh7372_fsibck_clk;
482 480
483extern void sh7372_intcs_suspend(void); 481extern void sh7372_intcs_suspend(void);
484extern void sh7372_intcs_resume(void); 482extern void sh7372_intcs_resume(void);
diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c
index 535426c306bd..f67456286280 100644
--- a/arch/arm/mach-shmobile/smp-emev2.c
+++ b/arch/arm/mach-shmobile/smp-emev2.c
@@ -32,8 +32,24 @@
32 32
33#define EMEV2_SCU_BASE 0x1e000000 33#define EMEV2_SCU_BASE 0x1e000000
34 34
35static DEFINE_SPINLOCK(scu_lock);
35static void __iomem *scu_base; 36static void __iomem *scu_base;
36 37
38static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
39{
40 unsigned long tmp;
41
42 /* we assume this code is running on a different cpu
43 * than the one that is changing coherency setting */
44 spin_lock(&scu_lock);
45 tmp = readl(scu_base + 8);
46 tmp &= ~clr;
47 tmp |= set;
48 writel(tmp, scu_base + 8);
49 spin_unlock(&scu_lock);
50
51}
52
37static unsigned int __init emev2_get_core_count(void) 53static unsigned int __init emev2_get_core_count(void)
38{ 54{
39 if (!scu_base) { 55 if (!scu_base) {
@@ -79,7 +95,7 @@ static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *
79 cpu = cpu_logical_map(cpu); 95 cpu = cpu_logical_map(cpu);
80 96
81 /* enable cache coherency */ 97 /* enable cache coherency */
82 scu_power_mode(scu_base, 0); 98 modify_scu_cpu_psr(0, 3 << (cpu * 8));
83 99
84 /* Tell ROM loader about our vector (in headsmp.S) */ 100 /* Tell ROM loader about our vector (in headsmp.S) */
85 emev2_set_boot_vector(__pa(shmobile_secondary_vector)); 101 emev2_set_boot_vector(__pa(shmobile_secondary_vector));
@@ -90,10 +106,12 @@ static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *
90 106
91static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) 107static void __init emev2_smp_prepare_cpus(unsigned int max_cpus)
92{ 108{
109 int cpu = cpu_logical_map(0);
110
93 scu_enable(scu_base); 111 scu_enable(scu_base);
94 112
95 /* enable cache coherency on CPU0 */ 113 /* enable cache coherency on CPU0 */
96 scu_power_mode(scu_base, 0); 114 modify_scu_cpu_psr(0, 3 << (cpu * 8));
97} 115}
98 116
99static void __init emev2_smp_init_cpus(void) 117static void __init emev2_smp_init_cpus(void)
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
index 9def0f22bf22..2ce6af9a6a37 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -61,6 +61,9 @@ static void __iomem *scu_base_addr(void)
61 return (void __iomem *)0xf0000000; 61 return (void __iomem *)0xf0000000;
62} 62}
63 63
64static DEFINE_SPINLOCK(scu_lock);
65static unsigned long tmp;
66
64#ifdef CONFIG_HAVE_ARM_TWD 67#ifdef CONFIG_HAVE_ARM_TWD
65static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); 68static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
66 69
@@ -70,6 +73,20 @@ void __init r8a7779_register_twd(void)
70} 73}
71#endif 74#endif
72 75
76static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
77{
78 void __iomem *scu_base = scu_base_addr();
79
80 spin_lock(&scu_lock);
81 tmp = __raw_readl(scu_base + 8);
82 tmp &= ~clr;
83 tmp |= set;
84 spin_unlock(&scu_lock);
85
86 /* disable cache coherency after releasing the lock */
87 __raw_writel(tmp, scu_base + 8);
88}
89
73static unsigned int __init r8a7779_get_core_count(void) 90static unsigned int __init r8a7779_get_core_count(void)
74{ 91{
75 void __iomem *scu_base = scu_base_addr(); 92 void __iomem *scu_base = scu_base_addr();
@@ -85,7 +102,7 @@ static int r8a7779_platform_cpu_kill(unsigned int cpu)
85 cpu = cpu_logical_map(cpu); 102 cpu = cpu_logical_map(cpu);
86 103
87 /* disable cache coherency */ 104 /* disable cache coherency */
88 scu_power_mode(scu_base_addr(), 3); 105 modify_scu_cpu_psr(3 << (cpu * 8), 0);
89 106
90 if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) 107 if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
91 ch = r8a7779_ch_cpu[cpu]; 108 ch = r8a7779_ch_cpu[cpu];
@@ -128,7 +145,7 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct
128 cpu = cpu_logical_map(cpu); 145 cpu = cpu_logical_map(cpu);
129 146
130 /* enable cache coherency */ 147 /* enable cache coherency */
131 scu_power_mode(scu_base_addr(), 0); 148 modify_scu_cpu_psr(0, 3 << (cpu * 8));
132 149
133 if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) 150 if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
134 ch = r8a7779_ch_cpu[cpu]; 151 ch = r8a7779_ch_cpu[cpu];
@@ -141,13 +158,15 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct
141 158
142static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) 159static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus)
143{ 160{
161 int cpu = cpu_logical_map(0);
162
144 scu_enable(scu_base_addr()); 163 scu_enable(scu_base_addr());
145 164
146 /* Map the reset vector (in headsmp.S) */ 165 /* Map the reset vector (in headsmp.S) */
147 __raw_writel(__pa(shmobile_secondary_vector), AVECR); 166 __raw_writel(__pa(shmobile_secondary_vector), AVECR);
148 167
149 /* enable cache coherency on CPU0 */ 168 /* enable cache coherency on CPU0 */
150 scu_power_mode(scu_base_addr(), 0); 169 modify_scu_cpu_psr(0, 3 << (cpu * 8));
151 170
152 r8a7779_pm_init(); 171 r8a7779_pm_init();
153 172
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index 96ddb97babbe..624f00f70abf 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -41,6 +41,9 @@ static void __iomem *scu_base_addr(void)
41 return (void __iomem *)0xf0000000; 41 return (void __iomem *)0xf0000000;
42} 42}
43 43
44static DEFINE_SPINLOCK(scu_lock);
45static unsigned long tmp;
46
44#ifdef CONFIG_HAVE_ARM_TWD 47#ifdef CONFIG_HAVE_ARM_TWD
45static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); 48static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
46void __init sh73a0_register_twd(void) 49void __init sh73a0_register_twd(void)
@@ -49,6 +52,20 @@ void __init sh73a0_register_twd(void)
49} 52}
50#endif 53#endif
51 54
55static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
56{
57 void __iomem *scu_base = scu_base_addr();
58
59 spin_lock(&scu_lock);
60 tmp = __raw_readl(scu_base + 8);
61 tmp &= ~clr;
62 tmp |= set;
63 spin_unlock(&scu_lock);
64
65 /* disable cache coherency after releasing the lock */
66 __raw_writel(tmp, scu_base + 8);
67}
68
52static unsigned int __init sh73a0_get_core_count(void) 69static unsigned int __init sh73a0_get_core_count(void)
53{ 70{
54 void __iomem *scu_base = scu_base_addr(); 71 void __iomem *scu_base = scu_base_addr();
@@ -66,7 +83,7 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct
66 cpu = cpu_logical_map(cpu); 83 cpu = cpu_logical_map(cpu);
67 84
68 /* enable cache coherency */ 85 /* enable cache coherency */
69 scu_power_mode(scu_base_addr(), 0); 86 modify_scu_cpu_psr(0, 3 << (cpu * 8));
70 87
71 if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3) 88 if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3)
72 __raw_writel(1 << cpu, WUPCR); /* wake up */ 89 __raw_writel(1 << cpu, WUPCR); /* wake up */
@@ -78,6 +95,8 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct
78 95
79static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) 96static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
80{ 97{
98 int cpu = cpu_logical_map(0);
99
81 scu_enable(scu_base_addr()); 100 scu_enable(scu_base_addr());
82 101
83 /* Map the reset vector (in headsmp.S) */ 102 /* Map the reset vector (in headsmp.S) */
@@ -85,7 +104,7 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
85 __raw_writel(__pa(shmobile_secondary_vector), SBAR); 104 __raw_writel(__pa(shmobile_secondary_vector), SBAR);
86 105
87 /* enable cache coherency on CPU0 */ 106 /* enable cache coherency on CPU0 */
88 scu_power_mode(scu_base_addr(), 0); 107 modify_scu_cpu_psr(0, 3 << (cpu * 8));
89} 108}
90 109
91static void __init sh73a0_smp_init_cpus(void) 110static void __init sh73a0_smp_init_cpus(void)
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 803a3281feb5..566e804d4036 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -12,5 +12,6 @@ config ARCH_SOCFPGA
12 select GENERIC_CLOCKEVENTS 12 select GENERIC_CLOCKEVENTS
13 select GPIO_PL061 if GPIOLIB 13 select GPIO_PL061 if GPIOLIB
14 select HAVE_ARM_SCU 14 select HAVE_ARM_SCU
15 select HAVE_SMP
15 select SPARSE_IRQ 16 select SPARSE_IRQ
16 select USE_OF 17 select USE_OF
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index 4fb93240971d..6dd7a93a90fe 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -3,3 +3,4 @@
3# 3#
4 4
5obj-y := socfpga.o 5obj-y := socfpga.o
6obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h
new file mode 100644
index 000000000000..9941caa94931
--- /dev/null
+++ b/arch/arm/mach-socfpga/core.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright 2012 Pavel Machek <pavel@denx.de>
3 * Copyright (C) 2012 Altera Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifndef __MACH_CORE_H
21#define __MACH_CORE_H
22
23extern void secondary_startup(void);
24extern void __iomem *socfpga_scu_base_addr;
25
26extern void socfpga_init_clocks(void);
27extern void socfpga_sysmgr_init(void);
28
29extern struct smp_operations socfpga_smp_ops;
30extern char secondary_trampoline, secondary_trampoline_end;
31
32#define SOCFPGA_SCU_VIRT_BASE 0xfffec000
33
34#endif
diff --git a/arch/arm/mach-socfpga/headsmp.S b/arch/arm/mach-socfpga/headsmp.S
new file mode 100644
index 000000000000..f09b1283ffca
--- /dev/null
+++ b/arch/arm/mach-socfpga/headsmp.S
@@ -0,0 +1,25 @@
1/*
2 * Copyright (c) 2003 ARM Limited
3 * Copyright (c) u-boot contributors
4 * Copyright (c) 2012 Pavel Machek <pavel@denx.de>
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 version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <linux/init.h>
12
13 __CPUINIT
14 .arch armv7-a
15
16#define CPU1_START_ADDR 0xffd08010
17
18ENTRY(secondary_trampoline)
19 movw r0, #:lower16:CPU1_START_ADDR
20 movt r0, #:upper16:CPU1_START_ADDR
21
22 ldr r1, [r0]
23 bx r1
24
25ENTRY(secondary_trampoline_end)
diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c
new file mode 100644
index 000000000000..68dd1b69512a
--- /dev/null
+++ b/arch/arm/mach-socfpga/platsmp.c
@@ -0,0 +1,116 @@
1/*
2 * Copyright 2010-2011 Calxeda, Inc.
3 * Copyright 2012 Pavel Machek <pavel@denx.de>
4 * Based on platsmp.c, Copyright (C) 2002 ARM Ltd.
5 * Copyright (C) 2012 Altera Corporation
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#include <linux/delay.h>
20#include <linux/init.h>
21#include <linux/smp.h>
22#include <linux/io.h>
23#include <linux/of.h>
24#include <linux/of_address.h>
25
26#include <asm/cacheflush.h>
27#include <asm/hardware/gic.h>
28#include <asm/smp_scu.h>
29#include <asm/smp_plat.h>
30
31#include "core.h"
32
33extern void __iomem *sys_manager_base_addr;
34extern void __iomem *rst_manager_base_addr;
35
36static void __cpuinit socfpga_secondary_init(unsigned int cpu)
37{
38 /*
39 * if any interrupts are already enabled for the primary
40 * core (e.g. timer irq), then they will not have been enabled
41 * for us: do so
42 */
43 gic_secondary_init(0);
44}
45
46static int __cpuinit socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle)
47{
48 int trampoline_size = &secondary_trampoline_end - &secondary_trampoline;
49
50 memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size);
51
52 __raw_writel(virt_to_phys(secondary_startup), (sys_manager_base_addr+0x10));
53
54 flush_cache_all();
55 smp_wmb();
56 outer_clean_range(0, trampoline_size);
57
58 /* This will release CPU #1 out of reset.*/
59 __raw_writel(0, rst_manager_base_addr + 0x10);
60
61 return 0;
62}
63
64/*
65 * Initialise the CPU possible map early - this describes the CPUs
66 * which may be present or become present in the system.
67 */
68static void __init socfpga_smp_init_cpus(void)
69{
70 unsigned int i, ncores;
71
72 ncores = scu_get_core_count(socfpga_scu_base_addr);
73
74 for (i = 0; i < ncores; i++)
75 set_cpu_possible(i, true);
76
77 /* sanity check */
78 if (ncores > num_possible_cpus()) {
79 pr_warn("socfpga: no. of cores (%d) greater than configured"
80 "maximum of %d - clipping\n", ncores, num_possible_cpus());
81 ncores = num_possible_cpus();
82 }
83
84 for (i = 0; i < ncores; i++)
85 set_cpu_possible(i, true);
86
87 set_smp_cross_call(gic_raise_softirq);
88}
89
90static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus)
91{
92 scu_enable(socfpga_scu_base_addr);
93}
94
95/*
96 * platform-specific code to shutdown a CPU
97 *
98 * Called with IRQs disabled
99 */
100static void socfpga_cpu_die(unsigned int cpu)
101{
102 cpu_do_idle();
103
104 /* We should have never returned from idle */
105 panic("cpu %d unexpectedly exit from shutdown\n", cpu);
106}
107
108struct smp_operations socfpga_smp_ops __initdata = {
109 .smp_init_cpus = socfpga_smp_init_cpus,
110 .smp_prepare_cpus = socfpga_smp_prepare_cpus,
111 .smp_secondary_init = socfpga_secondary_init,
112 .smp_boot_secondary = socfpga_boot_secondary,
113#ifdef CONFIG_HOTPLUG_CPU
114 .cpu_die = socfpga_cpu_die,
115#endif
116};
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c
index f01e1ebf5396..6732924a5fee 100644
--- a/arch/arm/mach-socfpga/socfpga.c
+++ b/arch/arm/mach-socfpga/socfpga.c
@@ -15,23 +15,73 @@
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17#include <linux/dw_apb_timer.h> 17#include <linux/dw_apb_timer.h>
18#include <linux/of_address.h>
18#include <linux/of_irq.h> 19#include <linux/of_irq.h>
19#include <linux/of_platform.h> 20#include <linux/of_platform.h>
20 21
21#include <asm/hardware/cache-l2x0.h> 22#include <asm/hardware/cache-l2x0.h>
22#include <asm/hardware/gic.h> 23#include <asm/hardware/gic.h>
23#include <asm/mach/arch.h> 24#include <asm/mach/arch.h>
25#include <asm/mach/map.h>
24 26
25extern void socfpga_init_clocks(void); 27#include "core.h"
28
29void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE));
30void __iomem *sys_manager_base_addr;
31void __iomem *rst_manager_base_addr;
32
33static struct map_desc scu_io_desc __initdata = {
34 .virtual = SOCFPGA_SCU_VIRT_BASE,
35 .pfn = 0, /* run-time */
36 .length = SZ_8K,
37 .type = MT_DEVICE,
38};
39
40static struct map_desc uart_io_desc __initdata = {
41 .virtual = 0xfec02000,
42 .pfn = __phys_to_pfn(0xffc02000),
43 .length = SZ_8K,
44 .type = MT_DEVICE,
45};
46
47static void __init socfpga_scu_map_io(void)
48{
49 unsigned long base;
50
51 /* Get SCU base */
52 asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
53
54 scu_io_desc.pfn = __phys_to_pfn(base);
55 iotable_init(&scu_io_desc, 1);
56}
57
58static void __init socfpga_map_io(void)
59{
60 socfpga_scu_map_io();
61 iotable_init(&uart_io_desc, 1);
62 early_printk("Early printk initialized\n");
63}
26 64
27const static struct of_device_id irq_match[] = { 65const static struct of_device_id irq_match[] = {
28 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, 66 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
29 {} 67 {}
30}; 68};
31 69
70void __init socfpga_sysmgr_init(void)
71{
72 struct device_node *np;
73
74 np = of_find_compatible_node(NULL, NULL, "altr,sys-mgr");
75 sys_manager_base_addr = of_iomap(np, 0);
76
77 np = of_find_compatible_node(NULL, NULL, "altr,rst-mgr");
78 rst_manager_base_addr = of_iomap(np, 0);
79}
80
32static void __init gic_init_irq(void) 81static void __init gic_init_irq(void)
33{ 82{
34 of_irq_init(irq_match); 83 of_irq_init(irq_match);
84 socfpga_sysmgr_init();
35} 85}
36 86
37static void socfpga_cyclone5_restart(char mode, const char *cmd) 87static void socfpga_cyclone5_restart(char mode, const char *cmd)
@@ -53,6 +103,8 @@ static const char *altera_dt_match[] = {
53}; 103};
54 104
55DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA") 105DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA")
106 .smp = smp_ops(socfpga_smp_ops),
107 .map_io = socfpga_map_io,
56 .init_irq = gic_init_irq, 108 .init_irq = gic_init_irq,
57 .handle_irq = gic_handle_irq, 109 .handle_irq = gic_handle_irq,
58 .timer = &dw_apb_timer, 110 .timer = &dw_apb_timer,
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
index 012bbd0b8d81..47c9fad43f00 100644
--- a/arch/arm/plat-samsung/clock.c
+++ b/arch/arm/plat-samsung/clock.c
@@ -389,6 +389,72 @@ int __init s3c24xx_register_baseclocks(unsigned long xtal)
389 389
390static struct dentry *clk_debugfs_root; 390static struct dentry *clk_debugfs_root;
391 391
392static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
393{
394 struct clk *child;
395 const char *state;
396 char buf[255] = { 0 };
397 int n = 0;
398
399 if (c->name)
400 n = snprintf(buf, sizeof(buf) - 1, "%s", c->name);
401
402 if (c->devname)
403 n += snprintf(buf + n, sizeof(buf) - 1 - n, ":%s", c->devname);
404
405 state = (c->usage > 0) ? "on" : "off";
406
407 seq_printf(s, "%*s%-*s %-6s %-3d %-10lu\n",
408 level * 3 + 1, "",
409 50 - level * 3, buf,
410 state, c->usage, clk_get_rate(c));
411
412 list_for_each_entry(child, &clocks, list) {
413 if (child->parent != c)
414 continue;
415
416 clock_tree_show_one(s, child, level + 1);
417 }
418}
419
420static int clock_tree_show(struct seq_file *s, void *data)
421{
422 struct clk *c;
423 unsigned long flags;
424
425 seq_printf(s, " clock state ref rate\n");
426 seq_printf(s, "----------------------------------------------------\n");
427
428 spin_lock_irqsave(&clocks_lock, flags);
429
430 list_for_each_entry(c, &clocks, list)
431 if (c->parent == NULL)
432 clock_tree_show_one(s, c, 0);
433
434 spin_unlock_irqrestore(&clocks_lock, flags);
435 return 0;
436}
437
438static int clock_tree_open(struct inode *inode, struct file *file)
439{
440 return single_open(file, clock_tree_show, inode->i_private);
441}
442
443static const struct file_operations clock_tree_fops = {
444 .open = clock_tree_open,
445 .read = seq_read,
446 .llseek = seq_lseek,
447 .release = single_release,
448};
449
450static int clock_rate_show(void *data, u64 *val)
451{
452 struct clk *c = data;
453 *val = clk_get_rate(c);
454 return 0;
455}
456DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_rate_show, NULL, "%llu\n");
457
392static int clk_debugfs_register_one(struct clk *c) 458static int clk_debugfs_register_one(struct clk *c)
393{ 459{
394 int err; 460 int err;
@@ -411,7 +477,7 @@ static int clk_debugfs_register_one(struct clk *c)
411 goto err_out; 477 goto err_out;
412 } 478 }
413 479
414 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); 480 d = debugfs_create_file("rate", S_IRUGO, c->dent, c, &clock_rate_fops);
415 if (!d) { 481 if (!d) {
416 err = -ENOMEM; 482 err = -ENOMEM;
417 goto err_out; 483 goto err_out;
@@ -446,13 +512,18 @@ static int __init clk_debugfs_init(void)
446{ 512{
447 struct clk *c; 513 struct clk *c;
448 struct dentry *d; 514 struct dentry *d;
449 int err; 515 int err = -ENOMEM;
450 516
451 d = debugfs_create_dir("clock", NULL); 517 d = debugfs_create_dir("clock", NULL);
452 if (!d) 518 if (!d)
453 return -ENOMEM; 519 return -ENOMEM;
454 clk_debugfs_root = d; 520 clk_debugfs_root = d;
455 521
522 d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL,
523 &clock_tree_fops);
524 if (!d)
525 goto err_out;
526
456 list_for_each_entry(c, &clocks, list) { 527 list_for_each_entry(c, &clocks, list) {
457 err = clk_debugfs_register(c); 528 err = clk_debugfs_register(c);
458 if (err) 529 if (err)
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
index b3dc44146ca0..5aedcdf4ac5c 100644
--- a/drivers/sh/clk/cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -401,7 +401,6 @@ static int fsidiv_enable(struct clk *clk)
401 401
402static int fsidiv_set_rate(struct clk *clk, unsigned long rate) 402static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
403{ 403{
404 u32 val;
405 int idx; 404 int idx;
406 405
407 idx = (clk->parent->rate / rate) & 0xffff; 406 idx = (clk->parent->rate / rate) & 0xffff;