/*
 *  PS3 SMP routines.
 *
 *  Copyright (C) 2006 Sony Computer Entertainment Inc.
 *  Copyright 2006 Sony Corp.
 *
 *  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; version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/kernel.h>
#include <linux/smp.h>

#include <asm/machdep.h>
#include <asm/udbg.h>

#include "platform.h"

#if defined(DEBUG)
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...) do{if(0)printk(fmt);}while(0)
#endif

static irqreturn_t ipi_function_handler(int irq, void *msg)
{
	smp_message_recv((int)(long)msg);
	return IRQ_HANDLED;
}

/**
  * virqs - a per cpu array of virqs for ipi use
  */

#define MSG_COUNT 4
static DEFINE_PER_CPU(unsigned int, virqs[MSG_COUNT]);

static const char *names[MSG_COUNT] = {
	"ipi call",
	"ipi reschedule",
	"ipi migrate",
	"ipi debug brk"
};

static void do_message_pass(int target, int msg)
{
	int result;
	unsigned int virq;

	if (msg >= MSG_COUNT) {
		DBG("%s:%d: bad msg: %d\n", __func__, __LINE__, msg);
		return;
	}

	virq = per_cpu(virqs, target)[msg];
	result = ps3_send_event_locally(virq);

	if (result)
		DBG("%s:%d: ps3_send_event_locally(%d, %d) failed"
			" (%d)\n", __func__, __LINE__, target, msg, result);
}

static void ps3_smp_message_pass(int target, int msg)
{
	int cpu;

	if (target < NR_CPUS)
		do_message_pass(target, msg);
	else if (target == MSG_ALL_BUT_SELF) {
		for_each_online_cpu(cpu)
			if (cpu != smp_processor_id())
				do_message_pass(cpu, msg);
	} else {
		for_each_online_cpu(cpu)
			do_message_pass(cpu, msg);
	}
}

static int ps3_smp_probe(void)
{
	return 2;
}

static void __init ps3_smp_setup_cpu(int cpu)
{
	int result;
	unsigned int *virqs = per_cpu(virqs, cpu);
	int i;

	DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);

	/*
	 * Check assumptions on virqs[] indexing. If this
	 * check fails, then a different mapping of PPC_MSG_
	 * to index needs to be setup.
	 */

	BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION  != 0);
	BUILD_BUG_ON(PPC_MSG_RESCHEDULE     != 1);
	BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3);

	for (i = 0; i < MSG_COUNT; i++) {
		result = ps3_alloc_event_irq(cpu, &virqs[i]);

		if (result)
			continue;

		DBG("%s:%d: (%d, %d) => virq %u\n",
			__func__, __LINE__, cpu, i, virqs[i]);


		request_irq(virqs[i], ipi_function_handler, IRQF_DISABLED,
			names[i], (void*)(long)i);
	}

	ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]);

	DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
}

void ps3_smp_cleanup_cpu(int cpu)
{
	unsigned int *virqs = per_cpu(virqs, cpu);
	int i;

	DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
	for (i = 0; i < MSG_COUNT; i++) {
		ps3_free_event_irq(virqs[i]);
		free_irq(virqs[i], (void*)(long)i);
		virqs[i] = NO_IRQ;
	}
	DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
}

static struct smp_ops_t ps3_smp_ops = {
	.probe		= ps3_smp_probe,
	.message_pass	= ps3_smp_message_pass,
	.kick_cpu	= smp_generic_kick_cpu,
	.setup_cpu	= ps3_smp_setup_cpu,
};

void smp_init_ps3(void)
{
	DBG(" -> %s\n", __func__);
	smp_ops = &ps3_smp_ops;
	DBG(" <- %s\n", __func__);
}
