aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r--arch/arm/mach-shmobile/Makefile7
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7740.c13
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7779.c8
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c7
-rw-r--r--arch/arm/mach-shmobile/headsmp-scu.S (renamed from arch/arm/mach-shmobile/headsmp-sh73a0.S)15
-rw-r--r--arch/arm/mach-shmobile/hotplug.c68
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h21
-rw-r--r--arch/arm/mach-shmobile/include/mach/irqs.h1
-rw-r--r--arch/arm/mach-shmobile/intc-r8a7779.c27
-rw-r--r--arch/arm/mach-shmobile/intc-sh73a0.c8
-rw-r--r--arch/arm/mach-shmobile/setup-emev2.c4
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c104
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c36
-rw-r--r--arch/arm/mach-shmobile/smp-emev2.c86
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7779.c129
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c36
16 files changed, 257 insertions, 313 deletions
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index e1fac57514b9..b646ff4d742a 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -14,10 +14,9 @@ obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o clock-emev2.o
14 14
15# SMP objects 15# SMP objects
16smp-y := platsmp.o headsmp.o 16smp-y := platsmp.o headsmp.o
17smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o 17smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o
18smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-sh73a0.o 18smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o
19smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o 19smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o
20smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o
21 20
22# IRQ objects 21# IRQ objects
23obj-$(CONFIG_ARCH_SH7372) += entry-intc.o 22obj-$(CONFIG_ARCH_SH7372) += entry-intc.o
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index 19ce885a3b43..1feb9a2286a8 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -593,29 +593,42 @@ static struct clk_lookup lookups[] = {
593 CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]), 593 CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]),
594 594
595 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), 595 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]),
596 CLKDEV_DEV_ID("e6c80000.sci", &mstp_clks[MSTP200]),
596 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), 597 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]),
598 CLKDEV_DEV_ID("e6c70000.sci", &mstp_clks[MSTP201]),
597 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), 599 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]),
600 CLKDEV_DEV_ID("e6c60000.sci", &mstp_clks[MSTP202]),
598 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), 601 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
602 CLKDEV_DEV_ID("e6c50000.sci", &mstp_clks[MSTP203]),
599 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), 603 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
604 CLKDEV_DEV_ID("e6c40000.sci", &mstp_clks[MSTP204]),
600 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), 605 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]),
606 CLKDEV_DEV_ID("e6c30000.sci", &mstp_clks[MSTP206]),
601 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), 607 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]),
608 CLKDEV_DEV_ID("e6cb0000.sci", &mstp_clks[MSTP207]),
602 CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), 609 CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]),
603 CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), 610 CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]),
604 CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), 611 CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]),
605 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), 612 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]),
606 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]), 613 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]),
614 CLKDEV_DEV_ID("e6cd0000.sci", &mstp_clks[MSTP222]),
607 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), 615 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
616 CLKDEV_DEV_ID("e6cc0000.sci", &mstp_clks[MSTP230]),
608 617
609 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), 618 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
610 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), 619 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]),
611 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), 620 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
612 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]), 621 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]),
613 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), 622 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
623 CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]),
614 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), 624 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
625 CLKDEV_DEV_ID("e6860000.sdhi", &mstp_clks[MSTP313]),
615 CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]), 626 CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]),
627 CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]),
616 CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP309]), 628 CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP309]),
617 629
618 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), 630 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]),
631 CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]),
619 632
620 /* ICK */ 633 /* ICK */
621 CLKDEV_ICK_ID("host", "renesas_usbhs", &mstp_clks[MSTP416]), 634 CLKDEV_ICK_ID("host", "renesas_usbhs", &mstp_clks[MSTP416]),
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index 1db36537255c..d9edeaf66007 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -87,7 +87,8 @@ static struct clk div4_clks[DIV4_NR] = {
87}; 87};
88 88
89enum { MSTP323, MSTP322, MSTP321, MSTP320, 89enum { MSTP323, MSTP322, MSTP321, MSTP320,
90 MSTP101, MSTP100, 90 MSTP115,
91 MSTP103, MSTP101, MSTP100,
91 MSTP030, 92 MSTP030,
92 MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, 93 MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
93 MSTP016, MSTP015, MSTP014, 94 MSTP016, MSTP015, MSTP014,
@@ -99,6 +100,8 @@ static struct clk mstp_clks[MSTP_NR] = {
99 [MSTP322] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 22, 0), /* SDHI1 */ 100 [MSTP322] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 22, 0), /* SDHI1 */
100 [MSTP321] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 21, 0), /* SDHI2 */ 101 [MSTP321] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 21, 0), /* SDHI2 */
101 [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 20, 0), /* SDHI3 */ 102 [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 20, 0), /* SDHI3 */
103 [MSTP115] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 15, 0), /* SATA */
104 [MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_S], MSTPCR1, 3, 0), /* DU */
102 [MSTP101] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 1, 0), /* USB2 */ 105 [MSTP101] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 1, 0), /* USB2 */
103 [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 0, 0), /* USB0/1 */ 106 [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 0, 0), /* USB0/1 */
104 [MSTP030] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 30, 0), /* I2C0 */ 107 [MSTP030] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 30, 0), /* I2C0 */
@@ -156,6 +159,8 @@ static struct clk_lookup lookups[] = {
156 CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), 159 CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
157 160
158 /* MSTP32 clocks */ 161 /* MSTP32 clocks */
162 CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
163 CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
159 CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */ 164 CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
160 CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */ 165 CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
161 CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ 166 CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
@@ -180,6 +185,7 @@ static struct clk_lookup lookups[] = {
180 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ 185 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
181 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ 186 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
182 CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */ 187 CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
188 CLKDEV_DEV_ID("rcar-du.0", &mstp_clks[MSTP103]), /* DU */
183}; 189};
184 190
185void __init r8a7779_clock_init(void) 191void __init r8a7779_clock_init(void)
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index afa5423a0f93..71843dd39e16 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -265,12 +265,12 @@ enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
265 265
266static struct clk div4_clks[DIV4_NR] = { 266static struct clk div4_clks[DIV4_NR] = {
267 [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT), 267 [DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
268 [DIV4_ZG] = DIV4(FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT), 268 [DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
269 [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT), 269 [DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
270 [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT), 270 [DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
271 [DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0), 271 [DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0),
272 [DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0), 272 [DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0),
273 [DIV4_Z] = DIV4(FRQCRB, 24, 0x97f, 0), 273 [DIV4_Z] = SH_CLK_DIV4(&pll0_clk, FRQCRB, 24, 0x97f, 0),
274 [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xdff, 0), 274 [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xdff, 0),
275 [DIV4_ZT] = DIV4(FRQCRB, 16, 0xdff, 0), 275 [DIV4_ZT] = DIV4(FRQCRB, 16, 0xdff, 0),
276 [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0), 276 [DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
@@ -581,10 +581,13 @@ static struct clk_lookup lookups[] = {
581 CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */ 581 CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
582 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */ 582 CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
583 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ 583 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
584 CLKDEV_DEV_ID("ee100000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */
584 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ 585 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
586 CLKDEV_DEV_ID("ee120000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */
585 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */ 587 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
586 CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */ 588 CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */
587 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */ 589 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
590 CLKDEV_DEV_ID("ee140000.sdhi", &mstp_clks[MSTP311]), /* SDHI2 */
588 CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */ 591 CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
589 CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */ 592 CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
590 CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */ 593 CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
diff --git a/arch/arm/mach-shmobile/headsmp-sh73a0.S b/arch/arm/mach-shmobile/headsmp-scu.S
index bec4c0d9b713..7d113f898e7f 100644
--- a/arch/arm/mach-shmobile/headsmp-sh73a0.S
+++ b/arch/arm/mach-shmobile/headsmp-scu.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * SMP support for SoC sh73a0 2 * Shared SCU setup for mach-shmobile
3 * 3 *
4 * Copyright (C) 2012 Bastian Hecht 4 * Copyright (C) 2012 Bastian Hecht
5 * 5 *
@@ -35,11 +35,12 @@
35 * the physical address as the MMU is still turned off. 35 * the physical address as the MMU is still turned off.
36 */ 36 */
37 .align 12 37 .align 12
38ENTRY(sh73a0_secondary_vector) 38ENTRY(shmobile_secondary_vector_scu)
39 mrc p15, 0, r0, c0, c0, 5 @ read MIPDR 39 mrc p15, 0, r0, c0, c0, 5 @ read MIPDR
40 and r0, r0, #3 @ mask out cpu ID 40 and r0, r0, #3 @ mask out cpu ID
41 lsl r0, r0, #3 @ we will shift by cpu_id * 8 bits 41 lsl r0, r0, #3 @ we will shift by cpu_id * 8 bits
42 mov r1, #0xf0000000 @ SCU base address 42 ldr r1, 2f
43 ldr r1, [r1] @ SCU base address
43 ldr r2, [r1, #8] @ SCU Power Status Register 44 ldr r2, [r1, #8] @ SCU Power Status Register
44 mov r3, #3 45 mov r3, #3
45 bic r2, r2, r3, lsl r0 @ Clear bits of our CPU (Run Mode) 46 bic r2, r2, r3, lsl r0 @ Clear bits of our CPU (Run Mode)
@@ -47,4 +48,10 @@ ENTRY(sh73a0_secondary_vector)
47 48
48 ldr pc, 1f 49 ldr pc, 1f
491: .long shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET 501: .long shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET
50ENDPROC(sh73a0_secondary_vector) 512: .long shmobile_scu_base - PAGE_OFFSET + PLAT_PHYS_OFFSET
52ENDPROC(shmobile_secondary_vector_scu)
53
54 .text
55 .globl shmobile_scu_base
56shmobile_scu_base:
57 .space 4
diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c
deleted file mode 100644
index a1524e3367b0..000000000000
--- a/arch/arm/mach-shmobile/hotplug.c
+++ /dev/null
@@ -1,68 +0,0 @@
1/*
2 * SMP support for R-Mobile / SH-Mobile
3 *
4 * Copyright (C) 2010 Magnus Damm
5 *
6 * Based on realview, Copyright (C) 2002 ARM Ltd, All Rights Reserved
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#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/smp.h>
15#include <linux/cpumask.h>
16#include <linux/delay.h>
17#include <linux/of.h>
18#include <mach/common.h>
19#include <mach/r8a7779.h>
20#include <mach/emev2.h>
21#include <asm/cacheflush.h>
22#include <asm/mach-types.h>
23
24static cpumask_t dead_cpus;
25
26void shmobile_cpu_die(unsigned int cpu)
27{
28 /* hardware shutdown code running on the CPU that is being offlined */
29 flush_cache_all();
30 dsb();
31
32 /* notify platform_cpu_kill() that hardware shutdown is finished */
33 cpumask_set_cpu(cpu, &dead_cpus);
34
35 /* wait for SoC code in platform_cpu_kill() to shut off CPU core
36 * power. CPU bring up starts from the reset vector.
37 */
38 while (1) {
39 /*
40 * here's the WFI
41 */
42 asm(".word 0xe320f003\n"
43 :
44 :
45 : "memory", "cc");
46 }
47}
48
49int shmobile_cpu_disable(unsigned int cpu)
50{
51 cpumask_clear_cpu(cpu, &dead_cpus);
52 /*
53 * we don't allow CPU 0 to be shutdown (it is still too special
54 * e.g. clock tick interrupts)
55 */
56 return cpu == 0 ? -EPERM : 0;
57}
58
59int shmobile_cpu_disable_any(unsigned int cpu)
60{
61 cpumask_clear_cpu(cpu, &dead_cpus);
62 return 0;
63}
64
65int shmobile_cpu_is_dead(unsigned int cpu)
66{
67 return cpumask_test_cpu(cpu, &dead_cpus);
68}
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 362f9b2d2c02..62c04c252418 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -8,6 +8,7 @@ extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz,
8struct twd_local_timer; 8struct twd_local_timer;
9extern void shmobile_setup_console(void); 9extern void shmobile_setup_console(void);
10extern void shmobile_secondary_vector(void); 10extern void shmobile_secondary_vector(void);
11extern void shmobile_secondary_vector_scu(void);
11struct clk; 12struct clk;
12extern int shmobile_clk_init(void); 13extern int shmobile_clk_init(void);
13extern void shmobile_handle_irq_intc(struct pt_regs *); 14extern void shmobile_handle_irq_intc(struct pt_regs *);
@@ -30,23 +31,23 @@ extern int sh7372_do_idle_sysc(unsigned long sleep_mode);
30extern struct clk sh7372_extal1_clk; 31extern struct clk sh7372_extal1_clk;
31extern struct clk sh7372_extal2_clk; 32extern struct clk sh7372_extal2_clk;
32 33
34extern void sh73a0_init_delay(void);
33extern void sh73a0_init_irq(void); 35extern void sh73a0_init_irq(void);
34extern void sh73a0_init_irq_dt(void); 36extern void sh73a0_init_irq_dt(void);
35extern void sh73a0_map_io(void); 37extern void sh73a0_map_io(void);
36extern void sh73a0_earlytimer_init(void); 38extern void sh73a0_earlytimer_init(void);
37extern void sh73a0_add_early_devices(void); 39extern void sh73a0_add_early_devices(void);
38extern void sh73a0_add_early_devices_dt(void);
39extern void sh73a0_add_standard_devices(void); 40extern void sh73a0_add_standard_devices(void);
40extern void sh73a0_add_standard_devices_dt(void); 41extern void sh73a0_add_standard_devices_dt(void);
41extern void sh73a0_clock_init(void); 42extern void sh73a0_clock_init(void);
42extern void sh73a0_pinmux_init(void); 43extern void sh73a0_pinmux_init(void);
43extern void sh73a0_pm_init(void); 44extern void sh73a0_pm_init(void);
44extern void sh73a0_secondary_vector(void);
45extern struct clk sh73a0_extal1_clk; 45extern struct clk sh73a0_extal1_clk;
46extern struct clk sh73a0_extal2_clk; 46extern struct clk sh73a0_extal2_clk;
47extern struct clk sh73a0_extcki_clk; 47extern struct clk sh73a0_extcki_clk;
48extern struct clk sh73a0_extalr_clk; 48extern struct clk sh73a0_extalr_clk;
49 49
50extern void r8a7740_meram_workaround(void);
50extern void r8a7740_init_irq(void); 51extern void r8a7740_init_irq(void);
51extern void r8a7740_map_io(void); 52extern void r8a7740_map_io(void);
52extern void r8a7740_add_early_devices(void); 53extern void r8a7740_add_early_devices(void);
@@ -55,16 +56,17 @@ extern void r8a7740_clock_init(u8 md_ck);
55extern void r8a7740_pinmux_init(void); 56extern void r8a7740_pinmux_init(void);
56extern void r8a7740_pm_init(void); 57extern void r8a7740_pm_init(void);
57 58
59extern void r8a7779_init_delay(void);
58extern void r8a7779_init_irq(void); 60extern void r8a7779_init_irq(void);
61extern void r8a7779_init_irq_dt(void);
59extern void r8a7779_map_io(void); 62extern void r8a7779_map_io(void);
60extern void r8a7779_earlytimer_init(void); 63extern void r8a7779_earlytimer_init(void);
61extern void r8a7779_add_early_devices(void); 64extern void r8a7779_add_early_devices(void);
62extern void r8a7779_add_standard_devices(void); 65extern void r8a7779_add_standard_devices(void);
66extern void r8a7779_add_standard_devices_dt(void);
63extern void r8a7779_clock_init(void); 67extern void r8a7779_clock_init(void);
64extern void r8a7779_pinmux_init(void); 68extern void r8a7779_pinmux_init(void);
65extern void r8a7779_pm_init(void); 69extern void r8a7779_pm_init(void);
66extern void r8a7740_meram_workaround(void);
67
68extern void r8a7779_register_twd(void); 70extern void r8a7779_register_twd(void);
69 71
70#ifdef CONFIG_SUSPEND 72#ifdef CONFIG_SUSPEND
@@ -79,16 +81,7 @@ int shmobile_cpuidle_init(void);
79static inline int shmobile_cpuidle_init(void) { return 0; } 81static inline int shmobile_cpuidle_init(void) { return 0; }
80#endif 82#endif
81 83
82extern void shmobile_cpu_die(unsigned int cpu); 84extern void __iomem *shmobile_scu_base;
83extern int shmobile_cpu_disable(unsigned int cpu);
84extern int shmobile_cpu_disable_any(unsigned int cpu);
85
86#ifdef CONFIG_HOTPLUG_CPU
87extern int shmobile_cpu_is_dead(unsigned int cpu);
88#else
89static inline int shmobile_cpu_is_dead(unsigned int cpu) { return 1; }
90#endif
91
92extern void shmobile_smp_init_cpus(unsigned int ncores); 85extern void shmobile_smp_init_cpus(unsigned int ncores);
93 86
94static inline void __init shmobile_init_late(void) 87static inline void __init shmobile_init_late(void)
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
index 06a5da3c3050..992ed213cec1 100644
--- a/arch/arm/mach-shmobile/include/mach/irqs.h
+++ b/arch/arm/mach-shmobile/include/mach/irqs.h
@@ -5,6 +5,7 @@
5 5
6/* GIC */ 6/* GIC */
7#define gic_spi(nr) ((nr) + 32) 7#define gic_spi(nr) ((nr) + 32)
8#define gic_iid(nr) (nr) /* ICCIAR / interrupt ID */
8 9
9/* INTCS */ 10/* INTCS */
10#define INTCS_VECT_BASE 0x3400 11#define INTCS_VECT_BASE 0x3400
diff --git a/arch/arm/mach-shmobile/intc-r8a7779.c b/arch/arm/mach-shmobile/intc-r8a7779.c
index 8807c27f71f9..f9cc4bc9c798 100644
--- a/arch/arm/mach-shmobile/intc-r8a7779.c
+++ b/arch/arm/mach-shmobile/intc-r8a7779.c
@@ -24,6 +24,7 @@
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/irqchip/arm-gic.h> 25#include <linux/irqchip/arm-gic.h>
26#include <mach/common.h> 26#include <mach/common.h>
27#include <linux/irqchip.h>
27#include <mach/intc.h> 28#include <mach/intc.h>
28#include <mach/r8a7779.h> 29#include <mach/r8a7779.h>
29#include <asm/mach-types.h> 30#include <asm/mach-types.h>
@@ -43,13 +44,8 @@ static int r8a7779_set_wake(struct irq_data *data, unsigned int on)
43 return 0; /* always allow wakeup */ 44 return 0; /* always allow wakeup */
44} 45}
45 46
46void __init r8a7779_init_irq(void) 47static void __init r8a7779_init_irq_common(void)
47{ 48{
48 void __iomem *gic_dist_base = IOMEM(0xf0001000);
49 void __iomem *gic_cpu_base = IOMEM(0xf0000100);
50
51 /* use GIC to handle interrupts */
52 gic_init(0, 29, gic_dist_base, gic_cpu_base);
53 gic_arch_extn.irq_set_wake = r8a7779_set_wake; 49 gic_arch_extn.irq_set_wake = r8a7779_set_wake;
54 50
55 /* route all interrupts to ARM */ 51 /* route all interrupts to ARM */
@@ -63,3 +59,22 @@ void __init r8a7779_init_irq(void)
63 __raw_writel(0xbffffffc, INT2SMSKCR3); 59 __raw_writel(0xbffffffc, INT2SMSKCR3);
64 __raw_writel(0x003fee3f, INT2SMSKCR4); 60 __raw_writel(0x003fee3f, INT2SMSKCR4);
65} 61}
62
63void __init r8a7779_init_irq(void)
64{
65 void __iomem *gic_dist_base = IOMEM(0xf0001000);
66 void __iomem *gic_cpu_base = IOMEM(0xf0000100);
67
68 /* use GIC to handle interrupts */
69 gic_init(0, 29, gic_dist_base, gic_cpu_base);
70
71 r8a7779_init_irq_common();
72}
73
74#ifdef CONFIG_OF
75void __init r8a7779_init_irq_dt(void)
76{
77 irqchip_init();
78 r8a7779_init_irq_common();
79}
80#endif
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
index 91faba666d46..a81a1d804e2e 100644
--- a/arch/arm/mach-shmobile/intc-sh73a0.c
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -460,11 +460,3 @@ void __init sh73a0_init_irq(void)
460 sh73a0_pint1_cascade.handler = sh73a0_pint1_demux; 460 sh73a0_pint1_cascade.handler = sh73a0_pint1_demux;
461 setup_irq(gic_spi(34), &sh73a0_pint1_cascade); 461 setup_irq(gic_spi(34), &sh73a0_pint1_cascade);
462} 462}
463
464#ifdef CONFIG_OF
465void __init sh73a0_init_irq_dt(void)
466{
467 irqchip_init();
468 gic_arch_extn.irq_set_wake = sh73a0_set_wake;
469}
470#endif
diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c
index 47662a581c0a..e4545c152722 100644
--- a/arch/arm/mach-shmobile/setup-emev2.c
+++ b/arch/arm/mach-shmobile/setup-emev2.c
@@ -404,7 +404,7 @@ void __init emev2_add_standard_devices(void)
404 ARRAY_SIZE(emev2_late_devices)); 404 ARRAY_SIZE(emev2_late_devices));
405} 405}
406 406
407void __init emev2_init_delay(void) 407static void __init emev2_init_delay(void)
408{ 408{
409 shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */ 409 shmobile_setup_delay(533, 1, 3); /* Cortex-A9 @ 533MHz */
410} 410}
@@ -439,7 +439,7 @@ static const struct of_dev_auxdata emev2_auxdata_lookup[] __initconst = {
439 { } 439 { }
440}; 440};
441 441
442void __init emev2_add_standard_devices_dt(void) 442static void __init emev2_add_standard_devices_dt(void)
443{ 443{
444 of_platform_populate(NULL, of_default_bus_match_table, 444 of_platform_populate(NULL, of_default_bus_match_table,
445 emev2_auxdata_lookup, NULL); 445 emev2_auxdata_lookup, NULL);
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index c54ff9b29fe5..042df35e71a0 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -21,6 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/of_platform.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
25#include <linux/delay.h> 26#include <linux/delay.h>
26#include <linux/input.h> 27#include <linux/input.h>
@@ -28,6 +29,7 @@
28#include <linux/serial_sci.h> 29#include <linux/serial_sci.h>
29#include <linux/sh_intc.h> 30#include <linux/sh_intc.h>
30#include <linux/sh_timer.h> 31#include <linux/sh_timer.h>
32#include <linux/dma-mapping.h>
31#include <mach/hardware.h> 33#include <mach/hardware.h>
32#include <mach/irqs.h> 34#include <mach/irqs.h>
33#include <mach/r8a7779.h> 35#include <mach/r8a7779.h>
@@ -91,7 +93,7 @@ static struct plat_sci_port scif0_platform_data = {
91 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 93 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
92 .scbrr_algo_id = SCBRR_ALGO_2, 94 .scbrr_algo_id = SCBRR_ALGO_2,
93 .type = PORT_SCIF, 95 .type = PORT_SCIF,
94 .irqs = SCIx_IRQ_MUXED(gic_spi(88)), 96 .irqs = SCIx_IRQ_MUXED(gic_iid(0x78)),
95}; 97};
96 98
97static struct platform_device scif0_device = { 99static struct platform_device scif0_device = {
@@ -108,7 +110,7 @@ static struct plat_sci_port scif1_platform_data = {
108 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 110 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
109 .scbrr_algo_id = SCBRR_ALGO_2, 111 .scbrr_algo_id = SCBRR_ALGO_2,
110 .type = PORT_SCIF, 112 .type = PORT_SCIF,
111 .irqs = SCIx_IRQ_MUXED(gic_spi(89)), 113 .irqs = SCIx_IRQ_MUXED(gic_iid(0x79)),
112}; 114};
113 115
114static struct platform_device scif1_device = { 116static struct platform_device scif1_device = {
@@ -125,7 +127,7 @@ static struct plat_sci_port scif2_platform_data = {
125 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 127 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
126 .scbrr_algo_id = SCBRR_ALGO_2, 128 .scbrr_algo_id = SCBRR_ALGO_2,
127 .type = PORT_SCIF, 129 .type = PORT_SCIF,
128 .irqs = SCIx_IRQ_MUXED(gic_spi(90)), 130 .irqs = SCIx_IRQ_MUXED(gic_iid(0x7a)),
129}; 131};
130 132
131static struct platform_device scif2_device = { 133static struct platform_device scif2_device = {
@@ -142,7 +144,7 @@ static struct plat_sci_port scif3_platform_data = {
142 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 144 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
143 .scbrr_algo_id = SCBRR_ALGO_2, 145 .scbrr_algo_id = SCBRR_ALGO_2,
144 .type = PORT_SCIF, 146 .type = PORT_SCIF,
145 .irqs = SCIx_IRQ_MUXED(gic_spi(91)), 147 .irqs = SCIx_IRQ_MUXED(gic_iid(0x7b)),
146}; 148};
147 149
148static struct platform_device scif3_device = { 150static struct platform_device scif3_device = {
@@ -159,7 +161,7 @@ static struct plat_sci_port scif4_platform_data = {
159 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 161 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
160 .scbrr_algo_id = SCBRR_ALGO_2, 162 .scbrr_algo_id = SCBRR_ALGO_2,
161 .type = PORT_SCIF, 163 .type = PORT_SCIF,
162 .irqs = SCIx_IRQ_MUXED(gic_spi(92)), 164 .irqs = SCIx_IRQ_MUXED(gic_iid(0x7c)),
163}; 165};
164 166
165static struct platform_device scif4_device = { 167static struct platform_device scif4_device = {
@@ -176,7 +178,7 @@ static struct plat_sci_port scif5_platform_data = {
176 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, 178 .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
177 .scbrr_algo_id = SCBRR_ALGO_2, 179 .scbrr_algo_id = SCBRR_ALGO_2,
178 .type = PORT_SCIF, 180 .type = PORT_SCIF,
179 .irqs = SCIx_IRQ_MUXED(gic_spi(93)), 181 .irqs = SCIx_IRQ_MUXED(gic_iid(0x7d)),
180}; 182};
181 183
182static struct platform_device scif5_device = { 184static struct platform_device scif5_device = {
@@ -203,7 +205,7 @@ static struct resource tmu00_resources[] = {
203 .flags = IORESOURCE_MEM, 205 .flags = IORESOURCE_MEM,
204 }, 206 },
205 [1] = { 207 [1] = {
206 .start = gic_spi(32), 208 .start = gic_iid(0x40),
207 .flags = IORESOURCE_IRQ, 209 .flags = IORESOURCE_IRQ,
208 }, 210 },
209}; 211};
@@ -233,7 +235,7 @@ static struct resource tmu01_resources[] = {
233 .flags = IORESOURCE_MEM, 235 .flags = IORESOURCE_MEM,
234 }, 236 },
235 [1] = { 237 [1] = {
236 .start = gic_spi(33), 238 .start = gic_iid(0x41),
237 .flags = IORESOURCE_IRQ, 239 .flags = IORESOURCE_IRQ,
238 }, 240 },
239}; 241};
@@ -255,7 +257,7 @@ static struct resource rcar_i2c0_res[] = {
255 .end = 0xffc70fff, 257 .end = 0xffc70fff,
256 .flags = IORESOURCE_MEM, 258 .flags = IORESOURCE_MEM,
257 }, { 259 }, {
258 .start = gic_spi(79), 260 .start = gic_iid(0x6f),
259 .flags = IORESOURCE_IRQ, 261 .flags = IORESOURCE_IRQ,
260 }, 262 },
261}; 263};
@@ -273,7 +275,7 @@ static struct resource rcar_i2c1_res[] = {
273 .end = 0xffc71fff, 275 .end = 0xffc71fff,
274 .flags = IORESOURCE_MEM, 276 .flags = IORESOURCE_MEM,
275 }, { 277 }, {
276 .start = gic_spi(82), 278 .start = gic_iid(0x72),
277 .flags = IORESOURCE_IRQ, 279 .flags = IORESOURCE_IRQ,
278 }, 280 },
279}; 281};
@@ -291,7 +293,7 @@ static struct resource rcar_i2c2_res[] = {
291 .end = 0xffc72fff, 293 .end = 0xffc72fff,
292 .flags = IORESOURCE_MEM, 294 .flags = IORESOURCE_MEM,
293 }, { 295 }, {
294 .start = gic_spi(80), 296 .start = gic_iid(0x70),
295 .flags = IORESOURCE_IRQ, 297 .flags = IORESOURCE_IRQ,
296 }, 298 },
297}; 299};
@@ -309,7 +311,7 @@ static struct resource rcar_i2c3_res[] = {
309 .end = 0xffc73fff, 311 .end = 0xffc73fff,
310 .flags = IORESOURCE_MEM, 312 .flags = IORESOURCE_MEM,
311 }, { 313 }, {
312 .start = gic_spi(81), 314 .start = gic_iid(0x71),
313 .flags = IORESOURCE_IRQ, 315 .flags = IORESOURCE_IRQ,
314 }, 316 },
315}; 317};
@@ -321,7 +323,31 @@ static struct platform_device i2c3_device = {
321 .num_resources = ARRAY_SIZE(rcar_i2c3_res), 323 .num_resources = ARRAY_SIZE(rcar_i2c3_res),
322}; 324};
323 325
324static struct platform_device *r8a7779_early_devices[] __initdata = { 326static struct resource sata_resources[] = {
327 [0] = {
328 .name = "rcar-sata",
329 .start = 0xfc600000,
330 .end = 0xfc601fff,
331 .flags = IORESOURCE_MEM,
332 },
333 [1] = {
334 .start = gic_iid(0x84),
335 .flags = IORESOURCE_IRQ,
336 },
337};
338
339static struct platform_device sata_device = {
340 .name = "sata_rcar",
341 .id = -1,
342 .resource = sata_resources,
343 .num_resources = ARRAY_SIZE(sata_resources),
344 .dev = {
345 .dma_mask = &sata_device.dev.coherent_dma_mask,
346 .coherent_dma_mask = DMA_BIT_MASK(32),
347 },
348};
349
350static struct platform_device *r8a7779_devices_dt[] __initdata = {
325 &scif0_device, 351 &scif0_device,
326 &scif1_device, 352 &scif1_device,
327 &scif2_device, 353 &scif2_device,
@@ -330,13 +356,14 @@ static struct platform_device *r8a7779_early_devices[] __initdata = {
330 &scif5_device, 356 &scif5_device,
331 &tmu00_device, 357 &tmu00_device,
332 &tmu01_device, 358 &tmu01_device,
359};
360
361static struct platform_device *r8a7779_late_devices[] __initdata = {
333 &i2c0_device, 362 &i2c0_device,
334 &i2c1_device, 363 &i2c1_device,
335 &i2c2_device, 364 &i2c2_device,
336 &i2c3_device, 365 &i2c3_device,
337}; 366 &sata_device,
338
339static struct platform_device *r8a7779_late_devices[] __initdata = {
340}; 367};
341 368
342void __init r8a7779_add_standard_devices(void) 369void __init r8a7779_add_standard_devices(void)
@@ -349,8 +376,8 @@ void __init r8a7779_add_standard_devices(void)
349 376
350 r8a7779_init_pm_domains(); 377 r8a7779_init_pm_domains();
351 378
352 platform_add_devices(r8a7779_early_devices, 379 platform_add_devices(r8a7779_devices_dt,
353 ARRAY_SIZE(r8a7779_early_devices)); 380 ARRAY_SIZE(r8a7779_devices_dt));
354 platform_add_devices(r8a7779_late_devices, 381 platform_add_devices(r8a7779_late_devices,
355 ARRAY_SIZE(r8a7779_late_devices)); 382 ARRAY_SIZE(r8a7779_late_devices));
356} 383}
@@ -367,8 +394,8 @@ void __init r8a7779_earlytimer_init(void)
367 394
368void __init r8a7779_add_early_devices(void) 395void __init r8a7779_add_early_devices(void)
369{ 396{
370 early_platform_add_devices(r8a7779_early_devices, 397 early_platform_add_devices(r8a7779_devices_dt,
371 ARRAY_SIZE(r8a7779_early_devices)); 398 ARRAY_SIZE(r8a7779_devices_dt));
372 399
373 /* Early serial console setup is not included here due to 400 /* Early serial console setup is not included here due to
374 * memory map collisions. The SCIF serial ports in r8a7779 401 * memory map collisions. The SCIF serial ports in r8a7779
@@ -386,3 +413,40 @@ void __init r8a7779_add_early_devices(void)
386 * command line in case of the marzen board. 413 * command line in case of the marzen board.
387 */ 414 */
388} 415}
416
417#ifdef CONFIG_USE_OF
418void __init r8a7779_init_delay(void)
419{
420 shmobile_setup_delay(1000, 2, 4); /* Cortex-A9 @ 1000MHz */
421}
422
423static const struct of_dev_auxdata r8a7779_auxdata_lookup[] __initconst = {
424 {},
425};
426
427void __init r8a7779_add_standard_devices_dt(void)
428{
429 /* clocks are setup late during boot in the case of DT */
430 r8a7779_clock_init();
431
432 platform_add_devices(r8a7779_devices_dt,
433 ARRAY_SIZE(r8a7779_devices_dt));
434 of_platform_populate(NULL, of_default_bus_match_table,
435 r8a7779_auxdata_lookup, NULL);
436}
437
438static const char *r8a7779_compat_dt[] __initdata = {
439 "renesas,r8a7779",
440 NULL,
441};
442
443DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)")
444 .map_io = r8a7779_map_io,
445 .init_early = r8a7779_init_delay,
446 .nr_irqs = NR_IRQS_LEGACY,
447 .init_irq = r8a7779_init_irq_dt,
448 .init_machine = r8a7779_add_standard_devices_dt,
449 .init_time = shmobile_timer_init,
450 .dt_compat = r8a7779_compat_dt,
451MACHINE_END
452#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index bdab575f88bc..2257a915746d 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/irqchip.h>
25#include <linux/platform_device.h> 26#include <linux/platform_device.h>
26#include <linux/of_platform.h> 27#include <linux/of_platform.h>
27#include <linux/delay.h> 28#include <linux/delay.h>
@@ -810,7 +811,7 @@ static struct platform_device ipmmu_device = {
810 .num_resources = ARRAY_SIZE(ipmmu_resources), 811 .num_resources = ARRAY_SIZE(ipmmu_resources),
811}; 812};
812 813
813static struct platform_device *sh73a0_early_devices_dt[] __initdata = { 814static struct platform_device *sh73a0_devices_dt[] __initdata = {
814 &scif0_device, 815 &scif0_device,
815 &scif1_device, 816 &scif1_device,
816 &scif2_device, 817 &scif2_device,
@@ -847,8 +848,8 @@ void __init sh73a0_add_standard_devices(void)
847 /* Clear software reset bit on SY-DMAC module */ 848 /* Clear software reset bit on SY-DMAC module */
848 __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2); 849 __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2);
849 850
850 platform_add_devices(sh73a0_early_devices_dt, 851 platform_add_devices(sh73a0_devices_dt,
851 ARRAY_SIZE(sh73a0_early_devices_dt)); 852 ARRAY_SIZE(sh73a0_devices_dt));
852 platform_add_devices(sh73a0_early_devices, 853 platform_add_devices(sh73a0_early_devices,
853 ARRAY_SIZE(sh73a0_early_devices)); 854 ARRAY_SIZE(sh73a0_early_devices));
854 platform_add_devices(sh73a0_late_devices, 855 platform_add_devices(sh73a0_late_devices,
@@ -867,8 +868,8 @@ void __init sh73a0_earlytimer_init(void)
867 868
868void __init sh73a0_add_early_devices(void) 869void __init sh73a0_add_early_devices(void)
869{ 870{
870 early_platform_add_devices(sh73a0_early_devices_dt, 871 early_platform_add_devices(sh73a0_devices_dt,
871 ARRAY_SIZE(sh73a0_early_devices_dt)); 872 ARRAY_SIZE(sh73a0_devices_dt));
872 early_platform_add_devices(sh73a0_early_devices, 873 early_platform_add_devices(sh73a0_early_devices,
873 ARRAY_SIZE(sh73a0_early_devices)); 874 ARRAY_SIZE(sh73a0_early_devices));
874 875
@@ -878,23 +879,9 @@ void __init sh73a0_add_early_devices(void)
878 879
879#ifdef CONFIG_USE_OF 880#ifdef CONFIG_USE_OF
880 881
881/* Please note that the clock initialisation shcheme used in 882void __init sh73a0_init_delay(void)
882 * sh73a0_add_early_devices_dt() and sh73a0_add_standard_devices_dt()
883 * does not work with SMP as there is a yet to be resolved lock-up in
884 * workqueue initialisation.
885 *
886 * CONFIG_SMP should be disabled when using this code.
887 */
888
889void __init sh73a0_add_early_devices_dt(void)
890{ 883{
891 shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */ 884 shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */
892
893 early_platform_add_devices(sh73a0_early_devices_dt,
894 ARRAY_SIZE(sh73a0_early_devices_dt));
895
896 /* setup early console here as well */
897 shmobile_setup_console();
898} 885}
899 886
900static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = { 887static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = {
@@ -906,8 +893,8 @@ void __init sh73a0_add_standard_devices_dt(void)
906 /* clocks are setup late during boot in the case of DT */ 893 /* clocks are setup late during boot in the case of DT */
907 sh73a0_clock_init(); 894 sh73a0_clock_init();
908 895
909 platform_add_devices(sh73a0_early_devices_dt, 896 platform_add_devices(sh73a0_devices_dt,
910 ARRAY_SIZE(sh73a0_early_devices_dt)); 897 ARRAY_SIZE(sh73a0_devices_dt));
911 of_platform_populate(NULL, of_default_bus_match_table, 898 of_platform_populate(NULL, of_default_bus_match_table,
912 sh73a0_auxdata_lookup, NULL); 899 sh73a0_auxdata_lookup, NULL);
913} 900}
@@ -918,10 +905,11 @@ static const char *sh73a0_boards_compat_dt[] __initdata = {
918}; 905};
919 906
920DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") 907DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)")
908 .smp = smp_ops(sh73a0_smp_ops),
921 .map_io = sh73a0_map_io, 909 .map_io = sh73a0_map_io,
922 .init_early = sh73a0_add_early_devices_dt, 910 .init_early = sh73a0_init_delay,
923 .nr_irqs = NR_IRQS_LEGACY, 911 .nr_irqs = NR_IRQS_LEGACY,
924 .init_irq = sh73a0_init_irq_dt, 912 .init_irq = irqchip_init,
925 .init_machine = sh73a0_add_standard_devices_dt, 913 .init_machine = sh73a0_add_standard_devices_dt,
926 .init_time = shmobile_timer_init, 914 .init_time = shmobile_timer_init,
927 .dt_compat = sh73a0_boards_compat_dt, 915 .dt_compat = sh73a0_boards_compat_dt,
diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c
index 384e27dd3601..e38691b4d0dd 100644
--- a/arch/arm/mach-shmobile/smp-emev2.c
+++ b/arch/arm/mach-shmobile/smp-emev2.c
@@ -27,90 +27,35 @@
27#include <mach/emev2.h> 27#include <mach/emev2.h>
28#include <asm/smp_plat.h> 28#include <asm/smp_plat.h>
29#include <asm/smp_scu.h> 29#include <asm/smp_scu.h>
30#include <asm/cacheflush.h>
31 30
32#define EMEV2_SCU_BASE 0x1e000000 31#define EMEV2_SCU_BASE 0x1e000000
33 32
34static DEFINE_SPINLOCK(scu_lock);
35static void __iomem *scu_base;
36
37static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
38{
39 unsigned long tmp;
40
41 /* we assume this code is running on a different cpu
42 * than the one that is changing coherency setting */
43 spin_lock(&scu_lock);
44 tmp = readl(scu_base + 8);
45 tmp &= ~clr;
46 tmp |= set;
47 writel(tmp, scu_base + 8);
48 spin_unlock(&scu_lock);
49
50}
51
52static unsigned int __init emev2_get_core_count(void)
53{
54 if (!scu_base) {
55 scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE);
56 emev2_clock_init(); /* need ioremapped SMU */
57 }
58
59 WARN_ON_ONCE(!scu_base);
60
61 return scu_base ? scu_get_core_count(scu_base) : 1;
62}
63
64static int emev2_platform_cpu_kill(unsigned int cpu)
65{
66 return 0; /* not supported yet */
67}
68
69static int __maybe_unused emev2_cpu_kill(unsigned int cpu)
70{
71 int k;
72
73 /* this function is running on another CPU than the offline target,
74 * here we need wait for shutdown code in platform_cpu_die() to
75 * finish before asking SoC-specific code to power off the CPU core.
76 */
77 for (k = 0; k < 1000; k++) {
78 if (shmobile_cpu_is_dead(cpu))
79 return emev2_platform_cpu_kill(cpu);
80 mdelay(1);
81 }
82
83 return 0;
84}
85
86
87static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *idle) 33static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *idle)
88{ 34{
89 cpu = cpu_logical_map(cpu); 35 arch_send_wakeup_ipi_mask(cpumask_of(cpu_logical_map(cpu)));
90
91 /* enable cache coherency */
92 modify_scu_cpu_psr(0, 3 << (cpu * 8));
93
94 /* Tell ROM loader about our vector (in headsmp.S) */
95 emev2_set_boot_vector(__pa(shmobile_secondary_vector));
96
97 arch_send_wakeup_ipi_mask(cpumask_of(cpu));
98 return 0; 36 return 0;
99} 37}
100 38
101static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) 39static void __init emev2_smp_prepare_cpus(unsigned int max_cpus)
102{ 40{
103 int cpu = cpu_logical_map(0); 41 scu_enable(shmobile_scu_base);
104 42
105 scu_enable(scu_base); 43 /* Tell ROM loader about our vector (in headsmp-scu.S) */
44 emev2_set_boot_vector(__pa(shmobile_secondary_vector_scu));
106 45
107 /* enable cache coherency on CPU0 */ 46 /* enable cache coherency on booting CPU */
108 modify_scu_cpu_psr(0, 3 << (cpu * 8)); 47 scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
109} 48}
110 49
111static void __init emev2_smp_init_cpus(void) 50static void __init emev2_smp_init_cpus(void)
112{ 51{
113 unsigned int ncores = emev2_get_core_count(); 52 unsigned int ncores;
53
54 /* setup EMEV2 specific SCU base */
55 shmobile_scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE);
56 emev2_clock_init(); /* need ioremapped SMU */
57
58 ncores = shmobile_scu_base ? scu_get_core_count(shmobile_scu_base) : 1;
114 59
115 shmobile_smp_init_cpus(ncores); 60 shmobile_smp_init_cpus(ncores);
116} 61}
@@ -119,9 +64,4 @@ struct smp_operations emev2_smp_ops __initdata = {
119 .smp_init_cpus = emev2_smp_init_cpus, 64 .smp_init_cpus = emev2_smp_init_cpus,
120 .smp_prepare_cpus = emev2_smp_prepare_cpus, 65 .smp_prepare_cpus = emev2_smp_prepare_cpus,
121 .smp_boot_secondary = emev2_boot_secondary, 66 .smp_boot_secondary = emev2_boot_secondary,
122#ifdef CONFIG_HOTPLUG_CPU
123 .cpu_kill = emev2_cpu_kill,
124 .cpu_die = shmobile_cpu_die,
125 .cpu_disable = shmobile_cpu_disable,
126#endif
127}; 67};
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
index 994906560edd..a853bf182ed5 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -25,11 +25,13 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <mach/common.h> 26#include <mach/common.h>
27#include <mach/r8a7779.h> 27#include <mach/r8a7779.h>
28#include <asm/cacheflush.h>
28#include <asm/smp_plat.h> 29#include <asm/smp_plat.h>
29#include <asm/smp_scu.h> 30#include <asm/smp_scu.h>
30#include <asm/smp_twd.h> 31#include <asm/smp_twd.h>
31 32
32#define AVECR IOMEM(0xfe700040) 33#define AVECR IOMEM(0xfe700040)
34#define R8A7779_SCU_BASE 0xf0000000
33 35
34static struct r8a7779_pm_ch r8a7779_ch_cpu1 = { 36static struct r8a7779_pm_ch r8a7779_ch_cpu1 = {
35 .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */ 37 .chan_offs = 0x40, /* PWRSR0 .. PWRER0 */
@@ -55,44 +57,14 @@ static struct r8a7779_pm_ch *r8a7779_ch_cpu[4] = {
55 [3] = &r8a7779_ch_cpu3, 57 [3] = &r8a7779_ch_cpu3,
56}; 58};
57 59
58static void __iomem *scu_base_addr(void)
59{
60 return (void __iomem *)0xf0000000;
61}
62
63static DEFINE_SPINLOCK(scu_lock);
64static unsigned long tmp;
65
66#ifdef CONFIG_HAVE_ARM_TWD 60#ifdef CONFIG_HAVE_ARM_TWD
67static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); 61static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, R8A7779_SCU_BASE + 0x600, 29);
68
69void __init r8a7779_register_twd(void) 62void __init r8a7779_register_twd(void)
70{ 63{
71 twd_local_timer_register(&twd_local_timer); 64 twd_local_timer_register(&twd_local_timer);
72} 65}
73#endif 66#endif
74 67
75static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
76{
77 void __iomem *scu_base = scu_base_addr();
78
79 spin_lock(&scu_lock);
80 tmp = __raw_readl(scu_base + 8);
81 tmp &= ~clr;
82 tmp |= set;
83 spin_unlock(&scu_lock);
84
85 /* disable cache coherency after releasing the lock */
86 __raw_writel(tmp, scu_base + 8);
87}
88
89static unsigned int __init r8a7779_get_core_count(void)
90{
91 void __iomem *scu_base = scu_base_addr();
92
93 return scu_get_core_count(scu_base);
94}
95
96static int r8a7779_platform_cpu_kill(unsigned int cpu) 68static int r8a7779_platform_cpu_kill(unsigned int cpu)
97{ 69{
98 struct r8a7779_pm_ch *ch = NULL; 70 struct r8a7779_pm_ch *ch = NULL;
@@ -100,9 +72,6 @@ static int r8a7779_platform_cpu_kill(unsigned int cpu)
100 72
101 cpu = cpu_logical_map(cpu); 73 cpu = cpu_logical_map(cpu);
102 74
103 /* disable cache coherency */
104 modify_scu_cpu_psr(3 << (cpu * 8), 0);
105
106 if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) 75 if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
107 ch = r8a7779_ch_cpu[cpu]; 76 ch = r8a7779_ch_cpu[cpu];
108 77
@@ -112,25 +81,6 @@ static int r8a7779_platform_cpu_kill(unsigned int cpu)
112 return ret ? ret : 1; 81 return ret ? ret : 1;
113} 82}
114 83
115static int __maybe_unused r8a7779_cpu_kill(unsigned int cpu)
116{
117 int k;
118
119 /* this function is running on another CPU than the offline target,
120 * here we need wait for shutdown code in platform_cpu_die() to
121 * finish before asking SoC-specific code to power off the CPU core.
122 */
123 for (k = 0; k < 1000; k++) {
124 if (shmobile_cpu_is_dead(cpu))
125 return r8a7779_platform_cpu_kill(cpu);
126
127 mdelay(1);
128 }
129
130 return 0;
131}
132
133
134static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle) 84static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle)
135{ 85{
136 struct r8a7779_pm_ch *ch = NULL; 86 struct r8a7779_pm_ch *ch = NULL;
@@ -138,9 +88,6 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct
138 88
139 cpu = cpu_logical_map(cpu); 89 cpu = cpu_logical_map(cpu);
140 90
141 /* enable cache coherency */
142 modify_scu_cpu_psr(0, 3 << (cpu * 8));
143
144 if (cpu < ARRAY_SIZE(r8a7779_ch_cpu)) 91 if (cpu < ARRAY_SIZE(r8a7779_ch_cpu))
145 ch = r8a7779_ch_cpu[cpu]; 92 ch = r8a7779_ch_cpu[cpu];
146 93
@@ -152,15 +99,13 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct
152 99
153static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) 100static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus)
154{ 101{
155 int cpu = cpu_logical_map(0); 102 scu_enable(shmobile_scu_base);
156 103
157 scu_enable(scu_base_addr()); 104 /* Map the reset vector (in headsmp-scu.S) */
105 __raw_writel(__pa(shmobile_secondary_vector_scu), AVECR);
158 106
159 /* Map the reset vector (in headsmp.S) */ 107 /* enable cache coherency on booting CPU */
160 __raw_writel(__pa(shmobile_secondary_vector), AVECR); 108 scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
161
162 /* enable cache coherency on CPU0 */
163 modify_scu_cpu_psr(0, 3 << (cpu * 8));
164 109
165 r8a7779_pm_init(); 110 r8a7779_pm_init();
166 111
@@ -172,10 +117,60 @@ static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus)
172 117
173static void __init r8a7779_smp_init_cpus(void) 118static void __init r8a7779_smp_init_cpus(void)
174{ 119{
175 unsigned int ncores = r8a7779_get_core_count(); 120 /* setup r8a7779 specific SCU base */
121 shmobile_scu_base = IOMEM(R8A7779_SCU_BASE);
122
123 shmobile_smp_init_cpus(scu_get_core_count(shmobile_scu_base));
124}
176 125
177 shmobile_smp_init_cpus(ncores); 126#ifdef CONFIG_HOTPLUG_CPU
127static int r8a7779_scu_psr_core_disabled(int cpu)
128{
129 unsigned long mask = 3 << (cpu * 8);
130
131 if ((__raw_readl(shmobile_scu_base + 8) & mask) == mask)
132 return 1;
133
134 return 0;
135}
136
137static int r8a7779_cpu_kill(unsigned int cpu)
138{
139 int k;
140
141 /* this function is running on another CPU than the offline target,
142 * here we need wait for shutdown code in platform_cpu_die() to
143 * finish before asking SoC-specific code to power off the CPU core.
144 */
145 for (k = 0; k < 1000; k++) {
146 if (r8a7779_scu_psr_core_disabled(cpu))
147 return r8a7779_platform_cpu_kill(cpu);
148
149 mdelay(1);
150 }
151
152 return 0;
153}
154
155static void r8a7779_cpu_die(unsigned int cpu)
156{
157 dsb();
158 flush_cache_all();
159
160 /* disable cache coherency */
161 scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF);
162
163 /* Endless loop until power off from r8a7779_cpu_kill() */
164 while (1)
165 cpu_do_idle();
166}
167
168static int r8a7779_cpu_disable(unsigned int cpu)
169{
170 /* only CPU1->3 have power domains, do not allow hotplug of CPU0 */
171 return cpu == 0 ? -EPERM : 0;
178} 172}
173#endif /* CONFIG_HOTPLUG_CPU */
179 174
180struct smp_operations r8a7779_smp_ops __initdata = { 175struct smp_operations r8a7779_smp_ops __initdata = {
181 .smp_init_cpus = r8a7779_smp_init_cpus, 176 .smp_init_cpus = r8a7779_smp_init_cpus,
@@ -183,7 +178,7 @@ struct smp_operations r8a7779_smp_ops __initdata = {
183 .smp_boot_secondary = r8a7779_boot_secondary, 178 .smp_boot_secondary = r8a7779_boot_secondary,
184#ifdef CONFIG_HOTPLUG_CPU 179#ifdef CONFIG_HOTPLUG_CPU
185 .cpu_kill = r8a7779_cpu_kill, 180 .cpu_kill = r8a7779_cpu_kill,
186 .cpu_die = shmobile_cpu_die, 181 .cpu_die = r8a7779_cpu_die,
187 .cpu_disable = shmobile_cpu_disable, 182 .cpu_disable = r8a7779_cpu_disable,
188#endif 183#endif
189}; 184};
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index d0f9aca22477..bf79626ee5a4 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -38,26 +38,16 @@
38 38
39#define PSTR_SHUTDOWN_MODE 3 39#define PSTR_SHUTDOWN_MODE 3
40 40
41static void __iomem *scu_base_addr(void) 41#define SH73A0_SCU_BASE 0xf0000000
42{
43 return (void __iomem *)0xf0000000;
44}
45 42
46#ifdef CONFIG_HAVE_ARM_TWD 43#ifdef CONFIG_HAVE_ARM_TWD
47static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29); 44static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, SH73A0_SCU_BASE + 0x600, 29);
48void __init sh73a0_register_twd(void) 45void __init sh73a0_register_twd(void)
49{ 46{
50 twd_local_timer_register(&twd_local_timer); 47 twd_local_timer_register(&twd_local_timer);
51} 48}
52#endif 49#endif
53 50
54static unsigned int __init sh73a0_get_core_count(void)
55{
56 void __iomem *scu_base = scu_base_addr();
57
58 return scu_get_core_count(scu_base);
59}
60
61static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle) 51static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle)
62{ 52{
63 cpu = cpu_logical_map(cpu); 53 cpu = cpu_logical_map(cpu);
@@ -72,21 +62,22 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct
72 62
73static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) 63static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
74{ 64{
75 scu_enable(scu_base_addr()); 65 scu_enable(shmobile_scu_base);
76 66
77 /* Map the reset vector (in headsmp-sh73a0.S) */ 67 /* Map the reset vector (in headsmp-scu.S) */
78 __raw_writel(0, APARMBAREA); /* 4k */ 68 __raw_writel(0, APARMBAREA); /* 4k */
79 __raw_writel(__pa(sh73a0_secondary_vector), SBAR); 69 __raw_writel(__pa(shmobile_secondary_vector_scu), SBAR);
80 70
81 /* enable cache coherency on booting CPU */ 71 /* enable cache coherency on booting CPU */
82 scu_power_mode(scu_base_addr(), SCU_PM_NORMAL); 72 scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL);
83} 73}
84 74
85static void __init sh73a0_smp_init_cpus(void) 75static void __init sh73a0_smp_init_cpus(void)
86{ 76{
87 unsigned int ncores = sh73a0_get_core_count(); 77 /* setup sh73a0 specific SCU base */
78 shmobile_scu_base = IOMEM(SH73A0_SCU_BASE);
88 79
89 shmobile_smp_init_cpus(ncores); 80 shmobile_smp_init_cpus(scu_get_core_count(shmobile_scu_base));
90} 81}
91 82
92#ifdef CONFIG_HOTPLUG_CPU 83#ifdef CONFIG_HOTPLUG_CPU
@@ -122,11 +113,16 @@ static void sh73a0_cpu_die(unsigned int cpu)
122 flush_cache_all(); 113 flush_cache_all();
123 114
124 /* Set power off mode. This takes the CPU out of the MP cluster */ 115 /* Set power off mode. This takes the CPU out of the MP cluster */
125 scu_power_mode(scu_base_addr(), SCU_PM_POWEROFF); 116 scu_power_mode(shmobile_scu_base, SCU_PM_POWEROFF);
126 117
127 /* Enter shutdown mode */ 118 /* Enter shutdown mode */
128 cpu_do_idle(); 119 cpu_do_idle();
129} 120}
121
122static int sh73a0_cpu_disable(unsigned int cpu)
123{
124 return 0; /* CPU0 and CPU1 supported */
125}
130#endif /* CONFIG_HOTPLUG_CPU */ 126#endif /* CONFIG_HOTPLUG_CPU */
131 127
132struct smp_operations sh73a0_smp_ops __initdata = { 128struct smp_operations sh73a0_smp_ops __initdata = {
@@ -136,6 +132,6 @@ struct smp_operations sh73a0_smp_ops __initdata = {
136#ifdef CONFIG_HOTPLUG_CPU 132#ifdef CONFIG_HOTPLUG_CPU
137 .cpu_kill = sh73a0_cpu_kill, 133 .cpu_kill = sh73a0_cpu_kill,
138 .cpu_die = sh73a0_cpu_die, 134 .cpu_die = sh73a0_cpu_die,
139 .cpu_disable = shmobile_cpu_disable_any, 135 .cpu_disable = sh73a0_cpu_disable,
140#endif 136#endif
141}; 137};