/*
 * linux/arch/arm/mach-omap2/irq.c
 *
 * Interrupt handler for OMAP2 boards.
 *
 * Copyright (C) 2005 Nokia Corporation
 * Author: Paul Mundt <paul.mundt@nokia.com>
 *
 * 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/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>

#include <asm/exception.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

/* Define these here for now until we drop all board-files */
#define OMAP24XX_IC_BASE	0x480fe000
#define OMAP34XX_IC_BASE	0x48200000

/* selected INTC register offsets */

#define INTC_REVISION		0x0000
#define INTC_SYSCONFIG		0x0010
#define INTC_SYSSTATUS		0x0014
#define INTC_SIR		0x0040
#define INTC_CONTROL		0x0048
#define INTC_PROTECTION		0x004C
#define INTC_IDLE		0x0050
#define INTC_THRESHOLD		0x0068
#define INTC_MIR0		0x0084
#define INTC_MIR_CLEAR0		0x0088
#define INTC_MIR_SET0		0x008c
#define INTC_PENDING_IRQ0	0x0098
#define INTC_PENDING_IRQ1	0x00b8
#define INTC_PENDING_IRQ2	0x00d8
#define INTC_PENDING_IRQ3	0x00f8
#define INTC_ILR0		0x0100

#define ACTIVEIRQ_MASK		0x7f	/* omap2/3 active interrupt bits */
#define SPURIOUSIRQ_MASK	(0x1ffffff << 7)
#define INTCPS_NR_ILR_REGS	128
#define INTCPS_NR_MIR_REGS	4

#define INTC_IDLE_FUNCIDLE	(1 << 0)
#define INTC_IDLE_TURBO		(1 << 1)

#define INTC_PROTECTION_ENABLE	(1 << 0)

struct omap_intc_regs {
	u32 sysconfig;
	u32 protection;
	u32 idle;
	u32 threshold;
	u32 ilr[INTCPS_NR_ILR_REGS];
	u32 mir[INTCPS_NR_MIR_REGS];
};
static struct omap_intc_regs intc_context;

static struct irq_domain *domain;
static void __iomem *omap_irq_base;
static int omap_nr_pending = 3;
static int omap_nr_irqs = 96;

static void intc_writel(u32 reg, u32 val)
{
	writel_relaxed(val, omap_irq_base + reg);
}

static u32 intc_readl(u32 reg)
{
	return readl_relaxed(omap_irq_base + reg);
}

void omap_intc_save_context(void)
{
	int i;

	intc_context.sysconfig =
		intc_readl(INTC_SYSCONFIG);
	intc_context.protection =
		intc_readl(INTC_PROTECTION);
	intc_context.idle =
		intc_readl(INTC_IDLE);
	intc_context.threshold =
		intc_readl(INTC_THRESHOLD);

	for (i = 0; i < omap_nr_irqs; i++)
		intc_context.ilr[i] =
			intc_readl((INTC_ILR0 + 0x4 * i));
	for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
		intc_context.mir[i] =
			intc_readl(INTC_MIR0 + (0x20 * i));
}

void omap_intc_restore_context(void)
{
	int i;

	intc_writel(INTC_SYSCONFIG, intc_context.sysconfig);
	intc_writel(INTC_PROTECTION, intc_context.protection);
	intc_writel(INTC_IDLE, intc_context.idle);
	intc_writel(INTC_THRESHOLD, intc_context.threshold);

	for (i = 0; i < omap_nr_irqs; i++)
		intc_writel(INTC_ILR0 + 0x4 * i,
				intc_context.ilr[i]);

	for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
		intc_writel(INTC_MIR0 + 0x20 * i,
			intc_context.mir[i]);
	/* MIRs are saved and restore with other PRCM registers */
}

void omap3_intc_prepare_idle(void)
{
	/*
	 * Disable autoidle as it can stall interrupt controller,
	 * cf. errata ID i540 for 3430 (all revisions up to 3.1.x)
	 */
	intc_writel(INTC_SYSCONFIG, 0);
	intc_writel(INTC_IDLE, INTC_IDLE_TURBO);
}

void omap3_intc_resume_idle(void)
{
	/* Re-enable autoidle */
	intc_writel(INTC_SYSCONFIG, 1);
	intc_writel(INTC_IDLE, 0);
}

/* XXX: FIQ and additional INTC support (only MPU at the moment) */
static void omap_ack_irq(struct irq_data *d)
{
	intc_writel(INTC_CONTROL, 0x1);
}

