/*
 *  arch/ppc64/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

#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 "mpic.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);


/*
 * 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_no)
{
	if (source_no >= 128 || !mpic->fixups)
		return 0;
	return mpic->fixups[source_no].base != NULL;
}

static inline void mpic_apic_end_irq(struct mpic *mpic, unsigned int source_no)
{
	struct mpic_irq_fixup *fixup = &mpic->fixups[source_no];
	u32 tmp;

	spin_lock(&mpic->fixup_lock);
	writeb(0x11 + 2 * fixup->irq, fixup->base);
	tmp = readl(fixup->base + 2);
	writel(tmp | 0x80000000ul, fixup->base + 2);
	/* config writes shouldn't be posted but let's be safe ... */
	(void)readl(fixup->base + 2);
	spin_unlock(&mpic->fixup_lock);
}


static void __init mpic_amd8111_read_irq(struct mpic *mpic, u8 __iomem *devbase)
{
	int i, irq;
	u32 tmp;

	printk(KERN_INFO "mpic:    - Workarounds on AMD 8111 @ %p\n", devbase);

	for (i=0; i < 24; i++) {
		writeb(0x10 + 2*i, devbase + 0xf2);
		tmp = readl(devbase + 0xf4);
		if ((tmp & 0x1) || !(tmp & 0x20))
			continue;
		irq = (tmp >> 16) & 0xff;
		mpic->fixups[irq].irq = i;
		mpic->fixups[irq].base = devbase + 0xf2;
	}
}
 
static void __init mpic_amd8131_read_irq(struct mpic *mpic, u8 __iomem *devbase)
{
	int i, irq;
	u32 tmp;

	printk(KERN_INFO "mpic:    - Workarounds on AMD 8131 @ %p\n", devbase);

	for (i=0; i < 4; i++) {
		writeb(0x10 + 2*i, devbase + 0xba);
		tmp = readl(devbase + 0xbc);
		if ((tmp & 0x1) || !(tmp & 0x20))
			continue;
		irq = (tmp >> 16) & 0xff;
		mpic->fixups[irq].irq = i;
		mpic->fixups[irq].base = devbase + 0xba;
	}
}
 
static void __init mpic_scan_ioapics(struct mpic *mpic)
{
	unsigned int devfn;
	u8 __iomem *cfgspace;

	printk(KERN_INFO "mpic: Setting up IO-APICs workarounds for U3\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
	 * and slot will never be above "0xf" so we only need to map 32k
	 */
	cfgspace = (unsigned char __iomem *)ioremap(0xf2000000, 0x8000);
	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 < PCI_DEVFN(0x10,0); devfn ++) {
		u8 __iomem *devbase = cfgspace + (devfn << 8);
		u8 hdr_type = readb(devbase + PCI_HEADER_TYPE);
		u32 l = readl(devbase + PCI_VENDOR_ID);
		u16 vendor_id, device_id;
		int multifunc = 0;

		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 it's a multifunction device (only really used
		 * to function 0 though
		 */
		multifunc = !!(hdr_type & 0x80);
		vendor_id = l & 0xffff;
		device_id = (l >> 16) & 0xffff;

		/* If a known device, go to fixup setup code */
		if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7460)
			mpic_amd8111_read_irq(mpic, devbase);
		if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7450)
			mpic_amd8131_read_irq(mpic, devbase);
	next:
		/* next device, if function 0 */
		if ((PCI_FUNC(devfn) == 0) && !multifunc)
			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("%s: enable_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_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_end_irq(unsigned int irq)
{
	struct mpic *mpic = mpic_from_irq(irq);

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

	/* 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))
			mpic_apic_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.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, 0x2000);
	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 ioapic fixups on U3 broken mpic */
	DBG("MPIC flags: %x\n", mpic->flags);
	if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY))
		mpic_scan_ioapics(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 << get_hard_smp_processor_id(boot_cpuid));

		/* 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 */
}

/*
 * 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);

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

	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;
	DBG("%s: get_one_irq(): %d\n", mpic->name, irq);

	if (mpic->cascade && irq == mpic->cascade_vec) {
		DBG("%s: cascading ...\n", mpic->name);
		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) 
		return irq + mpic->irq_offset;
       	DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0);
	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");
}
#endif /* CONFIG_SMP */
