Marvell Berlin SoC for 4.4 take 2

- use the non-self-clearing reset register
 - add cpu hotplug support
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJWH/wBAAoJEN2kpao7fSL4VrAQAJrMtI4jZI5hECFLsAWTldEu
 cFJ41zouS88Kxa042S9Mr6A6TV5WXWRdg3lb95+n71OQ9pEVc428X3Sc0FdHlbSH
 g5/W/y6Vic6KXBShTLpF9O7rMZgEFOZoLMeUMm4hlUu5NL+6ghVkEyNQioBvRgyC
 uIo97JBho0EsXXY0uZWHB+6DpPpcHKN54HZCm5nhNSBEpR/PgxXDxnqbcdQHKVCO
 +2bpNE8V/Lvt0MxiGHm36Hrabi0gcsUAXQEdVk6BWHM5nrvqCiBNq9xzHhb8VSg+
 R/i1wprXVi1Ecbm3DdVtNEqam3x+roo/tfc0zuqDoQ8A1zreP1SZVFvs2Je4Vlek
 yYbD1MuVqRQ4a9fqlTb2PzuKuCMubke3sq6Y3ZkDAXe8ToIASOT6mg8bKY8B4bgE
 GZwskH7tMofLwC8obux8hjIormAWMK+rsxdJ4HHFb2IfgJtofqhSrKgqRPnsjgmM
 OpJtayQOxL088/a2aY/JC3SQJdfMAPDdltuebXYDBVLL2AdgSpimjZx6fHJ1oxr8
 2N72NH59UOI8QGfukSC5iQjZ6eNaKRJ0T8/0QKorpdDtCk540welfXbPSNvWuF9N
 XgewsnsKtQIV6hfYtRbdGEk6VQ1HOh+1CTZ9sl2hjBuwqFS7SWCvAAdrSHsIbXll
 ARaG+v7CHIgFKqxpN54i
 =khG4
 -----END PGP SIGNATURE-----

Merge tag 'berlin-soc-for-4.4-2' of git://git.infradead.org/users/hesselba/linux-berlin into next/soc

Merge "Marvell Berlin SoC for 4.4 take 2" from Sebastian Hesselbarth:

- use the non-self-clearing reset register
- add cpu hotplug support

* tag 'berlin-soc-for-4.4-2' of git://git.infradead.org/users/hesselba/linux-berlin:
  arm: berlin: add CPU hotplug support
  arm: berlin: use non-self-cleared reset register to reset cpu
This commit is contained in:
Arnd Bergmann 2015-10-15 22:55:53 +02:00
commit 5462b10af1
1 changed files with 35 additions and 3 deletions

View File

@ -14,10 +14,16 @@
#include <linux/of_address.h>
#include <asm/cacheflush.h>
#include <asm/cp15.h>
#include <asm/smp_plat.h>
#include <asm/smp_scu.h>
#define CPU_RESET 0x00
/*
* There are two reset registers, one with self-clearing (SC)
* reset and one with non-self-clearing reset (NON_SC).
*/
#define CPU_RESET_SC 0x00
#define CPU_RESET_NON_SC 0x20
#define RESET_VECT 0x00
#define SW_RESET_ADDR 0x94
@ -30,9 +36,11 @@ static inline void berlin_perform_reset_cpu(unsigned int cpu)
{
u32 val;
val = readl(cpu_ctrl + CPU_RESET);
val = readl(cpu_ctrl + CPU_RESET_NON_SC);
val &= ~BIT(cpu_logical_map(cpu));
writel(val, cpu_ctrl + CPU_RESET_NON_SC);
val |= BIT(cpu_logical_map(cpu));
writel(val, cpu_ctrl + CPU_RESET);
writel(val, cpu_ctrl + CPU_RESET_NON_SC);
}
static int berlin_boot_secondary(unsigned int cpu, struct task_struct *idle)
@ -91,8 +99,32 @@ unmap_scu:
iounmap(scu_base);
}
#ifdef CONFIG_HOTPLUG_CPU
static void berlin_cpu_die(unsigned int cpu)
{
v7_exit_coherency_flush(louis);
while (1)
cpu_do_idle();
}
static int berlin_cpu_kill(unsigned int cpu)
{
u32 val;
val = readl(cpu_ctrl + CPU_RESET_NON_SC);
val &= ~BIT(cpu_logical_map(cpu));
writel(val, cpu_ctrl + CPU_RESET_NON_SC);
return 1;
}
#endif
static struct smp_operations berlin_smp_ops __initdata = {
.smp_prepare_cpus = berlin_smp_prepare_cpus,
.smp_boot_secondary = berlin_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = berlin_cpu_die,
.cpu_kill = berlin_cpu_kill,
#endif
};
CPU_METHOD_OF_DECLARE(berlin_smp, "marvell,berlin-smp", &berlin_smp_ops);