static void omap_mask_ack_irq(struct irq_data *d)
{
	irq_gc_mask_disable_reg(d);
	omap_ack_irq(d);
}

static void __init omap_irq_soft_reset(void)
{
	unsigned long tmp;

	tmp = intc_readl(INTC_REVISION) & 0xff;

	pr_info("IRQ: Found an INTC at 0x%p (revision %ld.%ld) with %d interrupts\n",
		omap_irq_base, tmp >> 4, tmp & 0xf, omap_nr_irqs);

	tmp = intc_readl(INTC_SYSCONFIG);
	tmp |= 1 << 1;	/* soft reset */
	intc_writel(INTC_SYSCONFIG, tmp);

	while (!(intc_readl(INTC_SYSSTATUS) & 0x1))
		/* Wait for reset to complete */;

	/* Enable autoidle */
	intc_writel(INTC_SYSCONFIG, 1 << 0);
}

int omap_irq_pending(void)
{
	int i;

	for (i = 0; i < omap_nr_pending; i++)
		if (intc_readl(INTC_PENDING_IRQ0 + (0x20 * i)))
			return 1;
	return 0;
}

void omap3_intc_suspend(void)
{
	/* A pending interrupt would prevent OMAP from entering suspend */
	omap_ack_irq(NULL);
}

static int __init omap_alloc_gc_of(struct irq_domain *d, void __iomem *base)
{
	int ret;
	int i;

	ret = irq_alloc_domain_generic_chips(d, 32, 1, "INTC",
			handle_level_irq, IRQ_NOREQUEST | IRQ_NOPROBE,
			IRQ_LEVEL, 0);
	if (ret) {
		pr_warn("Failed to allocate irq chips\n");
		return ret;
	}

	for (i = 0; i < omap_nr_pending; i++) {
		struct irq_chip_generic *gc;
		struct irq_chip_type *ct;

		gc = irq_get_domain_generic_chip(d, 32 * i);
		gc->reg_base = base;
		ct = gc->chip_types;

		ct->type = IRQ_TYPE_LEVEL_MASK;
		ct->handler = handle_level_irq;

		ct->chip.irq_ack = omap_mask_ack_irq;
		ct->chip.irq_mask = irq_gc_mask_disable_reg;
		ct->chip.irq_unmask = irq_gc_unmask_enable_reg;

		ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE;

		ct->regs.enable = INTC_MIR_CLEAR0 + 32 * i;
		ct->regs.disable = INTC_MIR_SET0 + 32 * i;
	}

	return 0;
}

static void __init omap_alloc_gc_legacy(void __iomem *base,
		unsigned int irq_start, unsigned int num)
{
	struct irq_chip_generic *gc;
	struct irq_chip_type *ct;

	gc = irq_alloc_generic_chip("INTC", 1, irq_start, base,
			handle_level_irq);
	ct = gc->chip_types;
	ct->chip.irq_ack = omap_mask_ack_irq;
	ct->chip.irq_mask = irq_gc_mask_disable_reg;
	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
	ct->chip.flags |= IRQCHIP_SKIP_SET_WAKE;

	ct->regs.enable = INTC_MIR_CLEAR0;
	ct->regs.disable = INTC_MIR_SET0;
	irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
			IRQ_NOREQUEST | IRQ_NOPROBE, 0);
}

static int __init omap_init_irq_of(struct device_node *node)
{
	int ret;

	omap_irq_base = of_iomap(node, 0);
	if (WARN_ON(!omap_irq_base))
		return -ENOMEM;

	domain = irq_domain_add_linear(node, omap_nr_irqs,
			&irq_generic_chip_ops, NULL);

	omap_irq_soft_reset();

	ret = omap_alloc_gc_of(domain, omap_irq_base);
	if (ret < 0)
		irq_domain_remove(domain);

	return ret;
}

static int __init omap_init_irq_legacy(u32 base, struct device_node *node)
{
	int j, irq_base;

	omap_irq_base = ioremap(base, SZ_4K);
	if (WARN_ON(!omap_irq_base))
		return -ENOMEM;

	irq_base = irq_alloc_descs(-1, 0, omap_nr_irqs, 0);
	if (irq_base < 0) {
		pr_warn("Couldn't allocate IRQ numbers\n");
		irq_base = 0;
	}

	domain = irq_domain_add_legacy(node, omap_nr_irqs, irq_base, 0,
			&irq_domain_simple_ops, NULL);

	omap_irq_soft_reset();

	for (j = 0; j < omap_nr_irqs; j += 32)
		omap_alloc_gc_legacy(omap_irq_base + j, j + irq_base, 32);

	return 0;
}

