* [PATCH 1/6] ARM: mvebu: introduce CPU reset code
2014-03-27 13:37 [PATCH 0/6] ARM: mvebu: prepare PMSU code for cpuidle and Armada 375/38x SMP Thomas Petazzoni
@ 2014-03-27 13:38 ` Thomas Petazzoni
2014-03-27 14:00 ` Gregory CLEMENT
2014-03-27 14:12 ` Sebastian Hesselbarth
2014-03-27 13:38 ` [PATCH 2/6] ARM: mvebu: start using the CPU reset driver Thomas Petazzoni
` (4 subsequent siblings)
5 siblings, 2 replies; 14+ messages in thread
From: Thomas Petazzoni @ 2014-03-27 13:38 UTC (permalink / raw)
To: linux-arm-kernel
The Armada 370 and Armada XP have registers that allow to reset the
CPUs, which is particularly useful to take the secondary CPUs out of
reset in the context of the SMP support.
Unfortunately, an implementation mistake was originally made and the
support for these registers was integrated into the PMSU driver, which
is in fact completely unrelated. And it turns out that the Armada 375
has the same CPU reset registers, but does not have the PMSU
registers.
Therefore, this commit creates a small CPU reset driver. All it does
is provide a simple mvebu_cpu_reset_deassert() function that the SMP
support code can call to take secondary CPUs out of reset. As of this
commit, the driver isn't being used, it will be used through changes
in the following commits.
Note that we initially planned to use the 'reset controller'
framework, but it requires the addition of "resets" properties in the
Device Tree, which are causing too many problems if we want to keep
the Device Tree backward compatibility. Moreover, the 'reset
controller' framework is mainly useful when a device driver needs to
request a reset of its device from a separate reset controller. In our
case, the CPU reset handling and the SMP core code are both located in
arch/arm/mach-mvebu/ and are tightly linked together, so there's no
real benefit in going through a separate framework.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
.../devicetree/bindings/arm/armada-cpu-reset.txt | 17 +++++
arch/arm/mach-mvebu/Makefile | 2 +-
arch/arm/mach-mvebu/armada-370-xp.h | 3 +-
arch/arm/mach-mvebu/common.h | 1 +
arch/arm/mach-mvebu/cpu-reset.c | 89 ++++++++++++++++++++++
5 files changed, 110 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/armada-cpu-reset.txt
create mode 100644 arch/arm/mach-mvebu/cpu-reset.c
diff --git a/Documentation/devicetree/bindings/arm/armada-cpu-reset.txt b/Documentation/devicetree/bindings/arm/armada-cpu-reset.txt
new file mode 100644
index 0000000..384cbf8
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/armada-cpu-reset.txt
@@ -0,0 +1,17 @@
+Marvell Armada CPU reset controller
+===================================
+
+Required properties:
+
+- compatible: Should be "marvell,armada-<chip>-cpu-reset". Supported
+ values are:
+ marvell,armada-370-cpu-reset
+ marvell,armada-xp-cpu-reset
+
+- reg: should be register base and length as documented in the
+ datasheet for the CPU reset registers
+
+cpurst: cpurst at 20800 {
+ compatible = "marvell,armada-xp-cpu-reset";
+ reg = <0x20800 0x20>;
+};
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 2c1db29..0e0eab5 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -3,7 +3,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \
AFLAGS_coherency_ll.o := -Wa,-march=armv7-a
-obj-y += system-controller.o mvebu-soc-id.o
+obj-y += system-controller.o mvebu-soc-id.o cpu-reset.o
obj-$(CONFIG_MACH_MVEBU_V7) += board-v7.o
obj-$(CONFIG_ARCH_MVEBU) += coherency.o coherency_ll.o pmsu.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
index 237c86b..991ab32 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.h
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -18,7 +18,8 @@
#ifdef CONFIG_SMP
#include <linux/cpumask.h>
-#define ARMADA_XP_MAX_CPUS 4
+#define ARMADA_370_MAX_CPUS 1
+#define ARMADA_XP_MAX_CPUS 4
void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq);
void armada_xp_mpic_smp_cpu_init(void);
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
index 55449c4..cfb129b 100644
--- a/arch/arm/mach-mvebu/common.h
+++ b/arch/arm/mach-mvebu/common.h
@@ -18,6 +18,7 @@
#include <linux/reboot.h>
void mvebu_restart(enum reboot_mode mode, const char *cmd);
+int mvebu_cpu_reset_deassert(int cpu);
void armada_xp_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mach-mvebu/cpu-reset.c b/arch/arm/mach-mvebu/cpu-reset.c
new file mode 100644
index 0000000..2819887
--- /dev/null
+++ b/arch/arm/mach-mvebu/cpu-reset.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 Marvell
+ *
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "mvebu-cpureset: " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/resource.h>
+#include "armada-370-xp.h"
+
+static struct of_device_id of_cpu_reset_table[] = {
+ {.compatible = "marvell,armada-370-cpu-reset", .data = (void*) ARMADA_370_MAX_CPUS },
+ {.compatible = "marvell,armada-xp-cpu-reset", .data = (void*) ARMADA_XP_MAX_CPUS },
+ { /* end of list */ },
+};
+
+static void __iomem *cpu_reset_base;
+static int ncpus;
+
+#define CPU_RESET_OFFSET(cpu) (cpu * 0x8)
+#define CPU_RESET_ASSERT BIT(0)
+
+int mvebu_cpu_reset_deassert(int cpu)
+{
+ u32 reg;
+
+ if (cpu >= ncpus)
+ return -EINVAL;
+
+ if (!cpu_reset_base)
+ return -ENODEV;
+
+ reg = readl(cpu_reset_base + CPU_RESET_OFFSET(cpu));
+ reg &= ~CPU_RESET_ASSERT;
+ writel(reg, cpu_reset_base + CPU_RESET_OFFSET(cpu));
+
+ return 0;
+}
+
+static int __init mvebu_cpu_reset_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *match;
+ struct resource res;
+ int ret = 0;
+
+ np = of_find_matching_node_and_match(NULL, of_cpu_reset_table,
+ &match);
+ if (!np)
+ return 0;
+
+ if (of_address_to_resource(np, 0, &res)) {
+ pr_err("unable to get resource\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ if (!request_mem_region(res.start, resource_size(&res),
+ np->full_name)) {
+ pr_err("unable to request region\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ cpu_reset_base = ioremap(res.start, resource_size(&res));
+ if (!cpu_reset_base) {
+ pr_err("unable to map registers\n");
+ release_mem_region(res.start, resource_size(&res));
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ncpus = (int) match->data;
+
+out:
+ of_node_put(np);
+ return ret;
+}
+
+early_initcall(mvebu_cpu_reset_init);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 1/6] ARM: mvebu: introduce CPU reset code
2014-03-27 13:38 ` [PATCH 1/6] ARM: mvebu: introduce CPU reset code Thomas Petazzoni
@ 2014-03-27 14:00 ` Gregory CLEMENT
2014-03-27 14:19 ` Thomas Petazzoni
2014-03-27 14:12 ` Sebastian Hesselbarth
1 sibling, 1 reply; 14+ messages in thread
From: Gregory CLEMENT @ 2014-03-27 14:00 UTC (permalink / raw)
To: linux-arm-kernel
Hi Thomas,
On 27/03/2014 14:38, Thomas Petazzoni wrote:
> The Armada 370 and Armada XP have registers that allow to reset the
> CPUs, which is particularly useful to take the secondary CPUs out of
> reset in the context of the SMP support.
>
> Unfortunately, an implementation mistake was originally made and the
> support for these registers was integrated into the PMSU driver, which
> is in fact completely unrelated. And it turns out that the Armada 375
> has the same CPU reset registers, but does not have the PMSU
> registers.
>
> Therefore, this commit creates a small CPU reset driver. All it does
> is provide a simple mvebu_cpu_reset_deassert() function that the SMP
> support code can call to take secondary CPUs out of reset. As of this
> commit, the driver isn't being used, it will be used through changes
> in the following commits.
>
> Note that we initially planned to use the 'reset controller'
> framework, but it requires the addition of "resets" properties in the
> Device Tree, which are causing too many problems if we want to keep
> the Device Tree backward compatibility. Moreover, the 'reset
> controller' framework is mainly useful when a device driver needs to
> request a reset of its device from a separate reset controller. In our
> case, the CPU reset handling and the SMP core code are both located in
> arch/arm/mach-mvebu/ and are tightly linked together, so there's no
> real benefit in going through a separate framework.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> ---
[...]
> +static struct of_device_id of_cpu_reset_table[] = {
> + {.compatible = "marvell,armada-370-cpu-reset", .data = (void*) ARMADA_370_MAX_CPUS },
What about removing the previous line. As explained in patch 5, the CPU
reset driver is not really needed as Armada 370 is single core and the
only use of the CPU reset driver is to boot secondary processors. So by
removing this line we can keep the marvell,armada-370-cpu-reset node in
the device tree without doing useless initialization.
Thanks,
Gregory
> + {.compatible = "marvell,armada-xp-cpu-reset", .data = (void*) ARMADA_XP_MAX_CPUS },
> + { /* end of list */ },
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 1/6] ARM: mvebu: introduce CPU reset code
2014-03-27 14:00 ` Gregory CLEMENT
@ 2014-03-27 14:19 ` Thomas Petazzoni
2014-03-27 15:58 ` Gregory CLEMENT
0 siblings, 1 reply; 14+ messages in thread
From: Thomas Petazzoni @ 2014-03-27 14:19 UTC (permalink / raw)
To: linux-arm-kernel
Dear Gregory CLEMENT,
On Thu, 27 Mar 2014 15:00:17 +0100, Gregory CLEMENT wrote:
> > +static struct of_device_id of_cpu_reset_table[] = {
> > + {.compatible = "marvell,armada-370-cpu-reset", .data = (void*) ARMADA_370_MAX_CPUS },
> What about removing the previous line. As explained in patch 5, the CPU
> reset driver is not really needed as Armada 370 is single core and the
> only use of the CPU reset driver is to boot secondary processors. So by
> removing this line we can keep the marvell,armada-370-cpu-reset node in
> the device tree without doing useless initialization.
I found it weird to have a compatible string marked as supported in the
DT binding document, but not actually supported by the kernel. I know
it's possible, but I found it odd, especially considering the fact that
mapping these registers, even if unused, isn't costing much.
I don't have a strong opinion on this, so if others voice in this way,
I'll change it.
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 1/6] ARM: mvebu: introduce CPU reset code
2014-03-27 14:19 ` Thomas Petazzoni
@ 2014-03-27 15:58 ` Gregory CLEMENT
0 siblings, 0 replies; 14+ messages in thread
From: Gregory CLEMENT @ 2014-03-27 15:58 UTC (permalink / raw)
To: linux-arm-kernel
On 27/03/2014 15:19, Thomas Petazzoni wrote:
> Dear Gregory CLEMENT,
>
> On Thu, 27 Mar 2014 15:00:17 +0100, Gregory CLEMENT wrote:
>
>>> +static struct of_device_id of_cpu_reset_table[] = {
>>> + {.compatible = "marvell,armada-370-cpu-reset", .data = (void*) ARMADA_370_MAX_CPUS },
>> What about removing the previous line. As explained in patch 5, the CPU
>> reset driver is not really needed as Armada 370 is single core and the
>> only use of the CPU reset driver is to boot secondary processors. So by
>> removing this line we can keep the marvell,armada-370-cpu-reset node in
>> the device tree without doing useless initialization.
>
> I found it weird to have a compatible string marked as supported in the
> DT binding document, but not actually supported by the kernel. I know
> it's possible, but I found it odd, especially considering the fact that
> mapping these registers, even if unused, isn't costing much.
>
> I don't have a strong opinion on this, so if others voice in this way,
> I'll change it.
Me neither I don't have a strong opinion on ths, so with our without this line,
you can add my:
Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
and also:
Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
by the way
>
> Thomas
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/6] ARM: mvebu: introduce CPU reset code
2014-03-27 13:38 ` [PATCH 1/6] ARM: mvebu: introduce CPU reset code Thomas Petazzoni
2014-03-27 14:00 ` Gregory CLEMENT
@ 2014-03-27 14:12 ` Sebastian Hesselbarth
2014-03-27 14:21 ` Thomas Petazzoni
1 sibling, 1 reply; 14+ messages in thread
From: Sebastian Hesselbarth @ 2014-03-27 14:12 UTC (permalink / raw)
To: linux-arm-kernel
On 03/27/2014 02:38 PM, Thomas Petazzoni wrote:
> The Armada 370 and Armada XP have registers that allow to reset the
> CPUs, which is particularly useful to take the secondary CPUs out of
> reset in the context of the SMP support.
[...]
> In our case, the CPU reset handling and the SMP core code are both
> located in arch/arm/mach-mvebu/ and are tightly linked together,
> so there's no real benefit in going through a separate framework.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> ---
[...]
> diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
> index 237c86b..991ab32 100644
> --- a/arch/arm/mach-mvebu/armada-370-xp.h
> +++ b/arch/arm/mach-mvebu/armada-370-xp.h
> @@ -18,7 +18,8 @@
> #ifdef CONFIG_SMP
> #include <linux/cpumask.h>
>
> -#define ARMADA_XP_MAX_CPUS 4
> +#define ARMADA_370_MAX_CPUS 1
> +#define ARMADA_XP_MAX_CPUS 4
>
> void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq);
> void armada_xp_mpic_smp_cpu_init(void);
[...]
> diff --git a/arch/arm/mach-mvebu/cpu-reset.c b/arch/arm/mach-mvebu/cpu-reset.c
> new file mode 100644
> index 0000000..2819887
> --- /dev/null
> +++ b/arch/arm/mach-mvebu/cpu-reset.c
> @@ -0,0 +1,89 @@
> +/*
> + * Copyright (C) 2013 Marvell
> + *
> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> + *
> + * 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.
> + */
> +
> +#define pr_fmt(fmt) "mvebu-cpureset: " fmt
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/of_address.h>
> +#include <linux/io.h>
> +#include <linux/resource.h>
> +#include "armada-370-xp.h"
> +
> +static struct of_device_id of_cpu_reset_table[] = {
> + {.compatible = "marvell,armada-370-cpu-reset", .data = (void*) ARMADA_370_MAX_CPUS },
> + {.compatible = "marvell,armada-xp-cpu-reset", .data = (void*) ARMADA_XP_MAX_CPUS },
> + { /* end of list */ },
> +};
> +
> +static void __iomem *cpu_reset_base;
> +static int ncpus;
> +
> +#define CPU_RESET_OFFSET(cpu) (cpu * 0x8)
> +#define CPU_RESET_ASSERT BIT(0)
> +
> +int mvebu_cpu_reset_deassert(int cpu)
> +{
> + u32 reg;
> +
> + if (cpu >= ncpus)
> + return -EINVAL;
Is this check required at all? I mean, the function is supposed to
be called from sane environments, that determine cpu to reset from
some ID register or so. Removing the check will allow you to remove
ncpus and therefore the scratchy (void *)CONST in the of_device_ids
above.
Sebastian
> + if (!cpu_reset_base)
> + return -ENODEV;
> +
> + reg = readl(cpu_reset_base + CPU_RESET_OFFSET(cpu));
> + reg &= ~CPU_RESET_ASSERT;
> + writel(reg, cpu_reset_base + CPU_RESET_OFFSET(cpu));
> +
> + return 0;
> +}
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 1/6] ARM: mvebu: introduce CPU reset code
2014-03-27 14:12 ` Sebastian Hesselbarth
@ 2014-03-27 14:21 ` Thomas Petazzoni
0 siblings, 0 replies; 14+ messages in thread
From: Thomas Petazzoni @ 2014-03-27 14:21 UTC (permalink / raw)
To: linux-arm-kernel
Dear Sebastian Hesselbarth,
On Thu, 27 Mar 2014 15:12:16 +0100, Sebastian Hesselbarth wrote:
> > +static struct of_device_id of_cpu_reset_table[] = {
> > + {.compatible = "marvell,armada-370-cpu-reset", .data = (void*) ARMADA_370_MAX_CPUS },
> > + {.compatible = "marvell,armada-xp-cpu-reset", .data = (void*) ARMADA_XP_MAX_CPUS },
> > + { /* end of list */ },
> > +};
> > +
> > +static void __iomem *cpu_reset_base;
> > +static int ncpus;
> > +
> > +#define CPU_RESET_OFFSET(cpu) (cpu * 0x8)
> > +#define CPU_RESET_ASSERT BIT(0)
> > +
> > +int mvebu_cpu_reset_deassert(int cpu)
> > +{
> > + u32 reg;
> > +
> > + if (cpu >= ncpus)
> > + return -EINVAL;
>
> Is this check required at all? I mean, the function is supposed to
> be called from sane environments, that determine cpu to reset from
> some ID register or so. Removing the check will allow you to remove
> ncpus and therefore the scratchy (void *)CONST in the of_device_ids
> above.
Just a safety check to ensure we're not writing outside of the CPU
reset registers that have been mapped. I more or less tend to believe
that it's nicer to have APIs that do some minimal amount of checking
and return an error, rather than having things completely blow up when
arguments are wrong.
But I certainly understand that this is a very subjective view, and I
wouldn't mind changing the code according to your suggestion if other
people agree with it.
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 2/6] ARM: mvebu: start using the CPU reset driver
2014-03-27 13:37 [PATCH 0/6] ARM: mvebu: prepare PMSU code for cpuidle and Armada 375/38x SMP Thomas Petazzoni
2014-03-27 13:38 ` [PATCH 1/6] ARM: mvebu: introduce CPU reset code Thomas Petazzoni
@ 2014-03-27 13:38 ` Thomas Petazzoni
2014-03-27 15:58 ` Gregory CLEMENT
2014-03-27 13:38 ` [PATCH 3/6] ARM: mvebu: improve PMSU driver to request its resource Thomas Petazzoni
` (3 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Thomas Petazzoni @ 2014-03-27 13:38 UTC (permalink / raw)
To: linux-arm-kernel
This commit changes the PMSU driver to no longer map itself the CPU
reset registers, and instead call into the CPU reset driver to
deassert the secondary CPUs for SMP booting.
In order to provide Device Tree backward compatibility, the CPU reset
driver is extended to not only support its official compatible strings
"marvell,armada-370-cpu-reset" and "marvell,armada-xp-cpu-reset", but
to also look at the PMSU compatible string
"marvell,armada-370-xp-pmsu" to find the CPU reset registers
address. This allows old Device Tree to work correctly with newer
kernel versions. Therefore, the CPU reset driver implements the
following logic:
* If one of the normal compatible strings
"marvell,armada-<chip>-cpu-reset" is found, then we map its first
memory resource as the CPU reset registers.
* Otherwise, if none of the normal compatible strings have been
found, we look for the "marvell,armada-370-xp-pmsu" compatible
string, and we map the second memory as the CPU reset registers.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm/mach-mvebu/cpu-reset.c | 56 ++++++++++++++++++++++++++++-------------
arch/arm/mach-mvebu/pmsu.c | 20 +++++++--------
2 files changed, 48 insertions(+), 28 deletions(-)
diff --git a/arch/arm/mach-mvebu/cpu-reset.c b/arch/arm/mach-mvebu/cpu-reset.c
index 2819887..e3821b1 100644
--- a/arch/arm/mach-mvebu/cpu-reset.c
+++ b/arch/arm/mach-mvebu/cpu-reset.c
@@ -46,43 +46,63 @@ int mvebu_cpu_reset_deassert(int cpu)
return 0;
}
-static int __init mvebu_cpu_reset_init(void)
+static int mvebu_cpu_reset_map(struct device_node *np, int res_idx)
{
- struct device_node *np;
- const struct of_device_id *match;
struct resource res;
- int ret = 0;
- np = of_find_matching_node_and_match(NULL, of_cpu_reset_table,
- &match);
- if (!np)
- return 0;
-
- if (of_address_to_resource(np, 0, &res)) {
+ if (of_address_to_resource(np, res_idx, &res)) {
pr_err("unable to get resource\n");
- ret = -ENOENT;
- goto out;
+ return -ENOENT;
}
if (!request_mem_region(res.start, resource_size(&res),
np->full_name)) {
pr_err("unable to request region\n");
- ret = -EBUSY;
- goto out;
+ return -EBUSY;
}
cpu_reset_base = ioremap(res.start, resource_size(&res));
if (!cpu_reset_base) {
pr_err("unable to map registers\n");
release_mem_region(res.start, resource_size(&res));
- ret = -ENOMEM;
- goto out;
+ return -ENOMEM;
}
- ncpus = (int) match->data;
+ return 0;
+}
-out:
+int __init mvebu_cpu_reset_init(void)
+{
+ struct device_node *np;
+ const struct of_device_id *match;
+ int res_idx;
+ int ret;
+
+ np = of_find_matching_node_and_match(NULL, of_cpu_reset_table,
+ &match);
+ if (np) {
+ res_idx = 0;
+ ncpus = (int) match->data;
+ } else {
+ /*
+ * This code is kept for backward compatibility with
+ * old Device Trees.
+ */
+ np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-pmsu");
+ if (np) {
+ pr_warn(FW_WARN "deprecated pmsu binding\n");
+ res_idx = 1;
+ ncpus = ARMADA_XP_MAX_CPUS;
+ }
+ }
+
+ /* No reset node found */
+ if (!np)
+ return 0;
+
+ ret = mvebu_cpu_reset_map(np, res_idx);
of_node_put(np);
+
return ret;
}
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index d71ef53..1807639 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -21,14 +21,14 @@
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/smp.h>
+#include <linux/resource.h>
#include <asm/smp_plat.h>
+#include "common.h"
#include "pmsu.h"
static void __iomem *pmsu_mp_base;
-static void __iomem *pmsu_reset_base;
#define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x24)
-#define PMSU_RESET_CTL_OFFSET(cpu) (cpu * 0x8)
static struct of_device_id of_pmsu_table[] = {
{.compatible = "marvell,armada-370-xp-pmsu"},
@@ -38,11 +38,11 @@ static struct of_device_id of_pmsu_table[] = {
#ifdef CONFIG_SMP
int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
{
- int reg, hw_cpu;
+ int hw_cpu, ret;
- if (!pmsu_mp_base || !pmsu_reset_base) {
+ if (!pmsu_mp_base) {
pr_warn("Can't boot CPU. PMSU is uninitialized\n");
- return 1;
+ return -ENODEV;
}
hw_cpu = cpu_logical_map(cpu_id);
@@ -50,10 +50,11 @@ int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
writel(virt_to_phys(boot_addr), pmsu_mp_base +
PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
- /* Release CPU from reset by clearing reset bit*/
- reg = readl(pmsu_reset_base + PMSU_RESET_CTL_OFFSET(hw_cpu));
- reg &= (~0x1);
- writel(reg, pmsu_reset_base + PMSU_RESET_CTL_OFFSET(hw_cpu));
+ ret = mvebu_cpu_reset_deassert(hw_cpu);
+ if (ret) {
+ pr_warn("unable to boot CPU: %d\n", ret);
+ return ret;
+ }
return 0;
}
@@ -67,7 +68,6 @@ static int __init armada_370_xp_pmsu_init(void)
if (np) {
pr_info("Initializing Power Management Service Unit\n");
pmsu_mp_base = of_iomap(np, 0);
- pmsu_reset_base = of_iomap(np, 1);
of_node_put(np);
}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 2/6] ARM: mvebu: start using the CPU reset driver
2014-03-27 13:38 ` [PATCH 2/6] ARM: mvebu: start using the CPU reset driver Thomas Petazzoni
@ 2014-03-27 15:58 ` Gregory CLEMENT
0 siblings, 0 replies; 14+ messages in thread
From: Gregory CLEMENT @ 2014-03-27 15:58 UTC (permalink / raw)
To: linux-arm-kernel
On 27/03/2014 14:38, Thomas Petazzoni wrote:
> This commit changes the PMSU driver to no longer map itself the CPU
> reset registers, and instead call into the CPU reset driver to
> deassert the secondary CPUs for SMP booting.
>
> In order to provide Device Tree backward compatibility, the CPU reset
> driver is extended to not only support its official compatible strings
> "marvell,armada-370-cpu-reset" and "marvell,armada-xp-cpu-reset", but
> to also look at the PMSU compatible string
> "marvell,armada-370-xp-pmsu" to find the CPU reset registers
> address. This allows old Device Tree to work correctly with newer
> kernel versions. Therefore, the CPU reset driver implements the
> following logic:
>
> * If one of the normal compatible strings
> "marvell,armada-<chip>-cpu-reset" is found, then we map its first
> memory resource as the CPU reset registers.
>
> * Otherwise, if none of the normal compatible strings have been
> found, we look for the "marvell,armada-370-xp-pmsu" compatible
> string, and we map the second memory as the CPU reset registers.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> arch/arm/mach-mvebu/cpu-reset.c | 56 ++++++++++++++++++++++++++++-------------
> arch/arm/mach-mvebu/pmsu.c | 20 +++++++--------
> 2 files changed, 48 insertions(+), 28 deletions(-)
>
> diff --git a/arch/arm/mach-mvebu/cpu-reset.c b/arch/arm/mach-mvebu/cpu-reset.c
> index 2819887..e3821b1 100644
> --- a/arch/arm/mach-mvebu/cpu-reset.c
> +++ b/arch/arm/mach-mvebu/cpu-reset.c
> @@ -46,43 +46,63 @@ int mvebu_cpu_reset_deassert(int cpu)
> return 0;
> }
>
> -static int __init mvebu_cpu_reset_init(void)
> +static int mvebu_cpu_reset_map(struct device_node *np, int res_idx)
> {
> - struct device_node *np;
> - const struct of_device_id *match;
> struct resource res;
> - int ret = 0;
>
> - np = of_find_matching_node_and_match(NULL, of_cpu_reset_table,
> - &match);
> - if (!np)
> - return 0;
> -
> - if (of_address_to_resource(np, 0, &res)) {
> + if (of_address_to_resource(np, res_idx, &res)) {
> pr_err("unable to get resource\n");
> - ret = -ENOENT;
> - goto out;
> + return -ENOENT;
> }
>
> if (!request_mem_region(res.start, resource_size(&res),
> np->full_name)) {
> pr_err("unable to request region\n");
> - ret = -EBUSY;
> - goto out;
> + return -EBUSY;
> }
>
> cpu_reset_base = ioremap(res.start, resource_size(&res));
> if (!cpu_reset_base) {
> pr_err("unable to map registers\n");
> release_mem_region(res.start, resource_size(&res));
> - ret = -ENOMEM;
> - goto out;
> + return -ENOMEM;
> }
>
> - ncpus = (int) match->data;
> + return 0;
> +}
>
> -out:
> +int __init mvebu_cpu_reset_init(void)
> +{
> + struct device_node *np;
> + const struct of_device_id *match;
> + int res_idx;
> + int ret;
> +
> + np = of_find_matching_node_and_match(NULL, of_cpu_reset_table,
> + &match);
> + if (np) {
> + res_idx = 0;
> + ncpus = (int) match->data;
> + } else {
> + /*
> + * This code is kept for backward compatibility with
> + * old Device Trees.
> + */
> + np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-pmsu");
> + if (np) {
> + pr_warn(FW_WARN "deprecated pmsu binding\n");
> + res_idx = 1;
> + ncpus = ARMADA_XP_MAX_CPUS;
> + }
> + }
> +
> + /* No reset node found */
> + if (!np)
> + return 0;
> +
> + ret = mvebu_cpu_reset_map(np, res_idx);
> of_node_put(np);
> +
> return ret;
> }
>
> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> index d71ef53..1807639 100644
> --- a/arch/arm/mach-mvebu/pmsu.c
> +++ b/arch/arm/mach-mvebu/pmsu.c
> @@ -21,14 +21,14 @@
> #include <linux/of_address.h>
> #include <linux/io.h>
> #include <linux/smp.h>
> +#include <linux/resource.h>
> #include <asm/smp_plat.h>
> +#include "common.h"
> #include "pmsu.h"
>
> static void __iomem *pmsu_mp_base;
> -static void __iomem *pmsu_reset_base;
>
> #define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x24)
> -#define PMSU_RESET_CTL_OFFSET(cpu) (cpu * 0x8)
>
> static struct of_device_id of_pmsu_table[] = {
> {.compatible = "marvell,armada-370-xp-pmsu"},
> @@ -38,11 +38,11 @@ static struct of_device_id of_pmsu_table[] = {
> #ifdef CONFIG_SMP
> int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
> {
> - int reg, hw_cpu;
> + int hw_cpu, ret;
>
> - if (!pmsu_mp_base || !pmsu_reset_base) {
> + if (!pmsu_mp_base) {
> pr_warn("Can't boot CPU. PMSU is uninitialized\n");
> - return 1;
> + return -ENODEV;
> }
>
> hw_cpu = cpu_logical_map(cpu_id);
> @@ -50,10 +50,11 @@ int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
> writel(virt_to_phys(boot_addr), pmsu_mp_base +
> PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
>
> - /* Release CPU from reset by clearing reset bit*/
> - reg = readl(pmsu_reset_base + PMSU_RESET_CTL_OFFSET(hw_cpu));
> - reg &= (~0x1);
> - writel(reg, pmsu_reset_base + PMSU_RESET_CTL_OFFSET(hw_cpu));
> + ret = mvebu_cpu_reset_deassert(hw_cpu);
> + if (ret) {
> + pr_warn("unable to boot CPU: %d\n", ret);
> + return ret;
> + }
>
> return 0;
> }
> @@ -67,7 +68,6 @@ static int __init armada_370_xp_pmsu_init(void)
> if (np) {
> pr_info("Initializing Power Management Service Unit\n");
> pmsu_mp_base = of_iomap(np, 0);
> - pmsu_reset_base = of_iomap(np, 1);
> of_node_put(np);
> }
>
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/6] ARM: mvebu: improve PMSU driver to request its resource
2014-03-27 13:37 [PATCH 0/6] ARM: mvebu: prepare PMSU code for cpuidle and Armada 375/38x SMP Thomas Petazzoni
2014-03-27 13:38 ` [PATCH 1/6] ARM: mvebu: introduce CPU reset code Thomas Petazzoni
2014-03-27 13:38 ` [PATCH 2/6] ARM: mvebu: start using the CPU reset driver Thomas Petazzoni
@ 2014-03-27 13:38 ` Thomas Petazzoni
2014-03-27 15:59 ` Gregory CLEMENT
2014-03-27 13:38 ` [PATCH 4/6] ARM: mvebu: extend the PMSU registers Thomas Petazzoni
` (2 subsequent siblings)
5 siblings, 1 reply; 14+ messages in thread
From: Thomas Petazzoni @ 2014-03-27 13:38 UTC (permalink / raw)
To: linux-arm-kernel
Until now, the PMSU driver was using of_iomap() to map its registers,
but of_iomap() doesn't call request_mem_region(). This commit fixes
the memory mapping code of the PMSU to do so, which will also be
useful for a later commit since we will need to adjust the resource
base address and size for Device Tree backward compatibility.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm/mach-mvebu/pmsu.c | 36 +++++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 1807639..b337fe5 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -16,6 +16,8 @@
* other SOC units
*/
+#define pr_fmt(fmt) "mvebu-pmsu: " fmt
+
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of_address.h>
@@ -63,15 +65,39 @@ int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
static int __init armada_370_xp_pmsu_init(void)
{
struct device_node *np;
+ struct resource res;
+ int ret = 0;
np = of_find_matching_node(NULL, of_pmsu_table);
- if (np) {
- pr_info("Initializing Power Management Service Unit\n");
- pmsu_mp_base = of_iomap(np, 0);
- of_node_put(np);
+ if (!np)
+ return 0;
+
+ pr_info("Initializing Power Management Service Unit\n");
+
+ if (of_address_to_resource(np, 0, &res)) {
+ pr_err("unable to get resource\n");
+ ret = -ENOENT;
+ goto out;
}
- return 0;
+ if (!request_mem_region(res.start, resource_size(&res),
+ np->full_name)) {
+ pr_err("unable to request region\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ pmsu_mp_base = ioremap(res.start, resource_size(&res));
+ if (!pmsu_mp_base) {
+ pr_err("unable to map registers\n");
+ release_mem_region(res.start, resource_size(&res));
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ out:
+ of_node_put(np);
+ return ret;
}
early_initcall(armada_370_xp_pmsu_init);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 3/6] ARM: mvebu: improve PMSU driver to request its resource
2014-03-27 13:38 ` [PATCH 3/6] ARM: mvebu: improve PMSU driver to request its resource Thomas Petazzoni
@ 2014-03-27 15:59 ` Gregory CLEMENT
0 siblings, 0 replies; 14+ messages in thread
From: Gregory CLEMENT @ 2014-03-27 15:59 UTC (permalink / raw)
To: linux-arm-kernel
On 27/03/2014 14:38, Thomas Petazzoni wrote:
> Until now, the PMSU driver was using of_iomap() to map its registers,
> but of_iomap() doesn't call request_mem_region(). This commit fixes
> the memory mapping code of the PMSU to do so, which will also be
> useful for a later commit since we will need to adjust the resource
> base address and size for Device Tree backward compatibility.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> arch/arm/mach-mvebu/pmsu.c | 36 +++++++++++++++++++++++++++++++-----
> 1 file changed, 31 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
> index 1807639..b337fe5 100644
> --- a/arch/arm/mach-mvebu/pmsu.c
> +++ b/arch/arm/mach-mvebu/pmsu.c
> @@ -16,6 +16,8 @@
> * other SOC units
> */
>
> +#define pr_fmt(fmt) "mvebu-pmsu: " fmt
> +
> #include <linux/kernel.h>
> #include <linux/init.h>
> #include <linux/of_address.h>
> @@ -63,15 +65,39 @@ int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
> static int __init armada_370_xp_pmsu_init(void)
> {
> struct device_node *np;
> + struct resource res;
> + int ret = 0;
>
> np = of_find_matching_node(NULL, of_pmsu_table);
> - if (np) {
> - pr_info("Initializing Power Management Service Unit\n");
> - pmsu_mp_base = of_iomap(np, 0);
> - of_node_put(np);
> + if (!np)
> + return 0;
> +
> + pr_info("Initializing Power Management Service Unit\n");
> +
> + if (of_address_to_resource(np, 0, &res)) {
> + pr_err("unable to get resource\n");
> + ret = -ENOENT;
> + goto out;
> }
>
> - return 0;
> + if (!request_mem_region(res.start, resource_size(&res),
> + np->full_name)) {
> + pr_err("unable to request region\n");
> + ret = -EBUSY;
> + goto out;
> + }
> +
> + pmsu_mp_base = ioremap(res.start, resource_size(&res));
> + if (!pmsu_mp_base) {
> + pr_err("unable to map registers\n");
> + release_mem_region(res.start, resource_size(&res));
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + out:
> + of_node_put(np);
> + return ret;
> }
>
> early_initcall(armada_370_xp_pmsu_init);
>
--
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 4/6] ARM: mvebu: extend the PMSU registers
2014-03-27 13:37 [PATCH 0/6] ARM: mvebu: prepare PMSU code for cpuidle and Armada 375/38x SMP Thomas Petazzoni
` (2 preceding siblings ...)
2014-03-27 13:38 ` [PATCH 3/6] ARM: mvebu: improve PMSU driver to request its resource Thomas Petazzoni
@ 2014-03-27 13:38 ` Thomas Petazzoni
2014-03-27 13:38 ` [PATCH 5/6] ARM: mvebu: switch to the new PMSU binding in Armada 370/XP Device Tree Thomas Petazzoni
2014-03-27 13:38 ` [PATCH 6/6] ARM: mvebu: use a separate function to set the boot address of CPUs Thomas Petazzoni
5 siblings, 0 replies; 14+ messages in thread
From: Thomas Petazzoni @ 2014-03-27 13:38 UTC (permalink / raw)
To: linux-arm-kernel
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
The initial binding for PMSU was wrong, as it didn't take into account
all the registers from the PMSU and moreover it referred to the CPU
reset registers which are not part of PMSU.
The Power Management Unit Service block also controls the Coherency
Fabric subsystem. These registers are needed for the CPU idle
implementation for the Armada 370/XP, it allows to enter a deep CPU
idle state where the Coherency Fabric and the L2 cache are powered
down.
This commit adds support for a new compatible for the PMSU node which
includes the registers related to the coherency fabric. It also keeps
compatibility with the old compatible string.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
.../devicetree/bindings/arm/armada-370-xp-pmsu.txt | 14 ++++++--------
arch/arm/mach-mvebu/pmsu.c | 14 ++++++++++++--
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt b/Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
index 926b4d6..9761887 100644
--- a/Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
+++ b/Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt
@@ -4,17 +4,15 @@ Available on Marvell SOCs: Armada 370 and Armada XP
Required properties:
-- compatible: "marvell,armada-370-xp-pmsu"
+- compatible: should be "marvell,armada-370-pmsu", whereas
+ "marvell,armada-370-xp-pmsu" is deprecated and will be removed
-- reg: Should contain PMSU registers location and length. First pair
- for the per-CPU SW Reset Control registers, second pair for the
- Power Management Service Unit.
+- reg: Should contain PMSU registers location and length.
Example:
-armada-370-xp-pmsu at d0022000 {
- compatible = "marvell,armada-370-xp-pmsu";
- reg = <0xd0022100 0x430>,
- <0xd0020800 0x20>;
+armada-370-xp-pmsu at 22000 {
+ compatible = "marvell,armada-370-pmsu";
+ reg = <0x22000 0x1000>;
};
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index b337fe5..4ae3ea1 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -30,10 +30,14 @@
static void __iomem *pmsu_mp_base;
-#define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x24)
+#define PMSU_BASE_OFFSET 0x100
+#define PMSU_REG_SIZE 0x1000
+
+#define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x124)
static struct of_device_id of_pmsu_table[] = {
- {.compatible = "marvell,armada-370-xp-pmsu"},
+ { .compatible = "marvell,armada-370-pmsu", },
+ { .compatible = "marvell,armada-370-xp-pmsu", },
{ /* end of list */ },
};
@@ -80,6 +84,12 @@ static int __init armada_370_xp_pmsu_init(void)
goto out;
}
+ if (of_device_is_compatible(np, "marvell,armada-370-xp-pmsu")) {
+ pr_warn(FW_WARN "deprecated pmsu binding\n");
+ res.start = res.start - PMSU_BASE_OFFSET;
+ res.end = res.start + PMSU_REG_SIZE - 1;
+ }
+
if (!request_mem_region(res.start, resource_size(&res),
np->full_name)) {
pr_err("unable to request region\n");
--
1.8.3.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 5/6] ARM: mvebu: switch to the new PMSU binding in Armada 370/XP Device Tree
2014-03-27 13:37 [PATCH 0/6] ARM: mvebu: prepare PMSU code for cpuidle and Armada 375/38x SMP Thomas Petazzoni
` (3 preceding siblings ...)
2014-03-27 13:38 ` [PATCH 4/6] ARM: mvebu: extend the PMSU registers Thomas Petazzoni
@ 2014-03-27 13:38 ` Thomas Petazzoni
2014-03-27 13:38 ` [PATCH 6/6] ARM: mvebu: use a separate function to set the boot address of CPUs Thomas Petazzoni
5 siblings, 0 replies; 14+ messages in thread
From: Thomas Petazzoni @ 2014-03-27 13:38 UTC (permalink / raw)
To: linux-arm-kernel
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Following the introduction of the new PMSU Device Tree binding, as
well as the separate CPU reset binding, this commit switches the
Armada 370 and Armada XP Device Trees to use them.
The PMSU node is moved from the Armada XP specific armada-xp.dtsi to
the common Armada 370/XP armada-370-xp.dtsi because the PMSU is in
fact available at the same location on both SOCs.
The CPU reset node is then added on both Armada 370 and Armada XP,
with a different compatible string. On Armada 370, the CPU reset
driver is not really needed as Armada 370 is single core and the only
use of the CPU reset driver is to boot secondary processors, but it
still makes sense to have this CPU reset register described in the
Device Tree.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm/boot/dts/armada-370-xp.dtsi | 5 +++++
arch/arm/boot/dts/armada-370.dtsi | 5 +++++
arch/arm/boot/dts/armada-xp.dtsi | 6 +++---
3 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 74b5964..d286d67 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -199,6 +199,11 @@
interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
};
+ armada-370-pmsu at 22000 {
+ compatible = "marvell,armada-370-pmsu";
+ reg = <0x22000 0x1000>;
+ };
+
usb at 50000 {
compatible = "marvell,orion-ehci";
reg = <0x50000 0x500>;
diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index 0d8530c..4636a22 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -196,6 +196,11 @@
clocks = <&coreclk 2>;
};
+ cpurst at 20800 {
+ compatible = "marvell,armada-370-cpu-reset";
+ reg = <0x20800 0x8>;
+ };
+
usb at 50000 {
clocks = <&coreclk 0>;
};
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index b8b84a2..4d36a12 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -111,9 +111,9 @@
clock-names = "nbclk", "fixed";
};
- armada-370-xp-pmsu at 22000 {
- compatible = "marvell,armada-370-xp-pmsu";
- reg = <0x22100 0x400>, <0x20800 0x20>;
+ cpurst at 20800 {
+ compatible = "marvell,armada-xp-cpu-reset";
+ reg = <0x20800 0x20>;
};
eth2: ethernet at 30000 {
--
1.8.3.2
^ permalink raw reply related [flat|nested] 14+ messages in thread* [PATCH 6/6] ARM: mvebu: use a separate function to set the boot address of CPUs
2014-03-27 13:37 [PATCH 0/6] ARM: mvebu: prepare PMSU code for cpuidle and Armada 375/38x SMP Thomas Petazzoni
` (4 preceding siblings ...)
2014-03-27 13:38 ` [PATCH 5/6] ARM: mvebu: switch to the new PMSU binding in Armada 370/XP Device Tree Thomas Petazzoni
@ 2014-03-27 13:38 ` Thomas Petazzoni
5 siblings, 0 replies; 14+ messages in thread
From: Thomas Petazzoni @ 2014-03-27 13:38 UTC (permalink / raw)
To: linux-arm-kernel
From: Gregory CLEMENT <gregory.clement@free-electrons.com>
Setting the start (or boot) address of a CPU is no more used only
during SMP bring up on Armada 370/XP, but it will also be used by the
CPU idle function of Armada XP, and by the Armada 38x SMP support.
Therefore this commit creates a separate PMSU function to set the boot
address of a CPU with the PMSU.
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
arch/arm/mach-mvebu/pmsu.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 4ae3ea1..8361281 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -41,6 +41,12 @@ static struct of_device_id of_pmsu_table[] = {
{ /* end of list */ },
};
+static void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr)
+{
+ writel(virt_to_phys(boot_addr), pmsu_mp_base +
+ PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
+}
+
#ifdef CONFIG_SMP
int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
{
@@ -53,8 +59,7 @@ int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
hw_cpu = cpu_logical_map(cpu_id);
- writel(virt_to_phys(boot_addr), pmsu_mp_base +
- PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
+ mvebu_pmsu_set_cpu_boot_addr(hw_cpu, boot_addr);
ret = mvebu_cpu_reset_deassert(hw_cpu);
if (ret) {
--
1.8.3.2
^ permalink raw reply related [flat|nested] 14+ messages in thread