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
6 Each cpu core has two FlexCAN interface, and the M54418's FlexCAN
7 also support Rx message buffer FIFO mode but M548X not.
9 Signed-off-by: Jingchang Lu <b35083@freescale.com>
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
22 --- a/arch/m68k/Kconfig
23 +++ b/arch/m68k/Kconfig
24 @@ -372,6 +372,7 @@ config M547X
28 + select HAVE_CAN_FLEXCAN
32 @@ -430,6 +431,7 @@ config M5441X
35 select HAVE_FSL_USB_DR
36 + select HAVE_CAN_FLEXCAN
38 This option will add support for the MCF5441x processor with mmu.
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),)
47 +ifneq ($(CONFIG_CAN_FLEXCAN),)
48 +obj-y += mcf-flexcan.o
51 +++ b/arch/m68k/coldfire/m5441x/mcf-flexcan.c
54 + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
56 + * Author: Huan Wang, b18965@freescale.com, Fri Aug 08 2008
59 + * CAN bus driver for Freescale Coldfire embedded CPU
62 + * Fri Aug 08 2008 Huan Wang <b18965@freescale.com>
63 + * - create, support for MCF548x
65 + * Tue Dec 08 2009 ChengJu Cai <b22600@freescale.com>
66 + * - support for MCF532x MCF5253 MCF5227x
68 + * July 2011 Jingchang.Lu <b35083@freescale.com>
69 + * - Add into kernel CAN driver layer
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.
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>
86 +static struct resource mcf5441x_can0_resources[] = {
88 + .start = 0xFC020000,
90 + .flags = IORESOURCE_MEM,
93 + .start = 0 + 64 + 64,
95 + .flags = IORESOURCE_IRQ,
99 +static struct resource mcf5441x_can1_resources[] = {
101 + .start = 0xFC024000,
103 + .flags = IORESOURCE_MEM,
106 + .start = 4 + 64 + 64,
107 + .end = 4 + 64 + 64,
108 + .flags = IORESOURCE_IRQ,
112 +static struct platform_device mcf_flexcan[PDEV_MAX] = {
116 + .num_resources = ARRAY_SIZE(mcf5441x_can0_resources),
117 + .resource = mcf5441x_can0_resources,
122 + .num_resources = ARRAY_SIZE(mcf5441x_can1_resources),
123 + .resource = mcf5441x_can1_resources,
129 +static void __init mcf_flexcan_config(void)
131 + MCF_PM_PPMCR0 = 8; /* enable FlexCAN0 clock */
132 + MCF_PM_PPMCR0 = 9; /* enable FlexCAN1 clock */
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;
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;
152 +static int __init flexcan_of_to_pdev(void)
154 + int i, err = -ENODEV;
155 + for (i = 0; i < PDEV_MAX; i++) {
156 + err = platform_device_register(&mcf_flexcan[i]);
159 + printk(KERN_INFO "ColdFire FlexCAN devices loaded\n");
164 +static int __init mcf_flexcan_init(void)
167 + mcf_flexcan_config();
168 + err = flexcan_of_to_pdev();
173 +arch_initcall(mcf_flexcan_init);
174 --- a/arch/m68k/coldfire/m547x/Makefile
175 +++ b/arch/m68k/coldfire/m547x/Makefile
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
184 +++ b/arch/m68k/coldfire/m547x/mcf-flexcan.c
187 + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
189 + * Author: Huan Wang, b18965@freescale.com, Fri Aug 08 2008
192 + * CAN bus driver for Freescale Coldfire embedded CPU
195 + * Fri Aug 08 2008 Huan Wang <b18965@freescale.com>
196 + * - create, support for MCF548x
198 + * Tue Dec 08 2009 ChengJu Cai <b22600@freescale.com>
199 + * - support for MCF532x MCF5253 MCF5227x
201 + * July 2011 Jingchang.Lu <b35083@freescale.com>
202 + * - Add into kernel CAN driver layer
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.
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>
219 +static struct resource mcf548x_can0_resources[] = {
221 + .start = MCF_MBAR + 0x0000A000,
222 + .end = MCF_MBAR + 0x0000A7FF,
223 + .flags = IORESOURCE_MEM,
228 + .flags = IORESOURCE_IRQ,
232 +static struct resource mcf548x_can1_resources[] = {
234 + .start = MCF_MBAR + 0x0000A800,
235 + .end = MCF_MBAR + 0x0000AFFF,
236 + .flags = IORESOURCE_MEM,
241 + .flags = IORESOURCE_IRQ,
245 +static struct platform_device mcf_flexcan[PDEV_MAX] = {
249 + .num_resources = ARRAY_SIZE(mcf548x_can1_resources),
250 + .resource = mcf548x_can0_resources,
255 + .num_resources = ARRAY_SIZE(mcf548x_can1_resources),
256 + .resource = mcf548x_can1_resources,
262 +static void __init mcf_flexcan_config(void)
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;
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;
281 +static int __init flexcan_of_to_pdev(void)
283 + int i, err = -ENODEV;
284 + for (i = 0; i < PDEV_MAX; i++) {
285 + err = platform_device_register(&mcf_flexcan[i]);
288 + printk(KERN_INFO "ColdFire FlexCAN devices loaded\n");
293 +static int __init mcf_flexcan_init(void)
296 + mcf_flexcan_config();
297 + err = flexcan_of_to_pdev();
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
307 Say Y here if you want to support for Freescale FlexCAN.
309 +config FLEXCAN_NORXFIFO
310 + bool "FlexCAN message buffer without Rx FIFO mode"
311 + depends on CAN_FLEXCAN && COLDFIRE
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.
320 depends on CAN_DEV && PCI
321 --- a/drivers/net/can/flexcan.c
322 +++ b/drivers/net/can/flexcan.c
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.
329 * Based on code originally by Andrey Volkov <avolkov@varma-el.com>
332 #include <linux/module.h>
333 #include <linux/platform_device.h>
335 +#ifndef CONFIG_COLDFIRE
336 #include <mach/clock.h>
339 +#include <asm/mcfsim.h>
344 +#define readb(addr) __raw_readb(addr)
345 +#define readw(addr) __raw_readw(addr)
346 +#define readl(addr) __raw_readl(addr)
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)
357 #define DRV_NAME "flexcan"
359 /* 8 for RX fifo and 2 error handling */
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)
365 +#ifdef CONFIG_COLDFIRE
367 +# if defined(CONFIG_M548X)
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)
373 +# elif defined(CONFIG_M5441X)
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)
383 +#else /* !CONFIG_COLDFIRE */
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)
392 /* FLEXCAN error and status register (ESR) bits */
393 #define FLEXCAN_ESR_TWRN_INT BIT(17)
394 #define FLEXCAN_ESR_RWRN_INT BIT(16)
396 (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE)
398 /* FLEXCAN interrupt flag register (IFLAG) bits */
400 +#ifdef CONFIG_FLEXCAN_NORXFIFO
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))
411 #define FLEXCAN_TX_BUF_ID 8
412 #define FLEXCAN_IFLAG_BUF(x) BIT(x)
413 #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7)
415 (FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | FLEXCAN_IFLAG_RX_FIFO_AVAILABLE | \
416 FLEXCAN_IFLAG_BUF(FLEXCAN_TX_BUF_ID))
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 */
426 +#ifdef CONFIG_COLDFIRE
427 + struct flexcan_mb cantxfg[CAN_MB];
429 struct flexcan_mb cantxfg[64];
433 struct flexcan_priv {
434 @@ -181,8 +241,13 @@ struct flexcan_priv {
436 static struct can_bittiming_const flexcan_bittiming_const = {
438 +#ifdef CONFIG_COLDFIRE
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;
453 + u32 can_id, tmp, tmp1;
454 u32 ctrl = FLEXCAN_MB_CNT_CODE(0xc) | (cf->can_dlc << 16);
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;
467 can_id = (cf->can_id & CAN_SFF_MASK) << 18;
469 @@ -456,6 +526,87 @@ static int flexcan_poll_state(struct net
473 +#ifdef CONFIG_FLEXCAN_NORXFIFO
474 +/* Get one frame from receive message buffer */
475 +static int flexcan_read_frame(struct net_device *dev)
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;
485 + reg_iflag1 = readl(®s->iflag1);
487 + /* buf[0] if for TX */
488 + for (i = 0; i < CAN_MB; i++) {
489 + if (i == FLEXCAN_TX_BUF_ID)
491 + /* find one received message slot */
492 + if (reg_iflag1 & (0x01 << i))
498 + mb = ®s->cantxfg[i];
500 + skb = alloc_can_skb(dev, &cf);
501 + if (unlikely(!skb)) {
502 + stats->rx_dropped++;
506 + reg_ctrl = readl(&mb->can_ctrl);
507 + reg_id = readl(&mb->can_id);
509 + /* deactive RX buff */
510 + writel(0, &mb->can_ctrl);
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;
519 + cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
522 + cf->can_id = (reg_id >> 18) & CAN_SFF_MASK;
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);
528 + *(__be32 *)(cf->data + 0) = cpu_to_be32(readl(&mb->data[0]));
529 + *(__be32 *)(cf->data + 4) = cpu_to_be32(readl(&mb->data[1]));
531 + /* reactive RX buffer */
532 + if (i == FLEXCAN_RX_EXT_ID)
533 + writel(FLEXCAN_MB_CNT_CODE(0x4)|0x600000,
534 + ®s->cantxfg[i].can_ctrl);
536 + writel(FLEXCAN_MB_CNT_CODE(0x4),
537 + ®s->cantxfg[i].can_ctrl);
540 + writel((0x01 << i), ®s->iflag1);
541 + /* release MB lock */
542 + readl(®s->timer);
544 + netif_receive_skb(skb);
546 + stats->rx_packets++;
547 + stats->rx_bytes += cf->can_dlc;
554 static void flexcan_read_fifo(const struct net_device *dev,
555 struct can_frame *cf)
557 @@ -466,9 +617,16 @@ static void flexcan_read_fifo(const stru
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;
569 cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG;
573 cf->can_id = (reg_id >> 18) & CAN_SFF_MASK;
575 if (reg_ctrl & FLEXCAN_MB_CNT_RTR)
576 @@ -503,6 +661,7 @@ static int flexcan_read_frame(struct net
582 static int flexcan_poll(struct napi_struct *napi, int quota)
584 @@ -554,6 +713,14 @@ static irqreturn_t flexcan_irq(int irq,
585 reg_iflag1 = readl(®s->iflag1);
586 reg_esr = readl(®s->esr);
587 writel(FLEXCAN_ESR_ERR_INT, ®s->esr); /* ACK err IRQ */
588 +#ifdef CONFIG_COLDFIRE
589 +#ifdef CONFIG_FLEXCAN_NORXFIFO
590 + writel(FLEXCAN_ESR_BOFF_INT, ®s->esr);
592 + /* ACK TWRN and RWRN error, and bus-off interrupt*/
593 + writel(FLEXCAN_ESR_ERR_STATE, ®s->esr);
598 * schedule NAPI in case of:
599 @@ -575,13 +742,14 @@ static irqreturn_t flexcan_irq(int irq,
601 napi_schedule(&priv->napi);
604 +#ifndef CONFIG_FLEXCAN_NORXFIFO
606 if (reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_OVERFLOW) {
607 writel(FLEXCAN_IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
608 dev->stats.rx_over_errors++;
609 dev->stats.rx_errors++;
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
618 reg_mcr = readl(®s->mcr);
619 +#ifdef CONFIG_FLEXCAN_NORXFIFO
620 + reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
623 reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT |
624 FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN |
627 dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr);
628 writel(reg_mcr, ®s->mcr);
630 @@ -713,9 +886,19 @@ static int flexcan_chip_start(struct net
631 writel(0, ®s->cantxfg[i].can_id);
632 writel(0, ®s->cantxfg[i].data[0]);
633 writel(0, ®s->cantxfg[i].data[1]);
635 +#ifdef CONFIG_FLEXCAN_NORXFIFO
636 + if (i == FLEXCAN_TX_BUF_ID)
638 + if (i == FLEXCAN_RX_EXT_ID) /* enable receive extend message */
639 + writel(FLEXCAN_MB_CNT_CODE(0x4)|0x600000,
640 + ®s->cantxfg[i].can_ctrl);
642 + writel(FLEXCAN_MB_CNT_CODE(0x4),
643 + ®s->cantxfg[i].can_ctrl);
645 /* put MB into rx queue */
646 writel(FLEXCAN_MB_CNT_CODE(0x4), ®s->cantxfg[i].can_ctrl);
650 /* acceptance mask/acceptance code (accept everything) */
651 @@ -772,6 +955,7 @@ static void flexcan_chip_stop(struct net
656 static int flexcan_open(struct net_device *dev)
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);
663 + err = request_irq(dev->irq + 1, flexcan_irq, \
664 + IRQF_DISABLED, dev->name, dev);
666 + free_irq(dev->irq, dev);
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);
677 + free_irq(dev->irq, dev);
678 + free_irq(dev->irq + 1, dev);
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);
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);
696 clk_disable(priv->clk);
699 @@ -854,14 +1064,23 @@ static int __devinit register_flexcandev
701 clk_enable(priv->clk);
703 +#if !defined(CONFIG_M548X)
704 /* select "bus clock", chip must be disabled */
705 flexcan_chip_disable(priv);
706 reg = readl(®s->ctrl);
707 reg |= FLEXCAN_CTRL_CLK_SRC;
708 writel(reg, ®s->ctrl);
711 flexcan_chip_enable(priv);
713 +#ifdef CONFIG_FLEXCAN_NORXFIFO
714 + /* set freeze, halt and restrict register access */
715 + reg = readl(®s->mcr);
716 + reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
718 + writel(reg, ®s->mcr);
720 /* set freeze, halt and activate FIFO, restrict register access */
721 reg = readl(®s->mcr);
722 reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT |
723 @@ -880,6 +1099,7 @@ static int __devinit register_flexcandev
729 err = register_candev(dev);
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;
736 + struct clk *clk = NULL;
738 resource_size_t mem_size;
741 +#ifndef CONFIG_COLDFIRE
742 clk = clk_get(&pdev->dev, NULL);
744 dev_err(&pdev->dev, "no clock defined\n");
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 */
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);
760 priv->can.clock.freq = clk_get_rate(clk);
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;