Merge tag 'arm-soc/for-4.5/soc' of http://github.com/Broadcom/stblinux into next/soc
Merge "Broadcom soc changes for v4.5" from Florian Fainelli: This pull request contains Broadcom SoC changes for 4.5, with the following changes: - Lucas Stach removes the workaround for an imprecise fault for Broadcom BCM5301x SoCs (Northstar) since this is now handled by the ARM/Linux kernel directly - Hauke Merthens enables a bunch of erratas for the Cortex-A9 and PL310 L2 cache present on early Northstar chips (BCM4708) - Kapil Hali adds SMP support for the Northstar Plus SoCs by consolidating the existing SMP code for Kona SoCs (mobile platforms), fixng the Device Tree binding for the Kona platforms (wrong placement for 'enable-method' and 'secondary-reg') and then finally adds the functional code for the Northstar Plus platforms to boot their secondary CPUs - Jon Mason enables SMP on BCM4708/BCM5301X (Northstar SoCs) by building the generic Northstar/Northstar Plus SMP code, and adding the relevant SMP Device Tree nodes * tag 'arm-soc/for-4.5/soc' of http://github.com/Broadcom/stblinux: ARM: BCM: Add SMP support for Broadcom 4708 ARM: BCM: Add SMP support for Broadcom NSP ARM: BCM: Clean up SMP support for Broadcom Kona ARM: BCM5310X: activate erratas needed for SoC ARM: BCM5301X: remove workaround imprecise abort fault handler
This commit is contained in:
commit
75f287180a
|
@ -31,7 +31,6 @@ cpus {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
enable-method = "brcm,bcm11351-cpu-method";
|
enable-method = "brcm,bcm11351-cpu-method";
|
||||||
secondary-boot-reg = <0x3500417c>;
|
|
||||||
|
|
||||||
cpu0: cpu@0 {
|
cpu0: cpu@0 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
|
@ -42,6 +41,7 @@ cpu0: cpu@0 {
|
||||||
cpu1: cpu@1 {
|
cpu1: cpu@1 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
compatible = "arm,cortex-a9";
|
compatible = "arm,cortex-a9";
|
||||||
|
secondary-boot-reg = <0x3500417c>;
|
||||||
reg = <1>;
|
reg = <1>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,7 +31,6 @@ cpus {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
enable-method = "brcm,bcm11351-cpu-method";
|
enable-method = "brcm,bcm11351-cpu-method";
|
||||||
secondary-boot-reg = <0x35004178>;
|
|
||||||
|
|
||||||
cpu0: cpu@0 {
|
cpu0: cpu@0 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
|
@ -42,6 +41,7 @@ cpu0: cpu@0 {
|
||||||
cpu1: cpu@1 {
|
cpu1: cpu@1 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
compatible = "arm,cortex-a9";
|
compatible = "arm,cortex-a9";
|
||||||
|
secondary-boot-reg = <0x35004178>;
|
||||||
reg = <1>;
|
reg = <1>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@ / {
|
||||||
cpus {
|
cpus {
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
enable-method = "brcm,bcm-nsp-smp";
|
||||||
|
|
||||||
cpu@0 {
|
cpu@0 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
|
@ -27,6 +28,7 @@ cpu@1 {
|
||||||
device_type = "cpu";
|
device_type = "cpu";
|
||||||
compatible = "arm,cortex-a9";
|
compatible = "arm,cortex-a9";
|
||||||
next-level-cache = <&L2>;
|
next-level-cache = <&L2>;
|
||||||
|
secondary-boot-reg = <0xffff0400>;
|
||||||
reg = <0x1>;
|
reg = <0x1>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,6 +40,8 @@ config ARCH_BCM_NSP
|
||||||
select ARCH_BCM_IPROC
|
select ARCH_BCM_IPROC
|
||||||
select ARM_ERRATA_754322
|
select ARM_ERRATA_754322
|
||||||
select ARM_ERRATA_775420
|
select ARM_ERRATA_775420
|
||||||
|
select ARM_ERRATA_764369 if SMP
|
||||||
|
select HAVE_SMP
|
||||||
help
|
help
|
||||||
Support for Broadcom Northstar Plus SoC.
|
Support for Broadcom Northstar Plus SoC.
|
||||||
Broadcom Northstar Plus family of SoCs are used for switching control
|
Broadcom Northstar Plus family of SoCs are used for switching control
|
||||||
|
@ -52,6 +54,11 @@ config ARCH_BCM_NSP
|
||||||
config ARCH_BCM_5301X
|
config ARCH_BCM_5301X
|
||||||
bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
|
bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
|
||||||
select ARCH_BCM_IPROC
|
select ARCH_BCM_IPROC
|
||||||
|
select ARM_ERRATA_754322
|
||||||
|
select ARM_ERRATA_775420
|
||||||
|
select ARM_ERRATA_764369 if SMP
|
||||||
|
select HAVE_SMP
|
||||||
|
|
||||||
help
|
help
|
||||||
Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
|
Support for Broadcom BCM470X and BCM5301X SoCs with ARM CPU cores.
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,11 @@
|
||||||
obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o
|
obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o
|
||||||
|
|
||||||
# Northstar Plus
|
# Northstar Plus
|
||||||
obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o
|
obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARCH_BCM_NSP),y)
|
||||||
|
obj-$(CONFIG_SMP) += platsmp.o
|
||||||
|
endif
|
||||||
|
|
||||||
# BCM281XX
|
# BCM281XX
|
||||||
obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
|
obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
|
||||||
|
@ -23,7 +27,7 @@ obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
|
||||||
obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o
|
obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o
|
||||||
|
|
||||||
# BCM281XX and BCM21664 SMP support
|
# BCM281XX and BCM21664 SMP support
|
||||||
obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += kona_smp.o
|
obj-$(CONFIG_ARCH_BCM_MOBILE_SMP) += platsmp.o
|
||||||
|
|
||||||
# BCM281XX and BCM21664 L2 cache control
|
# BCM281XX and BCM21664 L2 cache control
|
||||||
obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o
|
obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o
|
||||||
|
@ -39,6 +43,9 @@ obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o
|
||||||
|
|
||||||
# BCM5301X
|
# BCM5301X
|
||||||
obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
|
obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o
|
||||||
|
ifeq ($(CONFIG_ARCH_BCM_5301X),y)
|
||||||
|
obj-$(CONFIG_SMP) += platsmp.o
|
||||||
|
endif
|
||||||
|
|
||||||
# BCM63XXx
|
# BCM63XXx
|
||||||
ifeq ($(CONFIG_ARCH_BCM_63XX),y)
|
ifeq ($(CONFIG_ARCH_BCM_63XX),y)
|
||||||
|
|
|
@ -9,40 +9,6 @@
|
||||||
#include <asm/hardware/cache-l2x0.h>
|
#include <asm/hardware/cache-l2x0.h>
|
||||||
|
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
#include <asm/siginfo.h>
|
|
||||||
#include <asm/signal.h>
|
|
||||||
|
|
||||||
|
|
||||||
static bool first_fault = true;
|
|
||||||
|
|
||||||
static int bcm5301x_abort_handler(unsigned long addr, unsigned int fsr,
|
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
if ((fsr == 0x1406 || fsr == 0x1c06) && first_fault) {
|
|
||||||
first_fault = false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These faults with codes 0x1406 (BCM4709) or 0x1c06 happens
|
|
||||||
* for no good reason, possibly left over from the CFE boot
|
|
||||||
* loader.
|
|
||||||
*/
|
|
||||||
pr_warn("External imprecise Data abort at addr=%#lx, fsr=%#x ignored.\n",
|
|
||||||
addr, fsr);
|
|
||||||
|
|
||||||
/* Returning non-zero causes fault display and panic */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Others should cause a fault */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __init bcm5301x_init_early(void)
|
|
||||||
{
|
|
||||||
/* Install our hook */
|
|
||||||
hook_fault_code(16 + 6, bcm5301x_abort_handler, SIGBUS, BUS_OBJERR,
|
|
||||||
"imprecise external abort");
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *const bcm5301x_dt_compat[] __initconst = {
|
static const char *const bcm5301x_dt_compat[] __initconst = {
|
||||||
"brcm,bcm4708",
|
"brcm,bcm4708",
|
||||||
|
@ -52,6 +18,5 @@ static const char *const bcm5301x_dt_compat[] __initconst = {
|
||||||
DT_MACHINE_START(BCM5301X, "BCM5301X")
|
DT_MACHINE_START(BCM5301X, "BCM5301X")
|
||||||
.l2c_aux_val = 0,
|
.l2c_aux_val = 0,
|
||||||
.l2c_aux_mask = ~0,
|
.l2c_aux_mask = ~0,
|
||||||
.init_early = bcm5301x_init_early,
|
|
||||||
.dt_compat = bcm5301x_dt_compat,
|
.dt_compat = bcm5301x_dt_compat,
|
||||||
MACHINE_END
|
MACHINE_END
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Broadcom Corporation
|
* Copyright (C) 2014-2015 Broadcom Corporation
|
||||||
* Copyright 2014 Linaro Limited
|
* Copyright 2014 Linaro Limited
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -12,12 +12,17 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/cpumask.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
#include <linux/init.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
#include <linux/jiffies.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#include <linux/smp.h>
|
||||||
|
|
||||||
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
#include <asm/smp_plat.h>
|
#include <asm/smp_plat.h>
|
||||||
#include <asm/smp_scu.h>
|
#include <asm/smp_scu.h>
|
||||||
|
@ -30,9 +35,10 @@
|
||||||
|
|
||||||
/* Name of device node property defining secondary boot register location */
|
/* Name of device node property defining secondary boot register location */
|
||||||
#define OF_SECONDARY_BOOT "secondary-boot-reg"
|
#define OF_SECONDARY_BOOT "secondary-boot-reg"
|
||||||
|
#define MPIDR_CPUID_BITMASK 0x3
|
||||||
|
|
||||||
/* I/O address of register used to coordinate secondary core startup */
|
/* I/O address of register used to coordinate secondary core startup */
|
||||||
static u32 secondary_boot;
|
static u32 secondary_boot_addr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable the Cortex A9 Snoop Control Unit
|
* Enable the Cortex A9 Snoop Control Unit
|
||||||
|
@ -75,47 +81,101 @@ static int __init scu_a9_enable(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nsp_write_lut(void)
|
||||||
|
{
|
||||||
|
void __iomem *sku_rom_lut;
|
||||||
|
phys_addr_t secondary_startup_phy;
|
||||||
|
|
||||||
|
if (!secondary_boot_addr) {
|
||||||
|
pr_warn("required secondary boot register not specified\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr,
|
||||||
|
sizeof(secondary_boot_addr));
|
||||||
|
if (!sku_rom_lut) {
|
||||||
|
pr_warn("unable to ioremap SKU-ROM LUT register\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
secondary_startup_phy = virt_to_phys(secondary_startup);
|
||||||
|
BUG_ON(secondary_startup_phy > (phys_addr_t)U32_MAX);
|
||||||
|
|
||||||
|
writel_relaxed(secondary_startup_phy, sku_rom_lut);
|
||||||
|
|
||||||
|
/* Ensure the write is visible to the secondary core */
|
||||||
|
smp_wmb();
|
||||||
|
|
||||||
|
iounmap(sku_rom_lut);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
|
static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
|
||||||
{
|
{
|
||||||
static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
|
static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
|
||||||
struct device_node *node;
|
struct device_node *cpus_node = NULL;
|
||||||
|
struct device_node *cpu_node = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
BUG_ON(secondary_boot); /* We're called only once */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is only called via smp_ops->smp_prepare_cpu().
|
* This function is only called via smp_ops->smp_prepare_cpu().
|
||||||
* That only happens if a "/cpus" device tree node exists
|
* That only happens if a "/cpus" device tree node exists
|
||||||
* and has an "enable-method" property that selects the SMP
|
* and has an "enable-method" property that selects the SMP
|
||||||
* operations defined herein.
|
* operations defined herein.
|
||||||
*/
|
*/
|
||||||
node = of_find_node_by_path("/cpus");
|
cpus_node = of_find_node_by_path("/cpus");
|
||||||
BUG_ON(!node);
|
if (!cpus_node)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
for_each_child_of_node(cpus_node, cpu_node) {
|
||||||
* Our secondary enable method requires a "secondary-boot-reg"
|
u32 cpuid;
|
||||||
* property to specify a register address used to request the
|
|
||||||
* ROM code boot a secondary code. If we have any trouble
|
if (of_node_cmp(cpu_node->type, "cpu"))
|
||||||
* getting this we fall back to uniprocessor mode.
|
continue;
|
||||||
*/
|
|
||||||
if (of_property_read_u32(node, OF_SECONDARY_BOOT, &secondary_boot)) {
|
if (of_property_read_u32(cpu_node, "reg", &cpuid)) {
|
||||||
pr_err("%s: missing/invalid " OF_SECONDARY_BOOT " property\n",
|
pr_debug("%s: missing reg property\n",
|
||||||
node->name);
|
cpu_node->full_name);
|
||||||
ret = -ENOENT; /* Arrange to disable SMP */
|
ret = -ENOENT;
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "secondary-boot-reg" property should be defined only
|
||||||
|
* for secondary cpu
|
||||||
|
*/
|
||||||
|
if ((cpuid & MPIDR_CPUID_BITMASK) == 1) {
|
||||||
|
/*
|
||||||
|
* Our secondary enable method requires a
|
||||||
|
* "secondary-boot-reg" property to specify a register
|
||||||
|
* address used to request the ROM code boot a secondary
|
||||||
|
* core. If we have any trouble getting this we fall
|
||||||
|
* back to uniprocessor mode.
|
||||||
|
*/
|
||||||
|
if (of_property_read_u32(cpu_node,
|
||||||
|
OF_SECONDARY_BOOT,
|
||||||
|
&secondary_boot_addr)) {
|
||||||
|
pr_warn("%s: no" OF_SECONDARY_BOOT "property\n",
|
||||||
|
cpu_node->name);
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
|
* Enable the SCU on Cortex A9 based SoCs. If -ENOENT is
|
||||||
* returned, the SoC reported a uniprocessor configuration.
|
* returned, the SoC reported a uniprocessor configuration.
|
||||||
* We bail on any other error.
|
* We bail on any other error.
|
||||||
*/
|
*/
|
||||||
ret = scu_a9_enable();
|
ret = scu_a9_enable();
|
||||||
out:
|
out:
|
||||||
of_node_put(node);
|
of_node_put(cpu_node);
|
||||||
|
of_node_put(cpus_node);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/* Update the CPU present map to reflect uniprocessor mode */
|
/* Update the CPU present map to reflect uniprocessor mode */
|
||||||
BUG_ON(ret != -ENOENT);
|
|
||||||
pr_warn("disabling SMP\n");
|
pr_warn("disabling SMP\n");
|
||||||
init_cpu_present(&only_cpu_0);
|
init_cpu_present(&only_cpu_0);
|
||||||
}
|
}
|
||||||
|
@ -139,7 +199,7 @@ static void __init bcm_smp_prepare_cpus(unsigned int max_cpus)
|
||||||
* - Wait for the secondary boot register to be re-written, which
|
* - Wait for the secondary boot register to be re-written, which
|
||||||
* indicates the secondary core has started.
|
* indicates the secondary core has started.
|
||||||
*/
|
*/
|
||||||
static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
{
|
{
|
||||||
void __iomem *boot_reg;
|
void __iomem *boot_reg;
|
||||||
phys_addr_t boot_func;
|
phys_addr_t boot_func;
|
||||||
|
@ -154,15 +214,16 @@ static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!secondary_boot) {
|
if (!secondary_boot_addr) {
|
||||||
pr_err("required secondary boot register not specified\n");
|
pr_err("required secondary boot register not specified\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
boot_reg = ioremap_nocache((phys_addr_t)secondary_boot, sizeof(u32));
|
boot_reg = ioremap_nocache(
|
||||||
|
(phys_addr_t)secondary_boot_addr, sizeof(u32));
|
||||||
if (!boot_reg) {
|
if (!boot_reg) {
|
||||||
pr_err("unable to map boot register for cpu %u\n", cpu_id);
|
pr_err("unable to map boot register for cpu %u\n", cpu_id);
|
||||||
return -ENOSYS;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -191,12 +252,39 @@ static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
|
|
||||||
pr_err("timeout waiting for cpu %u to start\n", cpu_id);
|
pr_err("timeout waiting for cpu %u to start\n", cpu_id);
|
||||||
|
|
||||||
return -ENOSYS;
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* After wake up, secondary core branches to the startup
|
||||||
|
* address programmed at SKU ROM LUT location.
|
||||||
|
*/
|
||||||
|
ret = nsp_write_lut();
|
||||||
|
if (ret) {
|
||||||
|
pr_err("unable to write startup addr to SKU ROM LUT\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send a CPU wakeup interrupt to the secondary core */
|
||||||
|
arch_send_wakeup_ipi_mask(cpumask_of(cpu));
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct smp_operations bcm_smp_ops __initdata = {
|
static struct smp_operations bcm_smp_ops __initdata = {
|
||||||
.smp_prepare_cpus = bcm_smp_prepare_cpus,
|
.smp_prepare_cpus = bcm_smp_prepare_cpus,
|
||||||
.smp_boot_secondary = bcm_boot_secondary,
|
.smp_boot_secondary = kona_boot_secondary,
|
||||||
};
|
};
|
||||||
CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
|
CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method",
|
||||||
&bcm_smp_ops);
|
&bcm_smp_ops);
|
||||||
|
|
||||||
|
struct smp_operations nsp_smp_ops __initdata = {
|
||||||
|
.smp_prepare_cpus = bcm_smp_prepare_cpus,
|
||||||
|
.smp_boot_secondary = nsp_boot_secondary,
|
||||||
|
};
|
||||||
|
CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops);
|
Loading…
Reference in New Issue