18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * SMP operations for Alpine platform. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2015 Annapurna Labs Ltd. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/init.h> 98c2ecf20Sopenharmony_ci#include <linux/errno.h> 108c2ecf20Sopenharmony_ci#include <linux/io.h> 118c2ecf20Sopenharmony_ci#include <linux/of.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <asm/smp_plat.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include "alpine_cpu_pm.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistatic int alpine_boot_secondary(unsigned int cpu, struct task_struct *idle) 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci phys_addr_t addr; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci addr = __pa_symbol(secondary_startup); 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci if (addr > (phys_addr_t)(uint32_t)(-1)) { 248c2ecf20Sopenharmony_ci pr_err("FAIL: resume address over 32bit (%pa)", &addr); 258c2ecf20Sopenharmony_ci return -EINVAL; 268c2ecf20Sopenharmony_ci } 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci return alpine_cpu_wakeup(cpu_logical_map(cpu), (uint32_t)addr); 298c2ecf20Sopenharmony_ci} 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistatic void __init alpine_smp_prepare_cpus(unsigned int max_cpus) 328c2ecf20Sopenharmony_ci{ 338c2ecf20Sopenharmony_ci alpine_cpu_pm_init(); 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic const struct smp_operations alpine_smp_ops __initconst = { 378c2ecf20Sopenharmony_ci .smp_prepare_cpus = alpine_smp_prepare_cpus, 388c2ecf20Sopenharmony_ci .smp_boot_secondary = alpine_boot_secondary, 398c2ecf20Sopenharmony_ci}; 408c2ecf20Sopenharmony_ciCPU_METHOD_OF_DECLARE(alpine_smp, "al,alpine-smp", &alpine_smp_ops); 41