[PATCH v5 00/13] ARM: shmobile: APMU DT support via SMP Enable method

DORMANTno replies

Revision v5 of 2 in this series.

14 messages, 1 author, 2016-06-28 · open the first message on its own page

[PATCH v5 00/13] ARM: shmobile: APMU DT support via SMP Enable method

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:50

	Hi Simon, Magnus,

This patch series, which I took over from Magnus and extended, adds DT
support for the APMU hardware commonly found in Renesas R-Car Gen2 SoCs.
Without these patches the APMU gets configured through data expressed in
C, and with this series applied it is possible to describe the APMU
configuration in DT and let the enable method point out that the APMU
should be used.

  - Patch 1 documents DT support to describe that the APMU hardware is
    needed for SMP operation,
  - Patch 2 fixes a bug in the rcar-sysc driver that was harmless
    before,
  - Patches 3-5 prepare for handling SYSC interrupt configuration purely
    from DT in the rcar-sysc driver for new SoCs, while preserving
    backward compatibility with old DTBs for R-Car H1, H2, and M2-W,
  - Patch 6 is a small cleanup for CONFIG_SMP=n builds,
  - Patch 7 adds DT support to the APMU driver together with enabling
    use of the enable-method way to describe that the APMU hardware is
    needed for SMP operation,
  - Patches 8-10 make sure that during run-time, if the APMU is
    installed via the DT enable-method then it will not be overriden by
    older non-DT configuration.  To avoid breaking support for older
    DTBs out in the wild these patches keep the older existing C code
    APMU configuration as-is.
  - Patches 11 and 12 update the r8a7790 and r8a7791 DTSes to describe
    the APMU hardware,
  - Patch 13 adds r8a7793 SMP support using the new APMU DT interface.

Magnus suggested making APMU DT configuration mandatory for SMP
operation on newer SoCs and that we keep the old APMU support code in
place for a good number of kernel releases or until we can identify a
couple of major reasons good enough to force a DTB update on the end
users.

This is a prerequisite for adding SMP support for r8a7792 and r8a7794.
Patches updating the DTSes similar to patch 13 - without any C-based SMP
code and fallback - are already floating around.

Note that booting secondary CPUs using renesas,apmu is disabled on all
R-Car Gen2 SoCs if hardware debug mode is enabled through setting
MD21=1, like was done on R-Car M2-W before. While this may not be
necessary on all boards, SoCs, and firmware versions, dropping this
check requires adding some extra handling first.

Changes compared to v4 (more details in the individual patches):
  - Add Acked-by, Reviewed-by,
  - Add missing power-domains property to r8a7793 cpu1 node.

Changes compared to v3 (more details in the individual patches):
  - Use "renesas,<soctype>-apmu" instead of "renesas,apmu-<soctype>",
  - Handle SYSC interrupt configuration purely from DT in the rcar-sysc
    driver for new SoCs,
  - Dropped patch [PATCH v3 04/09] "ARM: shmobile: r8a7793 boot address
    update":
      - Hardcoded SYSCIER value is no longer needed due to the above,
      - ICRAM1 is already used since "ARM: shmobile: rcar-gen2: Use
	ICRAM1 for jump stub on all SoCs",
  - Fix CONFIG_SMP=n build.

This series is against renesas-devel-20160627-v4.7-rc5.
For testing, it's also available in the topic/apmu-dt-v5 branch
of https://git.kernel.org/cgit/linux/kernel/git/geert/renesas-drivers.git.

This has been tested on r8a7779/marzen, r8a7790/lager, r8a7791/koelsch,
and r8a7793/gose.

Please apply, thanks!

Geert Uytterhoeven (5):
  soc: renesas: rcar-sysc: Fix uninitialized error code in
    rcar_sysc_pd_init()
  soc: renesas: rcar-sysc: Make rcar_sysc_init() init the PM domains
  soc: renesas: rcar-sysc: Move SYSC interrupt config to rcar-sysc
    driver
  soc: renesas: rcar-sysc: Improve SYSC interrupt config in legacy
    wrapper
  ARM: shmobile: apmu: Move #ifdef CONFIG_SMP to cover more functions

