> 
> > +   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

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to