mvebu SoC changes for v3.17

- kirkwood
     - add setup file for netxbig LEDs (non-trivial DT binding doesn't exist yet)
 
  - mvebu
     - staticize where needed
     - add CPU hotplug for Armada XP
     - add public datasheet for Armada 370
     - don't apply thermal quirk by default
     - get SoC ID from the system controller when possible
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJTsqSHAAoJEP45WPkGe8Zn/6QP/2cTEIpMUDVMHCIPqyu32xNX
 3uprZuay6hL5vyLOM/p2iUHLGyMVKvEVVWJuB2bGZX9Nf47Uq92PQ4MEGxS7xJYU
 EKh8qjX3rQBFpsX1mOyP4XStlYxI5QxM3Jie2n2lquo5mxMMNNU8FcNWWMw02W0g
 EfyKwtxNRBkZi8KhgvDDGvE+Oe6qB394p/erFDaP8s9vLbGisoX/prnqBEYOWbAA
 e8qy338lSVu/if/Q4U4ffjBRXFShw1uJK+AHS9xEH2veuBisR3FaHcIqvgYpeMqx
 sIJWVyNaqWFs3kEAp4TlEkoEGUIc1Z/pL76WK69mgpnCO3X0OtnNFlrwMqb8rAwg
 9ziHN9uxSmxcjSLeYlroCxHzt8XKZ0UPmPASZq78Sl/q9Gr0V6bPTPusUYPKDln4
 uR7Px49Vvuc1ijn2mWRAQMW9wvDGCgUw8u3nhOHLktH2osWfD41SjAmbLEnysP//
 7j3Rw+auxtbyFrKGQDfVon+l/yUrUT9jXW6yq7/ON/YpT4OSJTHWz19nvokyCmW1
 aH8qlKS2oMy1ZfncWgHjgVCREmQP9lSfxfpqsHLxPVRPDuyhwp10EN3JeO+9MS85
 Vf9YveGiYWuGhkZtYrTy8qFMLoHOaTum5HVONNor0KIlUpeC5Epc7G2jO0P/Nmfx
 roK5zlcKzTGFyVZKDuur
 =Uq4l
 -----END PGP SIGNATURE-----

Merge tag 'mvebu-soc-3.17' of git://git.infradead.org/linux-mvebu into next/soc

Merge "mvebu SoC changes for v3.17" from Jason Cooper:

- kirkwood
  * add setup file for netxbig LEDs (non-trivial DT binding doesn't exist yet)

- mvebu
  * staticize where needed
  * add CPU hotplug for Armada XP
  * add public datasheet for Armada 370
  * don't apply thermal quirk by default
  * get SoC ID from the system controller when possible

* tag 'mvebu-soc-3.17' of git://git.infradead.org/linux-mvebu:
  ARM: mvebu: Staticize mvebu_cpu_reset_init
  ARM: mvebu: Staticize armada_370_xp_cpu_pm_init
  ARM: mvebu: Staticize armada_375_smp_cpu1_enable_wa
  ARM: mvebu: Use system controller to get the soc id when possible
  ARM: mvebu: Use the a standard errno in mvebu_get_soc_id
  ARM: mvebu: Don't apply the thermal quirk if the SoC revision is unknown
  Documentation: arm: add URLs to public datasheets for the Marvell Armada 370 SoC
  ARM: mvebu: implement CPU hotplug support for Armada XP
  ARM: mvebu: export PMSU idle enter/exit functions
  ARM: mvebu: slightly refactor/rename PMSU idle related functions
  ARM: mvebu: remove stub implementation of CPU hotplug on Armada 375/38x
  ARM: Kirkwood: Add setup file for netxbig LEDs
  ARM: mvebu: mark armada_370_xp_pmsu_idle_prepare() as static

Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Olof Johansson 2014-07-07 22:27:00 -07:00
commit b3c20e9832
16 changed files with 319 additions and 55 deletions

View File

@ -83,7 +83,9 @@ EBU Armada family
88F6710
88F6707
88F6W11
Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf
Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf
Hardware Spec: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-datasheet.pdf
Functional Spec: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-FunctionalSpec-datasheet.pdf
Armada 375 Flavors:
88F6720

View File

@ -96,4 +96,11 @@ config MACH_KIRKWOOD
Say 'Y' here if you want your kernel to support boards based
on the Marvell Kirkwood device tree.
config MACH_NETXBIG
bool "LaCie 2Big and 5Big Network v2"
depends on MACH_KIRKWOOD
help
Say 'Y' here if you want your kernel to support the
LaCie 2Big and 5Big Network v2
endif

View File

@ -9,8 +9,8 @@ obj-y += system-controller.o mvebu-soc-id.o
ifeq ($(CONFIG_MACH_MVEBU_V7),y)
obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
endif
obj-$(CONFIG_MACH_DOVE) += dove.o
obj-$(CONFIG_MACH_KIRKWOOD) += kirkwood.o kirkwood-pm.o
obj-$(CONFIG_MACH_NETXBIG) += netxbig.o

View File

@ -24,4 +24,7 @@ void armada_xp_secondary_startup(void);
extern struct smp_operations armada_xp_smp_ops;
#endif
int armada_370_xp_pmsu_idle_enter(unsigned long deepidle);
void armada_370_xp_pmsu_idle_exit(void);
#endif /* __MACH_ARMADA_370_XP_H */

View File

@ -118,8 +118,16 @@ static void __init thermal_quirk(void)
{
struct device_node *np;
u32 dev, rev;
int res;
if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > ARMADA_375_Z1_REV)
/*
* The early SoC Z1 revision needs a quirk to be applied in order
* for the thermal controller to work properly. This quirk breaks
* the thermal support if applied on a SoC that doesn't need it,
* so we enforce the SoC revision to be known.
*/
res = mvebu_get_soc_id(&dev, &rev);
if (res < 0 || (res == 0 && rev > ARMADA_375_Z1_REV))
return;
for_each_compatible_node(np, NULL, "marvell,armada375-thermal") {
@ -153,7 +161,8 @@ static void __init thermal_quirk(void)
/*
* The thermal controller needs some quirk too, so let's change
* the compatible string to reflect this.
* the compatible string to reflect this and allow the driver
* the take the necessary action.
*/
prop = kzalloc(sizeof(*prop), GFP_KERNEL);
prop->name = kstrdup("compatible", GFP_KERNEL);

View File

@ -13,4 +13,9 @@
#ifndef __ARCH_MVEBU_BOARD_H
#define __ARCH_MVEBU_BOARD_H
#ifdef CONFIG_MACH_NETXBIG
void netxbig_init(void);
#else
static inline void netxbig_init(void) {};
#endif
#endif

View File

@ -21,7 +21,6 @@ void mvebu_restart(enum reboot_mode mode, const char *cmd);
int mvebu_cpu_reset_deassert(int cpu);
void mvebu_pmsu_set_cpu_boot_addr(int hw_cpu, void *boot_addr);
void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr);
void armada_xp_cpu_die(unsigned int cpu);
int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev);
#endif

View File

@ -67,7 +67,7 @@ static int mvebu_cpu_reset_map(struct device_node *np, int res_idx)
return 0;
}
int __init mvebu_cpu_reset_init(void)
static int __init mvebu_cpu_reset_init(void)
{
struct device_node *np;
int res_idx;

View File

@ -1,31 +0,0 @@
/*
* Symmetric Multi Processing (SMP) support for Armada XP
*
* Copyright (C) 2012 Marvell
*
* Lior Amsalem <alior@marvell.com>
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* 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.
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
#include <asm/proc-fns.h>
#include "common.h"
/*
* platform-specific code to shutdown a CPU
*
* Called with IRQs disabled
*/
void __ref armada_xp_cpu_die(unsigned int cpu)
{
cpu_do_idle();
/* We should never return from idle */
panic("mvebu: cpu %d unexpectedly exit from shutdown\n", cpu);
}

View File

@ -180,6 +180,9 @@ static void __init kirkwood_dt_init(void)
kirkwood_pm_init();
kirkwood_dt_eth_fixup();
if (of_machine_is_compatible("lacie,netxbig"))
netxbig_init();
of_platform_populate(NULL, of_default_bus_match_table, auxdata, NULL);
}

