All of lore.kernel.org
 help / color / mirror / Atom feed
* [MeeGo-Dev][PATCH] Topcliff: Update PCH_CAN driver to 2.6.35
@ 2010-08-11  0:25 Masayuki Ohtak
       [not found] ` <4C61EDE5.4030505-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
  0 siblings, 1 reply; 40+ messages in thread
From: Masayuki Ohtak @ 2010-08-11  0:25 UTC (permalink / raw)
  To: meego-dev-WXzIur8shnEAvxtiuMwx3w, Wolfgang Grandegger,
	socketcan-core-0fE9KPoRgkgATYTw5x5z8w,
	netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: andrew.chih.howe.khor-ral2JQCrhuEAvxtiuMwx3w


[-- Attachment #1.1: Type: text/plain, Size: 124239 bytes --]

CAN driver of Topcliff PCH

Topcliff PCH is the platform controller hub that is going to be used in
Intel's upcoming general embedded platform. All IO peripherals in
Topcliff PCH are actually devices sitting on AMBA bus. 
Topcliff PCH has CAN I/F. This driver enables CAN function.

Signed-off-by: Masayuki Ohtake <masa-korg-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>

---
 drivers/net/can/Kconfig   |    8 +
 drivers/net/can/Makefile  |    1 +
 drivers/net/can/pch_can.c | 4076 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/can/pch_can.h |  435 +++++
 4 files changed, 4520 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/can/pch_can.c
 create mode 100644 drivers/net/can/pch_can.h

diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 2c5227c..5c98a20 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -73,6 +73,14 @@ config CAN_JANZ_ICAN3
 	  This driver can also be built as a module. If so, the module will be
 	  called janz-ican3.ko.
 
+config PCH_CAN
+	tristate "PCH CAN"
+	depends on  CAN_DEV
+	---help---
+	  This driver is for PCH CAN of Topcliff which is an IOH for x86
+	  embedded processor.
+	  This driver can access CAN bus.
+
 source "drivers/net/can/mscan/Kconfig"
 
 source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 9047cd0..3ddc6a7 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -16,5 +16,6 @@ obj-$(CONFIG_CAN_TI_HECC)	+= ti_hecc.o
 obj-$(CONFIG_CAN_MCP251X)	+= mcp251x.o
 obj-$(CONFIG_CAN_BFIN)		+= bfin_can.o
 obj-$(CONFIG_CAN_JANZ_ICAN3)	+= janz-ican3.o
+obj-$(CONFIG_PCH_CAN)		+= pch_can.o
 
 ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
new file mode 100644
index 0000000..3f4fb5e
--- /dev/null
+++ b/drivers/net/can/pch_can.c
@@ -0,0 +1,4076 @@
+/*
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+#include "pch_can.h"
+
+static unsigned int pch_can_clock = 50000;
+static unsigned int pch_can_rx_buf_size = 16;	/* The number of message objects
+						that has to be configured as
+						receive objects.
+						*/
+
+static unsigned int pch_can_tx_buf_size = 16;	/* The number of message objects
+						that has to be configured as
+						transmit objects.
+						*/
+
+static struct pch_can_os can_os[MAX_CAN_DEVICES];
+
+static enum pch_can_auto_restart restat_mode = CAN_MANUAL; /* The variable used
+							      to store the
+							      restart mode. */
+
+static struct can_bittiming_const pch_can_bittiming_const = {
+	.name = MODULE_NAME,
+	.tseg1_min = 1,
+	.tseg1_max = 16,
+	.tseg2_min = 1,
+	.tseg2_max = 8,
+	.sjw_max = 4,
+	.brp_min = 1,
+	.brp_max = 1024, /* 6bit + extended 4bit */
+	.brp_inc = 1,
+};
+
+static const struct pci_device_id pch_can_pcidev_id[] __devinitdata = {
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PCH1_CAN)},
+	{}
+};
+
+/*
+This variable is used to store the configuration (receive /transmit) of the
+available message objects.
+This variable is used for storing the message object configuration related
+information. It includes the information about which message object is used as
+Receiver and Transmitter.
+*/
+static unsigned int pch_msg_obj_conf[MAX_MSG_OBJ] = {
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3,
+	3, 3, 3, 3
+};
+
+/* Array to store the timing settings. */
+static struct pch_can_timing can_rec_timing[] = {
+	/* <Baud rate>   <BRP>   <TS1>   <TS2>   <SJW> */
+	/* settings for 62.5MHz */
+	{0xa, 0x250, 0x7, 0x0, 0x0, 0x0, 0x0},	/* < 10 kbits/s */
+	{0x14, 0x8D, 0xB, 0x5, 0x0, 0x0, 0x0},	/* < 20 kbits/s */
+	{0x32, 0x5C, 0x7, 0x0, 0x0, 0x0, 0x0},	/* < 50 kbits/s */
+	{0x7d, 0x18, 0xC, 0x5, 0x0, 0x0, 0x0},	/* < 125 kbits/s */
+	{0xfa, 0x18, 0x7, 0x0, 0x0, 0x0, 0x0},	/* < 250 kbits/s */
+	{0x1f4, 0x8, 0x9, 0x2, 0x0, 0x0, 0x0},	/* < 500 kbits/s */
+	{0x320, 0x5, 0x8, 0x2, 0x0, 0x0, 0x0},	/* < 800 kbits/s  */
+	{0x3e8, 0x2, 0xC, 0x6, 0x0, 0x0, 0x0},	/* < 1000 kbits/s */
+
+	/* settings for 24MHz */
+	{0xa, 0xCF, 0x7, 0x0, 0x0, 0x0, 0x0},	/* < 10 kbits/s */
+	{0x14, 0x57, 0x7, 0x0, 0x0, 0x0, 0x0},	/* < 20 kbits/s */
+	{0x32, 0xF, 0x7, 0x0, 0x0, 0x0, 0x0},	/* < 50 kbits/s */
+	{0x7d, 0xF, 0x8, 0x1, 0x0, 0x0, 0x0},	/* < 125 kbits/s */
+	{0xfa, 0x7, 0x8, 0x1, 0x0, 0x0, 0x0},	/* < 250 kbits/s */
+	{0x1f4, 0x3, 0x8, 0x1, 0x0, 0x0, 0x0},	/* < 500 kbits/s */
+	{0x320, 0x2, 0x7, 0x0, 0x0, 0x0, 0x0},	/* < 800 kbits/s  */
+	{0x3e8, 0x1, 0x8, 0x1, 0x0, 0x0, 0x0},	/* < 1000 kbits/s */
+
+	/* settings for 50MHz */
+	{0xa, 0xFA, 0xC, 0x5, 0x1, 0x0, 0x0},	/* < 10 kbits/s */
+	{0x14, 0x7D, 0xC, 0x5, 0x1, 0x0, 0x0},	/* < 20 kbits/s */
+	{0x32, 0x32, 0xF, 0x2, 0x0, 0x0, 0x0},	/* < 50 kbits/s */
+	{0x7d, 0x19, 0xC, 0x1, 0x0, 0x0, 0x0},	/* < 125 kbits/s */
+	{0xfa, 0xA, 0xF, 0x2, 0x0, 0x0, 0x0},	/* < 250 kbits/s */
+	{0x1f4, 0x5, 0xF, 0x2, 0x0, 0x0, 0x0},	/* < 500 kbits/s */
+	{0x320, 0x5, 0x8, 0x2, 0x1, 0x0, 0x0},	/* < 800 kbits/s  */
+	{0x3e8, 0x2, 0xF, 0x7, 0x0, 0x0, 0x0}	/* < 1000 kbits/s */
+	/* Add the new clock settings here. */
+};
+
+static DEFINE_MUTEX(pch_can_mutex);
+
+#ifdef PCH_CAN_FIFO_MODE
+static int check_can_fifo_status(int handle)
+{
+	int ret_val;
+	struct can_fifo *f = (struct can_fifo *) handle;
+
+	if (f->head == f->tail)
+		ret_val = PCH_CAN_FIFO_EMPTY;
+	else if (f->head->next == f->tail)
+		ret_val = PCH_CAN_FIFO_FULL;
+	else
+		ret_val = PCH_CAN_FIFO_NOT_EMPTY;
+
+	return ret_val;
+}
+
+static int
+read_can_fifo(int handle, struct pch_can_msg *msg, struct net_device *ndev)
+{
+	int i;
+	int retval = 0;
+	struct can_fifo *f = (struct can_fifo *) handle;
+	struct pch_can_msg msg_tmp;
+
+	if ((handle == 0) || (msg == NULL)) {
+		dev_err(&ndev->dev, "%s -> Invalid parameter.\n", __func__);
+		retval = -EPERM;
+	} else if (f->head == f->tail) {	/* Buffer Empty */
+		dev_dbg(&ndev->dev, "%s -> FIFO empty.\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Accessing the msg object in the FIFO. */
+		msg_tmp = f->tail->msg;
+
+		/* Filling in the msg object. */
+		msg->ide = msg_tmp.ide;
+		msg->id = msg_tmp.id;
+		msg->dlc = msg_tmp.dlc;
+		msg->rtr = msg_tmp.rtr;
+
+		for (i = 0; i < PCH_CAN_MSG_DATA_LEN; i++)
+			msg->data[i] = msg_tmp.data[i];
+
+		/* Proceeding the FIFO read pointer. */
+		f->tail = f->tail->next;
+		dev_dbg(&ndev->dev, "%s successful.\n", __func__);
+	}
+
+	dev_dbg(&ndev->dev, "%s returns %d.\n", __func__, retval);
+	return retval;
+}
+
+static int
+write_can_fifo(int handle, struct pch_can_msg *msg, struct net_device *ndev)
+{
+	int i;
+	int retval = 0;
+	struct can_fifo *f = (struct can_fifo *) handle;
+	struct pch_can_msg *msg_tmp;
+
+	if ((handle == 0) || (msg == NULL)) {
+		dev_err(&ndev->dev, "%s -> Invalid parameters.\n", __func__);
+		retval = -EPERM;
+	} else if (f->head->next == f->tail) {
+		dev_dbg(&ndev->dev, "%s -> FIFO Full.\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Accessing the write node in the FIFO */
+		msg_tmp = &(f->head->msg);
+
+		/* Filling in the FIFO node. */
+		msg_tmp->ide = msg->ide;
+		msg_tmp->rtr = msg->rtr;
+		msg_tmp->id = msg->id;
+		msg_tmp->dlc = msg->dlc;
+
+		for (i = 0; i < PCH_CAN_MSG_DATA_LEN; i++)
+			msg_tmp->data[i] = msg->data[i];
+
+		/* Proceeding the write node. */
+		f->head = f->head->next;
+		dev_dbg(&ndev->dev, "%s successful.\n", __func__);
+	}
+
+	dev_dbg(&ndev->dev, "%s returns %d.\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_get_error_stats(int handle, struct pch_can_error *error)
+{
+	u32 reg_val;
+	int retval = 0;
+
+	if ((handle == 0) || (error == NULL)) {
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Reading the error count register. */
+		reg_val = ioread32(can->io_base + CAN_ERRC_OFFSET);
+
+		error->rxgte96 = 0;
+		error->txgte96 = 0;
+
+		error->rx_err_cnt =
+		    (reg_val & MSK_ES_RXERRCNT) >> BIT_ES_RXERRCNT;
+		error->tx_err_cnt =
+		    (reg_val & MSK_ES_TXERRCNT) >> BIT_ES_TXERRCNT;
+
+		/* receive error count > 96 */
+		if (error->rx_err_cnt >= ERROR_COUNT)
+			error->rxgte96 = 1;
+		/* transmit error count > 96. */
+		if (error->tx_err_cnt >= ERROR_COUNT)
+			error->txgte96 = 1;
+
+		/* Reading the Can status register. */
+		reg_val = ioread32(can->io_base + CAN_STAT_OFFSET);
+
+		/* EPass */
+		if ((reg_val & (1 << BIT_SHIFT_FIVE)) != 0)
+			error->error_stat = 1;
+		/* Buss Off */
+		else if ((reg_val & (1 << BIT_SHIFT_SEVEN)) != 0)
+			error->error_stat = 3;
+		else
+			error->error_stat = 0;
+	}
+
+	return retval;
+}
+#endif
+
+static void delete_can_fifo(int handle, struct net_device *ndev)
+{
+	unsigned int i;
+	struct can_fifo_item *curr = NULL;
+	struct can_fifo_item *next = NULL;
+	struct can_fifo *f = (struct can_fifo *) handle;
+
+	if (handle != 0) {
+		curr = f->head;
+		if (f->head != NULL) {
+			next = curr->next;
+
+			/* Freeing individual node. */
+			for (i = 0; i < f->size; i++) {
+				kfree(curr);
+				curr = next;
+				next = (struct can_fifo_item *) curr->next;
+			}
+		}
+
+		/* Free the START node. */
+		kfree(f);
+	} else {
+		dev_err(&ndev->dev, "%s -> Invalid handle.\n", __func__);
+	}
+
+	dev_dbg(&ndev->dev, "%s successful.\n", __func__);
+}
+
+static int create_can_fifo(unsigned int fifo_entries, struct net_device *ndev)
+{
+	unsigned int i;
+	struct can_fifo_item *curr;
+	struct can_fifo *f;
+	int retval;
+
+	/* Allocating the Main start node. */
+	f = kmalloc(sizeof(struct can_fifo), GFP_KERNEL);
+
+	if (f == NULL) {
+		dev_err(&ndev->dev,
+			"%s -> msg queue allocation failed.\n", __func__);
+		retval = (int) PCH_CAN_NULL;
+	} else {
+		/* Allocating the first node. */
+		f->head = kmalloc(sizeof(struct can_fifo_item), GFP_KERNEL);
+		if ((f->head == NULL)) {
+			kfree(f);
+			retval = (int) PCH_CAN_NULL;
+		} else {
+			/* Initially empty. */
+			f->tail = f->head;
+			curr = f->head;
+
+			/* Rest of the nod ecreation Node creation. */
+			for (i = 1; i <= fifo_entries; i++) {
+				curr->next =
+					kmalloc(sizeof(struct can_fifo_item),
+								GFP_KERNEL);
+				/* If allocation failed. */
+				if ((curr->next == NULL)) {
+					dev_err(&ndev->dev,
+						"%s -> Allocation failed.\n",
+						__func__);
+					i = (i - 1);
+					/* Freeing the already allocated
+					   nodes. */
+					while (i > 0) {
+						curr = f->head;
+						f->head = curr->next;
+						kfree(curr);
+
+						i--;
+					}
+
+					/* Freeing the main start node. */
+					kfree(f);
+					f = NULL;
+					retval =
+					    (int) PCH_CAN_NULL;
+					break;
+				}
+
+				curr = curr->next;
+			}
+
+			if (f != NULL) {
+				/* Making it circular. */
+				curr->next = f->head;
+				f->size = fifo_entries;
+
+				retval = (int) f;
+				dev_dbg(&ndev->dev,
+						"%s sucessful.\n", __func__);
+			}
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s returns %u.\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_create(u8 *io_base, struct net_device *ndev)
+{
+	struct can_hw *can = NULL;
+	int retval = (int) PCH_CAN_NULL;
+
+	if (io_base == NULL) {
+		dev_err(&ndev->dev, "%s -> Invalid IO Base\n", __func__);
+	}
+
+	else {
+		/* Allocates memory for the handle. */
+		can = kmalloc(sizeof(struct can_hw), GFP_KERNEL);
+		if (can == NULL) {	/* Allocation failed */
+			dev_err(&ndev->dev,
+			    "%s -> CAN Memory allocation failed\n", __func__);
+		} else {	/* Allocation successful */
+
+			can->io_base = io_base;
+			retval = (int) can;
+			dev_dbg(&ndev->dev,
+			    "%s -> Handle Creation successful.\n", __func__);
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %x\n", __func__, retval);
+	return retval;
+}
+
+static void pch_can_destroy(int handle, struct net_device *ndev)
+{
+	struct can_hw *can = (struct can_hw *) handle;
+
+	if (handle !=  0) {
+		/* Free the memory for the handle. */
+		kfree(can);
+		dev_dbg(&ndev->dev, "%s -> Free successful.\n", __func__);
+	} else {
+		dev_err(&ndev->dev, "%s-> Invalid handle.\n", __func__);
+	}
+}
+
+static int pch_can_set_run_mode(int handle, enum pch_can_run_mode mode,
+				struct net_device *ndev)
+{
+	int retval = 0;
+	struct can_hw *can;
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid Handle\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Retrieving base address for access. */
+		can = (struct can_hw *) handle;
+
+		switch (mode) {
+		case PCH_CAN_RUN:
+			PCH_CAN_BIT_CLEAR((can->io_base + CAN_CONT_OFFSET),
+					  CAN_CTRL_INIT);
+			dev_dbg(&ndev->dev,
+			    "%s -> Can set to RUN Mode.\n", __func__);
+			break;
+
+		case PCH_CAN_STOP:
+			PCH_CAN_BIT_SET((can->io_base + CAN_CONT_OFFSET),
+					CAN_CTRL_INIT);
+			dev_dbg(&ndev->dev,
+			    "%s -> Can set to STOP Mode.\n", __func__);
+			break;
+
+		default:
+			dev_err(&ndev->dev,
+				"%s -> Invalid run mode.\n", __func__);
+			retval = -EPERM;
+			break;
+		}
+	}
+
+	dev_dbg(&ndev->dev,
+			"%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_get_run_mode(int handle, enum pch_can_run_mode *mode,
+				struct net_device *ndev)
+{
+	u32 reg_val;
+	struct can_hw *can;
+	int retval = 0;
+
+	if ((handle ==  0) || (mode == NULL)) {
+		dev_err(&ndev->dev,
+			"%s -> Invalid parameter.\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		can = (struct can_hw *) handle;
+
+		reg_val = ioread32(can->io_base + CAN_CONT_OFFSET);
+
+		/* Checking the Init bit of Can Control Register.
+		   Init Bit 1 -> Stop
+		   Init Bit 0 -> Run
+		 */
+		if ((reg_val & CAN_CTRL_INIT) != 0) {
+			*mode = PCH_CAN_STOP;
+			dev_dbg(&ndev->dev,
+			    "%s -> Mode is PCH_CAN_STOP\n", __func__);
+		} else {
+			*mode = PCH_CAN_RUN;
+			dev_dbg(&ndev->dev,
+			    "%s -> Mode is PCH_CAN_RUN\n", __func__);
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_set_arbiter_mode(int handle, enum pch_can_arbiter mode,
+				    struct net_device *ndev)
+{
+	int retval = 0;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev,
+			"%s -> Invalid Handle\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* PCH CAN Controller supports only PCH_CAN_FIXED_PRIORITY
+		   arbiter mode.
+		 */
+		switch (mode) {
+		case PCH_CAN_FIXED_PRIORITY:
+			dev_dbg(&ndev->dev,
+			    "%s -> FIXED PRIORITY is set for Arbiter mode\n",
+			    __func__);
+			break;
+
+		case PCH_CAN_ROUND_ROBIN:
+		default:
+			dev_dbg(&ndev->dev,
+				"%s -> Invalid arbiter mode\n", __func__);
+			retval = -EPERM;
+			break;
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_get_arbiter_mode(int handle, enum pch_can_arbiter *mode,
+				    struct net_device *ndev)
+{
+	int retval = 0;
+
+	if ((handle == 0) || (mode == NULL)) {
+		dev_err(&ndev->dev,
+			"%s -> Invalid parameter\n", __func__);
+		retval = -EPERM;
+	}
+
+	else {
+		/* PCH CAN Controller supports only PCH_CAN_FIXED_PRIORITY
+		   arbiter mode.
+		 */
+		*mode = PCH_CAN_FIXED_PRIORITY;
+		dev_dbg(&ndev->dev,
+		    "%s -> Arbiter Mode is PCH_CAN_FIXED_PRIORITY\n", __func__);
+	}
+
+	dev_dbg(&ndev->dev, "%s returns %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_set_restart_mode(int handle,	enum pch_can_auto_restart mode,
+				    struct net_device *ndev)
+{
+	int retval = 0;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid Handle\n", __func__);
+		retval = -EPERM;
+	} else {
+		switch (mode) {
+		case CAN_MANUAL:
+			restat_mode = CAN_MANUAL;
+			dev_dbg(&ndev->dev, "%s -> Value of variable "
+			     " restat_mode = 0. CAN_MANUAL mode set.\n",
+				__func__);
+			break;
+
+		case CAN_AUTO:
+			restat_mode = CAN_AUTO;
+			dev_dbg(&ndev->dev, "%s -> Value of variable "
+			     " restat_mode = 1. CAN_AUTO mode set.\n",
+			    __func__);
+			break;
+
+		default:
+			dev_dbg(&ndev->dev,
+				"%s -> Invalid restart mode\n", __func__);
+			retval = -EPERM;
+			break;
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s returns %d\n", __func__,
+								 retval);
+	return retval;
+}
+
+static int pch_can_get_restart_mode(int handle, enum pch_can_auto_restart *mode,
+				    struct net_device *ndev)
+{
+	int retval = 0;
+
+	if ((handle == 0) || (mode == NULL)) {
+		dev_err(&ndev->dev, "%s -> Invalid parameter.\n", __func__);
+		retval = -EPERM;
+	} else {
+		if (CAN_AUTO == restat_mode) {
+			*mode = CAN_AUTO;
+			dev_dbg(&ndev->dev,
+					"%s -> Mode CAN_AUTO.\n", __func__);
+		} else {
+			*mode = CAN_MANUAL;
+			dev_dbg(&ndev->dev,
+					"%s -> Mode CAN_MANUAL.\n", __func__);
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s returns: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_set_listen_mode(int handle, enum pch_can_listen_mode mode,
+				   struct net_device *ndev)
+{
+	int retval = 0;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid Handle\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Setting for Bit3 of Can Extended function register for
+		   appropriate mode.
+		   Silent bit = 0 (Active mode)
+		   Silent bit = 1 (Silent mode)
+		 */
+		switch (mode) {
+		case PCH_CAN_LISTEN:
+			PCH_CAN_BIT_SET((can->io_base + CAN_CONT_OFFSET),
+					CAN_CTRL_OPT);
+			PCH_CAN_BIT_SET((can->io_base + CAN_OPT_OFFSET),
+					CAN_OPT_SILENT);
+			dev_dbg(&ndev->dev,
+				"%s -> PCH_CAN_LISTEN mode set.\n", __func__);
+			break;
+
+		case PCH_CAN_ACTIVE:
+			PCH_CAN_BIT_SET((can->io_base + CAN_CONT_OFFSET),
+					CAN_CTRL_OPT);
+			PCH_CAN_BIT_CLEAR((can->io_base + CAN_OPT_OFFSET),
+					  CAN_OPT_SILENT);
+			dev_dbg(&ndev->dev,
+				"%s ->PCH_CAN_ACTIVE mode set.\n", __func__);
+			break;
+
+		default:
+			dev_dbg(&ndev->dev,
+					"%s ->Invalid listen mode\n", __func__);
+			retval = -EPERM;
+			break;
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_get_listen_mode(int handle, enum pch_can_listen_mode *mode,
+				   struct net_device *ndev)
+{
+	u32 reg_val;
+	int retval = 0;
+
+	if ((handle == 0) || (mode == NULL)) {
+		dev_err(&ndev->dev, "%s -> Invalid Parameter\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Attaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		reg_val = ioread32(can->io_base + CAN_OPT_OFFSET);
+
+		/*      Checking for Bit3 of Can Extended function register
+			 for silent mode
+		   Silent bit = 0 (Active mode)
+		   Silent bit = 1 (Silent mode)
+		 */
+
+		if ((reg_val & CAN_OPT_SILENT) != 0) {
+			*mode = PCH_CAN_LISTEN;
+			dev_dbg(&ndev->dev,
+					"%s -> Mode is listen\n", __func__);
+		} else {
+			*mode = PCH_CAN_ACTIVE;
+			dev_dbg(&ndev->dev, "%s -> Mode is active\n", __func__);
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_set_int_custom(int handle, u32 interrupts)
+{
+	int retval = 0;
+
+	if (handle == 0) {
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Clearing the IE, SIE and EIE bits of Can control register. */
+		PCH_CAN_BIT_CLEAR((can->io_base + CAN_CONT_OFFSET),
+				  CAN_CTRL_IE_SIE_EIE);
+
+		/* Appropriately setting them. */
+		PCH_CAN_BIT_SET((can->io_base + CAN_CONT_OFFSET),
+				((interrupts & MSK_CTRL_IE_SIE_EIE) <<
+				 BIT_SHIFT_ONE));
+	}
+
+	return retval;
+}
+
+/* This function retrieves interrupt enabled for the CAN device. */
+static int pch_can_get_int_enables(int handle, u32 *enables)
+{
+	u32 reg_ctrl_val;
+	int retval = 0;
+
+	if ((handle == 0) || (enables == NULL)) {
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Reading the Can control register. */
+		reg_ctrl_val = ioread32(can->io_base + CAN_CONT_OFFSET);
+
+		/* Obtaining the status of IE, SIE and EIE interrupt bits. */
+		*enables =
+		    (((reg_ctrl_val & CAN_CTRL_IE_SIE_EIE) >> BIT_SHIFT_ONE));
+	}
+
+	return retval;
+}
+
+static int pch_can_set_int_enables(int handle,
+				   enum pch_can_interrupt interrupt_no,
+				   struct net_device *ndev)
+{
+	int retval = 0;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid Handle.\n", __func__);
+		retval = -EPERM;
+	} else {
+
+		/* Obatining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/*
+		   Appropriately setting the IE, SIE and EIE bits of Can control
+			 register.
+		 */
+		switch (interrupt_no) {
+		case CAN_ENABLE:
+			PCH_CAN_BIT_SET((can->io_base + CAN_CONT_OFFSET),
+					CAN_CTRL_IE);
+			dev_dbg(&ndev->dev,
+			    "%s -> CAN_ENABLE (IE) interrupt set.\n", __func__);
+			break;
+
+		case CAN_DISABLE:
+			PCH_CAN_BIT_CLEAR((can->io_base + CAN_CONT_OFFSET),
+					  CAN_CTRL_IE);
+			dev_dbg(&ndev->dev,
+			  "%s -> CAN_DIABLE (IE) interrupt reset.\n", __func__);
+			break;
+
+		case CAN_ALL:
+			PCH_CAN_BIT_SET((can->io_base + CAN_CONT_OFFSET),
+					CAN_CTRL_IE_SIE_EIE);
+			dev_dbg(&ndev->dev,
+				"%s -> CAN_ALL (IE,SIE,EIE) interrupt set.\n",
+				__func__);
+			break;
+
+		case CAN_NONE:
+			PCH_CAN_BIT_CLEAR((can->io_base + CAN_CONT_OFFSET),
+					  CAN_CTRL_IE_SIE_EIE);
+			dev_dbg(&ndev->dev,
+			    "%s -> CAN_NONE (IE,SIE,EIE) interrupt reset.\n",
+			    __func__);
+			break;
+
+		default:
+			dev_dbg(&ndev->dev,
+			    "%s -> Invalid parameter interrupt.\n", __func__);
+			retval = -EPERM;
+			break;
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_set_rx_enable(int handle, u32 buff_num, u32 set,
+				 struct net_device *ndev)
+{
+	u32 counter;
+	int retval = 0;
+	u32 if1_creq;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid Handle.\n", __func__);
+		retval = -EPERM;
+	} else if ((pch_msg_obj_conf[buff_num - 1] != MSG_OBJ_RX) ||
+		 (buff_num > (pch_can_tx_buf_size + pch_can_rx_buf_size))) {
+		/* if invalid buffer number. */
+		dev_err(&ndev->dev,
+		    "%s -> Message object %u not configured for receive.\n",
+		    __func__, buff_num);
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/*Reading the receive buffer data from RAM to Interface1
+								 registers */
+		iowrite32(CAN_CMASK_RX_TX_GET,
+			       (can->io_base + CAN_IF1_CMASK_OFFSET));
+		iowrite32(buff_num,
+			       (can->io_base + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = (ioread32(can->io_base +
+							CAN_IF1_CREQ_OFFSET)) &
+							CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if ((counter == 0)) {
+			dev_err(&ndev->dev,
+			    "%s -> Cannot read the message buffer object %u.\n",
+			    __func__, buff_num);
+			retval = -EPERM;
+		} else {		/* Reading successful */
+
+			/* Setting the IF1MASK1 register to access MsgVal and
+								 RxIE bits */
+			iowrite32((CAN_CMASK_RDWR | CAN_CMASK_ARB |
+						CAN_CMASK_CTRL),
+						(can->io_base +
+						CAN_IF1_CMASK_OFFSET));
+
+			if (set == ENABLE) {
+				/* Setting the MsgVal and RxIE bits */
+				PCH_CAN_BIT_SET((can->io_base +
+						 CAN_IF1_MCONT_OFFSET),
+						CAN_IF_MCONT_RXIE);
+				PCH_CAN_BIT_SET((can->io_base +
+						 CAN_IF1_ID2_OFFSET),
+						CAN_ID_MSGVAL);
+
+				dev_dbg(&ndev->dev,
+				   "%s -> Enabled receive message buffer %u.\n",
+				   __func__, buff_num);
+			} else if (set == DISABLE) {
+				/* Resetting the MsgVal and RxIE bits */
+				PCH_CAN_BIT_CLEAR((can->io_base +
+						   CAN_IF1_MCONT_OFFSET),
+						  CAN_IF_MCONT_RXIE);
+				PCH_CAN_BIT_CLEAR((can->io_base +
+						   CAN_IF1_ID2_OFFSET),
+						  CAN_ID_MSGVAL);
+
+				dev_dbg(&ndev->dev,
+				    "%s -> Disabled receive message buffer %u",
+				    __func__, buff_num);
+			}
+
+			/* Updating the changes to the message object. */
+			iowrite32(buff_num,
+				       (can->io_base + CAN_IF1_CREQ_OFFSET));
+
+			/* Confirming the write by checking the busy bit. */
+			counter = COUNTER_LIMIT;
+			while (counter) {
+				if1_creq = (ioread32(can->io_base +
+							CAN_IF1_CREQ_OFFSET)) &
+							CAN_IF_CREQ_BUSY;
+				if (if1_creq == 0)
+					break;
+
+				counter--;
+			}
+
+			if ((counter == 0)) {
+				dev_err(&ndev->dev,
+					"%s -> Write failed.\n", __func__);
+				retval = -EPERM;
+			}
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_rx_enable_all(int handle, struct net_device *ndev)
+{
+	u32 counter = 0;
+	int retval = 0;
+	u32 i;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid Handle.\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Traversing to obtain the object configured as receivers. */
+		for (i = 0; i < (pch_can_tx_buf_size + pch_can_rx_buf_size);
+									i++) {
+			if (pch_msg_obj_conf[i] == MSG_OBJ_RX) {
+				/* Here i is the index, however (i+1) is object
+								 number. */
+				retval =
+				    pch_can_set_rx_enable(handle, (i + 1),
+							  ENABLE, ndev);
+
+				if (retval == -EPERM) {
+					dev_dbg(&ndev->dev,
+					    "%s -> Cannot Enable receive "
+					    "object%u\n", __func__, i + 1);
+					counter++;
+				} else {
+					dev_dbg(&ndev->dev,
+					   "%s -> Enabled receive object %u\n",
+					   __func__, i + 1);
+				}
+			}
+		}
+
+		/* If enabling of all the receive object failed. */
+		if (counter == pch_can_rx_buf_size) {
+			retval = -EPERM;
+			dev_err(&ndev->dev, "%s failed.\n", __func__);
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_rx_disable_all(int handle, struct net_device *ndev)
+{
+	u32 counter = 0;
+	int retval = 0;
+	u32 i;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid Handle.\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Traversing to obtain the object configured as receivers. */
+		for (i = 0; i < (pch_can_rx_buf_size + pch_can_tx_buf_size);
+									i++) {
+			if (pch_msg_obj_conf[i] == MSG_OBJ_RX) {
+				/* Here i is the index, however (i+1) is the
+							 object number. */
+				retval =
+				    pch_can_set_rx_enable(handle, (i + 1),
+							  DISABLE, ndev);
+
+				if (retval == -EPERM) {
+					dev_dbg(&ndev->dev,
+					    "%s -> Disabling of Rx buffer %u "
+					    "failed.\n", __func__, (i + 1));
+					counter++;
+				} else {
+					dev_dbg(&ndev->dev,
+					  "%s -> Disabled receive object %u\n",
+					  __func__, i + 1);
+				}
+			}
+		}
+
+		/* If disabling of all the receive object failed. */
+		if (counter == pch_can_rx_buf_size) {
+			retval = -EPERM;
+			dev_err(&ndev->dev, "%s failed.\n", __func__);
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_set_tx_enable(int handle, u32 buff_num, u32 set,
+				 struct net_device *ndev)
+{
+	int retval = 0;
+	u32 counter;
+	u32 if1_creq;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid Handle", __func__);
+		retval = -EPERM;
+	} else if ((pch_msg_obj_conf[buff_num - 1] != MSG_OBJ_TX) ||
+		 (buff_num > (pch_can_rx_buf_size + pch_can_tx_buf_size))) {
+		/* invalid buffer number. */
+		dev_err(&ndev->dev,
+		    "%s -> Message object %u not configured for transmit.\n",
+		    __func__, buff_num);
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/*Reading the Message buffer from Message RAM to Interface2
+								 registers. */
+		iowrite32(CAN_CMASK_RX_TX_GET,
+			       (can->io_base + CAN_IF1_CMASK_OFFSET));
+		iowrite32(buff_num,
+			       (can->io_base + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = (ioread32(can->io_base +
+						CAN_IF1_CREQ_OFFSET)) &
+						CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if ((counter == 0)) {
+			dev_err(&ndev->dev,
+			   "%s -> Reading transmit buffer failed.\n", __func__);
+			retval = -EPERM;
+		} else {	/* Reading successful. */
+
+			/* Setting the IF2CMASK register for accessing the
+				MsgVal and TxIE bits */
+			iowrite32((CAN_CMASK_RDWR | CAN_CMASK_ARB |
+					CAN_CMASK_CTRL),
+				       (can->io_base +
+					CAN_IF1_CMASK_OFFSET));
+
+			if (set == ENABLE) {
+				/* Setting the MsgVal and TxIE bits */
+				PCH_CAN_BIT_SET((can->io_base +
+						 CAN_IF1_MCONT_OFFSET),
+						CAN_IF_MCONT_TXIE);
+				PCH_CAN_BIT_SET((can->io_base +
+						 CAN_IF1_ID2_OFFSET),
+						CAN_ID_MSGVAL);
+
+				dev_dbg(&ndev->dev,
+				   "%s -> Enabled transmit message buffer %u\n",
+				   __func__, buff_num);
+			} else if (set == DISABLE) {
+				/* Resetting the MsgVal and TxIE bits. */
+				PCH_CAN_BIT_CLEAR((can->io_base +
+						   CAN_IF1_MCONT_OFFSET),
+						  CAN_IF_MCONT_TXIE);
+				PCH_CAN_BIT_CLEAR((can->io_base +
+						   CAN_IF1_ID2_OFFSET),
+						  CAN_ID_MSGVAL);
+
+				dev_dbg(&ndev->dev,
+				  "%s -> Disabled transmit message buffer %u\n",
+				  __func__, buff_num);
+			}
+
+			/* Updating the changes to the message buffer. */
+			iowrite32(buff_num,
+				       (can->io_base + CAN_IF1_CREQ_OFFSET));
+
+			/* Confirming the updation. */
+			counter = COUNTER_LIMIT;
+			while (counter) {
+				if1_creq = (ioread32(can->io_base +
+						CAN_IF1_CREQ_OFFSET)) &
+						CAN_IF_CREQ_BUSY;
+				if (if1_creq == 0)
+					break;
+
+				counter--;
+			}
+
+			if ((counter == 0)) {	/* Updation failed. */
+				dev_err(&ndev->dev,
+					"%s -> Write failed.\n", __func__);
+				retval = -EPERM;
+			}
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_tx_enable_all(int handle, struct net_device *ndev)
+{
+	u32 counter = 0;
+	int retval = 0;
+	u32 i;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid Handle.\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Traversing to obtain the object configured as transmit
+								 object. */
+		for (i = 0; i < (pch_can_tx_buf_size + pch_can_rx_buf_size);
+									i++) {
+			if (pch_msg_obj_conf[i] == MSG_OBJ_TX) {
+				/* Here i denotes the index, however (i+1) is
+							 the object number. */
+				retval =
+				    pch_can_set_tx_enable(handle, (i + 1),
+							  ENABLE, ndev);
+
+				if (retval == -EPERM) {
+					counter++;
+					dev_dbg(&ndev->dev, "%s -> "
+					  "Cannot Enable transmit object %u\n",
+					  __func__, (i + 1));
+				} else {
+					dev_dbg(&ndev->dev, "%s -> "
+					  "Enabled transmit object %u\n",
+					  __func__, (i + 1));
+				}
+			}
+		}
+
+		/* If enabling of all transmit object failed. */
+		if (counter == pch_can_tx_buf_size) {
+			dev_err(&ndev->dev, "%s failed.\n", __func__);
+			retval = -EPERM;
+		}
+
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_tx_disable_all(int handle, struct net_device *ndev)
+{
+	u32 counter = 0;
+	int retval = 0;
+	u32 i;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid Handle.\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Traversing to obtain the object configured as transmit
+								 object. */
+		for (i = 0; i < (pch_can_tx_buf_size + pch_can_tx_buf_size);
+									i++) {
+			if (pch_msg_obj_conf[i] == MSG_OBJ_TX) {
+				/* Here i denotes the index, however (i+1) is
+							 the object number. */
+
+				/* Disabling. */
+				retval =
+				    pch_can_set_tx_enable(handle, (i + 1),
+							  DISABLE, ndev);
+
+				if (retval == -EPERM) {
+					dev_dbg(&ndev->dev,  "%s -> Disabling"
+						" Tx buffer %u failed.\n",
+						__func__, (i + 1));
+					counter++;
+				} else {
+					dev_dbg(&ndev->dev,
+					  "%s -> Disabled transmit object %u\n",
+					  __func__, (i + 1));
+				}
+			}
+		}
+
+		/* If disabling of all the transmit object failed. */
+		if (counter == pch_can_tx_buf_size) {
+			dev_err(&ndev->dev, "%s -> failed.\n", __func__);
+			retval = -EPERM;
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_set_rx_filter(int handle, struct pch_can_rx_filter *filter)
+{
+	u32 reg1;
+	u32 reg2;
+	u32 counter;
+	int retval = 0;
+	u32 if1_creq;
+
+	if ((handle == 0) || (filter == NULL)) {
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		iowrite32(CAN_CMASK_RX_TX_GET,
+				can->io_base + CAN_IF1_CMASK_OFFSET);
+				/* Setting the CMASK for reading */
+		iowrite32(filter->num,
+				can->io_base + CAN_IF1_CREQ_OFFSET);
+				/* Setting CREQ to specified Msg Obj. */
+
+		/* Confirming the read completion. */
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = (ioread32(can->io_base +
+						CAN_IF1_CREQ_OFFSET)) &
+						CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if ((counter == 0)) {	/* Read Unsuccessful. */
+			retval = -EPERM;
+		} else {	/* read successful. */
+
+			PCH_CAN_BIT_CLEAR((can->io_base +
+					CAN_IF1_ID2_OFFSET), MSK_ALL_THIRTEEN);
+					/* Clearing the bit 0- 12 of ID2 */
+			PCH_CAN_BIT_CLEAR((can->io_base +
+					CAN_IF1_ID2_OFFSET), CAN_ID2_XTD);
+					/* Clearing XTD bit */
+
+			if ((filter->aidr.id_ext == 1)) { /* Extended ID */
+				reg1 = filter->aidr.id & MSK_ALL_SIXTEEN;
+								/* ID1 value. */
+				/* ID2 value with XTD bit set. */
+				reg2 =
+				    (((filter->aidr.
+				       id & (MSK_ALL_THIRTEEN <<
+					     BIT_SHIFT_SIXTEEN))
+				      >> BIT_SHIFT_SIXTEEN) | CAN_ID2_XTD);
+			} else {	/* Standard ID */
+
+				reg1 = 0;
+				reg2 = ((filter->aidr.id & MSK_ALL_ELEVEN) <<
+								BIT_SHIFT_TWO);
+			}
+
+			iowrite32(reg1, (can->io_base + CAN_IF1_ID1_OFFSET));
+			PCH_CAN_BIT_SET((can->io_base +
+						CAN_IF1_ID2_OFFSET), reg2);
+
+			if (filter->umask == 1) {
+				/* If mask has to be set. */
+				PCH_CAN_BIT_CLEAR((can->io_base +
+							CAN_IF1_MASK2_OFFSET),
+							MSK_ALL_THIRTEEN);
+						/* Clearing bit 0-12 */
+				PCH_CAN_BIT_CLEAR((can->io_base +
+							CAN_IF1_MASK2_OFFSET),
+							CAN_MASK2_MDIR_MXTD);
+						/* Clearing Mdir & MXtd */
+
+				if (filter->amr.id_ext == 1) {
+							/* Extended Mask */
+					reg1 = filter->amr.id & MSK_ALL_SIXTEEN;
+							/* Mask1 value */
+					/* Mask2 value with MXtd set */
+					reg2 = (((filter->amr.
+						id & (MSK_ALL_THIRTEEN <<
+						BIT_SHIFT_SIXTEEN))
+						>> BIT_SHIFT_SIXTEEN) |
+						CAN_IF_MASK2_MXTD);
+				} else {
+					reg1 = 0;
+					reg2 = ((filter->amr.id &
+							MSK_ALL_ELEVEN) <<
+							BIT_SHIFT_TWO);
+							/* Mask2 Value */
+				}
+
+				iowrite32(reg1,
+				    (can->io_base + CAN_IF1_MASK1_OFFSET));
+							/* Writing MASK1 */
+				PCH_CAN_BIT_SET((can->io_base +
+						CAN_IF1_MASK2_OFFSET), reg2);
+							/* Writing MASK2 */
+				PCH_CAN_BIT_SET((can->io_base +
+				    CAN_IF1_MCONT_OFFSET), CAN_IF_MCONT_UMASK);
+							/* Setting Umask bit */
+			} else {
+				PCH_CAN_BIT_CLEAR((can->io_base +
+				    CAN_IF1_MCONT_OFFSET), CAN_IF_MCONT_UMASK);
+						/* Resetting Umask bit. */
+			}
+
+			/* Setting CMASK for writing */
+			iowrite32((CAN_CMASK_RDWR | CAN_CMASK_MASK |
+					CAN_CMASK_ARB | CAN_CMASK_CTRL),
+					(can->io_base +
+					CAN_IF1_CMASK_OFFSET));
+			iowrite32(filter->num, (can->io_base +
+					CAN_IF1_CREQ_OFFSET));
+					/* Setting CREQ for specified sg Obj. */
+
+			/* Confirming the write completion. */
+			counter = COUNTER_LIMIT;
+			while (counter) {
+				if1_creq = (ioread32(can->io_base +
+							CAN_IF1_CREQ_OFFSET)) &
+							CAN_IF_CREQ_BUSY;
+				if (if1_creq == 0)
+					break;
+
+				counter--;
+			}
+
+			if (counter == 0) /* Write failed */
+				retval = -EPERM;
+		}
+	}
+
+	return retval;
+}
+
+static int
+pch_can_rx_init_filter(int handle, u32 buff_num, struct net_device *ndev)
+{
+	int retval = 0;
+	struct pch_can_rx_filter filter;
+
+	if (handle == 0) {
+		retval = -EPERM;
+	} else if ((pch_msg_obj_conf[buff_num - 1] != MSG_OBJ_RX) ||
+		 (buff_num > (pch_can_tx_buf_size + pch_can_rx_buf_size))) {
+		/* if invalid buffer number. */
+		dev_err(&ndev->dev,
+			"%s -> Invalid buffer no:%d\n", __func__, buff_num);
+		retval = -EPERM;
+	} else {
+		/* Set all Rx filters to allow all msgs. */
+		filter.amr.id = (u32) 0;
+		filter.amr.id_ext = (u32) 0;
+
+		filter.aidr.id = (u32) 0;
+		filter.aidr.id_ext = (u32) 0;
+
+		filter.num = buff_num;
+		filter.umask = 1;
+
+		retval = pch_can_set_rx_filter(handle, &filter);
+	}
+
+	return retval;
+}
+
+static int pch_can_get_rx_enable(int handle, u32 buff_num, u32 *enable,
+				 struct net_device *ndev)
+{
+	int retval = 0;
+	u32 counter;
+	u32 if1_creq;
+
+	if ((handle == 0) || (enable == NULL)) {
+		dev_err(&ndev->dev,
+			"%s -> Invalid Parameter.\n", __func__);
+		retval = -EPERM;
+	}
+	/* Invalid buffer number. */
+	else if ((pch_msg_obj_conf[buff_num - 1] != MSG_OBJ_RX) ||
+		 (buff_num > (pch_can_tx_buf_size + pch_can_rx_buf_size))) {
+		dev_err(&ndev->dev,
+			"%s -> Message object %u not configured for receive.\n",
+			__func__, buff_num);
+		retval = -EPERM;
+	}
+
+	else {
+		/* Obtaining the remap address fro access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		iowrite32(CAN_CMASK_RX_TX_GET,
+				(can->io_base + CAN_IF1_CMASK_OFFSET));
+		iowrite32(buff_num,
+				(can->io_base + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = (ioread32((can->io_base +
+						CAN_IF1_CREQ_OFFSET))) &
+						CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if (counter == 0) {
+			dev_err(&ndev->dev, "%s -> Read Failed.\n", __func__);
+			retval = -EPERM;
+		} else {
+			if (((ioread32(can->io_base +
+					CAN_IF1_ID2_OFFSET)) &
+					CAN_ID_MSGVAL) &&
+					((ioread32(can->io_base +
+					CAN_IF1_MCONT_OFFSET)) &
+					CAN_IF_MCONT_RXIE)) {
+				*enable = ENABLE;
+
+				dev_dbg(&ndev->dev, "%s -> Receive message "
+					"buffer %u is enabled.\n",
+					__func__, buff_num);
+			} else {
+				*enable = DISABLE;
+				dev_dbg(&ndev->dev, "%s -> Receive Message "
+					"buffer %u is disabled.\n",
+					__func__, buff_num);
+			}
+		}
+
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_get_tx_enable(int handle, u32 buff_num, u32 *enable,
+				 struct net_device *ndev)
+{
+	int retval = 0;
+	u32 counter;
+	u32 if1_creq;
+
+	if ((handle == 0) || (enable == NULL)) {
+		dev_err(&ndev->dev,
+			"%s -> Invalid Parameter.\n", __func__);
+		retval = -EPERM;
+	}
+	/* invalid buffer number. */
+	else if ((pch_msg_obj_conf[buff_num - 1] != MSG_OBJ_TX) ||
+		 (buff_num > (pch_can_rx_buf_size + pch_can_tx_buf_size))) {
+		dev_err(&ndev->dev, "%s ->"
+			" Invalid Message "
+			"object %u.\n", __func__, buff_num);
+		retval = -EPERM;
+	} else {
+		/* Obtaining the buffer number for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		iowrite32(CAN_CMASK_RX_TX_GET,
+			       (can->io_base + CAN_IF1_CMASK_OFFSET));
+		iowrite32(buff_num,
+			       (can->io_base + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = (ioread32(can->io_base +
+						CAN_IF1_CREQ_OFFSET)) &
+						CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if (counter == 0) {
+			dev_err(&ndev->dev, "%s -> Read Failed.\n", __func__);
+			retval = -EPERM;
+		} else {
+			if (((ioread32(can->io_base +
+					CAN_IF1_ID2_OFFSET)) & CAN_ID_MSGVAL) &&
+					((ioread32(can->io_base +
+					CAN_IF1_MCONT_OFFSET)) &
+					CAN_IF_MCONT_TXIE)) {
+				*enable = ENABLE;
+
+				dev_dbg(&ndev->dev,
+					"%s -> Transmit message buffer %u is "
+					"enabled.\n", __func__, buff_num);
+			} else {
+				*enable = DISABLE;
+
+				dev_dbg(&ndev->dev,
+					"%s -> Transmit message buffer %u is "
+					"disabled.\n", __func__, buff_num);
+			}
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d.\n", __func__, retval);
+	return retval;
+}
+
+/* This function returns whether or not interrupts are pending for the CAN
+ * device.
+*/
+static int pch_can_int_pending(int handle)
+{
+	int retval = 0;
+
+	if (handle ==  0) {
+		retval = -EPERM;
+	} else {
+		/* Obatining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		retval = (ioread32(can->io_base + CAN_INT_OFFSET) &
+							MSK_ALL_SIXTEEN);
+	}
+
+	return retval;
+}
+
+static int pch_can_set_baud_simple(int handle, enum pch_can_baud baud)
+{
+	u32 reg_val;
+	int retval = 0;
+
+	if (handle == 0) {
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+		u32 offset;
+
+		/* Setting the CCE bit of Can control register for accessing the
+							 Timing Register. */
+		PCH_CAN_BIT_SET((can->io_base + CAN_CONT_OFFSET),
+				CAN_CTRL_CCE);
+
+		/* Calculating the offset of the settings array for the current
+								 clock.  */
+		switch (pch_can_clock) {
+		case 62500:
+			offset = PCH_CAN_CLOCK_62_5_OFFSET;
+			break;
+
+		case 24000:
+			offset = PCH_CAN_CLOCK_24_OFFSET;
+			break;
+
+		case 50000:
+			offset = PCH_CAN_CLOCK_50_OFFSET;
+			break;
+
+			/* The default section will not be invoked since
+			the clock frequency has been validated at the module
+			init procedure. */
+		default:
+			offset = PCH_CAN_CLOCK_DEFAULT_OFFSET;
+			break;
+		}
+
+		/* Getting the appropriate register value. */
+		reg_val = (((can_rec_timing[baud + offset].
+				cfg_bitrate & MSK_BITT_BRP) << BIT_BITT_BRP) |
+				(can_rec_timing[baud + offset].
+				cfg_tseg1 << BIT_BITT_TSEG1) |
+				(can_rec_timing[baud + offset].cfg_tseg2 <<
+				BIT_BITT_TSEG2) |
+				(can_rec_timing[baud + offset].cfg_sjw <<
+				BIT_BITT_SJW));
+
+		/* Writing to Can Timing register. */
+		iowrite32(reg_val, (can->io_base + CAN_BITT_OFFSET));
+		/* Writing to the CAN BRP register. */
+		iowrite32(((can_rec_timing[baud + offset].
+				cfg_bitrate & MSK_BRPE_BRPE) >> BIT_BRPE_BRPE),
+				(can->io_base + CAN_BRPE_OFFSET));
+
+		/* Resetting the CCE bit of the Can control register. */
+		PCH_CAN_BIT_CLEAR((can->io_base + CAN_CONT_OFFSET),
+				  CAN_CTRL_CCE);
+	}
+
+	return retval;
+}
+
+static int pch_can_set_baud_custom(int handle, struct pch_can_timing *timing)
+{
+	u32 reg_val;
+	int retval = 0;
+
+	if ((handle == 0) || (timing == NULL))
+		retval = -EPERM;
+
+	/* max is MAX_BITRATE */
+	else if (timing->bitrate > MAX_BITRATE) {
+		retval = -EPERM;
+	}
+
+	else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Setting the CCE bit of Can control register for accessing the
+							 Can Timing register. */
+		PCH_CAN_BIT_SET((can->io_base + CAN_CONT_OFFSET),
+				CAN_CTRL_CCE);
+
+		/* Obtaining the appropriate register value. */
+		reg_val =
+		    (((timing->cfg_bitrate & MSK_BITT_BRP) << BIT_BITT_BRP) |
+		    (timing->cfg_tseg1 << BIT_BITT_TSEG1) |
+		    (timing->cfg_tseg2 << BIT_BITT_TSEG2) |
+		    (timing->cfg_sjw << BIT_BITT_SJW));
+
+		/* Writing to the timing register. */
+		iowrite32(reg_val, (can->io_base + CAN_BITT_OFFSET));
+		/* Writing to the BRP register. */
+		iowrite32(((timing->cfg_bitrate & MSK_BRPE_BRPE) >>
+					BIT_BRPE_BRPE),
+					(can->io_base + CAN_BRPE_OFFSET));
+
+		/* Resetting the CCE bit. */
+		PCH_CAN_BIT_CLEAR((can->io_base + CAN_CONT_OFFSET),
+								CAN_CTRL_CCE);
+
+	}
+
+	return retval;
+}
+
+static int pch_can_get_baud(int handle, struct pch_can_timing *timing)
+{
+	u32 timing_bitt_reg;
+	u32 timing_brpe_reg;
+	int retval = 0;
+
+	if ((handle == 0) || (timing == NULL)) {
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		timing_bitt_reg = ioread32(can->io_base + CAN_BITT_OFFSET);
+		timing_brpe_reg = ioread32(can->io_base + CAN_BRPE_OFFSET);
+
+		/* Separating the individual part from the values read. */
+		timing->cfg_bitrate = ((timing_bitt_reg & MSK_BITT_BRP) |
+			((timing_brpe_reg & MSK_BRPE_GET) << BIT_BRPE_BRPE));
+		timing->cfg_tseg1 =
+			(timing_bitt_reg & MSK_BITT_TSEG1) >> BIT_BITT_TSEG1;
+		timing->cfg_tseg2 =
+			(timing_bitt_reg & MSK_BITT_TSEG2) >> BIT_BITT_TSEG2;
+		timing->cfg_sjw =
+			(timing_bitt_reg & MSK_BITT_SJW) >> BIT_BITT_SJW;
+	}
+
+	return retval;
+}
+
+static int pch_can_set_rx_buffer_link(int handle, u32 buffer_num, u32 set,
+				      struct net_device *ndev)
+{
+	u32 counter;
+	int retval = 0;
+	u32 if1_creq;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid handle.\n", __func__);
+		retval = -EPERM;
+	} else if ((pch_msg_obj_conf[buffer_num - 1] != MSG_OBJ_RX) ||
+		(buffer_num > (pch_can_rx_buf_size + pch_can_tx_buf_size))) {
+		/* invalid buffer nummber. */
+		dev_err(&ndev->dev, "%s -> Invalid buffer number %u.\n"
+							, __func__, buffer_num);
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Reading the corresponding object. */
+		iowrite32(CAN_CMASK_RX_TX_GET,
+				(can->io_base + CAN_IF1_CMASK_OFFSET));
+		iowrite32(buffer_num,
+				(can->io_base + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = ioread32((can->io_base +
+							CAN_IF1_CREQ_OFFSET)) &
+							CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		/* Confirming read. */
+		if ((counter == 0)) {
+			dev_err(&ndev->dev, "%s -> Read failed\n", __func__);
+			retval = -EPERM;
+		} else {
+			iowrite32((CAN_CMASK_RDWR | CAN_CMASK_CTRL),
+				(can->io_base + CAN_IF1_CMASK_OFFSET));
+
+			/*
+			Setting/Resetting the EOD bit for Buffer link operation.
+			EOB bit = 1 -> Buffer link disabled.
+			EOB bit = 0 -> Biffer link enabled.
+			*/
+			if (set == ENABLE) {
+				PCH_CAN_BIT_CLEAR((can->io_base +
+				    CAN_IF1_MCONT_OFFSET), CAN_IF_MCONT_EOB);
+				dev_dbg(&ndev->dev,
+					"%s -> Buffer Link enabled.\n",
+					__func__);
+			} else {
+				PCH_CAN_BIT_SET((can->io_base +
+						 CAN_IF1_MCONT_OFFSET),
+						CAN_IF_MCONT_EOB);
+				dev_dbg(&ndev->dev,
+				    "%s -> Buffer Link disabled.\n", __func__);
+			}
+
+			iowrite32(buffer_num,
+				       (can->io_base + CAN_IF1_CREQ_OFFSET));
+
+			counter = COUNTER_LIMIT;
+			while (counter) {
+				if1_creq = ioread32(can->io_base +
+						CAN_IF1_CREQ_OFFSET) &
+						CAN_IF_CREQ_BUSY;
+				if (if1_creq == 0)
+					break;
+
+				counter--;
+			}
+
+			if (counter == 0) {
+				dev_err(&ndev->dev, "%s -> Write failed.\n",
+								__func__);
+				retval = -EPERM;
+			} else {
+				dev_dbg(&ndev->dev,
+					"%s -> Write successful.\n", __func__);
+				retval = 0;
+			}
+
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_get_rx_buffer_link(int handle, u32 buffer_num,
+				      u32 *link, struct net_device *ndev)
+{
+	u32 reg_val;
+	u32 counter;
+	int retval = 0;
+	u32 if1_creq;
+
+	if ((handle == 0) || (link == NULL)) {
+		dev_err(&ndev->dev, "%s -> Invalid Parameter.\n", __func__);
+		retval = -EPERM;
+	} else if ((pch_msg_obj_conf[buffer_num - 1] != MSG_OBJ_RX) ||
+		   (buffer_num > (pch_can_rx_buf_size + pch_can_tx_buf_size))) {
+		dev_err(&ndev->dev,
+		    "%s -> Invalid buffer number %u.\n", __func__, buffer_num);
+		retval = -EPERM;
+	} else {
+		/* Obatining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Reading the corresponding message object. */
+		iowrite32(CAN_CMASK_RX_TX_GET,
+			       (can->io_base + CAN_IF1_CMASK_OFFSET));
+		iowrite32(buffer_num,
+			       (can->io_base + CAN_IF1_CREQ_OFFSET));
+
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = (ioread32((can->io_base +
+				     CAN_IF1_CREQ_OFFSET)) & CAN_IF_CREQ_BUSY);
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		/* Confirming read. */
+		if ((counter == 0)) {
+			dev_err(&ndev->dev, "%s -> Read Failed.\n", __func__);
+			retval = -EPERM;
+		} else {
+			/* Checking for the EOB bit.
+			   EOB bit = 1 -> Buffer link disabled.
+			   EOB bit = 0 -> Biffer link enabled.
+			 */
+			reg_val = ioread32(can->io_base +
+							CAN_IF1_MCONT_OFFSET);
+			if (reg_val & CAN_IF_MCONT_EOB)
+				*link = DISABLE;
+			else
+				*link = ENABLE;
+			dev_dbg(&ndev->dev, "%s -> EOB bit =  %d\n", __func__,
+			    (reg_val & CAN_IF_MCONT_EOB) >> BIT_SHIFT_SEVEN);
+			dev_dbg(&ndev->dev,
+			    "%s -> Buffer Link =  %u (1 - Set ,0 -> not set)\n",
+			    __func__, *link);
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_get_rx_filter(int handle, struct pch_can_rx_filter *filter,
+				 struct net_device *ndev)
+{
+	u32 reg_val1;
+	u32 reg_val2;
+	u32 counter;
+	int retval = 0;
+	u32 if1_creq;
+
+	if ((handle == 0) || (filter == NULL)) {
+		dev_err(&ndev->dev, "%s -> Invalid Parameter.\n", __func__);
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Preparing to read the specified Msg Obj. */
+		iowrite32(CAN_CMASK_RX_TX_GET,
+				(can->io_base + CAN_IF1_CMASK_OFFSET));
+		iowrite32(filter->num,
+				(can->io_base + CAN_IF1_CREQ_OFFSET));
+
+		/* Confirming the read completion. */
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if1_creq = (ioread32(can->io_base +
+				CAN_IF1_CREQ_OFFSET)) & CAN_IF_CREQ_BUSY;
+			if (if1_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if ((counter == 0)) {	/* Read unsuccessful. */
+			dev_err(&ndev->dev,
+				"%s -> Reading of receive buffer %u failed.\n",
+				__func__, filter->num);
+			retval = -EPERM;
+		} else {	/* read successful. */
+
+			/* Checking for Umask */
+			reg_val1 = ioread32((can->io_base +
+							CAN_IF1_MCONT_OFFSET));
+			filter->umask = ((CAN_IF_MCONT_UMASK & reg_val1) >>
+							BIT_SHIFT_TWELVE);
+
+			if (filter->umask == 1) {	/* If Umask is set */
+				/* Getting the Mask data. */
+
+				/* Reading MASK2 register. */
+				reg_val1 = ioread32((can->io_base +
+							CAN_IF1_MASK2_OFFSET));
+
+				if ((CAN_IF_MASK2_MXTD & reg_val1) != 0) {
+					/* Extended Mask set.
+							 Mask ID is 29 bits */
+					reg_val2 = ioread32((can->io_base +
+							CAN_IF1_MASK1_OFFSET));
+
+					/* Extracting the 16 MSB bits of the
+					 29bit ID. */
+					reg_val2 = reg_val2 & MSK_ALL_SIXTEEN;
+					/* Extracting the remaing 13 bits */
+					reg_val1 = reg_val1 & MSK_ALL_THIRTEEN;
+
+					/* Combing them to a single 29bit ID. */
+					reg_val1 =
+						reg_val1 << BIT_SHIFT_SIXTEEN;
+					reg_val1 = reg_val1 | reg_val2;
+
+					filter->amr.id = reg_val1;
+					filter->amr.id_ext = 1;
+				} else { /* Standard Mask 11bit Mask ID */
+
+					/* Extracting the 13 bits of MASK2
+								 register. */
+					reg_val1 = reg_val1 & MSK_ALL_THIRTEEN;
+
+					/* Modifying it to represent 11bit Mask
+									 ID */
+					reg_val1 = reg_val1 >> BIT_SHIFT_TWO;
+
+					filter->amr.id = reg_val1;
+					filter->amr.id_ext = 0;
+				}
+			}
+
+			reg_val1 = ioread32((can->io_base +
+							CAN_IF1_ID2_OFFSET));
+
+			if ((CAN_ID2_XTD & reg_val1) != 0) {	/* Extended ID
+								 29bits */
+				reg_val2 = ioread32((can->io_base +
+							CAN_IF1_ID1_OFFSET));
+
+				/* Extracting the 16 MSB bits of the 29bit
+									 ID. */
+				reg_val2 = reg_val2 & MSK_ALL_SIXTEEN;
+				/* Extracting the remaining 13 bit. */
+				reg_val1 = reg_val1 & MSK_ALL_THIRTEEN;
+
+				/* Combining them to represent 29bit ID. */
+				reg_val1 = reg_val1 << BIT_SHIFT_SIXTEEN;
+				reg_val1 = reg_val1 | reg_val2;
+
+				filter->aidr.id = reg_val1;
+				filter->aidr.id_ext = 1;
+			} else {	/* Standard Id 11bits. */
+
+				/* Extracting the 13 bits of ID2 register */
+				reg_val1 = reg_val1 & MSK_ALL_THIRTEEN;
+				/* Modifying it to represent the 11 bit ID */
+				reg_val1 = reg_val1 >> BIT_SHIFT_TWO;
+
+				filter->aidr.id = reg_val1;
+				filter->aidr.id_ext = 0;
+			}
+
+			dev_dbg(&ndev->dev,
+			  "%s -> Successfully read the filter of Msg Obj %u.\n",
+			  __func__, filter->num);
+		}
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d.\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_clear_buffers(int handle)
+{
+	u32 i;
+	u32 rx_buff_num;
+	u32 tx_buff_num;
+	int retval = 0;
+
+	if (handle == 0) {
+		retval = -EPERM;
+	} else {
+		/* Obatining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		iowrite32(CAN_CMASK_RX_TX_SET,
+			       (can->io_base + CAN_IF1_CMASK_OFFSET));
+		iowrite32(CAN_CMASK_RX_TX_SET,
+			       (can->io_base + CAN_IF2_CMASK_OFFSET));
+
+		iowrite32(MSK_ALL_SIXTEEN,
+			       (can->io_base + CAN_IF1_MASK1_OFFSET));
+		iowrite32(MSK_ALL_SIXTEEN,
+			       (can->io_base + CAN_IF1_MASK2_OFFSET));
+		iowrite32(MSK_ALL_SIXTEEN,
+			       (can->io_base + CAN_IF2_MASK1_OFFSET));
+		iowrite32(MSK_ALL_SIXTEEN,
+			       (can->io_base + CAN_IF2_MASK2_OFFSET));
+
+		iowrite32(0x0, (can->io_base + CAN_IF1_ID1_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF1_ID2_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF2_ID1_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF2_ID2_OFFSET));
+
+		iowrite32(0x0, (can->io_base + CAN_IF1_MCONT_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF2_MCONT_OFFSET));
+
+		iowrite32(0x0, (can->io_base + CAN_IF1_DATAA1_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF1_DATAA2_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF1_DATAB1_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF1_DATAB2_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF2_DATAA1_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF2_DATAA2_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF2_DATAB1_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF2_DATAB2_OFFSET));
+
+		for (i = 1; i <= (MAX_MSG_OBJ / 2); i++) {
+			rx_buff_num = 2 * i;
+			tx_buff_num = (2 * i) - 1;
+
+			iowrite32(rx_buff_num,
+				       (can->io_base + CAN_IF1_CREQ_OFFSET));
+			iowrite32(tx_buff_num,
+				       (can->io_base + CAN_IF2_CREQ_OFFSET));
+
+			mdelay(10);
+		}
+	}
+
+	return retval;
+}
+
+static void pch_can_config_rx_tx_buffers(int handle, struct net_device *ndev)
+{
+	u32 i;
+	u32 counter;
+	u32 if1_creq;
+	u32 if2_creq;
+
+	if (handle != 0) {	/* if handle valid. */
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/*For accssing MsgVal, ID and EOB bit */
+		iowrite32((CAN_CMASK_RDWR | CAN_CMASK_ARB |
+				CAN_CMASK_CTRL),
+			       (can->io_base + CAN_IF1_CMASK_OFFSET));
+		iowrite32((CAN_CMASK_RDWR | CAN_CMASK_ARB |
+				CAN_CMASK_CTRL),
+			       (can->io_base + CAN_IF2_CMASK_OFFSET));
+
+		iowrite32(0x0, (can->io_base + CAN_IF1_ID1_OFFSET));
+		iowrite32(0x0, (can->io_base + CAN_IF1_ID2_OFFSET));
+					/* Resetting DIR bit for reception */
+		iowrite32(0x0, (can->io_base + CAN_IF2_ID1_OFFSET));
+		iowrite32((CAN_ID2_DIR | (MSK_ALL_ELEVEN << 2)),
+					(can->io_base + CAN_IF2_ID2_OFFSET));
+					/* Setting DIR bit for transmission */
+
+		iowrite32(CAN_IF_MCONT_EOB,
+				(can->io_base + CAN_IF1_MCONT_OFFSET));
+					/* Setting EOB bit for receiver */
+		iowrite32(CAN_IF_MCONT_EOB,
+				(can->io_base + CAN_IF2_MCONT_OFFSET));
+					/* Setting EOB bit for transmitter */
+
+		for (i = 0; i < (pch_can_tx_buf_size + pch_can_rx_buf_size);
+									i++) {
+			counter = COUNTER_LIMIT;
+			/* Configure the receive message objects */
+			if (pch_msg_obj_conf[i] == MSG_OBJ_RX) {
+
+				iowrite32((i + 1), (can->io_base +
+							CAN_IF1_CREQ_OFFSET));
+
+				while (counter) {
+					if1_creq = (ioread32(can->io_base +
+							CAN_IF1_CREQ_OFFSET)) &
+							CAN_IF_CREQ_BUSY;
+					if (if1_creq == 0)
+						break;
+
+					counter--;
+				}
+
+				if ((counter == 0)) {
+					dev_dbg(&ndev->dev, "%s ->Config failed"
+					    " for receive message object %u\n",
+					    __func__, (i + 1));
+				}
+			}
+			/* Configure the transmit message objects */
+			else if (pch_msg_obj_conf[i] == MSG_OBJ_TX) {
+				iowrite32((i + 1), (can->io_base +
+							CAN_IF2_CREQ_OFFSET));
+
+				while (counter) {
+					if2_creq = (ioread32(can->io_base +
+							CAN_IF2_CREQ_OFFSET)) &
+							CAN_IF_CREQ_BUSY;
+					if (if2_creq == 0)
+						break;
+
+					counter--;
+				}
+
+				if ((counter == 0)) {
+					dev_dbg(&ndev->dev, "%s ->Config failed"
+					    " for transmit message object %u\n",
+					    __func__, (i + 1));
+				}
+			}
+
+		}
+	}
+}
+
+static int pch_can_open(int handle, enum pch_can_listen_mode listen,
+			enum pch_can_arbiter arbiter, struct net_device *ndev)
+{
+	int retval;
+	s32 i;
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid handle.\n", __func__);
+		retval = -EPERM;
+	} else {
+		do {
+			/* Stopping the Can device. */
+			retval = pch_can_set_run_mode(handle, PCH_CAN_STOP,
+									ndev);
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+				    "%s -> pch_can_set_run_mode "
+				    "failed(returned %d).\n", __func__, retval);
+
+				break;
+			}
+			dev_dbg(&ndev->dev,
+			   "%s -> pch_can_set_run_mode invoked successfully.\n",
+			   __func__);
+
+			/* Clearing all the message object buffers. */
+			retval = pch_can_clear_buffers(handle);
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev, "%s ->pch_can_clear_buffers"
+				   " failed(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev, "%s ->pch_can_clear_buffers invoked"
+			     " successfully(returned %d).\n", __func__, retval);
+
+			/* Configuring the respective message object as either
+						 receive/transmit object. */
+			pch_can_config_rx_tx_buffers(handle, ndev);
+			dev_dbg(&ndev->dev, "%s -> pch_can_config_rx_tx_buffers"
+					" invoked successfully.\n", __func__);
+
+			/* Initializing filters for receive object. */
+			for (i = 0;
+			     i < (pch_can_tx_buf_size + pch_can_rx_buf_size);
+									i++) {
+				if (pch_msg_obj_conf[i] == MSG_OBJ_RX) {
+					/* Here i denotes the index, however
+						 the object number is (i+1) */
+					retval =
+					    pch_can_rx_init_filter(handle,
+							   (i + 1), ndev);
+
+					if (retval != 0) {
+						dev_err(&ndev->dev,
+						    "pch_can_rx_init_filter "
+						    "failed for msg obj:%d\n",
+						    (i + 1));
+						break;
+					}
+				}
+			}
+			if (retval != 0)
+				break;
+			dev_dbg(&ndev->dev, "%s -> pch_can_rx_init_filter "
+					"invoked successfully.\n", __func__);
+
+			/* Enabling all receive objects. */
+			retval = pch_can_rx_enable_all(handle, ndev);
+
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+				    "%s -> pch_can_rx_enable_all "
+				    "failed(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev, "%s -> pch_can_rx_enable_all "
+				"invoked successfully(returned %d).\n",
+				__func__, retval);
+
+			/* Enabling all transmit objects. */
+			retval = pch_can_tx_enable_all(handle, ndev);
+
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+					"%s -> pch_can_tx_enable_all failed"
+					"(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev, "%s -> pch_can_tx_enable_all "
+				"invoked successfully(returned %d).\n",
+				__func__, retval);
+
+			/* Setting the arbiter mode. */
+			retval = pch_can_set_arbiter_mode(handle, arbiter,
+									ndev);
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+				    "%s -> pch_can_set_arbiter_mode "
+				    "failed(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev, "%s -> pch_can_set_arbiter_mode "
+				"invoked successfully(returned %d).\n",
+				__func__, retval);
+
+			/* Setting the listen mode. */
+			retval = pch_can_set_listen_mode(handle, listen, ndev);
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+				    "%s -> pch_can_set_listen_mode "
+				    "failed(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev, "%s -> pch_can_set_listen_mode "
+				"invoked successfully(returned %d).\n",
+				__func__, retval);
+
+			/* Enabling the interrupts. */
+			retval = pch_can_set_int_enables(handle, CAN_ALL, ndev);
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+				    "%s -> pch_can_set_int_enables "
+				    "failed(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev, "%s -> pch_can_set_int_enables "
+				"invoked successfully(returned %d).\n",
+				__func__, retval);
+
+			/* Setting the restart mode. */
+			retval = pch_can_set_restart_mode(handle, CAN_AUTO,
+									ndev);
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+				    "%s -> pch_can_set_restart_mode failed"
+				    "(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev, "%s -> pch_can_set_restart_mode "
+				"invoked successfully(returned %d).\n",
+				__func__, retval);
+
+			/* Setting the CAN to run mode. */
+			retval = pch_can_set_run_mode(handle, PCH_CAN_RUN,
+									ndev);
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+				    "%s -> pch_can_set_run_mode "
+				    "failed(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev, "%s -> pch_can_set_set_run_mode "
+				"invoked successfully(returned %d).\n",
+				__func__, retval);
+
+		} while (false);
+	}
+
+	dev_dbg(&ndev->dev, "%s returns %d.\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_release(int handle, struct net_device *ndev)
+{
+	int retval = 0;
+
+	if (handle == 0) {
+		dev_err(&ndev->dev, "%s -> Invalid handle.\n", __func__);
+		retval = -EPERM;
+	} else {
+		do {
+			/* Stooping the CAN device. */
+			retval = pch_can_set_run_mode(handle, PCH_CAN_STOP,
+									ndev);
+
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+					"%s -> pch_can_set_run_mode failed"
+					"(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev, "%s -> pch_can_set_run_mode invoked"
+			    " successfully(returned %d).\n", __func__, retval);
+
+			/* Disabling the interrupts. */
+			retval = pch_can_set_int_enables(handle, CAN_NONE,
+									ndev);
+
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+				    "%s -> pch_can_set_int_enables failed"
+				    "(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev, "%s -> pch_can_set_int_enables "
+				"invoked successfully(returned %d).\n",
+				__func__, retval);
+
+			/* Disabling all the receive object. */
+			retval = pch_can_rx_disable_all(handle, ndev);
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+				"%s -> pch_can_rx_disable_all "
+				"failed(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev,
+			    "%s -> pch_can_rx_disable_all invoked "
+			    "successfully(returned %d).\n", __func__, retval);
+
+			/* Disabling all the transmit object. */
+			retval = pch_can_tx_disable_all(handle, ndev);
+			if (retval == -EPERM) {
+				dev_err(&ndev->dev,
+				    "%s -> pch_can_tx_disable_all "
+				    "failed(returned %d).\n", __func__, retval);
+				break;
+			}
+			dev_dbg(&ndev->dev,
+			    "%s -> pch_can_tx_disable_all invoked "
+			    "successfully(returned %d).\n", __func__, retval);
+
+		} while (false);
+	}
+
+	dev_dbg(&ndev->dev, "%s returns %d.\n", __func__, retval);
+	return retval;
+}
+
+/* This function clears interrupt(s) from the CAN device. */
+static void pch_can_int_clr(int handle, u32 mask, struct net_device *ndev)
+{
+	u32 counter;
+	u32 rtr;
+	u32 if2_creq;
+
+	if ((handle != 0) && (mask != 0)) {	/* if valid
+								 parameters. */
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Clearing status interrupt. */
+		if (mask == CAN_STATUS_INT) {
+			ioread32((can->io_base + CAN_STAT_OFFSET));
+			dev_dbg(&ndev->dev,
+				"%s -> Status Interrupt cleared.\n", __func__);
+		} else if ((mask > 0) && (mask <= MAX_MSG_OBJ)) {
+			/* Clear interrupt for transmit object */
+			if (pch_msg_obj_conf[mask - 1] == MSG_OBJ_TX) {
+				/* Checking if the transmission is for remote
+								 frame. */
+				rtr = ((ioread32((can->io_base +
+							CAN_IF2_ID2_OFFSET)) &
+							CAN_ID2_DIR) == 0);
+
+				if (rtr == 1) {
+
+					dev_dbg(&ndev->dev,
+					    "%s -> Remote frame transmission "
+					    "interrupt cleared for message"
+					    "object %d.\n", __func__, mask);
+				} else {
+					dev_dbg(&ndev->dev,
+					  "%s -> Data frame transmission "
+					  "interrupt cleared for message "
+					  "object %d.\n", __func__, mask);
+				}
+
+				/* Setting CMASK for clearing interrupts for
+							 frame transmission. */
+				iowrite32((CAN_CMASK_RDWR | CAN_CMASK_CTRL |
+							CAN_CMASK_ARB),
+							(can->io_base +
+							CAN_IF2_CMASK_OFFSET));
+
+				/* Resetting the ID registers. */
+				PCH_CAN_BIT_SET((can->io_base +
+						 CAN_IF2_ID2_OFFSET),
+						(CAN_ID2_DIR |
+						 (MSK_ALL_ELEVEN << 2)));
+				iowrite32(0x0,
+					(can->io_base + CAN_IF2_ID1_OFFSET));
+
+				/* Claring NewDat, TxRqst & IntPnd */
+				PCH_CAN_BIT_CLEAR((can->io_base +
+						   CAN_IF2_MCONT_OFFSET),
+						  (CAN_IF_MCONT_NEWDAT |
+						   CAN_IF_MCONT_INTPND |
+						   CAN_IF_MCONT_TXRQXT));
+
+				iowrite32(mask,
+				       (can->io_base + CAN_IF2_CREQ_OFFSET));
+
+				counter = COUNTER_LIMIT;
+				while (counter) {
+					if2_creq = (ioread32(can->io_base +
+							CAN_IF2_CREQ_OFFSET) &
+							CAN_IF_CREQ_BUSY);
+					if (if2_creq == 0)
+						break;
+
+					counter--;
+				}
+			}
+			/* Clear interrupt for receive object */
+			else if (pch_msg_obj_conf[mask - 1] == MSG_OBJ_RX) {
+				/* Checking if the reception is for remote
+								 frame. */
+				rtr = ((ioread32((can->io_base +
+							CAN_IF2_ID2_OFFSET)) &
+							CAN_ID2_DIR) != 0);
+
+				if (rtr == 1) {	/* if remote frame. */
+					dev_dbg(&ndev->dev,
+						"%s -> Remote frame reception "
+						"interrupt cleared for message "
+						"object %d.\n", __func__, mask);
+				} else {
+					dev_dbg(&ndev->dev,
+					  "%s -> Data frame reception "
+					  "interrupt cleared for message object"
+					  "%d.\n", __func__, mask);
+				}
+
+				/* Setting CMASK for clearing the reception
+								 interrupts. */
+				iowrite32((CAN_CMASK_RDWR | CAN_CMASK_CTRL |
+							CAN_CMASK_ARB),
+							(can->io_base +
+							CAN_IF2_CMASK_OFFSET));
+
+				/* Clearing the Dir bit. */
+				PCH_CAN_BIT_CLEAR((can->io_base +
+							CAN_IF2_ID2_OFFSET),
+							CAN_ID2_DIR);
+
+				/* Clearing NewDat & IntPnd */
+				PCH_CAN_BIT_CLEAR((can->io_base +
+						   CAN_IF2_MCONT_OFFSET),
+						  (CAN_IF_MCONT_NEWDAT |
+						   CAN_IF_MCONT_INTPND));
+
+				iowrite32(mask,
+				       (can->io_base + CAN_IF2_CREQ_OFFSET));
+
+				counter = COUNTER_LIMIT;
+				while (counter) {
+					if2_creq = ioread32(can->io_base +
+							CAN_IF2_CREQ_OFFSET) &
+							CAN_IF_CREQ_BUSY;
+					if (if2_creq == 0)
+						break;
+
+					counter--;
+				}
+
+			}
+		}
+	}
+}
+
+static int pch_can_get_buffer_status(int handle)
+{
+	u32 reg_treq1;
+	u32 reg_treq2;
+	int retval = 0;
+
+	if (handle == 0) {
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Reading the transmission request registers. */
+		reg_treq1 = (ioread32(can->io_base + CAN_TREQ1_OFFSET) &
+							MSK_ALL_SIXTEEN);
+		reg_treq2 = ((ioread32(can->io_base + CAN_TREQ2_OFFSET) &
+					MSK_ALL_SIXTEEN) << BIT_SHIFT_SIXTEEN);
+
+		retval = (reg_treq1 | reg_treq2);
+	}
+
+	return retval;
+}
+
+static int pch_can_msg_tx(int handle, struct pch_can_msg *msg,
+			  struct net_device *ndev)
+{
+	u32 id1 = 0;
+	u32 id2 = 0;
+	u32 data_a1 = 0;
+	u32 data_a2 = 0;
+	u32 data_b1 = 0;
+	u32 data_b2 = 0;
+	u32 tx_disable_counter = 0;
+	u32 buffer_status = 0;
+	u32 tx_buffer_avail = 0;
+	u32 status;
+	u32 i;
+	u32 counter;
+	enum pch_can_run_mode run_mode;
+	int retval = 0;
+	u32 if1_creq;
+
+	if ((handle == 0) || (msg == NULL)) {
+		dev_err(&ndev->dev, "%s -> Invalid Parameter.\n", __func__);
+		retval = -EPERM;
+	}
+
+	else {
+		/* Obatining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		/* Getting the current CAN mode. */
+		pch_can_get_run_mode(handle, &run_mode, ndev);
+
+		/* If CAN is in STOP mode. */
+		if (run_mode != PCH_CAN_RUN) {
+			dev_err(&ndev->dev,
+			  "%s -> CAN stopped on transmit attempt.\n", __func__);
+			retval = -EPERM;
+		} else {
+			unsigned long flags;
+			/* Attaining the lock. */
+			spin_lock_irqsave(&can_os->tx_spinlock, flags);
+
+			/* Getting the message object status. */
+			buffer_status = (u32) pch_can_get_buffer_status(handle);
+
+			/* Getting the free transmit message object. */
+			for (i = 0;
+			     i < (pch_can_rx_buf_size + pch_can_tx_buf_size);
+									i++) {
+				if ((pch_msg_obj_conf[i] == MSG_OBJ_TX)) {
+					/* Checking whether the object is
+								enabled. */
+					pch_can_get_tx_enable(handle,
+								(i + 1),
+								&status, ndev);
+
+					if ((ENABLE == status)) {
+						if ((((buffer_status >> i) & 1)
+									== 0)) {
+							tx_buffer_avail =
+							    (i + 1);
+							break;
+						}
+					} else {
+						tx_disable_counter++;
+					}
+				}
+			}
+
+			/* If no transmit object available. */
+			if (tx_buffer_avail == 0) {
+				dev_dbg(&ndev->dev, "%s -> tx_disable_counter "
+				    "= %d.\n", __func__, tx_disable_counter);
+				/* If no object is enabled. */
+				if ((tx_disable_counter ==
+							pch_can_tx_buf_size)){
+					retval = -EPERM;
+					dev_err(&ndev->dev,
+						"%s -> All transmit buffers "
+						"are disabled.\n", __func__);
+				} else {
+					dev_err(&ndev->dev,
+					    "%s -> No transmit buffer free.\n",
+					    __func__);
+					retval = PCH_CAN_NO_TX_BUFF;
+				}
+			} else {
+				dev_dbg(&ndev->dev,
+				  "%s ->Transmit buffer obtained.\n", __func__);
+
+				/* Reading the message object from the Message
+					 RAM to the Interface register. */
+				iowrite32(CAN_CMASK_RX_TX_GET,
+					       (can->io_base +
+						CAN_IF1_CMASK_OFFSET));
+				iowrite32(tx_buffer_avail,
+					       (can->io_base +
+						CAN_IF1_CREQ_OFFSET));
+
+				/* Confirming the read. */
+				counter = COUNTER_LIMIT;
+				while (counter) {
+					if1_creq = (ioread32(can->io_base +
+							CAN_IF1_CREQ_OFFSET)) &
+							CAN_IF_CREQ_BUSY;
+					if (if1_creq == 0)
+						break;
+
+					counter--;
+				}
+				/* If Read not successful. */
+				if (counter == 0) {
+					pch_can_set_tx_enable(handle,
+								tx_buffer_avail,
+								ENABLE, ndev);
+					retval = -EPERM;
+				} else {
+					/* Setting the CMASK register. */
+					PCH_CAN_BIT_SET((can->io_base +
+							 CAN_IF1_CMASK_OFFSET),
+							CAN_CMASK_ALL);
+
+					/* If ID extended is set. */
+					if (msg->ide == 1) {
+						/* Setting 29 bit ID with XTD
+								 bit set. */
+						id1 =
+						    (msg->id & MSK_ALL_SIXTEEN);
+						id2 =
+						    ((msg->
+						      id & (MSK_ALL_THIRTEEN <<
+							    BIT_SHIFT_SIXTEEN))
+						     >> BIT_SHIFT_SIXTEEN);
+
+						id2 |= CAN_ID2_XTD;
+					} else {
+						/* Setting 11bit ID with XTD bit
+								 reset. */
+						id1 = 0;
+						id2 =
+						    ((msg->
+						      id & MSK_ALL_ELEVEN) <<
+						     BIT_SHIFT_TWO);
+					}
+					PCH_CAN_BIT_CLEAR((can->io_base +
+							   CAN_IF1_ID1_OFFSET),
+							  MSK_ALL_SIXTEEN);
+					PCH_CAN_BIT_CLEAR((can->io_base +
+							   CAN_IF1_ID2_OFFSET),
+							  (MSK_ALL_THIRTEEN |
+							   CAN_ID2_XTD));
+
+					PCH_CAN_BIT_SET((can->io_base +
+							 CAN_IF1_ID1_OFFSET),
+							id1);
+					PCH_CAN_BIT_SET((can->io_base +
+							 CAN_IF1_ID2_OFFSET),
+							id2);
+
+					/* If remote frame has to be
+							 transmitted.. */
+					if (msg->rtr == 1) {
+						PCH_CAN_BIT_CLEAR((
+							can->io_base +
+							CAN_IF1_ID2_OFFSET),
+							CAN_ID2_DIR);
+						msg->dlc = 0;
+
+						dev_dbg(&ndev->dev,
+						  "%s -> Transmitting a remote"
+						  " frame.\n", __func__);
+					} else {	/* Data frame
+							 transmission. */
+
+						msg->dlc &= MSK_ALL_FOUR;
+
+						dev_dbg(&ndev->dev,
+						  "%s -> Transmitting a data "
+						  "frame.\n", __func__);
+					}
+
+					/* Writing the data and the DLC */
+					switch (msg->dlc) {
+					case 0:
+						break;
+
+					case 1:
+						data_a1 = msg->data[0];
+						break;
+					case 2:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						break;
+					case 3:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						break;
+					case 4:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						data_a2 |=
+						    (((u32) msg->
+						      data[3]) <<
+						     BIT_SHIFT_EIGHT);
+						break;
+					case 5:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						data_a2 |=
+						    (((u32) msg->
+						      data[3]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b1 = msg->data[4];
+						break;
+					case 6:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						data_a2 |=
+						    (((u32) msg->
+						      data[3]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b1 = msg->data[4];
+						data_b1 |=
+						    (((u32) msg->
+						      data[5]) <<
+						     BIT_SHIFT_EIGHT);
+						break;
+					case 7:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						data_a2 |=
+						    (((u32) msg->
+						      data[3]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b1 = msg->data[4];
+						data_b1 |=
+						    (((u32) msg->
+						      data[5]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b2 = msg->data[6];
+						break;
+					case 8:
+					default:
+						data_a1 = msg->data[0];
+						data_a1 |=
+						    (((u32) msg->
+						      data[1]) <<
+						     BIT_SHIFT_EIGHT);
+						data_a2 = msg->data[2];
+						data_a2 |=
+						    (((u32) msg->
+						      data[3]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b1 = msg->data[4];
+						data_b1 |=
+						    (((u32) msg->
+						      data[5]) <<
+						     BIT_SHIFT_EIGHT);
+						data_b2 = msg->data[6];
+						data_b2 |=
+						    (((u32) msg->
+						      data[7]) <<
+						     BIT_SHIFT_EIGHT);
+						break;
+
+					}
+
+					/* Writing the DATA registers. */
+					iowrite32(data_a1,
+						       (can->io_base +
+							CAN_IF1_DATAA1_OFFSET));
+					iowrite32(data_a2,
+						       (can->io_base +
+							CAN_IF1_DATAA2_OFFSET));
+					iowrite32(data_b1,
+						       (can->io_base +
+							CAN_IF1_DATAB1_OFFSET));
+					iowrite32(data_b2,
+						       (can->io_base +
+							CAN_IF1_DATAB2_OFFSET));
+
+					/* Updating the size of the data. */
+					PCH_CAN_BIT_CLEAR((can->io_base +
+							  CAN_IF1_MCONT_OFFSET),
+							  MSK_ALL_FOUR);
+					PCH_CAN_BIT_SET((can->io_base +
+							 CAN_IF1_MCONT_OFFSET),
+							msg->dlc);
+
+					/* Clearing IntPend, NewDat & TxRqst */
+					PCH_CAN_BIT_CLEAR((can->io_base +
+							CAN_IF1_MCONT_OFFSET),
+							(CAN_IF_MCONT_NEWDAT |
+							CAN_IF_MCONT_INTPND |
+							CAN_IF_MCONT_TXRQXT));
+
+					/* Setting NewDat, TxRqst bits */
+					PCH_CAN_BIT_SET((can->io_base +
+							 CAN_IF1_MCONT_OFFSET),
+							(CAN_IF_MCONT_NEWDAT |
+							 CAN_IF_MCONT_TXRQXT));
+
+					/* Writing the updation to the Message
+								 object. */
+					iowrite32(tx_buffer_avail,
+						       (can->io_base +
+							CAN_IF1_CREQ_OFFSET));
+
+					/* Confirming the updation. */
+					counter = COUNTER_LIMIT;
+					while (counter) {
+						if1_creq = (ioread32(
+							can->io_base +
+							CAN_IF1_CREQ_OFFSET)) &
+							CAN_IF_CREQ_BUSY;
+						if (if1_creq == 0)
+							break;
+
+						counter--;
+					}
+
+					if ((counter == 0)) {
+						retval = -EPERM;
+					} else {
+						dev_dbg(&ndev->dev,
+						  "%s -> Updation of transmit "
+						  "buffer successful.\n"
+						  "Message object enabled "
+						  "for transmission.\n",
+						  __func__);
+					}
+
+				}	/* if message read object successful */
+			}	/* if transmit buffer available */
+
+			/* Releasing the lock. */
+			spin_unlock_irqrestore(&can_os->tx_spinlock, flags);
+		}		/* if device in run mode */
+	}			/* if parameters valid */
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d.\n", __func__, retval);
+	return retval;
+}
+
+/* This function gets a pending message from the CAN device. */
+static int pch_can_rx_dequeue(int handle, struct pch_can_msg *msg,
+			      u32 buff_num, struct net_device *ndev)
+{
+	s32 i;
+	u32 reg;
+	int retval = -EPERM;
+
+	if ((handle == 0) || (msg == NULL)) {
+		dev_err(&ndev->dev, "%s -> Invalid Parameter.\n", __func__);
+	} else if ((pch_msg_obj_conf[buff_num - 1] != MSG_OBJ_RX) ||
+		 (buff_num > (pch_can_rx_buf_size + pch_can_tx_buf_size))) {
+		/* invalid buffer number. */
+		dev_err(&ndev->dev, "%s -> Invalid Buffer number.\n", __func__);
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) handle;
+
+		msg->ide = 0;
+		msg->id = 0;
+		msg->dlc = 0;
+		for (i = 0; i < PCH_CAN_MSG_DATA_LEN;)
+			msg->data[i++] = 0;
+
+		/* Read the ID type. */
+		msg->ide = ((ioread32(can->io_base + CAN_IF2_ID2_OFFSET)) &
+					CAN_ID2_XTD) >> BIT_SHIFT_FOURTEEN;
+
+		/* Extracting the ID. */
+		if (msg->ide == 1) {	/* Extended 29bit ID. */
+			msg->id = (ioread32(can->io_base +
+					CAN_IF2_ID1_OFFSET) & MSK_ALL_SIXTEEN);
+			msg->id |= (((ioread32(can->io_base +
+					CAN_IF2_ID2_OFFSET)) &
+					MSK_ALL_THIRTEEN) << BIT_SHIFT_SIXTEEN);
+		} else {	/* Standard 11bit ID. */
+
+			msg->id = (((ioread32(can->io_base +
+						CAN_IF2_ID2_OFFSET)) &
+						(MSK_ALL_ELEVEN <<
+						BIT_SHIFT_TWO)) >>
+						BIT_SHIFT_TWO);
+		}
+
+		/* Getting the size of the data and the Remote frame bit. */
+		if (msg->rtr == 1) {
+			msg->dlc = 0;
+
+			dev_dbg(&ndev->dev,
+			    "%s -> Remote frame read with message id: %x.\n",
+			    __func__, msg->id);
+		} else {
+			msg->dlc = ((ioread32(can->io_base +
+						CAN_IF2_MCONT_OFFSET)) &
+						MSK_ALL_FOUR);
+
+			dev_dbg(&ndev->dev,
+			    "%s -> Data frame read with message id: %x.\n",
+			    __func__, msg->id);
+		}
+
+		/* Reading back the data. */
+		switch (msg->dlc) {
+		case 0:
+			break;
+
+		case 1:
+			reg = ioread32(can->io_base + CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			break;
+
+		case 2:
+			reg = ioread32(can->io_base + CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+			break;
+
+		case 3:
+			reg = ioread32(can->io_base + CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			break;
+
+		case 4:
+			reg = ioread32(can->io_base + CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			msg->data[3] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+			break;
+
+		case 5:
+			reg = ioread32(can->io_base + CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			msg->data[3] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAB1_OFFSET);
+			msg->data[4] = reg & MSK_ALL_EIGHT;
+			break;
+
+		case 6:
+			reg = ioread32(can->io_base + CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			msg->data[3] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAB1_OFFSET);
+			msg->data[4] = reg & MSK_ALL_EIGHT;
+			msg->data[5] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+			break;
+
+		case 7:
+			reg = ioread32(can->io_base + CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			msg->data[3] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAB1_OFFSET);
+			msg->data[4] = reg & MSK_ALL_EIGHT;
+			msg->data[5] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAB2_OFFSET);
+			msg->data[6] = reg & MSK_ALL_EIGHT;
+			break;
+
+		case 8:
+		default:
+			reg = ioread32(can->io_base + CAN_IF2_DATAA1_OFFSET);
+			msg->data[0] = reg & MSK_ALL_EIGHT;
+			msg->data[1] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAA2_OFFSET);
+			msg->data[2] = reg & MSK_ALL_EIGHT;
+			msg->data[3] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAB1_OFFSET);
+			msg->data[4] = reg & MSK_ALL_EIGHT;
+			msg->data[5] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			reg = ioread32(can->io_base + CAN_IF2_DATAB2_OFFSET);
+			msg->data[6] = reg & MSK_ALL_EIGHT;
+			msg->data[7] =
+			    ((reg & (MSK_ALL_EIGHT << BIT_SHIFT_EIGHT))
+			     >> BIT_SHIFT_EIGHT);
+
+			break;
+		}
+		retval = 0;
+	}
+
+	dev_dbg(&ndev->dev, "%s -> Return value: %d\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_reset(struct pch_can_os *can_os)
+{
+	int retval = 0;
+
+	if ((can_os == NULL)) {
+		retval = -EPERM;
+	} else {
+		/* Obtaining the remap address for access. */
+		struct can_hw *can = (struct can_hw *) can_os->can;
+
+		/* write to sw reset register */
+		iowrite32(1, (can->io_base + CAN_SRST_OFFSET));
+		iowrite32(0, (can->io_base + CAN_SRST_OFFSET));
+
+	}
+	return retval;
+}
+
+static irqreturn_t pch_can_handler(int irq, void *dev_id)
+{
+	irqreturn_t retval = IRQ_NONE;
+	u32 int_stat;
+	struct pch_can_os *can_os = (struct pch_can_os *) dev_id;
+	dev_dbg(&can_os->ndev->dev, "%s -> Invoked.\n", __func__);
+
+	int_stat = pch_can_int_pending(can_os->can);
+
+	dev_dbg(&can_os->ndev->dev,
+	  "%s -> pch_can_int_pending returned value: %x\n", __func__, int_stat);
+
+	if ((can_os != NULL) && (int_stat > 0)) {
+		can_os->int_stat = int_stat;
+		(*can_os->can_callback) (can_os);
+
+		dev_dbg(&can_os->ndev->dev,
+		   "%s -> Callback function invoked successfully.\n", __func__);
+
+		retval = IRQ_HANDLED;
+	}
+	return retval;
+}
+
+static void pch_can_log_message(u32 status, struct net_device *ndev)
+{
+	static int cnt;
+
+	switch ((status & MSK_ALL_THREE)) {
+
+	case 0:
+		dev_dbg(&ndev->dev, "%s ->  No Error\n", __func__);
+		break;
+	case 1:
+		dev_err(&ndev->dev, "%s -> Stuff Error\n", __func__);
+		break;
+	case 2:
+		dev_err(&ndev->dev, "%s -> Form Error.\n", __func__);
+		break;
+	case 3:
+		if (cnt % 200 == 0)
+			dev_err(&ndev->dev, "%s -> Ack Error\n", __func__);
+		cnt++;
+		break;
+	case 4:
+		dev_err(&ndev->dev, "%s -> Bit 1 Error\n", __func__);
+		break;
+	case 5:
+		dev_err(&ndev->dev, "%s -> Bit 0 Error.\n", __func__);
+		break;
+	case 6:
+		dev_err(&ndev->dev, "%s -> Crc Error\n", __func__);
+		break;
+	case 7:
+		dev_err(&ndev->dev, "%s -> Undefined Error\n", __func__);
+		break;
+	default:
+		break;
+	}
+}
+
+static void pch_can_entcb(void (*pch_can_cb) (struct pch_can_os *),
+			  struct pch_can_os *p_can_os, struct net_device *ndev)
+{
+	if ((pch_can_cb != NULL) && (p_can_os != NULL)) {
+		p_can_os->can_callback = pch_can_cb;
+		dev_dbg(&ndev->dev,
+		    "%s -> Callback function set successful.\n", __func__);
+	} else {
+		dev_err(&ndev->dev,
+		    "%s -> Callback function set unsuccessful.\n", __func__);
+	}
+}
+
+static void pch_can_callback(struct pch_can_os *can_os)
+{
+	u32 int_stat;
+	u32 reg;
+	u32 reg_stat;
+	u32 counter;
+	struct pch_can_msg receive_msg;
+	struct can_hw *can = (struct can_hw *) (can_os->can);
+	int retval = 0;
+	u32 if2_creq;
+	enum pch_can_auto_restart restart_mode = 0;
+
+
+	/* Get the interrupt status */
+	int_stat = can_os->int_stat;
+	can_os->int_stat = 0;
+
+	/* Checking for status interrupt */
+	if (int_stat == CAN_STATUS_INT) {
+		/* Reading of the CANSTAT register. */
+		reg_stat = ioread32((can->io_base + CAN_STAT_OFFSET));
+		reg_stat = reg_stat & MSK_ALL_EIGHT;
+		dev_dbg(&can_os->ndev->dev,
+			"%s -> Status Register: %x.\n", __func__, reg_stat);
+
+		/* If recovered from Bus-Off interrupt. */
+		if ((reg_stat == 0) && (can_os->bus_off_interrupt == 1)) {
+			can_os->bus_off_interrupt = 0;
+			pch_can_tx_enable_all(can_os->can, can_os->ndev);
+			pch_can_rx_enable_all(can_os->can, can_os->ndev);
+
+			dev_err(&can_os->ndev->dev,
+				"%s -> Bus off stage recovered.\n", __func__);
+		} else {
+			/* Bus off interrupt. */
+			if (reg_stat & ((u32) 1 << BIT_SHIFT_SEVEN)) {
+				if (can_os->bus_off_interrupt == 0) {
+
+					dev_err(&can_os->ndev->dev,
+						"%s -> Bus off "
+						"interrupt.\n", __func__);
+
+					pch_can_tx_disable_all(can_os->can,
+								can_os->ndev);
+					pch_can_rx_disable_all(can_os->can,
+								can_os->ndev);
+
+					pch_can_get_restart_mode(can_os->can,
+						&restart_mode, can_os->ndev);
+
+					if (restart_mode == CAN_AUTO) {
+						can_os->bus_off_interrupt = 1;
+						pch_can_set_run_mode(
+							can_os->can,
+							PCH_CAN_RUN,
+							can_os->ndev);
+						dev_dbg(&can_os->ndev->dev,
+						    "%s -> Device restarted.\n",
+						    __func__);
+					}
+				}
+			}
+			/* EWarn interrupt. */
+			if ((reg_stat & ((u32) 1 << BIT_SHIFT_SIX)) != 0) {
+				dev_info(&can_os->ndev->dev,
+					"%s -> EWarn interrupt.\n", __func__);
+			}
+			/* EPass interrupt. */
+			if ((reg_stat & ((u32) 1 << BIT_SHIFT_FIVE)) != 0) {
+				dev_dbg(&can_os->ndev->dev,
+					"%s -> EPass interrupt.\n", __func__);
+			}
+			/* RxOK interrupt. */
+			if ((reg_stat & ((u32) 1 << BIT_SHIFT_FOUR)) != 0) {
+				dev_dbg(&can_os->ndev->dev,
+					"%s -> RxOK interrupt.\n", __func__);
+				reg_stat =
+				    reg_stat & ~((u32) 1 << BIT_SHIFT_FOUR);
+			}
+			/* TxOK interrupt */
+			if ((reg_stat & ((u32) 1 << BIT_SHIFT_THREE)) != 0) {
+				dev_dbg(&can_os->ndev->dev,
+					"%s -> TxOK interrupt.\n", __func__);
+				reg_stat =
+				    reg_stat & ~((u32) 1 << BIT_SHIFT_THREE);
+			}
+			/* Error status */
+			pch_can_log_message((reg_stat & MSK_ALL_THREE),
+								can_os->ndev);
+			reg_stat = reg_stat & ~(MSK_ALL_THREE);
+
+			/* Clearing status register interrupt bits. */
+			iowrite32(reg_stat,
+					(can->io_base + CAN_STAT_OFFSET));
+
+			int_stat = pch_can_int_pending(can_os->can);
+		}
+	}
+
+	/* Message object interrupt. */
+	if ((int_stat > 0) && (int_stat <= MAX_MSG_OBJ)) {
+		/* Reading the messsage object from the Message RAM to the
+							 interface registers. */
+		iowrite32(CAN_CMASK_RX_TX_GET,
+			       (can->io_base + CAN_IF2_CMASK_OFFSET));
+		iowrite32((int_stat),
+			       (can->io_base + CAN_IF2_CREQ_OFFSET));
+
+		/* Confirming the read. */
+		counter = COUNTER_LIMIT;
+		while (counter) {
+			if2_creq = (ioread32(can->io_base +
+						CAN_IF2_CREQ_OFFSET)) &
+						CAN_IF_CREQ_BUSY;
+
+			if (if2_creq == 0)
+				break;
+
+			counter--;
+		}
+
+		if (counter > 0) {	/* If read successful. */
+			/* Reading the MCONT register. */
+			reg = ioread32((can->io_base +
+							CAN_IF2_MCONT_OFFSET));
+			reg &= MSK_ALL_SIXTEEN;
+
+			/* If MsgLost bit set. */
+			if ((reg & CAN_IF_MCONT_MSGLOST) != 0) {
+				PCH_CAN_BIT_CLEAR((can->io_base +
+						   CAN_IF2_MCONT_OFFSET),
+						  CAN_IF_MCONT_MSGLOST);
+
+				dev_err(&can_os->ndev->dev,
+				    "%s -> Message object %d has "
+				    "been overwritten.\n", __func__, int_stat);
+			}
+
+			/* Read the direction bit for determination of remote
+						 frame during reception. */
+			receive_msg.rtr = ((ioread32((can->io_base +
+							CAN_IF2_ID2_OFFSET)) &
+							CAN_ID2_DIR) != 0);
+
+			/* Clearing interrupts. */
+			pch_can_int_clr(can_os->can, int_stat, can_os->ndev);
+			dev_dbg(&can_os->ndev->dev,
+			    "%s -> pch_can_int_clr invoked successfully.\n",
+			    __func__);
+
+			/* Hanlde reception interrupt */
+			if (pch_msg_obj_conf[int_stat - 1] == MSG_OBJ_RX) {
+				/* If new data arrived */
+				if ((reg & CAN_IF_MCONT_NEWDAT) != 0) {
+					/* Reading the message object content.*/
+					retval =
+					    pch_can_rx_dequeue(can_os->can,
+							&receive_msg,
+							int_stat, can_os->ndev);
+
+					if (retval == 0) {
+						struct sk_buff *skb;
+						struct can_frame *cf;
+						struct net_device_stats *stats;
+						stats = &(can_os->ndev->stats);
+						/* create zero'ed CAN frame
+								 buffer */
+						skb = alloc_can_skb
+							(can_os->ndev, &cf);
+						if (skb == NULL)
+							return;
+
+						if (receive_msg.ide) {
+							cf->can_id =
+							    ((receive_msg.id) &
+							    0x1fffffff) |
+							    0x80000000;
+						} else { /* Standard*/
+							cf->can_id =
+							    ((receive_msg.id) &
+							    0x00000fff);
+						}
+						if (receive_msg.rtr)
+							cf->can_id |=
+								0x40000000;
+						cf->can_dlc = receive_msg.dlc;
+						memcpy(cf->data,
+							receive_msg.data, 8);
+						netif_rx(skb);
+						stats->rx_packets++;
+						stats->rx_bytes += cf->can_dlc;
+
+					}
+					dev_dbg(&can_os->ndev->dev,
+					  "%s -> Reception interrupt handled "
+					  "for receive message object %u.\n",
+					  __func__, int_stat);
+				}
+
+			}
+			/* Hanlde transmission interrupt */
+			else if (pch_msg_obj_conf[int_stat - 1] == MSG_OBJ_TX) {
+				can_get_echo_skb(can_os->ndev, 0);
+				netif_wake_queue(can_os->ndev);
+
+				dev_dbg(&can_os->ndev->dev,
+				  "%s -> Transmission interrupt handled for "
+				  "transmit message object %u.\n",
+				  __func__, int_stat);
+			}
+		}
+	}
+}
+
+static void pch_can_start(struct net_device *ndev)
+{
+	struct pch_can_priv *priv = netdev_priv(ndev);
+
+	pch_can_reset(priv->pch_can_os_p);
+
+	return;
+}
+
+static int pch_can_do_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+	int ret = 0;
+
+	switch (mode) {
+	case CAN_MODE_START:
+		pch_can_start(ndev);
+		netif_wake_queue(ndev);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	return ret;
+}
+
+static int pch_can_get_state(const struct net_device *ndev,
+			     enum can_state *state)
+{
+	struct pch_can_priv *priv = netdev_priv(ndev);
+
+	*state = priv->can.state;
+	return 0;
+}
+
+static int get_baud_id(int baud_bps)
+{
+	int id;
+	switch (baud_bps) {
+	case 10000:/* 10kbps*/
+		id = PCH_CAN_BAUD_10;
+		break;
+	case 20000:
+		id = PCH_CAN_BAUD_20;
+		break;
+	case 50000:
+		id = PCH_CAN_BAUD_50;
+		break;
+	case 125000:
+		id = PCH_CAN_BAUD_125;
+		break;
+	case 250000:
+		id = PCH_CAN_BAUD_250;
+		break;
+	case 500000:
+		id = PCH_CAN_BAUD_500;
+		break;
+	case 800000:
+		id = PCH_CAN_BAUD_800;
+		break;
+	case 1000000:
+		id = PCH_CAN_BAUD_1000;
+		break;
+	default:
+		id = -1;
+	}
+	return id;
+}
+
+static int pch_set_bittiming(struct net_device *ndev)
+{
+	struct pch_can_priv *priv = netdev_priv(ndev);
+	struct pch_can_os *dev_can_os = priv->pch_can_os_p;
+	const struct can_bittiming *bt = &priv->can.bittiming;
+	struct pch_can_timing pch_can_timing_data;
+	int baurate_id;
+	enum pch_can_run_mode curr_mode;
+	int retval;
+
+	memset(&pch_can_timing_data, 0, sizeof(pch_can_timing_data));
+	pch_can_timing_data.bitrate = bt->bitrate/1000; /* bps to Kbps */
+	pch_can_timing_data.cfg_bitrate = (bt->tq) / (1000000/pch_can_clock);
+							/* Tq to BRP */
+	pch_can_timing_data.cfg_tseg1 = bt->phase_seg1;
+	pch_can_timing_data.cfg_tseg2 = bt->phase_seg2;
+	pch_can_timing_data.cfg_sjw = bt->sjw;
+	pch_can_timing_data.smpl_mode = bt->sample_point;
+	pch_can_timing_data.edge_mode = 0;
+
+	pch_can_get_run_mode(dev_can_os->can,
+				   &curr_mode, ndev);
+	if (curr_mode == PCH_CAN_RUN)
+		pch_can_set_run_mode(dev_can_os->can,
+					   PCH_CAN_STOP, ndev);
+
+	baurate_id = get_baud_id(bt->bitrate);
+	if (baurate_id == -1)
+		retval = pch_can_set_baud_custom(dev_can_os->can,
+							 &pch_can_timing_data);
+	else
+		retval = pch_can_set_baud_simple(dev_can_os->can, baurate_id);
+	if (curr_mode == PCH_CAN_RUN)
+		pch_can_set_run_mode(dev_can_os->can,
+					   PCH_CAN_RUN, ndev);
+
+	return 0;
+}
+
+static int pch_open(struct net_device *ndev)
+{
+	int err;
+	int retval;
+	int ret;
+	struct pch_can_priv *priv = netdev_priv(ndev);
+	struct pch_can_os *dev_can_os = priv->pch_can_os_p;
+
+	ret = mutex_lock_interruptible(&pch_can_mutex);
+	if (ret)
+		return -ERESTARTSYS;
+
+	retval = pch_can_open(dev_can_os->can,
+			      PCH_CAN_ACTIVE, PCH_CAN_FIXED_PRIORITY, ndev);
+	if (retval != 0) {
+		dev_err(&ndev->dev,
+			"%s -> pch_can_open failed (returned %d).\n",
+			__func__, retval);
+	} else {
+		dev_dbg(&ndev->dev,
+		    "%s -> pch_can_open invoked successfully (returned %d).\n",
+		    __func__, retval);
+
+		dev_can_os->rx_fifo = create_can_fifo(NUM_NODES, ndev);
+
+		if (!(dev_can_os->rx_fifo)) {
+			dev_err(&ndev->dev, "%s -> create_can_fifo failed.\n",
+								__func__);
+
+			pch_can_release(dev_can_os->can, ndev);
+			dev_dbg(&ndev->dev,
+				"%s -> pch_can_release invoked successfully.\n",
+				__func__);
+
+			retval = -EPERM;
+		} else {
+			dev_dbg(&ndev->dev,
+				"%s -> create_can_fifo invoked successfully.\n",
+				__func__);
+
+			/* Registering the callback function for
+						 interrupt handling. */
+			pch_can_entcb(pch_can_callback, dev_can_os, ndev);
+			dev_dbg(&ndev->dev,
+				"%s -> pch_can_entcb invoked successfully.\n",
+				__func__);
+
+			err = pci_enable_msi(dev_can_os->dev);
+			if (err != 0) {
+				priv->have_msi = 0;
+				dev_err(&ndev->dev, "Unable to allocate MSI "
+						"interrupt Error: %d\n", err);
+
+			} else {
+				priv->have_msi = 1;
+			}
+
+			/* Update IRQ value */
+			dev_can_os->irq = dev_can_os->dev->irq;
+			ndev->irq = dev_can_os->dev->irq;
+
+			/* Regsitering the interrupt. */
+			retval =
+			    request_irq(dev_can_os->dev->irq,
+					pch_can_handler, IRQF_SHARED,
+					ndev->name, dev_can_os
+			    );
+
+			if (retval != 0) {
+				pch_can_release(dev_can_os->can, ndev);
+				delete_can_fifo(dev_can_os->rx_fifo, ndev);
+				dev_can_os->rx_fifo = 0;
+				dev_can_os->can_callback = NULL;
+
+				dev_err(&ndev->dev,
+					"%s -> request_irq failed on irq %d"
+					"(returned %d).\n",
+					__func__, dev_can_os->irq, retval);
+			} else {
+				dev_dbg(&ndev->dev, "%s -> request_irq invoked "
+					"successfully(returned %d).\n",
+					__func__, retval);
+
+				/* Assuming that no bus off
+							 interrupt. */
+				dev_can_os->bus_off_interrupt = 0;
+				dev_can_os->write_wait_flag = 0;
+
+				/* Setting the block mode. */
+				dev_can_os->block_mode = 1;
+
+				dev_can_os->opened = 1;
+
+				/* Storing the can structure for further
+								 use. */
+				retval = 0;
+			}
+		}
+	}
+
+	/* Open common can device */
+	err = open_candev(ndev);
+	if (err) {
+		mutex_unlock(&pch_can_mutex);
+		dev_err(ndev->dev.parent, "open_candev() failed %d\n", err);
+		free_irq(ndev->irq, dev_can_os);
+		return err;
+	}
+
+	netif_start_queue(ndev);
+
+	mutex_unlock(&pch_can_mutex);
+	return 0;
+}
+
+static int pch_close(struct net_device *ndev)
+{
+	struct pch_can_priv *priv = netdev_priv(ndev);
+	struct pch_can_os *can_os = priv->pch_can_os_p;
+
+	netif_stop_queue(ndev);
+	close_candev(ndev);
+	free_irq(ndev->irq, can_os);
+	if (priv->have_msi != 0)
+		pci_disable_msi(can_os->dev);
+
+	delete_can_fifo(can_os->rx_fifo, ndev);
+	pch_can_release(can_os->can, ndev);
+	can_os->opened = 0;
+	can_os->rx_fifo = 0;
+	can_os->can_callback = NULL;
+
+	return 0;
+}
+
+static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	int err;		/* error variable. */
+	int ret;
+	struct pch_can_msg msg;	/* The message object for writing. */
+	struct pch_can_priv *priv = netdev_priv(ndev);
+	struct pch_can_os *can_os = priv->pch_can_os_p;
+	struct can_frame *canframe_dat = (struct can_frame *)skb->data;
+	struct net_device_stats *stats = &ndev->stats;
+
+	ret = mutex_lock_interruptible(&pch_can_mutex);
+	if (ret)
+		return -ERESTARTSYS;
+
+	/* Translate CAN core format to CAN PCH's HW format */
+	memset(&msg, 0, sizeof(msg));
+	msg.ide = canframe_dat->can_id & 0x80000000;
+	if (canframe_dat->can_id & 0x80000000) {
+		msg.ide = 1;
+		msg.id =  canframe_dat->can_id & 0x1fffffff;/* Extended
+								Message */
+	} else {
+		msg.ide = 0;
+		msg.id =  canframe_dat->can_id & 0x00000fff;/* Standard
+								Message */
+
+	}
+
+	msg.dlc = canframe_dat->can_dlc;
+	memcpy(&msg.data, canframe_dat->data, 8);
+
+	if (canframe_dat->can_id & 0x40000000)
+		msg.rtr = 1;
+	else
+		msg.rtr = 0;
+
+	/* If device suspended. */
+	if ((can_os->is_suspending) == 1) {
+		dev_err(&ndev->dev,
+				"%s -> Device is in suspend mode.\n", __func__);
+		dev_dbg(&ndev->dev, "%s returns %d\n", __func__, -EAGAIN);
+		err = -EAGAIN;
+		goto err_out;
+	}
+
+	can_put_echo_skb(skb, ndev, 0);
+	err = pch_can_msg_tx(can_os->can, &msg, ndev);
+
+	if ((err != 0)) {
+		/* Transmission failed due to unavailability of transmit object
+						 and it is block mode. */
+		if ((err == PCH_CAN_NO_TX_BUFF) && (can_os->block_mode == 1)) {
+			dev_dbg(&ndev->dev, "%s -> Waiting for "
+					"transmit message object.\n", __func__);
+
+			/* Transmitting again. */
+			err = pch_can_msg_tx(can_os->can, &msg, ndev);
+
+			/* If again error. */
+			if (err != 0) {
+				dev_err(&ndev->dev,
+				    "%s -> Transmit failed after 2 attempts.\n",
+				    __func__);
+				dev_dbg(&ndev->dev, "%s returns %d\n",
+							__func__, -EPERM);
+				err = -EPERM;
+				goto err_out;
+			}
+		} else {	/* If failed due to some other reasons. */
+			dev_err(&ndev->dev,
+			    "%s -> Write from CAN device failed %d.\n",
+			    __func__, -EIO);
+			dev_dbg(&ndev->dev, "%s returns %d\n", __func__, -EIO);
+			err = -EIO;
+			goto err_out;
+		}
+	}
+	dev_dbg(&ndev->dev,
+		"%s -> Message send for transmission successfully.\n"
+		"The transmitted Message is :\n"
+		"Msg ID   : 0x%x\n"
+		"EXT ID   : %hu\n"
+		"Msg Size : %hu\n"
+		"Rment    : %hu\n"
+		"Dat Byt1 : 0x%x\n"
+		"Dat Byt2 : 0x%x\n"
+		"Dat Byt3 : 0x%x\n"
+		"Dat Byt4 : 0x%x\n"
+		"Dat Byt5 : 0x%x\n"
+		"Dat Byt6 : 0x%x\n"
+		"Dat Byt7 : 0x%x\n"
+		"Dat Byt8 : 0x%x\n"
+		"Write from CAN device successful ( returns %d).",
+		__func__, msg.id, msg.ide, msg.dlc, msg.rtr, msg.data[0],
+		msg.data[1], msg.data[2], msg.data[3], msg.data[4], msg.data[5],
+		msg.data[6], msg.data[7], sizeof(struct pch_can_msg));
+
+	stats->tx_bytes += canframe_dat->can_dlc;
+	stats->tx_packets++;
+
+	mutex_unlock(&pch_can_mutex);
+	return NETDEV_TX_OK;
+
+err_out:
+	mutex_unlock(&pch_can_mutex);
+	return err;
+}
+
+static const struct net_device_ops pch_can_netdev_ops = {
+	.ndo_open		= pch_open,
+	.ndo_stop		= pch_close,
+	.ndo_start_xmit		= pch_xmit,
+};
+
+static void __devexit pch_can_remove(struct pci_dev *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct pch_can_priv *priv = netdev_priv(ndev);
+	struct pch_can_os *can_os = priv->pch_can_os_p;
+
+	unregister_candev(ndev);
+	pch_can_destroy(can_os->can, ndev);
+	pci_iounmap(pdev, (void *)priv->base);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	free_candev(priv->ndev);
+	can_free_echo_skb(ndev, 0);
+	platform_set_drvdata(pdev, NULL);
+}
+
+#ifdef CONFIG_PM
+static int pch_can_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int i;			/* Counter variable. */
+	int retval;		/* Return value. */
+/*      struct pch_can_os *can_os = pdev->dev.driver_data; */
+	struct pch_can_os *can_os =
+			(struct pch_can_os *) dev_get_drvdata(&pdev->dev);
+
+	/* If the device is opened get the current run mode. */
+	if (can_os->opened == 1) {
+		/* Save the Run Mode. */
+		pch_can_get_run_mode(can_os->can, &(can_os->run_mode),
+								can_os->ndev);
+	}
+
+	/* Stop the CAN controller */
+	pch_can_set_run_mode(can_os->can, PCH_CAN_STOP, can_os->ndev);
+
+	/* Indicate that we are aboutto/in suspend */
+	can_os->is_suspending = 1;
+
+	if (can_os->opened == 1) {
+		u32 buf_stat;	/* Variable for reading the transmit buffer
+								 status. */
+		u32 counter = 0xFFFFFF;
+
+		/*
+		   Waiting for all transmission to complete.
+		   This is done by checking the TXQST pending
+		    register. The loop teriminates when no
+		    transmission is pending.
+		 */
+		while (counter) {
+			buf_stat = pch_can_get_buffer_status(can_os->can);
+			if (buf_stat == 0)
+				break;
+
+			counter--;
+		}
+
+		if (counter > 0) {
+			dev_dbg(&pdev->dev,
+			    "%s -> No transmission is pending.\n", __func__);
+		} else {
+			dev_err(&pdev->dev,
+				"%s -> Transmission time out.\n", __func__);
+		}
+
+		/* Save interrupt configuration and then disable them */
+		pch_can_get_int_enables(can_os->can,
+					      &(can_os->int_enables));
+		pch_can_set_int_enables(can_os->can, CAN_DISABLE, can_os->ndev);
+
+		/* Save Tx buffer enable state */
+		for (i = 0; i < (pch_can_tx_buf_size + pch_can_rx_buf_size);
+									i++) {
+			if (pch_msg_obj_conf[i] == MSG_OBJ_TX) {
+				/* Here i is the index, however (i+1) is object
+								 number. */
+				pch_can_get_tx_enable(can_os->can,
+							(i + 1),
+							&(can_os->tx_enable[i]),
+							can_os->ndev);
+			}
+		}
+
+		/* Disable all Transmit buffers */
+		pch_can_tx_disable_all(can_os->can, can_os->ndev);
+
+		/* Save Rx buffer enable state */
+		for (i = 0; i < (pch_can_tx_buf_size + pch_can_rx_buf_size);
+									i++) {
+			if (pch_msg_obj_conf[i] == MSG_OBJ_RX) {
+				/* Here i is the index, however (i+1) is object
+								 number. */
+
+				pch_can_get_rx_enable(can_os->can,
+							(i + 1),
+							&(can_os->rx_enable[i]),
+							can_os->ndev);
+				pch_can_get_rx_buffer_link(can_os->can,
+							(i + 1),
+							&(can_os->rx_link[i]),
+							can_os->ndev);
+
+				/* Save Rx Filters */
+				can_os->rx_filter[i].num = (i + 1);
+				pch_can_get_rx_filter(can_os->can,
+							&(can_os->rx_filter[i]),
+							can_os->ndev);
+			}
+		}
+
+		/* Disable all Receive buffers */
+		pch_can_rx_disable_all(can_os->can, can_os->ndev);
+
+		/* Save Context */
+		pch_can_get_baud(can_os->can, &(can_os->timing));
+								/* Timing. */
+		pch_can_get_listen_mode(can_os->can,
+					&(can_os->listen_mode), can_os->ndev);
+							/* Listen mode  */
+		pch_can_get_arbiter_mode(can_os->can,
+					&(can_os->arbiter_mode), can_os->ndev);
+							/* Arbiter mode */
+
+	}
+
+	retval = pci_save_state(pdev);
+
+	if (retval != 0) {
+		/* Indicate that we have not suspended */
+		can_os->is_suspending = 0;
+
+		dev_err(&pdev->dev,
+			"%s -> pci_save_state failed(returned %d).\n",
+			__func__, retval);
+	} else {
+		dev_dbg(&pdev->dev,
+			"%s -> pci_save_state successful(returned %d).\n",
+			__func__, retval);
+
+		pci_enable_wake(pdev, PCI_D3hot, 0);
+		dev_dbg(&pdev->dev,
+		    "%s -> pci_enable_wake invoked successfully.\n", __func__);
+
+		pci_disable_device(pdev);
+		dev_dbg(&pdev->dev,
+		  "%s -> pci_disable_device invoked successfully.\n", __func__);
+
+		pci_set_power_state(pdev, pci_choose_state(pdev, state));
+		dev_dbg(&pdev->dev,
+		 "%s -> pci_set_power_state invoked successfully.\n", __func__);
+	}
+
+	dev_dbg(&pdev->dev, "%s returns %d.\n", __func__, retval);
+	return retval;
+}
+
+static int pch_can_resume(struct pci_dev *pdev)
+{
+	int i;			/* Counter variable. */
+	int retval;		/* Return variable. */
+	struct pch_can_os *can_os =
+			(struct pch_can_os *) dev_get_drvdata(&pdev->dev);
+
+	pci_set_power_state(pdev, PCI_D0);
+	dev_dbg(&pdev->dev,
+	    "pch_can_resume -> pci_set_power_state invoked successfully.\n");
+
+	pci_restore_state(pdev);
+	dev_dbg(&pdev->dev,
+		"pch_can_resume -> pci_restore_state invoked successfully.\n");
+
+	retval = pci_enable_device(pdev);
+	if (retval != 0) {
+		dev_err(&pdev->dev,
+		"pch_can_resume -> pci_enable_device failed(returned %d).\n",
+		retval);
+	}
+
+	else {
+		dev_dbg(&pdev->dev, "pch_can_resume -> pci_enable_device"
+				" invoked successfully(returned %d)\n", retval);
+		pci_enable_wake(pdev, PCI_D3hot, 0);
+
+		/* Disabling all interrupts. */
+		pch_can_set_int_enables(can_os->can, CAN_DISABLE, can_os->ndev);
+
+		/* Setting the CAN device in Stop Mode. */
+		pch_can_set_run_mode(can_os->can, PCH_CAN_STOP, can_os->ndev);
+
+		/* Configuring the transmit and receive buffers. */
+		pch_can_config_rx_tx_buffers(can_os->can, can_os->ndev);
+		dev_dbg(&pdev->dev, "pch_can_resume -> "
+			"pch_can_config_rx_tx_buffers invoked successfully.\n");
+
+		if (can_os->opened == 1) {
+			/* Restore the CAN state */
+			pch_can_set_baud_custom(can_os->can, &(can_os->timing));
+								/* Timing */
+			pch_can_set_listen_mode(
+				can_os->can, can_os->listen_mode, can_os->ndev);
+							/* Listen/Active */
+			pch_can_set_arbiter_mode(can_os->can,
+					can_os->arbiter_mode, can_os->ndev);
+							/* Arbiter mode */
+
+			/* Enabling the transmit buffer. */
+			for (i = 0;
+			     i < (pch_can_tx_buf_size + pch_can_rx_buf_size);
+									i++) {
+				if (pch_msg_obj_conf[i] == MSG_OBJ_TX) {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+					pch_can_set_tx_enable(can_os->can,
+							(i + 1),
+							can_os->tx_enable[i],
+							can_os->ndev);
+				}
+			}
+
+			/* Configuring the receive buffer and enabling them. */
+			for (i = 0;
+			     i < (pch_can_tx_buf_size + pch_can_rx_buf_size);
+									i++) {
+				if (pch_msg_obj_conf[i] == MSG_OBJ_RX) {
+					/* Here i is the index, however (i+1) is
+							 object number. */
+
+					/* Restore buffer link */
+					pch_can_set_rx_buffer_link(can_os->can,
+							(i + 1),
+							can_os->rx_link[i],
+							can_os->ndev);
+
+					/* Restore Rx Filters */
+					can_os->rx_filter[i].num = (i + 1);
+					pch_can_set_rx_filter(can_os->can,
+						       &(can_os->rx_filter[i]));
+
+					/* Restore buffer enables */
+					pch_can_set_rx_enable(can_os->can,
+							(i + 1),
+							can_os->rx_enable[i],
+							can_os->ndev);
+				}
+			}
+
+			/* Enable CAN Interrupts */
+			pch_can_set_int_custom(can_os->can,
+						     can_os->int_enables);
+
+			/* Restore Run Mode */
+			pch_can_set_run_mode(can_os->can,
+						can_os->run_mode, can_os->ndev);
+		}
+		/* if opened */
+		can_os->is_suspending = 0;
+	}			/* else */
+
+	dev_dbg(&pdev->dev, "pch_can_resume returns %d\n", retval);
+	return retval;
+}
+#else
+#define pch_can_suspend NULL
+#define pch_can_resume NULL
+#endif
+
+static int __devinit pch_can_probe(struct pci_dev *pdev,
+				   const struct pci_device_id *id)
+{
+	struct net_device *ndev;
+	struct pch_can_priv *priv;
+	unsigned int can_num = 0;	/* Variable to denote the CAN */
+	int rc;
+	int index;
+
+	ndev = alloc_candev(sizeof(struct pch_can_priv), 1);
+	if (!ndev)
+		return -ENOMEM;
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	priv = netdev_priv(ndev);
+
+	priv->ndev = ndev;
+
+	priv->can.bittiming_const = &pch_can_bittiming_const;
+	priv->can.do_set_bittiming = &pch_set_bittiming;
+	priv->can.do_set_mode = pch_can_do_set_mode;
+	priv->can.do_get_state = pch_can_get_state;
+	priv->can.clock.freq = pch_can_clock * 1000;
+					/* Unit is Hz(pch_can_clock is KHz) */
+	priv->pch_can_os_p = &can_os[can_num];
+	ndev->flags |= (IFF_NOARP | IFF_ECHO);
+	platform_set_drvdata(pdev, ndev);
+	ndev->netdev_ops = &pch_can_netdev_ops;
+	rc = pci_enable_device(pdev);
+	if (rc)
+		goto err_out_free;
+
+	rc = pci_request_regions(pdev, DRIVER_NAME);
+	if (rc)
+		goto err_out_disable;
+
+	can_os[can_num].pci_remap = pci_iomap(pdev, 1, 0);
+	if (can_os[can_num].pci_remap == 0) {
+		rc = -EIO;
+		goto err_out_res;
+	}
+
+	/* Creating the device handle denoting the remap base address. */
+	can_os[can_num].can = pch_can_create((void *)can_os[can_num].pci_remap,
+									ndev);
+
+	/* If handle creation fails. */
+	if (can_os[can_num].can == 0) {
+		dev_err(&pdev->dev,
+			"%s -> pch_can_create failed.\n", __func__);
+		rc = -EPERM;
+		goto err_out_iomap;
+	}
+
+	/* Can number (index to the structure) */
+	can_os[can_num].can_num = can_num;
+	can_os[can_num].irq = pdev->irq;/* IRQ allocated to this device. */
+	ndev->irq = pdev->irq;
+	can_os[can_num].dev = pdev;/* Reference to pci_device structure. */
+	can_os[can_num].opened = 0;/* Open flag denoting the device usage. */
+	can_os[can_num].is_suspending = 0;/* Flag denoting the suspend stage. */
+	can_os[can_num].ndev = ndev;
+
+	priv->base = (void *)can_os[can_num].pci_remap;
+
+	for (index = 0; index < pch_can_rx_buf_size;)
+		pch_msg_obj_conf[index++] = MSG_OBJ_RX;
+
+	for (index = index;
+	     index < (pch_can_rx_buf_size + pch_can_tx_buf_size);)
+		pch_msg_obj_conf[index++] = MSG_OBJ_TX;
+
+	rc = register_candev(ndev);
+	if (rc)
+		goto err_out_reg_candev;
+
+	return 0;
+
+err_out_reg_candev:
+	pch_can_destroy(can_os->can, ndev);
+err_out_iomap:
+	pci_iounmap(pdev, (void *)can_os[can_num].pci_remap);
+err_out_res:
+	pci_release_regions(pdev);
+err_out_disable:
+	pci_disable_device(pdev);
+err_out_free:
+	free_candev(ndev);
+
+	return rc;
+}
+
+static struct pci_driver pch_can_pcidev = {
+	.name = MODULE_NAME,
+	.id_table = pch_can_pcidev_id,
+	.probe = pch_can_probe,
+	.remove = __devexit_p(pch_can_remove),
+	.suspend = pch_can_suspend,
+	.resume = pch_can_resume,
+};
+
+static int __init pch_can_pci_init(void)
+{
+	return pci_register_driver(&pch_can_pcidev);
+}
+
+static void __exit pch_can_pci_exit(void)
+{
+	/* Unregistering the registered PCI Driver. */
+	pci_unregister_driver(&pch_can_pcidev);
+}
+
+MODULE_DESCRIPTION("Controller Area Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.94");
+
+module_param_named(pch_can_rx_buf_size, pch_can_rx_buf_size, int, 444);
+module_param_named(pch_can_tx_buf_size, pch_can_tx_buf_size, int, 444);
+module_param_named(pch_can_clock, pch_can_clock, int, 444);
+MODULE_DEVICE_TABLE(pci, pch_can_pcidev_id);
+
+module_init(pch_can_pci_init);
+module_exit(pch_can_pci_exit);
diff --git a/drivers/net/can/pch_can.h b/drivers/net/can/pch_can.h
new file mode 100644
index 0000000..88a9559
--- /dev/null
+++ b/drivers/net/can/pch_can.h
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __PCH_CAN_H__
+#define __PCH_CAN_H__
+
+#define MAX_CAN_DEVICES		1
+#define MAX_BITRATE		0x3e8
+#define NUM_NODES		2000	/* Maximum number of
+						 Software FIFO nodes. */
+#define MAX_MSG_OBJ		32
+#define MSG_OBJ_RX		0 /* The receive message object flag. */
+#define MSG_OBJ_TX		1 /* The transmit message object flag. */
+
+#define ENABLE			1 /* The enable flag */
+#define DISABLE			0 /* The disable flag */
+#define CAN_CTRL_INIT		0x0001 /* The INIT bit of CANCONT register. */
+#define CAN_CTRL_IE		0x0002 /* The IE bit of CAN control register */
+#define CAN_CTRL_SIE		0x0004
+#define CAN_CTRL_EIE		0x0008
+#define CAN_CTRL_DAR		0x0020
+#define CAN_CTRL_IE_SIE_EIE	0x000e
+#define CAN_CTRL_CCE		0x0040
+#define CAN_CTRL_OPT		0x0080 /* The OPT bit of CANCONT register. */
+#define CAN_OPT_SILENT		0x0008 /* The Silent bit of CANOPT register. */
+#define CAN_CMASK_RX_TX_SET	0x00f3
+#define CAN_CMASK_RX_TX_GET	0x0073
+#define CAN_CMASK_ALL		0xff
+#define CAN_CMASK_RDWR		0x80
+#define CAN_CMASK_ARB		0x20
+#define CAN_CMASK_CTRL		0x10
+#define CAN_CMASK_MASK		0x40
+#define CAN_CMASK_CLPNT		0x08
+
+#define CAN_CMASK_NEWINT	0x04 /* The TxRqst/NewDat bit for the CMASK
+					register. */
+
+#define CAN_IF_MCONT_NEWDAT	0x8000 /* The NewDat bit of the MCONT
+					  register. */
+
+#define CAN_IF_MCONT_INTPND	0x2000 /* The IntPnd bit of the MCONT
+					  register. */
+
+#define CAN_IF_MCONT_UMASK		0x1000
+#define CAN_IF_MCONT_TXIE		0x0800
+#define CAN_IF_MCONT_RXIE		0x0400
+#define CAN_IF_MCONT_RMTEN		0x0200
+#define CAN_IF_MCONT_TXRQXT		0x0100
+#define CAN_IF_MCONT_EOB		0x0080
+#define CAN_IF_MCONT_MSGLOST		0x4000
+#define CAN_MASK2_MDIR_MXTD		0xc000
+#define CAN_ID2_MSGVAL_XTD_DIR		0xe000
+#define CAN_ID2_MSGVAL_DIR		0xa000
+#define CAN_ID2_DIR			0x2000
+#define CAN_ID_MSGVAL			0x8000
+#define CAN_IF_MASK2_MDIR		((u32)1 << 14)
+#define CAN_IF_MASK2_MXTD		((u32)1 << 15)
+
+#define CAN_STATUS_INT			0x8000 /* The status interrupt value of
+						  the CAN device. */
+
+#define CAN_IF_CREQ_BUSY		0x8000 /* The Busy flag bit of the CREQ
+						  register. */
+
+#define CAN_ID2_XTD			0x4000 /* The Xtd bit of ID2
+						  register. */
+
+#define CAN_SRST_BIT			0x0001
+#define CAN_CONT_OFFSET			0x00	/*Can Control register */
+#define CAN_STAT_OFFSET			0x04
+#define CAN_ERRC_OFFSET			0x08
+#define CAN_BITT_OFFSET			0x0c
+#define CAN_INT_OFFSET			0x010
+#define CAN_OPT_OFFSET			0x14	/*Extended function register */
+#define CAN_BRPE_OFFSET			0x18
+
+/* Message interface one (IF1) registers */
+#define CAN_IF1_CREQ_OFFSET		0x020
+#define CAN_IF1_CMASK_OFFSET		0x024
+#define CAN_IF1_ID1_OFFSET		0x030
+#define CAN_IF1_ID2_OFFSET		0x034
+#define CAN_IF1_MCONT_OFFSET		0x038
+#define CAN_IF1_DATAA1_OFFSET		0x03C
+#define CAN_IF1_DATAA2_OFFSET		0x040
+#define CAN_IF1_DATAB1_OFFSET		0x044
+#define CAN_IF1_DATAB2_OFFSET		0x048
+#define CAN_IF1_MASK1_OFFSET		0x028
+#define CAN_IF1_MASK2_OFFSET		0x02c
+#define CAN_IF2_CREQ_OFFSET		0x080
+#define CAN_IF2_CMASK_OFFSET		0x084
+#define CAN_IF2_ID1_OFFSET		0x090
+#define CAN_IF2_ID2_OFFSET		0x094
+#define CAN_IF2_MCONT_OFFSET		0x098
+#define CAN_IF2_DATAA1_OFFSET		0x09c
+#define CAN_IF2_DATAA2_OFFSET		0x0a0
+#define CAN_IF2_DATAB1_OFFSET		0x0a4
+#define CAN_IF2_DATAB2_OFFSET		0x0a8
+#define CAN_IF2_MASK1_OFFSET		0x088
+#define CAN_IF2_MASK2_OFFSET		0x08c
+#define CAN_TREQ1_OFFSET		0x100
+#define CAN_TREQ2_OFFSET		0x104
+#define CAN_SRST_OFFSET			0x1FC
+#define BIT_SHIFT_ONE			1
+#define BIT_SHIFT_TWO			2
+#define BIT_SHIFT_THREE			3
+#define BIT_SHIFT_FOUR			4
+#define BIT_SHIFT_FIVE			5
+#define BIT_SHIFT_SIX			6
+#define BIT_SHIFT_SEVEN			7
+#define BIT_SHIFT_EIGHT			8
+#define BIT_SHIFT_TWELVE		12
+#define BIT_SHIFT_THIRTEEN		13
+#define BIT_SHIFT_FOURTEEN		14
+#define BIT_SHIFT_FIFTEEN		15
+#define BIT_SHIFT_SIXTEEN		16
+
+/* bit position of certain controller bits. */
+#define BIT_BITT_BRP			0
+#define BIT_BITT_SJW			6
+#define BIT_BITT_TSEG1			8
+#define BIT_BITT_TSEG2			12
+#define BIT_IF1_MCONT_RXIE		10
+#define BIT_IF2_MCONT_TXIE		11
+#define BIT_BRPE_BRPE			6
+#define BIT_ES_TXERRCNT			0
+#define BIT_ES_RXERRCNT			8
+#define MSK_BITT_BRP			0x3f
+#define MSK_BITT_SJW			0xc0
+#define MSK_BITT_TSEG1			0xf00
+#define MSK_BITT_TSEG2			0x7000
+#define MSK_BRPE_BRPE			0x3c0
+#define MSK_BRPE_GET			0x0f
+#define MSK_CTRL_IE_SIE_EIE		0x07
+#define MSK_MCONT_TXIE			0x08
+#define MSK_MCONT_RXIE			0x10
+#define MSK_ALL_THREE			0x07
+#define MSK_ALL_FOUR			0x0f
+#define MSK_ALL_EIGHT			0xff
+#define MSK_ALL_ELEVEN			0x7ff
+#define MSK_ALL_THIRTEEN		0x1fff
+#define MSK_ALL_SIXTEEN			0xffff
+
+/* Error */
+#define MSK_ES_TXERRCNT	((u32)0xff << BIT_ES_TXERRCNT)	/* Tx err count */
+#define MSK_ES_RXERRCNT	((u32)0x7f << BIT_ES_RXERRCNT)	/* Rx err count */
+
+#define PCH_CAN_BIT_SET(reg, bitmask)	\
+		(iowrite32((ioread32((reg)) | ((u32)(bitmask))), (reg)))
+#define PCH_CAN_BIT_CLEAR(reg, bitmask)	\
+		(iowrite32((ioread32((reg)) & ~((u32)(bitmask))), (reg)))
+
+#define PCH_CAN_NO_TX_BUFF		1 /* The flag value for denoting the
+					     unavailability of the transmit
+					     message object. */
+
+#define ERROR_COUNT			96
+#define PCH_CAN_MSG_DATA_LEN		8	/* CAN Msg data length */
+
+#define PCH_CAN_FIFO_NOT_EMPTY		0
+#define PCH_CAN_FIFO_EMPTY		1
+#define PCH_CAN_FIFO_FULL		2
+#define PCH_CAN_NULL			NULL
+
+#define PCI_DEVICE_ID_INTEL_PCH1_CAN	0x8818
+#define DRIVER_NAME			"can"
+
+#define PCH_CAN_CLOCK_DEFAULT_OFFSET	0
+#define PCH_CAN_CLOCK_62_5_OFFSET	0
+#define PCH_CAN_CLOCK_24_OFFSET		8
+#define PCH_CAN_CLOCK_50_OFFSET		16
+
+#define COUNTER_LIMIT 0xFFFF
+
+#define MODULE_NAME "pch_can"
+
+enum pch_can_listen_mode {
+	PCH_CAN_ACTIVE = 0,
+	PCH_CAN_LISTEN
+};
+
+enum pch_can_run_mode {
+	PCH_CAN_STOP = 0,
+	PCH_CAN_RUN
+};
+
+enum pch_can_arbiter {
+	PCH_CAN_ROUND_ROBIN = 0,
+	PCH_CAN_FIXED_PRIORITY
+};
+
+enum pch_can_auto_restart {
+	CAN_MANUAL = 0,
+	CAN_AUTO
+};
+
+enum pch_can_baud {
+	PCH_CAN_BAUD_10 = 0,
+	PCH_CAN_BAUD_20,
+	PCH_CAN_BAUD_50,
+	PCH_CAN_BAUD_125,
+	PCH_CAN_BAUD_250,
+	PCH_CAN_BAUD_500,
+	PCH_CAN_BAUD_800,
+	PCH_CAN_BAUD_1000
+};
+
+enum pch_can_interrupt {
+	CAN_ENABLE,
+	CAN_DISABLE,
+	CAN_ALL,
+	CAN_NONE
+};
+
+/**
+ * struct pch_can_msg - CAN message structure
+ * @ide:	Standard/extended msg
+ * @id:		11 or 29 bit msg id
+ * @dlc:	Size of data
+ * @data:	Message pay load
+ * @rtr:	RTR message
+ */
+struct pch_can_msg {
+	unsigned short ide;
+	unsigned int id;
+	unsigned short dlc;
+	unsigned char data[PCH_CAN_MSG_DATA_LEN];
+	unsigned short rtr;
+};
+
+/**
+ * pch_can_timing - CAN bittiming structure
+ * @bitrate:	Bitrate (kbps)
+ * @cfg_bitrate:	Bitrate
+ * @cfg_tseg1:	Tseg1
+ * @cfg_tseg2:	Tseg2
+ * @cfg_sjw:	Sync jump width
+ * @smpl_mode:	Sampling mode
+ * @edge_mode:	Edge R / D
+ */
+struct pch_can_timing {
+	unsigned int bitrate;
+	unsigned int cfg_bitrate;
+	unsigned int cfg_tseg1;
+	unsigned int cfg_tseg2;
+	unsigned int cfg_sjw;
+	unsigned int smpl_mode;
+	unsigned int edge_mode;
+};
+
+/**
+ * struct pch_can_error - CAN error structure
+ * @rxgte96:	Rx err cnt >=96
+ * @txgte96:	Tx err cnt >=96
+ * @error_stat:	Error state of CAN node,
+ *		00=error active (normal)
+ *		01=error passive
+ *		1x=bus off
+ * @rx_err_cnt:	Rx error count
+ * @tx_err_cnt:	Tx error count
+ */
+struct pch_can_error {
+	unsigned int rxgte96;
+	unsigned int txgte96;
+	unsigned int error_stat;
+	unsigned int rx_err_cnt;
+	unsigned int tx_err_cnt;
+};
+
+/**
+ * struct pch_can_acc_filter - CAN Filter structure
+ * @id:		The id/mask data
+ * @id_ext:	Standard/extended ID
+ * @rtr:	RTR message
+ */
+struct pch_can_acc_filter {
+	unsigned int id;
+	unsigned int id_ext;
+	unsigned int rtr;
+};
+
+/**
+ * struct pch_can_rx_filter - CAN RX filter
+ * @num:	Filter number
+ * @umask:	UMask value
+ * @amr:	Acceptance Mask Reg
+ * @aidr:	Acceptance Control Reg
+ */
+struct pch_can_rx_filter {
+	unsigned int num;
+	unsigned int umask;
+	struct pch_can_acc_filter amr;
+	struct pch_can_acc_filter aidr;
+};
+
+/**
+ * struct pch_can_os - structure to store the CAN device information.
+ * @can:		CAN: device handle
+ * @opened:		Linux opened device
+ * @can_num:		Linux: CAN Number
+ * @pci_remap:		Linux: MMap regs
+ * @dev:		Linux: PCI Device
+ * @irq:		Linux: IRQ
+ * @block_mode:		Blocking / non-blocking
+ * @rx_fifo:		Rx FIFO
+ * @read_wait_queue:	Linux: Read wait queue
+ * @write_wait_queue:	Linux: Write wait queue
+ * @write_wait_flag:	Linux: Write wait flag
+ * @read_wait_flag:	Linux: Read wait flag
+ * @open_spinlock:	Linux: Open lock variable
+ * @is_suspending:	Linux: Is suspending state
+ * @inode:		Linux: inode
+ * @timing:		CAN: timing
+ * @run_mode:		CAN: run mode
+ * @listen_mode:	CAN: listen mode
+ * @arbiter_mode:	CAN: arbiter mode
+ * @tx_enable:		CAN: Tx buffer state
+ * @rx_enable:		CAN: Rx buffer state
+ * @rx_link:		CAN: Rx link set
+ * @int_enables:	CAN: ints enabled
+ * @int_stat:		CAN: int status
+ * @bus_off_interrupt:	CAN: Buss off int flag
+ * @rx_filter:		CAN: Rx filters
+ * @can_callback:	CAN: callback function pointer
+ * @ndev:		net_device pointer
+ * @tx_spinlock:	CAN: transmission lock variable
+ */
+struct pch_can_os {
+	int can;
+	unsigned int opened;
+	unsigned int can_num;
+	void __iomem *pci_remap;
+	struct pci_dev *dev;
+	unsigned int irq;
+	int block_mode;
+	int rx_fifo;
+	wait_queue_head_t read_wait_queue;
+	wait_queue_head_t write_wait_queue;
+	unsigned int write_wait_flag;
+	unsigned int read_wait_flag;
+	spinlock_t open_spinlock;
+	unsigned int is_suspending;
+	struct inode *inode;
+	struct pch_can_timing timing;
+	enum pch_can_run_mode run_mode;
+	enum pch_can_listen_mode listen_mode;
+	enum pch_can_arbiter arbiter_mode;
+	unsigned int tx_enable[MAX_MSG_OBJ];
+	unsigned int rx_enable[MAX_MSG_OBJ];
+	unsigned int rx_link[MAX_MSG_OBJ];
+	unsigned int int_enables;
+	unsigned int int_stat;
+	unsigned int bus_off_interrupt;
+	struct pch_can_rx_filter rx_filter[MAX_MSG_OBJ];
+	void (*can_callback) (struct pch_can_os *);
+	struct net_device *ndev;
+	spinlock_t tx_spinlock;
+};
+
+/**
+ * struct pch_can_priv - CAN driver private data structure
+ * @can:		MUST be first member/field
+ * @ndev:		Pointer to net_device structure
+ * @clk:		unused
+ * @base:		Base address
+ * @scc_ram_offset:	unused
+ * @hecc_ram_offset:	unused
+ * @mbx_offset:		unused
+ * @int_line:		unused
+ * @mbx_lock:		unused
+ * @tx_head:		unused
+ * @tx_tail:		unused
+ * @rx_next:		unused
+ * @pch_can_os_p:	Pointer to CAN device information
+ * @have_msi:		PCI MSI mode flag
+ *
+ * Longer description of this structure.
+ */
+struct pch_can_priv {
+	struct can_priv can;
+	struct net_device *ndev;
+	struct clk *clk;
+	void __iomem *base;
+	u32 scc_ram_offset;
+	u32 hecc_ram_offset;
+	u32 mbx_offset;
+	u32 int_line;
+	spinlock_t mbx_lock;
+	u32 tx_head;
+	u32 tx_tail;
+	u32 rx_next;
+	struct pch_can_os *pch_can_os_p;
+	unsigned int have_msi;
+};
+
+/**
+ * struct can_fifo_item - FIFO Item structure
+ * @msg:	The msg object
+ * @next:	The next pointer
+ */
+struct can_fifo_item {
+	struct pch_can_msg msg;
+	struct can_fifo_item *next;
+};
+
+/**
+ * struct can_fifo - CAN FIFO structure
+ * @head:	The node where insertion can be done
+ * @tail:	The node where reading can be done
+ * @size:	The number of FIFO nodes
+ */
+struct can_fifo {
+	struct can_fifo_item *head;
+	struct can_fifo_item *tail;
+	unsigned int size;
+};
+
+/* This structure defines format for the storage of base address */
+struct can_hw {
+	void __iomem *io_base;
+};
+#endif /* __PCH_CAN_H__ */
-- 1.6.0.6


[-- Attachment #1.2: Type: text/html, Size: 130674 bytes --]

[-- Attachment #2: Type: text/plain, Size: 163 bytes --]

_______________________________________________
MeeGo-dev mailing list
MeeGo-dev-WXzIur8shnEAvxtiuMwx3w@public.gmane.org
http://lists.meego.com/listinfo/meego-dev

^ permalink raw reply related	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2010-09-15 12:10 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-11  0:25 [MeeGo-Dev][PATCH] Topcliff: Update PCH_CAN driver to 2.6.35 Masayuki Ohtak
     [not found] ` <4C61EDE5.4030505-ECg8zkTtlr0C6LszWs/t0g@public.gmane.org>