Magnus Damm (8):
  devicetree: bindings: Renesas APMU and SMP Enable method
  ARM: shmobile: apmu: Add APMU DT support via Enable method
  ARM: shmobile: smp: Add function to prioritize DT SMP
  ARM: shmobile: r8a7790: Prioritize DT APMU support
  ARM: shmobile: r8a7791: Prioritize DT APMU support
  ARM: dts: r8a7790: Add APMU nodes
  ARM: dts: r8a7791: Add APMU node
  ARM: dts: r8a7793: Add APMU node and second CPU core

 Documentation/devicetree/bindings/arm/cpus.txt     |  1 +
 .../devicetree/bindings/power/renesas,apmu.txt     | 31 +++++++
 arch/arm/boot/dts/r8a7790.dtsi                     | 13 +++
 arch/arm/boot/dts/r8a7791.dtsi                     |  7 ++
 arch/arm/boot/dts/r8a7793.dtsi                     | 15 ++++
 arch/arm/mach-shmobile/common.h                    |  1 +
 arch/arm/mach-shmobile/platsmp-apmu.c              | 94 ++++++++++++++++++++--
 arch/arm/mach-shmobile/platsmp.c                   |  6 ++
 arch/arm/mach-shmobile/pm-r8a7779.c                |  6 +-
 arch/arm/mach-shmobile/pm-rcar-gen2.c              |  6 +-
 arch/arm/mach-shmobile/setup-r8a7790.c             |  1 +
 arch/arm/mach-shmobile/setup-r8a7791.c             |  1 +
 drivers/soc/renesas/rcar-sysc.c                    | 39 ++++++---
 include/linux/soc/renesas/rcar-sysc.h              |  2 +-
 14 files changed, 197 insertions(+), 26 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/renesas,apmu.txt

-- 
1.9.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

[PATCH v5 01/13] devicetree: bindings: Renesas APMU and SMP Enable method

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:30

From: Magnus Damm <redacted>

Add DT binding documentation for the APMU hardware and add "renesas,apmu"
to the list of enable methods for the ARM cpus.

Signed-off-by: Magnus Damm <redacted>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Rob Herring <robh@kernel.org>
Cc: devicetree@vger.kernel.org
---
v5:
  - Add Acked-by,

v4:
  - s/reigsters/registers/,
  - Use "renesas,<soctype>-apmu" instead of "renesas,apmu-<soctype>",

v3:
  - s/Until/Unit/g,

v2:
  - No changes.
---
 Documentation/devicetree/bindings/arm/cpus.txt     |  1 +
 .../devicetree/bindings/power/renesas,apmu.txt     | 31 ++++++++++++++++++++++
 2 files changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/renesas,apmu.txt
diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index 3f0cbbb8395f84ef..fa7520eb6387edbe 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -204,6 +204,7 @@ nodes to be present and contain the properties described below.
 			    "qcom,gcc-msm8660"
 			    "qcom,kpss-acc-v1"
 			    "qcom,kpss-acc-v2"
+			    "renesas,apmu"
 			    "rockchip,rk3036-smp"
 			    "rockchip,rk3066-smp"
 			    "ste,dbx500-smp"
diff --git a/Documentation/devicetree/bindings/power/renesas,apmu.txt b/Documentation/devicetree/bindings/power/renesas,apmu.txt
new file mode 100644
index 0000000000000000..84404c9edff73d97
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/renesas,apmu.txt
@@ -0,0 +1,31 @@
+DT bindings for the Renesas Advanced Power Management Unit
+
+Renesas R-Car line of SoCs utilize one or more APMU hardware units
+for CPU core power domain control including SMP boot and CPU Hotplug.
+
+Required properties:
+
+- compatible: Should be "renesas,<soctype>-apmu", "renesas,apmu" as fallback.
+	      Examples with soctypes are:
+		- "renesas,r8a7790-apmu" (R-Car H2)
+		- "renesas,r8a7791-apmu" (R-Car M2-W)
+		- "renesas,r8a7792-apmu" (R-Car V2H)
+		- "renesas,r8a7793-apmu" (R-Car M2-N)
+		- "renesas,r8a7794-apmu" (R-Car E2)
+
+- reg: Base address and length of the I/O registers used by the APMU.
+
+- cpus: This node contains a list of CPU cores, which should match the order
+  of CPU cores used by the WUPCR and PSTR registers in the Advanced Power
+  Management Unit section of the device's datasheet.
+
+
+Example:
+
+This shows the r8a7791 APMU that can control CPU0 and CPU1.
+
+	apmu@e6152000 {
+		compatible = "renesas,r8a7791-apmu", "renesas,apmu";
+		reg = <0 0xe6152000 0 0x188>;
+		cpus = <&cpu0 &cpu1>;
+	};
-- 
1.9.1

