/*
 *  arch/powerpc/kernel/mpic.c
 *
 *  Driver for interrupt controllers following the OpenPIC standard, the
 *  common implementation beeing IBM's MPIC. This driver also can deal
 *  with various broken implementations of this HW.
 *
 *  Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License.  See the file COPYING in the main directory of this archive
 *  for more details.
 */

#undef DEBUG
#undef DEBUG_IPI
#undef DEBUG_IRQ
#undef DEBUG_LOW

#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/bootmem.h>
#include <linux/spinlock.h>
#include <linux/pci.h>

#include <asm/ptrace.h>
#include <asm/signal.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/mpic.h>
#include <asm/smp.h>

#ifdef DEBUG
#define DBG(fmt...) printk(fmt)
#else
#define DBG(fmt...)
#endif

static struct mpic *mpics;
static struct mpic *mpic_primary;
static DEFINE_SPINLOCK(mpic_lock);

#ifdef CONFIG_PPC32	/* XXX for now */
#ifdef CONFIG_IRQ_ALL_CPUS
#define distribute_irqs	(1)
#else
#define distribute_irqs	(0)
#endif
#endif

/*
 * Register accessor functions
 */


static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base,
			    unsigned int reg)
{
	if (be)
		return in_be32(base + (reg >> 2));
	else
		return in_le32(base + (reg >> 2));
}

static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base,
			      unsigned int reg, u32 value)
{
	if (be)
		out_be32(base + (reg >> 2), value);
	else
		out_le32(base + (reg >> 2), value);
}

static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
{
	unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);

	if (mpic->flags & MPIC_BROKEN_IPI)
		be = !be;
	return _mpic_read(be, mpic->gregs, offset);
}

static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
{
	unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);

	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value);
}

static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg)
{
	unsigned int cpu = 0;

	if (mpic->flags & MPIC_PRIMARY)
		cpu = hard_smp_processor_id();

	return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg);
}

static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value)
{
	unsigned int cpu = 0;

	if (mpic->flags & MPIC_PRIMARY)
		cpu = hard_smp_processor_id();

	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg, value);
}

static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg)
{
	unsigned int	isu = src_no >> mpic->isu_shift;
	unsigned int	idx = src_no & mpic->isu_mask;

	return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
			  reg + (idx * MPIC_IRQ_STRIDE));
}

static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
				   unsigned int reg, u32 value)
{
	unsigned int	isu = src_no >> mpic->isu_shift;
	unsigned int	idx = src_no & mpic->isu_mask;

	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
		    reg + (idx * MPIC_IRQ_STRIDE), value);
}

#define mpic_read(b,r)		_mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
#define mpic_write(b,r,v)	_mpic_write(mpic->flags & MPIC_BIG_ENDIAN,(b),(r),(v))
#define mpic_ipi_read(i)	_mpic_ipi_read(mpic,(i))
#define mpic_ipi_write(i,v)	_mpic_ipi_write(mpic,(i),(v))
#define mpic_cpu_read(i)	_mpic_cpu_read(mpic,(i))
#define mpic_cpu_write(i,v)	_mpic_cpu_write(mpic,(i),(v))
#define mpic_irq_read(s,r)	_mpic_irq_read(mpic,(s),(r))
#define mpic_irq_write(s,r,v)	_mpic_irq_write(mpic,(s),(r),(v))


/*
 * Low level utility functions
 */



/* Check if we have one of those nice broken MPICs with a flipped endian on
 * reads from IPI registers
 */
static void __init mpic_test_broken_ipi(struct mpic *mpic)
{
	u32 r;

	mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK);
	r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0);

	if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
		printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
		mpic->flags |= MPIC_BROKEN_IPI;
	}
}

#ifdef CONFIG_MPIC_BROKEN_U3

/* Test if an interrupt is sourced from HyperTransport (used on broken U3s)
 * to force the edge setting on the MPIC and do the ack workaround.
 */
static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source)
{
	if (source >= 128 || !mpic->fixups)
		return 0;
	return mpic->fixups[source].base != NULL;
}


static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source)
{
	struct mpic_irq_fixup *fixup = &mpic->fixups[source];

	if (fixup->applebase) {
		unsigned int soff = (fixup->index >> 3) & ~3;
		unsigned int mask = 1U << (fixup->index & 0x1f);
		writel(mask, fixup->applebase + soff);
	} else {
		spin_lock(&mpic->fixup_lock);
		writeb(0x11 + 2 * fixup->index, fixup->base + 2);
		writel(fixup->data, fixup->base + 4);
		spin_unlock(&mpic->fixup_lock);
	}
}

