/*
 * arch/ppc/syslib/ppc4xx_pic.c
 *
 * Interrupt controller driver for PowerPC 4xx-based processors.
 *
 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
 * Copyright (c) 2004, 2005 Zultys Technologies
 *
 * Based on original code by
 *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
 *    Armin Custer <akuster@mvista.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/config.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/stddef.h>

#include <asm/processor.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/ppc4xx_pic.h>

/* See comment in include/arch-ppc/ppc4xx_pic.h
 * for more info about these two variables
 */
extern struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[NR_UICS]
    __attribute__ ((weak));
extern unsigned char ppc4xx_uic_ext_irq_cfg[] __attribute__ ((weak));

#define IRQ_MASK_UIC0(irq)		(1 << (31 - (irq)))
#define IRQ_MASK_UICx(irq)		(1 << (31 - ((irq) & 0x1f)))
#define IRQ_MASK_UIC1(irq)		IRQ_MASK_UICx(irq)
#define IRQ_MASK_UIC2(irq)		IRQ_MASK_UICx(irq)

#define UIC_HANDLERS(n)							\
static void ppc4xx_uic##n##_enable(unsigned int irq)			\
{									\
	u32 mask = IRQ_MASK_UIC##n(irq);				\
	if (irq_desc[irq].status & IRQ_LEVEL)				\
		mtdcr(DCRN_UIC_SR(UIC##n), mask);			\
	ppc_cached_irq_mask[n] |= mask;					\
	mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]);		\
}									\
									\
static void ppc4xx_uic##n##_disable(unsigned int irq)			\
{									\
	ppc_cached_irq_mask[n] &= ~IRQ_MASK_UIC##n(irq);		\
	mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]);		\
	ACK_UIC##n##_PARENT						\
}									\
									\
