diff -Naur xenomai-2.6.0/ksrc/drivers/can/flexcan/Kconfig xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/Kconfig
--- xenomai-2.6.0/ksrc/drivers/can/flexcan/Kconfig	1970-01-01 01:00:00.000000000 +0100
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/Kconfig	2012-08-01 15:09:00.000000000 +0200
@@ -0,0 +1,8 @@
+config XENO_DRIVERS_CAN_FLEXCAN
+	depends on XENO_DRIVERS_CAN && (ARCH_MX28)
+	tristate "FlexCAN driver for IMX28"
+	default n
+	help
+
+	This driver is for the FlexCAN on the i.MX28 from Freescale.
+
diff -Naur xenomai-2.6.0/ksrc/drivers/can/flexcan/Makefile xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/Makefile
--- xenomai-2.6.0/ksrc/drivers/can/flexcan/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/Makefile	2012-08-01 17:15:51.000000000 +0200
@@ -0,0 +1,9 @@
+# Makefile frag for Linux v2.6 and v3.x
+
+EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai -Idrivers/xenomai/can -Idrivers/xenomai/can/flexcan
+
+obj-$(CONFIG_XENO_DRIVERS_CAN_FLEXCAN) += xeno_can_flexcan.o
+obj-$(CONFIG_XENO_DRIVERS_CAN_FLEXCAN) += xeno_can_flexcan_imx28.o
+
+xeno_can_flexcan-y := rtcan_flexcan.o rtcan_flexcan_proc.o rtcan_flexcan_mbm.o
+xeno_can_flexcan_imx28-y := rtcan_flexcan_imx28.o
diff -Naur xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan.c xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan.c
--- xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan.c	1970-01-01 01:00:00.000000000 +0100
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan.c	2012-09-26 15:01:43.000000000 +0200
@@ -0,0 +1,671 @@
+/*
+ * Copyright 2012 Francesco Mandracci. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * based on xenomai-2.6.0/ksrc/drivers/net/can/sja1000/rtcan_sja1000.c
+ * Copyright (C) 2005, 2006 Sebastian Smolorz
+ *                          <Sebastian.Smolorz@stud.uni-hannover.de>
+ * Copyright (C) 2006 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * based on linux-2.6.35/drivers/net/can/flexcan/{dev,drv,mbm}.c
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+#include <linux/module.h>
+
+#include <rtdm/rtdm_driver.h>
+#include <rtdm/rtcan.h>
+
+#include <rtcan_socket.h>
+#include <rtcan_dev.h>
+#include <rtcan_raw.h>
+#include <rtcan_list.h>
+
+#include "rtcan_flexcan_regs.h"
+#include "rtcan_flexcan.h"
+
+static char *flexcan_ctrl_name = RTCAN_DRV_NAME;
+
+MODULE_AUTHOR("Francesco Mandracci <francesco.mandracci@gmail.com>");
+MODULE_DESCRIPTION("RTCAN driver for FlexCAN ");
+MODULE_SUPPORTED_DEVICE(RTCAN_DRV_NAME);
+MODULE_LICENSE("GPL");
+
+/* NB see linux-2.6.35/drivers/net/can/flexcan/{dev,drv,mbm}.c with
+ * "struct flexcan_device *flexcan" =---> "struct rtcan_flexcan *flexcan"
+ */
+
+#define STATE_OPERATING(state) \
+    ((state) != CAN_STATE_STOPPED && (state) != CAN_STATE_BUS_OFF)
+
+#define STATE_RESET(state) \
+    ((state) == CAN_STATE_STOPPED || (state) == CAN_STATE_BUS_OFF)
+
+static void flexcan_hw_start(struct rtcan_flexcan *flexcan)
+{
+	unsigned int reg;
+	if ((flexcan->maxmb + 1) > 32) {
+		__raw_writel(0xFFFFFFFF, flexcan->io_base + CAN_HW_REG_IMASK1);
+		reg = (1 << (flexcan->maxmb - 31)) - 1;
+		__raw_writel(reg, flexcan->io_base + CAN_HW_REG_IMASK2);
+	} else {
+		reg = (1 << (flexcan->maxmb + 1)) - 1;
+		__raw_writel(reg, flexcan->io_base + CAN_HW_REG_IMASK1);
+		__raw_writel(0, flexcan->io_base + CAN_HW_REG_IMASK2);
+	}
+
+	reg = __raw_readl(flexcan->io_base + CAN_HW_REG_MCR) & (~__MCR_HALT);
+	__raw_writel(reg, flexcan->io_base + CAN_HW_REG_MCR);
+}
+
+static void flexcan_hw_stop(struct rtcan_flexcan *flexcan)
+{
+	unsigned int reg;
+	reg = __raw_readl(flexcan->io_base + CAN_HW_REG_MCR);
+	__raw_writel(reg | __MCR_HALT, flexcan->io_base + CAN_HW_REG_MCR);
+}
+
+static inline void rtcan_flexcan_enable(struct rtcan_device *dev)
+{
+	struct rtcan_flexcan *chip = (struct rtcan_flexcan *)dev->priv;
+
+	chip->enable(dev, 1);
+}
+
+static inline void rtcan_flexcan_disable(struct rtcan_device *dev)
+{
+	struct rtcan_flexcan *chip = (struct rtcan_flexcan *)dev->priv;
+	
+	chip->enable(dev, 0);
+}
+
+static inline void rtcan_flexcan_err_interrupt(struct rtcan_device *dev,
+					     struct rtcan_flexcan *flexcan,
+					     struct rtcan_skb *skb,
+					     unsigned int r_status)
+{
+	struct rtcan_rb_frame *frame = &skb->rb_frame;
+	can_state_t state = dev->state;	
+	unsigned int esr, ecr;
+
+	// reading the ESR register seems necessary even if the manual states otherwise
+	 esr = r_status;
+	//esr = __raw_readl(flexcan->io_base + CAN_HW_REG_ESR);
+	__raw_writel(esr & __ESR_INTERRUPTS, flexcan->io_base + CAN_HW_REG_ESR);
+
+	skb->rb_frame_size = EMPTY_RB_FRAME_SIZE + CAN_ERR_DLC;
+	frame->can_id = CAN_ERR_FLAG | CAN_ERR_CRTL;
+	frame->can_dlc = CAN_ERR_DLC;
+	memset(&frame->data[0], 0, frame->can_dlc);
+
+	/* Data overrun interrupt? */
+	/* Arbitratio lost interrupt? */
+	/* TODO: check these */
+
+	if (esr & __ESR_BOFF_INT) {
+		state = CAN_STATE_BUS_OFF;
+		frame->can_id |= CAN_ERR_BUSOFF;
+		/* Wake up waiting senders */
+		rtdm_sem_destroy(&dev->tx_sem);
+        } else if (esr & __ESR_WAK_INT) {
+                state = dev->state_before_sleep;
+	} else if (esr & __ESR_TWRN_INT || esr & __ESR_RWRN_INT) {
+		state = CAN_STATE_BUS_WARNING;
+		if (esr & __ESR_TWRN_INT) {
+			frame->data[1] |= CAN_ERR_CRTL_TX_WARNING;
+		}
+		if (esr & __ESR_RWRN_INT) {
+			frame->data[1] |= CAN_ERR_CRTL_RX_WARNING;
+		}
+	} else if (esr & __ESR_ERR_INT) {
+		/* Bus error interrupt? */
+		state = CAN_STATE_BUS_WARNING;
+		frame->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+		if (esr & __ESR_BIT1_ERR)
+			frame->data[2] |= CAN_ERR_PROT_BIT1;
+
+		if (esr & __ESR_BIT0_ERR)
+			frame->data[2] |= CAN_ERR_PROT_BIT0;
+
+		if (esr & __ESR_ACK_ERR)
+			frame->can_id |= CAN_ERR_ACK;
+
+		/*TODO:// if (esr & __ESR_CRC_ERR) */
+
+		if (esr & __ESR_FRM_ERR)
+			frame->data[2] |= CAN_ERR_PROT_FORM;
+
+		if (esr & __ESR_STF_ERR)
+			frame->data[2] |= CAN_ERR_PROT_STUFF;
+
+		ecr = __raw_readl(flexcan->io_base + CAN_HW_REG_ECR);
+		switch ((esr & __ESR_FLT_CONF_MASK) >> __ESR_FLT_CONF_OFF) {
+		case 0:
+			if (__ECR_TX_ERR_COUNTER(ecr) >= __ECR_ACTIVE_THRESHOLD)
+				frame->data[1] |= CAN_ERR_CRTL_TX_WARNING;
+			if (__ECR_RX_ERR_COUNTER(ecr) >= __ECR_ACTIVE_THRESHOLD)
+				frame->data[1] |= CAN_ERR_CRTL_RX_WARNING;
+			break;
+		case 1:
+			if (__ECR_TX_ERR_COUNTER(ecr) >=
+			    __ECR_PASSIVE_THRESHOLD)
+				frame->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
+
+			if (__ECR_RX_ERR_COUNTER(ecr) >=
+			    __ECR_PASSIVE_THRESHOLD)
+				frame->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
+			break;
+		default:
+			frame->can_id |= CAN_ERR_BUSOFF;
+		}
+	/* Re-entrance into error active state from bus-warn? */
+	} else if (state == CAN_STATE_BUS_WARNING) {
+	    state = CAN_STATE_ACTIVE;
+
+	} else {
+	    /* Bus-off recovery complete, enable all interrupts again */
+	    /*TODO: check bus off condition*/
+	}
+
+    dev->state = state;
+    frame->can_ifindex = dev->ifindex;
+}
+
+static int rtcan_flexcan_interrupt(rtdm_irq_t *irq_handle)
+{
+    struct rtcan_device *dev;
+    struct rtcan_flexcan *flexcan;
+    struct rtcan_skb skb;
+    int recv_lock_free = 1;
+    int ret = RTDM_IRQ_NONE;
+    unsigned int reg;
+    int tx, i;
+
+    memset(&skb, 0, sizeof(skb));
+    /* Get the ID of the device which registered this IRQ. */
+    dev = (struct rtcan_device *)rtdm_irq_get_arg(irq_handle, void);
+    flexcan = (struct rtcan_flexcan *)dev->priv;
+
+    /* Take spinlock protecting HW register access and device structures. */
+    rtdm_lock_get(&dev->device_lock);
+
+    reg = __raw_readl(flexcan->io_base + CAN_HW_REG_ESR);
+
+    /* Error Interrupt? */
+    if (reg & __ESR_INTERRUPTS) {
+        ret = RTDM_IRQ_HANDLED;
+    	rtcan_flexcan_err_interrupt(dev, flexcan, &skb, reg);
+        if (!(reg & __ESR_BOFF_INT)) {
+	    if (recv_lock_free) {
+	        recv_lock_free = 0;
+	        rtdm_lock_get(&rtcan_recv_list_lock);
+	        rtdm_lock_get(&rtcan_socket_lock);
+	    }
+	    /* Pass error frame out to the sockets */
+	    rtcan_rcv(dev, &skb);
+	}
+    }
+
+    /* Transmit or Receive Interrupt? */
+    ret = RTDM_IRQ_HANDLED;
+    /* rtcan_flexcan_mbm_isr() -> flexcan_mb_bottom() -> rtcan_rcv()+rtdm_lock_get() */
+    tx = rtcan_flexcan_mbm_isr(dev, flexcan, &skb, &recv_lock_free);
+    
+    /* Transmit Interrupt? */
+    for (i = 0; i < tx; ++i) {
+        /* Wake up a sender */
+        rtdm_sem_up(&dev->tx_sem);
+    
+        if (rtcan_loopback_pending(dev)) {
+		if (recv_lock_free) {
+		    recv_lock_free = 0;
+		    rtdm_lock_get(&rtcan_recv_list_lock);
+		    rtdm_lock_get(&rtcan_socket_lock);
+		}
+		rtcan_loopback(dev);
+        }
+    }
+    if (flexcan->irq_ack)
+	flexcan->irq_ack(dev);
+
+    /* Release spinlocks */
+    if (!recv_lock_free) {
+	rtdm_lock_put(&rtcan_socket_lock);
+	rtdm_lock_put(&rtcan_recv_list_lock);
+    }
+    rtdm_lock_put(&dev->device_lock);
+    return ret;
+}
+
+static inline void flexcan_ctrl_setup(struct rtcan_flexcan *flexcan)
+{
+	unsigned int reg;
+
+	reg = __raw_readl(flexcan->io_base + CAN_HW_REG_CTRL);
+	reg &= ~(__CTRL_PRESDIV_MASK | __CTRL_RJW_MASK | __CTRL_PSEG1_MASK |
+		 __CTRL_PSEG2_MASK | __CTRL_PROPSEG_MASK);
+
+	if (flexcan->loopback)
+		reg |= __CTRL_LPB;
+	else
+		reg &= ~__CTRL_LPB;
+
+	if (flexcan->smp)
+		reg |= __CTRL_SMP;
+	else
+		reg &= ~__CTRL_SMP;
+
+	if (flexcan->boff_rec)
+		reg |= __CTRL_BOFF_REC;
+	else
+		reg &= ~__CTRL_BOFF_REC;
+
+	if (flexcan->tsyn)
+		reg |= __CTRL_TSYN;
+	else
+		reg &= ~__CTRL_TSYN;
+
+	if (flexcan->listen)
+		reg |= __CTRL_LOM;
+	else
+		reg &= ~__CTRL_LOM;
+
+	reg |= (flexcan->br_presdiv << __CTRL_PRESDIV_OFFSET) |
+	    (flexcan->br_rjw << __CTRL_RJW_OFFSET) |
+	    (flexcan->br_pseg1 << __CTRL_PSEG1_OFFSET) |
+	    (flexcan->br_pseg2 << __CTRL_PSEG2_OFFSET) |
+	    (flexcan->br_propseg << __CTRL_PROPSEG_OFFSET);
+
+	reg &= ~__CTRL_LBUF;
+
+	//reg |= __CTRL_TWRN_MSK | __CTRL_RWRN_MSK | __CTRL_BOFF_MSK |
+	//    __CTRL_ERR_MSK;
+	reg &= ~(__CTRL_TWRN_MSK | __CTRL_RWRN_MSK | __CTRL_BOFF_MSK |
+	    __CTRL_ERR_MSK);
+
+	__raw_writel(reg, flexcan->io_base + CAN_HW_REG_CTRL);
+}
+
+static int rtcan_flexcan_mode_stop(struct rtcan_device *dev,
+				 rtdm_lockctx_t *lock_ctx)
+{
+	struct rtcan_flexcan *flexcan = (struct rtcan_flexcan *)dev->priv;
+	can_state_t state;
+
+	state = dev->state;
+	if (STATE_RESET(state))
+		goto out;
+	flexcan_hw_stop(flexcan);
+	dev->state = CAN_STATE_STOPPED;
+	rtdm_sem_destroy(&dev->tx_sem);
+out:
+	return 0;
+}
+
+static int rtcan_flexcan_mode_start(struct rtcan_device *dev,
+				  rtdm_lockctx_t *lock_ctx)
+{
+    int ret = 0;
+    struct rtcan_flexcan *chip = (struct rtcan_flexcan *)dev->priv;
+
+    if (dev->ctrl_mode & CAN_CTRLMODE_LISTENONLY)
+        ; /* FIXME return error */
+    if (dev->ctrl_mode & CAN_CTRLMODE_LOOPBACK)
+        ; /* FIXME return error */
+
+    switch (dev->state) {
+
+    case CAN_STATE_ACTIVE:
+    case CAN_STATE_BUS_WARNING:
+    case CAN_STATE_BUS_PASSIVE:
+        break;
+
+    case CAN_STATE_STOPPED:
+    case CAN_STATE_BUS_OFF:
+	flexcan_hw_start(chip);
+        dev->state = CAN_STATE_ACTIVE;
+        rtdm_sem_init(&dev->tx_sem, 1);
+        break;
+
+    case CAN_STATE_SLEEPING:
+	/* TODO */
+        break;
+
+    default:
+        ;
+    }
+    return ret;
+}
+
+static int rtcan_flexcan_set_bit_time(struct rtcan_device *dev,
+				    struct can_bittime *bit_time,
+				    rtdm_lockctx_t *lock_ctx)
+{
+    struct rtcan_flexcan *flexcan = (struct rtcan_flexcan *)dev->priv;
+
+    switch (bit_time->type) {
+    case CAN_BITTIME_BTR:
+	return -EINVAL;
+
+    case CAN_BITTIME_STD:
+	flexcan->br_presdiv = bit_time->std.brp;
+	flexcan->br_rjw = bit_time->std.sjw;
+	flexcan->br_pseg1 = bit_time->std.phase_seg1;
+	flexcan->br_pseg2 = bit_time->std.phase_seg2;
+	flexcan->br_propseg = bit_time->std.prop_seg;
+	/* ignore triple sampling bit_time->std.sam; */
+	break;
+
+    default:
+	return -EINVAL;
+    }
+
+    flexcan_ctrl_setup(flexcan);
+    return 0;
+}
+
+static int rtcan_flexcan_start_xmit(struct rtcan_device *dev, can_frame_t *cframe)
+{
+	struct rtcan_flexcan *flexcan = (struct rtcan_flexcan *)dev->priv;
+	
+	if (cframe->can_dlc > 8) {
+		return -EINVAL;
+	}
+	if (rtcan_flexcan_mbm_xmit(flexcan, cframe) < 0) {
+		return -EIO;
+	}
+	return 0;
+}
+
+static int flexcan_hw_reset(struct rtcan_flexcan *flexcan)
+{
+	unsigned int reg;
+	int timeout = 100000;
+
+	reg = __raw_readl(flexcan->io_base + CAN_HW_REG_MCR);
+	__raw_writel(reg | __MCR_MDIS, flexcan->io_base + CAN_HW_REG_MCR);
+
+	reg = __raw_readl(flexcan->io_base + CAN_HW_REG_CTRL);
+	if (flexcan->br_clksrc)
+		reg |= __CTRL_CLK_SRC;
+	else
+		reg &= ~__CTRL_CLK_SRC;
+	__raw_writel(reg, flexcan->io_base + CAN_HW_REG_CTRL);
+
+	reg = __raw_readl(flexcan->io_base + CAN_HW_REG_MCR) & (~__MCR_MDIS);
+	__raw_writel(reg, flexcan->io_base + CAN_HW_REG_MCR);
+	reg |= __MCR_SOFT_RST;
+	__raw_writel(reg, flexcan->io_base + CAN_HW_REG_MCR);
+
+	reg = __raw_readl(flexcan->io_base + CAN_HW_REG_MCR);
+	while (reg & __MCR_SOFT_RST) {
+		if (--timeout <= 0) {
+			printk(KERN_ERR "Flexcan software Reset Timeouted\n");
+			return -1;
+		}
+		udelay(10);
+		reg = __raw_readl(flexcan->io_base + CAN_HW_REG_MCR);
+	}
+	return 0;
+}
+
+static inline void flexcan_mcr_setup(struct rtcan_flexcan *flexcan)
+{
+	unsigned int reg;
+
+	reg = __raw_readl(flexcan->io_base + CAN_HW_REG_MCR);
+	reg &= ~(__MCR_MAX_MB_MASK | __MCR_WAK_MSK | __MCR_MAX_IDAM_MASK);
+
+	if (flexcan->fifo)
+		reg |= __MCR_FEN;
+	else
+		reg &= ~__MCR_FEN;
+
+	if (flexcan->wakeup)
+		reg |= __MCR_SLF_WAK | __MCR_WAK_MSK;
+	else
+		reg &= ~(__MCR_SLF_WAK | __MCR_WAK_MSK);
+
+	if (flexcan->wak_src)
+		reg |= __MCR_WAK_SRC;
+	else
+		reg &= ~__MCR_WAK_SRC;
+
+	if (flexcan->srx_dis)
+		reg |= __MCR_SRX_DIS;
+	else
+		reg &= ~__MCR_SRX_DIS;
+
+	if (flexcan->bcc)
+		reg |= __MCR_BCC;
+	else
+		reg &= ~__MCR_BCC;
+
+	if (flexcan->lprio)
+		reg |= __MCR_LPRIO_EN;
+	else
+		reg &= ~__MCR_LPRIO_EN;
+
+	if (flexcan->abort)
+		reg |= __MCR_AEN;
+	else
+		reg &= ~__MCR_AEN;
+
+	reg |= (flexcan->maxmb << __MCR_MAX_MB_OFFSET);
+	reg |= __MCR_DOZE | __MCR_MAX_IDAM_C;
+	__raw_writel(reg, flexcan->io_base + CAN_HW_REG_MCR);
+}
+
+static int flexcan_hw_open(struct rtcan_flexcan *flexcan)
+{
+	if (flexcan_hw_reset(flexcan))
+		return -EFAULT;
+
+	flexcan_mcr_setup(flexcan);
+	flexcan_ctrl_setup(flexcan);
+
+	__raw_writel(0, flexcan->io_base + CAN_HW_REG_IMASK2);
+	__raw_writel(0, flexcan->io_base + CAN_HW_REG_IMASK1);
+
+	__raw_writel(0xFFFFFFFF, flexcan->io_base + CAN_HW_REG_IFLAG2);
+	__raw_writel(0xFFFFFFFF, flexcan->io_base + CAN_HW_REG_IFLAG1);
+
+	__raw_writel(0, flexcan->io_base + CAN_HW_REG_ECR);
+	return 0;
+}
+
+static int flexcan_chip_config(struct rtcan_device *dev)
+{
+	struct rtcan_flexcan *flexcan = (struct rtcan_flexcan *)dev->priv;
+
+	
+	if (flexcan_hw_open(flexcan))
+		return -1;
+	rtcan_flexcan_mbm_init(flexcan);
+	flexcan_hw_start(flexcan);
+	return 0;
+}
+
+static inline int rtcan_flexcan_is_operating(struct rtcan_device *dev,
+					 can_state_t *state)
+{
+    int is_operating = STATE_OPERATING(*state);
+#if 0
+    struct rtcan_flexcan *flexcan = (struct rtcan_flexcan *)dev->priv;
+
+    /* this won't work in real-time because there's not enough time for the
+       FlexCAN hw module to initialize, so "unlikely" becomes "always" :(
+    */
+    if (unlikely(is_operating &&
+	__raw_readl(flexcan->io_base + CAN_HW_REG_MCR) & (~__MCR_NOTRDY))) {
+	*state = CAN_STATE_STOPPED;
+	is_operating = 0;
+	/* Disable the controller's interrupts */
+	__raw_writel(0, flexcan->io_base + CAN_HW_REG_IMASK2);
+	__raw_writel(0, flexcan->io_base + CAN_HW_REG_IMASK1);
+	/* Wake up waiting senders */
+	rtdm_sem_destroy(&dev->tx_sem);
+    }
+#endif
+    return is_operating;
+}
+
+static can_state_t rtcan_flexcan_get_state(struct rtcan_device *dev)
+{
+    can_state_t state = dev->state;
+    rtcan_flexcan_is_operating(dev, &state);
+    return state;
+}
+
+static int rtcan_flexcan_set_mode(struct rtcan_device *dev,
+		       can_mode_t mode,
+		       rtdm_lockctx_t *lock_ctx)
+{
+    int ret = 0;
+    can_state_t state;
+    struct rtcan_flexcan *flexcan = (struct rtcan_flexcan*)dev->priv;
+
+    switch (mode) {
+
+    case CAN_MODE_STOP:
+	ret = rtcan_flexcan_mode_stop(dev, lock_ctx);
+	break;
+
+    case CAN_MODE_START:
+	ret = rtcan_flexcan_mode_start(dev, lock_ctx);
+	break;
+
+    case CAN_MODE_SLEEP:
+
+	state = dev->state;
+
+	/* Controller must operate, otherwise go out */
+	if (!rtcan_flexcan_is_operating(dev, &state)) {
+	    ret = -ENETDOWN;
+	    goto mode_sleep_out;
+	}
+
+	/* Is controller sleeping yet? If yes, go out */
+	if (state == CAN_STATE_SLEEPING)
+	    goto mode_sleep_out;
+
+	/* Remember into which state to return when we
+	 * wake up */
+	dev->state_before_sleep = state;
+
+	/* Let's take a nap. (Now I REALLY understand
+	 * the meaning of interrupts ...) */
+	state = CAN_STATE_SLEEPING;
+	flexcan_hw_stop(flexcan);
+
+    mode_sleep_out:
+	dev->state = state;
+	break;
+
+    default:
+	ret = -EOPNOTSUPP;
+	break;
+    }
+
+    return ret;
+}
+
+int rtcan_flexcan_register(struct rtcan_device *dev)
+{
+	int ret;
+	struct rtcan_flexcan *chip;
+
+	if (dev == NULL)
+		return -EINVAL;
+	chip = (struct rtcan_flexcan *)dev->priv;
+	if (chip == NULL)
+		return -EINVAL;
+
+	/* Enable FlexCAN module */
+	rtcan_flexcan_enable(dev);
+
+	/* Enter reset mode */
+	dev->state = CAN_STATE_ACTIVE;
+	rtcan_flexcan_mode_stop(dev, NULL);
+
+	dev->ctrl_name = flexcan_ctrl_name;
+	dev->hard_start_xmit = rtcan_flexcan_start_xmit;
+	dev->do_set_mode = rtcan_flexcan_set_mode;
+	dev->do_get_state = rtcan_flexcan_get_state;
+	dev->do_set_bit_time = rtcan_flexcan_set_bit_time;
+
+	ret = rtdm_irq_request(&dev->irq_handle, chip->irq_num,
+				rtcan_flexcan_interrupt, chip->irq_flags,
+				dev->ctrl_name, (void *)dev);
+	if (ret) {
+		printk(KERN_ERR "ERROR %d: rtdm_irq_request(%d) failed\n",
+			ret, chip->irq_num);
+		goto out_can_disable;
+	}
+	/* Configure FlexCAN module */
+	if (flexcan_chip_config(dev)) {
+		printk(KERN_ERR
+		       "ERROR while trying to configure FlexCAN device!\n");
+		goto out_irq_free;
+	}
+
+	/* Register RTDM device */
+	ret = rtcan_dev_register(dev);
+	if (ret) {
+		printk(KERN_ERR
+		       "ERROR while trying to register RTCAN device!\n");
+		goto out_irq_free;
+	}
+	rtcan_flexcan_create_proc(dev);
+	return 0;
+
+out_irq_free:
+	rtdm_irq_free(&dev->irq_handle);
+out_can_disable:
+	/* Disable FLEXCAN module. */
+	rtcan_flexcan_disable(dev);
+	return ret;
+}
+
+void rtcan_flexcan_unregister(struct rtcan_device *dev)
+{
+	struct rtcan_flexcan *chip;
+
+	if (dev == NULL)
+		return;
+	chip = (struct rtcan_flexcan *)dev->priv;
+	if (chip == NULL)
+		return;
+
+	printk("Unregistering %s device %s\n", RTCAN_DRV_NAME, dev->name);
+	rtdm_irq_disable(&dev->irq_handle);
+	rtcan_flexcan_mode_stop(dev, NULL);
+	rtdm_irq_free(&dev->irq_handle);
+	rtcan_flexcan_remove_proc(dev);
+	rtcan_flexcan_disable(dev);
+	rtcan_dev_unregister(dev);
+}
+
+int __init rtcan_flexcan_init(void)
+{
+    printk("RTCAN %s driver initialized\n", RTCAN_DRV_NAME);
+    return 0;
+}
+
+void __exit rtcan_flexcan_exit(void)
+{
+    printk("RTCAN %s driver removed\n", RTCAN_DRV_NAME);
+}
+
+module_init(rtcan_flexcan_init);
+module_exit(rtcan_flexcan_exit);
+
+EXPORT_SYMBOL_GPL(rtcan_flexcan_register);
+EXPORT_SYMBOL_GPL(rtcan_flexcan_unregister);
diff -Naur xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan.h xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan.h
--- xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan.h	1970-01-01 01:00:00.000000000 +0100
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan.h	2012-09-19 17:10:19.000000000 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2012 Francesco Mandracci. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * based on xenomai-2.6.0/ksrc/drivers/net/can/mscan/rtcan_mscan.h
+ * Copyright (C) 2009 Wolfgang Grandegger <wg@denx.de>
+ * based on xenomai-2.6.0/ksrc/drivers/net/can/sja1000/rtcan_sja1000.h
+ * Copyright (C) 2006 Wolfgang Grandegger <wg@denx.de>
+ */
+
+#ifndef __RTCAN_FLEXCAN_H_
+#define __RTCAN_FLEXCAN_H_
+
+#define RTCAN_DEV_NAME    "rtcan%d"
+#define RTCAN_DRV_NAME    "rtcan_flexcan"
+
+/* FLEXCAN type variants */
+enum {
+        FLEXCAN_TYPE_IMX28
+};
+
+struct rtcan_flexcan {
+	void (*enable)(struct rtcan_device *dev, int enable);
+	void (*irq_ack)(struct rtcan_device *dev);
+
+	volatile void __iomem *io_base;
+	unsigned short irq_num;
+	unsigned short irq_flags;
+	unsigned short id;
+
+        struct can_hw_mb *hwmb;
+        unsigned int *rx_mask;
+        unsigned int xmit_mb;
+        unsigned int bitrate;
+
+	/* word 1 */
+	unsigned int br_presdiv:8;
+	unsigned int br_rjw:2;
+	unsigned int br_propseg:3;
+	unsigned int br_pseg1:3;
+	unsigned int br_pseg2:3;
+	unsigned int maxmb:6;
+	unsigned int xmit_maxmb:6;
+	unsigned int wd1_resv:1;
+
+	/* word 2 */
+	unsigned int fifo:1;
+	unsigned int wakeup:1;
+	unsigned int srx_dis:1;
+	unsigned int wak_src:1;
+	unsigned int bcc:1;
+	unsigned int lprio:1;
+	unsigned int abort:1;
+	unsigned int br_clksrc:1;
+	unsigned int loopback:1;
+	unsigned int smp:1;
+	unsigned int boff_rec:1;
+	unsigned int tsyn:1;
+	unsigned int listen:1;
+	
+	unsigned int ext_msg:1;
+	unsigned int std_msg:1;
+};
+
+extern int rtcan_flexcan_register(struct rtcan_device *dev);
+extern void rtcan_flexcan_unregister(struct rtcan_device *dev);
+
+extern int rtcan_flexcan_create_proc(struct rtcan_device* dev);
+extern void rtcan_flexcan_remove_proc(struct rtcan_device* dev);
+
+extern void rtcan_flexcan_mbm_init(struct rtcan_flexcan *flexcan);
+extern int rtcan_flexcan_mbm_isr(struct rtcan_device *dev,
+			struct rtcan_flexcan *flexcan,
+			struct rtcan_skb *skb,
+			int *rcv_lock_free_ptr);
+extern int rtcan_flexcan_mbm_xmit(struct rtcan_flexcan *flexcan, struct can_frame *cframe);
+
+#endif
diff -Naur xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan_imx28.c xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan_imx28.c
--- xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan_imx28.c	1970-01-01 01:00:00.000000000 +0100
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan_imx28.c	2012-09-19 09:25:50.000000000 +0200
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2012 Francesco Mandracci. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * based on xenomai-2.6.0/ksrc/drivers/can/sja1000/rtcan_mem.c
+ * Copyright (C) 2006 Matthias Fuchs <matthias.fuchs@esd-electronics.com>,
+ *                    Jan Kiszka <jan.kiszka@web.de>
+ */
+
+#include <linux/module.h>
+
+#include <rtdm/rtdm_driver.h>
+#include <rtdm/rtcan.h>
+#include "rtcan_dev.h"
+#include "rtcan_raw.h"
+#include "rtcan_internal.h"
+#include "rtcan_flexcan.h"
+#include "rtcan_flexcan_regs.h"
+
+#include <mach/hardware.h> // <mach/mx28.h>
+#include <mach/pinctrl.h>
+#include <mach/gpio.h>
+
+
+//#include <arch/arm/mach-mx28/regs-clkctrl.h>
+//#include <arch/arm/mach-mx28/mx28_pins.h>
+#define HW_CLKCTRL_FLEXCAN           (0x00000160)
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN0 0x40000000
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN1 0x10000000
+#define PINID_SSP1_CMD		MXS_PIN_ENCODE(2, 13)
+
+#define RTCAN_IMX28_MAX_DEV 2
+
+MODULE_AUTHOR("Francesco Mandracci <francesco.mandracci@gmail.com>");
+MODULE_DESCRIPTION("RTCAN driver for FlexCAN on i.MX28");
+MODULE_SUPPORTED_DEVICE(RTCAN_DRV_NAME);
+MODULE_LICENSE("GPL");
+
+struct rtcan_imx28
+{
+	u32 base_addr;
+	u32 base_size;
+};
+
+static struct rtcan_device *rtcan_devs[RTCAN_IMX28_MAX_DEV];
+
+static void rtcan_imx28_enable(struct rtcan_device *dev, int enable)
+{
+	struct rtcan_flexcan *chip = (struct rtcan_flexcan *)dev->priv;
+	unsigned enable_reg, enable_bits, reg;
+
+	enable_reg = IO_ADDRESS(CLKCTRL_PHYS_ADDR) + HW_CLKCTRL_FLEXCAN;
+	if (chip->id == 0) {
+		enable_bits = BM_CLKCTRL_FLEXCAN_STOP_CAN0;
+	} else {
+		enable_bits = BM_CLKCTRL_FLEXCAN_STOP_CAN1;
+	}
+	reg = __raw_readl(enable_reg);
+	if (enable) {
+		reg &= ~enable_bits;
+#ifdef CONFIG_MECT_CUSTOMIZATION
+		gpio_set_value(MXS_PIN_TO_GPIO(PINID_SSP1_CMD), 0);
+#else
+		gpio_set_value(MXS_PIN_TO_GPIO(PINID_SSP1_CMD), 1);
+#endif
+	} else {
+		reg |= enable_bits;
+#ifdef CONFIG_MECT_CUSTOMIZATION
+		gpio_set_value(MXS_PIN_TO_GPIO(PINID_SSP1_CMD), 1);
+#else
+		gpio_set_value(MXS_PIN_TO_GPIO(PINID_SSP1_CMD), 0);
+#endif
+	}
+	__raw_writel(reg, enable_reg);
+}
+
+int __init rtcan_imx28_init_one(int idx)
+{
+	struct rtcan_device *dev;
+	struct rtcan_flexcan *chip;
+	struct rtcan_imx28 *board;
+	int ret;
+
+	dev = rtcan_dev_alloc(sizeof(struct rtcan_flexcan),
+                                   sizeof(struct rtcan_imx28));
+	if (dev == NULL)
+		return -ENOMEM;
+
+	chip = (struct rtcan_flexcan *)dev->priv;
+	board = (struct rtcan_imx28 *)dev->board_priv;
+
+	dev->board_name = "iMX28";
+	chip->irq_flags = RTDM_IRQTYPE_SHARED; /* FIXME */
+	chip->enable = rtcan_imx28_enable;
+
+	// arch/arm/mach-mx28/device.c
+	chip->id = idx;
+	chip->br_presdiv = 2;
+	chip->br_rjw = 2;
+	chip->br_propseg = 4;
+	chip->br_pseg1 = 4;
+	chip->br_pseg2 = 4;
+	chip->srx_dis = 1;
+	chip->bcc = 1;
+	chip->br_clksrc = 1;
+	chip->smp = 0;
+	chip->boff_rec = 1;
+	chip->ext_msg = 1;
+	chip->std_msg = 1;
+
+	// linux-2.6.35.3_ipipe/drivers/net/can/flexcan/dev.c
+	chip->maxmb = FLEXCAN_MAX_MB - 1;
+	chip->xmit_maxmb = (FLEXCAN_MAX_MB >> 1) - 1;
+	chip->xmit_mb = chip->maxmb - chip->xmit_maxmb;
+	// chip->wd1_resv = 0;
+	chip->fifo = 0;
+	// chip->wakeup = 0;
+	// chip->wak_src = 0;
+	// chip->lprio = 0;
+	// chip->abort = 0;
+	// chip->loopback = 0;
+	// chip->tsyn = 0;
+	// chip->listen = 0;
+
+	switch (idx) {
+	case 0:
+		chip->irq_num = IRQ_CAN0;
+		board->base_addr = CAN0_PHYS_ADDR;
+		board->base_size = 0x2000;
+		break;
+	case 1:
+		chip->irq_num = IRQ_CAN1;
+		board->base_addr = CAN1_PHYS_ADDR;
+		board->base_size = 0x2000;
+		break;
+	default:
+		;
+	}
+	if (!request_mem_region(board->base_addr, board->base_size, RTCAN_DRV_NAME)) {
+		ret = -EBUSY;
+		goto out_dev_free;
+	}
+	/* ioremap io memory */
+	if (!(chip->io_base = ioremap(board->base_addr, board->base_size))) {
+		ret = -EBUSY;
+		goto out_release_mem;
+	}
+	chip->hwmb = (struct can_hw_mb *)(chip->io_base + CAN_MB_BASE);
+	chip->rx_mask = (unsigned int *)(chip->io_base + CAN_RXMASK_BASE);
+	/* Clock frequency in Hz */
+	dev->can_sys_clock = 24000000; /* XTALCLK 0 24MHz */
+	/* Registration */
+	strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ);
+	ret = rtcan_flexcan_register(dev);
+	if (ret) {
+		printk(KERN_ERR "ERROR %d while trying to register FLEXCAN "
+		       "device!\n", ret);
+		goto out_iounmap;
+	}
+	rtcan_devs[idx] = dev;
+	return 0;
+
+ out_iounmap:
+	iounmap((void *)chip->io_base);
+
+ out_release_mem:
+	release_mem_region(board->base_addr, board->base_size);
+
+ out_dev_free:
+	rtcan_dev_free(dev);
+
+	return ret;
+}
+
+static void rtcan_flexcan_imx28_exit(void);
+
+/** Init module */
+static int __init rtcan_flexcan_imx28_init(void)
+{
+	int i, err;
+	int devices = 0;
+
+	for (i = 0; i < RTCAN_IMX28_MAX_DEV; i++) {
+		err = rtcan_imx28_init_one(i);
+		if (err) {
+			rtcan_flexcan_imx28_exit();
+			return err;
+		}
+		devices++;
+	}
+	if (devices)
+		return 0;
+	return -EINVAL;
+}
+
+
+/** Cleanup module */
+static void rtcan_flexcan_imx28_exit(void)
+{
+	int i;
+	struct rtcan_device *dev;
+
+	for (i = 0; i < RTCAN_IMX28_MAX_DEV; i++) {
+		struct rtcan_flexcan *chip;
+		struct rtcan_imx28 *board;
+
+		dev = rtcan_devs[i];
+		if (!dev)
+			continue;
+		chip = (struct rtcan_flexcan *)dev->priv;
+		board = (struct rtcan_imx28 *)dev->board_priv;
+		rtcan_flexcan_unregister(dev);
+		iounmap(chip->io_base);
+		release_mem_region(board->base_addr, board->base_size);
+		rtcan_dev_free(dev);
+	}
+}
+
+module_init(rtcan_flexcan_imx28_init);
+module_exit(rtcan_flexcan_imx28_exit);
diff -Naur xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan_mbm.c xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan_mbm.c
--- xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan_mbm.c	1970-01-01 01:00:00.000000000 +0100
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan_mbm.c	2012-09-26 15:06:14.000000000 +0200
@@ -0,0 +1,347 @@
+/*
+ * Copyright 2012 Francesco Mandracci. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * based on linux-2.6.35.3_ipipe/drivers/net/can/flexcan/mbm.c
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+#include <linux/module.h>
+
+#include <rtdm/rtdm_driver.h>
+#include <rtdm/rtcan.h>
+#include "rtcan_dev.h"
+#include "rtcan_raw.h"
+#include "rtcan_internal.h"
+#include "rtcan_flexcan.h"
+#include "rtcan_flexcan_regs.h"
+
+#include <mach/hardware.h> // <mach/mx28.h>
+
+#if 0
+#define flexcan_swab32(x)	\
+	(((x) << 24) | ((x) >> 24) |\
+		(((x) & (__u32)0x0000ff00UL) << 8) |\
+		(((x) & (__u32)0x00ff0000UL) >> 8))
+
+static inline void flexcan_memcpy(void *dst, void *src, int len)
+{
+	int i;
+	unsigned int *d = (unsigned int *)dst, *s = (unsigned int *)src;
+	len = (len + 3) >> 2;
+	for (i = 0; i < len; i++, s++, d++)
+		*d = flexcan_swab32(*s);
+}
+#else
+/* necessary for avoiding alignment traps, which cause illegal calls
+   between Linux and Xenomai domains (don't know why there are no alignment
+   issues in the original Linux driver, checked with
+   "echo 5 > /proc/cpu/alignment"))
+ */
+static inline void flexcan_memcpy(void *dst, void *src, int len)
+{
+	register unsigned char *d = dst;
+	register unsigned char *s = src;
+	d[0] = s[3];
+	d[1] = s[2];
+	d[2] = s[1];
+	d[3] = s[0];
+	d[4] = s[7];
+	d[5] = s[6];
+	d[6] = s[5];
+	d[7] = s[4];
+}
+#endif
+
+static int flexcan_mb_bottom(struct rtcan_device *dev,
+			struct rtcan_flexcan *flexcan,
+			struct rtcan_skb *skb,
+			int index,
+			int *rcv_lock_free_ptr)
+{
+	int retval = 0;
+	struct can_hw_mb *hwmb;
+	struct rtcan_rb_frame *frame;
+	unsigned int tmp;
+
+	hwmb = flexcan->hwmb + index;
+	if (flexcan->fifo || (index >= (flexcan->maxmb - flexcan->xmit_maxmb))) {
+		if ((hwmb->mb_cs & MB_CS_CODE_MASK) >> MB_CS_CODE_OFFSET ==
+							CAN_MB_TX_ABORT) {
+			hwmb->mb_cs &= ~MB_CS_CODE_MASK;
+			hwmb->mb_cs |= CAN_MB_TX_INACTIVE << MB_CS_CODE_OFFSET;
+		}
+
+		if (hwmb->mb_cs & (CAN_MB_TX_INACTIVE << MB_CS_CODE_OFFSET)) {
+			++retval;
+			goto exit_function;
+		}
+	}
+	if (skb) {
+		frame = &skb->rb_frame;
+		memset(frame, 0, sizeof(*frame));
+		skb->rb_frame_size = EMPTY_RB_FRAME_SIZE;
+
+		if (hwmb->mb_cs & MB_CS_IDE_MASK)
+			frame->can_id =
+			    (hwmb->mb_id & CAN_EFF_MASK) | CAN_EFF_FLAG;
+		else
+			frame->can_id = (hwmb->mb_id >> 18) & CAN_SFF_MASK;
+
+		frame->can_dlc =
+		(hwmb->mb_cs & MB_CS_LENGTH_MASK) >> MB_CS_LENGTH_OFFSET;
+		if (frame->can_dlc > 8)
+			frame->can_dlc = 8;
+
+		if (frame->can_dlc && frame->can_dlc)
+			flexcan_memcpy(frame->data, hwmb->mb_data,
+				       frame->can_dlc);
+
+		if (flexcan->fifo
+		    || (index >= (flexcan->maxmb - flexcan->xmit_maxmb))) {
+			hwmb->mb_cs &= ~MB_CS_CODE_MASK;
+			hwmb->mb_cs |= CAN_MB_TX_INACTIVE << MB_CS_CODE_OFFSET;
+			++retval;
+		}
+
+		if (hwmb->mb_cs & MB_CS_RTR_MASK) {
+			frame->can_id |= CAN_RTR_FLAG;
+		} else {
+			skb->rb_frame_size += frame->can_dlc;
+		}
+		
+		/* the following timer read also unlocks the buffer */
+		tmp = __raw_readl(flexcan->io_base + CAN_HW_REG_TIMER);
+
+	    /* Take more locks. Ensure that they are taken and
+	     * released only once in the IRQ handler. */
+	    if (*rcv_lock_free_ptr) {
+		*rcv_lock_free_ptr = 0;
+		rtdm_lock_get(&rtcan_recv_list_lock);
+		rtdm_lock_get(&rtcan_socket_lock);
+	    }
+
+	    /* Pass received frame out to the sockets */
+	    rtcan_rcv(dev, skb);
+	} else {
+		tmp = hwmb->mb_cs;
+		tmp = hwmb->mb_id;
+		tmp = hwmb->mb_data[0];
+		if (flexcan->fifo
+		    || (index >= (flexcan->maxmb - flexcan->xmit_maxmb))) {
+			hwmb->mb_cs &= ~MB_CS_CODE_MASK;
+			hwmb->mb_cs |= CAN_MB_TX_INACTIVE << MB_CS_CODE_OFFSET;
+			++retval;
+		}
+		/* the following timer read also unlocks the buffer */
+		tmp = __raw_readl(flexcan->io_base + CAN_HW_REG_TIMER);
+	}
+exit_function:
+	return retval;
+}
+
+static void flexcan_fifo_isr(struct rtcan_device *dev, struct rtcan_flexcan *flexcan,
+			struct rtcan_skb *skb, unsigned int iflag1)
+{
+	struct can_hw_mb *hwmb = flexcan->hwmb;
+	struct rtcan_rb_frame *frame;
+	unsigned int tmp;
+
+	if (iflag1 & __FIFO_RDY_INT) {
+		if (skb) {
+			frame = &skb->rb_frame;
+			memset(frame, 0, sizeof(*frame));
+			if (hwmb->mb_cs & MB_CS_IDE_MASK)
+				frame->can_id =
+				    (hwmb->mb_id & CAN_EFF_MASK) | CAN_EFF_FLAG;
+			else
+				frame->can_id =
+				    (hwmb->mb_id >> 18) & CAN_SFF_MASK;
+
+			if (hwmb->mb_cs & MB_CS_RTR_MASK)
+				frame->can_id |= CAN_RTR_FLAG;
+
+			frame->can_dlc =
+				(hwmb->mb_cs & MB_CS_LENGTH_MASK) >>
+						MB_CS_LENGTH_OFFSET;
+
+			if (frame->can_dlc && (frame->can_dlc <= 8))
+				flexcan_memcpy(frame->data, hwmb->mb_data,
+					       frame->can_dlc);
+			tmp = __raw_readl(flexcan->io_base + CAN_HW_REG_TIMER);
+		} else {
+			tmp = hwmb->mb_cs;
+			tmp = hwmb->mb_id;
+			tmp = hwmb->mb_data[0];
+			tmp = __raw_readl(flexcan->io_base + CAN_HW_REG_TIMER);
+		}
+	}
+
+	if (iflag1 & (__FIFO_OV_INT | __FIFO_WARN_INT)) {
+		if (skb) {
+			frame = &skb->rb_frame;
+			memset(frame, 0, sizeof(*frame));
+			frame->can_id = CAN_ERR_FLAG | CAN_ERR_CRTL;
+			frame->can_dlc = CAN_ERR_DLC;
+			if (iflag1 & __FIFO_WARN_INT)
+				frame->data[1] |=
+				    CAN_ERR_CRTL_TX_WARNING |
+				    CAN_ERR_CRTL_RX_WARNING;
+			if (iflag1 & __FIFO_OV_INT)
+				frame->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
+		}
+	}
+}
+
+int rtcan_flexcan_mbm_isr(struct rtcan_device *dev,
+			struct rtcan_flexcan *flexcan,
+			struct rtcan_skb *skb,
+			int *rcv_lock_free_ptr)
+{
+	int i, iflag1, iflag2, maxmb, retval;
+
+	retval = 0;
+	if (flexcan->maxmb > 31) {
+		maxmb = flexcan->maxmb + 1 - 32;
+		iflag1 = __raw_readl(flexcan->io_base + CAN_HW_REG_IFLAG1) &
+		    __raw_readl(flexcan->io_base + CAN_HW_REG_IMASK1);
+		iflag2 = __raw_readl(flexcan->io_base + CAN_HW_REG_IFLAG2) &
+		    __raw_readl(flexcan->io_base + CAN_HW_REG_IMASK2);
+		iflag2 &= (1 << maxmb) - 1;
+		maxmb = 32;
+	} else {
+		maxmb = flexcan->maxmb + 1;
+		iflag1 = __raw_readl(flexcan->io_base + CAN_HW_REG_IFLAG1) &
+		    __raw_readl(flexcan->io_base + CAN_HW_REG_IMASK1);
+		iflag1 &= (1 << maxmb) - 1;
+		iflag2 = 0;
+	}
+
+	__raw_writel(iflag1, flexcan->io_base + CAN_HW_REG_IFLAG1);
+	__raw_writel(iflag2, flexcan->io_base + CAN_HW_REG_IFLAG2);
+
+	if (flexcan->fifo) { /*TODO: test this*/
+		flexcan_fifo_isr(dev, flexcan, skb, iflag1);
+		iflag1 &= 0xFFFFFF00;
+	}
+	for (i = 0; iflag1 && (i < maxmb); i++) {
+		if (iflag1 & (1 << i)) {
+			iflag1 &= ~(1 << i);
+			retval += flexcan_mb_bottom(dev, flexcan, skb, i, rcv_lock_free_ptr);
+		}
+	}
+
+	for (i = maxmb; iflag2 && (i <= flexcan->maxmb); i++) {
+		if (iflag2 & (1 << (i - 32))) {
+			iflag2 &= ~(1 << (i - 32));
+			retval += flexcan_mb_bottom(dev, flexcan, skb, i, rcv_lock_free_ptr);
+		}
+	}
+	return retval;
+}
+
+int rtcan_flexcan_mbm_xmit(struct rtcan_flexcan *flexcan, struct can_frame *cframe) /* NB no rtcan_rb_frame */
+{
+	int i = flexcan->xmit_mb;
+	struct can_hw_mb *hwmb = flexcan->hwmb;
+
+	do {
+		if ((hwmb[i].mb_cs & MB_CS_CODE_MASK) >> MB_CS_CODE_OFFSET ==
+							    CAN_MB_TX_INACTIVE)
+			break;
+		if ((++i) > flexcan->maxmb) {
+			if (flexcan->fifo)
+				i = FLEXCAN_MAX_FIFO_MB;
+			else
+				i = flexcan->xmit_maxmb + 1;
+		}
+		if (i == flexcan->xmit_mb)
+			return -1;
+	} while (1);
+
+	flexcan->xmit_mb = i + 1;
+	if (flexcan->xmit_mb > flexcan->maxmb) {
+		if (flexcan->fifo)
+			flexcan->xmit_mb = FLEXCAN_MAX_FIFO_MB;
+		else
+			flexcan->xmit_mb = flexcan->xmit_maxmb + 1;
+	}
+
+	if (cframe->can_id & CAN_RTR_FLAG)
+		hwmb[i].mb_cs |= 1 << MB_CS_RTR_OFFSET;
+	else
+		hwmb[i].mb_cs &= ~MB_CS_RTR_MASK;
+
+	if (cframe->can_id & CAN_EFF_FLAG) {
+		hwmb[i].mb_cs |= 1 << MB_CS_IDE_OFFSET;
+		hwmb[i].mb_cs |= 1 << MB_CS_SRR_OFFSET;
+		hwmb[i].mb_id = cframe->can_id & CAN_EFF_MASK;
+	} else {
+		hwmb[i].mb_cs &= ~MB_CS_IDE_MASK;
+		hwmb[i].mb_id = (cframe->can_id & CAN_SFF_MASK) << 18;
+	}
+
+	hwmb[i].mb_cs &= ~MB_CS_LENGTH_MASK;
+	hwmb[i].mb_cs |= cframe->can_dlc << MB_CS_LENGTH_OFFSET;
+	flexcan_memcpy(hwmb[i].mb_data, cframe->data, cframe->can_dlc);
+	hwmb[i].mb_cs &= ~MB_CS_CODE_MASK;
+	hwmb[i].mb_cs |= CAN_MB_TX_ONCE << MB_CS_CODE_OFFSET;
+	return 0;
+}
+
+void rtcan_flexcan_mbm_init(struct rtcan_flexcan *flexcan)
+{
+	struct can_hw_mb *hwmb;
+	int rx_mb, i;
+
+	/* Set global mask to receive all messages */
+	__raw_writel(0, flexcan->io_base + CAN_HW_REG_RXGMASK);
+	__raw_writel(0, flexcan->io_base + CAN_HW_REG_RX14MASK);
+	__raw_writel(0, flexcan->io_base + CAN_HW_REG_RX15MASK);
+
+	memset(flexcan->hwmb, 0, sizeof(*hwmb) * FLEXCAN_MAX_MB);
+	/* Set individual mask to receive all messages */
+	memset(flexcan->rx_mask, 0, sizeof(unsigned int) * FLEXCAN_MAX_MB);
+
+	if (flexcan->fifo)
+		rx_mb = FLEXCAN_MAX_FIFO_MB;
+	else
+		rx_mb = flexcan->maxmb - flexcan->xmit_maxmb;
+
+	hwmb = flexcan->hwmb;
+	if (flexcan->fifo) {
+		volatile unsigned long *id_table = flexcan->io_base + CAN_FIFO_BASE;
+		for (i = 0; i < rx_mb; i++)
+			id_table[i] = 0;
+	} else {
+		for (i = 0; i < rx_mb; i++) {
+			hwmb[i].mb_cs &= ~MB_CS_CODE_MASK;
+			hwmb[i].mb_cs |= CAN_MB_RX_EMPTY << MB_CS_CODE_OFFSET;
+			/*
+			 * IDE bit can not control by mask registers
+			 * So set message buffer to receive extend
+			 * or standard message.
+			 */
+			if (flexcan->ext_msg && flexcan->std_msg) {
+				hwmb[i].mb_cs &= ~MB_CS_IDE_MASK;
+				hwmb[i].mb_cs |= (i & 1) << MB_CS_IDE_OFFSET;
+			} else {
+				if (flexcan->ext_msg)
+					hwmb[i].mb_cs |= 1 << MB_CS_IDE_OFFSET;
+			}
+		}
+	}
+
+	for (; i <= flexcan->maxmb; i++) {
+		hwmb[i].mb_cs &= ~MB_CS_CODE_MASK;
+		hwmb[i].mb_cs |= CAN_MB_TX_INACTIVE << MB_CS_CODE_OFFSET;
+	}
+
+	flexcan->xmit_mb = rx_mb;
+}
diff -Naur xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan_proc.c xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan_proc.c
--- xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan_proc.c	1970-01-01 01:00:00.000000000 +0100
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan_proc.c	2012-08-01 16:02:14.000000000 +0200
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2012 Francesco Mandracci. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * based on xenomai-2.6.0/ksrc/drivers/can/sja1000/rtcan_sja1000_proc.c
+ * Copyright (C) 2006 Wolfgang Grandegger <wg@grandegger.com>
+ */
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include <rtdm/rtdm_driver.h>
+
+#include <rtcan_dev.h>
+#include <rtcan_internal.h>
+#include <rtcan_flexcan.h>
+
+#ifdef CONFIG_XENO_DRIVERS_CAN_DEBUG
+
+struct {
+	int offset;
+	char name[18];
+} flexcan_regs[] = {
+                //123456789012345678
+	{ 0x000, "HW_CAN_MCR       " },
+	{ 0x004, "HW_CAN_CRTL      " },
+	{ 0x008, "HW_CAN_TIMER     " },
+	{ 0x010, "HW_CAN_RXGMASK   " },
+	{ 0x014, "HW_CAN_RX14MASK  " },
+	{ 0x018, "HW_CAN_RX15MASK  " },
+	{ 0x01c, "HW_CAN_ECR       " },
+	{ 0x020, "HW_CAN_ESR       " },
+	{ 0x024, "HW_CAN_IMASK2    " },
+	{ 0x028, "HW_CAN_IMASK1    " },
+	{ 0x02c, "HW_CAN_IFLAG2    " },
+	{ 0x030, "HW_CAN_IFLAG1    " },
+	{ 0x034, "HW_CAN_GFWR      " },
+	{ 0x080, "HW_CAN_MBn[00]   " },
+	{ 0x084, "HW_CAN_MBn[01]   " },
+	{ 0x17c, "HW_CAN_MBn[63]   " },
+	{ 0x880, "HW_CAN_RXIMRn[00]" },
+	{ 0x884, "HW_CAN_RXIMRn[01]" },
+	{ 0x97c, "HW_CAN_RXIMRn[63]" },
+};
+
+static int rtcan_flexcan_proc_regs(char *buf, char **start, off_t offset,
+				 int count, int *eof, void *data)
+{
+    struct rtcan_device *dev = (struct rtcan_device *)data;
+    struct rtcan_flexcan *chip = (struct rtcan_flexcan *)dev->priv;
+    int i;
+    RTCAN_PROC_PRINT_VARS(80);
+
+    if (!RTCAN_PROC_PRINT("FlexCAN registers\n")) {
+	goto done;
+    }
+    for (i = 0; i < sizeof(flexcan_regs)/sizeof(flexcan_regs[0]); ++i) {
+        if (!RTCAN_PROC_PRINT("%s: 0x%08x\n", flexcan_regs[i].name,
+		__raw_readl(chip->io_base + flexcan_regs[i].offset))) {
+		goto done;
+	}
+    }
+ done:
+    RTCAN_PROC_PRINT_DONE;
+}
+
+int rtcan_flexcan_create_proc(struct rtcan_device* dev)
+{
+    struct proc_dir_entry *proc_entry;
+
+    if (!dev->proc_root)
+	return -EINVAL;
+
+    proc_entry = create_proc_entry("registers", S_IFREG | S_IRUGO | S_IWUSR,
+				   dev->proc_root);
+    if (!proc_entry)
+	goto error;
+    proc_entry->read_proc = rtcan_flexcan_proc_regs;
+    proc_entry->data = dev;
+
+    return 0;
+
+  error:
+    printk("%s: unable to create /proc entries for FlexCAN\n", dev->name);
+    return -1;
+}
+
+void rtcan_flexcan_remove_proc(struct rtcan_device* dev)
+{
+    if (!dev->proc_root)
+	return;
+
+    remove_proc_entry("registers", dev->proc_root);
+}
+
+#else /* !CONFIG_XENO_DRIVERS_CAN_DEBUG */
+
+void rtcan_flexcan_remove_proc(struct rtcan_device* dev)
+{
+}
+
+int rtcan_flexcan_create_proc(struct rtcan_device* dev)
+{
+    return 0;
+}
+#endif	/* CONFIG_XENO_DRIVERS_CAN_DEBUG */
+
diff -Naur xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan_regs.h xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan_regs.h
--- xenomai-2.6.0/ksrc/drivers/can/flexcan/rtcan_flexcan_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/flexcan/rtcan_flexcan_regs.h	2012-07-26 11:48:38.000000000 +0200
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2012 Francesco Mandracci. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * based on linux-2.6.35/drivers/net/can/flexcan/flexcan.h
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * based on xenomai-2.6.0/ksrc/drivers/net/can/rtcan_mscan_regs.h
+ * Copyright (C) 2006 Wolfgang Grandegger <wg@grandegger.com>
+ */
+
+#ifndef __RTCAN_FLEXCAN_REGS_H_
+#define __RTCAN_FLEXCAN_REGS_H_
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
+#error "minimum kernel version 2.6.35"
+#endif
+
+#define CAN_MB_RX_INACTIVE	0x0
+#define CAN_MB_RX_EMPTY		0x4
+#define CAN_MB_RX_FULL		0x2
+#define CAN_MB_RX_OVERRUN	0x6
+#define CAN_MB_RX_BUSY		0x1
+
+#define CAN_MB_TX_INACTIVE	0x8
+#define CAN_MB_TX_ABORT		0x9
+#define CAN_MB_TX_ONCE		0xC
+#define CAN_MB_TX_REMOTE	0xA
+
+struct can_hw_mb {
+	unsigned int mb_cs;
+	unsigned int mb_id;
+	unsigned char mb_data[8];
+};
+
+#define MB_CS_CODE_OFFSET	24
+#define MB_CS_CODE_MASK		(0xF << MB_CS_CODE_OFFSET)
+#define MB_CS_SRR_OFFSET	22
+#define MB_CS_SRR_MASK		(0x1 << MB_CS_SRR_OFFSET)
+#define MB_CS_IDE_OFFSET	21
+#define MB_CS_IDE_MASK		(0x1 << MB_CS_IDE_OFFSET)
+#define MB_CS_RTR_OFFSET	20
+#define MB_CS_RTR_MASK		(0x1 << MB_CS_RTR_OFFSET)
+#define MB_CS_LENGTH_OFFSET	16
+#define MB_CS_LENGTH_MASK	(0xF << MB_CS_LENGTH_OFFSET)
+#define MB_CS_TIMESTAMP_OFFSET	0
+#define MB_CS_TIMESTAMP_MASK	(0xFF << MB_CS_TIMESTAMP_OFFSET)
+
+#define CAN_HW_REG_MCR		0x00
+#define CAN_HW_REG_CTRL		0x04
+#define CAN_HW_REG_TIMER	0x08
+#define CAN_HW_REG_RXGMASK	0x10
+#define CAN_HW_REG_RX14MASK	0x14
+#define CAN_HW_REG_RX15MASK	0x18
+#define CAN_HW_REG_ECR		0x1C
+#define CAN_HW_REG_ESR		0x20
+#define CAN_HW_REG_IMASK2	0x24
+#define CAN_HW_REG_IMASK1	0x28
+#define CAN_HW_REG_IFLAG2	0x2C
+#define CAN_HW_REG_IFLAG1	0x30
+
+#define CAN_MB_BASE	0x0080
+#define CAN_RXMASK_BASE	0x0880
+#define CAN_FIFO_BASE	0xE0
+
+#define __MCR_MDIS		(1 << 31)
+#define __MCR_FRZ		(1 << 30)
+#define __MCR_FEN		(1 << 29)
+#define __MCR_HALT		(1 << 28)
+#define __MCR_NOTRDY		(1 << 27)
+#define __MCR_WAK_MSK		(1 << 26)
+#define __MCR_SOFT_RST		(1 << 25)
+#define __MCR_FRZ_ACK		(1 << 24)
+#define __MCR_SLF_WAK		(1 << 22)
+#define __MCR_WRN_EN		(1 << 21)
+#define __MCR_LPM_ACK		(1 << 20)
+#define __MCR_WAK_SRC		(1 << 19)
+#define __MCR_DOZE		(1 << 18)
+#define __MCR_SRX_DIS		(1 << 17)
+#define __MCR_BCC		(1 << 16)
+#define __MCR_LPRIO_EN		(1 << 13)
+#define __MCR_AEN		(1 << 12)
+#define __MCR_MAX_IDAM_OFFSET 	8
+#define __MCR_MAX_IDAM_MASK 	(0x3 << __MCR_MAX_IDAM_OFFSET)
+#define __MCR_MAX_IDAM_A	(0x0 << __MCR_MAX_IDAM_OFFSET)
+#define __MCR_MAX_IDAM_B	(0x1 << __MCR_MAX_IDAM_OFFSET)
+#define __MCR_MAX_IDAM_C	(0x2 << __MCR_MAX_IDAM_OFFSET)
+#define __MCR_MAX_IDAM_D	(0x3 << __MCR_MAX_IDAM_OFFSET)
+#define __MCR_MAX_MB_OFFSET 	0
+#define __MCR_MAX_MB_MASK 	(0x3F)
+
+#define __CTRL_PRESDIV_OFFSET	24
+#define __CTRL_PRESDIV_MASK	(0xFF << __CTRL_PRESDIV_OFFSET)
+#define __CTRL_RJW_OFFSET	22
+#define __CTRL_RJW_MASK		(0x3 << __CTRL_RJW_OFFSET)
+#define __CTRL_PSEG1_OFFSET	19
+#define __CTRL_PSEG1_MASK	(0x7 << __CTRL_PSEG1_OFFSET)
+#define __CTRL_PSEG2_OFFSET	16
+#define __CTRL_PSEG2_MASK	(0x7 << __CTRL_PSEG2_OFFSET)
+#define __CTRL_BOFF_MSK		(0x1 << 15)
+#define __CTRL_ERR_MSK		(0x1 << 14)
+#define __CTRL_CLK_SRC		(0x1 << 13)
+#define __CTRL_LPB		(0x1 << 12)
+#define __CTRL_TWRN_MSK		(0x1 << 11)
+#define __CTRL_RWRN_MSK		(0x1 << 10)
+#define __CTRL_SMP		(0x1 << 7)
+#define __CTRL_BOFF_REC		(0x1 << 6)
+#define __CTRL_TSYN		(0x1 << 5)
+#define __CTRL_LBUF		(0x1 << 4)
+#define __CTRL_LOM		(0x1 << 3)
+#define __CTRL_PROPSEG_OFFSET	0
+#define __CTRL_PROPSEG_MASK	(0x7)
+
+#define __ECR_TX_ERR_COUNTER(x) ((x) & 0xFF)
+#define __ECR_RX_ERR_COUNTER(x) (((x) >> 8) & 0xFF)
+#define __ECR_PASSIVE_THRESHOLD	128
+#define __ECR_ACTIVE_THRESHOLD	96
+
+#define __ESR_TWRN_INT		(0x1 << 17)
+#define __ESR_RWRN_INT		(0x1 << 16)
+#define __ESR_BIT1_ERR		(0x1 << 15)
+#define __ESR_BIT0_ERR		(0x1 << 14)
+#define __ESR_ACK_ERR		(0x1 << 13)
+#define __ESR_CRC_ERR		(0x1 << 12)
+#define __ESR_FRM_ERR		(0x1 << 11)
+#define __ESR_STF_ERR		(0x1 << 10)
+#define __ESR_TX_WRN		(0x1 << 9)
+#define __ESR_RX_WRN		(0x1 << 8)
+#define __ESR_IDLE		(0x1 << 7)
+#define __ESR_TXRX		(0x1 << 6)
+#define __ESR_FLT_CONF_OFF	4
+#define __ESR_FLT_CONF_MASK	(0x3 << __ESR_FLT_CONF_OFF)
+#define __ESR_BOFF_INT		(0x1 << 2)
+#define __ESR_ERR_INT		(0x1 << 1)
+#define __ESR_WAK_INT		(0x1)
+
+#define __ESR_INTERRUPTS	(__ESR_WAK_INT | __ESR_ERR_INT | \
+				__ESR_BOFF_INT | __ESR_TWRN_INT | \
+				__ESR_RWRN_INT)
+
+#define __FIFO_OV_INT		0x0080
+#define __FIFO_WARN_INT		0x0040
+#define __FIFO_RDY_INT		0x0020
+
+struct flexcan_device {
+	struct mutex mutex;
+	void *io_base;
+	struct can_hw_mb *hwmb;
+	unsigned int *rx_mask;
+	unsigned int xmit_mb;
+	unsigned int bitrate;
+	/* word 1 */
+	unsigned int br_presdiv:8;
+	unsigned int br_rjw:2;
+	unsigned int br_propseg:3;
+	unsigned int br_pseg1:3;
+	unsigned int br_pseg2:3;
+	unsigned int maxmb:6;
+	unsigned int xmit_maxmb:6;
+	unsigned int wd1_resv:1;
+
+	/* word 2 */
+	unsigned int fifo:1;
+	unsigned int wakeup:1;
+	unsigned int srx_dis:1;
+	unsigned int wak_src:1;
+	unsigned int bcc:1;
+	unsigned int lprio:1;
+	unsigned int abort:1;
+	unsigned int br_clksrc:1;
+	unsigned int loopback:1;
+	unsigned int smp:1;
+	unsigned int boff_rec:1;
+	unsigned int tsyn:1;
+	unsigned int listen:1;
+
+	unsigned int ext_msg:1;
+	unsigned int std_msg:1;
+
+	struct timer_list timer;
+	struct platform_device *dev;
+	struct regulator *core_reg;
+	struct regulator *io_reg;
+	struct clk *clk;
+	int irq;
+};
+
+#define FLEXCAN_MAX_FIFO_MB	8
+#define FLEXCAN_MAX_MB		64
+#define FLEXCAN_MAX_PRESDIV	256
+#define FLEXCAN_MAX_RJW		4
+#define FLEXCAN_MAX_PSEG1	8
+#define FLEXCAN_MAX_PSEG2	8
+#define FLEXCAN_MAX_PROPSEG	8
+#define FLEXCAN_MAX_BITRATE	1000000
+
+#endif
diff -Naur xenomai-2.6.0/ksrc/drivers/can/Kconfig xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/Kconfig
--- xenomai-2.6.0/ksrc/drivers/can/Kconfig	2011-10-18 20:17:18.000000000 +0200
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/Kconfig	2012-07-26 11:16:54.000000000 +0200
@@ -72,5 +72,6 @@
 
 source drivers/xenomai/can/mscan/Kconfig
 source drivers/xenomai/can/sja1000/Kconfig