static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
				      unsigned int irqflags)
{
	struct mpic_irq_fixup *fixup = &mpic->fixups[source];
	unsigned long flags;
	u32 tmp;

	if (fixup->base == NULL)
		return;

	DBG("startup_ht_interrupt(%u, %u) index: %d\n",
	    source, irqflags, fixup->index);
	spin_lock_irqsave(&mpic->fixup_lock, flags);
	/* Enable and configure */
	writeb(0x10 + 2 * fixup->index, fixup->base + 2);
	tmp = readl(fixup->base + 4);
	tmp &= ~(0x23U);
	if (irqflags & IRQ_LEVEL)
		tmp |= 0x22;
	writel(tmp, fixup->base + 4);
	spin_unlock_irqrestore(&mpic->fixup_lock, flags);
}

static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
				       unsigned int irqflags)
{
	struct mpic_irq_fixup *fixup = &mpic->fixups[source];
	unsigned long flags;
	u32 tmp;

	if (fixup->base == NULL)
		return;

	DBG("shutdown_ht_interrupt(%u, %u)\n", source, irqflags);

	/* Disable */
	spin_lock_irqsave(&mpic->fixup_lock, flags);
	writeb(0x10 + 2 * fixup->index, fixup->base + 2);
	tmp = readl(fixup->base + 4);
	tmp &= ~1U;
	writel(tmp, fixup->base + 4);
	spin_unlock_irqrestore(&mpic->fixup_lock, flags);
}

static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
				    unsigned int devfn, u32 vdid)
{
	int i, irq, n;
	u8 __iomem *base;
	u32 tmp;
	u8 pos;

	for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0;
	     pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) {
		u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
		if (id == PCI_CAP_ID_HT_IRQCONF) {
			id = readb(devbase + pos + 3);
			if (id == 0x80)
				break;
		}
	}
	if (pos == 0)
		return;

	base = devbase + pos;
	writeb(0x01, base + 2);
	n = (readl(base + 4) >> 16) & 0xff;

	printk(KERN_INFO "mpic:   - HT:%02x.%x [0x%02x] vendor %04x device %04x"
	       " has %d irqs\n",
	       devfn >> 3, devfn & 0x7, pos, vdid & 0xffff, vdid >> 16, n + 1);

	for (i = 0; i <= n; i++) {
		writeb(0x10 + 2 * i, base + 2);
		tmp = readl(base + 4);
		irq = (tmp >> 16) & 0xff;
		DBG("HT PIC index 0x%x, irq 0x%x, tmp: %08x\n", i, irq, tmp);
		/* mask it , will be unmasked later */
		tmp |= 0x1;
		writel(tmp, base + 4);
		mpic->fixups[irq].index = i;
		mpic->fixups[irq].base = base;
		/* Apple HT PIC has a non-standard way of doing EOIs */
		if ((vdid & 0xffff) == 0x106b)
			mpic->fixups[irq].applebase = devbase + 0x60;
		else
			mpic->fixups[irq].applebase = NULL;
		writeb(0x11 + 2 * i, base + 2);
		mpic->fixups[irq].data = readl(base + 4) | 0x80000000;
	}
}
 

static void __init mpic_scan_ht_pics(struct mpic *mpic)
{
	unsigned int devfn;
	u8 __iomem *cfgspace;

	printk(KERN_INFO "mpic: Setting up HT PICs workarounds for U3/U4\n");

	/* Allocate fixups array */
	mpic->fixups = alloc_bootmem(128 * sizeof(struct mpic_irq_fixup));
	BUG_ON(mpic->fixups == NULL);
	memset(mpic->fixups, 0, 128 * sizeof(struct mpic_irq_fixup));

	/* Init spinlock */
	spin_lock_init(&mpic->fixup_lock);

	/* Map U3 config space. We assume all IO-APICs are on the primary bus
	 * so we only need to map 64kB.
	 */
	cfgspace = ioremap(0xf2000000, 0x10000);
	BUG_ON(cfgspace == NULL);

	/* Now we scan all slots. We do a very quick scan, we read the header
	 * type, vendor ID and device ID only, that's plenty enough
	 */
	for (devfn = 0; devfn < 0x100; devfn++) {
		u8 __iomem *devbase = cfgspace + (devfn << 8);
		u8 hdr_type = readb(devbase + PCI_HEADER_TYPE);
		u32 l = readl(devbase + PCI_VENDOR_ID);
		u16 s;

		DBG("devfn %x, l: %x\n", devfn, l);

		/* If no device, skip */
		if (l == 0xffffffff || l == 0x00000000 ||
		    l == 0x0000ffff || l == 0xffff0000)
			goto next;
		/* Check if is supports capability lists */
		s = readw(devbase + PCI_STATUS);
		if (!(s & PCI_STATUS_CAP_LIST))
			goto next;

		mpic_scan_ht_pic(mpic, devbase, devfn, l);

	next:
		/* next device, if function 0 */
		if (PCI_FUNC(devfn) == 0 && (hdr_type & 0x80) == 0)
			devfn += 7;
	}
}

#endif /* CONFIG_MPIC_BROKEN_U3 */


/* Find an mpic associated with a given linux interrupt */
static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi)
{
	struct mpic *mpic = mpics;

	while(mpic) {
		/* search IPIs first since they may override the main interrupts */
		if (irq >= mpic->ipi_offset && irq < (mpic->ipi_offset + 4)) {
			if (is_ipi)
				*is_ipi = 1;
			return mpic;
		}
		if (irq >= mpic->irq_offset &&
		    irq < (mpic->irq_offset + mpic->irq_count)) {
			if (is_ipi)
				*is_ipi = 0;
			return mpic;
		}
		mpic = mpic -> next;
	}
	return NULL;
}

/* Convert a cpu mask from logical to physical cpu numbers. */
static inline u32 mpic_physmask(u32 cpumask)
{
	int i;
	u32 mask = 0;

	for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1)
		mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
	return mask;
}

#ifdef CONFIG_SMP
/* Get the mpic structure from the IPI number */
static inline struct mpic * mpic_from_ipi(unsigned int ipi)
{
	return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi);
}
#endif

/* Get the mpic structure from the irq number */
static inline struct mpic * mpic_from_irq(unsigned int irq)
{
	return container_of(irq_desc[irq].handler, struct mpic, hc_irq);
}

/* Send an EOI */
static inline void mpic_eoi(struct mpic *mpic)
{
	mpic_cpu_write(MPIC_CPU_EOI, 0);
	(void)mpic_cpu_read(MPIC_CPU_WHOAMI);
}

#ifdef CONFIG_SMP
static irqreturn_t mpic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
{
	struct mpic *mpic = dev_id;

	smp_message_recv(irq - mpic->ipi_offset, regs);
	return IRQ_HANDLED;
}
#endif /* CONFIG_SMP */

/*
 * Linux descriptor level callbacks
 */


static void mpic_enable_irq(unsigned int irq)
{
	unsigned int loops = 100000;
	struct mpic *mpic = mpic_from_irq(irq);
	unsigned int src = irq - mpic->irq_offset;

	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);

	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
		       ~MPIC_VECPRI_MASK);

	/* make sure mask gets to controller before we return to user */
	do {
		if (!loops--) {
			printk(KERN_ERR "mpic_enable_irq timeout\n");
			break;
		}
	} while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);	

#ifdef CONFIG_MPIC_BROKEN_U3
	if (mpic->flags & MPIC_BROKEN_U3) {
		unsigned int src = irq - mpic->irq_offset;
		if (mpic_is_ht_interrupt(mpic, src) &&
		    (irq_desc[irq].status & IRQ_LEVEL))
			mpic_ht_end_irq(mpic, src);
	}
#endif /* CONFIG_MPIC_BROKEN_U3 */
}

static unsigned int mpic_startup_irq(unsigned int irq)
{
#ifdef CONFIG_MPIC_BROKEN_U3
	struct mpic *mpic = mpic_from_irq(irq);
	unsigned int src = irq - mpic->irq_offset;

	if (mpic_is_ht_interrupt(mpic, src))
		mpic_startup_ht_interrupt(mpic, src, irq_desc[irq].status);

#endif /* CONFIG_MPIC_BROKEN_U3 */

	mpic_enable_irq(irq);

	return 0;
}

static void mpic_disable_irq(unsigned int irq)
{
	unsigned int loops = 100000;
	struct mpic *mpic = mpic_from_irq(irq);
	unsigned int src = irq - mpic->irq_offset;

	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);

	mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
		       mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
		       MPIC_VECPRI_MASK);

	/* make sure mask gets to controller before we return to user */
	do {
		if (!loops--) {
			printk(KERN_ERR "mpic_enable_irq timeout\n");
			break;
		}
	} while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
}

static void mpic_shutdown_irq(unsigned int irq)
{
#ifdef CONFIG_MPIC_BROKEN_U3
	struct mpic *mpic = mpic_from_irq(irq);
	unsigned int src = irq - mpic->irq_offset;

	if (mpic_is_ht_interrupt(mpic, src))
		mpic_shutdown_ht_interrupt(mpic, src, irq_desc[irq].status);

#endif /* CONFIG_MPIC_BROKEN_U3 */

	mpic_disable_irq(irq);
}

static void mpic_end_irq(unsigned int irq)
{
	struct mpic *mpic = mpic_from_irq(irq);

#ifdef DEBUG_IRQ
	DBG("%s: end_irq: %d\n", mpic->name, irq);
#endif
	/* We always EOI on end_irq() even for edge interrupts since that
	 * should only lower the priority, the MPIC should have properly
	 * latched another edge interrupt coming in anyway
	 */

#ifdef CONFIG_MPIC_BROKEN_U3
	if (mpic->flags & MPIC_BROKEN_U3) {
		unsigned int src = irq - mpic->irq_offset;
		if (mpic_is_ht_interrupt(mpic, src) &&
		    (irq_desc[irq].status & IRQ_LEVEL))
			mpic_ht_end_irq(mpic, src);
	}
#endif /* CONFIG_MPIC_BROKEN_U3 */

	mpic_eoi(mpic);
}

#ifdef CONFIG_SMP

static void mpic_enable_ipi(unsigned int irq)
{
	struct mpic *mpic = mpic_from_ipi(irq);
	unsigned int src = irq - mpic->ipi_offset;

	DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src);
	mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
}

static void mpic_disable_ipi(unsigned int irq)
{
	/* NEVER disable an IPI... that's just plain wrong! */
}

static void mpic_end_ipi(unsigned int irq)
{
	struct mpic *mpic = mpic_from_ipi(irq);

	/*
	 * IPIs are marked IRQ_PER_CPU. This has the side effect of
	 * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from
	 * applying to them. We EOI them late to avoid re-entering.
	 * We mark IPI's with SA_INTERRUPT as they must run with
	 * irqs disabled.
	 */
	mpic_eoi(mpic);
}

#endif /* CONFIG_SMP */

static void mpic_set_affinity(unsigned int irq, cpumask_t cpumask)
{
	struct mpic *mpic = mpic_from_irq(irq);

	cpumask_t tmp;

	cpus_and(tmp, cpumask, cpu_online_map);

	mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_DESTINATION,
		       mpic_physmask(cpus_addr(tmp)[0]));	
}


/*
 * Exported functions
 */


struct mpic * __init mpic_alloc(unsigned long phys_addr,
				unsigned int flags,
				unsigned int isu_size,
				unsigned int irq_offset,
				unsigned int irq_count,
				unsigned int ipi_offset,
				unsigned char *senses,
				unsigned int senses_count,
				const char *name)
{
	struct mpic	*mpic;
	u32		reg;
	const char	*vers;
	int		i;

	mpic = alloc_bootmem(sizeof(struct mpic));
	if (mpic == NULL)
		return NULL;
	

	memset(mpic, 0, sizeof(struct mpic));
	mpic->name = name;

	mpic->hc_irq.typename = name;
	mpic->hc_irq.startup = mpic_startup_irq;
	mpic->hc_irq.shutdown = mpic_shutdown_irq;
	mpic->hc_irq.enable = mpic_enable_irq;
	mpic->hc_irq.disable = mpic_disable_irq;
	mpic->hc_irq.end = mpic_end_irq;
	if (flags & MPIC_PRIMARY)
		mpic->hc_irq.set_affinity = mpic_set_affinity;
#ifdef CONFIG_SMP
	mpic->hc_ipi.typename = name;
	mpic->hc_ipi.enable = mpic_enable_ipi;
	mpic->hc_ipi.disable = mpic_disable_ipi;
	mpic->hc_ipi.end = mpic_end_ipi;
#endif /* CONFIG_SMP */

	mpic->flags = flags;
	mpic->isu_size = isu_size;
	mpic->irq_offset = irq_offset;
	mpic->irq_count = irq_count;
	mpic->ipi_offset = ipi_offset;
	mpic->num_sources = 0; /* so far */
	mpic->senses = senses;
	mpic->senses_count = senses_count;

	/* Map the global registers */
	mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
	mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
	BUG_ON(mpic->gregs == NULL);

	/* Reset */
	if (flags & MPIC_WANTS_RESET) {
		mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
			   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
			   | MPIC_GREG_GCONF_RESET);
		while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
		       & MPIC_GREG_GCONF_RESET)
			mb();
	}

	/* Read feature register, calculate num CPUs and, for non-ISU
	 * MPICs, num sources as well. On ISU MPICs, sources are counted
	 * as ISUs are added
	 */
	reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
	mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
			  >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
	if (isu_size == 0)
		mpic->num_sources = ((reg & MPIC_GREG_FEATURE_LAST_SRC_MASK)
				     >> MPIC_GREG_FEATURE_LAST_SRC_SHIFT) + 1;

	/* Map the per-CPU registers */
	for (i = 0; i < mpic->num_cpus; i++) {
		mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
					   i * MPIC_CPU_STRIDE, 0x1000);
		BUG_ON(mpic->cpuregs[i] == NULL);
	}

	/* Initialize main ISU if none provided */
	if (mpic->isu_size == 0) {
		mpic->isu_size = mpic->num_sources;
		mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
					MPIC_IRQ_STRIDE * mpic->isu_size);
		BUG_ON(mpic->isus[0] == NULL);
	}
	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
	mpic->isu_mask = (1 << mpic->isu_shift) - 1;

	/* Display version */
	switch (reg & MPIC_GREG_FEATURE_VERSION_MASK) {
	case 1:
		vers = "1.0";
		break;
	case 2:
		vers = "1.2";
		break;
	case 3:
		vers = "1.3";
		break;
	default:
		vers = "<unknown>";
		break;
	}
	printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %lx, max %d CPUs\n",
	       name, vers, phys_addr, mpic->num_cpus);
	printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", mpic->isu_size,
	       mpic->isu_shift, mpic->isu_mask);

	mpic->next = mpics;
	mpics = mpic;

	if (flags & MPIC_PRIMARY)
		mpic_primary = mpic;

	return mpic;
}

void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
			    unsigned long phys_addr)
{
	unsigned int isu_first = isu_num * mpic->isu_size;

	BUG_ON(isu_num >= MPIC_MAX_ISU);

	mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size);
	if ((isu_first + mpic->isu_size) > mpic->num_sources)
		mpic->num_sources = isu_first + mpic->isu_size;
}

void __init mpic_setup_cascade(unsigned int irq, mpic_cascade_t handler,
			       void *data)
{
	struct mpic *mpic = mpic_find(irq, NULL);
	unsigned long flags;

	/* Synchronization here is a bit dodgy, so don't try to replace cascade
	 * interrupts on the fly too often ... but normally it's set up at boot.
	 */
	spin_lock_irqsave(&mpic_lock, flags);
	if (mpic->cascade)	       
		mpic_disable_irq(mpic->cascade_vec + mpic->irq_offset);
	mpic->cascade = NULL;
	wmb();
	mpic->cascade_vec = irq - mpic->irq_offset;
	mpic->cascade_data = data;
	wmb();
	mpic->cascade = handler;
	mpic_enable_irq(irq);
	spin_unlock_irqrestore(&mpic_lock, flags);
}

void __init mpic_init(struct mpic *mpic)
{
	int i;

	BUG_ON(mpic->num_sources == 0);

	printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);

	/* Set current processor priority to max */
	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);

	/* Initialize timers: just disable them all */
	for (i = 0; i < 4; i++) {
		mpic_write(mpic->tmregs,
			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
		mpic_write(mpic->tmregs,
			   i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
			   MPIC_VECPRI_MASK |
			   (MPIC_VEC_TIMER_0 + i));
	}

	/* Initialize IPIs to our reserved vectors and mark them disabled for now */
	mpic_test_broken_ipi(mpic);
	for (i = 0; i < 4; i++) {
		mpic_ipi_write(i,
			       MPIC_VECPRI_MASK |
			       (10 << MPIC_VECPRI_PRIORITY_SHIFT) |
			       (MPIC_VEC_IPI_0 + i));
#ifdef CONFIG_SMP
		if (!(mpic->flags & MPIC_PRIMARY))
			continue;
		irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU;
		irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi;
#endif /* CONFIG_SMP */
	}

	/* Initialize interrupt sources */
	if (mpic->irq_count == 0)
		mpic->irq_count = mpic->num_sources;

#ifdef CONFIG_MPIC_BROKEN_U3
	/* Do the HT PIC fixups on U3 broken mpic */
	DBG("MPIC flags: %x\n", mpic->flags);
	if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY))
		mpic_scan_ht_pics(mpic);
#endif /* CONFIG_MPIC_BROKEN_U3 */

	for (i = 0; i < mpic->num_sources; i++) {
		/* start with vector = source number, and masked */
		u32 vecpri = MPIC_VECPRI_MASK | i | (8 << MPIC_VECPRI_PRIORITY_SHIFT);
		int level = 0;
		
		/* if it's an IPI, we skip it */
		if ((mpic->irq_offset + i) >= (mpic->ipi_offset + i) &&
		    (mpic->irq_offset + i) <  (mpic->ipi_offset + i + 4))
			continue;

		/* do senses munging */
		if (mpic->senses && i < mpic->senses_count) {
			if (mpic->senses[i] & IRQ_SENSE_LEVEL)
				vecpri |= MPIC_VECPRI_SENSE_LEVEL;
			if (mpic->senses[i] & IRQ_POLARITY_POSITIVE)
				vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
		} else
			vecpri |= MPIC_VECPRI_SENSE_LEVEL;

		/* remember if it was a level interrupts */
		level = (vecpri & MPIC_VECPRI_SENSE_LEVEL);

		/* deal with broken U3 */
		if (mpic->flags & MPIC_BROKEN_U3) {
#ifdef CONFIG_MPIC_BROKEN_U3
			if (mpic_is_ht_interrupt(mpic, i)) {
				vecpri &= ~(MPIC_VECPRI_SENSE_MASK |
					    MPIC_VECPRI_POLARITY_MASK);
				vecpri |= MPIC_VECPRI_POLARITY_POSITIVE;
			}
#else
			printk(KERN_ERR "mpic: BROKEN_U3 set, but CONFIG doesn't match\n");
#endif
		}

		DBG("setup source %d, vecpri: %08x, level: %d\n", i, vecpri,
		    (level != 0));

		/* init hw */
		mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
			       1 << hard_smp_processor_id());

		/* init linux descriptors */
		if (i < mpic->irq_count) {
			irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0;
			irq_desc[mpic->irq_offset+i].handler = &mpic->hc_irq;
		}
	}
	
	/* Init spurrious vector */
	mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS);

	/* Disable 8259 passthrough */
	mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
		   mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
		   | MPIC_GREG_GCONF_8259_PTHROU_DIS);

	/* Set current processor priority to 0 */
	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
}



void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
{
	int is_ipi;
	struct mpic *mpic = mpic_find(irq, &is_ipi);
	unsigned long flags;
	u32 reg;

	spin_lock_irqsave(&mpic_lock, flags);
	if (is_ipi) {
		reg = mpic_ipi_read(irq - mpic->ipi_offset) &
			~MPIC_VECPRI_PRIORITY_MASK;
		mpic_ipi_write(irq - mpic->ipi_offset,
			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
	} else {
		reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
			& ~MPIC_VECPRI_PRIORITY_MASK;
		mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
	}
	spin_unlock_irqrestore(&mpic_lock, flags);
}

unsigned int mpic_irq_get_priority(unsigned int irq)
{
	int is_ipi;
	struct mpic *mpic = mpic_find(irq, &is_ipi);
	unsigned long flags;
	u32 reg;

	spin_lock_irqsave(&mpic_lock, flags);
	if (is_ipi)
		reg = mpic_ipi_read(irq - mpic->ipi_offset);
	else
		reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI);
	spin_unlock_irqrestore(&mpic_lock, flags);
	return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT;
}

void mpic_setup_this_cpu(void)
{
#ifdef CONFIG_SMP
	struct mpic *mpic = mpic_primary;
	unsigned long flags;
	u32 msk = 1 << hard_smp_processor_id();
	unsigned int i;

	BUG_ON(mpic == NULL);

	DBG("%s: setup_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());

	spin_lock_irqsave(&mpic_lock, flags);

 	/* let the mpic know we want intrs. default affinity is 0xffffffff
	 * until changed via /proc. That's how it's done on x86. If we want
	 * it differently, then we should make sure we also change the default
	 * values of irq_affinity in irq.c.
 	 */
	if (distribute_irqs) {
	 	for (i = 0; i < mpic->num_sources ; i++)
			mpic_irq_write(i, MPIC_IRQ_DESTINATION,
				mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
	}

	/* Set current processor priority to 0 */
	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);

	spin_unlock_irqrestore(&mpic_lock, flags);
#endif /* CONFIG_SMP */
}

int mpic_cpu_get_priority(void)
{
	struct mpic *mpic = mpic_primary;

	return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI);
}

void mpic_cpu_set_priority(int prio)
{
	struct mpic *mpic = mpic_primary;

	prio &= MPIC_CPU_TASKPRI_MASK;
	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio);
}

/*
 * XXX: someone who knows mpic should check this.
 * do we need to eoi the ipi including for kexec cpu here (see xics comments)?
 * or can we reset the mpic in the new kernel?
 */
void mpic_teardown_this_cpu(int secondary)
{
	struct mpic *mpic = mpic_primary;
	unsigned long flags;
	u32 msk = 1 << hard_smp_processor_id();
	unsigned int i;

	BUG_ON(mpic == NULL);

	DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
	spin_lock_irqsave(&mpic_lock, flags);

	/* let the mpic know we don't want intrs.  */
	for (i = 0; i < mpic->num_sources ; i++)
		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
			mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);

	/* Set current processor priority to max */
	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);

	spin_unlock_irqrestore(&mpic_lock, flags);
}


void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask)
{
	struct mpic *mpic = mpic_primary;

	BUG_ON(mpic == NULL);

#ifdef DEBUG_IPI
	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
#endif

	mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
		       mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
}

int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
{
	u32 irq;

	irq = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK;
#ifdef DEBUG_LOW
	DBG("%s: get_one_irq(): %d\n", mpic->name, irq);
#endif
	if (mpic->cascade && irq == mpic->cascade_vec) {
#ifdef DEBUG_LOW
		DBG("%s: cascading ...\n", mpic->name);
#endif
		irq = mpic->cascade(regs, mpic->cascade_data);
		mpic_eoi(mpic);
		return irq;
	}
	if (unlikely(irq == MPIC_VEC_SPURRIOUS))
		return -1;
	if (irq < MPIC_VEC_IPI_0) {
#ifdef DEBUG_IRQ
		DBG("%s: irq %d\n", mpic->name, irq + mpic->irq_offset);
#endif
		return irq + mpic->irq_offset;
	}
#ifdef DEBUG_IPI
       	DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
#endif
	return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset;
}

int mpic_get_irq(struct pt_regs *regs)
{
	struct mpic *mpic = mpic_primary;

	BUG_ON(mpic == NULL);

	return mpic_get_one_irq(mpic, regs);
}


#ifdef CONFIG_SMP
void mpic_request_ipis(void)
{
	struct mpic *mpic = mpic_primary;

	BUG_ON(mpic == NULL);
	
	printk("requesting IPIs ... \n");

	/* IPIs are marked SA_INTERRUPT as they must run with irqs disabled */
	request_irq(mpic->ipi_offset+0, mpic_ipi_action, SA_INTERRUPT,
		    "IPI0 (call function)", mpic);
	request_irq(mpic->ipi_offset+1, mpic_ipi_action, SA_INTERRUPT,
		   "IPI1 (reschedule)", mpic);
	request_irq(mpic->ipi_offset+2, mpic_ipi_action, SA_INTERRUPT,
		   "IPI2 (unused)", mpic);
	request_irq(mpic->ipi_offset+3, mpic_ipi_action, SA_INTERRUPT,
		   "IPI3 (debugger break)", mpic);

	printk("IPIs requested... \n");
}

void smp_mpic_message_pass(int target, int msg)
{
	/* make sure we're sending something that translates to an IPI */
	if ((unsigned int)msg > 3) {
		printk("SMP %d: smp_message_pass: unknown msg %d\n",
		       smp_processor_id(), msg);
		return;
	}
	switch (target) {
	case MSG_ALL:
		mpic_send_ipi(msg, 0xffffffff);
		break;
	case MSG_ALL_BUT_SELF:
		mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id()));
		break;
	default:
		mpic_send_ipi(msg, 1 << target);
		break;
	}
}
#endif /* CONFIG_SMP */
