lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 10 Jan 2012 17:58:32 -0800
From:	Darren Hart <dvhart@...ux.intel.com>
To:	"lkml, " <linux-kernel@...r.kernel.org>
CC:	Masayuki Ohtake <masa-korg@....okisemi.com>,
	Wang Qi <qi.wang@...el.com>
Subject: Porting pch_pcieqos to 3.2 for Intel EG20T with no MAC

I find myself with a development board with no MAC address for the pch_gbe in
the Platform Controller Hub EG20T. I've dusted off an old patch and am trying
to get it working so it can be included upstream.

I found the phub_util_mac utility on sourceforge which appears to require the
following patch:

http://git.yoctoproject.org/cgit/cgit.cgi/meta-extras/plain/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-pch-pcieqos.patch

I've made the obvious changes to the driver to use unlocked_ioctl as ioctl has
been removed upstream. With this driver built and installed, the
topcliff_mac_util command reports no errors and reads the MAC address as:

00:00:00:00:00:00

Trying to set it reports no errors either, and the instrumentation suggests it
is at least trying to write the correct data. Reading back still results in all
zeros.

During boot, the pch_gbe driver reports:
[    2.211233] pch_gbe 0000:02:00.1: enabling device (0000 -> 0003)
[    2.217271] pch_gbe 0000:02:00.1: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[    2.224349] pch_gbe 0000:02:00.1: setting latency timer to 64
[    2.233388] pch_gbe 0000:02:00.1: Invalid MAC Address
[    2.238821] pch_gbe 0000:02:00.1: PCI INT A disabled
[    2.243809] pch_gbe: probe of 0000:02:00.1 failed with error -5

The patch itself follows, I have attached a rather lengthy log which includes a
read/write/read cycle demonstrating the write not taking effect.

Can you shed some light on why this might be the case?

Thanks,

Darren Hart


>From 53b8f7b9033e374be3edaa4ea620069bdfa4aebb Mon Sep 17 00:00:00 2001
Message-Id: <53b8f7b9033e374be3edaa4ea620069bdfa4aebb.1326246553.git.dvhart@...ux.intel.com>
From: Darren Hart <dvhart@...ux.intel.com>
Date: Mon, 9 Jan 2012 13:51:20 -0800
Subject: [PATCH] OKI Semiconductor PCH PCIEQOS driver

This driver implements PCH PCIEQOS controls for PCH.

Signed-off-by: Masayuki Ohtake <masa-korg@....okisemi.com>
Acked-by: Wang Qi <qi.wang@...el.com>

Ported to 3.2 from 2.6.34 by Darren Hart.

Signed-off-by: Darren Hart <dvhart@...ux.intel.com>
---
 drivers/char/Kconfig                       |    7 +
 drivers/char/Makefile                      |    2 +
 drivers/char/pch_pcieqos/Makefile          |    9 +
 drivers/char/pch_pcieqos/pch_common.h      |  146 ++++++++
 drivers/char/pch_pcieqos/pch_debug.h       |   60 +++
 drivers/char/pch_pcieqos/pch_pcieqos.c     |  400 ++++++++++++++++++++
 drivers/char/pch_pcieqos/pch_pcieqos.h     |  193 ++++++++++
 drivers/char/pch_pcieqos/pch_pcieqos_hal.c |  550 ++++++++++++++++++++++++++++
 drivers/char/pch_pcieqos/pch_pcieqos_hal.h |  125 +++++++
 drivers/char/pch_pcieqos/pch_pcieqos_pci.c |  523 ++++++++++++++++++++++++++
 10 files changed, 2015 insertions(+), 0 deletions(-)
 create mode 100644 drivers/char/pch_pcieqos/Makefile
 create mode 100644 drivers/char/pch_pcieqos/pch_common.h
 create mode 100644 drivers/char/pch_pcieqos/pch_debug.h
 create mode 100644 drivers/char/pch_pcieqos/pch_pcieqos.c
 create mode 100644 drivers/char/pch_pcieqos/pch_pcieqos.h
 create mode 100644 drivers/char/pch_pcieqos/pch_pcieqos_hal.c
 create mode 100644 drivers/char/pch_pcieqos/pch_pcieqos_hal.h
 create mode 100644 drivers/char/pch_pcieqos/pch_pcieqos_pci.c

diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 4364303..1a44568 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -627,5 +627,12 @@ config TILE_SROM
 	  device appear much like a simple EEPROM, and knows
 	  how to partition a single ROM for multiple purposes.
 
+config PCH_PCIEQOS
+       tristate "PCH PCIEQOS"
+       depends on PCI
+       help
+         If you say yes to this option, support will be included for the
+         PCH PCIEQOS Host controller.
+
 endmenu
 
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 32762ba..1163576 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -65,3 +65,5 @@ obj-$(CONFIG_JS_RTC)		+= js-rtc.o
 js-rtc-y = rtc.o
 
 obj-$(CONFIG_TILE_SROM)		+= tile-srom.o