[PATCH v5 02/13] soc: renesas: rcar-sysc: Fix uninitialized error code in rcar_sysc_pd_init()

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:31

On success, rcar_sysc_pd_init() returns an uninitialized error code.
Use the return value of of_genpd_add_provider_onecell() to fix this.

This went unnoticed, as early_initcall() doesn't care about the return
value.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v5:
  - No changes,

v4:
  - New.
---
 drivers/soc/renesas/rcar-sysc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
index a43ca24699bed1ec..59a8152681a59a5c 100644
--- a/drivers/soc/renesas/rcar-sysc.c
+++ b/drivers/soc/renesas/rcar-sysc.c
@@ -398,7 +398,7 @@ static int __init rcar_sysc_pd_init(void)
 		domains->domains[area->isr_bit] = &pd->genpd;
 	}
 
-	of_genpd_add_provider_onecell(np, &domains->onecell_data);
+	error = of_genpd_add_provider_onecell(np, &domains->onecell_data);
 
 out_put:
 	of_node_put(np);
-- 
1.9.1

[PATCH v5 04/13] soc: renesas: rcar-sysc: Move SYSC interrupt config to rcar-sysc driver

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:33

On R-Car H1 and Gen2, the SYSC interrupt registers are always configured
using hardcoded values in platform code. For R-Car Gen2, values are
provided for H2 and M2-W only, other SoCs are not yet supported, and
never will be.

Move this configuration from SoC-specific platform code to the
rcar_sysc_init() wrapper, so it can be skipped if the SYSC is configured
from DT. This would be the case not only for H1, H2, and M2-W using a
modern DTS, but also for other R-Car Gen2 SoCs not supported by the
platform code, relying purely on DT.

There is no longer a need to return the mapped register block, hence
make the function return void.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Ulrich Hecht <redacted>
---
v5:
  - Add Reviewed-by,

v4:
  - New.
---
 arch/arm/mach-shmobile/pm-r8a7779.c   |  6 +-----
 arch/arm/mach-shmobile/pm-rcar-gen2.c |  6 +-----
 drivers/soc/renesas/rcar-sysc.c       | 12 ++++++++----
 include/linux/soc/renesas/rcar-sysc.h |  2 +-
 4 files changed, 11 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mach-shmobile/pm-r8a7779.c b/arch/arm/mach-shmobile/pm-r8a7779.c
index 4174cbcbc467d047..5c9a93f5e650181a 100644
--- a/arch/arm/mach-shmobile/pm-r8a7779.c
+++ b/arch/arm/mach-shmobile/pm-r8a7779.c
@@ -23,11 +23,7 @@
 
 static void __init r8a7779_sysc_init(void)
 {
-	void __iomem *base = rcar_sysc_init(0xffd85000);
-
-	/* enable all interrupt sources, but do not use interrupt handler */
-	iowrite32(0x0131000e, base + SYSCIER);
-	iowrite32(0, base + SYSCIMR);
+	rcar_sysc_init(0xffd85000, 0x0131000e);
 }
 
 #else /* CONFIG_PM || CONFIG_SMP */
diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c
index 61361dac6068210a..dd9ac366868f4336 100644
--- a/arch/arm/mach-shmobile/pm-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c
@@ -36,11 +36,7 @@
 
 static void __init rcar_gen2_sysc_init(u32 syscier)
 {
-	void __iomem *base = rcar_sysc_init(0xe6180000);
-
-	/* enable all interrupt sources, but do not use interrupt handler */
-	iowrite32(syscier, base + SYSCIER);
-	iowrite32(0, base + SYSCIMR);
+	rcar_sysc_init(0xe6180000, syscier);
 }
 
 #else /* CONFIG_SMP */
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
index 68d6856c9d3cd192..22f0d646225c444e 100644
--- a/drivers/soc/renesas/rcar-sysc.c
+++ b/drivers/soc/renesas/rcar-sysc.c
@@ -400,10 +400,14 @@ out_put:
 }
 early_initcall(rcar_sysc_pd_init);
 
