/*
 * Copyright (c) 2008, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Google, Inc. nor the names of its contributors
 *    may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <debug.h>
#include <arch/arm.h>
#include <reg.h>
#include <kernel/thread.h>
#include <platform/interrupts.h>

#include <platform/irqs.h>
#include <platform/iomap.h>

#define VIC_REG(off) (MSM_VIC_BASE + (off))

#define VIC_INT_SELECT0     VIC_REG(0x0000)  /* 1: FIQ, 0: IRQ */
#define VIC_INT_SELECT1     VIC_REG(0x0004)  /* 1: FIQ, 0: IRQ */
#define VIC_INT_EN0         VIC_REG(0x0010)
#define VIC_INT_EN1         VIC_REG(0x0014)
#define VIC_INT_ENCLEAR0    VIC_REG(0x0020)
#define VIC_INT_ENCLEAR1    VIC_REG(0x0024)
#define VIC_INT_ENSET0      VIC_REG(0x0030)
#define VIC_INT_ENSET1      VIC_REG(0x0034)
#define VIC_INT_TYPE0       VIC_REG(0x0040)  /* 1: EDGE, 0: LEVEL  */
#define VIC_INT_TYPE1       VIC_REG(0x0044)  /* 1: EDGE, 0: LEVEL  */
#define VIC_INT_POLARITY0   VIC_REG(0x0050)  /* 1: NEG, 0: POS */
#define VIC_INT_POLARITY1   VIC_REG(0x0054)  /* 1: NEG, 0: POS */
#define VIC_NO_PEND_VAL     VIC_REG(0x0060)
#define VIC_INT_MASTEREN    VIC_REG(0x0068)  /* 1: IRQ, 2: FIQ     */
#define VIC_CONFIG          VIC_REG(0x006C)  /* 1: USE ARM1136 VIC */
#define VIC_SECURITY0       VIC_REG(0x0070)
#define VIC_SECURITY1       VIC_REG(0x0074)
#define VIC_IRQ_STATUS0     VIC_REG(0x0080)
#define VIC_IRQ_STATUS1     VIC_REG(0x0084)
#define VIC_FIQ_STATUS0     VIC_REG(0x0090)
#define VIC_FIQ_STATUS1     VIC_REG(0x0094)
#define VIC_RAW_STATUS0     VIC_REG(0x00A0)
#define VIC_RAW_STATUS1     VIC_REG(0x00A4)
#define VIC_INT_CLEAR0      VIC_REG(0x00B0)
#define VIC_INT_CLEAR1      VIC_REG(0x00B4)
#define VIC_SOFTINT0        VIC_REG(0x00C0)
#define VIC_SOFTINT1        VIC_REG(0x00C4)
#define VIC_IRQ_VEC_RD      VIC_REG(0x00D0)  /* pending int # */
#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4)  /* pending vector addr */
#define VIC_IRQ_VEC_WR      VIC_REG(0x00D8)
#define VIC_FIQ_VEC_RD      VIC_REG(0x00DC)  /* pending int # */
#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0)  /* pending vector addr */
#define VIC_FIQ_VEC_WR      VIC_REG(0x00E4)
#define VIC_IRQ_IN_SERVICE  VIC_REG(0x00E8)
#define VIC_IRQ_IN_STACK    VIC_REG(0x00EC)
#define VIC_FIQ_IN_SERVICE  VIC_REG(0x00F0)
#define VIC_FIQ_IN_STACK    VIC_REG(0x00F4)
#define VIC_TEST_BUS_SEL    VIC_REG(0x00F8)

#define SIRC_REG(off) (MSM_SIRC_BASE + (off))

#define SIRC_INT_SELECT     SIRC_REG(0x0000)  /* 0: IRQ0 1: IRQ1 */
#define SIRC_INT_ENABLE     SIRC_REG(0x0004)
#define SIRC_INT_ENCLEAR    SIRC_REG(0x0008)
#define SIRC_INT_ENSET      SIRC_REG(0x000C)
#define SIRC_INT_TYPE       SIRC_REG(0x0010)  /* 1: EDGE, 0: LEVEL */
#define SIRC_INT_POLARITY   SIRC_REG(0x0014)  /* 1: NEG, 0: POS */
#define SIRC_SECURITY       SIRC_REG(0x0018)  /* 0: SEC, 1: NSEC */
#define SIRC_IRQ0_STATUS    SIRC_REG(0x001C)
#define SIRC_IRQ1_STATUS    SIRC_REG(0x0020)
#define SIRC_RAW_STATUS     SIRC_REG(0x0024)

struct ihandler {
	int_handler func;
	void *arg;
};

static struct ihandler handler[NR_IRQS];

void platform_init_interrupts(void)
{
	writel(0xffffffff, VIC_INT_CLEAR0);
	writel(0xffffffff, VIC_INT_CLEAR1);
	writel(0, VIC_INT_SELECT0);
	writel(0, VIC_INT_SELECT1);
	writel(0xffffffff, VIC_INT_TYPE0);
	writel(0xffffffff, VIC_INT_TYPE1);
	writel(0, VIC_CONFIG);
	writel(1, VIC_INT_MASTEREN);
}

enum handler_return platform_irq(struct arm_iframe *frame)
{
	unsigned num;
	enum handler_return ret;
	num = readl(VIC_IRQ_VEC_RD);
	num = readl(VIC_IRQ_VEC_PEND_RD);
	if (num > NR_IRQS)
		return 0;
	writel(1 << (num & 31), (num > 31) ? VIC_INT_CLEAR1 : VIC_INT_CLEAR0);
	ret = handler[num].func(handler[num].arg);
	writel(0, VIC_IRQ_VEC_WR);
	return ret;
}

void platform_fiq(struct arm_iframe *frame)
{
	PANIC_UNIMPLEMENTED;
}

status_t mask_interrupt(unsigned int vector)
{
	unsigned reg = (vector > 31) ? VIC_INT_ENCLEAR1 : VIC_INT_ENCLEAR0;
	unsigned bit = 1 << (vector & 31);
	writel(bit, reg);
	return 0;
}

status_t unmask_interrupt(unsigned int vector)
{
	unsigned reg = (vector > 31) ? VIC_INT_ENSET1 : VIC_INT_ENSET0;
	unsigned bit = 1 << (vector & 31);
	writel(bit, reg);
	return 0;
}

void register_int_handler(unsigned int vector, int_handler func, void *arg)
{
	if (vector >= NR_IRQS)
		return;

	enter_critical_section();
	handler[vector].func = func;
	handler[vector].arg = arg;
	exit_critical_section();
}

