~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/mach-spear/platsmp.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * arch/arm/mach-spear13xx/platsmp.c
  4  *
  5  * based upon linux/arch/arm/mach-realview/platsmp.c
  6  *
  7  * Copyright (C) 2012 ST Microelectronics Ltd.
  8  * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
  9  */
 10 
 11 #include <linux/delay.h>
 12 #include <linux/jiffies.h>
 13 #include <linux/io.h>
 14 #include <linux/smp.h>
 15 #include <asm/cacheflush.h>
 16 #include <asm/smp_scu.h>
 17 #include "spear.h"
 18 #include "generic.h"
 19 
 20 /* XXX spear_pen_release is cargo culted code - DO NOT COPY XXX */
 21 volatile int spear_pen_release = -1;
 22 
 23 /*
 24  * XXX CARGO CULTED CODE - DO NOT COPY XXX
 25  *
 26  * Write spear_pen_release in a way that is guaranteed to be visible to
 27  * all observers, irrespective of whether they're taking part in coherency
 28  * or not.  This is necessary for the hotplug code to work reliably.
 29  */
 30 static void spear_write_pen_release(int val)
 31 {
 32         spear_pen_release = val;
 33         smp_wmb();
 34         sync_cache_w(&spear_pen_release);
 35 }
 36 
 37 static DEFINE_SPINLOCK(boot_lock);
 38 
 39 static void __iomem *scu_base = IOMEM(VA_SCU_BASE);
 40 
 41 static void spear13xx_secondary_init(unsigned int cpu)
 42 {
 43         /*
 44          * let the primary processor know we're out of the
 45          * pen, then head off into the C entry point
 46          */
 47         spear_write_pen_release(-1);
 48 
 49         /*
 50          * Synchronise with the boot thread.
 51          */
 52         spin_lock(&boot_lock);
 53         spin_unlock(&boot_lock);
 54 }
 55 
 56 static int spear13xx_boot_secondary(unsigned int cpu, struct task_struct *idle)
 57 {
 58         unsigned long timeout;
 59 
 60         /*
 61          * set synchronisation state between this boot processor
 62          * and the secondary one
 63          */
 64         spin_lock(&boot_lock);
 65 
 66         /*
 67          * The secondary processor is waiting to be released from
 68          * the holding pen - release it, then wait for it to flag
 69          * that it has been released by resetting spear_pen_release.
 70          *
 71          * Note that "spear_pen_release" is the hardware CPU ID, whereas
 72          * "cpu" is Linux's internal ID.
 73          */
 74         spear_write_pen_release(cpu);
 75 
 76         timeout = jiffies + (1 * HZ);
 77         while (time_before(jiffies, timeout)) {
 78                 smp_rmb();
 79                 if (spear_pen_release == -1)
 80                         break;
 81 
 82                 udelay(10);
 83         }
 84 
 85         /*
 86          * now the secondary core is starting up let it run its
 87          * calibrations, then wait for it to finish
 88          */
 89         spin_unlock(&boot_lock);
 90 
 91         return spear_pen_release != -1 ? -ENOSYS : 0;
 92 }
 93 
 94 /*
 95  * Initialise the CPU possible map early - this describes the CPUs
 96  * which may be present or become present in the system.
 97  */
 98 static void __init spear13xx_smp_init_cpus(void)
 99 {
100         unsigned int i, ncores = scu_get_core_count(scu_base);
101 
102         if (ncores > nr_cpu_ids) {
103                 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
104                         ncores, nr_cpu_ids);
105                 ncores = nr_cpu_ids;
106         }
107 
108         for (i = 0; i < ncores; i++)
109                 set_cpu_possible(i, true);
110 }
111 
112 static void __init spear13xx_smp_prepare_cpus(unsigned int max_cpus)
113 {
114 
115         scu_enable(scu_base);
116 
117         /*
118          * Write the address of secondary startup into the system-wide location
119          * (presently it is in SRAM). The BootMonitor waits until it receives a
120          * soft interrupt, and then the secondary CPU branches to this address.
121          */
122         __raw_writel(__pa_symbol(spear13xx_secondary_startup), SYS_LOCATION);
123 }
124 
125 const struct smp_operations spear13xx_smp_ops __initconst = {
126        .smp_init_cpus           = spear13xx_smp_init_cpus,
127        .smp_prepare_cpus        = spear13xx_smp_prepare_cpus,
128        .smp_secondary_init      = spear13xx_secondary_init,
129        .smp_boot_secondary      = spear13xx_boot_secondary,
130 #ifdef CONFIG_HOTPLUG_CPU
131        .cpu_die                 = spear13xx_cpu_die,
132 #endif
133 };
134 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php