Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: aspeed: Enable SMP boot

This brings the secondary CPU into Linux. It depends on the setup
performed by ASPEED's u-boot.

Signed-off-by: Joel Stanley <joel@jms.id.au>

+67
+1
arch/arm/Makefile
··· 155 155 machine-$(CONFIG_ARCH_ACTIONS) += actions 156 156 machine-$(CONFIG_ARCH_ALPINE) += alpine 157 157 machine-$(CONFIG_ARCH_ARTPEC) += artpec 158 + machine-$(CONFIG_ARCH_ASPEED) += aspeed 158 159 machine-$(CONFIG_ARCH_AT91) += at91 159 160 machine-$(CONFIG_ARCH_AXXIA) += axxia 160 161 machine-$(CONFIG_ARCH_BCM) += bcm
+5
arch/arm/mach-aspeed/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-or-later 2 + # Copyright (C) ASPEED Technology Inc. 3 + # Copyright IBM Corp. 4 + 5 + obj-$(CONFIG_SMP) += platsmp.o
+61
arch/arm/mach-aspeed/platsmp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + // Copyright (C) ASPEED Technology Inc. 3 + // Copyright IBM Corp. 4 + 5 + #include <linux/of_address.h> 6 + #include <linux/io.h> 7 + #include <linux/of.h> 8 + #include <linux/smp.h> 9 + 10 + #define BOOT_ADDR 0x00 11 + #define BOOT_SIG 0x04 12 + 13 + static struct device_node *secboot_node; 14 + 15 + static int aspeed_g6_boot_secondary(unsigned int cpu, struct task_struct *idle) 16 + { 17 + void __iomem *base; 18 + 19 + base = of_iomap(secboot_node, 0); 20 + if (!base) { 21 + pr_err("could not map the secondary boot base!"); 22 + return -ENODEV; 23 + } 24 + 25 + writel_relaxed(0, base + BOOT_ADDR); 26 + writel_relaxed(__pa_symbol(secondary_startup_arm), base + BOOT_ADDR); 27 + writel_relaxed((0xABBAAB00 | (cpu & 0xff)), base + BOOT_SIG); 28 + 29 + dsb_sev(); 30 + 31 + iounmap(base); 32 + 33 + return 0; 34 + } 35 + 36 + static void __init aspeed_g6_smp_prepare_cpus(unsigned int max_cpus) 37 + { 38 + void __iomem *base; 39 + 40 + secboot_node = of_find_compatible_node(NULL, NULL, "aspeed,ast2600-smpmem"); 41 + if (!secboot_node) { 42 + pr_err("secboot device node found!!\n"); 43 + return; 44 + } 45 + 46 + base = of_iomap(secboot_node, 0); 47 + if (!base) { 48 + pr_err("could not map the secondary boot base!"); 49 + return; 50 + } 51 + __raw_writel(0xBADABABA, base + BOOT_SIG); 52 + 53 + iounmap(base); 54 + } 55 + 56 + static const struct smp_operations aspeed_smp_ops __initconst = { 57 + .smp_prepare_cpus = aspeed_g6_smp_prepare_cpus, 58 + .smp_boot_secondary = aspeed_g6_boot_secondary, 59 + }; 60 + 61 + CPU_METHOD_OF_DECLARE(aspeed_smp, "aspeed,ast2600-smp", &aspeed_smp_ops);