platsmp.c 1.7 KB
Newer Older
M
Magnus Damm 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * SMP support for R-Mobile / SH-Mobile
 *
 * Copyright (C) 2010  Magnus Damm
 *
 * Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/smp.h>
#include <linux/io.h>
#include <asm/localtimer.h>
19 20
#include <asm/mach-types.h>
#include <mach/common.h>
M
Magnus Damm 已提交
21 22 23

static unsigned int __init shmobile_smp_get_core_count(void)
{
24 25 26
	if (machine_is_ag5evm())
		return sh73a0_get_core_count();

M
Magnus Damm 已提交
27 28 29 30 31
	return 1;
}

static void __init shmobile_smp_prepare_cpus(void)
{
32 33
	if (machine_is_ag5evm())
		sh73a0_smp_prepare_cpus();
M
Magnus Damm 已提交
34 35 36 37 38 39
}


void __cpuinit platform_secondary_init(unsigned int cpu)
{
	trace_hardirqs_off();
40 41 42

	if (machine_is_ag5evm())
		sh73a0_secondary_init(cpu);
M
Magnus Damm 已提交
43 44 45 46
}

int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
47 48 49
	if (machine_is_ag5evm())
		return sh73a0_boot_secondary(cpu);

M
Magnus Damm 已提交
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
	return -ENOSYS;
}

void __init smp_init_cpus(void)
{
	unsigned int ncores = shmobile_smp_get_core_count();
	unsigned int i;

	for (i = 0; i < ncores; i++)
		set_cpu_possible(i, true);
}

void __init smp_prepare_cpus(unsigned int max_cpus)
{
	unsigned int ncores = shmobile_smp_get_core_count();
	unsigned int cpu = smp_processor_id();
	int i;

	smp_store_cpu_info(cpu);

	if (max_cpus > ncores)
		max_cpus = ncores;

	for (i = 0; i < max_cpus; i++)
		set_cpu_present(i, true);

	if (max_cpus > 1) {
		shmobile_smp_prepare_cpus();

		/*
		 * Enable the local timer or broadcast device for the
		 * boot CPU, but only if we have more than one CPU.
		 */
		percpu_timer_setup();
	}
}