]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - arch/arm/mach-mvebu/pmsu.c
ARM: mvebu: start using the CPU reset driver
[mirror_ubuntu-artful-kernel.git] / arch / arm / mach-mvebu / pmsu.c
CommitLineData
7444dad2
GC
1/*
2 * Power Management Service Unit(PMSU) support for Armada 370/XP platforms.
3 *
4 * Copyright (C) 2012 Marvell
5 *
6 * Yehuda Yitschak <yehuday@marvell.com>
7 * Gregory Clement <gregory.clement@free-electrons.com>
8 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
9 *
10 * This file is licensed under the terms of the GNU General Public
11 * License version 2. This program is licensed "as is" without any
12 * warranty of any kind, whether express or implied.
13 *
14 * The Armada 370 and Armada XP SOCs have a power management service
15 * unit which is responsible for powering down and waking up CPUs and
16 * other SOC units
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/of_address.h>
22#include <linux/io.h>
23#include <linux/smp.h>
49754ffe 24#include <linux/resource.h>
7444dad2 25#include <asm/smp_plat.h>
49754ffe 26#include "common.h"
b12634e3 27#include "pmsu.h"
7444dad2
GC
28
29static void __iomem *pmsu_mp_base;
7444dad2
GC
30
31#define PMSU_BOOT_ADDR_REDIRECT_OFFSET(cpu) ((cpu * 0x100) + 0x24)
7444dad2
GC
32
33static struct of_device_id of_pmsu_table[] = {
34 {.compatible = "marvell,armada-370-xp-pmsu"},
35 { /* end of list */ },
36};
37
38#ifdef CONFIG_SMP
39int armada_xp_boot_cpu(unsigned int cpu_id, void *boot_addr)
40{
49754ffe 41 int hw_cpu, ret;
7444dad2 42
49754ffe 43 if (!pmsu_mp_base) {
7444dad2 44 pr_warn("Can't boot CPU. PMSU is uninitialized\n");
49754ffe 45 return -ENODEV;
7444dad2
GC
46 }
47
48 hw_cpu = cpu_logical_map(cpu_id);
49
50 writel(virt_to_phys(boot_addr), pmsu_mp_base +
51 PMSU_BOOT_ADDR_REDIRECT_OFFSET(hw_cpu));
52
49754ffe
TP
53 ret = mvebu_cpu_reset_deassert(hw_cpu);
54 if (ret) {
55 pr_warn("unable to boot CPU: %d\n", ret);
56 return ret;
57 }
7444dad2
GC
58
59 return 0;
60}
61#endif
62
b12634e3 63static int __init armada_370_xp_pmsu_init(void)
7444dad2
GC
64{
65 struct device_node *np;
66
67 np = of_find_matching_node(NULL, of_pmsu_table);
68 if (np) {
69 pr_info("Initializing Power Management Service Unit\n");
70 pmsu_mp_base = of_iomap(np, 0);
abe511ac 71 of_node_put(np);
7444dad2
GC
72 }
73
74 return 0;
75}
76
77early_initcall(armada_370_xp_pmsu_init);