Commit 0475e57f authored by Olof Johansson's avatar Olof Johansson

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: default avatarOlof 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
parents 2806683c ff8de98d
/*
* 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>;
};
};
/*
* 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 */
};
......
/*
* 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();
}
/*
* 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;
u32 pstr;
/* 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.
/*
* 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
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment