802-can-0015-can-flexcan-flexcan_read_reg_iflag_rx-optimize-readi.patch 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. From 74920ba156136a58dd3411c02d429d4f31497dc0 Mon Sep 17 00:00:00 2001
  2. From: Marc Kleine-Budde <[email protected]>
  3. Date: Fri, 1 Mar 2019 15:38:05 +0100
  4. Subject: [PATCH] can: flexcan: flexcan_read_reg_iflag_rx(): optimize reading
  5. The flexcan IP core has up to 64 mailboxes, each one has a corresponding
  6. interrupt bit in the iflag1 or iflag2 registers and a mask bit in the
  7. imask1 or imask2 registers.
  8. In the timestamp (i.e. non FIFO) mode the driver needs to mask all non RX
  9. interrupt sources, it uses the precomputed value rx_mask of struct flexcan_priv
  10. for this.
  11. In certain use cases, for example the CANFD mode, the contents of the iflag2
  12. register is completely masked.
  13. This patch optimizes the flexcan_read_reg_iflag_rx() function by not reading
  14. the iflag1 or iflag2 register if the contents is masked.
  15. Signed-off-by: Marc Kleine-Budde <[email protected]>
  16. ---
  17. drivers/net/can/flexcan.c | 28 +++++++++++++++++-----------
  18. 1 file changed, 17 insertions(+), 11 deletions(-)
  19. --- a/drivers/net/can/flexcan.c
  20. +++ b/drivers/net/can/flexcan.c
  21. @@ -780,6 +780,23 @@ static void flexcan_irq_state(struct net
  22. dev->stats.rx_fifo_errors++;
  23. }
  24. +static inline u64 flexcan_read64_mask(struct flexcan_priv *priv, void __iomem *addr, u64 mask)
  25. +{
  26. + u64 reg = 0;
  27. +
  28. + if (upper_32_bits(mask))
  29. + reg = (u64)priv->read(addr - 4) << 32;
  30. + if (lower_32_bits(mask))
  31. + reg |= priv->read(addr);
  32. +
  33. + return reg & mask;
  34. +}
  35. +
  36. +static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
  37. +{
  38. + return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->rx_mask);
  39. +}
  40. +
  41. static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
  42. {
  43. return container_of(offload, struct flexcan_priv, offload);
  44. @@ -874,17 +891,6 @@ static struct sk_buff *flexcan_mailbox_r
  45. return skb;
  46. }
  47. -static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
  48. -{
  49. - struct flexcan_regs __iomem *regs = priv->regs;
  50. - u64 iflag;
  51. -
  52. - iflag = (u64)priv->read(&regs->iflag2) << 32 |
  53. - priv->read(&regs->iflag1);
  54. -
  55. - return iflag & priv->rx_mask;
  56. -}
  57. -
  58. static irqreturn_t flexcan_irq(int irq, void *dev_id)
  59. {
  60. struct net_device *dev = dev_id;