+source drivers/xenomai/can/flexcan/Kconfig
 
 endmenu
diff -Naur xenomai-2.6.0/ksrc/drivers/can/Makefile xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/Makefile
--- xenomai-2.6.0/ksrc/drivers/can/Makefile	2011-10-18 20:17:18.000000000 +0200
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/Makefile	2012-07-30 10:45:11.000000000 +0200
@@ -4,7 +4,7 @@
 
 EXTRA_CFLAGS += -D__IN_XENOMAI__ -Iinclude/xenomai -Idrivers/xenomai/can
 
-obj-$(CONFIG_XENO_DRIVERS_CAN) += xeno_can.o mscan/ sja1000/
+obj-$(CONFIG_XENO_DRIVERS_CAN) += xeno_can.o mscan/ sja1000/ flexcan/
 obj-$(CONFIG_XENO_DRIVERS_CAN_VIRT) += xeno_can_virt.o
 
 xeno_can-y := rtcan_dev.o rtcan_socket.o rtcan_module.o rtcan_raw.o rtcan_raw_dev.o rtcan_raw_filter.o
diff -Naur xenomai-2.6.0/ksrc/drivers/can/rtcan_raw_dev.c xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/rtcan_raw_dev.c
--- xenomai-2.6.0/ksrc/drivers/can/rtcan_raw_dev.c	2011-10-18 20:17:18.000000000 +0200
+++ xenomai-2.6.0+flexcan_2012-09-26/ksrc/drivers/can/rtcan_raw_dev.c	2012-09-26 09:05:11.000000000 +0200
@@ -31,6 +31,79 @@
 #define RTCAN_MAX_TSEG1  15
 #define RTCAN_MAX_TSEG2  7
 
