1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-11-28 03:47:31 +02:00

[cns3xxx]: make smp code more similar to upstream

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27525 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
kaloz 2011-07-07 17:17:06 +00:00
parent af0b474c6e
commit f03e9c5d7f

View File

@ -9,14 +9,13 @@
+obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o +obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
--- /dev/null --- /dev/null
+++ b/arch/arm/mach-cns3xxx/headsmp.S +++ b/arch/arm/mach-cns3xxx/headsmp.S
@@ -0,0 +1,43 @@ @@ -0,0 +1,42 @@
+/* +/*
+ * linux/arch/arm/mach-cns3xxx/headsmp.S + * linux/arch/arm/mach-cns3xxx/headsmp.S
+ * + *
+ * Copyright (c) 2003 ARM Limited + * Cloned from linux/arch/arm/plat-versatile/headsmp.S
+ * Copyright 2011 Gateworks Corporation
+ * Chris Lang <clang@gateworks.com
+ * + *
+ * Copyright (c) 2003 ARM Limited
+ * All Rights Reserved + * All Rights Reserved
+ * + *
+ * This program is free software; you can redistribute it and/or modify + * This program is free software; you can redistribute it and/or modify
@ -29,9 +28,9 @@
+ __INIT + __INIT
+ +
+/* +/*
+ * CNS3XXX specific entry point for secondary CPUs. This + * CNS3XXX specific entry point for secondary CPUs. This provides
+ * provides a "holding pen" into which all secondary cores are held + * a "holding pen" into which all secondary cores are held until we're
+ * until we're ready for them to initialise. + * ready for them to initialise.
+ */ + */
+ENTRY(cns3xxx_secondary_startup) +ENTRY(cns3xxx_secondary_startup)
+ mrc p15, 0, r0, c0, c0, 5 + mrc p15, 0, r0, c0, c0, 5
@ -55,20 +54,19 @@
+ .long pen_release + .long pen_release
--- /dev/null --- /dev/null
+++ b/arch/arm/mach-cns3xxx/hotplug.c +++ b/arch/arm/mach-cns3xxx/hotplug.c
@@ -0,0 +1,131 @@ @@ -0,0 +1,130 @@
+/* +/* linux arch/arm/mach-cns3xxx/hotplug.c
+ * linux/arch/arm/mach-cns3xxx/hotplug.c + *
+ * Cloned from linux/arch/arm/mach-realview/hotplug.c
+ * + *
+ * Copyright (C) 2002 ARM Ltd. + * Copyright (C) 2002 ARM Ltd.
+ * Copyright 2011 Gateworks Corporation
+ * Chris Lang <clang@gateworks.com>
+ *
+ * All Rights Reserved + * All Rights Reserved
+ * + *
+ * This program is free software; you can redistribute it and/or modify + * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as + * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation. + * published by the Free Software Foundation.
+*/ +*/
+
+#include <linux/kernel.h> +#include <linux/kernel.h>
+#include <linux/errno.h> +#include <linux/errno.h>
+#include <linux/smp.h> +#include <linux/smp.h>
@ -189,52 +187,50 @@
+} +}
--- /dev/null --- /dev/null
+++ b/arch/arm/mach-cns3xxx/localtimer.c +++ b/arch/arm/mach-cns3xxx/localtimer.c
@@ -0,0 +1,29 @@ @@ -0,0 +1,26 @@
+/* +/* linux/arch/arm/mach-cns3xxx/localtimer.c
+ * linux/arch/arm/mach-cns3xxx/localtimer.c + *
+ * Cloned from linux/arch/arm/mach-realview/localtimer.c
+ * + *
+ * Copyright (C) 2002 ARM Ltd. + * Copyright (C) 2002 ARM Ltd.
+ * Copyright 2011 Gateworks Corporation
+ * Chris Lang <clang@gateworks.com>
+ *
+ * All Rights Reserved + * All Rights Reserved
+ * + *
+ * This program is free software; you can redistribute it and/or modify + * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as + * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation. + * published by the Free Software Foundation.
+*/ +*/
+#include <linux/init.h> +
+#include <linux/smp.h>
+#include <linux/clockchips.h> +#include <linux/clockchips.h>
+ +
+#include <asm/smp_twd.h> +#include <asm/irq.h>
+#include <asm/localtimer.h> +#include <asm/localtimer.h>
+#include <mach/irqs.h>
+ +
+/* +/*
+ * Setup the local clock events for a CPU. + * Setup the local clock events for a CPU.
+ */ + */
+void __cpuinit local_timer_setup(struct clock_event_device *evt) +int __cpuinit local_timer_setup(struct clock_event_device *evt)
+{ +{
+ evt->irq = IRQ_LOCALTIMER; + evt->irq = IRQ_LOCALTIMER;
+ twd_timer_setup(evt); + twd_timer_setup(evt);
+ return 0;
+} +}
--- /dev/null --- /dev/null
+++ b/arch/arm/mach-cns3xxx/platsmp.c +++ b/arch/arm/mach-cns3xxx/platsmp.c
@@ -0,0 +1,168 @@ @@ -0,0 +1,175 @@
+/* +/* linux/arch/arm/mach-cns3xxx/platsmp.c
+ * linux/arch/arm/mach-cns3xxx/platsmp.c
+ * + *
+ * Copyright (C) 2002 ARM Ltd.
+ * Copyright 2011 Gateworks Corporation + * Copyright 2011 Gateworks Corporation
+ * Chris Lang <clang@gateworks.com> + * Chris Lang <clang@gateworks.com>
+ * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
+ * + *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved + * All Rights Reserved
+ * + *
+ * This program is free software; you can redistribute it and/or modify + * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as + * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation. + * published by the Free Software Foundation.
+*/ +*/
+
+#include <linux/init.h> +#include <linux/init.h>
+#include <linux/errno.h> +#include <linux/errno.h>
+#include <linux/delay.h> +#include <linux/delay.h>
@ -244,19 +240,20 @@
+#include <linux/io.h> +#include <linux/io.h>
+ +
+#include <asm/cacheflush.h> +#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <asm/smp_scu.h> +#include <asm/smp_scu.h>
+#include <asm/unified.h> +#include <asm/unified.h>
+
+#include <mach/hardware.h> +#include <mach/hardware.h>
+#include <mach/cns3xxx.h> +#include <mach/cns3xxx.h>
+ +
+#include "core.h"
+
+extern void cns3xxx_secondary_startup(void); +extern void cns3xxx_secondary_startup(void);
+ +
+/* +/*
+ * control for which core is the next to come out of the secondary + * control for which core is the next to come out of the secondary
+ * boot "holding pen" + * boot "holding pen"
+ */ + */
+
+volatile int __cpuinitdata pen_release = -1; +volatile int __cpuinitdata pen_release = -1;
+ +
+/* +/*
@ -264,7 +261,7 @@
+ * observers, irrespective of whether they're taking part in coherency + * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably. + * or not. This is necessary for the hotplug code to work reliably.
+ */ + */
+static void __cpuinit write_pen_release(int val) +static void write_pen_release(int val)
+{ +{
+ pen_release = val; + pen_release = val;
+ smp_wmb(); + smp_wmb();
@ -312,10 +309,12 @@
+ spin_lock(&boot_lock); + spin_lock(&boot_lock);
+ +
+ /* + /*
+ * This is really belt and braces; we hold unintended secondary + * The secondary processor is waiting to be released from
+ * CPUs in the holding pen until we're ready for them. However, + * the holding pen - release it, then wait for it to flag
+ * since we haven't sent them a soft interrupt, they shouldn't + * that it has been released by resetting pen_release.
+ * be there. + *
+ * Note that "pen_release" is the hardware CPU ID, whereas
+ * "cpu" is Linux's internal ID.
+ */ + */
+ write_pen_release(cpu); + write_pen_release(cpu);
+ +
@ -324,7 +323,7 @@
+ * the boot monitor to read the system wide flags register, + * the boot monitor to read the system wide flags register,
+ * and branch to the address found there. + * and branch to the address found there.
+ */ + */
+ smp_cross_call(cpumask_of(cpu), 1); + gic_raise_softirq(cpumask_of(cpu), 1);
+ +
+ timeout = jiffies + (1 * HZ); + timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) { + while (time_before(jiffies, timeout)) {
@ -348,6 +347,7 @@
+ * Initialise the CPU possible map early - this describes the CPUs + * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system. + * which may be present or become present in the system.
+ */ + */
+
+void __init smp_init_cpus(void) +void __init smp_init_cpus(void)
+{ +{
+ void __iomem *scu_base = scu_base_addr(); + void __iomem *scu_base = scu_base_addr();
@ -366,6 +366,8 @@
+ +
+ for (i = 0; i < ncores; i++) + for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true); + set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+} +}
+ +
+void __init platform_smp_prepare_cpus(unsigned int max_cpus) +void __init platform_smp_prepare_cpus(unsigned int max_cpus)
@ -388,27 +390,11 @@
+ * secondary CPU branches to this address. + * secondary CPU branches to this address.
+ */ + */
+ __raw_writel(virt_to_phys(cns3xxx_secondary_startup), + __raw_writel(virt_to_phys(cns3xxx_secondary_startup),
+ (void __iomem *)(0xFFF07000 + 0x0600)); + (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0600));
+} +}
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/smp.h
@@ -0,0 +1,13 @@
+#ifndef __MACH_SMP_H
+#define __MACH_SMP_H
+
+#include <asm/hardware/gic.h>
+
+/*
+ * We use IRQ1 as the IPI
+ */
+static inline void smp_cross_call(const struct cpumask *mask, int ipi)
+{
+ gic_raise_softirq(mask, ipi);
+}
+#endif
--- a/arch/arm/Kconfig --- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig +++ b/arch/arm/Kconfig
@@ -1311,7 +1311,7 @@ config SMP @@ -1312,7 +1312,7 @@ config SMP
depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \ ARCH_EXYNOS4 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \