M_CAN-based devices such as TI TCAN4550 have device-specific interrupts which are not part of the M_CAN core, but are signaled on the same interrupt pin. Therefore, replace the clear_interrupts callback with handle_dev_interrupts, which can handle and clear interrupts, returning irqreturn_t. The clear_only argument is added to retain the option of clearing interrupts without any handling, for the purpose of saving overhead due to register accesses. Signed-off-by: Torin Cooper-Bennun <torin@xxxxxxxxxxxxxxxxxx> --- drivers/net/can/m_can/m_can.c | 4 ++-- drivers/net/can/m_can/m_can.h | 4 +++- drivers/net/can/m_can/tcan4x5x-core.c | 9 ++++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 34073cd077e4..fa853201d2c4 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1044,8 +1044,8 @@ static irqreturn_t m_can_isr(int irq, void *dev_id) if (ir & IR_ALL_INT) m_can_write(cdev, M_CAN_IR, ir); - if (cdev->ops->clear_interrupts) - cdev->ops->clear_interrupts(cdev); + if (cdev->ops->handle_dev_interrupts) + cdev->ops->handle_dev_interrupts(cdev, true); /* schedule NAPI in case of * - rx IRQ diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h index ace071c3e58c..81d201aa5af2 100644 --- a/drivers/net/can/m_can/m_can.h +++ b/drivers/net/can/m_can/m_can.h @@ -28,6 +28,7 @@ #include <linux/iopoll.h> #include <linux/can/dev.h> #include <linux/pinctrl/consumer.h> +#include <linux/irqreturn.h> /* m_can lec values */ enum m_can_lec_type { @@ -61,7 +62,8 @@ struct mram_cfg { struct m_can_classdev; struct m_can_ops { /* Device specific call backs */ - int (*clear_interrupts)(struct m_can_classdev *cdev); + irqreturn_t (*handle_dev_interrupts)(struct m_can_classdev *cdev, + bool clear_only); u32 (*read_reg)(struct m_can_classdev *cdev, int reg); int (*write_reg)(struct m_can_classdev *cdev, int reg, int val); u32 (*read_fifo)(struct m_can_classdev *cdev, int addr_offset); diff --git a/drivers/net/can/m_can/tcan4x5x-core.c b/drivers/net/can/m_can/tcan4x5x-core.c index 4147cecfbbd6..b4aeab10d62f 100644 --- a/drivers/net/can/m_can/tcan4x5x-core.c +++ b/drivers/net/can/m_can/tcan4x5x-core.c @@ -221,6 +221,13 @@ static int tcan4x5x_clear_interrupts(struct m_can_classdev *cdev) TCAN4X5X_CLEAR_ALL_INT); } +static irqreturn_t tcan4x5x_handle_dev_interrupts(struct m_can_classdev *cdev, + bool clear_only) +{ + tcan4x5x_clear_interrupts(cdev); + return IRQ_NONE; +} + static int tcan4x5x_init(struct m_can_classdev *cdev) { struct tcan4x5x_priv *tcan4x5x = cdev_to_priv(cdev); @@ -304,7 +311,7 @@ static struct m_can_ops tcan4x5x_ops = { .write_reg = tcan4x5x_write_reg, .write_fifo = tcan4x5x_write_fifo, .read_fifo = tcan4x5x_read_fifo, - .clear_interrupts = tcan4x5x_clear_interrupts, + .handle_dev_interrupts = tcan4x5x_handle_dev_interrupts, }; static int tcan4x5x_can_probe(struct spi_device *spi) -- 2.30.2