/*
 * Cell Internal Interrupt Controller
 *
 * Copyright (C) 2006 Benjamin Herrenschmidt (benh@kernel.crashing.org)
 *                    IBM, Corp.
 *
 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
 *
 * Author: Arnd Bergmann <arndb@de.ibm.com>
 *
 * 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, or (at your option)
 * any later version.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * TODO:
 * - Fix various assumptions related to HW CPU numbers vs. linux CPU numbers
 *   vs node numbers in the setup code
 * - Implement proper handling of maxcpus=1/2 (that is, routing of irqs from
 *   a non-active node to the active node)
 */

#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/export.h>
#include <linux/percpu.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/kernel_stat.h>

#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/prom.h>
#include <asm/ptrace.h>
#include <asm/machdep.h>
#include <asm/cell-regs.h>

#include "interrupt.h"

struct iic {
	struct cbe_iic_thread_regs __iomem *regs;
	u8 target_id;
	u8 eoi_stack[16];
	int eoi_ptr;
	struct device_node *node;
};

static DEFINE_PER_CPU(struct iic, cpu_iic);
#define IIC_NODE_COUNT	2
static struct irq_domain *iic_host;

/* Convert between "pending" bits and hw irq number */
static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
{
	unsigned char unit = bits.source & 0xf;
	unsigned char node = bits.source >> 4;
	unsigned char class = bits.class & 3;

	/* Decode IPIs */
	if (bits.flags & CBE_IIC_IRQ_IPI)
		return IIC_IRQ_TYPE_IPI | (bits.prio >> 4);
	else
		return (node << IIC_IRQ_NODE_SHIFT) | (class << 4) | unit;
}

static void iic_mask(struct irq_data *d)
{
}

static void iic_unmask(struct irq_data *d)
{
}

static void iic_eoi(struct irq_data *d)
{
	struct iic *iic = this_cpu_ptr(&cpu_iic);
	out_be64(&iic->regs->prio, iic->eoi_stack[--iic->eoi_ptr]);
	BUG_ON(iic->eoi_ptr < 0);
}

static struct irq_chip iic_chip = {
	.name = "CELL-IIC",
	.irq_mask = iic_mask,
	.irq_unmask = iic_unmask,
	.irq_eoi = iic_eoi,
};


static void iic_ioexc_eoi(struct irq_data *d)
{
}

static void iic_ioexc_cascade(struct irq_desc *desc)
{
	struct irq_chip *chip = irq_desc_get_chip(desc);
	struct cbe_iic_regs __iomem *node_iic =
		(void __iomem *)irq_desc_get_handler_data(desc);
	unsigned int irq = irq_desc_get_irq(desc);
	unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC;
	unsigned long bits, ack;
	int cascade;

	for (;;) {
		bits = in_be64(&node_iic->iic_is);
		if (bits == 0)
			break;
		/* pre-ack edge interrupts */
		ack = bits & IIC_ISR_EDGE_MASK;
		if (ack)
			out_be64(&node_iic->iic_is, ack);
		/* handle them */
		for (cascade = 63; cascade >= 0; cascade--)
			if (bits & (0x8000000000000000UL >> cascade)) {
				unsigned int cirq =
					irq_linear_revmap(iic_host,
							  base | cascade);
				if (cirq != NO_IRQ)
					generic_handle_irq(cirq);
			}
		/* post-ack level interrupts */
		ack = bits & ~IIC_ISR_EDGE_MASK;
		if (ack)
			out_be64(&node_iic->iic_is, ack);
	}
	chip->irq_eoi(&desc->irq_data);
}


static struct irq_chip iic_ioexc_chip = {
	.name = "CELL-IOEX",
	.irq_mask = iic_mask,
	.irq_unmask = iic_unmask,
	.irq_eoi = iic_ioexc_eoi,
};

/* Get an IRQ number from the pending state register of the IIC */
static unsigned int iic_get_irq(void)
{
	struct cbe_iic_pending_bits pending;
	struct iic *iic;
	unsigned int virq;

	iic = this_cpu_ptr(&cpu_iic);
	*(unsigned long *) &pending =
		in_be64((u64 __iomem *) &iic->regs->pending_destr);
	if (!(pending.flags & CBE_IIC_IRQ_VALID))
		return NO_IRQ;
	virq = irq_linear_revmap(iic_host, iic_pending_to_hwnum(pending));
	if (virq == NO_IRQ)
		return NO_IRQ;
	iic->eoi_stack[++iic->eoi_ptr] = pending.prio;
	BUG_ON(iic->eoi_ptr > 15);
	return virq;
}

void iic_setup_cpu(void)
{
	out_be64(&this_cpu_ptr(&cpu_iic)->regs->prio, 0xff);
}

u8 iic_get_target_id(int cpu)
{
	return per_cpu(cpu_iic, cpu).target_id;
}

EXPORT_SYMBOL_GPL(iic_get_target_id);

#ifdef CONFIG_SMP

/* Use the highest interrupt priorities for IPI */
static inline int iic_msg_to_irq(int msg)
{
	return IIC_IRQ_TYPE_IPI + 0xf - msg;
}

void iic_message_pass(int cpu, int msg)
{
	out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - msg) << 4);
}

struct irq_domain *iic_get_irq_host(int node)
{
	return iic_host;
}
EXPORT_SYMBOL_GPL(iic_get_irq_host);

static void iic_request_ipi(int msg)
{
	int virq;

	virq = irq_create_mapping(iic_host, iic_msg_to_irq(msg));
	if (virq == NO_IRQ) {
		printk(KERN_ERR
		       "iic: failed to map IPI %s\n", smp_ipi_name[msg]);
		return;
	}

	/*
	 * If smp_request_message_ipi encounters an error it will notify
	 * the error.  If a message is not needed it will return non-zero.
	 */
	if (smp_request_message_ipi(virq, msg))
		irq_dispose_mapping(virq);
}

void iic_request_IPIs(void)
{
	iic_request_ipi(PPC_MSG_CALL_FUNCTION);
	iic_request_ipi(PPC_MSG_RESCHEDULE);
	iic_request_ipi(PPC_MSG_TICK_BROADCAST);
	iic_request_ipi(PPC_MSG_DEBUGGER_BREAK);
}

#endif /* CONFIG_SMP */


static int iic_host_match(struct irq_domain *h, struct device_node *node,
			  enum irq_domain_bus_token bus_token)
{
	return of_device_is_compatible(node,
				    "IBM,CBEA-Internal-Interrupt-Controller");
}

static int iic_host_map(struct irq_domain *h, unsigned int virq,
			irq_hw_number_t hw)
{
	switch (hw & IIC_IRQ_TYPE_MASK) {
	case IIC_IRQ_TYPE_IPI:
		irq_set_chip_and_handler(virq, &iic_chip, handle_percpu_irq);
		break;
	case IIC_IRQ_TYPE_IOEXC:
		irq_set_chip_and_handler(virq, &iic_ioexc_chip,
					 handle_edge_eoi_irq);
		break;
	default:
		irq_set_chip_and_handler(virq, &iic_chip, handle_edge_eoi_irq);
	}
	return 0;
}

static int iic_host_xlate(struct irq_domain *h, struct device_node *ct,
			   const u32 *intspec, unsigned int intsize,
			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)

{
	unsigned int node, ext, unit, class;
	const u32 *val;

	if (!of_device_is_compatible(ct,
				     "IBM,CBEA-Internal-Interrupt-Controller"))
		return -ENODEV;
	if (intsize != 1)
		return -ENODEV;
	val = of_get_property(ct, "#interrupt-cells", NULL);
	if (val == NULL || *val != 1)
		return -ENODEV;

	node = intspec[0] >> 24;
	ext = (intspec[0] >> 16) & 0xff;
	class = (intspec[0] >> 8) & 0xff;
	unit = intspec[0] & 0xff;

	/* Check if node is in supported range */
	if (node > 1)
		return -EINVAL;

	/* Build up interrupt number, special case for IO exceptions */
	*out_hwirq = (node << IIC_IRQ_NODE_SHIFT);
	if (unit == IIC_UNIT_IIC && class == 1)
		*out_hwirq |= IIC_IRQ_TYPE_IOEXC | ext;
	else
		*out_hwirq |= IIC_IRQ_TYPE_NORMAL |
			(class << IIC_IRQ_CLASS_SHIFT) | unit;

	/* Dummy flags, ignored by iic code */
	*out_flags = IRQ_TYPE_EDGE_RISING;

	return 0;
}

static const struct irq_domain_ops iic_host_ops = {
	.match = iic_host_match,
	.map = iic_host_map,
	.xlate = iic_host_xlate,
};

