diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-08 10:04:20 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-08 10:04:20 -0800 |
commit | 21eb4fa1700112d1420d72e1de708af671a251c8 (patch) | |
tree | 3afd9f526da50108c27e05ac69826be5e7c2ad6e /arch/powerpc/sysdev/mpic.c | |
parent | 0c0e8caf9fd6c9a49fb9fbdba14a8b7b4239adde (diff) | |
parent | d003e7a1a569501cbe9a5ca14748177498c4893a (diff) | |
download | op-kernel-dev-21eb4fa1700112d1420d72e1de708af671a251c8.zip op-kernel-dev-21eb4fa1700112d1420d72e1de708af671a251c8.tar.gz |
Merge master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc
* master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc: (116 commits)
[POWERPC] Add export of vgacon_remap_base
[POWERPC] Remove bogus comment about page_is_ram
[POWERPC] windfarm: don't die on suspend thread signal
[POWERPC] Fix comment in kernel/irq.c
[POWERPC] ppc: Fix booke watchdog initialization
[POWERPC] PPC: Use ARRAY_SIZE macro when appropriate
[POWERPC] Use ARRAY_SIZE macro when appropriate
[POWERPC] Fix ppc64's writing to struct file_operations
[POWERPC] ppc: use syslog macro for the printk log level
[POWERPC] ppc: cs4218_tdm remove extra brace
[POWERPC] Add mpc52xx/lite5200 PCI support
[POWERPC] Only use H_BULK_REMOVE if the firmware supports it
[POWERPC] Fixup error handling when emulating a floating point instruction
[POWERPC] Enable interrupts if we are doing fp math emulation
[POWERPC] Added kprobes support to ppc32
[POWERPC] Make pSeries use the H_BULK_REMOVE hypervisor call
[POWERPC] Clear RI bit in MSR before restoring r13 when returning to userspace
[POWERPC] Fix performance monitor exception
[POWERPC] Compile fixes for arch/powerpc dcr code
[POWERPC] Maple: use mmio nvram
...
Diffstat (limited to 'arch/powerpc/sysdev/mpic.c')
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index d01ced1..aa701cc 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -496,13 +496,18 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi) { unsigned int src = mpic_irq_to_hw(irq); + struct mpic *mpic; if (irq < NUM_ISA_INTERRUPTS) return NULL; + + mpic = irq_desc[irq].chip_data; + if (is_ipi) - *is_ipi = (src >= MPIC_VEC_IPI_0 && src <= MPIC_VEC_IPI_3); + *is_ipi = (src >= mpic->ipi_vecs[0] && + src <= mpic->ipi_vecs[3]); - return irq_desc[irq].chip_data; + return mpic; } /* Convert a cpu mask from logical to physical cpu numbers. */ @@ -540,7 +545,11 @@ static inline void mpic_eoi(struct mpic *mpic) #ifdef CONFIG_SMP static irqreturn_t mpic_ipi_action(int irq, void *dev_id) { - smp_message_recv(mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0); + struct mpic *mpic; + + mpic = mpic_find(irq, NULL); + smp_message_recv(mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]); + return IRQ_HANDLED; } #endif /* CONFIG_SMP */ @@ -663,7 +672,7 @@ static void mpic_end_ht_irq(unsigned int irq) static void mpic_unmask_ipi(unsigned int irq) { struct mpic *mpic = mpic_from_ipi(irq); - unsigned int src = mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0; + unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]; DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src); mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK); @@ -807,11 +816,11 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, DBG("mpic: map virq %d, hwirq 0x%lx\n", virq, hw); - if (hw == MPIC_VEC_SPURRIOUS) + if (hw == mpic->spurious_vec) return -EINVAL; #ifdef CONFIG_SMP - else if (hw >= MPIC_VEC_IPI_0) { + else if (hw >= mpic->ipi_vecs[0]) { WARN_ON(!(mpic->flags & MPIC_PRIMARY)); DBG("mpic: mapping as IPI\n"); @@ -904,6 +913,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, u32 reg; const char *vers; int i; + int intvec_top; u64 paddr = phys_addr; mpic = alloc_bootmem(sizeof(struct mpic)); @@ -912,11 +922,11 @@ struct mpic * __init mpic_alloc(struct device_node *node, memset(mpic, 0, sizeof(struct mpic)); mpic->name = name; - mpic->of_node = node ? of_node_get(node) : NULL; + mpic->of_node = of_node_get(node); - mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 256, + mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, isu_size, &mpic_host_ops, - MPIC_VEC_SPURRIOUS); + flags & MPIC_LARGE_VECTORS ? 2048 : 256); if (mpic->irqhost == NULL) { of_node_put(node); return NULL; @@ -944,6 +954,21 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic->irq_count = irq_count; mpic->num_sources = 0; /* so far */ + if (flags & MPIC_LARGE_VECTORS) + intvec_top = 2047; + else + intvec_top = 255; + + mpic->timer_vecs[0] = intvec_top - 8; + mpic->timer_vecs[1] = intvec_top - 7; + mpic->timer_vecs[2] = intvec_top - 6; + mpic->timer_vecs[3] = intvec_top - 5; + mpic->ipi_vecs[0] = intvec_top - 4; + mpic->ipi_vecs[1] = intvec_top - 3; + mpic->ipi_vecs[2] = intvec_top - 2; + mpic->ipi_vecs[3] = intvec_top - 1; + mpic->spurious_vec = intvec_top; + /* Check for "big-endian" in device-tree */ if (node && get_property(node, "big-endian", NULL) != NULL) mpic->flags |= MPIC_BIG_ENDIAN; @@ -1084,11 +1109,6 @@ void __init mpic_init(struct mpic *mpic) int i; BUG_ON(mpic->num_sources == 0); - WARN_ON(mpic->num_sources > MPIC_VEC_IPI_0); - - /* Sanitize source count */ - if (mpic->num_sources > MPIC_VEC_IPI_0) - mpic->num_sources = MPIC_VEC_IPI_0; printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources); @@ -1104,7 +1124,7 @@ void __init mpic_init(struct mpic *mpic) i * MPIC_INFO(TIMER_STRIDE) + MPIC_INFO(TIMER_VECTOR_PRI), MPIC_VECPRI_MASK | - (MPIC_VEC_TIMER_0 + i)); + (mpic->timer_vecs[0] + i)); } /* Initialize IPIs to our reserved vectors and mark them disabled for now */ @@ -1113,7 +1133,7 @@ void __init mpic_init(struct mpic *mpic) mpic_ipi_write(i, MPIC_VECPRI_MASK | (10 << MPIC_VECPRI_PRIORITY_SHIFT) | - (MPIC_VEC_IPI_0 + i)); + (mpic->ipi_vecs[0] + i)); } /* Initialize interrupt sources */ @@ -1136,8 +1156,8 @@ void __init mpic_init(struct mpic *mpic) 1 << hard_smp_processor_id()); } - /* Init spurrious vector */ - mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS); + /* Init spurious vector */ + mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), mpic->spurious_vec); /* Disable 8259 passthrough, if supported */ if (!(mpic->flags & MPIC_NO_PTHROU_DIS)) @@ -1184,9 +1204,9 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) spin_lock_irqsave(&mpic_lock, flags); if (is_ipi) { - reg = mpic_ipi_read(src - MPIC_VEC_IPI_0) & + reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) & ~MPIC_VECPRI_PRIORITY_MASK; - mpic_ipi_write(src - MPIC_VEC_IPI_0, + mpic_ipi_write(src - mpic->ipi_vecs[0], reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); } else { reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) @@ -1207,7 +1227,7 @@ unsigned int mpic_irq_get_priority(unsigned int irq) spin_lock_irqsave(&mpic_lock, flags); if (is_ipi) - reg = mpic_ipi_read(src = MPIC_VEC_IPI_0); + reg = mpic_ipi_read(src = mpic->ipi_vecs[0]); else reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); spin_unlock_irqrestore(&mpic_lock, flags); @@ -1313,7 +1333,7 @@ unsigned int mpic_get_one_irq(struct mpic *mpic) #ifdef DEBUG_LOW DBG("%s: get_one_irq(): %d\n", mpic->name, src); #endif - if (unlikely(src == MPIC_VEC_SPURRIOUS)) + if (unlikely(src == mpic->spurious_vec)) return NO_IRQ; return irq_linear_revmap(mpic->irqhost, src); } @@ -1345,7 +1365,7 @@ void mpic_request_ipis(void) for (i = 0; i < 4; i++) { unsigned int vipi = irq_create_mapping(mpic->irqhost, - MPIC_VEC_IPI_0 + i); + mpic->ipi_vecs[0] + i); if (vipi == NO_IRQ) { printk(KERN_ERR "Failed to map IPI %d\n", i); break; |