-void __iomem * __init rcar_sysc_init(phys_addr_t base)
+void __init rcar_sysc_init(phys_addr_t base, u32 syscier)
 {
-	if (rcar_sysc_pd_init())
-		rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
+	if (!rcar_sysc_pd_init())
+		return;
 
-	return rcar_sysc_base;
+	rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
+
+	/* enable all interrupt sources, but do not use interrupt handler */
+	iowrite32(syscier, rcar_sysc_base + SYSCIER);
+	iowrite32(0, rcar_sysc_base + SYSCIMR);
 }
diff --git a/include/linux/soc/renesas/rcar-sysc.h b/include/linux/soc/renesas/rcar-sysc.h
index 92fc613ab23db091..7b8b280c181b8389 100644
--- a/include/linux/soc/renesas/rcar-sysc.h
+++ b/include/linux/soc/renesas/rcar-sysc.h
@@ -11,6 +11,6 @@ struct rcar_sysc_ch {
 
 int rcar_sysc_power_down(const struct rcar_sysc_ch *sysc_ch);
 int rcar_sysc_power_up(const struct rcar_sysc_ch *sysc_ch);
-void __iomem *rcar_sysc_init(phys_addr_t base);
+void rcar_sysc_init(phys_addr_t base, u32 syscier);
 
 #endif /* __LINUX_SOC_RENESAS_RCAR_SYSC_H__ */
-- 
1.9.1

[PATCH v5 09/13] ARM: shmobile: r8a7790: Prioritize DT APMU support

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:38

From: Magnus Damm <redacted>

Adjust the r8a7790 SoC support code to not configure any non-DT SMP code
in case the DT-based enable-method has been installed already.

Signed-off-by: Magnus Damm <redacted>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v5:
  - No changes,

v4:
  - No changes,

v3:
  - No changes,

v2:
  - New.
---
 arch/arm/mach-shmobile/setup-r8a7790.c | 1 +
 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index 3a18af4922b42577..3506327e0bed2422 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -28,6 +28,7 @@ static const char * const r8a7790_boards_compat_dt[] __initconst = {
 };
 
 DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)")
+	.smp_init	= shmobile_smp_init_fallback_ops,
 	.smp		= smp_ops(r8a7790_smp_ops),
 	.init_early	= shmobile_init_delay,
 	.init_time	= rcar_gen2_timer_init,
-- 
1.9.1

[PATCH v5 11/13] ARM: dts: r8a7790: Add APMU nodes

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:40

From: Magnus Damm <redacted>

Add DT nodes for the Advanced Power Management Units (APMU), and use the
enable-method to point out that the APMU should be used for SMP
support.

Signed-off-by: Magnus Damm <redacted>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v5:
  - No changes,

v4:
  - Improve patch description,
  - Use "renesas,<soctype>-apmu" instead of "renesas,apmu-<soctype>",

v3:
  - No changes,

v2:
  - New.
---
 arch/arm/boot/dts/r8a7790.dtsi | 13 +++++++++++++
 1 file changed, 13 insertions(+)
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 9997e7dfabe2250c..d18558f211022826 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -44,6 +44,7 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "renesas,apmu";
 
 		cpu0: cpu@0 {
 			device_type = "cpu";
@@ -164,6 +165,18 @@
 		};
 	};
 
+	apmu@e6151000 {
+		compatible = "renesas,r8a7790-apmu", "renesas,apmu";
+		reg = <0 0xe6151000 0 0x188>;
+		cpus = <&cpu4 &cpu5 &cpu6 &cpu7>;
+	};
+
+	apmu@e6152000 {
+		compatible = "renesas,r8a7790-apmu", "renesas,apmu";
+		reg = <0 0xe6152000 0 0x188>;
+		cpus = <&cpu0 &cpu1 &cpu2 &cpu3>;
+	};
+
 	gic: interrupt-controller@f1001000 {
 		compatible = "arm,gic-400";
 		#interrupt-cells = <3>;
-- 
1.9.1

[PATCH v5 12/13] ARM: dts: r8a7791: Add APMU node

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:41

From: Magnus Damm <redacted>

Add a DT node for the Advanced Power Management Units (APMU), and use
the enable-method to point out that the APMU should be used for SMP
support.

Signed-off-by: Magnus Damm <redacted>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
----
v5:
  - No changes,

v4:
  - Improve patch description,
  - Use "renesas,<soctype>-apmu" instead of "renesas,apmu-<soctype>",

v3:
  - No changes,

v2:
  - No changes.
---
 arch/arm/boot/dts/r8a7791.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 1985bd0dc32ce738..8f0086bbd96bb27a 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -43,6 +43,7 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "renesas,apmu";
 
 		cpu0: cpu@0 {
 			device_type = "cpu";
@@ -101,6 +102,12 @@
 		};
 	};
 
+	apmu@e6152000 {
+		compatible = "renesas,r8a7791-apmu", "renesas,apmu";
+		reg = <0 0xe6152000 0 0x188>;
+		cpus = <&cpu0 &cpu1>;
+	};
+
 	gic: interrupt-controller@f1001000 {
 		compatible = "arm,gic-400";
 		#interrupt-cells = <3>;
-- 
1.9.1

[PATCH v5 13/13] ARM: dts: r8a7793: Add APMU node and second CPU core

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:42

From: Magnus Damm <redacted>

Add DT nodes for the Advanced Power Management Unit (APMU) and the
second CPU core.  Use the enable-method to point out that the APMU
should be used for SMP support.

Signed-off-by: Magnus Damm <redacted>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v5:
  - Add missing power-domains property to cpu1 node,

v4:
  - Improve patch description,
  - Use "renesas,<soctype>-apmu" instead of "renesas,apmu-<soctype>",

v3:
  - New.
---
 arch/arm/boot/dts/r8a7793.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi
index 9b55c1c6ee31a49d..8d02aacf28926271 100644
--- a/arch/arm/boot/dts/r8a7793.dtsi
+++ b/arch/arm/boot/dts/r8a7793.dtsi
@@ -35,6 +35,7 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "renesas,apmu";
 
 		cpu0: cpu@0 {
 			device_type = "cpu";
@@ -56,6 +57,14 @@
 			next-level-cache = <&L2_CA15>;
 		};
 
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <1>;
+			clock-frequency = <1500000000>;
+			power-domains = <&sysc R8A7793_PD_CA15_CPU1>;
+		};
+
 		L2_CA15: cache-controller@0 {
 			compatible = "cache";
 			reg = <0>;
@@ -65,6 +74,12 @@
 		};
 	};
 
+	apmu@e6152000 {
+		compatible = "renesas,r8a7793-apmu", "renesas,apmu";
+		reg = <0 0xe6152000 0 0x188>;
+		cpus = <&cpu0 &cpu1>;
+	};
+
 	thermal-zones {
 		cpu_thermal: cpu-thermal {
 			polling-delay-passive	= <0>;
-- 
1.9.1

[PATCH v5 07/13] ARM: shmobile: apmu: Add APMU DT support via Enable method

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:49

From: Magnus Damm <redacted>

Allow DT configuration of the APMU hardware in the case when the APMU is
pointed out in the DTB via the enable-method. The ability to configure
the APMU via C code is still kept intact to prevent DTB breakage for older
SoCs that do not rely on the enable-method for SMP support.

Signed-off-by: Magnus Damm <redacted>
[geert: Fix CONFIG_SMP=n build]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v5:
  - No changes,

v4:
  - Remove bogus of_node_put(),
  - Fix CONFIG_SMP=n build,
  - Correct whitespace,

v3:
  - Move is_allowed declaration, break when allowed,

v2:
  - Adjust to use .cpu_can_disable instead of .cpu_disable.
---
 arch/arm/mach-shmobile/platsmp-apmu.c | 92 +++++++++++++++++++++++++++++++++--
 1 file changed, 88 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c
index c1558ef0c590dd3e..0c6bb458b7a45128 100644
--- a/arch/arm/mach-shmobile/platsmp-apmu.c
+++ b/arch/arm/mach-shmobile/platsmp-apmu.c
@@ -24,6 +24,7 @@
 #include <asm/suspend.h>
 #include "common.h"
 #include "platsmp-apmu.h"
+#include "rcar-gen2.h"
 
 static struct {
 	void __iomem *iomem;
@@ -118,14 +119,66 @@ static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit),
 	}
 }
 
-void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
-					   struct rcar_apmu_config *apmu_config,
-					   int num)
+static const struct of_device_id apmu_ids[] = {
+	{ .compatible = "renesas,apmu" },
+	{ /*sentinel*/ }
+};
+
+static void apmu_parse_dt(void (*fn)(struct resource *res, int cpu, int bit))
+{
+	struct device_node *np_apmu, *np_cpu;
+	struct resource res;
+	int bit, index;
+	u32 id;
+
+	for_each_matching_node(np_apmu, apmu_ids) {
+		/* only enable the cluster that includes the boot CPU */
+		bool is_allowed = false;
+
+		for (bit = 0; bit < CONFIG_NR_CPUS; bit++) {
+			np_cpu = of_parse_phandle(np_apmu, "cpus", bit);
+			if (np_cpu) {
+				if (!of_property_read_u32(np_cpu, "reg", &id)) {
+					if (id == cpu_logical_map(0)) {
+						is_allowed = true;
+						of_node_put(np_cpu);
+						break;
+					}
+
+				}
+				of_node_put(np_cpu);
+			}
+		}
+		if (!is_allowed)
+			continue;
+
+		for (bit = 0; bit < CONFIG_NR_CPUS; bit++) {
+			np_cpu = of_parse_phandle(np_apmu, "cpus", bit);
+			if (np_cpu) {
+				if (!of_property_read_u32(np_cpu, "reg", &id)) {
+					index = get_logical_index(id);
+					if ((index >= 0) &&
+					    !of_address_to_resource(np_apmu,
+								    0, &res))
+						fn(&res, index, bit);
+				}
+				of_node_put(np_cpu);
+			}
+		}
+	}
+}
+
+static void __init shmobile_smp_apmu_setup_boot(void)
 {
 	/* install boot code shared by all CPUs */
 	shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
+}
 
-	/* perform per-cpu setup */
+void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
+					   struct rcar_apmu_config *apmu_config,
+					   int num)
+{
+	shmobile_smp_apmu_setup_boot();
 	apmu_parse_cfg(apmu_init_cpu, apmu_config, num);
 }
 
@@ -136,7 +189,38 @@ int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 	return apmu_wrap(cpu, apmu_power_on);
 }
+
+static void __init shmobile_smp_apmu_prepare_cpus_dt(unsigned int max_cpus)
+{
+	shmobile_smp_apmu_setup_boot();
+	apmu_parse_dt(apmu_init_cpu);
+	rcar_gen2_pm_init();
+}
+
+static int shmobile_smp_apmu_boot_secondary_md21(unsigned int cpu,
+						 struct task_struct *idle)
+{
+	/* Error out when hardware debug mode is enabled */
+	if (rcar_gen2_read_mode_pins() & BIT(21)) {
+		pr_warn("Unable to boot CPU%u when MD21 is set\n", cpu);
+		return -ENOTSUPP;
+	}
+
+	return shmobile_smp_apmu_boot_secondary(cpu, idle);
+}
+
+static struct smp_operations apmu_smp_ops __initdata = {
+	.smp_prepare_cpus	= shmobile_smp_apmu_prepare_cpus_dt,
+	.smp_boot_secondary	= shmobile_smp_apmu_boot_secondary_md21,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_can_disable	= shmobile_smp_cpu_can_disable,
+	.cpu_die		= shmobile_smp_apmu_cpu_die,
+	.cpu_kill		= shmobile_smp_apmu_cpu_kill,
 #endif
+};
+
+CPU_METHOD_OF_DECLARE(shmobile_smp_apmu, "renesas,apmu", &apmu_smp_ops);
+#endif /* CONFIG_SMP */
 
 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_SUSPEND)
 /* nicked from arch/arm/mach-exynos/hotplug.c */