static void __init init_one_iic(unsigned int hw_cpu, unsigned long addr,
				struct device_node *node)
{
	/* XXX FIXME: should locate the linux CPU number from the HW cpu
	 * number properly. We are lucky for now
	 */
	struct iic *iic = &per_cpu(cpu_iic, hw_cpu);

	iic->regs = ioremap(addr, sizeof(struct cbe_iic_thread_regs));
	BUG_ON(iic->regs == NULL);

	iic->target_id = ((hw_cpu & 2) << 3) | ((hw_cpu & 1) ? 0xf : 0xe);
	iic->eoi_stack[0] = 0xff;
	iic->node = of_node_get(node);
	out_be64(&iic->regs->prio, 0);

	printk(KERN_INFO "IIC for CPU %d target id 0x%x : %s\n",
	       hw_cpu, iic->target_id, node->full_name);
}

static int __init setup_iic(void)
{
	struct device_node *dn;
	struct resource r0, r1;
	unsigned int node, cascade, found = 0;
	struct cbe_iic_regs __iomem *node_iic;
	const u32 *np;

	for (dn = NULL;
	     (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
		if (!of_device_is_compatible(dn,
				     "IBM,CBEA-Internal-Interrupt-Controller"))
			continue;
		np = of_get_property(dn, "ibm,interrupt-server-ranges", NULL);
		if (np == NULL) {
			printk(KERN_WARNING "IIC: CPU association not found\n");
			of_node_put(dn);
			return -ENODEV;
		}
		if (of_address_to_resource(dn, 0, &r0) ||
		    of_address_to_resource(dn, 1, &r1)) {
			printk(KERN_WARNING "IIC: Can't resolve addresses\n");
			of_node_put(dn);
			return -ENODEV;
		}
		found++;
		init_one_iic(np[0], r0.start, dn);
		init_one_iic(np[1], r1.start, dn);

		/* Setup cascade for IO exceptions. XXX cleanup tricks to get
		 * node vs CPU etc...
		 * Note that we configure the IIC_IRR here with a hard coded
		 * priority of 1. We might want to improve that later.
		 */
		node = np[0] >> 1;
		node_iic = cbe_get_cpu_iic_regs(np[0]);
		cascade = node << IIC_IRQ_NODE_SHIFT;
		cascade |= 1 << IIC_IRQ_CLASS_SHIFT;
		cascade |= IIC_UNIT_IIC;
		cascade = irq_create_mapping(iic_host, cascade);
		if (cascade == NO_IRQ)
			continue;
		/*
		 * irq_data is a generic pointer that gets passed back
		 * to us later, so the forced cast is fine.
		 */
		irq_set_handler_data(cascade, (void __force *)node_iic);
		irq_set_chained_handler(cascade, iic_ioexc_cascade);
		out_be64(&node_iic->iic_ir,
			 (1 << 12)		/* priority */ |
			 (node << 4)		/* dest node */ |
			 IIC_UNIT_THREAD_0	/* route them to thread 0 */);
		/* Flush pending (make sure it triggers if there is
		 * anything pending
		 */
		out_be64(&node_iic->iic_is, 0xfffffffffffffffful);
	}

	if (found)
		return 0;
	else
		return -ENODEV;
}

void __init iic_init_IRQ(void)
{
	/* Setup an irq host data structure */
	iic_host = irq_domain_add_linear(NULL, IIC_SOURCE_COUNT, &iic_host_ops,
					 NULL);
	BUG_ON(iic_host == NULL);
	irq_set_default_host(iic_host);

	/* Discover and initialize iics */
	if (setup_iic() < 0)
		panic("IIC: Failed to initialize !\n");

	/* Set master interrupt handling function */
	ppc_md.get_irq = iic_get_irq;

	/* Enable on current CPU */
	iic_setup_cpu();
}

void iic_set_interrupt_routing(int cpu, int thread, int priority)
{
	struct cbe_iic_regs __iomem *iic_regs = cbe_get_cpu_iic_regs(cpu);
	u64 iic_ir = 0;
	int node = cpu >> 1;

	/* Set which node and thread will handle the next interrupt */
	iic_ir |= CBE_IIC_IR_PRIO(priority) |
		  CBE_IIC_IR_DEST_NODE(node);
	if (thread == 0)
		iic_ir |= CBE_IIC_IR_DEST_UNIT(CBE_IIC_IR_PT_0);
	else
		iic_ir |= CBE_IIC_IR_DEST_UNIT(CBE_IIC_IR_PT_1);
	out_be64(&iic_regs->iic_ir, iic_ir);
}
