Skip to content

Commit d3a5150

Browse files
can: flexcan: flexcan_read_reg_iflag_rx(): optimize reading
The flexcan IP core has up to 64 mailboxes, each one has a corresponding interrupt bit in the iflag1 or iflag2 registers and a mask bit in the imask1 or imask2 registers. In the timestamp (i.e. non FIFO) mode the driver needs to mask all non RX interrupt sources, it uses the precomputed value rx_mask of struct flexcan_priv for this. In certain use cases, for example the CANFD mode, the contents of the iflag2 register is completely masked. This patch optimizes the flexcan_read_reg_iflag_rx() function by not reading the iflag1 or iflag2 register if the contents is masked. Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent 0ca64f0 commit d3a5150

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

drivers/net/can/flexcan.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,23 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
778778
dev->stats.rx_fifo_errors++;
779779
}
780780

781+
static inline u64 flexcan_read64_mask(struct flexcan_priv *priv, void __iomem *addr, u64 mask)
782+
{
783+
u64 reg = 0;
784+
785+
if (upper_32_bits(mask))
786+
reg = (u64)priv->read(addr - 4) << 32;
787+
if (lower_32_bits(mask))
788+
reg |= priv->read(addr);
789+
790+
return reg & mask;
791+
}
792+
793+
static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
794+
{
795+
return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->rx_mask);
796+
}
797+
781798
static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
782799
{
783800
return container_of(offload, struct flexcan_priv, offload);
@@ -872,17 +889,6 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload,
872889
return skb;
873890
}
874891

875-
static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
876-
{
877-
struct flexcan_regs __iomem *regs = priv->regs;
878-
u64 iflag;
879-
880-
iflag = (u64)priv->read(&regs->iflag2) << 32 |
881-
priv->read(&regs->iflag1);
882-
883-
return iflag & priv->rx_mask;
884-
}
885-
886892
static irqreturn_t flexcan_irq(int irq, void *dev_id)
887893
{
888894
struct net_device *dev = dev_id;

0 commit comments

Comments
 (0)