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

#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);


/*
 * 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, 0x1000);
	mpic->tmregs = mpic->gregs + (MPIC_TIMER_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 << 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);

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