root/arch/powerpc/platforms/ps3/smp.c

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

DEFINITIONS

This source file includes following definitions.
  1. ps3_smp_message_pass
  2. ps3_smp_probe
  3. ps3_smp_cleanup_cpu
  4. smp_init_ps3

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  PS3 SMP routines.
   4  *
   5  *  Copyright (C) 2006 Sony Computer Entertainment Inc.
   6  *  Copyright 2006 Sony Corp.
   7  */
   8 
   9 #include <linux/kernel.h>
  10 #include <linux/smp.h>
  11 
  12 #include <asm/machdep.h>
  13 #include <asm/udbg.h>
  14 
  15 #include "platform.h"
  16 
  17 #if defined(DEBUG)
  18 #define DBG udbg_printf
  19 #else
  20 #define DBG pr_debug
  21 #endif
  22 
  23 /**
  24   * ps3_ipi_virqs - a per cpu array of virqs for ipi use
  25   */
  26 
  27 #define MSG_COUNT 4
  28 static DEFINE_PER_CPU(unsigned int [MSG_COUNT], ps3_ipi_virqs);
  29 
  30 static void ps3_smp_message_pass(int cpu, int msg)
  31 {
  32         int result;
  33         unsigned int virq;
  34 
  35         if (msg >= MSG_COUNT) {
  36                 DBG("%s:%d: bad msg: %d\n", __func__, __LINE__, msg);
  37                 return;
  38         }
  39 
  40         virq = per_cpu(ps3_ipi_virqs, cpu)[msg];
  41         result = ps3_send_event_locally(virq);
  42 
  43         if (result)
  44                 DBG("%s:%d: ps3_send_event_locally(%d, %d) failed"
  45                         " (%d)\n", __func__, __LINE__, cpu, msg, result);
  46 }
  47 
  48 static void __init ps3_smp_probe(void)
  49 {
  50         int cpu;
  51 
  52         for (cpu = 0; cpu < 2; cpu++) {
  53                 int result;
  54                 unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
  55                 int i;
  56 
  57                 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
  58 
  59                 /*
  60                 * Check assumptions on ps3_ipi_virqs[] indexing. If this
  61                 * check fails, then a different mapping of PPC_MSG_
  62                 * to index needs to be setup.
  63                 */
  64 
  65                 BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION    != 0);
  66                 BUILD_BUG_ON(PPC_MSG_RESCHEDULE       != 1);
  67                 BUILD_BUG_ON(PPC_MSG_TICK_BROADCAST   != 2);
  68                 BUILD_BUG_ON(PPC_MSG_NMI_IPI          != 3);
  69 
  70                 for (i = 0; i < MSG_COUNT; i++) {
  71                         result = ps3_event_receive_port_setup(cpu, &virqs[i]);
  72 
  73                         if (result)
  74                                 continue;
  75 
  76                         DBG("%s:%d: (%d, %d) => virq %u\n",
  77                                 __func__, __LINE__, cpu, i, virqs[i]);
  78 
  79                         result = smp_request_message_ipi(virqs[i], i);
  80 
  81                         if (result)
  82                                 virqs[i] = 0;
  83                         else
  84                                 ps3_register_ipi_irq(cpu, virqs[i]);
  85                 }
  86 
  87                 ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_NMI_IPI]);
  88 
  89                 DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
  90         }
  91 }
  92 
  93 void ps3_smp_cleanup_cpu(int cpu)
  94 {
  95         unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu);
  96         int i;
  97 
  98         DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
  99 
 100         for (i = 0; i < MSG_COUNT; i++) {
 101                 /* Can't call free_irq from interrupt context. */
 102                 ps3_event_receive_port_destroy(virqs[i]);
 103                 virqs[i] = 0;
 104         }
 105 
 106         DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
 107 }
 108 
 109 static struct smp_ops_t ps3_smp_ops = {
 110         .probe          = ps3_smp_probe,
 111         .message_pass   = ps3_smp_message_pass,
 112         .kick_cpu       = smp_generic_kick_cpu,
 113 };
 114 
 115 void smp_init_ps3(void)
 116 {
 117         DBG(" -> %s\n", __func__);
 118         smp_ops = &ps3_smp_ops;
 119         DBG(" <- %s\n", __func__);
 120 }

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