can: fix sja1000 post_irq handling and resulting return value
This patch fixes the issue that the sja1000_interrupt() function may have returned IRQ_NONE without processing the optional post_irq function before. Additionally the irq processing counter 'n' is moved to the end of the while statement to return correct IRQ_[NONE|HANDLED] values at error conditions.
---
drivers/net/can/sja1000/sja1000.c +9 -8
@@ -494,20 +494,20 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)uint8_t isrc, status;int n =0 ; -/* Shared interrupts and IRQ off? */ -if (priv->read_reg (priv,SJA1000_IER ) ==IRQ_OFF ) -return IRQ_NONE ; -if (priv->pre_irq) priv->pre_irq (priv); +/* Shared interrupts and IRQ off? */ +if (priv->read_reg (priv,SJA1000_IER ) ==IRQ_OFF ) + goto out; +while ((isrc = priv->read_reg (priv,SJA1000_IR )) && (n <SJA1000_MAX_IRQ )) { - n++; + status = priv->read_reg (priv,SJA1000_SR );/* check for absent controller due to hw unplug */ if (status ==0xFF &&sja1000_is_absent (priv)) -return IRQ_NONE ; + goto out;if (isrc &IRQ_WUI )netdev_warn (dev,"wakeup interrupt\n" );
@@ -535,7 +535,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) status = priv->read_reg (priv,SJA1000_SR );/* check for absent controller */ if (status ==0xFF &&sja1000_is_absent (priv)) -return IRQ_NONE ; + goto out; } }if (isrc & (IRQ_DOI |IRQ_EI |IRQ_BEI |IRQ_EPI |IRQ_ALI )) {
@@ -543,8 +543,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)if (sja1000_err (dev, isrc, status))break ; } + n++; } - +out:if (priv->post_irq) priv->post_irq (priv);
Quoted 5 lines · Oliver Hartkopp
This patch fixes the issue that the
sja1000_interrupt()function may have returnedIRQ_NONEwithout processing the optionalpost_irqfunction before. Additionally the irq processing counter 'n' is moved to the end of the while statement to return correct IRQ_[NONE|HANDLED] values at error conditions.
8-)
Quoted 60 lines
---
drivers/net/can/sja1000/sja1000.c +9
-9@@ -494,20 +494,20 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)uint8_t isrc, status;int n =0 ; -/* Shared interrupts and IRQ off? */ -if (priv->read_reg (priv,SJA1000_IER ) ==IRQ_OFF ) -return IRQ_NONE ; -if (priv->pre_irq) priv->pre_irq (priv); +/* Shared interrupts and IRQ off? */ +if (priv->read_reg (priv,SJA1000_IER ) ==IRQ_OFF ) + goto out; +while ((isrc = priv->read_reg (priv,SJA1000_IR )) && (n <SJA1000_MAX_IRQ )) { - n++; + status = priv->read_reg (priv,SJA1000_SR );/* check for absent controller due to hw unplug */ if (status ==0xFF &&sja1000_is_absent (priv)) -return IRQ_NONE ; + goto out;if (isrc &IRQ_WUI )netdev_warn (dev,"wakeup interrupt\n" );@@ -535,7 +535,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) status = priv->read_reg (priv,SJA1000_SR );/* check for absent controller */ if (status ==0xFF &&sja1000_is_absent (priv)) -return IRQ_NONE ; + goto out; } }if (isrc & (IRQ_DOI |IRQ_EI |IRQ_BEI |IRQ_EPI |IRQ_ALI )) {@@ -543,8 +543,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)if (sja1000_err (dev, isrc, status))break ; } + n++; } - +out:if (priv->post_irq) priv->post_irq (priv); --To unsubscribe from this list: send the line "unsubscribe linux-can" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html