diff mbox

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

Message ID 1466072862-28030-8-git-send-email-geert+renesas@glider.be (mailing list archive)
State Superseded
Delegated to: Simon Horman
Headers show

Commit Message

Geert Uytterhoeven June 16, 2016, 10:27 a.m. UTC
From: Magnus Damm <damm+renesas@opensource.se>

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 <damm+renesas@opensource.se>
[geert: Fix CONFIG_SMP=n build]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
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(-)

Comments

Sergei Shtylyov June 21, 2016, 5:49 p.m. UTC | #1
On 06/16/2016 01:27 PM, Geert Uytterhoeven wrote:

> From: Magnus Damm <damm+renesas@opensource.se>
>
> 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 <damm+renesas@opensource.se>
> [geert: Fix CONFIG_SMP=n build]
> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
[...]

> 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
[...]
> +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

    For the record: it turned out that I tested my non-DT SMP on 
R8A7792/Blanche with MD21 bit set. And I've just made sure it still works with 
this implementation (by commenting out the check above.
    Also, I was going to try the workaround for MD21 I saw in the BSP tree -- 
perhaps it'll help get R8A7791 working w/MD21 set...

MBR, Sergei
Geert Uytterhoeven June 24, 2016, 7:44 a.m. UTC | #2
Hi Sergei,

On Tue, Jun 21, 2016 at 7:49 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> On 06/16/2016 01:27 PM, Geert Uytterhoeven wrote:
>> From: Magnus Damm <damm+renesas@opensource.se>
>> 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 <damm+renesas@opensource.se>
>> [geert: Fix CONFIG_SMP=n build]
>> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>
> [...]
>
>> 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
>
> [...]
>>
>> +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
>
>
>    For the record: it turned out that I tested my non-DT SMP on
> R8A7792/Blanche with MD21 bit set. And I've just made sure it still works
> with this implementation (by commenting out the check above.
>    Also, I was going to try the workaround for MD21 I saw in the BSP tree --

Which workaround? I only saw the BSP removed the check, but it didn't mention
why (because E2 and V2H don't need it, or...?).

> perhaps it'll help get R8A7791 working w/MD21 set...

Does your Porter work with the other MD21 setting (and the check commented
out, of coutse)?

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
Sergei Shtylyov June 26, 2016, 4:36 p.m. UTC | #3
Hello.

On 06/24/2016 10:44 AM, Geert Uytterhoeven wrote:

>>> From: Magnus Damm <damm+renesas@opensource.se>
>>> 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 <damm+renesas@opensource.se>
>>> [geert: Fix CONFIG_SMP=n build]
>>> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>>
>> [...]
>>
>>> 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
>>
>> [...]
>>>
>>> +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
>>
>>
>>    For the record: it turned out that I tested my non-DT SMP on
>> R8A7792/Blanche with MD21 bit set. And I've just made sure it still works
>> with this implementation (by commenting out the check above.
>>    Also, I was going to try the workaround for MD21 I saw in the BSP tree --

> Which workaround? I only saw the BSP removed the check, but it didn't mention
> why (because E2 and V2H don't need it, or...?).

    I'm looking at the <soc>_smp_prepare_cpus() in 
arch/arm/mach-shmobile/setup-<soc>.c in the 
'bsp/v3.10.31-ltsi/rcar-gen2-1.9.6' branch of Simon's renesas-backport.git. 
The all have the code to handle MD21 bit set (by setting some bits in 
CA{7,15}DBGRCR.

>> perhaps it'll help get R8A7791 working w/MD21 set...
>
> Does your Porter work with the other MD21 setting (and the check commented
> out, of coutse)?

    Yes, I've made sure it works now.

> Gr{oetje,eeting}s,
>
>                         Geert

MBR, Sergei
Geert Uytterhoeven June 27, 2016, 9:41 a.m. UTC | #4
Hi Sergei,

On Sun, Jun 26, 2016 at 6:36 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> On 06/24/2016 10:44 AM, Geert Uytterhoeven wrote:
>>>> From: Magnus Damm <damm+renesas@opensource.se>
>>>> 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 <damm+renesas@opensource.se>
>>>> [geert: Fix CONFIG_SMP=n build]
>>>> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>>>
>>> [...]
>>>
>>>> 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
>>>
>>> [...]
>>>>
>>>>
>>>> +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
>>>
>>>    For the record: it turned out that I tested my non-DT SMP on
>>> R8A7792/Blanche with MD21 bit set. And I've just made sure it still works
>>> with this implementation (by commenting out the check above.
>>>    Also, I was going to try the workaround for MD21 I saw in the BSP tree
>>> --
>
>> Which workaround? I only saw the BSP removed the check, but it didn't
>> mention
>> why (because E2 and V2H don't need it, or...?).
>
>    I'm looking at the <soc>_smp_prepare_cpus() in
> arch/arm/mach-shmobile/setup-<soc>.c in the

.../smp-<soc>.c

> 'bsp/v3.10.31-ltsi/rcar-gen2-1.9.6' branch of Simon's renesas-backport.git.
> The all have the code to handle MD21 bit set (by setting some bits in
> CA{7,15}DBGRCR.
>
>>> perhaps it'll help get R8A7791 working w/MD21 set...

Thanks! I'll give that a try...

Note that for SoCs with CA7 cores, it sets undocumented bits (the 0x3330 part)?

For now we can keep the check, as the behavior is the same as on H2/M2-W
before, so it doesn't introduce a regression.

>> Does your Porter work with the other MD21 setting (and the check commented
>> out, of coutse)?
>
>    Yes, I've made sure it works now.

With or without the DBGRCR code from the BSP?

Thanks!

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
Sergei Shtylyov June 27, 2016, 12:59 p.m. UTC | #5
Hello.

On 06/27/2016 12:41 PM, Geert Uytterhoeven wrote:

>>>>> From: Magnus Damm <damm+renesas@opensource.se>
>>>>> 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 <damm+renesas@opensource.se>
>>>>> [geert: Fix CONFIG_SMP=n build]
>>>>> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>>>>
>>>> [...]
>>>>
>>>>> 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
>>>>
>>>> [...]
>>>>>
>>>>>
>>>>> +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
>>>>
>>>>    For the record: it turned out that I tested my non-DT SMP on
>>>> R8A7792/Blanche with MD21 bit set. And I've just made sure it still works
>>>> with this implementation (by commenting out the check above.
>>>>    Also, I was going to try the workaround for MD21 I saw in the BSP tree
>>>> --
>>
>>> Which workaround? I only saw the BSP removed the check, but it didn't
>>> mention
>>> why (because E2 and V2H don't need it, or...?).
>>
>>    I'm looking at the <soc>_smp_prepare_cpus() in
>> arch/arm/mach-shmobile/setup-<soc>.c in the
>
> .../smp-<soc>.c

    Yes, sorry. :-)

>> 'bsp/v3.10.31-ltsi/rcar-gen2-1.9.6' branch of Simon's renesas-backport.git.
>> The all have the code to handle MD21 bit set (by setting some bits in
>> CA{7,15}DBGRCR.
>>
>>>> perhaps it'll help get R8A7791 working w/MD21 set...
>
> Thanks! I'll give that a try...
>
> Note that for SoCs with CA7 cores, it sets undocumented bits (the 0x3330 part)?

    Yes, looks like they're undocumented.

> For now we can keep the check, as the behavior is the same as on H2/M2-W
> before, so it doesn't introduce a regression.

    Wait, H2 SMP code doesn't have this check.

>>> Does your Porter work with the other MD21 setting (and the check commented
>>> out, of coutse)?
>>
>>    Yes, I've made sure it works now.
>
> With or without the DBGRCR code from the BSP?

    Without.

> Thanks!
>
> Gr{oetje,eeting}s,
>
>                         Geert

MBR, Sergei
Geert Uytterhoeven June 27, 2016, 1:20 p.m. UTC | #6
Hi Sergei,

On Mon, Jun 27, 2016 at 2:59 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> On 06/27/2016 12:41 PM, Geert Uytterhoeven wrote:
>>>>>> From: Magnus Damm <damm+renesas@opensource.se>
>>>>>> 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 <damm+renesas@opensource.se>
>>>>>> [geert: Fix CONFIG_SMP=n build]
>>>>>> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>>>>>
>>>>> [...]
>>>>>
>>>>>> 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
>>>>>
>>>>> [...]
>>>>>>
>>>>>> +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
>>>>>
>>>>>    For the record: it turned out that I tested my non-DT SMP on
>>>>> R8A7792/Blanche with MD21 bit set. And I've just made sure it still
>>>>> works
>>>>> with this implementation (by commenting out the check above.
>>>>>    Also, I was going to try the workaround for MD21 I saw in the BSP
>>>>> tree
>>>>> --
>>>
>>>> Which workaround? I only saw the BSP removed the check, but it didn't
>>>> mention
>>>> why (because E2 and V2H don't need it, or...?).
>>>
>>>    I'm looking at the <soc>_smp_prepare_cpus() in
>>> arch/arm/mach-shmobile/setup-<soc>.c in the
>>
>> .../smp-<soc>.c
>
>    Yes, sorry. :-)
>
>>> 'bsp/v3.10.31-ltsi/rcar-gen2-1.9.6' branch of Simon's
>>> renesas-backport.git.
>>> The all have the code to handle MD21 bit set (by setting some bits in
>>> CA{7,15}DBGRCR.
>>>
>>>>> perhaps it'll help get R8A7791 working w/MD21 set...

>>
>> Thanks! I'll give that a try...
>>
>> Note that for SoCs with CA7 cores, it sets undocumented bits (the 0x3330
>> part)?
>
>    Yes, looks like they're undocumented.
>
>> For now we can keep the check, as the behavior is the same as on H2/M2-W
>> before, so it doesn't introduce a regression.
>
>    Wait, H2 SMP code doesn't have this check.

You're right. While Magnus did send out a patch that added the check for both,
in the end a newer revision touching r8a7791 only was applied.
Whether r8a7790 is really not affected is not clear to me...

>>>> Does your Porter work with the other MD21 setting (and the check
>>>> commented
>>>> out, of coutse)?
>>>
>>>    Yes, I've made sure it works now.
>>
>> With or without the DBGRCR code from the BSP?
>
>    Without.

That's interesting. So there may be different firmware/boot loader on Koelsch
and Porter.

Or perhaps it's just random: on Koelsch, I only had the issue after a Real Cold
Boot (in the morning). During the day, it used to work with MD21=1, too.

Now, we're getting closer to the moment Simon will close his tree for v4.8.
Can we apply my series as-is, or do we need the DBGRCR handling first,
probably postponing all of this to v4.9?

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
diff mbox

Patch

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 */