[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