/*
 * 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 <asm/plat-orion/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();
}
