/* linux/arch/arm/plat-s5p/irq-gpioint.c
 *
 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
 * Author: Kyungmin Park <kyungmin.park@samsung.com>
 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
 * Author: Marek Szyprowski <m.szyprowski@samsung.com>
 *
 *  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/kernel.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/slab.h>

#include <mach/map.h>
#include <plat/gpio-core.h>
#include <plat/gpio-cfg.h>

#define GPIO_BASE(chip)		(((unsigned long)(chip)->base) & 0xFFFFF000u)

#define CON_OFFSET		0x700
#define MASK_OFFSET		0x900
#define PEND_OFFSET		0xA00
#define REG_OFFSET(x)		((x) << 2)

struct s5p_gpioint_bank {
	struct list_head	list;
	int			start;
	int			nr_groups;
	int			irq;
	struct s3c_gpio_chip	**chips;
	void			(*handler)(unsigned int, struct irq_desc *);
};

LIST_HEAD(banks);

static int s5p_gpioint_get_offset(struct irq_data *data)
{
	struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
	return data->irq - chip->irq_base;
}

static void s5p_gpioint_ack(struct irq_data *data)
{
	struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
	int group, offset, pend_offset;
	unsigned int value;

	group = chip->group;
	offset = s5p_gpioint_get_offset(data);
	pend_offset = REG_OFFSET(group);

	value = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
	value |= BIT(offset);
	__raw_writel(value, GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
}

static void s5p_gpioint_mask(struct irq_data *data)
{
	struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
	int group, offset, mask_offset;
	unsigned int value;

	group = chip->group;
	offset = s5p_gpioint_get_offset(data);
	mask_offset = REG_OFFSET(group);

	value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
	value |= BIT(offset);
	__raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
}

static void s5p_gpioint_unmask(struct irq_data *data)
{
	struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
	int group, offset, mask_offset;
	unsigned int value;

	group = chip->group;
	offset = s5p_gpioint_get_offset(data);
	mask_offset = REG_OFFSET(group);

	value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
	value &= ~BIT(offset);
	__raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
}

static void s5p_gpioint_mask_ack(struct irq_data *data)
{
	s5p_gpioint_mask(data);
	s5p_gpioint_ack(data);
}

static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
{
	struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
	int group, offset, con_offset;
	unsigned int value;

	group = chip->group;
	offset = s5p_gpioint_get_offset(data);
	con_offset = REG_OFFSET(group);

	switch (type) {
	case IRQ_TYPE_EDGE_RISING:
		type = S5P_IRQ_TYPE_EDGE_RISING;
		break;
	case IRQ_TYPE_EDGE_FALLING:
		type = S5P_IRQ_TYPE_EDGE_FALLING;
		break;
	case IRQ_TYPE_EDGE_BOTH:
		type = S5P_IRQ_TYPE_EDGE_BOTH;
		break;
	case IRQ_TYPE_LEVEL_HIGH:
		type = S5P_IRQ_TYPE_LEVEL_HIGH;
		break;
	case IRQ_TYPE_LEVEL_LOW:
		type = S5P_IRQ_TYPE_LEVEL_LOW;
		break;
	case IRQ_TYPE_NONE:
	default:
		printk(KERN_WARNING "No irq type\n");
		return -EINVAL;
	}

	value = __raw_readl(GPIO_BASE(chip) + CON_OFFSET + con_offset);
	value &= ~(0x7 << (offset * 0x4));
	value |= (type << (offset * 0x4));
	__raw_writel(value, GPIO_BASE(chip) + CON_OFFSET + con_offset);

	return 0;
}

static struct irq_chip s5p_gpioint = {
	.name		= "s5p_gpioint",
	.irq_ack	= s5p_gpioint_ack,
	.irq_mask	= s5p_gpioint_mask,
	.irq_mask_ack	= s5p_gpioint_mask_ack,
	.irq_unmask	= s5p_gpioint_unmask,
	.irq_set_type	= s5p_gpioint_set_type,
};

static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
{
	struct s5p_gpioint_bank *bank = get_irq_data(irq);
	int group, pend_offset, mask_offset;
	unsigned int pend, mask;

	for (group = 0; group < bank->nr_groups; group++) {
		struct s3c_gpio_chip *chip = bank->chips[group];
		if (!chip)
			continue;

		pend_offset = REG_OFFSET(group);
		pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
		if (!pend)
			continue;

		mask_offset = REG_OFFSET(group);
		mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
		pend &= ~mask;

		while (pend) {
			int offset = fls(pend) - 1;
			int real_irq = chip->irq_base + offset;
			generic_handle_irq(real_irq);
			pend &= ~BIT(offset);
		}
	}
}

static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
{
	static int used_gpioint_groups = 0;
	int irq, group = chip->group;
	int i;
	struct s5p_gpioint_bank *bank = NULL;

	if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
		return -ENOMEM;

	list_for_each_entry(bank, &banks, list) {
		if (group >= bank->start &&
		    group < bank->start + bank->nr_groups)
			break;
	}
	if (!bank)
		return -EINVAL;

	if (!bank->handler) {
		bank->chips = kzalloc(sizeof(struct s3c_gpio_chip *) *
				      bank->nr_groups, GFP_KERNEL);
		if (!bank->chips)
			return -ENOMEM;

		set_irq_chained_handler(bank->irq, s5p_gpioint_handler);
		set_irq_data(bank->irq, bank);
		bank->handler = s5p_gpioint_handler;
		printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n",
		       bank->irq);
	}

	/*
	 * chained GPIO irq has been sucessfully registered, allocate new gpio
	 * int group and assign irq nubmers
	 */

	chip->irq_base = S5P_GPIOINT_BASE +
			 used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
	used_gpioint_groups++;

	bank->chips[group - bank->start] = chip;
	for (i = 0; i < chip->chip.ngpio; i++) {
		irq = chip->irq_base + i;
		set_irq_chip(irq, &s5p_gpioint);
		set_irq_data(irq, chip);
		set_irq_handler(irq, handle_level_irq);
		set_irq_flags(irq, IRQF_VALID);
	}
	return 0;
}

int __init s5p_register_gpio_interrupt(int pin)
{
	struct s3c_gpio_chip *my_chip = s3c_gpiolib_getchip(pin);
	int offset, group;
	int ret;

	if (!my_chip)
		return -EINVAL;

	offset = pin - my_chip->chip.base;
	group = my_chip->group;

	/* check if the group has been already registered */
	if (my_chip->irq_base)
		return my_chip->irq_base + offset;

	/* register gpio group */
	ret = s5p_gpioint_add(my_chip);
	if (ret == 0) {
		my_chip->chip.to_irq = samsung_gpiolib_to_irq;
		printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
		       group);
		return my_chip->irq_base + offset;
	}
	return ret;
}

int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups)
{
	struct s5p_gpioint_bank *bank;

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

	bank->start = start;
	bank->nr_groups = nr_groups;
	bank->irq = chain_irq;

	list_add_tail(&bank->list, &banks);
	return 0;
}
