/*
 * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
 * Copyright (C) 2012-2013 Xilinx, Inc.
 * Copyright (C) 2007-2009 PetaLogix
 * Copyright (C) 2006 Atmark Techno, Inc.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License. See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/irqdomain.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/bug.h>

static void __iomem *intc_baseaddr;

/* No one else should require these constants, so define them locally here. */
#define ISR 0x00			/* Interrupt Status Register */
#define IPR 0x04			/* Interrupt Pending Register */
#define IER 0x08			/* Interrupt Enable Register */
#define IAR 0x0c			/* Interrupt Acknowledge Register */
#define SIE 0x10			/* Set Interrupt Enable bits */
#define CIE 0x14			/* Clear Interrupt Enable bits */
#define IVR 0x18			/* Interrupt Vector Register */
#define MER 0x1c			/* Master Enable Register */

#define MER_ME (1<<0)
#define MER_HIE (1<<1)

static unsigned int (*read_fn)(void __iomem *);
static void (*write_fn)(u32, void __iomem *);

static void intc_write32(u32 val, void __iomem *addr)
{
	iowrite32(val, addr);
}

static unsigned int intc_read32(void __iomem *addr)
{
	return ioread32(addr);
}

static void intc_write32_be(u32 val, void __iomem *addr)
{
	iowrite32be(val, addr);
}

static unsigned int intc_read32_be(void __iomem *addr)
{
	return ioread32be(addr);
}

static void intc_enable_or_unmask(struct irq_data *d)
{
	unsigned long mask = 1 << d->hwirq;

	pr_debug("enable_or_unmask: %ld\n", d->hwirq);

	/* ack level irqs because they can't be acked during
	 * ack function since the handle_level_irq function
	 * acks the irq before calling the interrupt handler
	 */
	if (irqd_is_level_type(d))
		write_fn(mask, intc_baseaddr + IAR);

	write_fn(mask, intc_baseaddr + SIE);
}

static void intc_disable_or_mask(struct irq_data *d)
{
	pr_debug("disable: %ld\n", d->hwirq);
	write_fn(1 << d->hwirq, intc_baseaddr + CIE);
}

static void intc_ack(struct irq_data *d)
{
	pr_debug("ack: %ld\n", d->hwirq);
	write_fn(1 << d->hwirq, intc_baseaddr + IAR);
}

static void intc_mask_ack(struct irq_data *d)
{
	unsigned long mask = 1 << d->hwirq;

	pr_debug("disable_and_ack: %ld\n", d->hwirq);
	write_fn(mask, intc_baseaddr + CIE);
	write_fn(mask, intc_baseaddr + IAR);
}

static struct irq_chip intc_dev = {
	.name = "Xilinx INTC",
	.irq_unmask = intc_enable_or_unmask,
	.irq_mask = intc_disable_or_mask,
	.irq_ack = intc_ack,
	.irq_mask_ack = intc_mask_ack,
};

static struct irq_domain *root_domain;

unsigned int get_irq(void)
{
	unsigned int hwirq, irq = -1;

	hwirq = read_fn(intc_baseaddr + IVR);
	if (hwirq != -1U)
		irq = irq_find_mapping(root_domain, hwirq);

	pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);

	return irq;
}

static int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
{
	u32 intr_mask = (u32)d->host_data;

	if (intr_mask & (1 << hw)) {
		irq_set_chip_and_handler_name(irq, &intc_dev,
						handle_edge_irq, "edge");
		irq_clear_status_flags(irq, IRQ_LEVEL);
	} else {
		irq_set_chip_and_handler_name(irq, &intc_dev,
						handle_level_irq, "level");
		irq_set_status_flags(irq, IRQ_LEVEL);
	}
	return 0;
}

static const struct irq_domain_ops xintc_irq_domain_ops = {
	.xlate = irq_domain_xlate_onetwocell,
	.map = xintc_map,
};

static int __init xilinx_intc_of_init(struct device_node *intc,
					     struct device_node *parent)
{
	u32 nr_irq, intr_mask;
	int ret;

	intc_baseaddr = of_iomap(intc, 0);
	BUG_ON(!intc_baseaddr);

	ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
	if (ret < 0) {
		pr_err("%s: unable to read xlnx,num-intr-inputs\n", __func__);
		return ret;
	}

	ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
	if (ret < 0) {
		pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
		return ret;
	}

	if (intr_mask >> nr_irq)
		pr_warn("%s: mismatch in kind-of-intr param\n", __func__);

	pr_info("%s: num_irq=%d, edge=0x%x\n",
		intc->full_name, nr_irq, intr_mask);

	write_fn = intc_write32;
	read_fn = intc_read32;

	/*
	 * Disable all external interrupts until they are
	 * explicity requested.
	 */
	write_fn(0, intc_baseaddr + IER);

	/* Acknowledge any pending interrupts just in case. */
	write_fn(0xffffffff, intc_baseaddr + IAR);

	/* Turn on the Master Enable. */
	write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
	if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) {
		write_fn = intc_write32_be;
		read_fn = intc_read32_be;
		write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
	}

	/* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
	 * lazy and Michal can clean it up to something nicer when he tests
	 * and commits this patch.  ~~gcl */
	root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
							(void *)intr_mask);

	irq_set_default_host(root_domain);

	return 0;
}

IRQCHIP_DECLARE(xilinx_intc, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);
