Commit 5462b10a authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'berlin-soc-for-4.4-2' of...

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
parents 8207e2ed a7b3d5a7
...@@ -14,10 +14,16 @@ ...@@ -14,10 +14,16 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/cp15.h>
#include <asm/smp_plat.h> #include <asm/smp_plat.h>
#include <asm/smp_scu.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 RESET_VECT 0x00
#define SW_RESET_ADDR 0x94 #define SW_RESET_ADDR 0x94
...@@ -30,9 +36,11 @@ static inline void berlin_perform_reset_cpu(unsigned int cpu) ...@@ -30,9 +36,11 @@ static inline void berlin_perform_reset_cpu(unsigned int cpu)
{ {
u32 val; 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)); 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) static int berlin_boot_secondary(unsigned int cpu, struct task_struct *idle)
...@@ -91,8 +99,32 @@ static void __init berlin_smp_prepare_cpus(unsigned int max_cpus) ...@@ -91,8 +99,32 @@ static void __init berlin_smp_prepare_cpus(unsigned int max_cpus)
iounmap(scu_base); 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 = { static struct smp_operations berlin_smp_ops __initdata = {
.smp_prepare_cpus = berlin_smp_prepare_cpus, .smp_prepare_cpus = berlin_smp_prepare_cpus,
.smp_boot_secondary = berlin_boot_secondary, .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); CPU_METHOD_OF_DECLARE(berlin_smp, "marvell,berlin-smp", &berlin_smp_ops);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment