/*
 *  CLPS711X IRQ driver
 *
 *  Copyright (C) 2013 Alexander Shiyan <shc_work@mail.ru>
 *
 * 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/io.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqdomain.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/slab.h>

#include <asm/exception.h>
#include <asm/mach/irq.h>

#define CLPS711X_INTSR1	(0x0240)
#define CLPS711X_INTMR1	(0x0280)
#define CLPS711X_BLEOI	(0x0600)
#define CLPS711X_MCEOI	(0x0640)
#define CLPS711X_TEOI	(0x0680)
#define CLPS711X_TC1EOI	(0x06c0)
#define CLPS711X_TC2EOI	(0x0700)
#define CLPS711X_RTCEOI	(0x0740)
#define CLPS711X_UMSEOI	(0x0780)
#define CLPS711X_COEOI	(0x07c0)
#define CLPS711X_INTSR2	(0x1240)
#define CLPS711X_INTMR2	(0x1280)
#define CLPS711X_SRXEOF	(0x1600)
#define CLPS711X_KBDEOI	(0x1700)
#define CLPS711X_INTSR3	(0x2240)
#define CLPS711X_INTMR3	(0x2280)

static const struct {
#define CLPS711X_FLAG_EN	(1 << 0)
#define CLPS711X_FLAG_FIQ	(1 << 1)
	unsigned int	flags;
	phys_addr_t	eoi;
} clps711x_irqs[] = {
	[1]	= { CLPS711X_FLAG_FIQ, CLPS711X_BLEOI, },
	[3]	= { CLPS711X_FLAG_FIQ, CLPS711X_MCEOI, },
	[4]	= { CLPS711X_FLAG_EN, CLPS711X_COEOI, },
	[5]	= { CLPS711X_FLAG_EN, },
	[6]	= { CLPS711X_FLAG_EN, },
	[7]	= { CLPS711X_FLAG_EN, },
	[8]	= { CLPS711X_FLAG_EN, CLPS711X_TC1EOI, },
	[9]	= { CLPS711X_FLAG_EN, CLPS711X_TC2EOI, },
	[10]	= { CLPS711X_FLAG_EN, CLPS711X_RTCEOI, },
	[11]	= { CLPS711X_FLAG_EN, CLPS711X_TEOI, },
	[12]	= { CLPS711X_FLAG_EN, },
	[13]	= { CLPS711X_FLAG_EN, },
	[14]	= { CLPS711X_FLAG_EN, CLPS711X_UMSEOI, },
	[15]	= { CLPS711X_FLAG_EN, CLPS711X_SRXEOF, },
	[16]	= { CLPS711X_FLAG_EN, CLPS711X_KBDEOI, },
	[17]	= { CLPS711X_FLAG_EN, },
	[18]	= { CLPS711X_FLAG_EN, },
	[28]	= { CLPS711X_FLAG_EN, },
	[29]	= { CLPS711X_FLAG_EN, },
	[32]	= { CLPS711X_FLAG_FIQ, },
};

static struct {
	void __iomem		*base;
	void __iomem		*intmr[3];
	void __iomem		*intsr[3];
	struct irq_domain	*domain;
	struct irq_domain_ops	ops;
} *clps711x_intc;

static asmlinkage void __exception_irq_entry clps711x_irqh(struct pt_regs *regs)
{
	u32 irqstat;

	do {
		irqstat = readw_relaxed(clps711x_intc->intmr[0]) &
			  readw_relaxed(clps711x_intc->intsr[0]);
		if (irqstat)
			handle_domain_irq(clps711x_intc->domain,
					  fls(irqstat) - 1, regs);

		irqstat = readw_relaxed(clps711x_intc->intmr[1]) &
			  readw_relaxed(clps711x_intc->intsr[1]);
		if (irqstat)
			handle_domain_irq(clps711x_intc->domain,
					  fls(irqstat) - 1 + 16, regs);
	} while (irqstat);
}

static void clps711x_intc_eoi(struct irq_data *d)
{
	irq_hw_number_t hwirq = irqd_to_hwirq(d);

	writel_relaxed(0, clps711x_intc->base + clps711x_irqs[hwirq].eoi);
}

static void clps711x_intc_mask(struct irq_data *d)
{
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	void __iomem *intmr = clps711x_intc->intmr[hwirq / 16];
	u32 tmp;

	tmp = readl_relaxed(intmr);
	tmp &= ~(1 << (hwirq % 16));
	writel_relaxed(tmp, intmr);
}

static void clps711x_intc_unmask(struct irq_data *d)
{
	irq_hw_number_t hwirq = irqd_to_hwirq(d);
	void __iomem *intmr = clps711x_intc->intmr[hwirq / 16];
	u32 tmp;

	tmp = readl_relaxed(intmr);
	tmp |= 1 << (hwirq % 16);
	writel_relaxed(tmp, intmr);
}

static struct irq_chip clps711x_intc_chip = {
	.name		= "clps711x-intc",
	.irq_eoi	= clps711x_intc_eoi,
	.irq_mask	= clps711x_intc_mask,
	.irq_unmask	= clps711x_intc_unmask,
};

static int __init clps711x_intc_irq_map(struct irq_domain *h, unsigned int virq,
					irq_hw_number_t hw)
{
	irq_flow_handler_t handler = handle_level_irq;
	unsigned int flags = 0;

	if (!clps711x_irqs[hw].flags)
		return 0;

	if (clps711x_irqs[hw].flags & CLPS711X_FLAG_FIQ) {
		handler = handle_bad_irq;
		flags |= IRQ_NOAUTOEN;
	} else if (clps711x_irqs[hw].eoi) {
		handler = handle_fasteoi_irq;
	}

	/* Clear down pending interrupt */
	if (clps711x_irqs[hw].eoi)
		writel_relaxed(0, clps711x_intc->base + clps711x_irqs[hw].eoi);

	irq_set_chip_and_handler(virq, &clps711x_intc_chip, handler);
	irq_modify_status(virq, IRQ_NOPROBE, flags);

	return 0;
}

static int __init _clps711x_intc_init(struct device_node *np,
				      phys_addr_t base, resource_size_t size)
{
	int err;

	clps711x_intc = kzalloc(sizeof(*clps711x_intc), GFP_KERNEL);
	if (!clps711x_intc)
		return -ENOMEM;

	clps711x_intc->base = ioremap(base, size);
	if (!clps711x_intc->base) {
		err = -ENOMEM;
		goto out_kfree;
	}

	clps711x_intc->intsr[0] = clps711x_intc->base + CLPS711X_INTSR1;
	clps711x_intc->intmr[0] = clps711x_intc->base + CLPS711X_INTMR1;
	clps711x_intc->intsr[1] = clps711x_intc->base + CLPS711X_INTSR2;
	clps711x_intc->intmr[1] = clps711x_intc->base + CLPS711X_INTMR2;
	clps711x_intc->intsr[2] = clps711x_intc->base + CLPS711X_INTSR3;
	clps711x_intc->intmr[2] = clps711x_intc->base + CLPS711X_INTMR3;

	/* Mask all interrupts */
	writel_relaxed(0, clps711x_intc->intmr[0]);
	writel_relaxed(0, clps711x_intc->intmr[1]);
	writel_relaxed(0, clps711x_intc->intmr[2]);

	err = irq_alloc_descs(-1, 0, ARRAY_SIZE(clps711x_irqs), numa_node_id());
	if (err < 0)
		goto out_iounmap;

	clps711x_intc->ops.map = clps711x_intc_irq_map;
	clps711x_intc->ops.xlate = irq_domain_xlate_onecell;
	clps711x_intc->domain =
		irq_domain_add_legacy(np, ARRAY_SIZE(clps711x_irqs),
				      0, 0, &clps711x_intc->ops, NULL);
	if (!clps711x_intc->domain) {
		err = -ENOMEM;
		goto out_irqfree;
	}

	irq_set_default_host(clps711x_intc->domain);
	set_handle_irq(clps711x_irqh);

#ifdef CONFIG_FIQ
	init_FIQ(0);
#endif

	return 0;

out_irqfree:
	irq_free_descs(0, ARRAY_SIZE(clps711x_irqs));

out_iounmap:
	iounmap(clps711x_intc->base);

out_kfree:
	kfree(clps711x_intc);

	return err;
}

void __init clps711x_intc_init(phys_addr_t base, resource_size_t size)
{
	BUG_ON(_clps711x_intc_init(NULL, base, size));
}

#ifdef CONFIG_IRQCHIP
static int __init clps711x_intc_init_dt(struct device_node *np,
					struct device_node *parent)
{
	struct resource res;
	int err;

	err = of_address_to_resource(np, 0, &res);
	if (err)
		return err;

	return _clps711x_intc_init(np, res.start, resource_size(&res));
}
IRQCHIP_DECLARE(clps711x, "cirrus,ep7209-intc", clps711x_intc_init_dt);
#endif
