linux/arch/powerpc/platforms/iseries/smp.c
<<
>>
Prefs
   1/*
   2 * SMP support for iSeries machines.
   3 *
   4 * Dave Engebretsen, Peter Bergner, and
   5 * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
   6 *
   7 * Plus various changes from other IBM teams...
   8 *
   9 *      This program is free software; you can redistribute it and/or
  10 *      modify it under the terms of the GNU General Public License
  11 *      as published by the Free Software Foundation; either version
  12 *      2 of the License, or (at your option) any later version.
  13 */
  14
  15#undef DEBUG
  16
  17#include <linux/kernel.h>
  18#include <linux/sched.h>
  19#include <linux/smp.h>
  20#include <linux/interrupt.h>
  21#include <linux/kernel_stat.h>
  22#include <linux/delay.h>
  23#include <linux/init.h>
  24#include <linux/spinlock.h>
  25#include <linux/cache.h>
  26#include <linux/err.h>
  27#include <linux/device.h>
  28#include <linux/cpu.h>
  29
  30#include <asm/ptrace.h>
  31#include <linux/atomic.h>
  32#include <asm/irq.h>
  33#include <asm/page.h>
  34#include <asm/pgtable.h>
  35#include <asm/io.h>
  36#include <asm/smp.h>
  37#include <asm/paca.h>
  38#include <asm/iseries/hv_call.h>
  39#include <asm/time.h>
  40#include <asm/machdep.h>
  41#include <asm/cputable.h>
  42#include <asm/system.h>
  43
  44static void smp_iSeries_cause_ipi(int cpu, unsigned long data)
  45{
  46        HvCall_sendIPI(&(paca[cpu]));
  47}
  48
  49static int smp_iSeries_probe(void)
  50{
  51        return cpumask_weight(cpu_possible_mask);
  52}
  53
  54static int smp_iSeries_kick_cpu(int nr)
  55{
  56        BUG_ON((nr < 0) || (nr >= NR_CPUS));
  57
  58        /* Verify that our partition has a processor nr */
  59        if (lppaca_of(nr).dyn_proc_status >= 2)
  60                return -ENOENT;
  61
  62        /* The processor is currently spinning, waiting
  63         * for the cpu_start field to become non-zero
  64         * After we set cpu_start, the processor will
  65         * continue on to secondary_start in iSeries_head.S
  66         */
  67        paca[nr].cpu_start = 1;
  68
  69        return 0;
  70}
  71
  72static void __devinit smp_iSeries_setup_cpu(int nr)
  73{
  74}
  75
  76static struct smp_ops_t iSeries_smp_ops = {
  77        .message_pass = NULL,   /* Use smp_muxed_ipi_message_pass */
  78        .cause_ipi    = smp_iSeries_cause_ipi,
  79        .probe        = smp_iSeries_probe,
  80        .kick_cpu     = smp_iSeries_kick_cpu,
  81        .setup_cpu    = smp_iSeries_setup_cpu,
  82};
  83
  84/* This is called very early. */
  85void __init smp_init_iSeries(void)
  86{
  87        smp_ops = &iSeries_smp_ops;
  88}
  89