[PATCH 3/3 v2] powerpc/mpic: FSL MPIC error interrupt support.
Sethi Varun-B16395
B16395 at freescale.com
Tue Jul 10 19:26:35 EST 2012
>
> > + u32 eisr, eimr;
> > + int errint;
> > + unsigned int cascade_irq;
> > +
> > + eisr = fsl_mpic_err_read(mpic->err_regs, eisr_offset);
> > + eimr = fsl_mpic_err_read(mpic->err_regs, eimr_offset);
> > +
> > + if (!(eisr & ~eimr))
> > + return IRQ_NONE;
> > +
> > + while (eisr) {
> > + errint = __builtin_clz(eisr);
> > + cascade_irq = irq_linear_revmap(mpic->irqhost,
> > + mpic->err_int_vecs[errint]);
> > + WARN_ON(cascade_irq == NO_IRQ);
> > + if (cascade_irq != NO_IRQ) {
> > + generic_handle_irq(cascade_irq);
> > + } else {
> > + eimr |= 1 << (31 - errint);
> > + fsl_mpic_err_write(mpic->err_regs, eimr_offset, eimr);
> > + }
> > + eisr &= ~(1 << (31 - errint));
> > + }
> > +
> > + return IRQ_HANDLED;
> > +}
> > +
> > +int mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum) {
>
> Why can't we do this during mpic_init() time?
>
[Sethi Varun-B16395] Don't want to hard code the error interrupt number.
> > + unsigned int virq;
> > + unsigned int offset = MPIC_ERR_INT_EIMR;
>
> remove offset, just use MPIC_ERR_INT_EIMR in mpic_err_write
>
> > + int ret;
> > +
> > + virq = irq_create_mapping(mpic->irqhost, irqnum);
> > + if (virq == NO_IRQ) {
> > + pr_err("Error interrupt setup failed\n");
> > + return -ENOSPC;
> > + }
> > +
> > + fsl_mpic_err_write(mpic->err_regs, offset, ~0);
>
> Add a comment about what this line is doing
>
[Sethi Varun-B16395] We are masking all the error interrupts here. I
Will add a comment for this.
> > +
> > + ret = request_irq(virq, fsl_error_int_handler, IRQF_NO_THREAD,
> > + "mpic-error-int", mpic);
>
> Hmm, should we be using irq_set_chained_handler() instead of request_irq
>
> > + if (ret) {
> > + pr_err("Failed to register error interrupt handler\n");
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> > index 61c7225..7002ef3 100644
> > --- a/arch/powerpc/sysdev/mpic.c
> > +++ b/arch/powerpc/sysdev/mpic.c
> > @@ -1026,6 +1026,9 @@ static int mpic_host_map(struct irq_domain *h,
> unsigned int virq,
> > return 0;
> > }
> >
> > + if (mpic_map_error_int(mpic, virq, hw))
> > + return 0;
> > +
> > if (hw >= mpic->num_sources)
> > return -EINVAL;
> >
> > @@ -1085,7 +1088,24 @@ static int mpic_host_xlate(struct irq_domain *h,
> struct device_node *ct,
> > */
> > switch (intspec[2]) {
> > case 0:
> > - case 1: /* no EISR/EIMR support for now, treat as shared IRQ
> */
> > + break;
> > + case 1:
> > + if (!(mpic->flags & MPIC_FSL_HAS_EIMR))
> > + break;
> > +
> > + if (intspec[3] >= ARRAY_SIZE(mpic->err_int_vecs))
> > + return -EINVAL;
> > +
> > + if (!mpic->err_int_config_done) {
> > + int ret;
> > + ret = mpic_err_int_init(mpic, intspec[0]);
> > + if (ret)
> > + return ret;
> > + mpic->err_int_config_done = 1;
> > + }
> > +
> > + *out_hwirq = mpic->err_int_vecs[intspec[3]];
> > +
> > break;
> > case 2:
> > if (intspec[0] >= ARRAY_SIZE(mpic->ipi_vecs)) @@ -
> 1302,6 +1322,8 @@
> > struct mpic * __init mpic_alloc(struct device_node *node,
> > mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE),
> > 0x1000);
> >
> > if (mpic->flags & MPIC_FSL) {
> > + u32 brr1, version;
> > +
> > /*
> > * Yes, Freescale really did put global registers in the
> > * magic per-cpu area -- and they don't even show up in the
> @@
> > -1309,6 +1331,17 @@ struct mpic * __init mpic_alloc(struct device_node
> *node,
> > */
> > mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
> > MPIC_CPU_THISBASE, 0x1000);
> > +
> > + brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
> > + MPIC_FSL_BRR1);
> > + version = brr1 & MPIC_FSL_BRR1_VER;
> > +
> > + /* Error interrupt mask register (EIMR) is required for
> > + * handling individual device error interrupts. EIMR
> > + * was added in MPIC version 4.1.
> > + */
> > + if (version >= 0x401)
> > + mpic_setup_error_int(mpic, intvec_top - 12);
>
> Would really like not to have this magic 12, but a comment would be nice
> if we keep it where the 12 comes from
>
[Sethi Varun-B16395]Obtaining vector numbers beyond ipi and timers for the error interrupts.
Will add a comment.
-Varun
More information about the Linuxppc-dev
mailing list