This patch drastically reduces the amount of SPI transactions needed in the ISR of the driver. This can have a significant performance impact.
Signed-off-by: David Jander <[email protected]> --- drivers/net/can/mcp251x.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 files changed, 34 insertions(+), 8 deletions(-) diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index b11a0cb..32037d8 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -319,6 +319,20 @@ static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg) return val; } +static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg, + uint8_t *v1, uint8_t *v2) +{ + struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); + + priv->spi_tx_buf[0] = INSTRUCTION_READ; + priv->spi_tx_buf[1] = reg; + + mcp251x_spi_trans(spi, 4); + + *v1 = priv->spi_rx_buf[2]; + *v2 = priv->spi_rx_buf[3]; +} + static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); @@ -330,6 +344,18 @@ static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val) mcp251x_spi_trans(spi, 3); } +static void mcp251x_write_2regs(struct spi_device *spi, u8 reg, uint8_t v1, uint8_t v2) +{ + struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); + + priv->spi_tx_buf[0] = INSTRUCTION_WRITE; + priv->spi_tx_buf[1] = reg; + priv->spi_tx_buf[2] = v1; + priv->spi_tx_buf[3] = v2; + + mcp251x_spi_trans(spi, 4); +} + static void mcp251x_write_bits(struct spi_device *spi, u8 reg, u8 mask, uint8_t val) { @@ -754,25 +780,23 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) mutex_lock(&priv->mcp_lock); while (!priv->force_quit) { enum can_state new_state; - u8 intf = mcp251x_read_reg(spi, CANINTF); + u8 intf; u8 eflag; int can_id = 0, data1 = 0; + mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); + if (intf & CANINTF_RX0IF) { mcp251x_hw_rx(spi, 0); /* Free one buffer ASAP */ - mcp251x_write_bits(spi, CANINTF, intf & CANINTF_RX0IF, - 0x00); + if (intf & CANINTF_RX1IF) + mcp251x_write_bits(spi, CANINTF, + intf & CANINTF_RX0IF, 0x00); } if (intf & CANINTF_RX1IF) mcp251x_hw_rx(spi, 1); - mcp251x_write_bits(spi, CANINTF, intf, 0x00); - - eflag = mcp251x_read_reg(spi, EFLG); - mcp251x_write_reg(spi, EFLG, 0x00); - /* Update can state */ if (eflag & EFLG_TXBO) { new_state = CAN_STATE_BUS_OFF; @@ -838,6 +862,8 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) if (intf == 0) break; + mcp251x_write_2regs(spi, CANINTF, 0x00, 0x00); + if (intf & (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)) { net->stats.tx_packets++; net->stats.tx_bytes += priv->tx_len - 1; -- 1.6.3.3 _______________________________________________ Socketcan-core mailing list [email protected] https://lists.berlios.de/mailman/listinfo/socketcan-core
