forked from luck/tmp_suning_uos_patched
Merge branch 'soc' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/soc
From Simon Horman, a series of SoC updates for shmobile. * 'soc' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas: ARM: shmobile: r8a7779: scif .irqs used SCIx_IRQ_MUXED() ARM: mach-shmobile: sh73a0: Initialise MMCIF using DT ARM: mach-shmobile: sh73a0: Minimal setup using DT ARM: mach-shmobile: sh73a0: Allow initialisation of GIC by DT ARM: SH-Mobile: sh73a0: Add CPU Hotplug ARM: SH-Mobile: sh73a0: Secondary CPUs handle own SCU flags ARM: shmobile: r8a7740: Add CPU sleep suspend ARM: shmobile: sh73a0: Add CPU sleep suspend ARM: shmobile: add function declarations for sh7372 DT helper functions ARM: sh7372: fix cache clean / invalidate order ARM: sh7372: add clock lookup entries for DT-based devices ARM: mach-shmobile: sh73a0 external IRQ wake update ARM: shmobile: sh73a0: fixup div4_clks bitmap ARM: shmobile: r8a7740: add TMU timer support ARM: shmobile: Remove duplicate inclusion of dma-mapping.h in setup-r8a7740.c Signed-off-by: Olof Johansson <olof@lixom.net> Fix trivial conflict in board_bcm due to Simon resolving the same conflict with one less line of whitespace. Keeping end result common with what we already have in arm-soc. Conflicts: arch/arm/mach-bcm/board_bcm.c
This commit is contained in:
commit
0475e57fc3
24
arch/arm/boot/dts/sh73a0-reference.dtsi
Normal file
24
arch/arm/boot/dts/sh73a0-reference.dtsi
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Device Tree Source for the SH73A0 SoC
|
||||
*
|
||||
* Copyright (C) 2012 Renesas Solutions Corp.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
/include/ "sh73a0.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "renesas,sh73a0";
|
||||
|
||||
mmcif: mmcif@0x10010000 {
|
||||
compatible = "renesas,sh-mmcif";
|
||||
reg = <0xe6bd0000 0x100>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <0 140 0x4
|
||||
0 141 0x4>;
|
||||
reg-io-width = <4>;
|
||||
};
|
||||
};
|
93
arch/arm/boot/dts/sh73a0.dtsi
Normal file
93
arch/arm/boot/dts/sh73a0.dtsi
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Device Tree Source for the SH73A0 SoC
|
||||
*
|
||||
* Copyright (C) 2012 Renesas Solutions Corp.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
/include/ "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "renesas,sh73a0";
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "arm,cortex-a9";
|
||||
};
|
||||
cpu@1 {
|
||||
compatible = "arm,cortex-a9";
|
||||
};
|
||||
};
|
||||
|
||||
gic: interrupt-controller@f0001000 {
|
||||
compatible = "arm,cortex-a9-gic";
|
||||
#interrupt-cells = <3>;
|
||||
#address-cells = <1>;
|
||||
interrupt-controller;
|
||||
reg = <0xf0001000 0x1000>,
|
||||
<0xf0000100 0x100>;
|
||||
};
|
||||
|
||||
i2c0: i2c@0xe6820000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "renesas,rmobile-iic";
|
||||
reg = <0xe6820000 0x425>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <0 167 0x4
|
||||
0 168 0x4
|
||||
0 169 0x4
|
||||
0 170 0x4>;
|
||||
};
|
||||
|
||||
i2c1: i2c@0xe6822000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "renesas,rmobile-iic";
|
||||
reg = <0xe6822000 0x425>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <0 51 0x4
|
||||
0 52 0x4
|
||||
0 53 0x4
|
||||
0 54 0x4>;
|
||||
};
|
||||
|
||||
i2c2: i2c@0xe6824000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "renesas,rmobile-iic";
|
||||
reg = <0xe6824000 0x425>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <0 171 0x4
|
||||
0 172 0x4
|
||||
0 173 0x4
|
||||
0 174 0x4>;
|
||||
};
|
||||
|
||||
i2c3: i2c@0xe6826000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "renesas,rmobile-iic";
|
||||
reg = <0xe6826000 0x425>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <0 183 0x4
|
||||
0 184 0x4
|
||||
0 185 0x4
|
||||
0 186 0x4>;
|
||||
};
|
||||
|
||||
i2c4: i2c@0xe6828000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "renesas,rmobile-iic";
|
||||
reg = <0xe6828000 0x425>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <0 187 0x4
|
||||
0 188 0x4
|
||||
0 189 0x4
|
||||
0 190 0x4>;
|
||||
};
|
||||
};
|
@ -15,7 +15,7 @@ obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o clock-emev2.o
|
||||
# SMP objects
|
||||
smp-y := platsmp.o headsmp.o
|
||||
smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o
|
||||
smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-sh73a0.o
|
||||
smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o
|
||||
smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o
|
||||
|
||||
@ -37,6 +37,7 @@ obj-$(CONFIG_ARCH_SHMOBILE) += pm-rmobile.o
|
||||
obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o
|
||||
obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o
|
||||
obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o
|
||||
obj-$(CONFIG_ARCH_SH73A0) += pm-sh73a0.o
|
||||
|
||||
# Board objects
|
||||
obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o
|
||||
|
@ -1181,6 +1181,8 @@ static void __init eva_init(void)
|
||||
rmobile_add_device_to_domain("A4LC", &hdmi_lcdc_device);
|
||||
if (usb)
|
||||
rmobile_add_device_to_domain("A3SP", usb);
|
||||
|
||||
r8a7740_pm_init();
|
||||
}
|
||||
|
||||
static void __init eva_earlytimer_init(void)
|
||||
|
@ -772,6 +772,8 @@ static void __init kzm_init(void)
|
||||
|
||||
sh73a0_add_standard_devices();
|
||||
platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices));
|
||||
|
||||
sh73a0_pm_init();
|
||||
}
|
||||
|
||||
static void kzm9g_restart(char mode, const char *cmd)
|
||||
|
@ -581,10 +581,14 @@ static struct clk_lookup lookups[] = {
|
||||
|
||||
/* MSTP32 clocks */
|
||||
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]),
|
||||
CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP111]),
|
||||
CLKDEV_DEV_ID("sh_tmu.3", &mstp_clks[MSTP111]),
|
||||
CLKDEV_DEV_ID("sh_tmu.4", &mstp_clks[MSTP111]),
|
||||
CLKDEV_DEV_ID("sh_tmu.5", &mstp_clks[MSTP111]),
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]),
|
||||
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]),
|
||||
CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]),
|
||||
CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]),
|
||||
CLKDEV_DEV_ID("sh_tmu.2", &mstp_clks[MSTP125]),
|
||||
CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]),
|
||||
CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]),
|
||||
|
||||
|
@ -544,6 +544,7 @@ static struct clk_lookup lookups[] = {
|
||||
|
||||
/* MSTP32 clocks */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
|
||||
CLKDEV_DEV_ID("fff30000.i2c", &mstp_clks[MSTP001]), /* IIC2 */
|
||||
CLKDEV_DEV_ID("spi_sh_msiof.0", &mstp_clks[MSTP000]), /* MSIOF0 */
|
||||
CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
|
||||
CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
|
||||
@ -556,6 +557,7 @@ static struct clk_lookup lookups[] = {
|
||||
CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
|
||||
CLKDEV_DEV_ID("fff20000.i2c", &mstp_clks[MSTP116]), /* IIC0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
|
||||
CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
|
||||
CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
|
||||
@ -577,18 +579,25 @@ static struct clk_lookup lookups[] = {
|
||||
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
|
||||
CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
|
||||
CLKDEV_DEV_ID("e6c20000.i2c", &mstp_clks[MSTP323]), /* IIC1 */
|
||||
CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
|
||||
CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
|
||||
CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
|
||||
CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
|
||||
CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]), /* SDHI0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
|
||||
CLKDEV_DEV_ID("e6860000.sdhi", &mstp_clks[MSTP313]), /* SDHI1 */
|
||||
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
|
||||
CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMC */
|
||||
CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
|
||||
CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]), /* SDHI2 */
|
||||
CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
|
||||
CLKDEV_DEV_ID("e6d20000.i2c", &mstp_clks[MSTP411]), /* IIC3 */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
|
||||
CLKDEV_DEV_ID("e6d30000.i2c", &mstp_clks[MSTP410]), /* IIC4 */
|
||||
CLKDEV_DEV_ID("sh-dma-engine.4", &mstp_clks[MSTP407]), /* USB-DMAC1 */
|
||||
CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
|
||||
CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
|
||||
|
@ -264,17 +264,17 @@ enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
|
||||
SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
|
||||
|
||||
static struct clk div4_clks[DIV4_NR] = {
|
||||
[DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_M3] = DIV4(FRQCRA, 12, 0xfff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0),
|
||||
[DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0),
|
||||
[DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0),
|
||||
[DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0),
|
||||
[DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0),
|
||||
[DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0),
|
||||
[DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0),
|
||||
[DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_ZG] = DIV4(FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_M1] = DIV4(FRQCRA, 4, 0x1dff, 0),
|
||||
[DIV4_M2] = DIV4(FRQCRA, 0, 0x1dff, 0),
|
||||
[DIV4_Z] = DIV4(FRQCRB, 24, 0x97f, 0),
|
||||
[DIV4_ZTR] = DIV4(FRQCRB, 20, 0xdff, 0),
|
||||
[DIV4_ZT] = DIV4(FRQCRB, 16, 0xdff, 0),
|
||||
[DIV4_ZX] = DIV4(FRQCRB, 12, 0xdff, 0),
|
||||
[DIV4_HP] = DIV4(FRQCRB, 4, 0xdff, 0),
|
||||
};
|
||||
|
||||
enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
|
||||
@ -525,6 +525,13 @@ static struct clk mstp_clks[MSTP_NR] = {
|
||||
[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
|
||||
};
|
||||
|
||||
/* The lookups structure below includes duplicate entries for some clocks
|
||||
* with alternate names.
|
||||
* - The traditional name used when a device is initialised with platform data
|
||||
* - The name used when a device is initialised using device tree
|
||||
* The longer-term aim is to remove these duplicates, and indeed the
|
||||
* lookups table entirely, by describing clocks using device tree.
|
||||
*/
|
||||
static struct clk_lookup lookups[] = {
|
||||
/* main clocks */
|
||||
CLKDEV_CON_ID("r_clk", &r_clk),
|
||||
@ -545,6 +552,7 @@ static struct clk_lookup lookups[] = {
|
||||
|
||||
/* MSTP32 clocks */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
|
||||
CLKDEV_DEV_ID("e6824000.i2c", &mstp_clks[MSTP001]), /* I2C2 */
|
||||
CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
|
||||
CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
|
||||
CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
|
||||
@ -553,6 +561,7 @@ static struct clk_lookup lookups[] = {
|
||||
CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
|
||||
CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
|
||||
CLKDEV_DEV_ID("e6820000.i2c", &mstp_clks[MSTP116]), /* I2C0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
|
||||
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
|
||||
CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
|
||||
@ -569,17 +578,21 @@ static struct clk_lookup lookups[] = {
|
||||
CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
|
||||
CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
|
||||
CLKDEV_DEV_ID("e6822000.i2c", &mstp_clks[MSTP323]), /* I2C1 */
|
||||
CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
|
||||
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
|
||||
CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]), /* MMCIF0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
|
||||
CLKDEV_DEV_ID("leds-renesas-tpu.12", &mstp_clks[MSTP303]), /* TPU1 */
|
||||
CLKDEV_DEV_ID("leds-renesas-tpu.21", &mstp_clks[MSTP302]), /* TPU2 */
|
||||
CLKDEV_DEV_ID("leds-renesas-tpu.30", &mstp_clks[MSTP301]), /* TPU3 */
|
||||
CLKDEV_DEV_ID("leds-renesas-tpu.41", &mstp_clks[MSTP300]), /* TPU4 */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
|
||||
CLKDEV_DEV_ID("e6826000.i2c", &mstp_clks[MSTP411]), /* I2C3 */
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
|
||||
CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
|
||||
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
|
||||
};
|
||||
|
||||
|
50
arch/arm/mach-shmobile/headsmp-sh73a0.S
Normal file
50
arch/arm/mach-shmobile/headsmp-sh73a0.S
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* SMP support for SoC sh73a0
|
||||
*
|
||||
* Copyright (C) 2012 Bastian Hecht
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/memory.h>
|
||||
|
||||
__CPUINIT
|
||||
/*
|
||||
* Reset vector for secondary CPUs.
|
||||
*
|
||||
* First we turn on L1 cache coherency for our CPU. Then we jump to
|
||||
* shmobile_invalidate_start that invalidates the cache and hands over control
|
||||
* to the common ARM startup code.
|
||||
* This function will be mapped to address 0 by the SBAR register.
|
||||
* A normal branch is out of range here so we need a long jump. We jump to
|
||||
* the physical address as the MMU is still turned off.
|
||||
*/
|
||||
.align 12
|
||||
ENTRY(sh73a0_secondary_vector)
|
||||
mrc p15, 0, r0, c0, c0, 5 @ read MIPDR
|
||||
and r0, r0, #3 @ mask out cpu ID
|
||||
lsl r0, r0, #3 @ we will shift by cpu_id * 8 bits
|
||||
mov r1, #0xf0000000 @ SCU base address
|
||||
ldr r2, [r1, #8] @ SCU Power Status Register
|
||||
mov r3, #3
|
||||
bic r2, r2, r3, lsl r0 @ Clear bits of our CPU (Run Mode)
|
||||
str r2, [r1, #8] @ write back
|
||||
|
||||
ldr pc, 1f
|
||||
1: .long shmobile_invalidate_start - PAGE_OFFSET + PLAT_PHYS_OFFSET
|
||||
ENDPROC(sh73a0_secondary_vector)
|
@ -23,6 +23,8 @@ extern void sh7372_map_io(void);
|
||||
extern void sh7372_earlytimer_init(void);
|
||||
extern void sh7372_add_early_devices(void);
|
||||
extern void sh7372_add_standard_devices(void);
|
||||
extern void sh7372_add_early_devices_dt(void);
|
||||
extern void sh7372_add_standard_devices_dt(void);
|
||||
extern void sh7372_clock_init(void);
|
||||
extern void sh7372_pinmux_init(void);
|
||||
extern void sh7372_pm_init(void);
|
||||
@ -32,12 +34,17 @@ extern struct clk sh7372_extal1_clk;
|
||||
extern struct clk sh7372_extal2_clk;
|
||||
|
||||
extern void sh73a0_init_irq(void);
|
||||
extern void sh73a0_init_irq_dt(void);
|
||||
extern void sh73a0_map_io(void);
|
||||
extern void sh73a0_earlytimer_init(void);
|
||||
extern void sh73a0_add_early_devices(void);
|
||||
extern void sh73a0_add_early_devices_dt(void);
|
||||
extern void sh73a0_add_standard_devices(void);
|
||||
extern void sh73a0_add_standard_devices_dt(void);
|
||||
extern void sh73a0_clock_init(void);
|
||||
extern void sh73a0_pinmux_init(void);
|
||||
extern void sh73a0_pm_init(void);
|
||||
extern void sh73a0_secondary_vector(void);
|
||||
extern struct clk sh73a0_extal1_clk;
|
||||
extern struct clk sh73a0_extal2_clk;
|
||||
extern struct clk sh73a0_extcki_clk;
|
||||
@ -49,6 +56,7 @@ extern void r8a7740_add_early_devices(void);
|
||||
extern void r8a7740_add_standard_devices(void);
|
||||
extern void r8a7740_clock_init(u8 md_ck);
|
||||
extern void r8a7740_pinmux_init(void);
|
||||
extern void r8a7740_pm_init(void);
|
||||
|
||||
extern void r8a7779_init_irq(void);
|
||||
extern void r8a7779_map_io(void);
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/sh_intc.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/irqchip/arm-gic.h>
|
||||
#include <mach/intc.h>
|
||||
#include <mach/irqs.h>
|
||||
@ -315,11 +316,6 @@ static int intca_gic_set_type(struct irq_data *data, unsigned int type)
|
||||
return irq_cbp(irq_set_type, to_intca_reloc_irq(data), type);
|
||||
}
|
||||
|
||||
static int intca_gic_set_wake(struct irq_data *data, unsigned int on)
|
||||
{
|
||||
return irq_cbp(irq_set_wake, to_intca_reloc_irq(data), on);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static int intca_gic_set_affinity(struct irq_data *data,
|
||||
const struct cpumask *cpumask,
|
||||
@ -339,7 +335,7 @@ struct irq_chip intca_gic_irq_chip = {
|
||||
.irq_disable = intca_gic_disable,
|
||||
.irq_shutdown = intca_gic_disable,
|
||||
.irq_set_type = intca_gic_set_type,
|
||||
.irq_set_wake = intca_gic_set_wake,
|
||||
.irq_set_wake = sh73a0_set_wake,
|
||||
#ifdef CONFIG_SMP
|
||||
.irq_set_affinity = intca_gic_set_affinity,
|
||||
#endif
|
||||
@ -464,3 +460,11 @@ void __init sh73a0_init_irq(void)
|
||||
sh73a0_pint1_cascade.handler = sh73a0_pint1_demux;
|
||||
setup_irq(gic_spi(34), &sh73a0_pint1_cascade);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
void __init sh73a0_init_irq_dt(void)
|
||||
{
|
||||
irqchip_init();
|
||||
gic_arch_extn.irq_set_wake = sh73a0_set_wake;
|
||||
}
|
||||
#endif
|
||||
|
@ -9,7 +9,9 @@
|
||||
* for more details.
|
||||
*/
|
||||
#include <linux/console.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <mach/pm-rmobile.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int r8a7740_pd_a4s_suspend(void)
|
||||
@ -58,3 +60,23 @@ void __init r8a7740_init_pm_domains(void)
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
static int r8a7740_enter_suspend(suspend_state_t suspend_state)
|
||||
{
|
||||
cpu_do_idle();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void r8a7740_suspend_init(void)
|
||||
{
|
||||
shmobile_suspend_ops.enter = r8a7740_enter_suspend;
|
||||
}
|
||||
#else
|
||||
static void r8a7740_suspend_init(void) {}
|
||||
#endif
|
||||
|
||||
void __init r8a7740_pm_init(void)
|
||||
{
|
||||
r8a7740_suspend_init();
|
||||
}
|
||||
|
32
arch/arm/mach-shmobile/pm-sh73a0.c
Normal file
32
arch/arm/mach-shmobile/pm-sh73a0.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* sh73a0 Power management support
|
||||
*
|
||||
* Copyright (C) 2012 Bastian Hecht <hechtb+renesas@gmail.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/suspend.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
static int sh73a0_enter_suspend(suspend_state_t suspend_state)
|
||||
{
|
||||
cpu_do_idle();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sh73a0_suspend_init(void)
|
||||
{
|
||||
shmobile_suspend_ops.enter = sh73a0_enter_suspend;
|
||||
}
|
||||
#else
|
||||
static void sh73a0_suspend_init(void) {}
|
||||
#endif
|
||||
|
||||
void __init sh73a0_pm_init(void)
|
||||
{
|
||||
sh73a0_suspend_init();
|
||||
}
|
@ -27,7 +27,6 @@
|
||||
#include <linux/serial_sci.h>
|
||||
#include <linux/sh_dma.h>
|
||||
#include <linux/sh_timer.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <mach/dma-register.h>
|
||||
#include <mach/r8a7740.h>
|
||||
#include <mach/pm-rmobile.h>
|
||||
@ -262,6 +261,97 @@ static struct platform_device cmt10_device = {
|
||||
.num_resources = ARRAY_SIZE(cmt10_resources),
|
||||
};
|
||||
|
||||
/* TMU */
|
||||
static struct sh_timer_config tmu00_platform_data = {
|
||||
.name = "TMU00",
|
||||
.channel_offset = 0x4,
|
||||
.timer_bit = 0,
|
||||
.clockevent_rating = 200,
|
||||
};
|
||||
|
||||
static struct resource tmu00_resources[] = {
|
||||
[0] = {
|
||||
.name = "TMU00",
|
||||
.start = 0xfff80008,
|
||||
.end = 0xfff80014 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = intcs_evt2irq(0xe80),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device tmu00_device = {
|
||||
.name = "sh_tmu",
|
||||
.id = 0,
|
||||
.dev = {
|
||||
.platform_data = &tmu00_platform_data,
|
||||
},
|
||||
.resource = tmu00_resources,
|
||||
.num_resources = ARRAY_SIZE(tmu00_resources),
|
||||
};
|
||||
|
||||
static struct sh_timer_config tmu01_platform_data = {
|
||||
.name = "TMU01",
|
||||
.channel_offset = 0x10,
|
||||
.timer_bit = 1,
|
||||
.clocksource_rating = 200,
|
||||
};
|
||||
|
||||
static struct resource tmu01_resources[] = {
|
||||
[0] = {
|
||||
.name = "TMU01",
|
||||
.start = 0xfff80014,
|
||||
.end = 0xfff80020 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = intcs_evt2irq(0xea0),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device tmu01_device = {
|
||||
.name = "sh_tmu",
|
||||
.id = 1,
|
||||
.dev = {
|
||||
.platform_data = &tmu01_platform_data,
|
||||
},
|
||||
.resource = tmu01_resources,
|
||||
.num_resources = ARRAY_SIZE(tmu01_resources),
|
||||
};
|
||||
|
||||
static struct sh_timer_config tmu02_platform_data = {
|
||||
.name = "TMU02",
|
||||
.channel_offset = 0x1C,
|
||||
.timer_bit = 2,
|
||||
.clocksource_rating = 200,
|
||||
};
|
||||
|
||||
static struct resource tmu02_resources[] = {
|
||||
[0] = {
|
||||
.name = "TMU02",
|
||||
.start = 0xfff80020,
|
||||
.end = 0xfff8002C - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = intcs_evt2irq(0xec0),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device tmu02_device = {
|
||||
.name = "sh_tmu",
|
||||
.id = 2,
|
||||
.dev = {
|
||||
.platform_data = &tmu02_platform_data,
|
||||
},
|
||||
.resource = tmu02_resources,
|
||||
.num_resources = ARRAY_SIZE(tmu02_resources),
|
||||
};
|
||||
|
||||
static struct platform_device *r8a7740_early_devices[] __initdata = {
|
||||
&scif0_device,
|
||||
&scif1_device,
|
||||
@ -273,6 +363,9 @@ static struct platform_device *r8a7740_early_devices[] __initdata = {
|
||||
&scif7_device,
|
||||
&scifb_device,
|
||||
&cmt10_device,
|
||||
&tmu00_device,
|
||||
&tmu01_device,
|
||||
&tmu02_device,
|
||||
};
|
||||
|
||||
/* DMA */
|
||||
|
@ -66,8 +66,7 @@ static struct plat_sci_port scif0_platform_data = {
|
||||
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
|
||||
.scbrr_algo_id = SCBRR_ALGO_2,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { gic_spi(88), gic_spi(88),
|
||||
gic_spi(88), gic_spi(88) },
|
||||
.irqs = SCIx_IRQ_MUXED(gic_spi(88)),
|
||||
};
|
||||
|
||||
static struct platform_device scif0_device = {
|
||||
@ -84,8 +83,7 @@ static struct plat_sci_port scif1_platform_data = {
|
||||
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
|
||||
.scbrr_algo_id = SCBRR_ALGO_2,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { gic_spi(89), gic_spi(89),
|
||||
gic_spi(89), gic_spi(89) },
|
||||
.irqs = SCIx_IRQ_MUXED(gic_spi(89)),
|
||||
};
|
||||
|
||||
static struct platform_device scif1_device = {
|
||||
@ -102,8 +100,7 @@ static struct plat_sci_port scif2_platform_data = {
|
||||
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
|
||||
.scbrr_algo_id = SCBRR_ALGO_2,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { gic_spi(90), gic_spi(90),
|
||||
gic_spi(90), gic_spi(90) },
|
||||
.irqs = SCIx_IRQ_MUXED(gic_spi(90)),
|
||||
};
|
||||
|
||||
static struct platform_device scif2_device = {
|
||||
@ -120,8 +117,7 @@ static struct plat_sci_port scif3_platform_data = {
|
||||
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
|
||||
.scbrr_algo_id = SCBRR_ALGO_2,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { gic_spi(91), gic_spi(91),
|
||||
gic_spi(91), gic_spi(91) },
|
||||
.irqs = SCIx_IRQ_MUXED(gic_spi(91)),
|
||||
};
|
||||
|
||||
static struct platform_device scif3_device = {
|
||||
@ -138,8 +134,7 @@ static struct plat_sci_port scif4_platform_data = {
|
||||
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
|
||||
.scbrr_algo_id = SCBRR_ALGO_2,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { gic_spi(92), gic_spi(92),
|
||||
gic_spi(92), gic_spi(92) },
|
||||
.irqs = SCIx_IRQ_MUXED(gic_spi(92)),
|
||||
};
|
||||
|
||||
static struct platform_device scif4_device = {
|
||||
@ -156,8 +151,7 @@ static struct plat_sci_port scif5_platform_data = {
|
||||
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
|
||||
.scbrr_algo_id = SCBRR_ALGO_2,
|
||||
.type = PORT_SCIF,
|
||||
.irqs = { gic_spi(93), gic_spi(93),
|
||||
gic_spi(93), gic_spi(93) },
|
||||
.irqs = SCIx_IRQ_MUXED(gic_spi(93)),
|
||||
};
|
||||
|
||||
static struct platform_device scif5_device = {
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/io.h>
|
||||
@ -754,7 +755,7 @@ static struct platform_device pmu_device = {
|
||||
.resource = pmu_resources,
|
||||
};
|
||||
|
||||
static struct platform_device *sh73a0_early_devices[] __initdata = {
|
||||
static struct platform_device *sh73a0_early_devices_dt[] __initdata = {
|
||||
&scif0_device,
|
||||
&scif1_device,
|
||||
&scif2_device,
|
||||
@ -765,6 +766,9 @@ static struct platform_device *sh73a0_early_devices[] __initdata = {
|
||||
&scif7_device,
|
||||
&scif8_device,
|
||||
&cmt10_device,
|
||||
};
|
||||
|
||||
static struct platform_device *sh73a0_early_devices[] __initdata = {
|
||||
&tmu00_device,
|
||||
&tmu01_device,
|
||||
};
|
||||
@ -787,6 +791,8 @@ void __init sh73a0_add_standard_devices(void)
|
||||
/* Clear software reset bit on SY-DMAC module */
|
||||
__raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2);
|
||||
|
||||
platform_add_devices(sh73a0_early_devices_dt,
|
||||
ARRAY_SIZE(sh73a0_early_devices_dt));
|
||||
platform_add_devices(sh73a0_early_devices,
|
||||
ARRAY_SIZE(sh73a0_early_devices));
|
||||
platform_add_devices(sh73a0_late_devices,
|
||||
@ -805,9 +811,63 @@ void __init sh73a0_earlytimer_init(void)
|
||||
|
||||
void __init sh73a0_add_early_devices(void)
|
||||
{
|
||||
early_platform_add_devices(sh73a0_early_devices_dt,
|
||||
ARRAY_SIZE(sh73a0_early_devices_dt));
|
||||
early_platform_add_devices(sh73a0_early_devices,
|
||||
ARRAY_SIZE(sh73a0_early_devices));
|
||||
|
||||
/* setup early console here as well */
|
||||
shmobile_setup_console();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USE_OF
|
||||
|
||||
/* Please note that the clock initialisation shcheme used in
|
||||
* sh73a0_add_early_devices_dt() and sh73a0_add_standard_devices_dt()
|
||||
* does not work with SMP as there is a yet to be resolved lock-up in
|
||||
* workqueue initialisation.
|
||||
*
|
||||
* CONFIG_SMP should be disabled when using this code.
|
||||
*/
|
||||
|
||||
void __init sh73a0_add_early_devices_dt(void)
|
||||
{
|
||||
shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */
|
||||
|
||||
early_platform_add_devices(sh73a0_early_devices_dt,
|
||||
ARRAY_SIZE(sh73a0_early_devices_dt));
|
||||
|
||||
/* setup early console here as well */
|
||||
shmobile_setup_console();
|
||||
}
|
||||
|
||||
static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = {
|
||||
{},
|
||||
};
|
||||
|
||||
void __init sh73a0_add_standard_devices_dt(void)
|
||||
{
|
||||
/* clocks are setup late during boot in the case of DT */
|
||||
sh73a0_clock_init();
|
||||
|
||||
platform_add_devices(sh73a0_early_devices_dt,
|
||||
ARRAY_SIZE(sh73a0_early_devices_dt));
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
sh73a0_auxdata_lookup, NULL);
|
||||
}
|
||||
|
||||
static const char *sh73a0_boards_compat_dt[] __initdata = {
|
||||
"renesas,sh73a0",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)")
|
||||
.map_io = sh73a0_map_io,
|
||||
.init_early = sh73a0_add_early_devices_dt,
|
||||
.nr_irqs = NR_IRQS_LEGACY,
|
||||
.init_irq = sh73a0_init_irq_dt,
|
||||
.init_machine = sh73a0_add_standard_devices_dt,
|
||||
.init_time = shmobile_timer_init,
|
||||
.dt_compat = sh73a0_boards_compat_dt,
|
||||
MACHINE_END
|
||||
#endif /* CONFIG_USE_OF */
|
||||
|
@ -59,16 +59,18 @@ sh7372_do_idle_sysc:
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
isb
|
||||
|
||||
/*
|
||||
* Clean and invalidate data cache again.
|
||||
*/
|
||||
ldr r1, kernel_flush
|
||||
blx r1
|
||||
|
||||
/* disable L2 cache in the aux control register */
|
||||
mrc p15, 0, r10, c1, c0, 1
|
||||
bic r10, r10, #2
|
||||
mcr p15, 0, r10, c1, c0, 1
|
||||
isb
|
||||
|
||||
/*
|
||||
* Invalidate data cache again.
|
||||
*/
|
||||
ldr r1, kernel_flush
|
||||
blx r1
|
||||
/*
|
||||
* The kernel doesn't interwork: v7_flush_dcache_all in particluar will
|
||||
* always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled.
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/irqchip/arm-gic.h>
|
||||
#include <mach/common.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <mach/sh73a0.h>
|
||||
#include <asm/smp_scu.h>
|
||||
@ -36,14 +37,13 @@
|
||||
#define SBAR IOMEM(0xe6180020)
|
||||
#define APARMBAREA IOMEM(0xe6f10020)
|
||||
|
||||
#define PSTR_SHUTDOWN_MODE 3
|
||||
|
||||
static void __iomem *scu_base_addr(void)
|
||||
{
|
||||
return (void __iomem *)0xf0000000;
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(scu_lock);
|
||||
static unsigned long tmp;
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_TWD
|
||||
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
|
||||
void __init sh73a0_register_twd(void)
|
||||
@ -52,20 +52,6 @@ void __init sh73a0_register_twd(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
|
||||
{
|
||||
void __iomem *scu_base = scu_base_addr();
|
||||
|
||||
spin_lock(&scu_lock);
|
||||
tmp = __raw_readl(scu_base + 8);
|
||||
tmp &= ~clr;
|
||||
tmp |= set;
|
||||
spin_unlock(&scu_lock);
|
||||
|
||||
/* disable cache coherency after releasing the lock */
|
||||
__raw_writel(tmp, scu_base + 8);
|
||||
}
|
||||
|
||||
static unsigned int __init sh73a0_get_core_count(void)
|
||||
{
|
||||
void __iomem *scu_base = scu_base_addr();
|
||||
@ -82,9 +68,6 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct
|
||||
{
|
||||
cpu = cpu_logical_map(cpu);
|
||||
|
||||
/* enable cache coherency */
|
||||
modify_scu_cpu_psr(0, 3 << (cpu * 8));
|
||||
|
||||
if (((__raw_readl(PSTR) >> (4 * cpu)) & 3) == 3)
|
||||
__raw_writel(1 << cpu, WUPCR); /* wake up */
|
||||
else
|
||||
@ -95,16 +78,14 @@ static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct
|
||||
|
||||
static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
int cpu = cpu_logical_map(0);
|
||||
|
||||
scu_enable(scu_base_addr());
|
||||
|
||||
/* Map the reset vector (in headsmp.S) */
|
||||
/* Map the reset vector (in headsmp-sh73a0.S) */
|
||||
__raw_writel(0, APARMBAREA); /* 4k */
|
||||
__raw_writel(__pa(shmobile_secondary_vector), SBAR);
|
||||
__raw_writel(__pa(sh73a0_secondary_vector), SBAR);
|
||||
|
||||
/* enable cache coherency on CPU0 */
|
||||
modify_scu_cpu_psr(0, 3 << (cpu * 8));
|
||||
/* enable cache coherency on booting CPU */
|
||||
scu_power_mode(scu_base_addr(), SCU_PM_NORMAL);
|
||||
}
|
||||
|
||||
static void __init sh73a0_smp_init_cpus(void)
|
||||
@ -114,16 +95,20 @@ static void __init sh73a0_smp_init_cpus(void)
|
||||
shmobile_smp_init_cpus(ncores);
|
||||
}
|
||||
|
||||
static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu)
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
static int sh73a0_cpu_kill(unsigned int cpu)
|
||||
{
|
||||
int k;
|
||||
|
||||
/* this function is running on another CPU than the offline target,
|
||||
* here we need wait for shutdown code in platform_cpu_die() to
|
||||
* finish before asking SoC-specific code to power off the CPU core.
|
||||
int k;
|
||||
u32 pstr;
|
||||
|
||||
/*
|
||||
* wait until the power status register confirms the shutdown of the
|
||||
* offline target
|
||||
*/
|
||||
for (k = 0; k < 1000; k++) {
|
||||
if (shmobile_cpu_is_dead(cpu))
|
||||
pstr = (__raw_readl(PSTR) >> (4 * cpu)) & 3;
|
||||
if (pstr == PSTR_SHUTDOWN_MODE)
|
||||
return 1;
|
||||
|
||||
mdelay(1);
|
||||
@ -132,6 +117,23 @@ static int __maybe_unused sh73a0_cpu_kill(unsigned int cpu)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sh73a0_cpu_die(unsigned int cpu)
|
||||
{
|
||||
/*
|
||||
* The ARM MPcore does not issue a cache coherency request for the L1
|
||||
* cache when powering off single CPUs. We must take care of this and
|
||||
* further caches.
|
||||
*/
|
||||
dsb();
|
||||
flush_cache_all();
|
||||
|
||||
/* Set power off mode. This takes the CPU out of the MP cluster */
|
||||
scu_power_mode(scu_base_addr(), SCU_PM_POWEROFF);
|
||||
|
||||
/* Enter shutdown mode */
|
||||
cpu_do_idle();
|
||||
}
|
||||
#endif /* CONFIG_HOTPLUG_CPU */
|
||||
|
||||
struct smp_operations sh73a0_smp_ops __initdata = {
|
||||
.smp_init_cpus = sh73a0_smp_init_cpus,
|
||||
@ -140,7 +142,7 @@ struct smp_operations sh73a0_smp_ops __initdata = {
|
||||
.smp_boot_secondary = sh73a0_boot_secondary,
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
.cpu_kill = sh73a0_cpu_kill,
|
||||
.cpu_die = shmobile_cpu_die,
|
||||
.cpu_die = sh73a0_cpu_die,
|
||||
.cpu_disable = shmobile_cpu_disable,
|
||||
#endif
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user