12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- From 57d3edbdcfee9b677452744bba5c4f08b476872a Mon Sep 17 00:00:00 2001
- From: Marc Kleine-Budde <[email protected]>
- Date: Fri, 1 Mar 2019 15:38:05 +0100
- Subject: [PATCH] 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]>
- ---
- drivers/net/can/flexcan.c | 17 +++++++++++++++--
- 1 file changed, 15 insertions(+), 2 deletions(-)
- --- a/drivers/net/can/flexcan.c
- +++ b/drivers/net/can/flexcan.c
- @@ -792,11 +792,24 @@ static inline u64 flexcan_read64_mask(st
- return reg & mask;
- }
-
- +static inline void flexcan_write64(struct flexcan_priv *priv, u64 val, void __iomem *addr)
- +{
- + if (upper_32_bits(val))
- + priv->write(upper_32_bits(val), addr - 4);
- + if (lower_32_bits(val))
- + priv->write(lower_32_bits(val), addr);
- +}
- +
- static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv)
- {
- return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->rx_mask);
- }
-
- +static inline u64 flexcan_read_reg_iflag_tx(struct flexcan_priv *priv)
- +{
- + return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->tx_mask);
- +}
- +
- static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
- {
- return container_of(offload, struct flexcan_priv, offload);
- @@ -933,7 +946,7 @@ static irqreturn_t flexcan_irq(int irq,
- }
- }
-
- - reg_iflag_tx = (u64)priv->read(®s->iflag2) << 32;
- + reg_iflag_tx = flexcan_read_reg_iflag_tx(priv);
-
- /* transmission complete interrupt */
- if (reg_iflag_tx & priv->tx_mask) {
- @@ -948,7 +961,7 @@ static irqreturn_t flexcan_irq(int irq,
- /* after sending a RTR frame MB is in RX mode */
- priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
- &priv->tx_mb->can_ctrl);
- - priv->write(priv->tx_mask >> 32, ®s->iflag2);
- + flexcan_write64(priv, priv->tx_mask, ®s->iflag1);
- netif_wake_queue(dev);
- }
-
|