+
+obj-$(CONFIG_PCH_PCIEQOS)	+= pch_pcieqos/
diff --git a/drivers/char/pch_pcieqos/Makefile b/drivers/char/pch_pcieqos/Makefile
new file mode 100644
index 0000000..8024021
--- /dev/null
+++ b/drivers/char/pch_pcieqos/Makefile
@@ -0,0 +1,9 @@
+ifeq ($(CONFIG_PCIEQOS_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_PCH_PCIEQOS) += pch_pcieqos_drv.o
+#to set CAN clock to 50Mhz
+EXTRA_CFLAGS+=-DIOH_CAN_PCLK_50MHZ
+
+pch_pcieqos_drv-objs := pch_pcieqos.o pch_pcieqos_pci.o pch_pcieqos_hal.o
diff --git a/drivers/char/pch_pcieqos/pch_common.h b/drivers/char/pch_pcieqos/pch_common.h
new file mode 100644
index 0000000..10526b2
--- /dev/null
+++ b/drivers/char/pch_pcieqos/pch_common.h
@@ -0,0 +1,146 @@
+/*!
+ * @file ioh_common.h
+ * @brief Provides the macro definitions used by all files.
+ * @version 1.0.0.0
+ * @section
+ * 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.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_COMMON_H__
+#define __IOH_COMMON_H__
+
+/*! @ingroup	Global
+@def		    IOH_WRITE8
+@...ef			Macro for writing 8 bit data to an io/mem address
+*/
+#define IOH_WRITE8(val, addr)   iowrite8((val), (void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_LOG
+@...ef			Macro for writing 16 bit data to an io/mem address
+*/
+#define IOH_WRITE16(val, addr)  iowrite16((val), (void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_LOG
+@...ef			Macro for writing 32 bit data to an io/mem address
+*/
+#define IOH_WRITE32(val, addr)  iowrite32((val), (void __iomem *)(addr))
+
+/*! @ingroup	Global
+@def		    IOH_READ8
+@...ef			Macro for reading 8 bit data from an io/mem address
+*/
+#define IOH_READ8(addr)   ioread8((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_READ16
+@...ef			Macro for reading 16 bit data from an io/mem address
+*/
+#define IOH_READ16(addr)  ioread16((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_READ32
+@...ef			Macro for reading 32 bit data from an io/mem address
+*/
+#define IOH_READ32(addr)  ioread32((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_WRITE32_F
+@...ef			Macro for writing 32 bit data to an io/mem address
+*/
+#define IOH_WRITE32_F(val, addr) do \
+	{ IOH_WRITE32((val), (addr)); (void)IOH_READ32((addr)); } while (0);
+
+/*! @ingroup	Global
+@def		    IOH_WRITE_BYTE
+@...ef			Macro for writing 1 byte data to an io/mem address
+*/
+#define IOH_WRITE_BYTE IOH_WRITE8
+/*! @ingroup	Global
+@def		    IOH_WRITE_WORD
+@...ef			Macro for writing 1 word data to an io/mem address
+*/
+#define IOH_WRITE_WORD IOH_WRITE16
+/*! @ingroup	Global
+@def		    IOH_WRITE_LONG
+@...ef			Macro for writing long data to an io/mem address
+*/
+#define IOH_WRITE_LONG IOH_WRITE32
+
+/*! @ingroup	Global
+@def		    IOH_READ_BYTE
+@...ef			Macro for reading 1 byte data from an io/mem address
+*/
+#define IOH_READ_BYTE  IOH_READ8
+/*! @ingroup	Global
+@def		    IOH_READ_WORD
+@...ef			Macro for reading 1 word data from an io/mem address
+*/
+#define IOH_READ_WORD  IOH_READ16
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@...ef			Macro for reading long data from an io/mem address
+*/
+#define IOH_READ_LONG  IOH_READ32
+
+/* Bit Manipulation Macros */
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@...ef			macro to set a specified bit(mask) at the
+			specified address
+*/
+#define IOH_SET_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) |\
+							 (bitmask)), (addr))
+
+/*! @ingroup	Global
+@def	    IOH_READ_LONG
+@...ef		macro to clear a specified bit(mask) at the specified address
+*/
+#define IOH_CLR_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) &\
+							 ~(bitmask)), (addr))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@...ef			macro to set a specified bitmask for a variable
+*/
+#define IOH_SET_BITMSK(var, bitmask) ((var) |= (bitmask))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@...ef			macro to clear a specified bitmask for a variable
+*/
+#define IOH_CLR_BITMSK(var, bitmask) ((var) &= (~(bitmask)))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@...ef			macro to set a specified bit for a variable
+*/
+#define IOH_SET_BIT(var, bit) ((var) |= (1<<(bit)))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@...ef			macro to clear a specified bit for a variable
+*/
+#define IOH_CLR_BIT(var, bit) ((var) &= ~(1<<(bit)))
+
+#endif
diff --git a/drivers/char/pch_pcieqos/pch_debug.h b/drivers/char/pch_pcieqos/pch_debug.h
new file mode 100644
index 0000000..e89f659
--- /dev/null
+++ b/drivers/char/pch_pcieqos/pch_debug.h
@@ -0,0 +1,60 @@
+/*!
+ * @file ioh_debug.h
+ * @brief Provides the macro definitions used for debugging.
+ * @version 1.0.0.0
+ * @section
+ * 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.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_DEBUG_H__
+#define __IOH_DEBUG_H__
+
+#ifdef MODULE
+#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n",\
+						 THIS_MODULE->name, ##args)
+#else
+#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n" ,\
+							 __FILE__, ##args)
+#endif
+
+#define DEBUG 1
+#ifdef DEBUG
+	#define IOH_DEBUG(fmt, args...) IOH_LOG(KERN_DEBUG, fmt, ##args)
+#else
+	#define IOH_DEBUG(fmt, args...)
+#endif
+
+#ifdef IOH_TRACE_ENABLED
+	#define IOH_TRACE IOH_DEBUG
+#else
+	#define IOH_TRACE(fmt, args...)
+#endif
+
+#define IOH_TRACE_ENTER IOH_TRACE("Enter %s", __func__)
+#define IOH_TRACE_EXIT 	IOH_TRACE("Exit %s", __func__)
+
+
+#endif
diff --git a/drivers/char/pch_pcieqos/pch_pcieqos.c b/drivers/char/pch_pcieqos/pch_pcieqos.c
new file mode 100644
index 0000000..e0699d4
--- /dev/null
+++ b/drivers/char/pch_pcieqos/pch_pcieqos.c
@@ -0,0 +1,400 @@
+/*!
+ * @file ioh_pcieqos.c
+ * @brief Provides all the implementation of the interfaces pertaining to the PCIEQOS module.
+ * @version 1.0.0.0
+ * @section
+ * 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.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 06/20/2009
+ * modified:
+ *
+ */
+
+/* includes */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/string.h>
+
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_pcieqos.h"
+#include "pch_pcieqos_hal.h"
+
+#define MODULE_NAME "pch_pcieqos"
+
+/* global variables */
+s32 ioh_pcieqos_opencount;	/* check whether opened or not */
+
+DEFINE_SPINLOCK(ioh_pcieqos_lock);	/* for spin lock */
+
+/**
+ * file_operations structure initialization
+ */
+const struct file_operations ioh_pcieqos_fops = {
+	.owner = THIS_MODULE,
+	.open = ioh_pcieqos_open,
+	.release = ioh_pcieqos_release,
+	.unlocked_ioctl = ioh_pcieqos_ioctl,
+};
+
+/*function implementations*/
+
+/*! @ingroup PCIEQOS_InterfaceLayerAPI
+  @fn  int ioh_pcieqos_open( struct inode *inode,struct file *file)
+  @remarks  Implements the Initializing and opening of the pcieqos module.
+  @param  inode 	[@ref INOUT] Contains the reference of the inode
+								 structure
+  @param  file 	[@ref INOUT] Contains the reference of the file structure
+  @retval returnvalue	[@ref OUT] contains the result for the concerned
+								 attempt.
+  The result would generally comprise of success code
+  or failure code. The failure code will indicate reason for
+  failure.
+  @see
+  EBUSY
+  */
+int ioh_pcieqos_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	spin_lock(&ioh_pcieqos_lock);
+	IOH_DEBUG("ioh_pcieqos_open : open count value = %d",
+		  ioh_pcieqos_opencount);
+	if (ioh_pcieqos_opencount) {
+		IOH_LOG(KERN_ERR,
+			"ioh_pcieqos_open :  device already opened\n");
+		ret = -EBUSY;
+	} else {
+		ioh_pcieqos_opencount++;
+		ret = IOH_PCIEQOS_SUCCESS;
+	}
+	spin_unlock(&ioh_pcieqos_lock);
+
+	IOH_DEBUG("ioh_pcieqos_open returns=%d\n", ret);
+	return ret;
+}
+
+/*! @ingroup PCIEQOS_InterfaceLayerAPI
+  @fn  int ioh_pcieqos_release(struct inode *inode,struct file *file)
+  @remarks  Implements the release functionality of the pcieqos module.
+  @param  inode 	[@ref INOUT] Contains the reference of the inode
+								 structure
+  @param  file 	[@ref INOUT] Contains the reference of the file structure
+  @retval returnvalue	[@ref OUT] contains the result for the concerned
+								 attempt.
+  The result would generally comprise of success code
+  or failure code. The failure code will indicate reason for
+  failure.
+  @see
+  SUCCESS
+  */
+int ioh_pcieqos_release(struct inode *inode, struct file *file)
+{
+	spin_lock(&ioh_pcieqos_lock);
+
+	if (ioh_pcieqos_opencount > 0)
+		ioh_pcieqos_opencount--;
+	spin_unlock(&ioh_pcieqos_lock);
+
+	IOH_DEBUG("ioh_pcieqos_release : ioh_pcieqos_opencount =%d\n",
+		  ioh_pcieqos_opencount);
+
+	IOH_DEBUG("ioh_pcieqos_release returning=%d\n", IOH_PCIEQOS_SUCCESS);
+	return IOH_PCIEQOS_SUCCESS;
+}
+
+/*! @ingroup PCIEQOS_InterfaceLayerAPI
+  @fn  int ioh_pcieqos_ioctl(struct inode * inode,struct file * file,
+					 unsigned int cmd,unsigned long arg)
+  @remarks  Implements the various ioctl functionalities of the pcieqos module.
+  @param  file 	[@ref INOUT] Contains the reference of the file structure
+  @param  cmd 	[@ref IN] Contains the command value
+  @param  arg 	[@ref IN] Contains the command argument value
+  @retval returnvalue	[@ref OUT] contains the result for the concerned attempt.
+  The result would generally comprise of success code
+  or failure code. The failure code will indicate reason for
+  failure.
+  @see
+  EINVAL
+  EFAULT
+  */
+long ioh_pcieqos_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+
+	long ret_value = IOH_PCIEQOS_SUCCESS;
+	struct ioh_pcieqos_reqt __user *p_ioh_pcieqos_reqt;
+	unsigned long addr_offset;
+	unsigned long data;
+	unsigned long mask;
+
+	printk("ioh_pcieqos arguments:\n");
+	printk("\tfile: %p\n", file);
+	printk("\t  cmd: %x\n", cmd);
+	printk("\t  arg: %lx\n", arg);
+
+	printk("command summary:\n");
+	printk("\t%x: IOCTL_PCIEQOS_READ_MAC_ADDR\n", IOCTL_PCIEQOS_READ_MAC_ADDR); 
+	printk("\t%x: IOCTL_PCIEQOS_WRITE_MAC_ADDR\n", IOCTL_PCIEQOS_WRITE_MAC_ADDR); 
+
+	do {
+		if (ioh_pcieqos_suspended == true) {
+			IOH_LOG(KERN_ERR,
+				"ioh_pcieqos_ioctl : suspend initiated\
+							 returning =%d\n",
+				IOH_PCIEQOS_FAIL);
+			ret_value = IOH_PCIEQOS_FAIL;
+			break;
+		}
+
+		p_ioh_pcieqos_reqt = (struct ioh_pcieqos_reqt __user *)arg;
+		printk("%d: copy_from_user\n", __LINE__);
+		printk("\t&addr_offset: %p\n", &addr_offset);
+		printk("\t&reqt->addr_offset: %p\n", &p_ioh_pcieqos_reqt->addr_offset);
+		ret_value =
+		    copy_from_user(&addr_offset,
+				   &p_ioh_pcieqos_reqt->addr_offset,
+				   sizeof(addr_offset));
+		if (ret_value) {
+			IOH_LOG(KERN_ERR,
+				"ioh_pcieqos_ioctl : copy_from_user fail\
+							 returning =%d\n",
+				-EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		IOH_DEBUG("ioh_pcieqos_ioctl  : copy_from_user returns =%d\n",
+			  ret_value);
+
+		switch (cmd) {
+		case IOCTL_PCIEQOS_READ_REG:
+			{
+
+				ioh_pcieqos_read_reg(addr_offset, &data);
+				IOH_DEBUG
+				    ("ioh_pcieqos_ioctl  : Invoked\
+					 ioh_pcieqos_read_reg successfully\n");
+
+				ret_value =
+				    copy_to_user((void *)&p_ioh_pcieqos_reqt->
+						 data, (void *)&data,
+						 sizeof(data));
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_pcieqos_ioctl :\
+					 copy_to_user fail returning =%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+					break;
+				}
+				break;
+			}
+
+		case IOCTL_PCIEQOS_WRITE_REG:
+			{
+
+				ret_value =
+				    copy_from_user((void *)&data,
+						   (void *)&p_ioh_pcieqos_reqt->
+						   data, sizeof(data));
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_pcieqos_ioctl :\
+					 copy_from_user fail returning =%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+					break;
+				}
+				ioh_pcieqos_write_reg(addr_offset, data);
+				IOH_DEBUG
+				    ("ioh_pcieqos_ioctl  : Invoked\
+					 ioh_pcieqos_write_reg successfully\n");
+				break;
+			}
+
+		case IOCTL_PCIEQOS_READ_MODIFY_WRITE_REG:
+			{
+
+				ret_value =
+				    copy_from_user((void *)&data,
+						   (void *)&p_ioh_pcieqos_reqt->
+						   data, sizeof(data));
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_pcieqos_ioctl :\
+					 copy_from_user fail returning =%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+					break;
+				}
+				ret_value =
+				    copy_from_user((void *)&mask,
+						   (void *)&p_ioh_pcieqos_reqt->
+						   mask, sizeof(mask));
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_pcieqos_ioctl :\
+					 copy_from_user fail returning =%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+					break;
+				}
+				ioh_pcieqos_read_modify_write_reg(addr_offset,
+								  data, mask);
+				IOH_DEBUG
+				    ("ioh_pcieqos_ioctl  : Invoked\
+			 ioh_pcieqos_read_modify_write_reg successfully\n");
+				break;
+			}
+
+		case IOCTL_PCIEQOS_READ_OROM:
+			{
+
+				ret_value =
+				    ioh_pcieqos_read_serial_rom(addr_offset,
+							(unsigned char *)&data);
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_pcieqos_ioctl :\
+				 Invoked ioh_pcieqos_read_serial_rom =%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+					break;
+				} else {
+					IOH_DEBUG
+					    ("ioh_pcieqos_ioctl  :\
+			 Invoked ioh_pcieqos_read_serial_rom successfully\n");
+				}
+
+				ret_value =
+				    copy_to_user((void *)&p_ioh_pcieqos_reqt->
+						 data, (void *)&data,
+						 sizeof(data));
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_pcieqos_ioctl :\
+					 copy_to_user fail returning =%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+					break;
+				}
+				break;
+			}
+
+		case IOCTL_PCIEQOS_WRITE_OROM:
+			{
+
+				ret_value =
+				    copy_from_user((void *)&data,
+						   (void *)&p_ioh_pcieqos_reqt->
+						   data, sizeof(data));
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_pcieqos_ioctl :\
+					 copy_from_user fail returning =%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+					break;
+				}
+				ret_value =
+				    ioh_pcieqos_write_serial_rom(addr_offset,
+								 data);
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_pcieqos_ioctl :\
+				 Invoked ioh_pcieqos_write_serial_rom =%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+					break;
+				} else {
+					IOH_DEBUG
+					    ("ioh_pcieqos_ioctl  :\
+			 Invoked ioh_pcieqos_write_serial_rom successfully\n");
+				}
+				break;
+			}
+
+		case IOCTL_PCIEQOS_READ_MAC_ADDR:
+			{
+
+				ioh_pcieqos_read_gbe_mac_addr(addr_offset,
+						 (unsigned char *)&data);
+				IOH_DEBUG
+				    ("ioh_pcieqos_ioctl  : Invoked\
+				 ioh_pcieqos_read_gbe_mac_addr successfully\n");
+
+				ret_value =
+				    copy_to_user((void *)&p_ioh_pcieqos_reqt->
+						 data, (void *)&data,
+						 sizeof(data));
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_pcieqos_ioctl :\
+					 copy_to_user fail returning =%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+					break;
+				}
+				break;
+			}
+
+		case IOCTL_PCIEQOS_WRITE_MAC_ADDR:
+			{
+
+				ret_value =
+				    copy_from_user((void *)&data,
+						   (void *)&p_ioh_pcieqos_reqt->
+						   data, sizeof(data));
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_pcieqos_ioctl :\
+					 copy_from_user fail returning =%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+					break;
+				}
+				ioh_pcieqos_write_gbe_mac_addr(addr_offset,
+							       data);
+				IOH_DEBUG
+				    ("ioh_pcieqos_ioctl  : Invoked\
+			 ioh_pcieqos_write_gbe_mac_addr successfully\n");
+				break;
+			}
+
+		default:
+			{
+				IOH_LOG(KERN_ERR,
+					"ioh_write_ioctl invalid command\
+							 returning=%d\n",
+					-EINVAL);
+				ret_value = -EINVAL;
+				break;
+			}
+		}
+		break;
+
+	} while (0);
+	IOH_LOG(KERN_ERR, "ioh_write_ioctl returns=%ld\n", ret_value);
+	return ret_value;
+}
diff --git a/drivers/char/pch_pcieqos/pch_pcieqos.h b/drivers/char/pch_pcieqos/pch_pcieqos.h
new file mode 100644
index 0000000..1b0512b
--- /dev/null
+++ b/drivers/char/pch_pcieqos/pch_pcieqos.h
@@ -0,0 +1,193 @@
+#ifndef __IOH_PCIEQOS_H__
+#define __IOH_PCIEQOS_H__
+/*!
+ * @file ioh_pcieqos.h
+ * @brief Provides all the interfaces pertaining to the PCIEQOS module.
+ * @version 1.0.0.0
+ * @section
+ * 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.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 06/20/2009
+ * modified:
+ *
+ */
+
+/*! @defgroup PCIEQOS */
+/*! @defgroup PCIEQOS_Global  				Global
+  @ingroup PCIEQOS */
+/*! @defgroup PCIEQOS_GlobalGeneral			General
+  @ingroup PCIEQOS_Global */
+/*! @defgroup PCIEQOS_GlobalResultCodes			StatusCodes
+  @ingroup PCIEQOS_Global */
+/*! @defgroup PCIEQOS_InterfaceLayer			InterfaceLayer
+  @ingroup PCIEQOS */
+/*! @defgroup PCIEQOS_InterfaceLayerAPI  		Providers
+  @ingroup PCIEQOS_InterfaceLayer
+  */
+/*! @defgroup PCIEQOS_InterfaceLayerNotifyRoutines  	Notifiers
+  @ingroup PCIEQOS_InterfaceLayer
+  */
+/*! @defgroup PCIEQOS_PCILayer				PCILayer
+  @ingroup PCIEQOS */
+/*! @defgroup PCIEQOS_PCILayerAPI  			Providers
+  @ingroup PCIEQOS_PCILayer
+  */
+/*! @defgroup PCIEQOS_PCILayerFacilitators  		Facilitators
+  @ingroup PCIEQOS_PCILayer
+  */
+/*! @defgroup PCIEQOS_HALLayer				HALLayer
+  @ingroup PCIEQOS */
+/*! @defgroup PCIEQOS_HALLayerAPI  			Providers
+  @ingroup PCIEQOS_HALLayer
+  */
+/*! @defgroup PCIEQOS_HALLayerFacilitators  		Facilitators
+  @ingroup PCIEQOS_HALLayer
+  */
+/*! @defgroup PCIEQOS_Utilities				Utilities
+  @ingroup PCIEQOS */
+/*! @defgroup PCIEQOS_UtilitiesAPI  			Providers
+  @ingroup PCIEQOS_Utilities
+  */
+
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @def PCIEQOS_IOCTL_MAGIC
+  @brief Outlines the ioctl magic.
+  */
+#define PCIEQOS_IOCTL_MAGIC 		(0xf7)
+
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @def IOCTL_PCIEQOS_READ_REG
+  @brief Outlines the read register function signature.
+  */
+#define IOCTL_PCIEQOS_READ_REG (_IOW(PCIEQOS_IOCTL_MAGIC, 1, unsigned long))
+
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @def IOCTL_PCIEQOS_WRITE_REG
+  @brief Outlines the write register function signature.
+  */
+#define IOCTL_PCIEQOS_WRITE_REG (_IOW(PCIEQOS_IOCTL_MAGIC, 2, unsigned long))
+
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @def IOCTL_PCIEQOS_READ_MODIFY_WRITE_REG
+  @brief Outlines the read, modify and write register function signature.
+  */
+#define IOCTL_PCIEQOS_READ_MODIFY_WRITE_REG (_IOW(PCIEQOS_IOCTL_MAGIC, 3,\
+								 unsigned long))
+
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @def IOCTL_PCIEQOS_READ_OROM
+  @brief Outlines the read option rom function signature.
+  */
+#define IOCTL_PCIEQOS_READ_OROM (_IOW(PCIEQOS_IOCTL_MAGIC, 4, unsigned long))
+
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @def IOCTL_PCIEQOS_WRITE_OROM
+  @brief Outlines the write option rom function signature.
+  */
+#define IOCTL_PCIEQOS_WRITE_OROM (_IOW(PCIEQOS_IOCTL_MAGIC, 5, unsigned long))
+
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @def IOCTL_PCIEQOS_READ_MAC_ADDR
+  @brief Outlines the read mac address function signature.
+  */
+#define IOCTL_PCIEQOS_READ_MAC_ADDR (_IOW(PCIEQOS_IOCTL_MAGIC, 6,\
+								 unsigned long))
+
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @def IOCTL_PCIEQOS_WRITE_MAC_ADDR
+  @brief Outlines the write mac address function signature.
+  */
+#define IOCTL_PCIEQOS_WRITE_MAC_ADDR (_IOW(PCIEQOS_IOCTL_MAGIC, 7,\
+								 unsigned long))
+
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @def PCIEQOS STATUS CODE
+  @brief Outlines PCIEQOS SUCCESS STATUS CODE
+  */
+#define IOH_PCIEQOS_SUCCESS 	(0)
+
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @def PCIEQOS STATUS CODE
+  @brief Outlines PCIEQOS ERROR STATUS CODE
+  */
+#define IOH_PCIEQOS_FAIL 		(-1)
+
+/* Registers address offset */
+#define IOH_PCIEQOS_PHUB_ID_REG			(0x0000)
+#define IOH_PCIEQOS_QUEUE_PRI_VAL_REG		(0x0004)
+#define IOH_PCIEQOS_RC_QUEUE_MAXSIZE_REG	(0x0008)
+#define IOH_PCIEQOS_BRI_QUEUE_MAXSIZE_REG	(0x000C)
+#define IOH_PCIEQOS_COMP_RESP_TIMEOUT_REG	(0x0010)
+#define IOH_PCIEQOS_BUS_SLAVE_CONTROL_REG	(0x0014)
+#define IOH_PCIEQOS_DEADLOCK_AVOID_TYPE_REG	(0x0018)
+#define IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG0	(0x0020)
+#define IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG1	(0x0024)
+#define IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG2	(0x0028)
+#define IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG3	(0x002C)
+#define IOH_PCIEQOS_INT_REDUCE_CONTROL_REG_BASE	(0x0040)
+#define CLKCFG_REG_OFFSET           		(0x500)
+
+/*structures*/
+/*! @ingroup PCIEQOS_InterfaceLayer
+  @struct ioh_pcieqos_reqt
+  @brief It is a structure used for perserving information related to the
+  pcieqos request.
+  @note
+  The concerned details should be provided during the read register,
+   write register and read / modify / write register.
+  @see
+  ioh_pcieqos_ioctl
+  */
+struct ioh_pcieqos_reqt {
+	unsigned long addr_offset;	/*specifies the register address
+								 offset */
+	unsigned long data;	/*specifies the data */
+	unsigned long mask;	/*specifies the mask */
+};
+
+/* exported function prototypes */
+/*! @ingroup PCIEQOS_InterfaceLayerAPI
+  @fn nt ioh_pcieqos_open( struct inode *inode,struct file *file )
+  @brief  Provides the functionality of initialization of the module
+  */
+int ioh_pcieqos_open(struct inode *inode, struct file *file);
+
+/*! @ingroup PCIEQOS_InterfaceLayerAPI
+  @fn int ioh_pcieqos_release(struct inode *inode,struct file *file)
+  @brief  Provides the functionality of releasing the module
+  */
+int ioh_pcieqos_release(struct inode *inode, struct file *file);
+
+/*! @ingroup PCIEQOS_InterfaceLayerAPI
+  @fn long ioh_pcieqos_ioctl(struct file * file, unsigned int cmd, unsigned long arg)
+  @brief  Provides the functionality of invoking various functionalities of
+								 the PCIEQOS.
+  */
+long ioh_pcieqos_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+
+/**global variables*/
+extern u32 ioh_pcieqos_base_address;	/* base address */
+extern s32 ioh_pcieqos_suspended;	/* suspend status */
+
+extern s32 ioh_pcieqos_opencount;
+extern spinlock_t ioh_pcieqos_lock;
+extern const struct file_operations ioh_pcieqos_fops;
+#endif
diff --git a/drivers/char/pch_pcieqos/pch_pcieqos_hal.c b/drivers/char/pch_pcieqos/pch_pcieqos_hal.c
new file mode 100644
index 0000000..a312a23
--- /dev/null
+++ b/drivers/char/pch_pcieqos/pch_pcieqos_hal.c
@@ -0,0 +1,550 @@
+/*!
+ * @file ioh_pcieqos_hal.c
+ * @brief Provides all the implementation of the interfaces pertaining to the
+ * 									 HAL.
+ * @version 1.0.0.0
+ * @section
+ * 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.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 06/20/2009
+ * modified:
+ *
+ */
+
+/*includes*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_pcieqos.h"
+#include "pch_pcieqos_hal.h"
+
+/* Status Register offset */
+#define PCIEQOS_STATUS (0x00)
+
+/* Control Register offset */
+#define PCIEQOS_CONTROL (0x04)
+
+/* Time out value for Status Register */
+#define PCIEQOS_TIMEOUT (0x05)
+
+/* Enabling for writing ROM */
+#define IOH_PCIEQOS_ROM_WRITE_ENABLE (0x01)
+
+/* Disabling for writing ROM */
+#define IOH_PCIEQOS_ROM_WRITE_DISABLE (0x00)
+
+/* ROM data area start address offset */
+#define IOH_PCIEQOS_ROM_START_ADDR (0x14)
+
+/* MAX number of INT_REDUCE_CONTROL registers */
+#define MAX_NUM_INT_REDUCE_CONTROL_REG (128)
+
+/* global variables */
+struct ioh_pcieqos_reg {
+	u32 phub_id_reg;	/* PHUB_ID register val */
+	u32 q_pri_val_reg;	/* QUEUE_PRI_VAL register val */
+	u32 rc_q_maxsize_reg;	/* RC_QUEUE_MAXSIZE register val */
+	u32 bri_q_maxsize_reg;	/* BRI_QUEUE_MAXSIZE register val */
+	u32 comp_resp_timeout_reg;	/* COMP_RESP_TIMEOUT register val */
+	u32 bus_slave_control_reg;	/* BUS_SLAVE_CONTROL_REG register val */
+	u32 deadlock_avoid_type_reg;	/* DEADLOCK_AVOID_TYPE register val */
+	u32 intpin_reg_wpermit_reg0;	/* INTPIN_REG_WPERMIT register 0 val */
+	u32 intpin_reg_wpermit_reg1;	/* INTPIN_REG_WPERMIT register 1 val */
+	u32 intpin_reg_wpermit_reg2;	/* INTPIN_REG_WPERMIT register 2 val */
+	u32 intpin_reg_wpermit_reg3;	/* INTPIN_REG_WPERMIT register 3 val */
+	/* INT_REDUCE_CONTROL registers val */
+	u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG];
+#ifdef IOH_CAN_PCLK_50MHZ
+	u32 clkcfg_reg;		/* CLK CFG register val */
+#endif
+} g_ioh_pcieqos_reg;
+
+/*functions implementations*/
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn  void ioh_pcieqos_read_reg(unsigned long reg_addr_offset,
+							 unsigned long *data)
+  @remarks  Implements the functionality of reading register.
+  @param  reg_addr_offset [@ref IN] Contains the register offset address value
+  @param  *data           [@ref INOUT] Contains the register value
+  @retval NONE
+  @see
+  */
+void ioh_pcieqos_read_reg(unsigned long reg_addr_offset, unsigned long *data)
+{
+	unsigned long reg_addr = ioh_pcieqos_base_address + reg_addr_offset;
+	*data = IOH_READ32(reg_addr);
+
+	return;
+}
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn  void ioh_pcieqos_write_reg(unsigned long reg_addr_offset,
+							 unsigned long data)
+  @remarks  Implements the functionality of writing register.
+  @param  reg_addr_offset [@ref IN] Contains the register offset address value
+  @param  data            [@ref IN] Contains the writing value
+  @retval NONE
+  @see
+  */
+void ioh_pcieqos_write_reg(unsigned long reg_addr_offset, unsigned long data)
+{
+	unsigned long reg_addr = ioh_pcieqos_base_address + reg_addr_offset;
+	IOH_WRITE32(data, reg_addr);
+
+	return;
+}
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn  void ioh_pcieqos_read_modify_write_reg(unsigned long reg_addr_offset,
+					 unsigned long data, unsigned long mask)
+  @remarks  Implements the functionality of reading, modifying and writing
+								 register.
+  @param  reg_addr_offset [@ref IN] Contains the register offset address value
+  @param  data            [@ref IN] Contains the writing value
+  @param  mask            [@ref IN] Contains the mask value
+  @retval NONE
+  @see
+  */
+void ioh_pcieqos_read_modify_write_reg(unsigned long reg_addr_offset,
+				       unsigned long data, unsigned long mask)
+{
+	unsigned long reg_addr = ioh_pcieqos_base_address + reg_addr_offset;
+	IOH_WRITE32(((IOH_READ32(reg_addr) & ~mask)) | data, reg_addr);
+
+	return;
+}
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn int ioh_pcieqos_read_gbe_mac_addr(unsigned long offset_address,
+							 unsigned char *data)
+  @param  unsigned long offset_address [@ref IN] Contains the Gigabit
+					 Ethernet MAC address offset value
+  @param  *data                        [@ref INOUT] Contains the Gigabit
+						 Ethernet MAC address value
+  @retval return value	               [@ref OUT] contains the result
+			 for the reading Gigabit Ethernet MAC address attempt
+  @see
+  */
+int ioh_pcieqos_read_gbe_mac_addr(unsigned long offset_address,
+				  unsigned char *data)
+{
+	int retval = IOH_PCIEQOS_SUCCESS;
+
+	retval = ioh_pcieqos_read_serial_rom_val(offset_address, data);
+
+	return retval;
+}
+EXPORT_SYMBOL(ioh_pcieqos_read_gbe_mac_addr);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn int ioh_pcieqos_write_gbe_mac_addr(unsigned long offset_address,
+							 unsigned char data)
+  @param  unsigned long offset_address [@ref IN] Contains the Gigabit
+					 Ethernet MAC address offset value
+  @param  data                         [@ref IN] Contains the Gigabit Ethernet
+							 MAC address value
+  @retval return value	               [@ref OUT] contains the result for the
+				 writing Gigabit Ethernet MAC address attempt
+  @see
+  */
+int ioh_pcieqos_write_gbe_mac_addr(unsigned long offset_address,
+				   unsigned char data)
+{
+	int retval = IOH_PCIEQOS_SUCCESS;
+
+	retval = ioh_pcieqos_gbe_serial_rom_conf();
+	retval |= ioh_pcieqos_write_serial_rom_val(offset_address, data);
+
+	return retval;
+}
+EXPORT_SYMBOL(ioh_pcieqos_write_gbe_mac_addr);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn  void ioh_pcieqos_save_reg_conf(void)
+  @remarks  saves register configuration
+  @param NONE
+  @retval  NONE
+  @see
+  ioh_pcieqos_suspend
+  */
+void ioh_pcieqos_save_reg_conf(void)
+{
+	u32 base_addr = ioh_pcieqos_base_address;
+	u32 i = 0;
+
+	IOH_DEBUG("ioh_pcieqos_save_reg_conf ENTRY\n");
+	/* to store contents of PHUB_ID register */
+	g_ioh_pcieqos_reg.phub_id_reg =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_PHUB_ID_REG);
+	/* to store contents of QUEUE_PRI_VAL register */
+	g_ioh_pcieqos_reg.q_pri_val_reg =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_QUEUE_PRI_VAL_REG);
+	/* to store contents of RC_QUEUE_MAXSIZE register */
+	g_ioh_pcieqos_reg.rc_q_maxsize_reg =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_RC_QUEUE_MAXSIZE_REG);
+	/* to store contents of BRI_QUEUE_MAXSIZE register */
+	g_ioh_pcieqos_reg.bri_q_maxsize_reg =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_BRI_QUEUE_MAXSIZE_REG);
+	/* to store contents of COMP_RESP_TIMEOUT register */
+	g_ioh_pcieqos_reg.comp_resp_timeout_reg =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_COMP_RESP_TIMEOUT_REG);
+	/* to store contents of BUS_SLAVE_CONTROL_REG register */
+	g_ioh_pcieqos_reg.bus_slave_control_reg =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_BUS_SLAVE_CONTROL_REG);
+	/* to store contents of DEADLOCK_AVOID_TYPE register */
+	g_ioh_pcieqos_reg.deadlock_avoid_type_reg =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_DEADLOCK_AVOID_TYPE_REG);
+	/* to store contents of INTPIN_REG_WPERMIT register 0 */
+	g_ioh_pcieqos_reg.intpin_reg_wpermit_reg0 =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG0);
+	/* to store contents of INTPIN_REG_WPERMIT register 1 */
+	g_ioh_pcieqos_reg.intpin_reg_wpermit_reg1 =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG1);
+	/* to store contents of INTPIN_REG_WPERMIT register 2 */
+	g_ioh_pcieqos_reg.intpin_reg_wpermit_reg2 =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG2);
+	/* to store contents of INTPIN_REG_WPERMIT register 3 */
+	g_ioh_pcieqos_reg.intpin_reg_wpermit_reg3 =
+	    IOH_READ32(base_addr + IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG3);
+	IOH_DEBUG
+	    ("ioh_pcieqos_save_reg_conf : g_ioh_pcieqos_reg.phub_id_reg=%x, \
+		g_ioh_pcieqos_reg.q_pri_val_reg=%x, \
+		g_ioh_pcieqos_reg.rc_q_maxsize_reg=%x, \
+		g_ioh_pcieqos_reg.bri_q_maxsize_reg=%x, \
+		g_ioh_pcieqos_reg.comp_resp_timeout_reg=%x, \
+		g_ioh_pcieqos_reg.bus_slave_control_reg=%x, \
+		g_ioh_pcieqos_reg.deadlock_avoid_type_reg=%x, \
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg0=%x, \
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg1=%x, \
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg2=%x, \
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg3=%x\n",
+		g_ioh_pcieqos_reg.phub_id_reg,
+		g_ioh_pcieqos_reg.q_pri_val_reg,
+		g_ioh_pcieqos_reg.rc_q_maxsize_reg,
+		g_ioh_pcieqos_reg.bri_q_maxsize_reg,
+		g_ioh_pcieqos_reg.comp_resp_timeout_reg,
+		g_ioh_pcieqos_reg.bus_slave_control_reg,
+		g_ioh_pcieqos_reg.deadlock_avoid_type_reg,
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg0,
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg1,
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg2,
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg3);
+	/* to store contents of INT_REDUCE_CONTROL registers */
+	for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
+		g_ioh_pcieqos_reg.int_reduce_control_reg[i] =
+		    IOH_READ32(base_addr +
+			       IOH_PCIEQOS_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+		IOH_DEBUG
+		    ("ioh_pcieqos_save_reg_conf : \
+			g_ioh_pcieqos_reg.int_reduce_control_reg[%d]=%x\n",
+		     i, g_ioh_pcieqos_reg.int_reduce_control_reg[i]);
+	}
+#ifdef IOH_CAN_PCLK_50MHZ
+	/* save clk cfg register */
+	g_ioh_pcieqos_reg.clkcfg_reg =
+	    IOH_READ32(base_addr + CLKCFG_REG_OFFSET);
+#endif
+	return;
+}
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn  void ioh_pcieqos_restore_reg_conf(void)
+  @remarks  restore register configuration
+  @param NONE
+  @retval  NONE
+  @see
+  ioh_pcieqos_resume
+  */
+void ioh_pcieqos_restore_reg_conf(void)
+{
+	u32 base_addr = ioh_pcieqos_base_address;
+	u32 i = 0;
+
+	IOH_DEBUG("ioh_pcieqos_restore_reg_conf ENTRY\n");
+	/* to store contents of PHUB_ID register */
+	IOH_WRITE32(g_ioh_pcieqos_reg.phub_id_reg,
+		    base_addr + IOH_PCIEQOS_PHUB_ID_REG);
+	/* to store contents of QUEUE_PRI_VAL register */
+	IOH_WRITE32(g_ioh_pcieqos_reg.q_pri_val_reg,
+		    base_addr + IOH_PCIEQOS_QUEUE_PRI_VAL_REG);
+	/* to store contents of RC_QUEUE_MAXSIZE register */
+	IOH_WRITE32(g_ioh_pcieqos_reg.rc_q_maxsize_reg,
+		    base_addr + IOH_PCIEQOS_RC_QUEUE_MAXSIZE_REG);
+	/* to store contents of BRI_QUEUE_MAXSIZE register */
+	IOH_WRITE32(g_ioh_pcieqos_reg.bri_q_maxsize_reg,
+		    base_addr + IOH_PCIEQOS_BRI_QUEUE_MAXSIZE_REG);
+	/* to store contents of COMP_RESP_TIMEOUT register */
+	IOH_WRITE32(g_ioh_pcieqos_reg.comp_resp_timeout_reg,
+		    base_addr + IOH_PCIEQOS_COMP_RESP_TIMEOUT_REG);
+	/* to store contents of BUS_SLAVE_CONTROL_REG register */
+	IOH_WRITE32(g_ioh_pcieqos_reg.bus_slave_control_reg,
+		    base_addr + IOH_PCIEQOS_BUS_SLAVE_CONTROL_REG);
+	/* to store contents of DEADLOCK_AVOID_TYPE register */
+	IOH_WRITE32(g_ioh_pcieqos_reg.deadlock_avoid_type_reg,
+		    base_addr + IOH_PCIEQOS_DEADLOCK_AVOID_TYPE_REG);
+	/* to store contents of INTPIN_REG_WPERMIT register 0 */
+	IOH_WRITE32(g_ioh_pcieqos_reg.intpin_reg_wpermit_reg0,
+		    base_addr + IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG0);
+	/* to store contents of INTPIN_REG_WPERMIT register 1 */
+	IOH_WRITE32(g_ioh_pcieqos_reg.intpin_reg_wpermit_reg1,
+		    base_addr + IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG1);
+	/* to store contents of INTPIN_REG_WPERMIT register 2 */
+	IOH_WRITE32(g_ioh_pcieqos_reg.intpin_reg_wpermit_reg2,
+		    base_addr + IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG2);
+	/* to store contents of INTPIN_REG_WPERMIT register 3 */
+	IOH_WRITE32(g_ioh_pcieqos_reg.intpin_reg_wpermit_reg3,
+		    base_addr + IOH_PCIEQOS_INTPIN_REG_WPERMIT_REG3);
+	IOH_DEBUG
+	    ("ioh_pcieqos_save_reg_conf : g_ioh_pcieqos_reg.phub_id_reg=%x, \
+		g_ioh_pcieqos_reg.q_pri_val_reg=%x, \
+		g_ioh_pcieqos_reg.rc_q_maxsize_reg=%x, \
+		g_ioh_pcieqos_reg.bri_q_maxsize_reg=%x, \
+		g_ioh_pcieqos_reg.comp_resp_timeout_reg=%x, \
+		g_ioh_pcieqos_reg.bus_slave_control_reg=%x, \
+		g_ioh_pcieqos_reg.deadlock_avoid_type_reg=%x, \
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg0=%x, \
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg1=%x, \
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg2=%x, \
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg3=%x\n",
+		g_ioh_pcieqos_reg.phub_id_reg, g_ioh_pcieqos_reg.q_pri_val_reg,
+		g_ioh_pcieqos_reg.rc_q_maxsize_reg,
+		g_ioh_pcieqos_reg.bri_q_maxsize_reg,
+		g_ioh_pcieqos_reg.comp_resp_timeout_reg,
+		g_ioh_pcieqos_reg.bus_slave_control_reg,
+		g_ioh_pcieqos_reg.deadlock_avoid_type_reg,
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg0,
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg1,
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg2,
+		g_ioh_pcieqos_reg.intpin_reg_wpermit_reg3);
+	/* to store contents of INT_REDUCE_CONTROL register */
+	for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
+		IOH_WRITE32(g_ioh_pcieqos_reg.int_reduce_control_reg[i],
+			    base_addr +
+			    IOH_PCIEQOS_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+		IOH_DEBUG
+		    ("ioh_pcieqos_save_reg_conf : \
+			g_ioh_pcieqos_reg.int_reduce_control_reg[%d]=%x\n",
+			i, g_ioh_pcieqos_reg.int_reduce_control_reg[i]);
+	}
+
+#ifdef IOH_CAN_PCLK_50MHZ
+	/*restore the clock config reg */
+	IOH_WRITE32(g_ioh_pcieqos_reg.clkcfg_reg,
+		    base_addr + CLKCFG_REG_OFFSET);
+#endif
+
+	return;
+}
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn  void ioh_pcieqos_read_serial_rom(unsigned long offset_address,
+							 unsigned char *data)
+  @remarks  Implements the functionality of reading Serial ROM.
+  @param  unsigned long offset_address [@ref IN] Contains the Serial ROM
+							 address offset value
+  @param  *data                        [@ref INOUT] Contains the Serial
+								 ROM value
+  @retval returnvalue	[@ref OUT] contains the result for the reading Serial
+								 ROM attempt
+  @see
+  */
+int ioh_pcieqos_read_serial_rom(unsigned long offset_address,
+				unsigned char *data)
+{
+	unsigned long mem_addr =
+	    ioh_pcieqos_extrom_base_address + offset_address;
+
+	IOH_DEBUG("ioh_pcieqos_read_serial_rom:mem_addr=0x%08x\n", mem_addr);
+	*data = IOH_READ8(mem_addr);
+
+	return IOH_PCIEQOS_SUCCESS;
+}
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn  void ioh_pcieqos_write_serial_rom(unsigned long offset_address,
+							 unsigned char data)
+  @remarks  Implements the functionality of writing Serial ROM.
+  @param  unsigned long offset_address [@ref IN] Contains the Serial ROM
+							 address offset value
+  @param  data                         [@ref IN] Contains the Serial ROM value
+  @retval returnvalue	[@ref OUT] contains the result for the writing Serial
+								 ROM attempt
+  @see
+  */
+int ioh_pcieqos_write_serial_rom(unsigned long offset_address,
+				 unsigned char data)
+{
+	int retval = IOH_PCIEQOS_SUCCESS;
+	unsigned long mem_addr =
+	    ioh_pcieqos_extrom_base_address + offset_address;
+	int i = 0;
+	unsigned long word_data = 0;
+
+	IOH_DEBUG("ioh_pcieqos_write_serial_rom:mem_addr=0x%08x\n", mem_addr);
+	IOH_WRITE32(IOH_PCIEQOS_ROM_WRITE_ENABLE,
+		    ioh_pcieqos_extrom_base_address + PCIEQOS_CONTROL);
+
+	word_data = IOH_READ32((mem_addr & 0xFFFFFFFC));
+	IOH_DEBUG("word_data=0x%08x\n", word_data);
+	IOH_DEBUG("data=0x%02x\n", data);
+	switch (mem_addr % 4) {
+	case 0:
+		{
+			word_data &= 0xFFFFFF00;
+			IOH_WRITE32((word_data | (unsigned long)data),
+				    (mem_addr & 0xFFFFFFFC));
+		}
+	case 1:
+		{
+			word_data &= 0xFFFF00FF;
+			IOH_WRITE32((word_data | ((unsigned long)data << 8)),
+				    (mem_addr & 0xFFFFFFFC));
+		}
+	case 2:
+		{
+			word_data &= 0xFF00FFFF;
+			IOH_WRITE32((word_data | ((unsigned long)data << 16)),
+				    (mem_addr & 0xFFFFFFFC));
+		}
+	case 3:
+		{
+			word_data &= 0x00FFFFFF;
+			IOH_WRITE32((word_data | ((unsigned long)data << 24)),
+				    (mem_addr & 0xFFFFFFFC));
+		}
+	}
+	while (0x00 !=
+	       IOH_READ8(ioh_pcieqos_extrom_base_address + PCIEQOS_STATUS)) {
+		msleep(1);
+		if (PCIEQOS_TIMEOUT == i) {
+			retval = IOH_PCIEQOS_FAIL;
+			break;
+		}
+		i++;
+	}
+
+	IOH_WRITE32(IOH_PCIEQOS_ROM_WRITE_DISABLE,
+		    ioh_pcieqos_extrom_base_address + PCIEQOS_CONTROL);
+
+	return retval;
+}
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn  void ioh_pcieqos_read_serial_rom_val(unsigned long offset_address,
+							 unsigned char *data)
+  @remarks  Implements the functionality of reading Serial ROM value.
+  @param  unsigned long offset_address [@ref IN] Contains the Serial ROM
+							 address offset value
+  @param  *data                        [@ref INOUT] Contains the Serial
+								 ROM value
+  @retval returnvalue	[@ref OUT] contains the result for the reading Serial
+								 ROM attempt
+  @see
+  */
+int ioh_pcieqos_read_serial_rom_val(unsigned long offset_address,
+				    unsigned char *data)
+{
+	int retval = IOH_PCIEQOS_SUCCESS;
+	unsigned long mem_addr;
+
+	mem_addr =
+	    (offset_address / 4 * 8) + 3 - (offset_address % 4) +
+	    IOH_PCIEQOS_ROM_START_ADDR;
+	retval = ioh_pcieqos_read_serial_rom(mem_addr, data);
+
+	return retval;
+}
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn  void ioh_pcieqos_write_serial_rom_val(unsigned long offset_address,
+							 unsigned char data)
+  @remarks  Implements the functionality of writing Serial ROM value.
+  @param  unsigned long offset_address [@ref IN] Contains the Serial ROM
+							 address offset value
+  @param  data                         [@ref IN] Contains the Serial ROM value
+  @retval returnvalue	[@ref OUT] contains the result for the writing Serial
+								 ROM attempt
+  @see
+  */
+int ioh_pcieqos_write_serial_rom_val(unsigned long offset_address,
+				     unsigned char data)
+{
+	int retval = IOH_PCIEQOS_SUCCESS;
+	unsigned long mem_addr;
+
+	mem_addr =
+	    (offset_address / 4 * 8) + 3 - (offset_address % 4) +
+	    IOH_PCIEQOS_ROM_START_ADDR;
+	retval = ioh_pcieqos_write_serial_rom(mem_addr, data);
+
+	return retval;
+}
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn int ioh_pcieqos_gbe_serial_rom_conf(void)
+  @remarks  makes Serial ROM header format configuration for Gigabit Ethernet
+								 MAC address
+  @param NONE
+  @retval returnvalue	[@ref OUT] contains the result for the writing Serial
+								 ROM attempt
+  @see
+  */
+int ioh_pcieqos_gbe_serial_rom_conf(void)
+{
+	int retval = IOH_PCIEQOS_SUCCESS;
+
+	retval |= ioh_pcieqos_write_serial_rom(0x0b, 0xbc);
+	retval |= ioh_pcieqos_write_serial_rom(0x0a, 0x10);
+	retval |= ioh_pcieqos_write_serial_rom(0x09, 0x01);
+	retval |= ioh_pcieqos_write_serial_rom(0x08, 0x02);
+
+	retval |= ioh_pcieqos_write_serial_rom(0x0f, 0x00);
+	retval |= ioh_pcieqos_write_serial_rom(0x0e, 0x00);
+	retval |= ioh_pcieqos_write_serial_rom(0x0d, 0x00);
+	retval |= ioh_pcieqos_write_serial_rom(0x0c, 0x80);
+
+	retval |= ioh_pcieqos_write_serial_rom(0x13, 0xbc);
+	retval |= ioh_pcieqos_write_serial_rom(0x12, 0x10);
+	retval |= ioh_pcieqos_write_serial_rom(0x11, 0x01);
+	retval |= ioh_pcieqos_write_serial_rom(0x10, 0x18);
+
+	retval |= ioh_pcieqos_write_serial_rom(0x1b, 0xbc);
+	retval |= ioh_pcieqos_write_serial_rom(0x1a, 0x10);
+	retval |= ioh_pcieqos_write_serial_rom(0x19, 0x01);
+	retval |= ioh_pcieqos_write_serial_rom(0x18, 0x19);
+
+	retval |= ioh_pcieqos_write_serial_rom(0x23, 0xbc);
+	retval |= ioh_pcieqos_write_serial_rom(0x22, 0x10);
+	retval |= ioh_pcieqos_write_serial_rom(0x21, 0x01);
+	retval |= ioh_pcieqos_write_serial_rom(0x20, 0x3a);
+
+	retval |= ioh_pcieqos_write_serial_rom(0x27, 0x01);
+	retval |= ioh_pcieqos_write_serial_rom(0x26, 0x00);
+	retval |= ioh_pcieqos_write_serial_rom(0x25, 0x00);
+	retval |= ioh_pcieqos_write_serial_rom(0x24, 0x00);
+
+	return retval;
+}
+
diff --git a/drivers/char/pch_pcieqos/pch_pcieqos_hal.h b/drivers/char/pch_pcieqos/pch_pcieqos_hal.h
new file mode 100644
index 0000000..bd84c96
--- /dev/null
+++ b/drivers/char/pch_pcieqos/pch_pcieqos_hal.h
@@ -0,0 +1,125 @@
+#ifndef __IOH_PCIEQOS_HAL_H__
+#define __IOH_PCIEQOS_HAL_H__
+/*!
+ * @file ioh_pcieqos_hal.h
+ * @brief Provides all the interfaces pertaining to the HAL.
+ * @version 1.0.0.0
+ * @section
+ * 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.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 06/20/2009
+ * modified:
+ *
+ */
+
+/* exported function prototypes */
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn void ioh_pcieqos_read_reg(unsigned long reg_addr_offset,
+							 unsigned long *data)
+  @brief  Provides the functionality of reading register
+  */
+void ioh_pcieqos_read_reg(unsigned long reg_addr_offset, unsigned long *data);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn ioh_pcieqos_write_reg(unsigned long reg_addr_offset, unsigned long data)
+  @brief  Provides the functionality of writing register
+  */
+void ioh_pcieqos_write_reg(unsigned long reg_addr_offset, unsigned long data);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn ioh_pcieqos_read_modify_write_reg(unsigned long reg_addr_offset,
+					 unsigned long data, unsigned long mask)
+  @brief  Provides the functionality of reading, modifying and writing register
+  */
+void ioh_pcieqos_read_modify_write_reg(unsigned long reg_addr_offset,
+				       unsigned long data, unsigned long mask);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn int ioh_pcieqos_read_gbe_mac_addr(unsigned long offset_address,
+							 unsigned char *data)
+  @brief  Provides the functionality of reading Gigabit Ethernet MAC address
+  */
+int ioh_pcieqos_read_gbe_mac_addr(unsigned long offset_address,
+				  unsigned char *data);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn int ioh_pcieqos_write_gbe_mac_addr(unsigned long offset_address,
+							 unsigned char data)
+  @brief  Provides the functionality of writing Gigabit Ethernet MAC address
+  */
+int ioh_pcieqos_write_gbe_mac_addr(unsigned long offset_address,
+				   unsigned char data);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn void ioh_pcieqos_save_reg_conf(void)
+  @brief  saves register configuration
+  */
+void ioh_pcieqos_save_reg_conf(void);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn void ioh_pcieqos_restore_reg_conf(void)
+  @brief  restores register configuration
+  */
+void ioh_pcieqos_restore_reg_conf(void);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn int ioh_pcieqos_read_serial_rom(unsigned long offset_address,
+							 unsigned char *data)
+  @brief  Provides the functionality of reading Serial ROM
+  */
+int ioh_pcieqos_read_serial_rom(unsigned long offset_address,
+				unsigned char *data);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn int ioh_pcieqos_write_serial_rom(unsigned long offset_address,
+							 unsigned char data)
+  @brief  Provides the functionality of writing Serial ROM
+  */
+int ioh_pcieqos_write_serial_rom(unsigned long offset_address,
+				 unsigned char data);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn int ioh_pcieqos_read_serial_rom_val(unsigned long offset_address,
+							 unsigned char *data)
+  @brief  Provides the functionality of reading Serial ROM value
+  */
+int ioh_pcieqos_read_serial_rom_val(unsigned long offset_address,
+				    unsigned char *data);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn int ioh_pcieqos_write_serial_rom_val(unsigned long offset_address,
+							 unsigned char data)
+  @brief  Provides the functionality of writing Serial ROM value
+  */
+int ioh_pcieqos_write_serial_rom_val(unsigned long offset_address,
+				     unsigned char data);
+
+/*! @ingroup PCIEQOS_HALLayerAPI
+  @fn int ioh_pcieqos_gbe_serial_rom_conf(void)
+  @brief  makes Serial ROM data format configuration for Gigabit Ethernet
+								 MAC address
+  */
+int ioh_pcieqos_gbe_serial_rom_conf(void);
+
+/* global variables */
+extern u32 ioh_pcieqos_base_address;
+extern u32 ioh_pcieqos_extrom_base_address;
+#endif
diff --git a/drivers/char/pch_pcieqos/pch_pcieqos_pci.c b/drivers/char/pch_pcieqos/pch_pcieqos_pci.c
new file mode 100644
index 0000000..a288415
--- /dev/null
+++ b/drivers/char/pch_pcieqos/pch_pcieqos_pci.c
@@ -0,0 +1,523 @@
+/*!
+ * @file ioh_pcieqos_pci.c
+ * @brief Provides all the implementation of the interfaces pertaining to the
+ * 						 pci and gpic registrations.
+ * @version 1.0.0.0
+ * @section
+ * 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.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2009 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 06/20/2009
+ * modified:
+ *
+ */
+/*includes*/
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/string.h>
+
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_pcieqos.h"
+#include "pch_pcieqos_hal.h"
+
+/*macros*/
+
+/*! @ingroup PCIEQOS_PCILayer
+  @def PCI_DEVICE_ID_IOH1_PCIEQOS
+  @brief Outlines the PCI Device ID.
+  */
+#define PCI_DEVICE_ID_IOH1_PCIEQOS (0x8801)
+
+/*! @ingroup PCIEQOS_PCILayer
+  @def IOH_MINOR_NOS
+  @brief Outlines the PCIEQOS minor numbers limit.
+  */
+#define IOH_MINOR_NOS (1)
+
+/*values for configuring CLKCFG reg
+ * for CAN clock of 50Mhz*/
+
+/*! @ingroup PCIEQOS_PCILayer
+  @def CLKCFG_CAN_50MHZ
+  @brief CLKCFG register setting for CAN clock of 50Mhz.
+  */
+#define CLKCFG_CAN_50MHZ (0x12000000)
+
+/*! @ingroup PCIEQOS_PCILayer
+  @def CLKCFG_CANCLK_MASK
+  @brief Bit mask for bit fields in CLKCFG register
+	     to set CAN clock to 50Mhz.
+  */
+#define CLKCFG_CANCLK_MASK (0xFF000000)
+
+/**global variables*/
+u32 ioh_pcieqos_base_address;
+u32 ioh_pcieqos_extrom_base_address;
+s32 ioh_pcieqos_suspended;
+
+/* ToDo: major number allocation via module parameter */
+static dev_t ioh_pcieqos_dev_no;
+static int ioh_pcieqos_major_no;
+
+static struct cdev ioh_pcieqos_dev;
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+  @fn static int __devinit ioh_pcieqos_probe(struct pci_dev* ioh_pci_dev,
+					 const struct pci_device_id* pci_id)
+  @brief  Provides the functionality of probing the module
+  */
+static int __devinit ioh_pcieqos_probe(struct pci_dev *pdev, const
+				       struct pci_device_id *id);
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+  @fn static void __devexit ioh_pcieqos_remove(struct pci_dev * ioh_pci_dev)
+  @brief  Provides the functionality of removing the module
+  */
+static void __devexit ioh_pcieqos_remove(struct pci_dev *pdev);
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+  @fn static int ioh_pcieqos_suspend(struct pci_dev* pDev,pm_message_t state)
+  @brief  Provides the functionality of suspending the module
+  */
+static int ioh_pcieqos_suspend(struct pci_dev *pdev, pm_message_t state);
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+  @fn static int ioh_pcieqos_resume(struct pci_dev* pDev)
+  @brief  Provides the functionality of resuming the module
+  */
+static int ioh_pcieqos_resume(struct pci_dev *pdev);
+
+/*structures*/
+/*! @ingroup PCIEQOS_PCILayerFacilitators
+  @static struct pci_device_id
+  @brief It is a structure used for perserving information related to the
+  device id.
+  @note
+  The concerned details should be provided as a reference in the pci driver
+  structure.
+  */
+static struct pci_device_id ioh_pcieqos_pcidev_id[] = {
+
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_IOH1_PCIEQOS)},
+	{0,}
+};
+
+/*! @ingroup PCIEQOS_PCILayerFacilitators
+  @static struct ioh_pcieqos_driver
+  @brief It is a structure used for perserving information related to the
+  pcieqos device and preserves function signatures to manipulate the device.
+  @note
+  The structure contains the various interfaces aspects
+  provided to the pci layer.
+  @see
+  ioh_pcieqos_probe
+  ioh_pcieqos_suspend
+  ioh_pcieqos_resume
+  ioh_pcieqos_remove
+  */
+static struct pci_driver ioh_pcieqos_driver = {
+	.name = "ioh_pcieqos",
+	.id_table = ioh_pcieqos_pcidev_id,
+	.probe = ioh_pcieqos_probe,
+	.remove = __devexit_p(ioh_pcieqos_remove),
+#ifdef CONFIG_PM
+	.suspend = ioh_pcieqos_suspend,
+	.resume = ioh_pcieqos_resume
+#endif
+};
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+ * @fn static int __init ioh_pcieqos_pci_init(void)
+ * @brief  Provides the functionality of initializing the module
+ * */
+static int __init ioh_pcieqos_pci_init(void);
+/*! @ingroup PCIEQOS_PCILayerAPI
+ * @fn static void __exit ioh_pcieqos_pci_exit(void)
+ * @brief  Provides the functionality of exiting the module
+ * */
+static void __exit ioh_pcieqos_pci_exit(void);
+
+MODULE_DESCRIPTION("IOH PCIEQOS PCI Driver");
+MODULE_LICENSE("GPL");
+module_init(ioh_pcieqos_pci_init);
+module_exit(ioh_pcieqos_pci_exit);
+module_param(ioh_pcieqos_major_no, int, S_IRUSR | S_IWUSR);
+
+/*function implementations*/
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+  @fn  static int __init ioh_pcieqos_pci_init(void)
+  @remarks  Implements the initialization functionality of the module.
+  @param  NONE
+  @retval returnvalue	[@ref OUT] contains the result for the concerned
+								 attempt.
+  The result would generally comprise of success code
+  or failure code. The failure code will indicate reason for
+  failure.
+  @see
+  ioh_pcieqos_pci_exit
+  */
+static int __init ioh_pcieqos_pci_init(void)
+{
+	s32 ret;
+	ret = pci_register_driver(&ioh_pcieqos_driver);
+	IOH_DEBUG
+	    ("ioh_pcieqos_pci_init : Invoked pci_register_driver\
+							 successfully\n");
+	IOH_DEBUG("ioh_pcieqos_pci_init returns %d\n", ret);
+	return ret;
+}
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+  @fn  static void __exit ioh_pcieqos_pci_exit(void)
+  @remarks  Implements the exit functionality of the module.
+  @param  NONE
+  @retval returnvalue	[@ref OUT] contains the result for the concerned
+								 attempt.
+  The result would generally comprise of success code
+  or failure code. The failure code will indicate reason for
+  failure.
+  @see
+  ioh_pcieqos_pci_init
+  */
+static void __exit ioh_pcieqos_pci_exit(void)
+{
+	pci_unregister_driver(&ioh_pcieqos_driver);
+	IOH_DEBUG
+	    ("ioh_pcieqos_pci_exit : Invoked pci_unregister_driver\
+							 successfully\n");
+}
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+  @fn  static int __devinit ioh_pcieqos_probe(struct pci_dev* pdev,
+						 const struct pci_device_id* id)
+  @remarks  Implements the probe functionality of the module.
+  @param  pdev [@ref INOUT] Contains the reference of the pci_dev structure
+  @param  id [@ref INOUT] Contains the reference of the pci_device_id structure
+  @retval returnvalue	[@ref OUT] contains the result for the concerned
+								 attempt.
+  The result would generally comprise of success code
+  or failure code. The failure code will indicate reason for
+  failure.
+  @see
+  ioh_pcieqos_pci_init
+  */
+static int __devinit ioh_pcieqos_probe(struct pci_dev *pdev,
+				       const struct pci_device_id *id)
+{
+
+	char *DRIVER_NAME = "ioh_pcieqos";
+	int ret;
+	unsigned int rom_size;
+
+	ioh_pcieqos_major_no = (ioh_pcieqos_major_no < 0
+				|| ioh_pcieqos_major_no >
+				254) ? 0 : ioh_pcieqos_major_no;
+
+	do {
+
+		ret = pci_enable_device(pdev);
+		if (ret) {
+			IOH_LOG(KERN_ERR,
+				"\nioh_pcieqos_probe : pci_enable_device\
+								 FAILED");
+			break;
+		}
+		IOH_DEBUG("ioh_pcieqos_probe : pci_enable_device returns %d\n",
+			  ret);
+
+		ret = pci_request_regions(pdev, DRIVER_NAME);
+		if (ret) {
+			IOH_LOG(KERN_ERR,
+				"ioh_pcieqos_probe : pci_request_regions\
+								 FAILED");
+			pci_disable_device(pdev);
+			break;
+		}
+		IOH_DEBUG
+		    ("ioh_pcieqos_probe : pci_request_regions returns %d\n",
+		     ret);
+
+		ioh_pcieqos_base_address = (unsigned long)pci_iomap(pdev, 1, 0);
+
+		if (ioh_pcieqos_base_address == 0) {
+			IOH_LOG(KERN_ERR,
+				"ioh_pcieqos_probe : pci_iomap FAILED");
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			ret = -ENOMEM;
+			break;
+		}
+		IOH_DEBUG
+		    ("ioh_pcieqos_probe : pci_iomap SUCCESS and value in\
+				 ioh_pcieqos_base_address variable is 0x%08x\n",
+		     ioh_pcieqos_base_address);
+
+		ioh_pcieqos_extrom_base_address =
+		    (unsigned long)pci_map_rom(pdev, &rom_size);
+		if (ioh_pcieqos_extrom_base_address == 0) {
+			IOH_LOG(KERN_ERR,
+				"ioh_pcieqos_probe : pci_map_rom FAILED");
+			pci_iounmap(pdev, (void *)ioh_pcieqos_base_address);
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			ret = -ENOMEM;
+			break;
+		}
+		IOH_DEBUG
+		    ("ioh_pcieqos_probe : pci_map_rom SUCCESS and value in\
+			 ioh_pcieqos_extrom_base_address variable is 0x%08x\n",
+		     ioh_pcieqos_extrom_base_address);
+
+		if (ioh_pcieqos_major_no) {
+			ioh_pcieqos_dev_no = MKDEV(ioh_pcieqos_major_no, 0);
+			ret =
+			    register_chrdev_region(ioh_pcieqos_dev_no,
+						   IOH_MINOR_NOS, DRIVER_NAME);
+			if (ret) {
+				IOH_LOG(KERN_ERR,
+					"ioh_pcieqos_probe :\
+					 register_chrdev_region FAILED");
+				pci_unmap_rom(pdev,
+					      (void *)
+					      ioh_pcieqos_extrom_base_address);
+				pci_iounmap(pdev,
+					    (void *)ioh_pcieqos_base_address);
+				pci_release_regions(pdev);
+				pci_disable_device(pdev);
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_pcieqos_probe :\
+					 register_chrdev_region returns %d\n",
+			     ret);
+		} else {
+			ret =
+			    alloc_chrdev_region(&ioh_pcieqos_dev_no, 0,
+						IOH_MINOR_NOS, DRIVER_NAME);
+			if (ret) {
+				IOH_LOG(KERN_ERR,
+					"ioh_pcieqos_probe :\
+						 alloc_chrdev_region FAILED");
+				pci_unmap_rom(pdev,
+					      (void *)
+					      ioh_pcieqos_extrom_base_address);
+				pci_iounmap(pdev,
+					    (void *)ioh_pcieqos_base_address);
+				pci_release_regions(pdev);
+				pci_disable_device(pdev);
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_pcieqos_probe :\
+					 alloc_chrdev_region returns %d\n",
+			     ret);
+		}
+
+		cdev_init(&ioh_pcieqos_dev, &ioh_pcieqos_fops);
+		IOH_DEBUG
+		    ("ioh_pcieqos_probe :  cdev_init invoked successfully\n");
+
+		ioh_pcieqos_dev.owner = THIS_MODULE;
+		ioh_pcieqos_dev.ops = &ioh_pcieqos_fops;
+
+		ret =
+		    cdev_add(&ioh_pcieqos_dev, ioh_pcieqos_dev_no,
+			     IOH_MINOR_NOS);
+		if (ret) {
+			IOH_LOG(KERN_ERR,
+				"ioh_pcieqos_probe :  cdev_add FAILED");
+			unregister_chrdev_region(ioh_pcieqos_dev_no,
+						 IOH_MINOR_NOS);
+			pci_unmap_rom(pdev,
+				      (void *)ioh_pcieqos_extrom_base_address);
+			pci_iounmap(pdev, (void *)ioh_pcieqos_base_address);
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			break;
+		}
+		IOH_DEBUG("ioh_pcieqos_probe :  cdev_add returns %d\n", ret);
+
+#ifdef IOH_CAN_PCLK_50MHZ
+		/*set the clock config reg if CAN clock is 50Mhz */
+		IOH_DEBUG
+		    ("ioh_pcieqos_probe : invoking\
+			 ioh_pcieqos_read_modify_write_reg to set CLKCFG reg\
+							 for CAN clk 50Mhz\n");
+		ioh_pcieqos_read_modify_write_reg(CLKCFG_REG_OFFSET,
+						  CLKCFG_CAN_50MHZ,
+						  CLKCFG_CANCLK_MASK);
+#endif
+		return IOH_PCIEQOS_SUCCESS;
+	} while (0);
+	IOH_DEBUG("ioh_pcieqos_probe returns %d\n", ret);
+	return ret;
+}
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+  @fn  static void __devexit ioh_pcieqos_remove(struct pci_dev * pdev)
+  @remarks  Implements the remove functionality of the module.
+  @param  pdev [@ref INOUT] Contains the reference of the pci_dev structure
+  @retval returnvalue	[@ref OUT] contains the result for the concerned
+								 attempt.
+  The result would generally comprise of success code
+  or failure code. The failure code will indicate reason for
+  failure.
+  @see
+  ioh_pcieqos_pci_init
+  */
+static void __devexit ioh_pcieqos_remove(struct pci_dev *pdev)
+{
+
+	cdev_del(&ioh_pcieqos_dev);
+	IOH_DEBUG("ioh_pcieqos_remove - cdev_del Invoked successfully\n");
+
+	unregister_chrdev_region(ioh_pcieqos_dev_no, IOH_MINOR_NOS);
+	IOH_DEBUG
+	    ("ioh_pcieqos_remove - unregister_chrdev_region Invoked\
+							 successfully\n");
+
+	pci_unmap_rom(pdev, (void *)ioh_pcieqos_extrom_base_address);
+
+	pci_iounmap(pdev, (void *)ioh_pcieqos_base_address);
+
+	IOH_DEBUG("ioh_pcieqos_remove - pci_iounmap Invoked successfully\n");
+
+	pci_release_regions(pdev);
+	IOH_DEBUG
+	    ("ioh_pcieqos_remove - pci_release_regions Invoked successfully\n");
+
+	pci_disable_device(pdev);
+	IOH_DEBUG
+	    ("ioh_pcieqos_remove - pci_disable_device Invoked successfully\n");
+
+}
+
+#ifdef CONFIG_PM
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+  @fn static int ioh_pcieqos_suspend(struct pci_dev* pdev,pm_message_t state)
+  @remarks  Implements the suspend functionality of the module.
+  @param  pdev [@ref INOUT] Contains the reference of the pci_dev structure
+  @param  state [@ref INOUT] Contains the reference of the pm_message_t
+								 structure
+  @retval returnvalue	[@ref OUT] contains the result for the concerned
+								 attempt.
+  The result would generally comprise of success code
+  or failure code. The failure code will indicate reason for
+  failure.
+  @see
+  ioh_pcieqos_pci_init
+  ioh_pcieqos_resume
+  */
+static int ioh_pcieqos_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int ret;
+
+	ioh_pcieqos_suspended = true;	/* For blocking further IOCTLs */
+
+	ioh_pcieqos_save_reg_conf();
+	IOH_DEBUG
+	    ("ioh_pcieqos_suspend - ioh_pcieqos_save_reg_conf Invoked\
+							 successfully\n");
+
+	ret = pci_save_state(pdev);
+	if (ret) {
+		IOH_LOG(KERN_ERR,
+			" ioh_pcieqos_suspend -pci_save_state returns-%d\n",
+			ret);
+		return ret;
+	}
+
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	IOH_DEBUG
+	    ("ioh_pcieqos_suspend - pci_enable_wake Invoked successfully\n");
+
+	IOH_DEBUG("ioh_pcieqos_suspend - pci_save_state returns %d\n", ret);
+
+	pci_disable_device(pdev);
+	IOH_DEBUG
+	    ("ioh_pcieqos_suspend - pci_disable_device Invoked successfully\n");
+
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	IOH_DEBUG
+	    ("ioh_pcieqos_suspend - pci_set_power_state Invoked\
+							 successfully\n");
+
+	IOH_DEBUG("ioh_pcieqos_suspend - return %d\n", IOH_PCIEQOS_SUCCESS);
+
+	return IOH_PCIEQOS_SUCCESS;
+}
+
+/*! @ingroup PCIEQOS_PCILayerAPI
+  @fn static int ioh_pcieqos_resume(struct pci_dev* pdev)
+  @remarks  Implements the resume functionality of the module.
+  @param  pdev [@ref INOUT] Contains the reference of the pci_dev structure
+  @retval returnvalue	[@ref OUT] contains the result for the concerned\
+								 attempt.
+  The result would generally comprise of success code
+  or failure code. The failure code will indicate reason for
+  failure.
+  @see
+  ioh_pcieqos_pci_init
+  ioh_pcieqos_suspend
+  */
+static int ioh_pcieqos_resume(struct pci_dev *pdev)
+{
+
+	int ret;
+
+	pci_set_power_state(pdev, PCI_D0);
+	IOH_DEBUG
+	    ("ioh_pcieqos_resume - pci_set_power_state Invoked successfully\n");
+
+	pci_restore_state(pdev);
+	IOH_DEBUG
+	    ("ioh_pcieqos_resume - pci_restore_state Invoked successfully\n");
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		IOH_LOG(KERN_ERR,
+			"ioh_pcieqos_resume-pci_enable_device failed ");
+		return ret;
+	}
+
+	IOH_DEBUG("ioh_pcieqos_resume - pci_enable_device returns -%d\n", ret);
+
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	IOH_DEBUG
+	    ("ioh_pcieqos_resume - pci_enable_wake Invoked successfully\n");
+
+	ioh_pcieqos_restore_reg_conf();
+	IOH_DEBUG
+	    ("ioh_pcieqos_resume - ioh_pcieqos_restore_reg_conf Invoked\
+							 successfully\n");
+
+	ioh_pcieqos_suspended = false;
+
+	IOH_DEBUG("ioh_pcieqos_resume  returns- %d\n", IOH_PCIEQOS_SUCCESS);
+	return IOH_PCIEQOS_SUCCESS;
+}
+
+#endif
-- 
1.7.5.4



-- 
Darren Hart
Intel Open Source Technology Center
Yocto Project - Linux Kernel

View attachment "screenlog.0" of type "text/plain" (61848 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