/*
 *  linux/arch/arm/mach-mmp/irq-mmp2.c
 *
 *  Generic IRQ handling, GPIO IRQ demultiplexing, etc.
 *
 *  Author:	Haojian Zhuang <haojian.zhuang@marvell.com>
 *  Copyright:	Marvell International Ltd.
 *
 *  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.
 */

#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>

#include <mach/regs-icu.h>

#include "common.h"

static void icu_mask_irq(unsigned int irq)
{
	uint32_t r = __raw_readl(ICU_INT_CONF(irq));

	r &= ~ICU_INT_ROUTE_PJ4_IRQ;
	__raw_writel(r, ICU_INT_CONF(irq));
}

static void icu_unmask_irq(unsigned int irq)
{
	uint32_t r = __raw_readl(ICU_INT_CONF(irq));

	r |= ICU_INT_ROUTE_PJ4_IRQ;
	__raw_writel(r, ICU_INT_CONF(irq));
}

static struct irq_chip icu_irq_chip = {
	.name		= "icu_irq",
	.mask		= icu_mask_irq,
	.mask_ack	= icu_mask_irq,
	.unmask		= icu_unmask_irq,
};

static void pmic_irq_ack(unsigned int irq)
{
	if (irq == IRQ_MMP2_PMIC)
		mmp2_clear_pmic_int();
}

#define SECOND_IRQ_MASK(_name_, irq_base, prefix)			\
static void _name_##_mask_irq(unsigned int irq)				\
{									\
	uint32_t r;							\
	r = __raw_readl(prefix##_MASK) | (1 << (irq - irq_base));	\
	__raw_writel(r, prefix##_MASK);					\
}

#define SECOND_IRQ_UNMASK(_name_, irq_base, prefix)			\
static void _name_##_unmask_irq(unsigned int irq)			\
{									\
	uint32_t r;							\
	r = __raw_readl(prefix##_MASK) & ~(1 << (irq - irq_base));	\
	__raw_writel(r, prefix##_MASK);					\
}

#define SECOND_IRQ_DEMUX(_name_, irq_base, prefix)			\
static void _name_##_irq_demux(unsigned int irq, struct irq_desc *desc)	\
{									\
	unsigned long status, mask, n;					\
	mask = __raw_readl(prefix##_MASK);				\
	while (1) {							\
		status = __raw_readl(prefix##_STATUS) & ~mask;		\
		if (status == 0)					\
			break;						\
		n = find_first_bit(&status, BITS_PER_LONG);		\
		while (n < BITS_PER_LONG) {				\
			generic_handle_irq(irq_base + n);		\
			n = find_next_bit(&status, BITS_PER_LONG, n+1);	\
		}							\
	}								\
}

#define SECOND_IRQ_CHIP(_name_, irq_base, prefix)			\
SECOND_IRQ_MASK(_name_, irq_base, prefix)				\
SECOND_IRQ_UNMASK(_name_, irq_base, prefix)				\
SECOND_IRQ_DEMUX(_name_, irq_base, prefix)				\
static struct irq_chip _name_##_irq_chip = {				\
	.name		= #_name_,					\
	.mask		= _name_##_mask_irq,				\
	.unmask		= _name_##_unmask_irq,				\
}

SECOND_IRQ_CHIP(pmic, IRQ_MMP2_PMIC_BASE, MMP2_ICU_INT4);
SECOND_IRQ_CHIP(rtc,  IRQ_MMP2_RTC_BASE,  MMP2_ICU_INT5);
SECOND_IRQ_CHIP(twsi, IRQ_MMP2_TWSI_BASE, MMP2_ICU_INT17);
SECOND_IRQ_CHIP(misc, IRQ_MMP2_MISC_BASE, MMP2_ICU_INT35);
SECOND_IRQ_CHIP(ssp,  IRQ_MMP2_SSP_BASE,  MMP2_ICU_INT51);

static void init_mux_irq(struct irq_chip *chip, int start, int num)
{
	int irq;

	for (irq = start; num > 0; irq++, num--) {
		/* mask and clear the IRQ */
		chip->mask(irq);
		if (chip->ack)
			chip->ack(irq);

		set_irq_chip(irq, chip);
		set_irq_flags(irq, IRQF_VALID);
		set_irq_handler(irq, handle_level_irq);
	}
}

void __init mmp2_init_icu(void)
{
	int irq;

	for (irq = 0; irq < IRQ_MMP2_MUX_BASE; irq++) {
		icu_mask_irq(irq);
		set_irq_chip(irq, &icu_irq_chip);
		set_irq_flags(irq, IRQF_VALID);

		switch (irq) {
		case IRQ_MMP2_PMIC_MUX:
		case IRQ_MMP2_RTC_MUX:
		case IRQ_MMP2_TWSI_MUX:
		case IRQ_MMP2_MISC_MUX:
		case IRQ_MMP2_SSP_MUX:
			break;
		default:
			set_irq_handler(irq, handle_level_irq);
			break;
		}
	}

	/* NOTE: IRQ_MMP2_PMIC requires the PMIC MFPR register
	 * to be written to clear the interrupt
	 */
	pmic_irq_chip.ack = pmic_irq_ack;

	init_mux_irq(&pmic_irq_chip, IRQ_MMP2_PMIC_BASE, 2);
	init_mux_irq(&rtc_irq_chip, IRQ_MMP2_RTC_BASE, 2);
	init_mux_irq(&twsi_irq_chip, IRQ_MMP2_TWSI_BASE, 5);
	init_mux_irq(&misc_irq_chip, IRQ_MMP2_MISC_BASE, 15);
	init_mux_irq(&ssp_irq_chip, IRQ_MMP2_SSP_BASE, 2);

	set_irq_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux);
	set_irq_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux);
	set_irq_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux);
	set_irq_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux);
	set_irq_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux);
}