+#ifdef CONFIG_XENO_DRIVERS_CAN_FLEXCAN
+/* from linux-2.6.35.3_ipipe/drivers/net/can/flexcan/dev.c */
+
+#define DEFAULT_BITRATE	    500000
+#define TIME_SEGMENT_MIN    8
+#define TIME_SEGMENT_MAX    25
+#define TIME_SEGMENT_MID    ((TIME_SEGMENT_MIN + TIME_SEGMENT_MAX)/2)
+
+struct time_segment {
+	char propseg;
+	char pseg1;
+	char pseg2;
+};
+
+struct time_segment time_segments[] = {
+    { /* total 8 timequanta */
+	1, 2, 1
+    },
+    { /* total 9 timequanta */
+	1, 2, 2
+    },
+    { /* total 10 timequanta */
+	2, 2, 2
+    },
+    { /* total 11 timequanta */
+	2, 2, 3
+    },
+    { /* total 12 timequanta */
+	2, 3, 3
+    },
+    { /* total 13 timequanta */
+	3, 3, 3
+    },
+    { /* total 14 timequanta */
+	3, 3, 4
+    },
+    { /* total 15 timequanta */
+	3, 4, 4
+    },
+    { /* total 16 timequanta */
+	4, 4, 4
+    },
+    { /* total 17 timequanta */
+	4, 4, 5
+    },
+    { /* total 18 timequanta */
+	4, 5, 5
+    },
+    { /* total 19 timequanta */
+	5, 5, 5
+    },
+    { /* total 20 timequanta */
+	5, 5, 6
+    },
+    { /* total 21 timequanta */
+	5, 6, 6
+    },
+    { /* total 22 timequanta */
+	6, 6, 6
+    },
+    { /* total 23 timequanta */
+	6, 6, 7
+    },
+    { /* total 24 timequanta */
+	6, 7, 7
+    },
+    { /* total 25 timequanta */
+	7, 7, 7
+    },
+};
+
+#endif
+
 /*
  * Calculate standard bit-time values for odd bitrates.
  * Most parts of this code is from Arnaud Westenberg <arnaud@wanadoo.nl>
@@ -39,11 +112,59 @@
 			       can_baudrate_t rate,
 			       struct can_bittime_std *bit_time)
 {
+    int clock = dev->can_sys_clock;
+
+#ifdef CONFIG_XENO_DRIVERS_CAN_FLEXCAN
+{
+	int i, div;
+	bool found = false;
+	struct time_segment *segment;
+
+	if (!rate)
+		rate = DEFAULT_BITRATE;
+
+	if (clock % rate == 0) {
+		div = clock / rate;
+		for (i = TIME_SEGMENT_MID; i <= TIME_SEGMENT_MAX; i++) {
+			if (div % i == 0) {
+				found = true;
+				break;
+			}
+		}
+		if (!found) {
+			for (i = TIME_SEGMENT_MID - 1;
+					    i >= TIME_SEGMENT_MIN; i--) {
+				if (div % i == 0) {
+					found = true;
+					break;
+				}
+			}
+		}
+	}
+
+	if (found) {
+	    segment = &time_segments[i - TIME_SEGMENT_MIN];
+	    bit_time->brp = div/i - 1;
+	    bit_time->prop_seg = segment->propseg;
+	    bit_time->phase_seg1 = segment->pseg1;
+	    bit_time->phase_seg2 = segment->pseg2;
+	    bit_time->sjw = 2;
+	    bit_time->sam = 0;
+	} else {
+	    // default for iMX28 and 500kbit/s rate
+	    bit_time->brp = 2;		// PRESDIV
+	    bit_time->prop_seg = 4;	// PROPSEG
+	    bit_time->phase_seg1 = 4;	// PSEG1
+	    bit_time->phase_seg2 = 4;	// PSEG2
+	    bit_time->sjw = 2;		// RJW
+	    bit_time->sam = 0;		// dontcare
+	}
+}
+#else
     int best_error = 1000000000;
     int error;
     int best_tseg=0, best_brp=0, best_rate=0, brp=0;
     int tseg=0, tseg1=0, tseg2=0;
-    int clock = dev->can_sys_clock;
     int sjw = 0;
     int sampl_pt = 90;
 
@@ -97,7 +218,6 @@
 	tseg1 = RTCAN_MAX_TSEG1;
 	tseg2 = best_tseg-tseg1-2;
     }
-
     bit_time->brp = best_brp + 1;
     bit_time->prop_seg = 0;
     bit_time->phase_seg1 = tseg1 + 1;
@@ -105,6 +225,8 @@
     bit_time->sjw = sjw + 1;
     bit_time->sam = 0;
 
+#endif
+
     return 0;
 }
 
@@ -172,6 +294,8 @@
 	    break;
 	bit_time.type = CAN_BITTIME_STD;
 	break;
+    default:
+	;
     }
 
     rtdm_lock_get_irqsave(&dev->device_lock, lock_ctx);
@@ -188,6 +312,8 @@
 		goto out;
 	}
 	break;
+    default:
+	;
     }
 
     switch (request) {
