From 73042934e4a30d9f45ff9cb0b3b029a01dbe7130 Mon Sep 17 00:00:00 2001 From: Markus Schneider-Pargmann Date: Wed, 15 Mar 2023 12:05:31 +0100 Subject: [PATCH 1/5] can: m_can: Remove repeated check for is_peripheral Merge both if-blocks to fix this. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Link: https://lore.kernel.org/all/20230315110546.2518305-2-msp@baylibre.com Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 8e83d6963d85..563625a701fc 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1592,10 +1592,8 @@ static int m_can_close(struct net_device *dev) cdev->tx_skb = NULL; destroy_workqueue(cdev->tx_wq); cdev->tx_wq = NULL; - } - - if (cdev->is_peripheral) can_rx_offload_disable(&cdev->offload); + } close_candev(dev); From 4ab639480900be41d7c7c0b89a6db7fa5fe951e4 Mon Sep 17 00:00:00 2001 From: Markus Schneider-Pargmann Date: Wed, 15 Mar 2023 12:05:32 +0100 Subject: [PATCH 2/5] can: m_can: Always acknowledge all interrupts The code already exits the function on !ir before this condition. No need to check again if anything is set as IR_ALL_INT is 0xffffffff. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Link: https://lore.kernel.org/all/20230315110546.2518305-3-msp@baylibre.com Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 563625a701fc..8eb327ae3bdf 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1083,8 +1083,7 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) return IRQ_NONE; /* ACK all irqs */ - if (ir & IR_ALL_INT) - m_can_write(cdev, M_CAN_IR, ir); + m_can_write(cdev, M_CAN_IR, ir); if (cdev->ops->clear_interrupts) cdev->ops->clear_interrupts(cdev); From 71725bfdbbf263ec4897ce310087d3f6bd331c19 Mon Sep 17 00:00:00 2001 From: Markus Schneider-Pargmann Date: Wed, 15 Mar 2023 12:05:33 +0100 Subject: [PATCH 3/5] can: m_can: Remove double interrupt enable Interrupts are enabled a few lines further down as well. Remove this second call to enable all interrupts. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Link: https://lore.kernel.org/all/20230315110546.2518305-4-msp@baylibre.com Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 8eb327ae3bdf..5274d9642566 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1364,7 +1364,6 @@ static int m_can_chip_config(struct net_device *dev) m_can_write(cdev, M_CAN_TEST, test); /* Enable interrupts */ - m_can_write(cdev, M_CAN_IR, IR_ALL_INT); if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) if (cdev->version == 30) m_can_write(cdev, M_CAN_IE, IR_ALL_INT & From 897e663218e2d05607a6f5b258134cb026a2fa85 Mon Sep 17 00:00:00 2001 From: Markus Schneider-Pargmann Date: Wed, 15 Mar 2023 12:05:34 +0100 Subject: [PATCH 4/5] can: m_can: Disable unused interrupts There are a number of interrupts that are not used by the driver at the moment. Disable all of these. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Link: https://lore.kernel.org/all/20230315110546.2518305-5-msp@baylibre.com Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 5274d9642566..e7aceeba3759 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1261,6 +1261,7 @@ static int m_can_set_bittiming(struct net_device *dev) static int m_can_chip_config(struct net_device *dev) { struct m_can_classdev *cdev = netdev_priv(dev); + u32 interrupts = IR_ALL_INT; u32 cccr, test; int err; @@ -1270,6 +1271,11 @@ static int m_can_chip_config(struct net_device *dev) return err; } + /* Disable unused interrupts */ + interrupts &= ~(IR_ARA | IR_ELO | IR_DRX | IR_TEFF | IR_TEFW | IR_TFE | + IR_TCF | IR_HPM | IR_RF1F | IR_RF1W | IR_RF1N | + IR_RF0F | IR_RF0W); + m_can_config_endisable(cdev, true); /* RX Buffer/FIFO Element Size 64 bytes data field */ @@ -1364,15 +1370,13 @@ static int m_can_chip_config(struct net_device *dev) m_can_write(cdev, M_CAN_TEST, test); /* Enable interrupts */ - if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) + if (!(cdev->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) { if (cdev->version == 30) - m_can_write(cdev, M_CAN_IE, IR_ALL_INT & - ~(IR_ERR_LEC_30X)); + interrupts &= ~(IR_ERR_LEC_30X); else - m_can_write(cdev, M_CAN_IE, IR_ALL_INT & - ~(IR_ERR_LEC_31X)); - else - m_can_write(cdev, M_CAN_IE, IR_ALL_INT); + interrupts &= ~(IR_ERR_LEC_31X); + } + m_can_write(cdev, M_CAN_IE, interrupts); /* route all interrupts to INT0 */ m_can_write(cdev, M_CAN_ILS, ILS_ALL_INT0); From 9083e0b09df33376abef2bb28e6a4b0c88f4d00b Mon Sep 17 00:00:00 2001 From: Markus Schneider-Pargmann Date: Wed, 15 Mar 2023 12:05:35 +0100 Subject: [PATCH 5/5] can: m_can: Keep interrupts enabled during peripheral read Interrupts currently get disabled if the interrupt status shows new received data. Non-peripheral chips handle receiving in a worker thread, but peripheral chips are handling the receive process in the threaded interrupt routine itself without scheduling it for a different worker. So there is no need to disable interrupts for peripheral chips. Signed-off-by: Markus Schneider-Pargmann Reviewed-by: Simon Horman Link: https://lore.kernel.org/all/20230315110546.2518305-6-msp@baylibre.com Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index e7aceeba3759..a5003435802b 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -972,8 +972,8 @@ static int m_can_rx_peripheral(struct net_device *dev, u32 irqstatus) /* Don't re-enable interrupts if the driver had a fatal error * (e.g., FIFO read failure). */ - if (work_done >= 0) - m_can_enable_all_interrupts(cdev); + if (work_done < 0) + m_can_disable_all_interrupts(cdev); return work_done; } @@ -1095,11 +1095,12 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) */ if ((ir & IR_RF0N) || (ir & IR_ERR_ALL_30X)) { cdev->irqstatus = ir; - m_can_disable_all_interrupts(cdev); - if (!cdev->is_peripheral) + if (!cdev->is_peripheral) { + m_can_disable_all_interrupts(cdev); napi_schedule(&cdev->napi); - else if (m_can_rx_peripheral(dev, ir) < 0) + } else if (m_can_rx_peripheral(dev, ir) < 0) { goto out_fail; + } } if (cdev->version == 30) {