View File

@ -25,6 +25,7 @@
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/sys_soc.h>
#include "common.h"
#include "mvebu-soc-id.h"
#define PCIE_DEV_ID_OFF 0x0
@ -51,10 +52,10 @@ int mvebu_get_soc_id(u32 *dev, u32 *rev)
*rev = soc_rev;
return 0;
} else
return -1;
return -ENODEV;
}
static int __init mvebu_soc_id_init(void)
static int __init get_soc_id_by_pci(void)
{
struct device_node *np;
int ret = 0;
@ -129,6 +130,22 @@ static int __init mvebu_soc_id_init(void)
return ret;
}
static int __init mvebu_soc_id_init(void)
{
/*
* First try to get the ID and the revision by the system
* register and use PCI registers only if it is not possible
*/
if (!mvebu_system_controller_get_soc_id(&soc_dev_id, &soc_rev)) {
is_id_valid = true;
pr_info("MVEBU SoC ID=0x%X, Rev=0x%X\n", soc_dev_id, soc_rev);
return 0;
}
return get_soc_id_by_pci();
}
early_initcall(mvebu_soc_id_init);
static int __init mvebu_soc_device(void)

View File

@ -0,0 +1,191 @@
/*
* arch/arm/mach-mvbu/board-netxbig.c
*
* LaCie 2Big and 5Big Network v2 board setup
*
* Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/platform_data/leds-kirkwood-netxbig.h>
#include "common.h"
/*****************************************************************************
* GPIO extension LEDs
****************************************************************************/
/*
* The LEDs are controlled by a CPLD and can be configured through a GPIO
* extension bus:
*
* - address register : bit [0-2] -> GPIO [47-49]
* - data register : bit [0-2] -> GPIO [44-46]
* - enable register : GPIO 29
*/
static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 };
static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 };
static struct netxbig_gpio_ext netxbig_v2_gpio_ext = {
.addr = netxbig_v2_gpio_ext_addr,
.num_addr = ARRAY_SIZE(netxbig_v2_gpio_ext_addr),
.data = netxbig_v2_gpio_ext_data,
.num_data = ARRAY_SIZE(netxbig_v2_gpio_ext_data),
.enable = 29,
};
/*
* Address register selection:
*
* addr | register
* ----------------------------
* 0 | front LED
* 1 | front LED brightness
* 2 | SATA LED brightness
* 3 | SATA0 LED
* 4 | SATA1 LED
* 5 | SATA2 LED
* 6 | SATA3 LED
* 7 | SATA4 LED
*
* Data register configuration:
*
* data | LED brightness
* -------------------------------------------------
* 0 | min (off)
* - | -
* 7 | max
*
* data | front LED mode
* -------------------------------------------------
* 0 | fix off
* 1 | fix blue on
* 2 | fix red on
* 3 | blink blue on=1 sec and blue off=1 sec
* 4 | blink red on=1 sec and red off=1 sec
* 5 | blink blue on=2.5 sec and red on=0.5 sec
* 6 | blink blue on=1 sec and red on=1 sec
* 7 | blink blue on=0.5 sec and blue off=2.5 sec
*
* data | SATA LED mode
* -------------------------------------------------
* 0 | fix off
* 1 | SATA activity blink
* 2 | fix red on
* 3 | blink blue on=1 sec and blue off=1 sec
* 4 | blink red on=1 sec and red off=1 sec
* 5 | blink blue on=2.5 sec and red on=0.5 sec
* 6 | blink blue on=1 sec and red on=1 sec
* 7 | fix blue on
*/
static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = {
[NETXBIG_LED_OFF] = 0,
[NETXBIG_LED_ON] = 2,
[NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
[NETXBIG_LED_TIMER1] = 4,
[NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
};
static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = {
[NETXBIG_LED_OFF] = 0,
[NETXBIG_LED_ON] = 1,
[NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
[NETXBIG_LED_TIMER1] = 3,
[NETXBIG_LED_TIMER2] = 7,
};
static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = {
[NETXBIG_LED_OFF] = 0,
[NETXBIG_LED_ON] = 7,
[NETXBIG_LED_SATA] = 1,
[NETXBIG_LED_TIMER1] = 3,
[NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
};
static struct netxbig_led_timer netxbig_v2_led_timer[] = {
[0] = {
.delay_on = 500,
.delay_off = 500,
.mode = NETXBIG_LED_TIMER1,
},
[1] = {
.delay_on = 500,
.delay_off = 1000,
.mode = NETXBIG_LED_TIMER2,
},
};
#define NETXBIG_LED(_name, maddr, mval, baddr) \
{ .name = _name, \
.mode_addr = maddr, \
.mode_val = mval, \
.bright_addr = baddr }
static struct netxbig_led net2big_v2_leds_ctrl[] = {
NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
NETXBIG_LED("net2big-v2:red:power", 0, netxbig_v2_red_mled, 1),
NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
NETXBIG_LED("net2big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
NETXBIG_LED("net2big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
};
static struct netxbig_led_platform_data net2big_v2_leds_data = {
.gpio_ext = &netxbig_v2_gpio_ext,
.timer = netxbig_v2_led_timer,
.num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
.leds = net2big_v2_leds_ctrl,
.num_leds = ARRAY_SIZE(net2big_v2_leds_ctrl),
};
static struct netxbig_led net5big_v2_leds_ctrl[] = {
NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
NETXBIG_LED("net5big-v2:red:power", 0, netxbig_v2_red_mled, 1),
NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
NETXBIG_LED("net5big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
NETXBIG_LED("net5big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2),
NETXBIG_LED("net5big-v2:red:sata2", 5, netxbig_v2_red_mled, 2),
NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2),
NETXBIG_LED("net5big-v2:red:sata3", 6, netxbig_v2_red_mled, 2),
NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2),
NETXBIG_LED("net5big-v2:red:sata4", 7, netxbig_v2_red_mled, 2),
};
static struct netxbig_led_platform_data net5big_v2_leds_data = {
.gpio_ext = &netxbig_v2_gpio_ext,
.timer = netxbig_v2_led_timer,
.num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
.leds = net5big_v2_leds_ctrl,
.num_leds = ARRAY_SIZE(net5big_v2_leds_ctrl),
};
static struct platform_device netxbig_v2_leds = {
.name = "leds-netxbig",
.id = -1,
.dev = {
.platform_data = &net2big_v2_leds_data,
},
};
void __init netxbig_init(void)
{
if (of_machine_is_compatible("lacie,net5big_v2"))
netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data;
platform_device_register(&netxbig_v2_leds);
}

View File

@ -33,7 +33,7 @@
extern unsigned char armada_375_smp_cpu1_enable_code_end;
extern unsigned char armada_375_smp_cpu1_enable_code_start;
void armada_375_smp_cpu1_enable_wa(void)
static void armada_375_smp_cpu1_enable_wa(void)
{
void __iomem *sram_virt_base;
@ -91,9 +91,6 @@ static int __cpuinit mvebu_cortex_a9_boot_secondary(unsigned int cpu,
static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = {
.smp_boot_secondary = mvebu_cortex_a9_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = armada_xp_cpu_die,
#endif
};
CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp",

View File

@ -78,6 +78,17 @@ static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
hw_cpu = cpu_logical_map(cpu);
mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup);
/*
* This is needed to wake up CPUs in the offline state after
* using CPU hotplug.
*/
arch_send_wakeup_ipi_mask(cpumask_of(cpu));
/*
* This is needed to take secondary CPUs out of reset on the
* initial boot.
*/
ret = mvebu_cpu_reset_deassert(hw_cpu);
if (ret) {
pr_warn("unable to boot CPU: %d\n", ret);
@ -87,6 +98,19 @@ static int armada_xp_boot_secondary(unsigned int cpu, struct task_struct *idle)
return 0;
}
/*
* When a CPU is brought back online, either through CPU hotplug, or
* because of the boot of a kexec'ed kernel, the PMSU configuration
* for this CPU might be in the deep idle state, preventing this CPU
* from receiving interrupts. Here, we therefore take out the current
* CPU from this state, which was entered by armada_xp_cpu_die()
* below.
*/
static void armada_xp_secondary_init(unsigned int cpu)
{
armada_370_xp_pmsu_idle_exit();
}
static void __init armada_xp_smp_init_cpus(void)
{
unsigned int ncores = num_possible_cpus();
@ -122,12 +146,36 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
panic("The address for the BootROM is incorrect");
}
#ifdef CONFIG_HOTPLUG_CPU
static void armada_xp_cpu_die(unsigned int cpu)
{
/*
* CPU hotplug is implemented by putting offline CPUs into the
* deep idle sleep state.
*/
armada_370_xp_pmsu_idle_enter(true);
}
/*
* We need a dummy function, so that platform_can_cpu_hotplug() knows
* we support CPU hotplug. However, the function does not need to do
* anything, because CPUs going offline can enter the deep idle state
* by themselves, without any help from a still alive CPU.
*/
static int armada_xp_cpu_kill(unsigned int cpu)
{
return 1;
}
#endif
struct smp_operations armada_xp_smp_ops __initdata = {
.smp_init_cpus = armada_xp_smp_init_cpus,
.smp_prepare_cpus = armada_xp_smp_prepare_cpus,
.smp_boot_secondary = armada_xp_boot_secondary,
.smp_secondary_init = armada_xp_secondary_init,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = armada_xp_cpu_die,
.cpu_kill = armada_xp_cpu_kill,
#endif
};

View File

@ -148,13 +148,13 @@ static void armada_370_xp_cpu_resume(void)
}
/* No locking is needed because we only access per-CPU registers */
void armada_370_xp_pmsu_idle_prepare(bool deepidle)
int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
{
unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
u32 reg;
if (pmsu_mp_base == NULL)
return;
return -EINVAL;
/*
* Adjust the PMSU configuration to wait for WFI signal, enable
@ -183,11 +183,6 @@ void armada_370_xp_pmsu_idle_prepare(bool deepidle)
reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP;
writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
}
static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
{
armada_370_xp_pmsu_idle_prepare(deepidle);
v7_exit_coherency_flush(all);
@ -220,11 +215,11 @@ static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
static int armada_370_xp_cpu_suspend(unsigned long deepidle)
{
return cpu_suspend(deepidle, do_armada_370_xp_cpu_suspend);
return cpu_suspend(deepidle, armada_370_xp_pmsu_idle_enter);
}
/* No locking is needed because we only access per-CPU registers */
static noinline void armada_370_xp_pmsu_idle_restore(void)
void armada_370_xp_pmsu_idle_exit(void)
{
unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
u32 reg;
@ -253,7 +248,7 @@ static int armada_370_xp_cpu_pm_notify(struct notifier_block *self,
unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
} else if (action == CPU_PM_EXIT) {
armada_370_xp_pmsu_idle_restore();
armada_370_xp_pmsu_idle_exit();
}
return NOTIFY_OK;
@ -263,7 +258,7 @@ static struct notifier_block armada_370_xp_cpu_pm_notifier = {
.notifier_call = armada_370_xp_cpu_pm_notify,
};
int __init armada_370_xp_cpu_pm_init(void)
static int __init armada_370_xp_cpu_pm_init(void)
{
struct device_node *np;

View File

@ -39,6 +39,9 @@ struct mvebu_system_controller {
u32 system_soft_reset;
u32 resume_boot_addr;
u32 dev_id;
u32 rev_id;
};
static struct mvebu_system_controller *mvebu_sc;
@ -47,6 +50,8 @@ static const struct mvebu_system_controller armada_370_xp_system_controller = {
.system_soft_reset_offset = 0x64,
.rstoutn_mask_reset_out_en = 0x1,
.system_soft_reset = 0x1,
.dev_id = 0x38,
.rev_id = 0x3c,
};
static const struct mvebu_system_controller armada_375_system_controller = {
@ -55,6 +60,8 @@ static const struct mvebu_system_controller armada_375_system_controller = {
.rstoutn_mask_reset_out_en = 0x1,
.system_soft_reset = 0x1,
.resume_boot_addr = 0xd4,
.dev_id = 0x38,
.rev_id = 0x3c,
};
static const struct mvebu_system_controller orion_system_controller = {
@ -101,6 +108,18 @@ void mvebu_restart(enum reboot_mode mode, const char *cmd)
;
}
int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev)
{
if (of_machine_is_compatible("marvell,armada380") &&
system_controller_base) {
*dev = readl(system_controller_base + mvebu_sc->dev_id) >> 16;
*rev = (readl(system_controller_base + mvebu_sc->rev_id) >> 8)
& 0xF;
return 0;
} else
return -ENODEV;
}
#ifdef CONFIG_SMP
void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr)
{