Skip to content

Commit b87c28b

Browse files
can: flexcan: flexcan_irq(): add support for TX mailbox in iflag1
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. The driver will always use the last mailbox for TX, which falls into the iflag2 register. To support CANFD the payload size has to increase to 64 bytes and the number of mailboxes will decrease so much that the TX mailbox will be handled in the iflag1 register. This patch add support to handle the TX mailbox independent whether it's in iflag1 or iflag2 by introducing th flexcan_read_reg_iflag_tx() function, similar to flexcan_read_reg_iflag_rx(), for the read path. For the write path the function flexcan_write64() is added. Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent d3a5150 commit b87c28b

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

drivers/net/can/flexcan.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -790,11 +790,24 @@ static inline u64 flexcan_read64_mask(struct flexcan_priv *priv, void __iomem *a
790790
return reg & mask;
791791
}
792792

793+
static inline void flexcan_write64(struct flexcan_priv *priv, u64 val, void __iomem *addr)
794+
{
795+
if (upper_32_bits(val))
796+
priv->write(upper_32_bits(val), addr - 4);
797+
if (lower_32_bits(val))
798+
priv->write(lower_32_bits(val), addr);
799+
}
800+
793801
static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
794802
{
795803
return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->rx_mask);
796804
}
797805

806+
static inline u64 flexcan_read_reg_iflag_tx(struct flexcan_priv *priv)
807+
{
808+
return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->tx_mask);
809+
}
810+
798811
static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
799812
{
800813
return container_of(offload, struct flexcan_priv, offload);
@@ -931,7 +944,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
931944
}
932945
}
933946

934-
reg_iflag_tx = (u64)priv->read(&regs->iflag2) << 32;
947+
reg_iflag_tx = flexcan_read_reg_iflag_tx(priv);
935948

936949
/* transmission complete interrupt */
937950
if (reg_iflag_tx & priv->tx_mask) {
@@ -946,7 +959,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
946959
/* after sending a RTR frame MB is in RX mode */
947960
priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
948961
&priv->tx_mb->can_ctrl);
949-
priv->write(priv->tx_mask >> 32, &regs->iflag2);
962+
flexcan_write64(priv, priv->tx_mask, &regs->iflag1);
950963
netif_wake_queue(dev);
951964
}
952965

0 commit comments

Comments
 (0)