162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * SMP operations for Alpine platform. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2015 Annapurna Labs Ltd. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/init.h> 962306a36Sopenharmony_ci#include <linux/errno.h> 1062306a36Sopenharmony_ci#include <linux/io.h> 1162306a36Sopenharmony_ci#include <linux/of.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <asm/smp_plat.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "alpine_cpu_pm.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistatic int alpine_boot_secondary(unsigned int cpu, struct task_struct *idle) 1862306a36Sopenharmony_ci{ 1962306a36Sopenharmony_ci phys_addr_t addr; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci addr = __pa_symbol(secondary_startup); 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci if (addr > (phys_addr_t)(uint32_t)(-1)) { 2462306a36Sopenharmony_ci pr_err("FAIL: resume address over 32bit (%pa)", &addr); 2562306a36Sopenharmony_ci return -EINVAL; 2662306a36Sopenharmony_ci } 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci return alpine_cpu_wakeup(cpu_logical_map(cpu), (uint32_t)addr); 2962306a36Sopenharmony_ci} 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic void __init alpine_smp_prepare_cpus(unsigned int max_cpus) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci alpine_cpu_pm_init(); 3462306a36Sopenharmony_ci} 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic const struct smp_operations alpine_smp_ops __initconst = { 3762306a36Sopenharmony_ci .smp_prepare_cpus = alpine_smp_prepare_cpus, 3862306a36Sopenharmony_ci .smp_boot_secondary = alpine_boot_secondary, 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ciCPU_METHOD_OF_DECLARE(alpine_smp, "al,alpine-smp", &alpine_smp_ops); 41