xburst: remove support for old kernels
[openwrt.git] / target / linux / coldfire / patches / 036-Add-FlexCAN-support-on-ColdFire-M548X-M54418-platfor.patch
1 From c3b97e08b06be76ee9f2b410b13c045425fc7f3e Mon Sep 17 00:00:00 2001
2 From: Jingchang Lu <b35083@freescale.com>
3 Date: Thu, 4 Aug 2011 09:59:48 +0800
4 Subject: [PATCH 36/52] Add FlexCAN support on ColdFire M548X, M54418 platform
5
6 Each cpu core has two FlexCAN interface, and the M54418's FlexCAN
7 also support Rx message buffer FIFO mode but M548X not.
8
9 Signed-off-by: Jingchang Lu <b35083@freescale.com>
10 ---
11  arch/m68k/Kconfig                       |    2 +
12  arch/m68k/coldfire/m5441x/Makefile      |    4 +
13  arch/m68k/coldfire/m5441x/mcf-flexcan.c |  121 ++++++++++++++++
14  arch/m68k/coldfire/m547x/Makefile       |    3 +
15  arch/m68k/coldfire/m547x/mcf-flexcan.c  |  117 +++++++++++++++
16  drivers/net/can/Kconfig                 |    9 ++
17  drivers/net/can/flexcan.c               |  239 ++++++++++++++++++++++++++++++-
18  7 files changed, 489 insertions(+), 6 deletions(-)
19  create mode 100644 arch/m68k/coldfire/m5441x/mcf-flexcan.c
20  create mode 100644 arch/m68k/coldfire/m547x/mcf-flexcan.c
21
22 --- a/arch/m68k/Kconfig
23 +++ b/arch/m68k/Kconfig
24 @@ -372,6 +372,7 @@ config M547X
25  config M548X
26         bool
27         depends on M547X_8X
28 +       select HAVE_CAN_FLEXCAN
29         default n
30  
31  choice
32 @@ -430,6 +431,7 @@ config M5441X
33         select GENERIC_TIME
34         select USB_EHCI_FSL
35         select HAVE_FSL_USB_DR
36 +       select HAVE_CAN_FLEXCAN
37         help
38           This option will add support for the MCF5441x processor with mmu.
39  
40 --- a/arch/m68k/coldfire/m5441x/Makefile
41 +++ b/arch/m68k/coldfire/m5441x/Makefile
42 @@ -36,3 +36,7 @@ endif
43  ifneq ($(CONFIG_MODELO_SWITCH),)
44  obj-y += l2switch.o
45  endif
46 +
47 +ifneq ($(CONFIG_CAN_FLEXCAN),)
48 +obj-y += mcf-flexcan.o
49 +endif
50 --- /dev/null
51 +++ b/arch/m68k/coldfire/m5441x/mcf-flexcan.c
52 @@ -0,0 +1,121 @@
53 +/*
54 + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
55 + *
56 + * Author: Huan Wang, b18965@freescale.com, Fri Aug 08 2008
57 + *
58 + * Description:
59 + * CAN bus driver for Freescale Coldfire embedded CPU
60 + *
61 + * Changelog:
62 + * Fri Aug 08 2008 Huan Wang <b18965@freescale.com>
63 + * - create, support for MCF548x
64 + *
65 + * Tue Dec 08 2009 ChengJu Cai <b22600@freescale.com>
66 + * - support for MCF532x MCF5253 MCF5227x
67 + *
68 + * July 2011 Jingchang.Lu <b35083@freescale.com>
69 + * - Add into kernel CAN driver layer
70 + *
71 + * This file is part of the Linux kernel
72 + * This is free software; you can redistribute it and/or modify
73 + * it under the terms of the GNU General Public License as published by
74 + * the Free Software Foundation; either version 2 of the License, or
75 + * (at your option) any later version.
76 + *
77 + */
78 +
79 +#include <linux/kernel.h>
80 +#include <linux/module.h>
81 +#include <linux/interrupt.h>
82 +#include <linux/platform_device.h>
83 +#include <asm/mcfsim.h>
84 +
85 +
86 +static struct resource mcf5441x_can0_resources[] = {
87 +       [0] = {
88 +               .start          = 0xFC020000,
89 +               .end            = 0xFC0208C0,
90 +               .flags          = IORESOURCE_MEM,
91 +       },
92 +       [1] = {
93 +               .start          = 0 + 64 + 64,
94 +               .end            = 0 + 64 + 64,
95 +               .flags          = IORESOURCE_IRQ,
96 +       },
97 +};
98 +
99 +static struct resource mcf5441x_can1_resources[] = {
100 +       [0] = {
101 +               .start          = 0xFC024000,
102 +               .end            = 0xFC0248C0,
103 +               .flags          = IORESOURCE_MEM,
104 +       },
105 +       [1] = {
106 +               .start          = 4 + 64 + 64,
107 +               .end            = 4 + 64 + 64,
108 +               .flags          = IORESOURCE_IRQ,
109 +       },
110 +};
111 +
112 +static struct platform_device mcf_flexcan[PDEV_MAX] = {
113 +       [0] = {
114 +               .name                   = "flexcan",
115 +               .id                     = 0,
116 +               .num_resources          = ARRAY_SIZE(mcf5441x_can0_resources),
117 +               .resource               = mcf5441x_can0_resources,
118 +       },
119 +       [1] = {
120 +               .name                   = "flexcan",
121 +               .id                     = 1,
122 +               .num_resources          = ARRAY_SIZE(mcf5441x_can1_resources),
123 +               .resource               = mcf5441x_can1_resources,
124 +       },
125 +
126 +};
127 +
128 +
129 +static void __init mcf_flexcan_config(void)
130 +{
131 +       MCF_PM_PPMCR0 = 8;      /* enable FlexCAN0 clock */
132 +       MCF_PM_PPMCR0 = 9;      /* enable FlexCAN1 clock */
133 +
134 +       /* CAN0 */
135 +       MCF_GPIO_PAR_CANI2C =
136 +               (MCF_GPIO_PAR_CANI2C & MCF_GPIO_PAR_CANI2C_I2C0SCL_MASK) |
137 +               MCF_GPIO_PAR_CANI2C_I2C0SCL_CAN0TX;
138 +       MCF_GPIO_PAR_CANI2C =
139 +               (MCF_GPIO_PAR_CANI2C & MCF_GPIO_PAR_CANI2C_I2C0SDA_MASK) |
140 +               MCF_GPIO_PAR_CANI2C_I2C0SDA_CAN0RX;
141 +       /* CAN1 */
142 +       MCF_GPIO_PAR_CANI2C =
143 +               (MCF_GPIO_PAR_CANI2C & MCF_GPIO_PAR_CANI2C_CAN1TX_MASK) |
144 +               MCF_GPIO_PAR_CANI2C_CAN1TX_CAN1TX;
145 +       MCF_GPIO_PAR_CANI2C =
146 +               (MCF_GPIO_PAR_CANI2C & MCF_GPIO_PAR_CANI2C_CAN1RX_MASK) |
147 +               MCF_GPIO_PAR_CANI2C_CAN1RX_CAN1RX;
148 +
149 +
150 +}
151 +
152 +static int __init flexcan_of_to_pdev(void)
153 +{
154 +       int i, err = -ENODEV;
155 +       for (i = 0; i < PDEV_MAX; i++) {
156 +               err = platform_device_register(&mcf_flexcan[i]);
157 +               if (err)
158 +                       return err;
159 +               printk(KERN_INFO "ColdFire FlexCAN devices loaded\n");
160 +       }
161 +       return err;
162 +}
163 +
164 +static int __init mcf_flexcan_init(void)
165 +{
166 +       int err;
167 +       mcf_flexcan_config();
168 +       err = flexcan_of_to_pdev();
169 +
170 +       return 0;
171 +}
172 +
173 +arch_initcall(mcf_flexcan_init);
174 --- a/arch/m68k/coldfire/m547x/Makefile
175 +++ b/arch/m68k/coldfire/m547x/Makefile
176 @@ -5,3 +5,6 @@
177  obj-$(CONFIG_M547X_8X) += config.o mcf548x-devices.o devices.o
178  obj-$(CONFIG_PCI)       += pci.o pci_dummy.o
179  obj-$(CONFIG_MCD_DMA)  += dma.o
180 +ifneq ($(CONFIG_CAN_FLEXCAN),)
181 +obj-y += mcf-flexcan.o
182 +endif
183 --- /dev/null
184 +++ b/arch/m68k/coldfire/m547x/mcf-flexcan.c
185 @@ -0,0 +1,117 @@
186 +/*
187 + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
188 + *
189 + * Author: Huan Wang, b18965@freescale.com, Fri Aug 08 2008
190 + *
191 + * Description:
192 + * CAN bus driver for Freescale Coldfire embedded CPU
193 + *
194 + * Changelog:
195 + * Fri Aug 08 2008 Huan Wang <b18965@freescale.com>
196 + * - create, support for MCF548x
197 + *
198 + * Tue Dec 08 2009 ChengJu Cai <b22600@freescale.com>
199 + * - support for MCF532x MCF5253 MCF5227x
200 + *
201 + * July 2011 Jingchang.Lu <b35083@freescale.com>
202 + * - Add into kernel CAN driver layer
203 + *
204 + * This file is part of the Linux kernel
205 + * This is free software; you can redistribute it and/or modify
206 + * it under the terms of the GNU General Public License as published by
207 + * the Free Software Foundation; either version 2 of the License, or
208 + * (at your option) any later version.
209 + *
210 + */
211 +
212 +#include <linux/kernel.h>
213 +#include <linux/module.h>
214 +#include <linux/interrupt.h>
215 +#include <linux/platform_device.h>
216 +#include <asm/mcfsim.h>
217 +
218 +
219 +static struct resource mcf548x_can0_resources[] = {
220 +       [0] = {
221 +               .start          = MCF_MBAR + 0x0000A000,
222 +               .end            = MCF_MBAR + 0x0000A7FF,
223 +               .flags          = IORESOURCE_MEM,
224 +       },
225 +       [1] = {
226 +               .start          = 49 + 64,
227 +               .end            = 49 + 64,
228 +               .flags          = IORESOURCE_IRQ,
229 +       },
230 +};
231 +
232 +static struct resource mcf548x_can1_resources[] = {
233 +       [0] = {
234 +               .start          = MCF_MBAR + 0x0000A800,
235 +               .end            = MCF_MBAR + 0x0000AFFF,
236 +               .flags          = IORESOURCE_MEM,
237 +       },
238 +       [1] = {
239 +               .start          = 55 + 64,
240 +               .end            = 55 + 64,
241 +               .flags          = IORESOURCE_IRQ,
242 +       },
243 +};
244 +
245 +static struct platform_device mcf_flexcan[PDEV_MAX] = {
246 +       [0] = {
247 +               .name                   = "flexcan",
248 +               .id                     = 0,
249 +               .num_resources          = ARRAY_SIZE(mcf548x_can1_resources),
250 +               .resource               = mcf548x_can0_resources,
251 +       },
252 +       [1] = {
253 +               .name                   = "flexcan",
254 +               .id                     = 1,
255 +               .num_resources          = ARRAY_SIZE(mcf548x_can1_resources),
256 +               .resource               = mcf548x_can1_resources,
257 +       },
258 +
259 +};
260 +
261 +
262 +static void __init mcf_flexcan_config(void)
263 +{
264 +       int i;
265 +       MCF_PAR_TIMER = MCF_PAR_TIMER | 0x28;
266 +       MCF_PAR_TIMER = MCF_PAR_TIMER & 0xf8;
267 +       MCF_PAR_DSPI = MCF_PAR_DSPI | 0x0a00;
268 +       MCF_PAR_FECI2CIRQ = MCF_PAR_FECI2CIRQ | 0x0283;
269 +       MCF_PAR_PSCn(2) = MCF_PAR_PSCn(2) & 0x0f;
270 +       MCF_PAR_PSCn(2) = MCF_PAR_PSCn(2) | 0x50;
271 +
272 +       for (i = 0; i < 2; i++) {
273 +               MCF_ICR(ISC_CANn_MBOR(i)) = 0x33 + 0x01 * i;
274 +               MCF_ICR(ISC_CANn_ERR(i)) = 0x33 + 0x01 * i;
275 +               MCF_ICR(ISC_CANn_BUSOFF(i)) = 0x33 + 0x01 * i;
276 +       }
277 +
278 +
279 +}
280 +
281 +static int __init flexcan_of_to_pdev(void)
282 +{
283 +       int i, err = -ENODEV;
284 +       for (i = 0; i < PDEV_MAX; i++) {
285 +               err = platform_device_register(&mcf_flexcan[i]);
286 +               if (err)
287 +                       return err;
288 +               printk(KERN_INFO "ColdFire FlexCAN devices loaded\n");
289 +       }
290 +       return err;
291 +}
292 +
293 +static int __init mcf_flexcan_init(void)
294 +{
295 +       int err;
296 +       mcf_flexcan_config();
297 +       err = flexcan_of_to_pdev();
298 +
299 +       return 0;
300 +}
301 +
302 +arch_initcall(mcf_flexcan_init);
303 --- a/drivers/net/can/Kconfig
304 +++ b/drivers/net/can/Kconfig
305 @@ -103,6 +103,15 @@ config CAN_FLEXCAN
306         ---help---
307           Say Y here if you want to support for Freescale FlexCAN.
308  
309 +config FLEXCAN_NORXFIFO
310 +       bool "FlexCAN message buffer without Rx FIFO mode"
311 +       depends on CAN_FLEXCAN && COLDFIRE
312 +       default n
313 +       ---help---
314 +         Say Y here if you FlexCAN message buffer has no Rx FIFO mode.
315 +         Freescale Coldfire series have different FlexCAN core version,
316 +         MCF54418's support Rx FIFO mode while others such as MCF5485 not.
317 +
318  config PCH_CAN
319         tristate "PCH CAN"
320         depends on CAN_DEV && PCI
321 --- a/drivers/net/can/flexcan.c
322 +++ b/drivers/net/can/flexcan.c
323 @@ -4,6 +4,7 @@
324   * Copyright (c) 2005-2006 Varma Electronics Oy
325   * Copyright (c) 2009 Sascha Hauer, Pengutronix
326   * Copyright (c) 2010 Marc Kleine-Budde, Pengutronix
327 + * Copyright (C) 2011 Freescale Semiconductor, Inc. All rights reserved.
328   *
329   * Based on code originally by Andrey Volkov <avolkov@varma-el.com>
330   *
331 @@ -35,8 +36,28 @@
332  #include <linux/module.h>
333  #include <linux/platform_device.h>
334  
335 +#ifndef CONFIG_COLDFIRE
336  #include <mach/clock.h>
337  
338 +#else
339 +#include <asm/mcfsim.h>
340 +
341 +#undef readb
342 +#undef readw
343 +#undef readl
344 +#define readb(addr) __raw_readb(addr)
345 +#define readw(addr) __raw_readw(addr)
346 +#define readl(addr) __raw_readl(addr)
347 +
348 +#undef writeb
349 +#undef writew
350 +#undef writel
351 +#define writeb(b, addr) __raw_writeb(b, addr)
352 +#define writew(b, addr) __raw_writew(b, addr)
353 +#define writel(b, addr) __raw_writel(b, addr)
354 +
355 +#endif
356 +
357  #define DRV_NAME                       "flexcan"
358  
359  /* 8 for RX fifo and 2 error handling */
360 @@ -85,12 +106,34 @@
361  #define FLEXCAN_CTRL_LOM               BIT(3)
362  #define FLEXCAN_CTRL_PROPSEG(x)                ((x) & 0x07)
363  #define FLEXCAN_CTRL_ERR_BUS           (FLEXCAN_CTRL_ERR_MSK)
364 +
365 +#ifdef CONFIG_COLDFIRE
366 +
367 +# if defined(CONFIG_M548X)
368 +
369 +#define FLEXCAN_CTRL_ERR_STATE FLEXCAN_CTRL_BOFF_MSK
370 +#define FLEXCAN_CTRL_ERR_ALL \
371 +       (FLEXCAN_CTRL_BOFF_MSK | FLEXCAN_CTRL_ERR_MSK)
372 +
373 +# elif defined(CONFIG_M5441X)
374 +
375  #define FLEXCAN_CTRL_ERR_STATE \
376         (FLEXCAN_CTRL_TWRN_MSK | FLEXCAN_CTRL_RWRN_MSK | \
377          FLEXCAN_CTRL_BOFF_MSK)
378  #define FLEXCAN_CTRL_ERR_ALL \
379         (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE)
380  
381 +# endif
382 +
383 +#else /* !CONFIG_COLDFIRE */
384 +
385 +#define FLEXCAN_CTRL_ERR_STATE \
386 +       (FLEXCAN_CTRL_TWRN_MSK | FLEXCAN_CTRL_RWRN_MSK | \
387 +        FLEXCAN_CTRL_BOFF_MSK)
388 +#define FLEXCAN_CTRL_ERR_ALL \
389 +       (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE)
390 +
391 +#endif
392  /* FLEXCAN error and status register (ESR) bits */
393  #define FLEXCAN_ESR_TWRN_INT           BIT(17)
394  #define FLEXCAN_ESR_RWRN_INT           BIT(16)
395 @@ -121,6 +164,18 @@
396         (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE)
397  
398  /* FLEXCAN interrupt flag register (IFLAG) bits */
399 +
400 +#ifdef CONFIG_FLEXCAN_NORXFIFO
401 +
402 +/* MB assignment for no Rx FIFO mode module */
403 +#define FLEXCAN_TX_BUF_ID               0
404 +#define FLEXCAN_RX_EXT_ID              15
405 +#define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE 0xfffe
406 +#define FLEXCAN_IFLAG_DEFAULT \
407 +       (FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | (0x01 << FLEXCAN_TX_BUF_ID))
408 +
409 +#else
410 +
411  #define FLEXCAN_TX_BUF_ID              8
412  #define FLEXCAN_IFLAG_BUF(x)           BIT(x)
413  #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
414 @@ -130,6 +185,7 @@
415         (FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | \
416          FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID))
417  
418 +#endif
419  /* FLEXCAN message buffers */
420  #define FLEXCAN_MB_CNT_CODE(x)         (((x) & 0xf) << 24)
421  #define FLEXCAN_MB_CNT_SRR             BIT(22)
422 @@ -163,7 +219,11 @@ struct flexcan_regs {
423         u32 iflag2;             /* 0x2c */
424         u32 iflag1;             /* 0x30 */
425         u32 _reserved2[19];
426 +#ifdef CONFIG_COLDFIRE
427 +       struct flexcan_mb cantxfg[CAN_MB];
428 +#else
429         struct flexcan_mb cantxfg[64];
430 +#endif
431  };
432  
433  struct flexcan_priv {
434 @@ -181,8 +241,13 @@ struct flexcan_priv {
435  
436  static struct can_bittiming_const flexcan_bittiming_const = {
437         .name = DRV_NAME,
438 +#ifdef CONFIG_COLDFIRE
439 +       .tseg1_min = 1,
440 +       .tseg1_max = 8,
441 +#else
442         .tseg1_min = 4,
443         .tseg1_max = 16,
444 +#endif
445         .tseg2_min = 2,
446         .tseg2_max = 8,
447         .sjw_max = 4,
448 @@ -248,7 +313,7 @@ static int flexcan_start_xmit(struct sk_
449         struct net_device_stats *stats = &dev->stats;
450         struct flexcan_regs __iomem *regs = priv->base;
451         struct can_frame *cf = (struct can_frame *)skb->data;
452 -       u32 can_id;
453 +       u32 can_id, tmp, tmp1;
454         u32 ctrl = FLEXCAN_MB_CNT_CODE(0xc) | (cf->can_dlc << 16);
455  
456         if (can_dropped_invalid_skb(dev, skb))
457 @@ -259,6 +324,11 @@ static int flexcan_start_xmit(struct sk_
458         if (cf->can_id & CAN_EFF_FLAG) {
459                 can_id = cf->can_id & CAN_EFF_MASK;
460                 ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR;
461 +#ifdef CONFIG_COLDFIRE
462 +               tmp = (can_id & CAN_SFF_MASK) << 18;
463 +               tmp1 = can_id >> 11;
464 +               can_id = tmp | tmp1;
465 +#endif
466         } else {
467                 can_id = (cf->can_id & CAN_SFF_MASK) << 18;
468         }
469 @@ -456,6 +526,87 @@ static int flexcan_poll_state(struct net
470         return 1;
471  }
472  
473 +#ifdef CONFIG_FLEXCAN_NORXFIFO
474 +/* Get one frame from receive message buffer */
475 +static int flexcan_read_frame(struct net_device *dev)
476 +{
477 +       const struct flexcan_priv *priv = netdev_priv(dev);
478 +       struct flexcan_regs __iomem *regs = priv->base;
479 +       struct net_device_stats *stats = &dev->stats;
480 +       struct can_frame *cf;
481 +       struct sk_buff *skb;
482 +       struct flexcan_mb __iomem *mb;
483 +       u32 reg_iflag1, reg_ctrl, reg_id, i;
484 +
485 +       reg_iflag1 = readl(&regs->iflag1);
486 +
487 +       /* buf[0] if for TX */
488 +       for (i = 0; i < CAN_MB; i++) {
489 +               if (i == FLEXCAN_TX_BUF_ID)
490 +                       continue;
491 +               /* find one received message slot */
492 +               if (reg_iflag1 & (0x01 << i))
493 +                       break;
494 +       }
495 +       if (i >= CAN_MB)
496 +               return 0;
497 +
498 +       mb = &regs->cantxfg[i];
499 +
500 +       skb = alloc_can_skb(dev, &cf);
501 +       if (unlikely(!skb)) {
502 +               stats->rx_dropped++;
503 +                return 0;
504 +       }
505 +
506 +       reg_ctrl = readl(&mb->can_ctrl);
507 +       reg_id = readl(&mb->can_id);
508 +
509 +       /* deactive RX buff */
510 +       writel(0, &mb->can_ctrl);
511 +
512 +       if (reg_ctrl & FLEXCAN_MB_CNT_IDE) {
513 +#ifdef CONFIG_COLDFIRE
514 +               /* Coldfire can_id order */
515 +               cf->can_id = (reg_id & CAN_EFF_MASK) >> 18;
516 +               cf->can_id |= (reg_id & 0x3ffff) << 11;
517 +               cf->can_id |= CAN_EFF_FLAG;
518 +#else
519 +               cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
520 +#endif
521 +       } else
522 +               cf->can_id = (reg_id >> 18) & CAN_SFF_MASK;
523 +
524 +       if (reg_ctrl & FLEXCAN_MB_CNT_RTR)
525 +               cf->can_id |= CAN_RTR_FLAG;
526 +       cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf);
527 +
528 +       *(__be32 *)(cf->data + 0) = cpu_to_be32(readl(&mb->data[0]));
529 +       *(__be32 *)(cf->data + 4) = cpu_to_be32(readl(&mb->data[1]));
530 +
531 +       /* reactive RX buffer */
532 +       if (i == FLEXCAN_RX_EXT_ID)
533 +               writel(FLEXCAN_MB_CNT_CODE(0x4)|0x600000,
534 +                               &regs->cantxfg[i].can_ctrl);
535 +       else
536 +               writel(FLEXCAN_MB_CNT_CODE(0x4),
537 +                               &regs->cantxfg[i].can_ctrl);
538 +
539 +       /* mark as read */
540 +       writel((0x01 << i), &regs->iflag1);
541 +       /* release MB lock */
542 +       readl(&regs->timer);
543 +
544 +       netif_receive_skb(skb);
545 +
546 +       stats->rx_packets++;
547 +       stats->rx_bytes += cf->can_dlc;
548 +
549 +       return 1;
550 +
551 +}
552 +#else
553 +
554  static void flexcan_read_fifo(const struct net_device *dev,
555                               struct can_frame *cf)
556  {
557 @@ -466,9 +617,16 @@ static void flexcan_read_fifo(const stru
558  
559         reg_ctrl = readl(&mb->can_ctrl);
560         reg_id = readl(&mb->can_id);
561 -       if (reg_ctrl & FLEXCAN_MB_CNT_IDE)
562 +       if (reg_ctrl & FLEXCAN_MB_CNT_IDE) {
563 +#ifdef CONFIG_COLDFIRE
564 +               /* ColdFire can_id order as follow */
565 +               cf->can_id = (reg_id & CAN_EFF_MASK) >> 18;
566 +               cf->can_id |= (reg_id & 0x3ffff) << 11;
567 +               cf->can_id |= CAN_EFF_FLAG;
568 +#else
569                 cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
570 -       else
571 +#endif
572 +       } else
573                 cf->can_id = (reg_id >> 18) & CAN_SFF_MASK;
574  
575         if (reg_ctrl & FLEXCAN_MB_CNT_RTR)
576 @@ -503,6 +661,7 @@ static int flexcan_read_frame(struct net
577  
578         return 1;
579  }
580 +#endif
581  
582  static int flexcan_poll(struct napi_struct *napi, int quota)
583  {
584 @@ -554,6 +713,14 @@ static irqreturn_t flexcan_irq(int irq,
585         reg_iflag1 = readl(&regs->iflag1);
586         reg_esr = readl(&regs->esr);
587         writel(FLEXCAN_ESR_ERR_INT, &regs->esr);        /* ACK err IRQ */
588 +#ifdef CONFIG_COLDFIRE
589 +#ifdef CONFIG_FLEXCAN_NORXFIFO
590 +       writel(FLEXCAN_ESR_BOFF_INT, &regs->esr);
591 +#else
592 +       /* ACK TWRN and RWRN error, and bus-off interrupt*/
593 +       writel(FLEXCAN_ESR_ERR_STATE, &regs->esr);
594 +#endif
595 +#endif
596  
597         /*
598          * schedule NAPI in case of:
599 @@ -575,13 +742,14 @@ static irqreturn_t flexcan_irq(int irq,
600                        &regs->ctrl);
601                 napi_schedule(&priv->napi);
602         }
603 -
604 +#ifndef CONFIG_FLEXCAN_NORXFIFO
605         /* FIFO overflow */
606         if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
607                 writel(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, &regs->iflag1);
608                 dev->stats.rx_over_errors++;
609                 dev->stats.rx_errors++;
610         }
611 +#endif
612  
613         /* transmission complete interrupt */
614         if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) {
615 @@ -676,9 +844,14 @@ static int flexcan_chip_start(struct net
616          *
617          */
618         reg_mcr = readl(&regs->mcr);
619 +#ifdef CONFIG_FLEXCAN_NORXFIFO
620 +       reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
621 +               FLEXCAN_MCR_SUPV;
622 +#else
623         reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
624                 FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
625                 FLEXCAN_MCR_IDAM_C;
626 +#endif
627         dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr);
628         writel(reg_mcr, &regs->mcr);
629  
630 @@ -713,9 +886,19 @@ static int flexcan_chip_start(struct net
631                 writel(0, &regs->cantxfg[i].can_id);
632                 writel(0, &regs->cantxfg[i].data[0]);
633                 writel(0, &regs->cantxfg[i].data[1]);
634 -
635 +#ifdef CONFIG_FLEXCAN_NORXFIFO
636 +               if (i == FLEXCAN_TX_BUF_ID)
637 +                       continue;
638 +               if (i == FLEXCAN_RX_EXT_ID) /* enable receive extend message */
639 +                       writel(FLEXCAN_MB_CNT_CODE(0x4)|0x600000,
640 +                                       &regs->cantxfg[i].can_ctrl);
641 +               else
642 +                       writel(FLEXCAN_MB_CNT_CODE(0x4),
643 +                                       &regs->cantxfg[i].can_ctrl);
644 +#else
645                 /* put MB into rx queue */
646                 writel(FLEXCAN_MB_CNT_CODE(0x4), &regs->cantxfg[i].can_ctrl);
647 +#endif
648         }
649  
650         /* acceptance mask/acceptance code (accept everything) */
651 @@ -772,6 +955,7 @@ static void flexcan_chip_stop(struct net
652         return;
653  }
654  
655 +
656  static int flexcan_open(struct net_device *dev)
657  {
658         struct flexcan_priv *priv = netdev_priv(dev);
659 @@ -786,6 +970,24 @@ static int flexcan_open(struct net_devic
660         err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev);
661         if (err)
662                 goto out_close;
663 +       err = request_irq(dev->irq + 1, flexcan_irq, \
664 +                       IRQF_DISABLED, dev->name, dev);
665 +       if (err) {
666 +               free_irq(dev->irq, dev);
667 +               goto out_close;
668 +       }
669 +#if defined(CONFIG_M548X)
670 +       err = request_irq(dev->irq + 2, flexcan_irq, \
671 +                       IRQF_DISABLED, dev->name, dev);
672 +#elif defined(CONFIG_M5441X)
673 +       err = request_irq(dev->irq + 3, flexcan_irq, \
674 +                       IRQF_DISABLED, dev->name, dev);
675 +#endif
676 +       if (err) {
677 +               free_irq(dev->irq, dev);
678 +               free_irq(dev->irq + 1, dev);
679 +               goto out_close;
680 +       }
681  
682         /* start chip and queuing */
683         err = flexcan_chip_start(dev);
684 @@ -813,6 +1015,14 @@ static int flexcan_close(struct net_devi
685         flexcan_chip_stop(dev);
686  
687         free_irq(dev->irq, dev);
688 +#ifdef CONFIG_COLDFIRE
689 +       free_irq(dev->irq + 1, dev);
690 +#if defined(CONFIG_M548X)
691 +       free_irq(dev->irq + 2, dev);
692 +#elif defined(CONFIG_M5441X)
693 +       free_irq(dev->irq + 3, dev);
694 +#endif
695 +#endif
696         clk_disable(priv->clk);
697  
698         close_candev(dev);
699 @@ -854,14 +1064,23 @@ static int __devinit register_flexcandev
700  
701         clk_enable(priv->clk);
702  
703 +#if !defined(CONFIG_M548X)
704         /* select "bus clock", chip must be disabled */
705         flexcan_chip_disable(priv);
706         reg = readl(&regs->ctrl);
707         reg |= FLEXCAN_CTRL_CLK_SRC;
708         writel(reg, &regs->ctrl);
709 +#endif
710  
711         flexcan_chip_enable(priv);
712  
713 +#ifdef CONFIG_FLEXCAN_NORXFIFO
714 +       /* set freeze, halt and restrict register access */
715 +       reg = readl(&regs->mcr);
716 +       reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
717 +               FLEXCAN_MCR_SUPV;
718 +       writel(reg, &regs->mcr);
719 +#else
720         /* set freeze, halt and activate FIFO, restrict register access */
721         reg = readl(&regs->mcr);
722         reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
723 @@ -880,6 +1099,7 @@ static int __devinit register_flexcandev
724                 err = -ENODEV;
725                 goto out;
726         }
727 +#endif
728  
729         err = register_candev(dev);
730  
731 @@ -901,17 +1121,19 @@ static int __devinit flexcan_probe(struc
732         struct net_device *dev;
733         struct flexcan_priv *priv;
734         struct resource *mem;
735 -       struct clk *clk;
736 +       struct clk *clk = NULL;
737         void __iomem *base;
738         resource_size_t mem_size;
739         int err, irq;
740  
741 +#ifndef CONFIG_COLDFIRE
742         clk = clk_get(&pdev->dev, NULL);
743         if (IS_ERR(clk)) {
744                 dev_err(&pdev->dev, "no clock defined\n");
745                 err = PTR_ERR(clk);
746                 goto failed_clock;
747         }
748 +#endif
749  
750         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
751         irq = platform_get_irq(pdev, 0);
752 @@ -943,7 +1165,12 @@ static int __devinit flexcan_probe(struc
753         dev->flags |= IFF_ECHO; /* we support local echo in hardware */
754  
755         priv = netdev_priv(dev);
756 +#ifdef CONFIG_COLDFIRE
757 +       /* return value is core clock but we need bus clock */
758 +       priv->can.clock.freq = (clk_get_rate(clk)/2);
759 +#else
760         priv->can.clock.freq = clk_get_rate(clk);
761 +#endif
762         priv->can.bittiming_const = &flexcan_bittiming_const;
763         priv->can.do_set_mode = flexcan_set_mode;
764         priv->can.do_get_berr_counter = flexcan_get_berr_counter;