smp-r8a7779.c (1814B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * SMP support for R-Mobile / SH-Mobile - r8a7779 portion 4 * 5 * Copyright (C) 2011 Renesas Solutions Corp. 6 * Copyright (C) 2011 Magnus Damm 7 */ 8#include <linux/kernel.h> 9#include <linux/init.h> 10#include <linux/smp.h> 11#include <linux/spinlock.h> 12#include <linux/io.h> 13#include <linux/delay.h> 14#include <linux/soc/renesas/rcar-sysc.h> 15 16#include <asm/cacheflush.h> 17#include <asm/smp_plat.h> 18#include <asm/smp_scu.h> 19 20#include "common.h" 21#include "r8a7779.h" 22 23#define HPBREG_BASE 0xfe700000 24#define AVECR 0x0040 /* ARM Reset Vector Address Register */ 25 26#define R8A7779_SCU_BASE 0xf0000000 27 28static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle) 29{ 30 int ret = -EIO; 31 32 cpu = cpu_logical_map(cpu); 33 if (cpu) 34 ret = rcar_sysc_power_up_cpu(cpu); 35 36 return ret; 37} 38 39static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) 40{ 41 void __iomem *base = ioremap(HPBREG_BASE, 0x1000); 42 43 /* Map the reset vector (in headsmp-scu.S, headsmp.S) */ 44 writel(__pa(shmobile_boot_vector), base + AVECR); 45 46 /* setup r8a7779 specific SCU bits */ 47 shmobile_smp_scu_prepare_cpus(R8A7779_SCU_BASE, max_cpus); 48 49 iounmap(base); 50} 51 52#ifdef CONFIG_HOTPLUG_CPU 53static int r8a7779_platform_cpu_kill(unsigned int cpu) 54{ 55 int ret = -EIO; 56 57 cpu = cpu_logical_map(cpu); 58 if (cpu) 59 ret = rcar_sysc_power_down_cpu(cpu); 60 61 return ret ? ret : 1; 62} 63 64static int r8a7779_cpu_kill(unsigned int cpu) 65{ 66 if (shmobile_smp_scu_cpu_kill(cpu)) 67 return r8a7779_platform_cpu_kill(cpu); 68 69 return 0; 70} 71#endif /* CONFIG_HOTPLUG_CPU */ 72 73const struct smp_operations r8a7779_smp_ops __initconst = { 74 .smp_prepare_cpus = r8a7779_smp_prepare_cpus, 75 .smp_boot_secondary = r8a7779_boot_secondary, 76#ifdef CONFIG_HOTPLUG_CPU 77 .cpu_die = shmobile_smp_scu_cpu_die, 78 .cpu_kill = r8a7779_cpu_kill, 79#endif 80};