-- 
1.9.1

[PATCH v5 03/13] soc: renesas: rcar-sysc: Make rcar_sysc_init() init the PM domains

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:49

Let rcar_sysc_init() trigger initialization of the SYSC PM domains from
DT if called before the early_initcall.
On failure, it falls back to mapping the passed register block, as
before.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v5:
  - No changes,

v4:
  - New.
---
 drivers/soc/renesas/rcar-sysc.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
index 59a8152681a59a5c..68d6856c9d3cd192 100644
--- a/drivers/soc/renesas/rcar-sysc.c
+++ b/drivers/soc/renesas/rcar-sysc.c
@@ -164,15 +164,6 @@ static bool rcar_sysc_power_is_off(const struct rcar_sysc_ch *sysc_ch)
 	return false;
 }
 
-void __iomem *rcar_sysc_init(phys_addr_t base)
-{
-	rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
-	if (!rcar_sysc_base)
-		panic("unable to ioremap R-Car SYSC hardware block\n");
-
-	return rcar_sysc_base;
-}
-
 struct rcar_sysc_pd {
 	struct generic_pm_domain genpd;
 	struct rcar_sysc_ch ch;
@@ -328,6 +319,9 @@ static int __init rcar_sysc_pd_init(void)
 	unsigned int i;
 	int error;
 
+	if (rcar_sysc_base)
+		return 0;
+
 	np = of_find_matching_node_and_match(NULL, rcar_sysc_matches, &match);
 	if (!np)
 		return -ENODEV;
@@ -405,3 +399,11 @@ out_put:
 	return error;
 }
 early_initcall(rcar_sysc_pd_init);
+
+void __iomem * __init rcar_sysc_init(phys_addr_t base)
+{
+	if (rcar_sysc_pd_init())
+		rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
+
+	return rcar_sysc_base;
+}
-- 
1.9.1

[PATCH v5 05/13] soc: renesas: rcar-sysc: Improve SYSC interrupt config in legacy wrapper

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:49

Align SYSC interrupt configuration in the legacy wrapper with the DT
version:
  - Mask SYSC interrupt sources before enabling them (doesn't matter
    much as they're disabled at the GIC level anyway),
  - Make sure not to clear reserved SYSCIMR bits that were set before.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Ulrich Hecht <redacted>
---
v5:
  - Add Reviewed-by,

v4:
  - New.
---
 drivers/soc/renesas/rcar-sysc.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c
index 22f0d646225c444e..65c8e1eb90c09bb3 100644
--- a/drivers/soc/renesas/rcar-sysc.c
+++ b/drivers/soc/renesas/rcar-sysc.c
@@ -402,12 +402,25 @@ early_initcall(rcar_sysc_pd_init);
 
 void __init rcar_sysc_init(phys_addr_t base, u32 syscier)
 {
+	u32 syscimr;
+
 	if (!rcar_sysc_pd_init())
 		return;
 
 	rcar_sysc_base = ioremap_nocache(base, PAGE_SIZE);
 
-	/* enable all interrupt sources, but do not use interrupt handler */
+	/*
+	 * Mask all interrupt sources to prevent the CPU from receiving them.
+	 * Make sure not to clear reserved bits that were set before.
+	 */
+	syscimr = ioread32(rcar_sysc_base + SYSCIMR);
+	syscimr |= syscier;
+	pr_debug("%s: syscimr = 0x%08x\n", __func__, syscimr);
+	iowrite32(syscimr, rcar_sysc_base + SYSCIMR);
+
+	/*
+	 * SYSC needs all interrupt sources enabled to control power.
+	 */
+	pr_debug("%s: syscier = 0x%08x\n", __func__, syscier);
 	iowrite32(syscier, rcar_sysc_base + SYSCIER);
-	iowrite32(0, rcar_sysc_base + SYSCIMR);
 }
-- 
1.9.1

[PATCH v5 08/13] ARM: shmobile: smp: Add function to prioritize DT SMP

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:49

From: Magnus Damm <redacted>

Add a function to check if other DT based method is available, and
if so return false to not hook up smp_ops from the machine vector.

This results in that DT-based SMP support has priority over older
C-based smp_ops code, and in case DT-based SMP support code does not
exist in the DTB then the old smp_ops code will still work as-is.

Signed-off-by: Magnus Damm <redacted>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v5:
  - No changes,

v4:
  - Remove empty line at end of file,

v3:
  - No changes,

v2:
  - Rework r8a7791-specific version to become reusable function.
---
 arch/arm/mach-shmobile/common.h  | 1 +
 arch/arm/mach-shmobile/platsmp.c | 6 ++++++
 2 files changed, 7 insertions(+)
diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h
index 3b562d87826d7410..1a8f7b3ab449db56 100644
--- a/arch/arm/mach-shmobile/common.h
+++ b/arch/arm/mach-shmobile/common.h
@@ -10,6 +10,7 @@ extern void shmobile_smp_sleep(void);
 extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn,
 			      unsigned long arg);
 extern bool shmobile_smp_cpu_can_disable(unsigned int cpu);