static void __init omap_irq_enable_protection(void)
{
	u32 reg;

	reg = intc_readl(INTC_PROTECTION);
	reg |= INTC_PROTECTION_ENABLE;
	intc_writel(INTC_PROTECTION, reg);
}

static int __init omap_init_irq(u32 base, struct device_node *node)
{
	int ret;

	/*
	 * FIXME legacy OMAP DMA driver sitting under arch/arm/plat-omap/dma.c
	 * depends is still not ready for linear IRQ domains; because of that
	 * we need to temporarily "blacklist" OMAP2 and OMAP3 devices from using
	 * linear IRQ Domain until that driver is finally fixed.
	 */
	if (of_device_is_compatible(node, "ti,omap2-intc") ||
			of_device_is_compatible(node, "ti,omap3-intc")) {
		struct resource res;

		if (of_address_to_resource(node, 0, &res))
			return -ENOMEM;

		base = res.start;
		ret = omap_init_irq_legacy(base, node);
	} else if (node) {
		ret = omap_init_irq_of(node);
	} else {
		ret = omap_init_irq_legacy(base, NULL);
	}

	if (ret == 0)
		omap_irq_enable_protection();

	return ret;
}

static asmlinkage void __exception_irq_entry
omap_intc_handle_irq(struct pt_regs *regs)
{
	extern unsigned long irq_err_count;
	u32 irqnr;

	irqnr = intc_readl(INTC_SIR);

	/*
	 * A spurious IRQ can result if interrupt that triggered the
	 * sorting is no longer active during the sorting (10 INTC
	 * functional clock cycles after interrupt assertion). Or a
	 * change in interrupt mask affected the result during sorting
	 * time. There is no special handling required except ignoring
	 * the SIR register value just read and retrying.
	 * See section 6.2.5 of AM335x TRM Literature Number: SPRUH73K
	 *
	 * Many a times, a spurious interrupt situation has been fixed
	 * by adding a flush for the posted write acking the IRQ in
	 * the device driver. Typically, this is going be the device
	 * driver whose interrupt was handled just before the spurious
	 * IRQ occurred. Pay attention to those device drivers if you
	 * run into hitting the spurious IRQ condition below.
	 */
	if (unlikely((irqnr & SPURIOUSIRQ_MASK) == SPURIOUSIRQ_MASK)) {
		pr_err_once("%s: spurious irq!\n", __func__);
		irq_err_count++;
		omap_ack_irq(NULL);
		return;
	}

	irqnr &= ACTIVEIRQ_MASK;
	handle_domain_irq(domain, irqnr, regs);
}

void __init omap3_init_irq(void)
{
	omap_nr_irqs = 96;
	omap_nr_pending = 3;
	omap_init_irq(OMAP34XX_IC_BASE, NULL);
	set_handle_irq(omap_intc_handle_irq);
}

static int __init intc_of_init(struct device_node *node,
			     struct device_node *parent)
{
	int ret;

	omap_nr_pending = 3;
	omap_nr_irqs = 96;

	if (WARN_ON(!node))
		return -ENODEV;

	if (of_device_is_compatible(node, "ti,dm814-intc") ||
	    of_device_is_compatible(node, "ti,dm816-intc") ||
	    of_device_is_compatible(node, "ti,am33xx-intc")) {
		omap_nr_irqs = 128;
		omap_nr_pending = 4;
	}

	ret = omap_init_irq(-1, of_node_get(node));
	if (ret < 0)
		return ret;

	set_handle_irq(omap_intc_handle_irq);

	return 0;
}

IRQCHIP_DECLARE(omap2_intc, "ti,omap2-intc", intc_of_init);
IRQCHIP_DECLARE(omap3_intc, "ti,omap3-intc", intc_of_init);
IRQCHIP_DECLARE(dm814x_intc, "ti,dm814-intc", intc_of_init);
IRQCHIP_DECLARE(dm816x_intc, "ti,dm816-intc", intc_of_init);
IRQCHIP_DECLARE(am33xx_intc, "ti,am33xx-intc", intc_of_init);
