linux/arch/mips/pmc-sierra/msp71xx/msp_smtc.c
<<
>>
Prefs
   1/*
   2 * MSP71xx Platform-specific hooks for SMP operation
   3 */
   4#include <linux/irq.h>
   5#include <linux/init.h>
   6
   7#include <asm/mipsmtregs.h>
   8#include <asm/mipsregs.h>
   9#include <asm/smtc.h>
  10#include <asm/smtc_ipi.h>
  11
  12/* VPE/SMP Prototype implements platform interfaces directly */
  13
  14/*
  15 * Cause the specified action to be performed on a targeted "CPU"
  16 */
  17
  18static void msp_smtc_send_ipi_single(int cpu, unsigned int action)
  19{
  20        /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
  21        smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
  22}
  23
  24static void msp_smtc_send_ipi_mask(const struct cpumask *mask,
  25                                                unsigned int action)
  26{
  27        unsigned int i;
  28
  29        for_each_cpu(i, mask)
  30                msp_smtc_send_ipi_single(i, action);
  31}
  32
  33/*
  34 * Post-config but pre-boot cleanup entry point
  35 */
  36static void __cpuinit msp_smtc_init_secondary(void)
  37{
  38        int myvpe;
  39
  40        /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
  41        myvpe = read_c0_tcbind() & TCBIND_CURVPE;
  42        if (myvpe > 0)
  43                change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
  44                                STATUSF_IP6 | STATUSF_IP7);
  45        smtc_init_secondary();
  46}
  47
  48/*
  49 * Platform "CPU" startup hook
  50 */
  51static void __cpuinit msp_smtc_boot_secondary(int cpu,
  52                                        struct task_struct *idle)
  53{
  54        smtc_boot_secondary(cpu, idle);
  55}
  56
  57/*
  58 * SMP initialization finalization entry point
  59 */
  60static void __cpuinit msp_smtc_smp_finish(void)
  61{
  62        smtc_smp_finish();
  63}
  64
  65/*
  66 * Hook for after all CPUs are online
  67 */
  68
  69static void msp_smtc_cpus_done(void)
  70{
  71}
  72
  73/*
  74 * Platform SMP pre-initialization
  75 *
  76 * As noted above, we can assume a single CPU for now
  77 * but it may be multithreaded.
  78 */
  79
  80static void __init msp_smtc_smp_setup(void)
  81{
  82        /*
  83         * we won't get the definitive value until
  84         * we've run smtc_prepare_cpus later, but
  85         */
  86
  87        if (read_c0_config3() & (1 << 2))
  88                smp_num_siblings = smtc_build_cpu_map(0);
  89}
  90
  91static void __init msp_smtc_prepare_cpus(unsigned int max_cpus)
  92{
  93        smtc_prepare_cpus(max_cpus);
  94}
  95
  96struct plat_smp_ops msp_smtc_smp_ops = {
  97        .send_ipi_single        = msp_smtc_send_ipi_single,
  98        .send_ipi_mask          = msp_smtc_send_ipi_mask,
  99        .init_secondary         = msp_smtc_init_secondary,
 100        .smp_finish             = msp_smtc_smp_finish,
 101        .cpus_done              = msp_smtc_cpus_done,
 102        .boot_secondary         = msp_smtc_boot_secondary,
 103        .smp_setup              = msp_smtc_smp_setup,
 104        .prepare_cpus           = msp_smtc_prepare_cpus,
 105};
 106