[PATCH] qe_ic: Do a sync when masking interrupts.

Li Yang-r58472 LeoLi at freescale.com
Fri Oct 20 13:03:30 EST 2006


> -----Original Message-----
> From: linuxppc-dev-bounces+leoli=freescale.com at ozlabs.org
> [mailto:linuxppc-dev-bounces+leoli=freescale.com at ozlabs.org] On Behalf
Of Scott
> Wood
> Sent: Friday, October 20, 2006 2:03 AM
> To: linuxppc-dev at ozlabs.org
> Subject: [PATCH] qe_ic: Do a sync when masking interrupts.
> 
> This patch causes a sync do be done after masking a QE interrupt, to
> ensure that the masking has completed before interrupts are enabled.
> This allows the masking of the cascade IRQ to be removed without
causing
> spurious interrupts.
> 
> The mask_and_ack function is also removed and set to the mask
function,
> as the two are identical.
> 
> Signed-off-by: Scott Wood <scottwood at freescale.com>

Acked-by: Li Yang <leoli at freescale.com>
> ---
>  arch/powerpc/sysdev/qe_lib/qe_ic.c |   34
+++++++---------------------------
>  1 files changed, 7 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c
> b/arch/powerpc/sysdev/qe_lib/qe_ic.c
> index 6995f51..d96e48d 100644
> --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
> +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
> @@ -222,24 +222,12 @@ static void qe_ic_mask_irq(unsigned int
>  	temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
>  	qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
>  		    temp & ~qe_ic_info[src].mask);
> -
> -	spin_unlock_irqrestore(&qe_ic_lock, flags);
> -}
> -
> -static void qe_ic_mask_irq_and_ack(unsigned int virq)
> -{
> -	struct qe_ic *qe_ic = qe_ic_from_irq(virq);
> -	unsigned int src = virq_to_hw(virq);
> -	unsigned long flags;
> -	u32 temp;
> -
> -	spin_lock_irqsave(&qe_ic_lock, flags);
> -
> -	temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
> -	qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
> -		    temp & ~qe_ic_info[src].mask);
> -
> -	/* There is nothing to do for ack here, ack is handled in ISR */
> +
> +	/* Flush the above write before enabling interrupts;
> +	 * otherwise, spurious interrupts will sometimes
> +	 * happen
> +	 */
> +	mb();
> 
>  	spin_unlock_irqrestore(&qe_ic_lock, flags);
>  }
> @@ -248,7 +236,7 @@ static struct irq_chip qe_ic_irq_chip =
>  	.typename = " QEIC  ",
>  	.unmask = qe_ic_unmask_irq,
>  	.mask = qe_ic_mask_irq,
> -	.mask_ack = qe_ic_mask_irq_and_ack,
> +	.mask_ack = qe_ic_mask_irq,
>  };
> 
>  static int qe_ic_host_match(struct irq_host *h, struct device_node
*node)
> @@ -331,8 +319,6 @@ unsigned int qe_ic_get_high_irq(struct q
>  	return irq_linear_revmap(qe_ic->irqhost, irq);
>  }
> 
> -/* FIXME: We mask all the QE Low interrupts while handling.  We
should
> - * let other interrupt come in, but BAD interrupts are generated */
>  void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc
*desc)
>  {
>  	struct qe_ic *qe_ic = desc->handler_data;
> @@ -340,14 +326,10 @@ void fastcall qe_ic_cascade_low(unsigned
> 
>  	unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
> 
> -	chip->mask_ack(irq);
>  	if (cascade_irq != NO_IRQ)
>  		generic_handle_irq(cascade_irq);
> -	chip->unmask(irq);
>  }
> 
> -/* FIXME: We mask all the QE High interrupts while handling.  We
should
> - * let other interrupt come in, but BAD interrupts are generated */
>  void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc
*desc)
>  {
>  	struct qe_ic *qe_ic = desc->handler_data;
> @@ -355,10 +337,8 @@ void fastcall qe_ic_cascade_high(unsigne
> 
>  	unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
> 
> -	chip->mask_ack(irq);
>  	if (cascade_irq != NO_IRQ)
>  		generic_handle_irq(cascade_irq);
> -	chip->unmask(irq);
>  }
> 
>  void __init qe_ic_init(struct device_node *node, unsigned int flags)
> --
> 1.4.2.3
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev



More information about the Linuxppc-dev mailing list