/*
 * arch/arm/mach-orion5x/irq.c
 *
 * Core IRQ functions for Marvell Orion System On Chip
 *
 * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2.  This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <mach/orion5x.h>
#include <plat/irq.h>
#include "common.h"

/*****************************************************************************
 * Orion GPIO IRQ
 *
 * GPIO_IN_POL register controlls whether GPIO_DATA_IN will hold the same
 * value of the line or the opposite value.
 *
 * Level IRQ handlers: DATA_IN is used directly as cause register.
 *                     Interrupt are masked by LEVEL_MASK registers.
 * Edge IRQ handlers:  Change in DATA_IN are latched in EDGE_CAUSE.
 *                     Interrupt are masked by EDGE_MASK registers.
 * Both-edge handlers: Similar to regular Edge handlers, but also swaps
 *                     the polarity to catch the next line transaction.
 *                     This is a race condition that might not perfectly
 *                     work on some use cases.
 *
 * Every eight GPIO lines are grouped (OR'ed) before going up to main
 * cause register.
 *
 *                    EDGE  cause    mask
 *        data-in   /--------| |-----| |----\
 *     -----| |-----                         ---- to main cause reg
 *           X      \----------------| |----/
 *        polarity    LEVEL          mask
 *
 ****************************************************************************/
static void orion5x_gpio_irq_ack(u32 irq)
{
	int pin = irq_to_gpio(irq);
	if (irq_desc[irq].status & IRQ_LEVEL)
		/*
		 * Mask bit for level interrupt
		 */
		orion5x_clrbits(GPIO_LEVEL_MASK, 1 << pin);
	else
		/*
		 * Clear casue bit for egde interrupt
		 */
		orion5x_clrbits(GPIO_EDGE_CAUSE, 1 << pin);
}

static void orion5x_gpio_irq_mask(u32 irq)
{
	int pin = irq_to_gpio(irq);
	if (irq_desc[irq].status & IRQ_LEVEL)
		orion5x_clrbits(GPIO_LEVEL_MASK, 1 << pin);
	else
		orion5x_clrbits(GPIO_EDGE_MASK, 1 << pin);
}

static void orion5x_gpio_irq_unmask(u32 irq)
{
	int pin = irq_to_gpio(irq);
	if (irq_desc[irq].status & IRQ_LEVEL)
		orion5x_setbits(GPIO_LEVEL_MASK, 1 << pin);
	else
		orion5x_setbits(GPIO_EDGE_MASK, 1 << pin);
}

static int orion5x_gpio_set_irq_type(u32 irq, u32 type)
{
	int pin = irq_to_gpio(irq);
	struct irq_desc *desc;

	if ((readl(GPIO_IO_CONF) & (1 << pin)) == 0) {
		printk(KERN_ERR "orion5x_gpio_set_irq_type failed "
				"(irq %d, pin %d).\n", irq, pin);
		return -EINVAL;
	}

	desc = irq_desc + irq;

	switch (type) {
	case IRQ_TYPE_LEVEL_HIGH:
		desc->handle_irq = handle_level_irq;
		desc->status |= IRQ_LEVEL;
		orion5x_clrbits(GPIO_IN_POL, (1 << pin));
		break;
	case IRQ_TYPE_LEVEL_LOW:
		desc->handle_irq = handle_level_irq;
		desc->status |= IRQ_LEVEL;
		orion5x_setbits(GPIO_IN_POL, (1 << pin));
		break;
	case IRQ_TYPE_EDGE_RISING:
		desc->handle_irq = handle_edge_irq;
		desc->status &= ~IRQ_LEVEL;
		orion5x_clrbits(GPIO_IN_POL, (1 << pin));
		break;
	case IRQ_TYPE_EDGE_FALLING:
		desc->handle_irq = handle_edge_irq;
		desc->status &= ~IRQ_LEVEL;
		orion5x_setbits(GPIO_IN_POL, (1 << pin));
		break;
	case IRQ_TYPE_EDGE_BOTH:
		desc->handle_irq = handle_edge_irq;
		desc->status &= ~IRQ_LEVEL;
		/*
		 * set initial polarity based on current input level
		 */
		if ((readl(GPIO_IN_POL) ^ readl(GPIO_DATA_IN))
		    & (1 << pin))
			orion5x_setbits(GPIO_IN_POL, (1 << pin)); /* falling */
		else
			orion5x_clrbits(GPIO_IN_POL, (1 << pin)); /* rising */

		break;
	default:
		printk(KERN_ERR "failed to set irq=%d (type=%d)\n", irq, type);
		return -EINVAL;
	}

	desc->status &= ~IRQ_TYPE_SENSE_MASK;
	desc->status |= type & IRQ_TYPE_SENSE_MASK;

	return 0;
}

static struct irq_chip orion5x_gpio_irq_chip = {
	.name		= "Orion-IRQ-GPIO",
	.ack		= orion5x_gpio_irq_ack,
	.mask		= orion5x_gpio_irq_mask,
	.unmask		= orion5x_gpio_irq_unmask,
	.set_type	= orion5x_gpio_set_irq_type,
};

static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
	u32 cause, offs, pin;

	BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31);
	offs = (irq - IRQ_ORION5X_GPIO_0_7) * 8;
	cause = (readl(GPIO_DATA_IN) & readl(GPIO_LEVEL_MASK)) |
		(readl(GPIO_EDGE_CAUSE) & readl(GPIO_EDGE_MASK));

	for (pin = offs; pin < offs + 8; pin++) {
		if (cause & (1 << pin)) {
			irq = gpio_to_irq(pin);
			desc = irq_desc + irq;
			if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
				/* Swap polarity (race with GPIO line) */
				u32 polarity = readl(GPIO_IN_POL);
				polarity ^= 1 << pin;
				writel(polarity, GPIO_IN_POL);
			}
			desc_handle_irq(irq, desc);
		}
	}
}

static void __init orion5x_init_gpio_irq(void)
{
	int i;
	struct irq_desc *desc;

	/*
	 * Mask and clear GPIO IRQ interrupts
	 */
	writel(0x0, GPIO_LEVEL_MASK);
	writel(0x0, GPIO_EDGE_MASK);
	writel(0x0, GPIO_EDGE_CAUSE);

	/*
	 * Register chained level handlers for GPIO IRQs by default.
	 * User can use set_type() if he wants to use edge types handlers.
	 */
	for (i = IRQ_ORION5X_GPIO_START; i < NR_IRQS; i++) {
		set_irq_chip(i, &orion5x_gpio_irq_chip);
		set_irq_handler(i, handle_level_irq);
		desc = irq_desc + i;
		desc->status |= IRQ_LEVEL;
		set_irq_flags(i, IRQF_VALID);
	}
	set_irq_chained_handler(IRQ_ORION5X_GPIO_0_7, orion5x_gpio_irq_handler);
	set_irq_chained_handler(IRQ_ORION5X_GPIO_8_15, orion5x_gpio_irq_handler);
	set_irq_chained_handler(IRQ_ORION5X_GPIO_16_23, orion5x_gpio_irq_handler);
	set_irq_chained_handler(IRQ_ORION5X_GPIO_24_31, orion5x_gpio_irq_handler);
}

/*****************************************************************************
 * Orion Main IRQ
 ****************************************************************************/
static void __init orion5x_init_main_irq(void)
{
	orion_irq_init(0, (void __iomem *)MAIN_IRQ_MASK);
}

void __init orion5x_init_irq(void)
{
	orion5x_init_main_irq();
	orion5x_init_gpio_irq();
}