+extern bool shmobile_smp_init_fallback_ops(void);
 extern void shmobile_boot_scu(void);
 extern void shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys,
 					  unsigned int max_cpus);
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
index b23378f3d7e1726b..f3dba6f356e29446 100644
--- a/arch/arm/mach-shmobile/platsmp.c
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -36,3 +36,9 @@ bool shmobile_smp_cpu_can_disable(unsigned int cpu)
 	return true; /* Hotplug of any CPU is supported */
 }
 #endif
+
+bool __init shmobile_smp_init_fallback_ops(void)
+{
+	/* fallback on PSCI/smp_ops if no other DT based method is detected */
+	return platform_can_secondary_boot() ? true : false;
+}
-- 
1.9.1

[PATCH v5 06/13] ARM: shmobile: apmu: Move #ifdef CONFIG_SMP to cover more functions

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:49

shmobile_smp_apmu_prepare_cpus() is used only if CONFIG_SMP=y.

Hence move the #ifdef to cover shmobile_smp_apmu_prepare_cpus() and all
functions only called by it (apmu_init_cpu() and apmu_parse_cfg()).

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Ulrich Hecht <redacted>
---
v5:
  - Add Reviewed-by,

v4:
  - New.
---
 arch/arm/mach-shmobile/platsmp-apmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c
index aba75c89f9c1c5eb..c1558ef0c590dd3e 100644
--- a/arch/arm/mach-shmobile/platsmp-apmu.c
+++ b/arch/arm/mach-shmobile/platsmp-apmu.c
@@ -74,6 +74,7 @@ static int __maybe_unused apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)
 	return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL;
 }
 
+#ifdef CONFIG_SMP
 static void apmu_init_cpu(struct resource *res, int cpu, int bit)
 {
 	if ((cpu >= ARRAY_SIZE(apmu_cpus)) || apmu_cpus[cpu].iomem)
@@ -128,7 +129,6 @@ void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
 	apmu_parse_cfg(apmu_init_cpu, apmu_config, num);
 }
 
-#ifdef CONFIG_SMP
 int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	/* For this particular CPU register boot vector */
-- 
1.9.1

[PATCH v5 10/13] ARM: shmobile: r8a7791: Prioritize DT APMU support

From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: 2016-06-28 14:10:49

From: Magnus Damm <redacted>

Adjust the r8a7791 SoC support code to not configure any non-DT SMP code
in case the DT-based enable-method has been installed already.

Signed-off-by: Magnus Damm <redacted>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v5:
  - No changes,

v4:
  - No changes,

v3:
  - No changes,

v2:
  - New.
---
 arch/arm/mach-shmobile/setup-r8a7791.c | 1 +
 1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c
index 3b8dbaf07777145e..110e8b588e563fca 100644
--- a/arch/arm/mach-shmobile/setup-r8a7791.c
+++ b/arch/arm/mach-shmobile/setup-r8a7791.c
@@ -29,6 +29,7 @@ static const char *const r8a7791_boards_compat_dt[] __initconst = {
 };
 
 DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)")
+	.smp_init	= shmobile_smp_init_fallback_ops,
 	.smp		= smp_ops(r8a7791_smp_ops),
 	.init_early	= shmobile_init_delay,
 	.init_time	= rcar_gen2_timer_init,
-- 
1.9.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help