/*
 * 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 <linux/module.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;
EXPORT_SYMBOL(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);
	
	task_thread_info(tsk)->cpu = cpu;

	cpu_set(cpu, cpu_online_map);

	return 0;
}

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

	cpu = smp_processor_id();

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

	smp_store_cpu_info(cpu);

	__smp_slave_init(cpu);
	preempt_disable();
	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;
}

