3df5afd815a3d9bef5753c95055909ea7f27fb99
[openwrt/staging/aparcar.git] /
1 From 1693e5693b77f0d172aac8adcfaa4888d64f8996 Mon Sep 17 00:00:00 2001
2 From: Marc Kleine-Budde <mkl@pengutronix.de>
3 Date: Fri, 1 Mar 2019 13:54:19 +0100
4 Subject: [PATCH] can: flexcan: introduce struct flexcan_priv::tx_mask and make
5 use of it
6
7 The current driver uses FLEXCAN_IFLAG2_MB() to generate the mask to check for
8 the TX complete interrupt. This works well, as the driver will always use the
9 last mailbox for TX, which falls into the iflag2 register.
10
11 To support CANFD the payload size has to increase to 64 bytes and the
12 number of mailboxes will decrease so much that the TX mailbox will be
13 handled in the iflag1 register.
14
15 This patch introduces a tx_mask in the struct flexcan_priv (similar to rx_mask)
16 and makes use of it. The actual support to handle the TX mailbox in iflag1 will
17 be added in the next patches.
18
19 Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
20 ---
21 drivers/net/can/flexcan.c | 14 ++++++++------
22 1 file changed, 8 insertions(+), 6 deletions(-)
23
24 --- a/drivers/net/can/flexcan.c
25 +++ b/drivers/net/can/flexcan.c
26 @@ -143,7 +143,6 @@
27 #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0
28 #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1)
29 #define FLEXCAN_IFLAG_MB(x) BIT_ULL(x)
30 -#define FLEXCAN_IFLAG2_MB(x) BIT((x) & 0x1f)
31 #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
32 #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6)
33 #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5)
34 @@ -279,6 +278,7 @@ struct flexcan_priv {
35 u8 clk_src; /* clock source of CAN Protocol Engine */
36
37 u64 rx_mask;
38 + u64 tx_mask;
39 u32 reg_ctrl_default;
40
41 struct clk *clk_ipg;
42 @@ -891,7 +891,8 @@ static irqreturn_t flexcan_irq(int irq,
43 struct flexcan_priv *priv = netdev_priv(dev);
44 struct flexcan_regs __iomem *regs = priv->regs;
45 irqreturn_t handled = IRQ_NONE;
46 - u32 reg_iflag2, reg_esr;
47 + u64 reg_iflag_tx;
48 + u32 reg_esr;
49 enum can_state last_state = priv->can.state;
50
51 /* reception interrupt */
52 @@ -925,10 +926,10 @@ static irqreturn_t flexcan_irq(int irq,
53 }
54 }
55
56 - reg_iflag2 = priv->read(&regs->iflag2);
57 + reg_iflag_tx = (u64)priv->read(&regs->iflag2) << 32;
58
59 /* transmission complete interrupt */
60 - if (reg_iflag2 & FLEXCAN_IFLAG2_MB(priv->tx_mb_idx)) {
61 + if (reg_iflag_tx & priv->tx_mask) {
62 u32 reg_ctrl = priv->read(&priv->tx_mb->can_ctrl);
63
64 handled = IRQ_HANDLED;
65 @@ -940,7 +941,7 @@ static irqreturn_t flexcan_irq(int irq,
66 /* after sending a RTR frame MB is in RX mode */
67 priv->write(FLEXCAN_MB_CODE_TX_INACTIVE,
68 &priv->tx_mb->can_ctrl);
69 - priv->write(FLEXCAN_IFLAG2_MB(priv->tx_mb_idx), &regs->iflag2);
70 + priv->write(priv->tx_mask >> 32, &regs->iflag2);
71 netif_wake_queue(dev);
72 }
73
74 @@ -1227,7 +1228,7 @@ static int flexcan_chip_start(struct net
75 /* enable interrupts atomically */
76 disable_irq(dev->irq);
77 priv->write(priv->reg_ctrl_default, &regs->ctrl);
78 - reg_imask = priv->rx_mask | FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
79 + reg_imask = priv->rx_mask | priv->tx_mask;
80 priv->write(upper_32_bits(reg_imask), &regs->imask2);
81 priv->write(lower_32_bits(reg_imask), &regs->imask1);
82 enable_irq(dev->irq);
83 @@ -1297,6 +1298,7 @@ static int flexcan_open(struct net_devic
84 flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO);
85 priv->tx_mb_idx = priv->mb_count - 1;
86 priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx);
87 + priv->tx_mask = FLEXCAN_IFLAG_MB(priv->tx_mb_idx);
88
89 priv->offload.mailbox_read = flexcan_mailbox_read;
90