summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mvebu/cpu-reset.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2014-05-19 21:59:55 -0700
committerOlof Johansson <olof@lixom.net>2014-05-19 21:59:55 -0700
commit5df22a6148d7f073513a61eb306a98654c5a6fe8 (patch)
treed80a90222f36b303eea4f6334a3cbe6e35baeecd /arch/arm/mach-mvebu/cpu-reset.c
parentc15c1199b0031f2dcc3437e9998e9abe99e2609c (diff)
parent9f0affcf3e21fc56d8bce625bb3d5800b7a7d284 (diff)
Merge tag 'mvebu-soc-3.16' of git://git.infradead.org/linux-mvebu into next/soc
Merge "ARM: mvebu: SoC changes for v3.16" from Jason Cooper: mvebu SoC changes for v3.16 - Armada 375/38x coherency support - Armada 375/38x SMP support - mvebu PMSU and CPU reset support - Armada 370/XP cpuidle support - kirkwood remove platform init of audio device - small fixes and cleanup for new SoC (375/38x) Note: - due to complex deps, cpuidle changes Acked by appropriate maintainer for going though arm-soc tree. * tag 'mvebu-soc-3.16' of git://git.infradead.org/linux-mvebu: (46 commits) ARM: mvebu: Fix pmsu compilation when ARMv6 is selected ARM: mvebu: conditionalize Armada 375 coherency workaround ARM: mvebu: conditionalize Armada 375 SMP workaround ARM: mvebu: add Armada 375 A0 revision definition ARM: mvebu: initialize mvebu-soc-id earlier ARM: mvebu: fix thermal quirk SoC revision check ARM: Kirkwood: t5325: Remove platform device to instantiate audio ARM: Kirkwood: Remove platform driver for codec ARM: mvebu: Add thermal quirk for the Armada 375 DB board ARM: mvebu: Select HAVE_ARM_TWD only if SMP is enabled ARM: mvebu: fix the name of the parameter used in mvebu_get_soc_id ARM: mvebu: remove unnecessary ifdef around l2x0_of_init ARM: mvebu: register the cpuidle driver for the Armada XP SoCs cpuidle: mvebu: Add initial CPU idle support for Armada 370/XP SoC ARM: mvebu: Register notifier callback for the cpuidle transition ARM: mvebu: refine which files are build in mach-mvebu ARM: mvebu: Add the PMSU related part of the cpu idle functions ARM: mvebu: Allow to power down L2 cache controller in idle mode ARM: mvebu: Low level function to disable HW coherency support ARM: mvebu: Split low level functions to manipulate HW coherency ... Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-mvebu/cpu-reset.c')
-rw-r--r--arch/arm/mach-mvebu/cpu-reset.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/arch/arm/mach-mvebu/cpu-reset.c b/arch/arm/mach-mvebu/cpu-reset.c
new file mode 100644
index 00000000000..4a8f9eebebe
--- /dev/null
+++ b/arch/arm/mach-mvebu/cpu-reset.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2014 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 void __iomem *cpu_reset_base;
+static size_t cpu_reset_size;
+
+#define CPU_RESET_OFFSET(cpu) (cpu * 0x8)
+#define CPU_RESET_ASSERT BIT(0)
+
+int mvebu_cpu_reset_deassert(int cpu)
+{
+ u32 reg;
+
+ if (!cpu_reset_base)
+ return -ENODEV;
+
+ if (CPU_RESET_OFFSET(cpu) >= cpu_reset_size)
+ return -EINVAL;
+
+ 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 mvebu_cpu_reset_map(struct device_node *np, int res_idx)
+{
+ struct resource res;
+
+ if (of_address_to_resource(np, res_idx, &res)) {
+ pr_err("unable to get resource\n");
+ return -ENOENT;
+ }
+
+ if (!request_mem_region(res.start, resource_size(&res),
+ np->full_name)) {
+ pr_err("unable to request region\n");
+ 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));
+ return -ENOMEM;
+ }
+
+ cpu_reset_size = resource_size(&res);
+
+ return 0;
+}
+
+int __init mvebu_cpu_reset_init(void)
+{
+ struct device_node *np;
+ int res_idx;
+ int ret;
+
+ np = of_find_compatible_node(NULL, NULL,
+ "marvell,armada-370-cpu-reset");
+ if (np) {
+ res_idx = 0;
+ } 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;
+ }
+ }
+
+ /* No reset node found */
+ if (!np)
+ return -ENODEV;
+
+ ret = mvebu_cpu_reset_map(np, res_idx);
+ of_node_put(np);
+
+ return ret;
+}
+
+early_initcall(mvebu_cpu_reset_init);