/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
 */

#include <linux/io.h>
#include <linux/bitops.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>

#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>

#include "common.h"

/* INTC register offsets */
#define INTC_REG_STATUS0	0x00
#define INTC_REG_STATUS1	0x04
#define INTC_REG_TYPE		0x20
#define INTC_REG_RAW_STATUS	0x30
#define INTC_REG_ENABLE		0x34
#define INTC_REG_DISABLE	0x38

#define INTC_INT_GLOBAL		BIT(31)

#define RALINK_CPU_IRQ_INTC	(MIPS_CPU_IRQ_BASE + 2)
#define RALINK_CPU_IRQ_PCI	(MIPS_CPU_IRQ_BASE + 4)
#define RALINK_CPU_IRQ_FE	(MIPS_CPU_IRQ_BASE + 5)
#define RALINK_CPU_IRQ_WIFI	(MIPS_CPU_IRQ_BASE + 6)
#define RALINK_CPU_IRQ_COUNTER	(MIPS_CPU_IRQ_BASE + 7)

/* we have a cascade of 8 irqs */
#define RALINK_INTC_IRQ_BASE	8

/* we have 32 SoC irqs */
#define RALINK_INTC_IRQ_COUNT	32

#define RALINK_INTC_IRQ_PERFC   (RALINK_INTC_IRQ_BASE + 9)

static void __iomem *rt_intc_membase;

static inline void rt_intc_w32(u32 val, unsigned reg)
{
	__raw_writel(val, rt_intc_membase + reg);
}

static inline u32 rt_intc_r32(unsigned reg)
{
	return __raw_readl(rt_intc_membase + reg);
}

static void ralink_intc_irq_unmask(struct irq_data *d)
{
	rt_intc_w32(BIT(d->hwirq), INTC_REG_ENABLE);
}

static void ralink_intc_irq_mask(struct irq_data *d)
{
	rt_intc_w32(BIT(d->hwirq), INTC_REG_DISABLE);
}

static struct irq_chip ralink_intc_irq_chip = {
	.name		= "INTC",
	.irq_unmask	= ralink_intc_irq_unmask,
	.irq_mask	= ralink_intc_irq_mask,
	.irq_mask_ack	= ralink_intc_irq_mask,
};

unsigned int __cpuinit get_c0_compare_int(void)
{
	return CP0_LEGACY_COMPARE_IRQ;
}

static void ralink_intc_irq_handler(unsigned int irq, struct irq_desc *desc)
{
	u32 pending = rt_intc_r32(INTC_REG_STATUS0);

	if (pending) {
		struct irq_domain *domain = irq_get_handler_data(irq);
		generic_handle_irq(irq_find_mapping(domain, __ffs(pending)));
	} else {
		spurious_interrupt();
	}
}

asmlinkage void plat_irq_dispatch(void)
{
	unsigned long pending;

	pending = read_c0_status() & read_c0_cause() & ST0_IM;

	if (pending & STATUSF_IP7)
		do_IRQ(RALINK_CPU_IRQ_COUNTER);

	else if (pending & STATUSF_IP5)
		do_IRQ(RALINK_CPU_IRQ_FE);

	else if (pending & STATUSF_IP6)
		do_IRQ(RALINK_CPU_IRQ_WIFI);

	else if (pending & STATUSF_IP4)
		do_IRQ(RALINK_CPU_IRQ_PCI);

	else if (pending & STATUSF_IP2)
		do_IRQ(RALINK_CPU_IRQ_INTC);

	else
		spurious_interrupt();
}

static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
{
	irq_set_chip_and_handler(irq, &ralink_intc_irq_chip, handle_level_irq);

	return 0;
}

static const struct irq_domain_ops irq_domain_ops = {
	.xlate = irq_domain_xlate_onecell,
	.map = intc_map,
};

static int __init intc_of_init(struct device_node *node,
			       struct device_node *parent)
{
	struct resource res;
	struct irq_domain *domain;
	int irq;

	irq = irq_of_parse_and_map(node, 0);
	if (!irq)
		panic("Failed to get INTC IRQ");

	if (of_address_to_resource(node, 0, &res))
		panic("Failed to get intc memory range");

	if (request_mem_region(res.start, resource_size(&res),
				res.name) < 0)
		pr_err("Failed to request intc memory");

	rt_intc_membase = ioremap_nocache(res.start,
					resource_size(&res));
	if (!rt_intc_membase)
		panic("Failed to remap intc memory");

	/* disable all interrupts */
	rt_intc_w32(~0, INTC_REG_DISABLE);

	/* route all INTC interrupts to MIPS HW0 interrupt */
	rt_intc_w32(0, INTC_REG_TYPE);

	domain = irq_domain_add_legacy(node, RALINK_INTC_IRQ_COUNT,
			RALINK_INTC_IRQ_BASE, 0, &irq_domain_ops, NULL);
	if (!domain)
		panic("Failed to add irqdomain");

	rt_intc_w32(INTC_INT_GLOBAL, INTC_REG_ENABLE);

	irq_set_chained_handler(irq, ralink_intc_irq_handler);
	irq_set_handler_data(irq, domain);

	/* tell the kernel which irq is used for performance monitoring */
	cp0_perfcount_irq = irq_create_mapping(domain, 9);

	return 0;
}

static struct of_device_id __initdata of_irq_ids[] = {
	{ .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init },
	{ .compatible = "ralink,rt2880-intc", .data = intc_of_init },
	{},
};

void __init arch_init_irq(void)
{
	of_irq_init(of_irq_ids);
}

