OpenWrt – Blame information for rev 2
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 3ed707fde8a33f2b888f75ac2f5e0a98e7774dad Mon Sep 17 00:00:00 2001 |
2 | From: Biwen Li <biwen.li@nxp.com> |
||
3 | Date: Tue, 30 Oct 2018 18:26:27 +0800 |
||
4 | Subject: [PATCH 26/40] flexcan: support layerscape |
||
5 | This is an integrated patch of flexcan for layerscape |
||
6 | |||
7 | Signed-off-by: Bhupesh Sharma <bhupesh.sharma@freescale.com> |
||
8 | Signed-off-by: Guanhua Gao <guanhua.gao@nxp.com> |
||
9 | Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com> |
||
10 | Signed-off-by: Sakar Arora <Sakar.Arora@freescale.com> |
||
11 | Signed-off-by: Biwen Li <biwen.li@nxp.com> |
||
12 | --- |
||
13 | drivers/net/can/flexcan.c | 240 ++++++++++++++++++++++---------------- |
||
14 | 1 file changed, 138 insertions(+), 102 deletions(-) |
||
15 | |||
16 | --- a/drivers/net/can/flexcan.c |
||
17 | +++ b/drivers/net/can/flexcan.c |
||
18 | @@ -190,6 +190,7 @@ |
||
19 | * MX53 FlexCAN2 03.00.00.00 yes no no no no |
||
20 | * MX6s FlexCAN3 10.00.12.00 yes yes no no yes |
||
21 | * VF610 FlexCAN3 ? no yes no yes yes? |
||
22 | + * LS1021A FlexCAN2 03.00.04.00 no yes no yes |
||
23 | * |
||
24 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. |
||
25 | */ |
||
26 | @@ -279,6 +280,10 @@ struct flexcan_priv { |
||
27 | struct clk *clk_per; |
||
28 | const struct flexcan_devtype_data *devtype_data; |
||
29 | struct regulator *reg_xceiver; |
||
30 | + |
||
31 | + /* Read and Write APIs */ |
||
32 | + u32 (*read)(void __iomem *addr); |
||
33 | + void (*write)(u32 val, void __iomem *addr); |
||
34 | }; |
||
35 | |||
36 | static const struct flexcan_devtype_data fsl_p1010_devtype_data = { |
||
37 | @@ -301,6 +306,11 @@ static const struct flexcan_devtype_data |
||
38 | FLEXCAN_QUIRK_BROKEN_PERR_STATE, |
||
39 | }; |
||
40 | |||
41 | +static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = { |
||
42 | + .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
||
43 | + FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, |
||
44 | +}; |
||
45 | + |
||
46 | static const struct can_bittiming_const flexcan_bittiming_const = { |
||
47 | .name = DRV_NAME, |
||
48 | .tseg1_min = 4, |
||
49 | @@ -313,39 +323,45 @@ static const struct can_bittiming_const |
||
50 | .brp_inc = 1, |
||
51 | }; |
||
52 | |||
53 | -/* Abstract off the read/write for arm versus ppc. This |
||
54 | - * assumes that PPC uses big-endian registers and everything |
||
55 | - * else uses little-endian registers, independent of CPU |
||
56 | - * endianness. |
||
57 | +/* FlexCAN module is essentially modelled as a little-endian IP in most |
||
58 | + * SoCs, i.e the registers as well as the message buffer areas are |
||
59 | + * implemented in a little-endian fashion. |
||
60 | + * |
||
61 | + * However there are some SoCs (e.g. LS1021A) which implement the FlexCAN |
||
62 | + * module in a big-endian fashion (i.e the registers as well as the |
||
63 | + * message buffer areas are implemented in a big-endian way). |
||
64 | + * |
||
65 | + * In addition, the FlexCAN module can be found on SoCs having ARM or |
||
66 | + * PPC cores. So, we need to abstract off the register read/write |
||
67 | + * functions, ensuring that these cater to all the combinations of module |
||
68 | + * endianness and underlying CPU endianness. |
||
69 | */ |
||
70 | -#if defined(CONFIG_PPC) |
||
71 | -static inline u32 flexcan_read(void __iomem *addr) |
||
72 | +static inline u32 flexcan_read_be(void __iomem *addr) |
||
73 | { |
||
74 | - return in_be32(addr); |
||
75 | + return ioread32be(addr); |
||
76 | } |
||
77 | |||
78 | -static inline void flexcan_write(u32 val, void __iomem *addr) |
||
79 | +static inline void flexcan_write_be(u32 val, void __iomem *addr) |
||
80 | { |
||
81 | - out_be32(addr, val); |
||
82 | + iowrite32be(val, addr); |
||
83 | } |
||
84 | -#else |
||
85 | -static inline u32 flexcan_read(void __iomem *addr) |
||
86 | + |
||
87 | +static inline u32 flexcan_read_le(void __iomem *addr) |
||
88 | { |
||
89 | - return readl(addr); |
||
90 | + return ioread32(addr); |
||
91 | } |
||
92 | |||
93 | -static inline void flexcan_write(u32 val, void __iomem *addr) |
||
94 | +static inline void flexcan_write_le(u32 val, void __iomem *addr) |
||
95 | { |
||
96 | - writel(val, addr); |
||
97 | + iowrite32(val, addr); |
||
98 | } |
||
99 | -#endif |
||
100 | |||
101 | static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) |
||
102 | { |
||
103 | struct flexcan_regs __iomem *regs = priv->regs; |
||
104 | u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK); |
||
105 | |||
106 | - flexcan_write(reg_ctrl, ®s->ctrl); |
||
107 | + priv->write(reg_ctrl, ®s->ctrl); |
||
108 | } |
||
109 | |||
110 | static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv) |
||
111 | @@ -353,7 +369,7 @@ static inline void flexcan_error_irq_dis |
||
112 | struct flexcan_regs __iomem *regs = priv->regs; |
||
113 | u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK); |
||
114 | |||
115 | - flexcan_write(reg_ctrl, ®s->ctrl); |
||
116 | + priv->write(reg_ctrl, ®s->ctrl); |
||
117 | } |
||
118 | |||
119 | static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) |
||
120 | @@ -378,14 +394,14 @@ static int flexcan_chip_enable(struct fl |
||
121 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
||
122 | u32 reg; |
||
123 | |||
124 | - reg = flexcan_read(®s->mcr); |
||
125 | + reg = priv->read(®s->mcr); |
||
126 | reg &= ~FLEXCAN_MCR_MDIS; |
||
127 | - flexcan_write(reg, ®s->mcr); |
||
128 | + priv->write(reg, ®s->mcr); |
||
129 | |||
130 | - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
||
131 | + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
||
132 | udelay(10); |
||
133 | |||
134 | - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) |
||
135 | + if (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) |
||
136 | return -ETIMEDOUT; |
||
137 | |||
138 | return 0; |
||
139 | @@ -397,14 +413,14 @@ static int flexcan_chip_disable(struct f |
||
140 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
||
141 | u32 reg; |
||
142 | |||
143 | - reg = flexcan_read(®s->mcr); |
||
144 | + reg = priv->read(®s->mcr); |
||
145 | reg |= FLEXCAN_MCR_MDIS; |
||
146 | - flexcan_write(reg, ®s->mcr); |
||
147 | + priv->write(reg, ®s->mcr); |
||
148 | |||
149 | - while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
||
150 | + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
||
151 | udelay(10); |
||
152 | |||
153 | - if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
||
154 | + if (!(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
||
155 | return -ETIMEDOUT; |
||
156 | |||
157 | return 0; |
||
158 | @@ -416,14 +432,14 @@ static int flexcan_chip_freeze(struct fl |
||
159 | unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate; |
||
160 | u32 reg; |
||
161 | |||
162 | - reg = flexcan_read(®s->mcr); |
||
163 | + reg = priv->read(®s->mcr); |
||
164 | reg |= FLEXCAN_MCR_HALT; |
||
165 | - flexcan_write(reg, ®s->mcr); |
||
166 | + priv->write(reg, ®s->mcr); |
||
167 | |||
168 | - while (timeout-- && !(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) |
||
169 | + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) |
||
170 | udelay(100); |
||
171 | |||
172 | - if (!(flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) |
||
173 | + if (!(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) |
||
174 | return -ETIMEDOUT; |
||
175 | |||
176 | return 0; |
||
177 | @@ -435,14 +451,14 @@ static int flexcan_chip_unfreeze(struct |
||
178 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
||
179 | u32 reg; |
||
180 | |||
181 | - reg = flexcan_read(®s->mcr); |
||
182 | + reg = priv->read(®s->mcr); |
||
183 | reg &= ~FLEXCAN_MCR_HALT; |
||
184 | - flexcan_write(reg, ®s->mcr); |
||
185 | + priv->write(reg, ®s->mcr); |
||
186 | |||
187 | - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) |
||
188 | + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) |
||
189 | udelay(10); |
||
190 | |||
191 | - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK) |
||
192 | + if (priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK) |
||
193 | return -ETIMEDOUT; |
||
194 | |||
195 | return 0; |
||
196 | @@ -453,11 +469,11 @@ static int flexcan_chip_softreset(struct |
||
197 | struct flexcan_regs __iomem *regs = priv->regs; |
||
198 | unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
||
199 | |||
200 | - flexcan_write(FLEXCAN_MCR_SOFTRST, ®s->mcr); |
||
201 | - while (timeout-- && (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST)) |
||
202 | + priv->write(FLEXCAN_MCR_SOFTRST, ®s->mcr); |
||
203 | + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_SOFTRST)) |
||
204 | udelay(10); |
||
205 | |||
206 | - if (flexcan_read(®s->mcr) & FLEXCAN_MCR_SOFTRST) |
||
207 | + if (priv->read(®s->mcr) & FLEXCAN_MCR_SOFTRST) |
||
208 | return -ETIMEDOUT; |
||
209 | |||
210 | return 0; |
||
211 | @@ -468,7 +484,7 @@ static int __flexcan_get_berr_counter(co |
||
212 | { |
||
213 | const struct flexcan_priv *priv = netdev_priv(dev); |
||
214 | struct flexcan_regs __iomem *regs = priv->regs; |
||
215 | - u32 reg = flexcan_read(®s->ecr); |
||
216 | + u32 reg = priv->read(®s->ecr); |
||
217 | |||
218 | bec->txerr = (reg >> 0) & 0xff; |
||
219 | bec->rxerr = (reg >> 8) & 0xff; |
||
220 | @@ -524,24 +540,24 @@ static int flexcan_start_xmit(struct sk_ |
||
221 | |||
222 | if (cf->can_dlc > 0) { |
||
223 | data = be32_to_cpup((__be32 *)&cf->data[0]); |
||
224 | - flexcan_write(data, &priv->tx_mb->data[0]); |
||
225 | + priv->write(data, &priv->tx_mb->data[0]); |
||
226 | } |
||
227 | if (cf->can_dlc > 4) { |
||
228 | data = be32_to_cpup((__be32 *)&cf->data[4]); |
||
229 | - flexcan_write(data, &priv->tx_mb->data[1]); |
||
230 | + priv->write(data, &priv->tx_mb->data[1]); |
||
231 | } |
||
232 | |||
233 | can_put_echo_skb(skb, dev, 0); |
||
234 | |||
235 | - flexcan_write(can_id, &priv->tx_mb->can_id); |
||
236 | - flexcan_write(ctrl, &priv->tx_mb->can_ctrl); |
||
237 | + priv->write(can_id, &priv->tx_mb->can_id); |
||
238 | + priv->write(ctrl, &priv->tx_mb->can_ctrl); |
||
239 | |||
240 | /* Errata ERR005829 step8: |
||
241 | * Write twice INACTIVE(0x8) code to first MB. |
||
242 | */ |
||
243 | - flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, |
||
244 | + priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
||
245 | &priv->tx_mb_reserved->can_ctrl); |
||
246 | - flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, |
||
247 | + priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
||
248 | &priv->tx_mb_reserved->can_ctrl); |
||
249 | |||
250 | return NETDEV_TX_OK; |
||
251 | @@ -660,7 +676,7 @@ static unsigned int flexcan_mailbox_read |
||
252 | u32 code; |
||
253 | |||
254 | do { |
||
255 | - reg_ctrl = flexcan_read(&mb->can_ctrl); |
||
256 | + reg_ctrl = priv->read(&mb->can_ctrl); |
||
257 | } while (reg_ctrl & FLEXCAN_MB_CODE_RX_BUSY_BIT); |
||
258 | |||
259 | /* is this MB empty? */ |
||
260 | @@ -675,17 +691,17 @@ static unsigned int flexcan_mailbox_read |
||
261 | offload->dev->stats.rx_errors++; |
||
262 | } |
||
263 | } else { |
||
264 | - reg_iflag1 = flexcan_read(®s->iflag1); |
||
265 | + reg_iflag1 = priv->read(®s->iflag1); |
||
266 | if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE)) |
||
267 | return 0; |
||
268 | |||
269 | - reg_ctrl = flexcan_read(&mb->can_ctrl); |
||
270 | + reg_ctrl = priv->read(&mb->can_ctrl); |
||
271 | } |
||
272 | |||
273 | /* increase timstamp to full 32 bit */ |
||
274 | *timestamp = reg_ctrl << 16; |
||
275 | |||
276 | - reg_id = flexcan_read(&mb->can_id); |
||
277 | + reg_id = priv->read(&mb->can_id); |
||
278 | if (reg_ctrl & FLEXCAN_MB_CNT_IDE) |
||
279 | cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; |
||
280 | else |
||
281 | @@ -695,19 +711,19 @@ static unsigned int flexcan_mailbox_read |
||
282 | cf->can_id |= CAN_RTR_FLAG; |
||
283 | cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf); |
||
284 | |||
285 | - *(__be32 *)(cf->data + 0) = cpu_to_be32(flexcan_read(&mb->data[0])); |
||
286 | - *(__be32 *)(cf->data + 4) = cpu_to_be32(flexcan_read(&mb->data[1])); |
||
287 | + *(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0])); |
||
288 | + *(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1])); |
||
289 | |||
290 | /* mark as read */ |
||
291 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
||
292 | /* Clear IRQ */ |
||
293 | if (n < 32) |
||
294 | - flexcan_write(BIT(n), ®s->iflag1); |
||
295 | + priv->write(BIT(n), ®s->iflag1); |
||
296 | else |
||
297 | - flexcan_write(BIT(n - 32), ®s->iflag2); |
||
298 | + priv->write(BIT(n - 32), ®s->iflag2); |
||
299 | } else { |
||
300 | - flexcan_write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); |
||
301 | - flexcan_read(®s->timer); |
||
302 | + priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); |
||
303 | + priv->read(®s->timer); |
||
304 | } |
||
305 | |||
306 | return 1; |
||
307 | @@ -719,8 +735,8 @@ static inline u64 flexcan_read_reg_iflag |
||
308 | struct flexcan_regs __iomem *regs = priv->regs; |
||
309 | u32 iflag1, iflag2; |
||
310 | |||
311 | - iflag2 = flexcan_read(®s->iflag2) & priv->reg_imask2_default; |
||
312 | - iflag1 = flexcan_read(®s->iflag1) & priv->reg_imask1_default & |
||
313 | + iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default; |
||
314 | + iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default & |
||
315 | ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx); |
||
316 | |||
317 | return (u64)iflag2 << 32 | iflag1; |
||
318 | @@ -736,7 +752,7 @@ static irqreturn_t flexcan_irq(int irq, |
||
319 | u32 reg_iflag1, reg_esr; |
||
320 | enum can_state last_state = priv->can.state; |
||
321 | |||
322 | - reg_iflag1 = flexcan_read(®s->iflag1); |
||
323 | + reg_iflag1 = priv->read(®s->iflag1); |
||
324 | |||
325 | /* reception interrupt */ |
||
326 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
||
327 | @@ -759,7 +775,8 @@ static irqreturn_t flexcan_irq(int irq, |
||
328 | /* FIFO overflow interrupt */ |
||
329 | if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) { |
||
330 | handled = IRQ_HANDLED; |
||
331 | - flexcan_write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1); |
||
332 | + priv->write(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, |
||
333 | + ®s->iflag1); |
||
334 | dev->stats.rx_over_errors++; |
||
335 | dev->stats.rx_errors++; |
||
336 | } |
||
337 | @@ -773,18 +790,18 @@ static irqreturn_t flexcan_irq(int irq, |
||
338 | can_led_event(dev, CAN_LED_EVENT_TX); |
||
339 | |||
340 | /* after sending a RTR frame MB is in RX mode */ |
||
341 | - flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, |
||
342 | - &priv->tx_mb->can_ctrl); |
||
343 | - flexcan_write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1); |
||
344 | + priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
||
345 | + &priv->tx_mb->can_ctrl); |
||
346 | + priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag1); |
||
347 | netif_wake_queue(dev); |
||
348 | } |
||
349 | |||
350 | - reg_esr = flexcan_read(®s->esr); |
||
351 | + reg_esr = priv->read(®s->esr); |
||
352 | |||
353 | /* ACK all bus error and state change IRQ sources */ |
||
354 | if (reg_esr & FLEXCAN_ESR_ALL_INT) { |
||
355 | handled = IRQ_HANDLED; |
||
356 | - flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr); |
||
357 | + priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr); |
||
358 | } |
||
359 | |||
360 | /* state change interrupt or broken error state quirk fix is enabled */ |
||
361 | @@ -846,7 +863,7 @@ static void flexcan_set_bittiming(struct |
||
362 | struct flexcan_regs __iomem *regs = priv->regs; |
||
363 | u32 reg; |
||
364 | |||
365 | - reg = flexcan_read(®s->ctrl); |
||
366 | + reg = priv->read(®s->ctrl); |
||
367 | reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) | |
||
368 | FLEXCAN_CTRL_RJW(0x3) | |
||
369 | FLEXCAN_CTRL_PSEG1(0x7) | |
||
370 | @@ -870,11 +887,11 @@ static void flexcan_set_bittiming(struct |
||
371 | reg |= FLEXCAN_CTRL_SMP; |
||
372 | |||
373 | netdev_dbg(dev, "writing ctrl=0x%08x\n", reg); |
||
374 | - flexcan_write(reg, ®s->ctrl); |
||
375 | + priv->write(reg, ®s->ctrl); |
||
376 | |||
377 | /* print chip status */ |
||
378 | netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, |
||
379 | - flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); |
||
380 | + priv->read(®s->mcr), priv->read(®s->ctrl)); |
||
381 | } |
||
382 | |||
383 | /* flexcan_chip_start |
||
384 | @@ -913,7 +930,7 @@ static int flexcan_chip_start(struct net |
||
385 | * choose format C |
||
386 | * set max mailbox number |
||
387 | */ |
||
388 | - reg_mcr = flexcan_read(®s->mcr); |
||
389 | + reg_mcr = priv->read(®s->mcr); |
||
390 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); |
||
391 | reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | |
||
392 | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | |
||
393 | @@ -927,7 +944,7 @@ static int flexcan_chip_start(struct net |
||
394 | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); |
||
395 | } |
||
396 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); |
||
397 | - flexcan_write(reg_mcr, ®s->mcr); |
||
398 | + priv->write(reg_mcr, ®s->mcr); |
||
399 | |||
400 | /* CTRL |
||
401 | * |
||
402 | @@ -940,7 +957,7 @@ static int flexcan_chip_start(struct net |
||
403 | * enable bus off interrupt |
||
404 | * (== FLEXCAN_CTRL_ERR_STATE) |
||
405 | */ |
||
406 | - reg_ctrl = flexcan_read(®s->ctrl); |
||
407 | + reg_ctrl = priv->read(®s->ctrl); |
||
408 | reg_ctrl &= ~FLEXCAN_CTRL_TSYN; |
||
409 | reg_ctrl |= FLEXCAN_CTRL_BOFF_REC | FLEXCAN_CTRL_LBUF | |
||
410 | FLEXCAN_CTRL_ERR_STATE; |
||
411 | @@ -960,45 +977,45 @@ static int flexcan_chip_start(struct net |
||
412 | /* leave interrupts disabled for now */ |
||
413 | reg_ctrl &= ~FLEXCAN_CTRL_ERR_ALL; |
||
414 | netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); |
||
415 | - flexcan_write(reg_ctrl, ®s->ctrl); |
||
416 | + priv->write(reg_ctrl, ®s->ctrl); |
||
417 | |||
418 | if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) { |
||
419 | - reg_ctrl2 = flexcan_read(®s->ctrl2); |
||
420 | + reg_ctrl2 = priv->read(®s->ctrl2); |
||
421 | reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS; |
||
422 | - flexcan_write(reg_ctrl2, ®s->ctrl2); |
||
423 | + priv->write(reg_ctrl2, ®s->ctrl2); |
||
424 | } |
||
425 | |||
426 | /* clear and invalidate all mailboxes first */ |
||
427 | for (i = priv->tx_mb_idx; i < ARRAY_SIZE(regs->mb); i++) { |
||
428 | - flexcan_write(FLEXCAN_MB_CODE_RX_INACTIVE, |
||
429 | - ®s->mb[i].can_ctrl); |
||
430 | + priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, |
||
431 | + ®s->mb[i].can_ctrl); |
||
432 | } |
||
433 | |||
434 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
||
435 | for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) |
||
436 | - flexcan_write(FLEXCAN_MB_CODE_RX_EMPTY, |
||
437 | - ®s->mb[i].can_ctrl); |
||
438 | + priv->write(FLEXCAN_MB_CODE_RX_EMPTY, |
||
439 | + ®s->mb[i].can_ctrl); |
||
440 | } |
||
441 | |||
442 | /* Errata ERR005829: mark first TX mailbox as INACTIVE */ |
||
443 | - flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, |
||
444 | - &priv->tx_mb_reserved->can_ctrl); |
||
445 | + priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
||
446 | + &priv->tx_mb_reserved->can_ctrl); |
||
447 | |||
448 | /* mark TX mailbox as INACTIVE */ |
||
449 | - flexcan_write(FLEXCAN_MB_CODE_TX_INACTIVE, |
||
450 | - &priv->tx_mb->can_ctrl); |
||
451 | + priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
||
452 | + &priv->tx_mb->can_ctrl); |
||
453 | |||
454 | /* acceptance mask/acceptance code (accept everything) */ |
||
455 | - flexcan_write(0x0, ®s->rxgmask); |
||
456 | - flexcan_write(0x0, ®s->rx14mask); |
||
457 | - flexcan_write(0x0, ®s->rx15mask); |
||
458 | + priv->write(0x0, ®s->rxgmask); |
||
459 | + priv->write(0x0, ®s->rx14mask); |
||
460 | + priv->write(0x0, ®s->rx15mask); |
||
461 | |||
462 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) |
||
463 | - flexcan_write(0x0, ®s->rxfgmask); |
||
464 | + priv->write(0x0, ®s->rxfgmask); |
||
465 | |||
466 | /* clear acceptance filters */ |
||
467 | for (i = 0; i < ARRAY_SIZE(regs->mb); i++) |
||
468 | - flexcan_write(0, ®s->rximr[i]); |
||
469 | + priv->write(0, ®s->rximr[i]); |
||
470 | |||
471 | /* On Vybrid, disable memory error detection interrupts |
||
472 | * and freeze mode. |
||
473 | @@ -1011,16 +1028,16 @@ static int flexcan_chip_start(struct net |
||
474 | * and Correction of Memory Errors" to write to |
||
475 | * MECR register |
||
476 | */ |
||
477 | - reg_ctrl2 = flexcan_read(®s->ctrl2); |
||
478 | + reg_ctrl2 = priv->read(®s->ctrl2); |
||
479 | reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE; |
||
480 | - flexcan_write(reg_ctrl2, ®s->ctrl2); |
||
481 | + priv->write(reg_ctrl2, ®s->ctrl2); |
||
482 | |||
483 | - reg_mecr = flexcan_read(®s->mecr); |
||
484 | + reg_mecr = priv->read(®s->mecr); |
||
485 | reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS; |
||
486 | - flexcan_write(reg_mecr, ®s->mecr); |
||
487 | + priv->write(reg_mecr, ®s->mecr); |
||
488 | reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK | |
||
489 | FLEXCAN_MECR_FANCEI_MSK); |
||
490 | - flexcan_write(reg_mecr, ®s->mecr); |
||
491 | + priv->write(reg_mecr, ®s->mecr); |
||
492 | } |
||
493 | |||
494 | err = flexcan_transceiver_enable(priv); |
||
495 | @@ -1036,14 +1053,14 @@ static int flexcan_chip_start(struct net |
||
496 | |||
497 | /* enable interrupts atomically */ |
||
498 | disable_irq(dev->irq); |
||
499 | - flexcan_write(priv->reg_ctrl_default, ®s->ctrl); |
||
500 | - flexcan_write(priv->reg_imask1_default, ®s->imask1); |
||
501 | - flexcan_write(priv->reg_imask2_default, ®s->imask2); |
||
502 | + priv->write(priv->reg_ctrl_default, ®s->ctrl); |
||
503 | + priv->write(priv->reg_imask1_default, ®s->imask1); |
||
504 | + priv->write(priv->reg_imask2_default, ®s->imask2); |
||
505 | enable_irq(dev->irq); |
||
506 | |||
507 | /* print chip status */ |
||
508 | netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, |
||
509 | - flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); |
||
510 | + priv->read(®s->mcr), priv->read(®s->ctrl)); |
||
511 | |||
512 | return 0; |
||
513 | |||
514 | @@ -1068,10 +1085,10 @@ static void flexcan_chip_stop(struct net |
||
515 | flexcan_chip_disable(priv); |
||
516 | |||
517 | /* Disable all interrupts */ |
||
518 | - flexcan_write(0, ®s->imask2); |
||
519 | - flexcan_write(0, ®s->imask1); |
||
520 | - flexcan_write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, |
||
521 | - ®s->ctrl); |
||
522 | + priv->write(0, ®s->imask2); |
||
523 | + priv->write(0, ®s->imask1); |
||
524 | + priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, |
||
525 | + ®s->ctrl); |
||
526 | |||
527 | flexcan_transceiver_disable(priv); |
||
528 | priv->can.state = CAN_STATE_STOPPED; |
||
529 | @@ -1186,26 +1203,26 @@ static int register_flexcandev(struct ne |
||
530 | err = flexcan_chip_disable(priv); |
||
531 | if (err) |
||
532 | goto out_disable_per; |
||
533 | - reg = flexcan_read(®s->ctrl); |
||
534 | + reg = priv->read(®s->ctrl); |
||
535 | reg |= FLEXCAN_CTRL_CLK_SRC; |
||
536 | - flexcan_write(reg, ®s->ctrl); |
||
537 | + priv->write(reg, ®s->ctrl); |
||
538 | |||
539 | err = flexcan_chip_enable(priv); |
||
540 | if (err) |
||
541 | goto out_chip_disable; |
||
542 | |||
543 | /* set freeze, halt and activate FIFO, restrict register access */ |
||
544 | - reg = flexcan_read(®s->mcr); |
||
545 | + reg = priv->read(®s->mcr); |
||
546 | reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | |
||
547 | FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; |
||
548 | - flexcan_write(reg, ®s->mcr); |
||
549 | + priv->write(reg, ®s->mcr); |
||
550 | |||
551 | /* Currently we only support newer versions of this core |
||
552 | * featuring a RX hardware FIFO (although this driver doesn't |
||
553 | * make use of it on some cores). Older cores, found on some |
||
554 | * Coldfire derivates are not tested. |
||
555 | */ |
||
556 | - reg = flexcan_read(®s->mcr); |
||
557 | + reg = priv->read(®s->mcr); |
||
558 | if (!(reg & FLEXCAN_MCR_FEN)) { |
||
559 | netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); |
||
560 | err = -ENODEV; |
||
561 | @@ -1233,8 +1250,12 @@ static void unregister_flexcandev(struct |
||
562 | static const struct of_device_id flexcan_of_match[] = { |
||
563 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, |
||
564 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, |
||
565 | + { .compatible = "fsl,imx53-flexcan", .data = &fsl_p1010_devtype_data, }, |
||
566 | + { .compatible = "fsl,imx35-flexcan", .data = &fsl_p1010_devtype_data, }, |
||
567 | + { .compatible = "fsl,imx25-flexcan", .data = &fsl_p1010_devtype_data, }, |
||
568 | { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, |
||
569 | { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, |
||
570 | + { .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, }, |
||
571 | { /* sentinel */ }, |
||
572 | }; |
||
573 | MODULE_DEVICE_TABLE(of, flexcan_of_match); |
||
574 | @@ -1314,6 +1335,21 @@ static int flexcan_probe(struct platform |
||
575 | dev->flags |= IFF_ECHO; |
||
576 | |||
577 | priv = netdev_priv(dev); |
||
578 | + |
||
579 | + if (of_property_read_bool(pdev->dev.of_node, "big-endian")) { |
||
580 | + priv->read = flexcan_read_be; |
||
581 | + priv->write = flexcan_write_be; |
||
582 | + } else { |
||
583 | + if (of_device_is_compatible(pdev->dev.of_node, |
||
584 | + "fsl,p1010-flexcan")) { |
||
585 | + priv->read = flexcan_read_be; |
||
586 | + priv->write = flexcan_write_be; |
||
587 | + } else { |
||
588 | + priv->read = flexcan_read_le; |
||
589 | + priv->write = flexcan_write_le; |
||
590 | + } |
||
591 | + } |
||
592 | + |
||
593 | priv->can.clock.freq = clock_freq; |
||
594 | priv->can.bittiming_const = &flexcan_bittiming_const; |
||
595 | priv->can.do_set_mode = flexcan_set_mode; |