static void ppc4xx_uic##n##_ack(unsigned int irq)			\
{									\
	u32 mask = IRQ_MASK_UIC##n(irq);				\
	ppc_cached_irq_mask[n] &= ~mask;				\
	mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]);		\
	mtdcr(DCRN_UIC_SR(UIC##n), mask);				\
	ACK_UIC##n##_PARENT						\
}									\
									\
static void ppc4xx_uic##n##_end(unsigned int irq)			\
{									\
	unsigned int status = irq_desc[irq].status;			\
	u32 mask = IRQ_MASK_UIC##n(irq);				\
	if (status & IRQ_LEVEL) {					\
		mtdcr(DCRN_UIC_SR(UIC##n), mask);			\
		ACK_UIC##n##_PARENT					\
	}								\
	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {		\
		ppc_cached_irq_mask[n] |= mask;				\
		mtdcr(DCRN_UIC_ER(UIC##n), ppc_cached_irq_mask[n]);	\
	}								\
}

#define DECLARE_UIC(n)							\
{									\
	.typename 	= "UIC"#n,					\
	.enable 	= ppc4xx_uic##n##_enable,			\
	.disable 	= ppc4xx_uic##n##_disable,			\
	.ack 		= ppc4xx_uic##n##_ack,				\
	.end 		= ppc4xx_uic##n##_end,				\
}									\

#if NR_UICS == 3
#define ACK_UIC0_PARENT	mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
#define ACK_UIC1_PARENT	mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
#define ACK_UIC2_PARENT	mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
UIC_HANDLERS(0);
UIC_HANDLERS(1);
UIC_HANDLERS(2);

static int ppc4xx_pic_get_irq(struct pt_regs *regs)
{
	u32 uicb = mfdcr(DCRN_UIC_MSR(UICB));
	if (uicb & UICB_UIC0NC)
		return 32 - ffs(mfdcr(DCRN_UIC_MSR(UIC0)));
	else if (uicb & UICB_UIC1NC)
		return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
	else if (uicb & UICB_UIC2NC)
		return 96 - ffs(mfdcr(DCRN_UIC_MSR(UIC2)));
	else
		return -1;
}

static void __init ppc4xx_pic_impl_init(void)
{
#if defined(CONFIG_440GX)
	/* Disable 440GP compatibility mode if it was enabled in firmware */
	SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~DCRN_SDR_MFR_PCM);
#endif
	/* Configure Base UIC */
	mtdcr(DCRN_UIC_CR(UICB), 0);
	mtdcr(DCRN_UIC_TR(UICB), 0);
	mtdcr(DCRN_UIC_PR(UICB), 0xffffffff);
	mtdcr(DCRN_UIC_SR(UICB), 0xffffffff);
	mtdcr(DCRN_UIC_ER(UICB), UICB_UIC0NC | UICB_UIC1NC | UICB_UIC2NC);
}

#elif NR_UICS == 2
#define ACK_UIC0_PARENT
#define ACK_UIC1_PARENT	mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
UIC_HANDLERS(0);
UIC_HANDLERS(1);

static int ppc4xx_pic_get_irq(struct pt_regs *regs)
{
	u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
	if (uic0 & UIC0_UIC1NC)
		return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
	else
		return uic0 ? 32 - ffs(uic0) : -1;
}

static void __init ppc4xx_pic_impl_init(void)
{
	/* Enable cascade interrupt in UIC0 */
	ppc_cached_irq_mask[0] |= UIC0_UIC1NC;
	mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
	mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
}

#elif NR_UICS == 1
#define ACK_UIC0_PARENT
UIC_HANDLERS(0);

static int ppc4xx_pic_get_irq(struct pt_regs *regs)
{
	u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
	return uic0 ? 32 - ffs(uic0) : -1;
}

static inline void ppc4xx_pic_impl_init(void)
{
}
#endif

static struct ppc4xx_uic_impl {
	struct hw_interrupt_type decl;
	int base;			/* Base DCR number */
} __uic[] = {
	{ .decl = DECLARE_UIC(0), .base = UIC0 },
#if NR_UICS > 1
	{ .decl = DECLARE_UIC(1), .base = UIC1 },
#if NR_UICS > 2
	{ .decl = DECLARE_UIC(2), .base = UIC2 },
#endif
#endif
};

static inline int is_level_sensitive(int irq)
{
	u32 tr = mfdcr(DCRN_UIC_TR(__uic[irq >> 5].base));
	return (tr & IRQ_MASK_UICx(irq)) == 0;
}

void __init ppc4xx_pic_init(void)
{
	int i;
	unsigned char *eirqs = ppc4xx_uic_ext_irq_cfg;

	for (i = 0; i < NR_UICS; ++i) {
		int base = __uic[i].base;

		/* Disable everything by default */
		ppc_cached_irq_mask[i] = 0;
		mtdcr(DCRN_UIC_ER(base), 0);

		/* We don't use critical interrupts */
		mtdcr(DCRN_UIC_CR(base), 0);

		/* Configure polarity and triggering */
		if (ppc4xx_core_uic_cfg) {
			struct ppc4xx_uic_settings *p = ppc4xx_core_uic_cfg + i;
			u32 mask = p->ext_irq_mask;
			u32 pr = mfdcr(DCRN_UIC_PR(base)) & mask;
			u32 tr = mfdcr(DCRN_UIC_TR(base)) & mask;

			/* "Fixed" interrupts (on-chip devices) */
			pr |= p->polarity & ~mask;
			tr |= p->triggering & ~mask;

			/* Merge external IRQs settings if board port
			 * provided them
			 */
			if (eirqs && mask) {
				pr &= ~mask;
				tr &= ~mask;
				while (mask) {
					/* Extract current external IRQ mask */
					u32 eirq_mask = 1 << __ilog2(mask);

					if (!(*eirqs & IRQ_SENSE_LEVEL))
						tr |= eirq_mask;

					if (*eirqs & IRQ_POLARITY_POSITIVE)
						pr |= eirq_mask;

					mask &= ~eirq_mask;
					++eirqs;
				}
			}
			mtdcr(DCRN_UIC_PR(base), pr);
			mtdcr(DCRN_UIC_TR(base), tr);
		}

		/* ACK any pending interrupts to prevent false
		 * triggering after first enable
		 */
		mtdcr(DCRN_UIC_SR(base), 0xffffffff);
	}

	/* Perform optional implementation specific setup
	 * (e.g. enable cascade interrupts for multi-UIC configurations)
	 */
	ppc4xx_pic_impl_init();

	/* Attach low-level handlers */
	for (i = 0; i < (NR_UICS << 5); ++i) {
		irq_desc[i].handler = &__uic[i >> 5].decl;
		if (is_level_sensitive(i))
			irq_desc[i].status |= IRQ_LEVEL;
	}

	ppc_md.get_irq = ppc4xx_pic_get_irq;
}
