root/arch/arm/mach-sti/platsmp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sti_boot_secondary
  2. sti_smp_prepare_cpus

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  arch/arm/mach-sti/platsmp.c
   4  *
   5  * Copyright (C) 2013 STMicroelectronics (R&D) Limited.
   6  *              http://www.st.com
   7  *
   8  * Cloned from linux/arch/arm/mach-vexpress/platsmp.c
   9  *
  10  *  Copyright (C) 2002 ARM Ltd.
  11  *  All Rights Reserved
  12  */
  13 #include <linux/init.h>
  14 #include <linux/errno.h>
  15 #include <linux/delay.h>
  16 #include <linux/smp.h>
  17 #include <linux/io.h>
  18 #include <linux/of.h>
  19 #include <linux/of_address.h>
  20 #include <linux/memblock.h>
  21 
  22 #include <asm/cacheflush.h>
  23 #include <asm/smp_plat.h>
  24 #include <asm/smp_scu.h>
  25 
  26 #include "smp.h"
  27 
  28 static u32 __iomem *cpu_strt_ptr;
  29 
  30 static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle)
  31 {
  32         unsigned long entry_pa = __pa_symbol(secondary_startup);
  33 
  34         /*
  35          * Secondary CPU is initialised and started by a U-BOOTROM firmware.
  36          * Secondary CPU is spinning and waiting for a write at cpu_strt_ptr.
  37          * Writing secondary_startup address at cpu_strt_ptr makes it to
  38          * jump directly to secondary_startup().
  39          */
  40         __raw_writel(entry_pa, cpu_strt_ptr);
  41 
  42         /* wmb so that data is actually written before cache flush is done */
  43         smp_wmb();
  44         sync_cache_w(cpu_strt_ptr);
  45 
  46         return 0;
  47 }
  48 
  49 static void __init sti_smp_prepare_cpus(unsigned int max_cpus)
  50 {
  51         struct device_node *np;
  52         void __iomem *scu_base;
  53         u32 release_phys;
  54         int cpu;
  55 
  56         np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
  57 
  58         if (np) {
  59                 scu_base = of_iomap(np, 0);
  60                 scu_enable(scu_base);
  61                 of_node_put(np);
  62         }
  63 
  64         if (max_cpus <= 1)
  65                 return;
  66 
  67         for_each_possible_cpu(cpu) {
  68 
  69                 np = of_get_cpu_node(cpu, NULL);
  70 
  71                 if (!np)
  72                         continue;
  73 
  74                 if (of_property_read_u32(np, "cpu-release-addr",
  75                                                 &release_phys)) {
  76                         pr_err("CPU %d: missing or invalid cpu-release-addr "
  77                                 "property\n", cpu);
  78                         continue;
  79                 }
  80 
  81                 /*
  82                  * cpu-release-addr is usually configured in SBC DMEM but can
  83                  * also be in RAM.
  84                  */
  85 
  86                 if (!memblock_is_memory(release_phys))
  87                         cpu_strt_ptr =
  88                                 ioremap(release_phys, sizeof(release_phys));
  89                 else
  90                         cpu_strt_ptr =
  91                                 (u32 __iomem *)phys_to_virt(release_phys);
  92 
  93                 set_cpu_possible(cpu, true);
  94         }
  95 }
  96 
  97 const struct smp_operations sti_smp_ops __initconst = {
  98         .smp_prepare_cpus       = sti_smp_prepare_cpus,
  99         .smp_boot_secondary     = sti_boot_secondary,
 100 };

/* [<][>][^][v][top][bottom][index][help] */