> diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h > index e000cce..7e1be12 100644 > --- a/arch/powerpc/include/asm/mpic.h > +++ b/arch/powerpc/include/asm/mpic.h > @@ -325,6 +325,8 @@ struct mpic > #ifdef CONFIG_PM > struct mpic_irq_save *save_data; > #endif > + > + int cpu; > };
Why ? The MPIC isn't specifically associated with a CPU and whatever we pick as default during boot isn't relevant later on, so I don't see why we should have global permanent state here. > > +static inline void mpic_init_vector(struct mpic *mpic, int source) > +{ > + /* start with vector = source number, and masked */ > + u32 vecpri = MPIC_VECPRI_MASK | source | (8 << > MPIC_VECPRI_PRIORITY_SHIFT); > + > + /* init hw */ > + mpic_irq_write(source, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); > + mpic_irq_write(source, MPIC_INFO(IRQ_DESTINATION), 1 << mpic->cpu); > +} Just pass the CPU as an argument... but better... just don't do that, put the code back where it was and ... see below :-) > /* Check if we have one of those nice broken MPICs with a flipped endian on > @@ -622,6 +631,14 @@ static unsigned int mpic_is_ipi(struct mpic *mpic, > unsigned int irq) > return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]); > } > > +/* Determine if the linux irq is a timer interrupt */ > +static unsigned int mpic_is_timer_interrupt(struct mpic *mpic, unsigned int > irq) > +{ > + unsigned int src = mpic_irq_to_hw(irq); > + > + return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[3]); > +} > + > > /* Convert a cpu mask from logical to physical cpu numbers. */ > static inline u32 mpic_physmask(u32 cpumask) > @@ -967,6 +984,15 @@ static int mpic_host_map(struct irq_host *h, unsigned > int virq, > if (hw >= mpic->irq_count) > return -EINVAL; > > + /* If the MPIC was reset, then all vectors have already been > + * initialized. Otherwise, the appropriate vector needs to be > + * initialized here to ensure that only used sources are setup with > + * a vector. > + */ > + if (mpic->flags & MPIC_NO_RESET) > + if (!(mpic_is_ipi(mpic, hw) || mpic_is_timer_interrupt(mpic, > hw))) > + mpic_init_vector(mpic, hw); > + The above isn't useful. Of those two registers you want to initialize, afaik, one (the destination) will be initialized by the core calling into set_affinity when the interrupt is requested, and the other one is partially initialized in set_type, I'd say just modify set_type to initialize the source as well, and problem solved, no ? Or is there a chance that the interrupt was left unmasked ? I think it would be kosher to mask it in set_type unconditionally, I don't think it's ever supposed to be called for an enabled interrupt. > mpic_msi_reserve_hwirq(mpic, hw); > > /* Default chip */ > @@ -1033,6 +1059,11 @@ static struct irq_host_ops mpic_host_ops = { > .xlate = mpic_host_xlate, > }; > > +static int mpic_reset_prohibited(struct device_node *node) > +{ > + return node && of_get_property(node, "pic-no-reset", NULL); > +} > + > /* > * Exported functions > */ > @@ -1153,7 +1184,16 @@ struct mpic * __init mpic_alloc(struct device_node > *node, > mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), > 0x1000); > > /* Reset */ > - if (flags & MPIC_WANTS_RESET) { > + > + /* When using a device-node, reset requests are only honored if the MPIC > + * is allowed to reset. > + */ > + if (mpic_reset_prohibited(node)) { > + mpic->flags |= MPIC_NO_RESET; > + } No { } for single line nested statements > + if ((flags & MPIC_WANTS_RESET) && !(mpic->flags & MPIC_NO_RESET)) { > + printk(KERN_DEBUG "mpic: Resetting\n"); > mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), > mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) > | MPIC_GREG_GCONF_RESET); > @@ -1270,7 +1310,6 @@ void __init mpic_set_default_senses(struct mpic *mpic, > u8 *senses, int count) > void __init mpic_init(struct mpic *mpic) > { > int i; > - int cpu; > > BUG_ON(mpic->num_sources == 0); > > @@ -1314,21 +1353,17 @@ void __init mpic_init(struct mpic *mpic) > mpic_pasemi_msi_init(mpic); > > if (mpic->flags & MPIC_PRIMARY) > - cpu = hard_smp_processor_id(); > + mpic->cpu = hard_smp_processor_id(); > else > - cpu = 0; > + mpic->cpu = 0; Get rid of all that. > - 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); > - > - /* check if protected */ > - if (mpic->protected && test_bit(i, mpic->protected)) > - continue; > - /* init hw */ > - mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); > - mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), 1 << cpu); > + if (!(mpic->flags & MPIC_NO_RESET)) { > + for (i = 0; i < mpic->num_sources; i++) { > + /* check if protected */ > + if (mpic->protected && test_bit(i, mpic->protected)) > + continue; > + mpic_init_vector(mpic, i); > + } > } > > /* Init spurious vector */ Cheers, Ben. _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev