root/arch/arm/common/mcpm_platsmp.c

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

DEFINITIONS

This source file includes following definitions.
  1. cpu_to_pcpu
  2. mcpm_boot_secondary
  3. mcpm_secondary_init
  4. mcpm_cpu_kill
  5. mcpm_cpu_can_disable
  6. mcpm_cpu_die
  7. mcpm_smp_set_ops

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * linux/arch/arm/mach-vexpress/mcpm_platsmp.c
   4  *
   5  * Created by:  Nicolas Pitre, November 2012
   6  * Copyright:   (C) 2012-2013  Linaro Limited
   7  *
   8  * Code to handle secondary CPU bringup and hotplug for the cluster power API.
   9  */
  10 
  11 #include <linux/init.h>
  12 #include <linux/smp.h>
  13 #include <linux/spinlock.h>
  14 
  15 #include <asm/mcpm.h>
  16 #include <asm/smp.h>
  17 #include <asm/smp_plat.h>
  18 
  19 static void cpu_to_pcpu(unsigned int cpu,
  20                         unsigned int *pcpu, unsigned int *pcluster)
  21 {
  22         unsigned int mpidr;
  23 
  24         mpidr = cpu_logical_map(cpu);
  25         *pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
  26         *pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
  27 }
  28 
  29 static int mcpm_boot_secondary(unsigned int cpu, struct task_struct *idle)
  30 {
  31         unsigned int pcpu, pcluster, ret;
  32         extern void secondary_startup(void);
  33 
  34         cpu_to_pcpu(cpu, &pcpu, &pcluster);
  35 
  36         pr_debug("%s: logical CPU %d is physical CPU %d cluster %d\n",
  37                  __func__, cpu, pcpu, pcluster);
  38 
  39         mcpm_set_entry_vector(pcpu, pcluster, NULL);
  40         ret = mcpm_cpu_power_up(pcpu, pcluster);
  41         if (ret)
  42                 return ret;
  43         mcpm_set_entry_vector(pcpu, pcluster, secondary_startup);
  44         arch_send_wakeup_ipi_mask(cpumask_of(cpu));
  45         dsb_sev();
  46         return 0;
  47 }
  48 
  49 static void mcpm_secondary_init(unsigned int cpu)
  50 {
  51         mcpm_cpu_powered_up();
  52 }
  53 
  54 #ifdef CONFIG_HOTPLUG_CPU
  55 
  56 static int mcpm_cpu_kill(unsigned int cpu)
  57 {
  58         unsigned int pcpu, pcluster;
  59 
  60         cpu_to_pcpu(cpu, &pcpu, &pcluster);
  61 
  62         return !mcpm_wait_for_cpu_powerdown(pcpu, pcluster);
  63 }
  64 
  65 static bool mcpm_cpu_can_disable(unsigned int cpu)
  66 {
  67         /* We assume all CPUs may be shut down. */
  68         return true;
  69 }
  70 
  71 static void mcpm_cpu_die(unsigned int cpu)
  72 {
  73         unsigned int mpidr, pcpu, pcluster;
  74         mpidr = read_cpuid_mpidr();
  75         pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
  76         pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
  77         mcpm_set_entry_vector(pcpu, pcluster, NULL);
  78         mcpm_cpu_power_down();
  79 }
  80 
  81 #endif
  82 
  83 static const struct smp_operations mcpm_smp_ops __initconst = {
  84         .smp_boot_secondary     = mcpm_boot_secondary,
  85         .smp_secondary_init     = mcpm_secondary_init,
  86 #ifdef CONFIG_HOTPLUG_CPU
  87         .cpu_kill               = mcpm_cpu_kill,
  88         .cpu_can_disable        = mcpm_cpu_can_disable,
  89         .cpu_die                = mcpm_cpu_die,
  90 #endif
  91 };
  92 
  93 void __init mcpm_smp_set_ops(void)
  94 {
  95         smp_set_ops(&mcpm_smp_ops);
  96 }

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