/*
 * arch/sh/kernel/smp.c
 *
 * SMP support for the SuperH processors.
 *
 * Copyright (C) 2002, 2003 Paul Mundt
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 */
#include <linux/config.h>
#include <linux/cache.h>
#include <linux/cpumask.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/threads.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/sched.h>

#include <asm/atomic.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/smp.h>

/*
 * This was written with the Sega Saturn (SMP SH-2 7604) in mind,
 * but is designed to be usable regardless if there's an MMU
 * present or not.
 */
struct sh_cpuinfo cpu_data[NR_CPUS];

extern void per_cpu_trap_init(void);

cpumask_t cpu_possible_map;
cpumask_t cpu_online_map;
static atomic_t cpus_booted = ATOMIC_INIT(0);

/* These are defined by the board-specific code. */

/*
 * Cause the function described by call_data to be executed on the passed
 * cpu.  When the function has finished, increment the finished field of
 * call_data.
 */
void __smp_send_ipi(unsigned int cpu, unsigned int action);

/*
 * Find the number of available processors
 */
unsigned int __smp_probe_cpus(void);

/*
 * Start a particular processor
 */
void __smp_slave_init(unsigned int cpu);

/*
 * Run specified function on a particular processor.
 */
void __smp_call_function(unsigned int cpu);

static inline void __init smp_store_cpu_info(unsigned int cpu)
{
	cpu_data[cpu].loops_per_jiffy = loops_per_jiffy;
}

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

	atomic_set(&cpus_booted, 1);
	smp_store_cpu_info(cpu);
	
	for (i = 0; i < __smp_probe_cpus(); i++)
		cpu_set(i, cpu_possible_map);
}

void __devinit smp_prepare_boot_cpu(void)
{
	unsigned int cpu = smp_processor_id();

	cpu_set(cpu, cpu_online_map);
	cpu_set(cpu, cpu_possible_map);
}

int __cpu_up(unsigned int cpu)
{
	struct task_struct *tsk;

	tsk = fork_idle(cpu);

	if (IS_ERR(tsk))
		panic("Failed forking idle task for cpu %d\n", cpu);
	
	tsk->thread_info->cpu = cpu;

	cpu_set(cpu, cpu_online_map);

	return 0;
}

int start_secondary(void *unused)
{
	unsigned int cpu = smp_processor_id();

	atomic_inc(&init_mm.mm_count);
	current->active_mm = &init_mm;

	smp_store_cpu_info(cpu);

	__smp_slave_init(cpu);
	per_cpu_trap_init();
	
	atomic_inc(&cpus_booted);

	cpu_idle();
	return 0;
}

void __init smp_cpus_done(unsigned int max_cpus)
{
	smp_mb();
}

void smp_send_reschedule(int cpu)
{
	__smp_send_ipi(cpu, SMP_MSG_RESCHEDULE);
}

static void stop_this_cpu(void *unused)
{
	cpu_clear(smp_processor_id(), cpu_online_map);
	local_irq_disable();

	for (;;)
		cpu_relax();
}

void smp_send_stop(void)
{
	smp_call_function(stop_this_cpu, 0, 1, 0);
}


struct smp_fn_call_struct smp_fn_call = {
	.lock		= SPIN_LOCK_UNLOCKED,
	.finished	= ATOMIC_INIT(0),
};

/*
 * The caller of this wants the passed function to run on every cpu.  If wait
 * is set, wait until all cpus have finished the function before returning.
 * The lock is here to protect the call structure.
 * You must not call this function with disabled interrupts or from a
 * hardware interrupt handler or from a bottom half handler.
 */
int smp_call_function(void (*func)(void *info), void *info, int retry, int wait)
{
	unsigned int nr_cpus = atomic_read(&cpus_booted);
	int i;

	if (nr_cpus < 2)
		return 0;

	/* Can deadlock when called with interrupts disabled */
	WARN_ON(irqs_disabled());

	spin_lock(&smp_fn_call.lock);

	atomic_set(&smp_fn_call.finished, 0);
	smp_fn_call.fn = func;
	smp_fn_call.data = info;

	for (i = 0; i < nr_cpus; i++)
		if (i != smp_processor_id())
			__smp_call_function(i);

	if (wait)
		while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1));

	spin_unlock(&smp_fn_call.lock);

	return 0;
}

/* Not really SMP stuff ... */
int setup_profiling_timer(unsigned int multiplier)
{
	return 0;
}