2010-08-11 10:37   ` Daniel Baluta
2010-08-12  1:42     ` Wang, Qi
2010-08-12  2:04       ` Greg KH
2010-08-12  2:13         ` Wang, Qi
     [not found]         ` <20100812020414.GD14121-l3A5Bk7waGM@public.gmane.org>
2010-08-12  6:25           ` Oliver Hartkopp
2010-08-12  6:29             ` Wang, Qi
2010-08-12  2:39       ` Masayuki Ohtake
     [not found]       ` <D5AB6E638E5A3E4B8F4406B113A5A19A28EA26EB-QQHDSDV1ERZpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2010-08-12  5:17         ` Daniel Baluta
2010-08-12  9:03         ` Wolfgang Grandegger
2010-08-13  0:23           ` Wang, Qi
     [not found]             ` <D5AB6E638E5A3E4B8F4406B113A5A19A28EA2AB1-QQHDSDV1ERZpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2010-08-13  6:11               ` Daniel Baluta
2010-08-13 10:58               ` Wolfgang Grandegger
2010-08-20  6:01                 ` Masayuki Ohtake
     [not found]                   ` <000f01cb402d$34b675b0$66f8800a-a06+6cuVnkTSQfdrb5gaxUEOCMrvLtNR@public.gmane.org>
2010-08-20  7:59                     ` Wolfgang Grandegger
2010-08-20  8:37                       ` Masayuki Ohtake
2010-08-11 12:31   ` Wolfgang Grandegger
     [not found]     ` <D5AB6E638E5A3E4B8F4406B113A5A19A28EA26CC@shsmsx501.ccr.corp.intel.com>
     [not found]       ` <4C63B6C9.5050804@grandegger.com>
     [not found]         ` <D5AB6E638E5A3E4B8F4406B113A5A19A28EA29DF@shsmsx501.ccr.corp.intel.com>
2010-09-01  7:45           ` Masayuki Ohtake
2010-09-01 17:04             ` out-of-order tx objects - was " Oliver Hartkopp
2010-09-01 17:04               ` Oliver Hartkopp
2010-09-01 18:51             ` Wolfgang Grandegger
2010-09-01 18:51               ` Wolfgang Grandegger
2010-09-02  3:19               ` Masayuki Ohtake
2010-09-02  3:19                 ` Masayuki Ohtake
2010-09-02  6:32                 ` Wolfgang Grandegger
2010-09-02  6:32                   ` Wolfgang Grandegger
2010-08-11 13:04   ` Marc Kleine-Budde
2010-09-13 12:07     ` Masayuki Ohtake
     [not found]       ` <005f01cb533e$5c21d530$66f8800a-a06+6cuVnkTSQfdrb5gaxUEOCMrvLtNR@public.gmane.org>
2010-09-13 12:29         ` Marc Kleine-Budde
2010-09-14  0:46           ` Masayuki Ohtake
2010-09-14  7:08             ` Marc Kleine-Budde
     [not found]             ` <003a01cb53a6$4ca724d0$66f8800a-a06+6cuVnkTSQfdrb5gaxUEOCMrvLtNR@public.gmane.org>
2010-09-15  7:42               ` Wolfgang Grandegger
     [not found]                 ` <4C9078D3.50300-5Yr1BZd7O62+XT7JhA+gdA@public.gmane.org>
2010-09-15  9:42                   ` Oliver Hartkopp
2010-09-15 10:55                     ` Wolfgang Grandegger
2010-09-15 12:04                       ` Marc Kleine-Budde
2010-09-15 12:11                         ` Wolfgang Grandegger
2010-09-13 15:22         ` Greg KH
2010-09-14  8:48           ` Masayuki Ohtake
     [not found]             ` <00ca01cb53e9$a50c1930$66f8800a-a06+6cuVnkTSQfdrb5gaxUEOCMrvLtNR@public.gmane.org>
2010-09-14 13:10               ` Greg KH
2010-09-15  1:21                 ` Masayuki Ohtake

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.