[PATCH] can: m_can: m_can_isr: IR_ERR_ALL_30X

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



For m_can version >3.0 the correct IR_ERR_ALL_31X mask is used.
If an error occurs when processing RX status flags, the TX flags are processed anyway.

I am not sure, but maybe it is better to save IR to cdev->irqstatus
immediately before clear IR and not only by RX-Flags handling.

As far as I have seen, cdev->irqstatus is not accessed by tx-handling, therefore it does not matter.

This is my first patch, sorry if something is not right.

---
 drivers/net/can/m_can/m_can.c | 33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 1a4b56f6fa8c..eb9fd9c846a2 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -1053,6 +1053,7 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)
 {
 	struct net_device *dev = (struct net_device *)dev_id;
 	struct m_can_classdev *cdev = netdev_priv(dev);
+	int err=0;
 	u32 ir;

 	if (pm_runtime_suspended(cdev->dev))
@@ -1073,16 +1074,17 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)
 	 * - state change IRQ
 	 * - bus error IRQ and bus error reporting
 	 */
-	if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_30X)) {
-		cdev->irqstatus = ir;
-		m_can_disable_all_interrupts(cdev);
-		if (!cdev->is_peripheral)
-			napi_schedule(&cdev->napi);
-		else if (m_can_rx_peripheral(dev) < 0)
-			goto out_fail;
-	}
-
 	if (cdev->version == 30) {
+
+		if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_30X)) {
+			cdev->irqstatus = ir;
+			m_can_disable_all_interrupts(cdev);
+			if (!cdev->is_peripheral)
+				napi_schedule(&cdev->napi);
+			else if (m_can_rx_peripheral(dev) < 0)
+				err=-1;
+		}
+
 		if (ir & IR_TC) {
 			/* Transmission Complete Interrupt*/
 			u32 timestamp = 0;
@@ -1095,10 +1097,18 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)
 			netif_wake_queue(dev);
 		}
 	} else  {
+		if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_31X)) {
+			cdev->irqstatus = ir;
+			m_can_disable_all_interrupts(cdev);
+			if (!cdev->is_peripheral)
+				napi_schedule(&cdev->napi);
+			else if (m_can_rx_peripheral(dev) < 0)
+				err=-2;
+		}
 		if (ir & IR_TEFN) {
 			/* New TX FIFO Element arrived */
 			if (m_can_echo_tx_event(dev) != 0)
-				goto out_fail;
+				err=-2;

 			can_led_event(dev, CAN_LED_EVENT_TX);
 			if (netif_queue_stopped(dev) &&
@@ -1107,6 +1117,9 @@ static irqreturn_t m_can_isr(int irq, void *dev_id)
 		}
 	}

+	if (err)
+		goto out_fail;
+
 	if (cdev->is_peripheral)
 		can_rx_offload_threaded_irq_finish(&cdev->offload);

--
2.20.1



[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux