linux/arch/arm/mach-realview/platsmp.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/arm/mach-realview/platsmp.c
   3 *
   4 *  Copyright (C) 2002 ARM Ltd.
   5 *  All Rights Reserved
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11#include <linux/init.h>
  12#include <linux/errno.h>
  13#include <linux/smp.h>
  14#include <linux/io.h>
  15
  16#include <mach/hardware.h>
  17#include <asm/hardware/gic.h>
  18#include <asm/mach-types.h>
  19#include <asm/smp_scu.h>
  20#include <asm/unified.h>
  21
  22#include <mach/board-eb.h>
  23#include <mach/board-pb11mp.h>
  24#include <mach/board-pbx.h>
  25
  26#include "core.h"
  27
  28extern void versatile_secondary_startup(void);
  29
  30static void __iomem *scu_base_addr(void)
  31{
  32        if (machine_is_realview_eb_mp())
  33                return __io_address(REALVIEW_EB11MP_SCU_BASE);
  34        else if (machine_is_realview_pb11mp())
  35                return __io_address(REALVIEW_TC11MP_SCU_BASE);
  36        else if (machine_is_realview_pbx() &&
  37                 (core_tile_pbx11mp() || core_tile_pbxa9mp()))
  38                return __io_address(REALVIEW_PBX_TILE_SCU_BASE);
  39        else
  40                return (void __iomem *)0;
  41}
  42
  43/*
  44 * Initialise the CPU possible map early - this describes the CPUs
  45 * which may be present or become present in the system.
  46 */
  47void __init smp_init_cpus(void)
  48{
  49        void __iomem *scu_base = scu_base_addr();
  50        unsigned int i, ncores;
  51
  52        ncores = scu_base ? scu_get_core_count(scu_base) : 1;
  53
  54        /* sanity check */
  55        if (ncores > NR_CPUS) {
  56                printk(KERN_WARNING
  57                       "Realview: no. of cores (%d) greater than configured "
  58                       "maximum of %d - clipping\n",
  59                       ncores, NR_CPUS);
  60                ncores = NR_CPUS;
  61        }
  62
  63        for (i = 0; i < ncores; i++)
  64                set_cpu_possible(i, true);
  65
  66        set_smp_cross_call(gic_raise_softirq);
  67}
  68
  69void __init platform_smp_prepare_cpus(unsigned int max_cpus)
  70{
  71
  72        scu_enable(scu_base_addr());
  73
  74        /*
  75         * Write the address of secondary startup into the
  76         * system-wide flags register. The BootMonitor waits
  77         * until it receives a soft interrupt, and then the
  78         * secondary CPU branches to this address.
  79         */
  80        __raw_writel(BSYM(virt_to_phys(versatile_secondary_startup)),
  81                     __io_address(REALVIEW_SYS_FLAGSSET));
  82}
  83