public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Topcliff PHUB: Generate PacketHub driver
@ 2010-06-04 10:16 Masayuki Ohtake
  2010-06-04 12:00 ` Alan Cox
  2010-06-07 13:37 ` Arnd Bergmann
  0 siblings, 2 replies; 45+ messages in thread
From: Masayuki Ohtake @ 2010-06-04 10:16 UTC (permalink / raw)
  To: LKML; +Cc: Andrew, Intel OTC, Wang, Qi, Wang, Yong Y, Masayuki Ohtake

From: Masayuki Ohtake <masa-korg@dsn.okisemi.com>

This patch adds the Packet Hub driver for Topcliff.
Patch created against 2.6.33.1

Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
---
 linux-2.6.33.1/drivers/char/Kconfig             |   20 +
 linux-2.6.33.1/drivers/char/Makefile            |    4 +
 linux-2.6.33.1/drivers/char/pch_phub/Makefile   |   11 +
 linux-2.6.33.1/drivers/char/pch_phub/pch_phub.c | 1500 +++++++++++++++++++++++
 linux-2.6.33.1/drivers/char/pch_phub/pch_phub.h |  182 +++
 5 files changed, 1717 insertions(+), 0 deletions(-)
 create mode 100644 linux-2.6.33.1/drivers/char/pch_phub/Makefile
 create mode 100644 linux-2.6.33.1/drivers/char/pch_phub/pch_phub.c
 create mode 100644 linux-2.6.33.1/drivers/char/pch_phub/pch_phub.h

diff --git a/linux-2.6.33.1/drivers/char/Kconfig b/linux-2.6.33.1/drivers/char/Kconfig
index e023682..16a8334 100644
--- a/linux-2.6.33.1/drivers/char/Kconfig
+++ b/linux-2.6.33.1/drivers/char/Kconfig
@@ -4,6 +4,26 @@
 
 menu "Character devices"
 
+config PCH_IEEE1588
+	tristate "PCH IEEE1588"
+	depends on PCI
+	help
+	  If you say yes to this option, support will be included for the
+	  PCH IEEE1588 Host controller.
+
+config PCH_PHUB
+        tristate "PCH PHUB"
+        depends on PCI
+        help
+          If you say yes to this option, support will be included for the
+          PCH Packet Hub Host controller.
+
+config PCH_CAN_PCLK_50MHZ
+	bool "CAN PCLK 50MHz"
+	depends on PCH_PHUB
+        help
+          If you say yes to this option, clock is set to 50MHz.(For CAN control)
+
 config VT
 	bool "Virtual terminal" if EMBEDDED
 	depends on !S390
diff --git a/linux-2.6.33.1/drivers/char/Makefile b/linux-2.6.33.1/drivers/char/Makefile
index f957edf..dc092d0 100644
--- a/linux-2.6.33.1/drivers/char/Makefile
+++ b/linux-2.6.33.1/drivers/char/Makefile
@@ -111,6 +111,10 @@ obj-$(CONFIG_PS3_FLASH)		+= ps3flash.o
 obj-$(CONFIG_JS_RTC)		+= js-rtc.o
 js-rtc-y = rtc.o
 
+obj-$(CONFIG_PCH_IEEE1588)		+= pch_ieee1588/
+
+obj-$(CONFIG_PCH_PHUB)	+= pch_phub/
+
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c
 
diff --git a/linux-2.6.33.1/drivers/char/pch_phub/Makefile b/linux-2.6.33.1/drivers/char/pch_phub/Makefile
new file mode 100644
index 0000000..bfe2a2b
--- /dev/null
+++ b/linux-2.6.33.1/drivers/char/pch_phub/Makefile
@@ -0,0 +1,11 @@
+ifeq ($(CONFIG_PHUB_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o
+#to set CAN clock to 50Mhz
+ifdef CONFIG_PCH_CAN_PCLK_50MHZ
+EXTRA_CFLAGS +=-DPCH_CAN_PCLK_50MHZ
+endif
+
+pch_phub_drv-objs := pch_phub.o
diff --git a/linux-2.6.33.1/drivers/char/pch_phub/pch_phub.c b/linux-2.6.33.1/drivers/char/pch_phub/pch_phub.c
new file mode 100644
index 0000000..162653b
--- /dev/null
+++ b/linux-2.6.33.1/drivers/char/pch_phub/pch_phub.c
@@ -0,0 +1,1500 @@
+/*!
+ * @file pch_phub.c
+ * @brief Provides all the implementation of the interfaces pertaining to
+ *		the Packet Hub 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) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 04/14/2010
+ * 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 <linux/pci.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+
+#include "pch_phub.h"
+
+/*--------------------------------------------
+	macros
+--------------------------------------------*/
+/* Status Register offset */
+#define PHUB_STATUS (0x00)
+/* Control Register offset */
+#define PHUB_CONTROL (0x04)
+/* Time out value for Status Register */
+#define PHUB_TIMEOUT (0x05)
+/* Enabling for writing ROM */
+#define PCH_PHUB_ROM_WRITE_ENABLE (0x01)
+/* Disabling for writing ROM */
+#define PCH_PHUB_ROM_WRITE_DISABLE (0x00)
+/* ROM data area start address offset */
+#define PCH_PHUB_ROM_START_ADDR (0x14)
+/* MAX number of INT_REDUCE_CONTROL registers */
+#define MAX_NUM_INT_REDUCE_CONTROL_REG (128)
+
+/*!
+  @ingroup PHUB_PCILayer
+  @def PCI_DEVICE_ID_PCH1_PHUB
+  @brief Outlines the PCI Device ID.
+  */
+#define PCI_DEVICE_ID_PCH1_PHUB (0x8801)
+
+/*!
+  @ingroup	PHUB_PCILayer
+  @def		PCH_MINOR_NOS
+  @brief	Outlines the Packet Hub minor numbers limit.
+  */
+#define PCH_MINOR_NOS (1)
+
+/*values for configuring CLKCFG reg
+ * for CAN clock of 50Mhz*/
+
+/*!
+  @ingroup	PHUB_PCILayer
+  @def		CLKCFG_CAN_50MHZ
+  @brief	CLKCFG register setting for CAN clock of 50Mhz.
+  */
+#define CLKCFG_CAN_50MHZ (0x12000000)
+
+/*!
+  @ingroup	PHUB_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)
+
+#define MODULE_NAME "pch_phub"
+
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @def		PCH_READ_REG(a)
+  @remarks 	Implements the functionality of reading register.
+  @param	a [@ref IN] Contains the register offset address value
+  @retval	Contains the register value
+  */
+#define PCH_READ_REG(a)	ioread32((pch_phub_base_address + a))
+
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @def		PCH_WRITE_REG(a, b)
+  @remarks	Implements the functionality of writing register.
+  @param	a [@ref IN] Contains the writing value
+  @param	b [@ref IN] Contains the register offset address value
+  @retval	NONE
+  */
+#define PCH_WRITE_REG(a, b)	iowrite32(a, (pch_phub_base_address + b))
+
+/*--------------------------------------------
+	global variables
+--------------------------------------------*/
+struct pch_phub_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 PCH_CAN_PCLK_50MHZ
+	u32 clkcfg_reg;		/* CLK CFG register val */
+#endif
+} g_pch_phub_reg;
+
+s32 pch_phub_opencount;	/* check whether opened or not */
+u32 pch_phub_base_address;
+u32 pch_phub_extrom_base_address;
+s32 pch_phub_suspended;
+
+struct device *dev_dbg;
+
+DEFINE_SPINLOCK(pch_phub_lock);	/* for spin lock */
+
+/**
+ * file_operations structure initialization
+ */
+const struct file_operations pch_phub_fops = {
+	.owner = THIS_MODULE,
+	.open = pch_phub_open,
+	.release = pch_phub_release,
+	.ioctl = pch_phub_ioctl,
+};
+
+/* ToDo: major number allocation via module parameter */
+static dev_t pch_phub_dev_no;
+static int pch_phub_major_no;
+static struct cdev pch_phub_dev;
+
+
+/*--------------------------------------------
+	exported function prototypes
+--------------------------------------------*/
+/*!
+  @ingroup	PHUB_PCILayerAPI
+  @fn		static int __devinit pch_phub_probe(struct pci_dev* pch_pci_dev,
+					 const struct pci_device_id* pci_id)
+  @brief	Provides the functionality of probing the module
+  */
+static int __devinit pch_phub_probe(struct pci_dev *pdev, const
+				       struct pci_device_id *id);
+
+/*!
+  @ingroup	PHUB_PCILayerAPI
+  @fn		static void __devexit pch_phub_remove(
+				struct pci_dev * pch_pci_dev)
+  @brief	Provides the functionality of removing the module
+  */
+static void __devexit pch_phub_remove(struct pci_dev *pdev);
+
+/*!
+  @ingroup	PHUB_PCILayerAPI
+  @fn		static int pch_phub_suspend(struct pci_dev* pDev,
+						pm_message_t state)
+  @brief	Provides the functionality of suspending the module
+  */
+static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state);
+
+/*!
+  @ingroup	PHUB_PCILayerAPI
+  @fn		static int pch_phub_resume(struct pci_dev* pDev)
+  @brief	Provides the functionality of resuming the module
+  */
+static int pch_phub_resume(struct pci_dev *pdev);
+
+/*--------------------------------------------
+	structures
+--------------------------------------------*/
+/*!
+  @ingroup	PHUB_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 pch_phub_pcidev_id[] = {
+
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH1_PHUB)},
+	{0,}
+};
+
+/*!
+  @ingroup	PHUB_PCILayerFacilitators
+  @static	struct pch_phub_driver
+  @brief	It is a structure used for perserving information related to
+		the Packet Hub device and preserves function signatures to
+		manipulate the device.
+  @note	The structure contains the various interfaces aspects
+		provided to the pci layer.
+  @see
+  pch_phub_probe
+  pch_phub_suspend
+  pch_phub_resume
+  pch_phub_remove
+  */
+static struct pci_driver pch_phub_driver = {
+	.name = "pch_phub",
+	.id_table = pch_phub_pcidev_id,
+	.probe = pch_phub_probe,
+	.remove = __devexit_p(pch_phub_remove),
+#ifdef CONFIG_PM
+	.suspend = pch_phub_suspend,
+	.resume = pch_phub_resume
+#endif
+};
+
+/*!
+ * @ingroup	PHUB_PCILayerAPI
+ * @fn		static int __init pch_phub_pci_init(void)
+ * @brief	Provides the functionality of initializing the module
+ * */
+static int __init pch_phub_pci_init(void);
+/*!
+ * @ingroup	PHUB_PCILayerAPI
+ * @fn		static void __exit pch_phub_pci_exit(void)
+ * @brief	Provides the functionality of exiting the module
+ * */
+static void __exit pch_phub_pci_exit(void);
+
+MODULE_DESCRIPTION("PCH PACKET HUB PCI Driver");
+MODULE_LICENSE("GPL");
+module_init(pch_phub_pci_init);
+module_exit(pch_phub_pci_exit);
+module_param(pch_phub_major_no, int, S_IRUSR | S_IWUSR);
+
+
+/*--------------------------------------------
+	functions implementations
+--------------------------------------------*/
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @fn		void pch_phub_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 pch_phub_read_modify_write_reg(unsigned long reg_addr_offset,
+				       unsigned long data, unsigned long mask)
+{
+	unsigned long reg_addr = pch_phub_base_address + reg_addr_offset;
+	iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr);
+
+	return;
+}
+
+
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @fn		void pch_phub_save_reg_conf(void)
+  @remarks	saves register configuration
+  @param	NONE
+  @retval	NONE
+  @see
+  pch_phub_suspend
+  */
+void pch_phub_save_reg_conf(void)
+{
+	u32 i = 0;
+
+	dev_dbg(dev_dbg, "pch_phub_save_reg_conf ENTRY\n");
+	/* to store contents of PHUB_ID register */
+	g_pch_phub_reg.phub_id_reg = PCH_READ_REG(PCH_PHUB_PHUB_ID_REG);
+	/* to store contents of QUEUE_PRI_VAL register */
+	g_pch_phub_reg.q_pri_val_reg = PCH_READ_REG(PCH_PHUB_QUEUE_PRI_VAL_REG);
+	/* to store contents of RC_QUEUE_MAXSIZE register */
+	g_pch_phub_reg.rc_q_maxsize_reg =
+	    PCH_READ_REG(PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
+	/* to store contents of BRI_QUEUE_MAXSIZE register */
+	g_pch_phub_reg.bri_q_maxsize_reg =
+	    PCH_READ_REG(PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
+	/* to store contents of COMP_RESP_TIMEOUT register */
+	g_pch_phub_reg.comp_resp_timeout_reg =
+	    PCH_READ_REG(PCH_PHUB_COMP_RESP_TIMEOUT_REG);
+	/* to store contents of BUS_SLAVE_CONTROL_REG register */
+	g_pch_phub_reg.bus_slave_control_reg =
+	    PCH_READ_REG(PCH_PHUB_BUS_SLAVE_CONTROL_REG);
+	/* to store contents of DEADLOCK_AVOID_TYPE register */
+	g_pch_phub_reg.deadlock_avoid_type_reg =
+	    PCH_READ_REG(PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
+	/* to store contents of INTPIN_REG_WPERMIT register 0 */
+	g_pch_phub_reg.intpin_reg_wpermit_reg0 =
+	    PCH_READ_REG(PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
+	/* to store contents of INTPIN_REG_WPERMIT register 1 */
+	g_pch_phub_reg.intpin_reg_wpermit_reg1 =
+	    PCH_READ_REG(PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
+	/* to store contents of INTPIN_REG_WPERMIT register 2 */
+	g_pch_phub_reg.intpin_reg_wpermit_reg2 =
+	    PCH_READ_REG(PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
+	/* to store contents of INTPIN_REG_WPERMIT register 3 */
+	g_pch_phub_reg.intpin_reg_wpermit_reg3 =
+	    PCH_READ_REG(PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
+	dev_dbg(dev_dbg, "pch_phub_save_reg_conf : "
+		"g_pch_phub_reg.phub_id_reg=%x, "
+		"g_pch_phub_reg.q_pri_val_reg=%x, "
+		"g_pch_phub_reg.rc_q_maxsize_reg=%x, "
+		"g_pch_phub_reg.bri_q_maxsize_reg=%x, "
+		"g_pch_phub_reg.comp_resp_timeout_reg=%x, "
+		"g_pch_phub_reg.bus_slave_control_reg=%x, "
+		"g_pch_phub_reg.deadlock_avoid_type_reg=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg0=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg1=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg2=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg3=%x\n",
+		g_pch_phub_reg.phub_id_reg,
+		g_pch_phub_reg.q_pri_val_reg,
+		g_pch_phub_reg.rc_q_maxsize_reg,
+		g_pch_phub_reg.bri_q_maxsize_reg,
+		g_pch_phub_reg.comp_resp_timeout_reg,
+		g_pch_phub_reg.bus_slave_control_reg,
+		g_pch_phub_reg.deadlock_avoid_type_reg,
+		g_pch_phub_reg.intpin_reg_wpermit_reg0,
+		g_pch_phub_reg.intpin_reg_wpermit_reg1,
+		g_pch_phub_reg.intpin_reg_wpermit_reg2,
+		g_pch_phub_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_pch_phub_reg.int_reduce_control_reg[i] =
+		    PCH_READ_REG(
+			PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+		dev_dbg(dev_dbg, "pch_phub_save_reg_conf : "
+			"g_pch_phub_reg.int_reduce_control_reg[%d]=%x\n",
+			i, g_pch_phub_reg.int_reduce_control_reg[i]);
+	}
+#ifdef PCH_CAN_PCLK_50MHZ
+	/* save clk cfg register */
+	g_pch_phub_reg.clkcfg_reg = PCH_READ_REG(CLKCFG_REG_OFFSET);
+#endif
+	return;
+}
+
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @fn		void pch_phub_restore_reg_conf(void)
+  @remarks	restore register configuration
+  @param	NONE
+  @retval	NONE
+  @see
+  pch_phub_resume
+  */
+
+void pch_phub_restore_reg_conf(void)
+{
+	u32 i = 0;
+
+	dev_dbg(dev_dbg, "pch_phub_restore_reg_conf ENTRY\n");
+	/* to store contents of PHUB_ID register */
+	PCH_WRITE_REG(g_pch_phub_reg.phub_id_reg, PCH_PHUB_PHUB_ID_REG);
+	/* to store contents of QUEUE_PRI_VAL register */
+	PCH_WRITE_REG(g_pch_phub_reg.q_pri_val_reg, PCH_PHUB_QUEUE_PRI_VAL_REG);
+	/* to store contents of RC_QUEUE_MAXSIZE register */
+	PCH_WRITE_REG(g_pch_phub_reg.rc_q_maxsize_reg,
+			PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
+	/* to store contents of BRI_QUEUE_MAXSIZE register */
+	PCH_WRITE_REG(g_pch_phub_reg.bri_q_maxsize_reg,
+			PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
+	/* to store contents of COMP_RESP_TIMEOUT register */
+	PCH_WRITE_REG(g_pch_phub_reg.comp_resp_timeout_reg,
+			PCH_PHUB_COMP_RESP_TIMEOUT_REG);
+	/* to store contents of BUS_SLAVE_CONTROL_REG register */
+	PCH_WRITE_REG(g_pch_phub_reg.bus_slave_control_reg,
+			PCH_PHUB_BUS_SLAVE_CONTROL_REG);
+	/* to store contents of DEADLOCK_AVOID_TYPE register */
+	PCH_WRITE_REG(g_pch_phub_reg.deadlock_avoid_type_reg,
+			PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
+	/* to store contents of INTPIN_REG_WPERMIT register 0 */
+	PCH_WRITE_REG(g_pch_phub_reg.intpin_reg_wpermit_reg0,
+			PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
+	/* to store contents of INTPIN_REG_WPERMIT register 1 */
+	PCH_WRITE_REG(g_pch_phub_reg.intpin_reg_wpermit_reg1,
+			PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
+	/* to store contents of INTPIN_REG_WPERMIT register 2 */
+	PCH_WRITE_REG(g_pch_phub_reg.intpin_reg_wpermit_reg2,
+			PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
+	/* to store contents of INTPIN_REG_WPERMIT register 3 */
+	PCH_WRITE_REG(g_pch_phub_reg.intpin_reg_wpermit_reg3,
+			PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
+	dev_dbg(dev_dbg, "pch_phub_save_reg_conf : "
+		"g_pch_phub_reg.phub_id_reg=%x, "
+		"g_pch_phub_reg.q_pri_val_reg=%x, "
+		"g_pch_phub_reg.rc_q_maxsize_reg=%x, "
+		"g_pch_phub_reg.bri_q_maxsize_reg=%x, "
+		"g_pch_phub_reg.comp_resp_timeout_reg=%x, "
+		"g_pch_phub_reg.bus_slave_control_reg=%x, "
+		"g_pch_phub_reg.deadlock_avoid_type_reg=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg0=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg1=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg2=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg3=%x\n",
+		g_pch_phub_reg.phub_id_reg,
+		g_pch_phub_reg.q_pri_val_reg,
+		g_pch_phub_reg.rc_q_maxsize_reg,
+		g_pch_phub_reg.bri_q_maxsize_reg,
+		g_pch_phub_reg.comp_resp_timeout_reg,
+		g_pch_phub_reg.bus_slave_control_reg,
+		g_pch_phub_reg.deadlock_avoid_type_reg,
+		g_pch_phub_reg.intpin_reg_wpermit_reg0,
+		g_pch_phub_reg.intpin_reg_wpermit_reg1,
+		g_pch_phub_reg.intpin_reg_wpermit_reg2,
+		g_pch_phub_reg.intpin_reg_wpermit_reg3);
+	/* to store contents of INT_REDUCE_CONTROL register */
+	for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
+		PCH_WRITE_REG(g_pch_phub_reg.int_reduce_control_reg[i],
+			PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+		dev_dbg(dev_dbg, "pch_phub_save_reg_conf : "
+			"g_pch_phub_reg.int_reduce_control_reg[%d]=%x\n",
+			i, g_pch_phub_reg.int_reduce_control_reg[i]);
+	}
+
+#ifdef PCH_CAN_PCLK_50MHZ
+	/*restore the clock config reg */
+	PCH_WRITE_REG(g_pch_phub_reg.clkcfg_reg, CLKCFG_REG_OFFSET);
+#endif
+
+	return;
+}
+
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @fn		void pch_phub_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 pch_phub_read_serial_rom(unsigned long offset_address, unsigned char *data)
+{
+	unsigned long mem_addr = pch_phub_extrom_base_address + offset_address;
+
+	dev_dbg(dev_dbg,
+		"pch_phub_read_serial_rom:mem_addr=0x%08x\n", mem_addr);
+	*data = ioread8(mem_addr);
+
+	return 0;
+}
+
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @fn		void pch_phub_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 pch_phub_write_serial_rom(unsigned long offset_address, unsigned char data)
+{
+	int retval = 0;
+	unsigned long mem_addr = pch_phub_extrom_base_address + offset_address;
+	int i = 0;
+	unsigned long word_data = 0;
+
+	dev_dbg(dev_dbg,
+		"pch_phub_write_serial_rom:mem_addr=0x%08x\n", mem_addr);
+	iowrite32(PCH_PHUB_ROM_WRITE_ENABLE,
+			pch_phub_extrom_base_address + PHUB_CONTROL);
+
+	word_data = ioread32(mem_addr & 0xFFFFFFFC);
+	dev_dbg(dev_dbg, "word_data=0x%08x  data=0x%02x\n",
+		 word_data, data);
+	switch (mem_addr % 4) {
+	case 0:
+		word_data &= 0xFFFFFF00;
+		iowrite32((word_data | (unsigned long)data),
+				(mem_addr & 0xFFFFFFFC));
+		break;
+	case 1:
+		word_data &= 0xFFFF00FF;
+		iowrite32((word_data | ((unsigned long)data << 8)),
+				(mem_addr & 0xFFFFFFFC));
+		break;
+	case 2:
+		word_data &= 0xFF00FFFF;
+		iowrite32((word_data | ((unsigned long)data << 16)),
+				(mem_addr & 0xFFFFFFFC));
+		break;
+	case 3:
+		word_data &= 0x00FFFFFF;
+		iowrite32((word_data | ((unsigned long)data << 24)),
+				(mem_addr & 0xFFFFFFFC));
+		break;
+	}
+	while (0x00 !=
+	       ioread8(pch_phub_extrom_base_address + PHUB_STATUS)) {
+		msleep(1);
+		if (PHUB_TIMEOUT == i) {
+			retval = -EPERM;
+			break;
+		}
+		i++;
+	}
+
+	iowrite32(PCH_PHUB_ROM_WRITE_DISABLE,
+			pch_phub_extrom_base_address + PHUB_CONTROL);
+
+	return retval;
+}
+
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @fn		void pch_phub_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 pch_phub_read_serial_rom_val(unsigned long offset_address,
+				    unsigned char *data)
+{
+	int retval = 0;
+	unsigned long mem_addr;
+
+	mem_addr = (offset_address / 4 * 8) + 3 -
+			(offset_address % 4) + PCH_PHUB_ROM_START_ADDR;
+	retval = pch_phub_read_serial_rom(mem_addr, data);
+
+	return retval;
+}
+
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @fn		void pch_phub_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 pch_phub_write_serial_rom_val(unsigned long offset_address,
+				     unsigned char data)
+{
+	int retval = 0;
+	unsigned long mem_addr;
+
+	mem_addr =
+	    (offset_address / 4 * 8) + 3 - (offset_address % 4) +
+	    PCH_PHUB_ROM_START_ADDR;
+	retval = pch_phub_write_serial_rom(mem_addr, data);
+
+	return retval;
+}
+
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @fn		int pch_phub_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 pch_phub_gbe_serial_rom_conf(void)
+{
+	int retval = 0;
+
+	retval |= pch_phub_write_serial_rom(0x0b, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x0a, 0x10);
+	retval |= pch_phub_write_serial_rom(0x09, 0x01);
+	retval |= pch_phub_write_serial_rom(0x08, 0x02);
+
+	retval |= pch_phub_write_serial_rom(0x0f, 0x00);
+	retval |= pch_phub_write_serial_rom(0x0e, 0x00);
+	retval |= pch_phub_write_serial_rom(0x0d, 0x00);
+	retval |= pch_phub_write_serial_rom(0x0c, 0x80);
+
+	retval |= pch_phub_write_serial_rom(0x13, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x12, 0x10);
+	retval |= pch_phub_write_serial_rom(0x11, 0x01);
+	retval |= pch_phub_write_serial_rom(0x10, 0x18);
+
+	retval |= pch_phub_write_serial_rom(0x1b, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x1a, 0x10);
+	retval |= pch_phub_write_serial_rom(0x19, 0x01);
+	retval |= pch_phub_write_serial_rom(0x18, 0x19);
+
+	retval |= pch_phub_write_serial_rom(0x23, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x22, 0x10);
+	retval |= pch_phub_write_serial_rom(0x21, 0x01);
+	retval |= pch_phub_write_serial_rom(0x20, 0x3a);
+
+	retval |= pch_phub_write_serial_rom(0x27, 0x01);
+	retval |= pch_phub_write_serial_rom(0x26, 0x00);
+	retval |= pch_phub_write_serial_rom(0x25, 0x00);
+	retval |= pch_phub_write_serial_rom(0x24, 0x00);
+
+	return retval;
+}
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @fn		int pch_phub_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 pch_phub_read_gbe_mac_addr(unsigned long offset_address,
+				  unsigned char *data)
+{
+	int retval = 0;
+
+	retval = pch_phub_read_serial_rom_val(offset_address, data);
+
+	return retval;
+}
+
+/*!
+  @ingroup	PHUB_HALLayerAPI
+  @fn		int pch_phub_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 pch_phub_write_gbe_mac_addr(unsigned long offset_address,
+				   unsigned char data)
+{
+	int retval = 0;
+
+	retval = pch_phub_gbe_serial_rom_conf();
+	retval |= pch_phub_write_serial_rom_val(offset_address, data);
+
+	return retval;
+}
+
+/*!
+  @ingroup	PHUB_InterfaceLayerAPI
+  @fn		int pch_phub_open( struct inode *inode,struct file *file)
+  @remarks	Implements the Initializing and opening of
+		the Packet Hub 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 pch_phub_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	spin_lock(&pch_phub_lock);
+	dev_dbg(dev_dbg, "pch_phub_open : open count value = %d",
+		  pch_phub_opencount);
+	if (pch_phub_opencount) {
+		dev_dbg(dev_dbg, "pch_phub_open :  device already opened\n");
+		ret = -EBUSY;
+	} else {
+		pch_phub_opencount++;
+		ret = 0;
+	}
+	spin_unlock(&pch_phub_lock);
+
+	dev_dbg(dev_dbg, "pch_phub_open returns=%d\n", ret);
+	return ret;
+}
+
+/*!
+  @ingroup	PHUB_InterfaceLayerAPI
+  @fn		int pch_phub_release(struct inode *inode,struct file *file)
+  @remarks	Implements the release functionality of the Packet Hub 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 pch_phub_release(struct inode *inode, struct file *file)
+{
+	spin_lock(&pch_phub_lock);
+
+	if (pch_phub_opencount > 0)
+		pch_phub_opencount--;
+	spin_unlock(&pch_phub_lock);
+
+	dev_dbg(dev_dbg, "pch_phub_release : "
+		"pch_phub_opencount=%d  returning=%d\n",
+		pch_phub_opencount, 0);
+	return 0;
+}
+
+/*!
+  @ingroup	PHUB_InterfaceLayerAPI
+  @fn		int pch_phub_ioctl(struct inode * inode,struct file * file,
+					 unsigned int cmd,unsigned long arg)
+  @remarks	Implements the various ioctl functionalities of
+		the Packet Hub module.
+  @param	inode
+		[@ref INOUT] Contains the reference of the inode structure
+  @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
+  */
+#if 0
+int pch_phub_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	int ret_value = 0;
+	struct pch_phub_reqt *p_pch_phub_reqt;
+	unsigned long addr_offset;
+	unsigned long data;
+	unsigned long mask;
+
+	do {
+		if (pch_phub_suspended == true) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"suspend initiated returning =%d\n",
+				-EPERM);
+			ret_value = -EPERM;
+			break;
+		}
+
+		p_pch_phub_reqt = (struct pch_phub_reqt *)arg;
+		ret_value =
+			copy_from_user((void *)&addr_offset,
+				(void *)&p_pch_phub_reqt->addr_offset,
+				sizeof(addr_offset));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_from_user fail returning =%d\n",
+				-EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		dev_dbg(dev_dbg, "pch_phub_ioctl : "
+			"copy_from_user returns =%d\n", ret_value);
+
+		/* Access area check */
+		switch (cmd) {
+		case IOCTL_PHUB_READ_REG:
+		case IOCTL_PHUB_WRITE_REG:
+		case IOCTL_PHUB_READ_MODIFY_WRITE_REG:
+			if (addr_offset >= 0x504)
+				ret_value = -EPERM;
+			break;
+		case IOCTL_PHUB_READ_OROM:
+		case IOCTL_PHUB_WRITE_OROM:
+		case IOCTL_PHUB_READ_MAC_ADDR:
+		case IOCTL_PHUB_WRITE_MAC_ADDR:
+			if (addr_offset >= 0x10000)
+				ret_value = -EPERM;
+			break;
+		}
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"access area is wrong returning =%d\n",
+				-EPERM);
+			break;
+		}
+		/* End of Access area check */
+
+		switch (cmd) {
+		case IOCTL_PHUB_READ_REG:
+			data = PCH_READ_REG(addr_offset);
+			dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+				"PCH_READ_REG successfully\n");
+
+			ret_value =
+			    copy_to_user((void *)&p_pch_phub_reqt->data,
+					 (void *)&data, sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_to_user fail returning =%d\n",
+					-EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			break;
+		case IOCTL_PHUB_WRITE_REG:
+			ret_value = copy_from_user((void *)&data,
+						(void *)&p_pch_phub_reqt->data,
+						sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_from_user fail returning =%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			PCH_WRITE_REG(data, addr_offset);
+			dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+				"PCH_WRITE_REG successfully\n");
+			break;
+		case IOCTL_PHUB_READ_MODIFY_WRITE_REG:
+			ret_value = copy_from_user((void *)&data,
+						   (void *)&p_pch_phub_reqt->
+						   data, sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+						"copy_from_user fail "
+						"returning =%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			ret_value = copy_from_user((void *)&mask,
+						   (void *)&p_pch_phub_reqt->
+						   mask, sizeof(mask));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_from_user fail "
+					"returning =%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			pch_phub_read_modify_write_reg(addr_offset, data, mask);
+			dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+				"pch_phub_read_modify_write_reg "
+				"successfully\n");
+			break;
+		case IOCTL_PHUB_READ_OROM:
+			ret_value = pch_phub_read_serial_rom(addr_offset,
+							(unsigned char *)&data);
+			if (ret_value) {
+				dev_dbg(dev_dbg,
+					"pch_phub_ioctl : Invoked "
+					"pch_phub_read_serial_rom "
+					"=%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			} else {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+					"pch_phub_read_serial_rom "
+					"successfully\n");
+			}
+			ret_value = copy_to_user((void *)&p_pch_phub_reqt->
+						 data, (void *)&data,
+						 sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_to_user fail returning "
+					"=%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			break;
+		case IOCTL_PHUB_WRITE_OROM:
+			ret_value =
+			    copy_from_user((void *)&data,
+					   (void *)&p_pch_phub_reqt->
+					   data, sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_from_user fail returning "
+					"=%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			ret_value =
+				pch_phub_write_serial_rom(addr_offset, data);
+			if (ret_value) {
+				dev_dbg(dev_dbg,
+					"pch_phub_ioctl : Invoked "
+					"pch_phub_write_serial_rom "
+					"=%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			} else {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+					"pch_phub_write_serial_rom "
+					"successfully\n");
+			}
+			break;
+		case IOCTL_PHUB_READ_MAC_ADDR:
+			pch_phub_read_gbe_mac_addr(addr_offset,
+					 (unsigned char *)&data);
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_read_gbe_mac_addr successfully\n");
+
+			ret_value =
+			    copy_to_user((void *)&p_pch_phub_reqt->data,
+					 (void *)&data, sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_to_user fail "
+					"returning =%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			break;
+		case IOCTL_PHUB_WRITE_MAC_ADDR:
+			ret_value =
+			    copy_from_user((void *)&data,
+					   (void *)&p_pch_phub_reqt->data,
+					   sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_from_user fail "
+					"returning =%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			pch_phub_write_gbe_mac_addr(addr_offset, data);
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+					"pch_phub_write_gbe_mac_addr "
+					"successfully\n");
+			break;
+		default:
+			dev_dbg(dev_dbg, "pch_write_ioctl invalid "
+				"command returning=%d\n", -EINVAL);
+			ret_value = -EINVAL;
+			break;
+		}
+		break;
+
+	} while (0);
+
+
+	dev_dbg(dev_dbg, "pch_write_ioctl returns=%d\n", ret_value);
+	return ret_value;
+}
+#endif
+int pch_phub_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	int ret_value = 0;
+	struct pch_phub_reqt *p_pch_phub_reqt;
+	unsigned long addr_offset;
+	unsigned long data;
+	unsigned long mask;
+
+	if (pch_phub_suspended == true) {
+		dev_dbg(dev_dbg, "pch_phub_ioctl : "
+			"suspend initiated returning =%d\n", -EPERM);
+		ret_value = -EPERM;
+		goto return_ioctrl;
+	}
+
+	p_pch_phub_reqt = (struct pch_phub_reqt *)arg;
+	ret_value = copy_from_user((void *)&addr_offset,
+				(void *)&p_pch_phub_reqt->addr_offset,
+				sizeof(addr_offset));
+	if (ret_value) {
+		dev_dbg(dev_dbg, "pch_phub_ioctl : "
+			"copy_from_user fail returning =%d\n", -EFAULT);
+		ret_value = -EFAULT;
+		goto return_ioctrl;
+	}
+	dev_dbg(dev_dbg, "pch_phub_ioctl : "
+		"copy_from_user returns =%d\n", ret_value);
+
+	/* Access area check */
+	switch (cmd) {
+	case IOCTL_PHUB_READ_REG:
+	case IOCTL_PHUB_WRITE_REG:
+	case IOCTL_PHUB_READ_MODIFY_WRITE_REG:
+		if (addr_offset >= 0x504)
+			ret_value = -EPERM;
+		break;
+	case IOCTL_PHUB_READ_OROM:
+	case IOCTL_PHUB_WRITE_OROM:
+	case IOCTL_PHUB_READ_MAC_ADDR:
+	case IOCTL_PHUB_WRITE_MAC_ADDR:
+		if (addr_offset >= 0x10000)
+			ret_value = -EPERM;
+		break;
+	}
+	if (ret_value) {
+		dev_dbg(dev_dbg, "pch_phub_ioctl : "
+			"access area is wrong returning =%d\n", -EPERM);
+		goto return_ioctrl;
+	}
+	/* End of Access area check */
+
+	switch (cmd) {
+	case IOCTL_PHUB_READ_REG:
+		data = PCH_READ_REG(addr_offset);
+		dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+			"PCH_READ_REG successfully\n");
+
+		ret_value = copy_to_user((void *)&p_pch_phub_reqt->data,
+					 (void *)&data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_to_user fail returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		break;
+	case IOCTL_PHUB_WRITE_REG:
+		ret_value = copy_from_user((void *)&data,
+					(void *)&p_pch_phub_reqt->data,
+					sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_from_user fail returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		PCH_WRITE_REG(data, addr_offset);
+		dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+				"PCH_WRITE_REG successfully\n");
+		break;
+	case IOCTL_PHUB_READ_MODIFY_WRITE_REG:
+		ret_value = copy_from_user((void *)&data,
+			   (void *)&p_pch_phub_reqt->data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : copy_from_user fail "
+					"returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		ret_value = copy_from_user((void *)&mask,
+			   (void *)&p_pch_phub_reqt->mask, sizeof(mask));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : copy_from_user fail "
+					"returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		pch_phub_read_modify_write_reg(addr_offset, data, mask);
+		dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+			"pch_phub_read_modify_write_reg successfully\n");
+		break;
+	case IOCTL_PHUB_READ_OROM:
+		ret_value = pch_phub_read_serial_rom(addr_offset,
+							(unsigned char *)&data);
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_read_serial_rom =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		} else {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_read_serial_rom successfully\n");
+		}
+		ret_value = copy_to_user((void *)&p_pch_phub_reqt->data,
+						(void *)&data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_to_user fail returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		break;
+	case IOCTL_PHUB_WRITE_OROM:
+		ret_value = copy_from_user((void *)&data,
+			   (void *)&p_pch_phub_reqt->data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_from_user fail returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		ret_value = pch_phub_write_serial_rom(addr_offset, data);
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_write_serial_rom =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		} else {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_write_serial_rom successfully\n");
+		}
+		break;
+	case IOCTL_PHUB_READ_MAC_ADDR:
+		pch_phub_read_gbe_mac_addr(addr_offset, (unsigned char *)&data);
+		dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_read_gbe_mac_addr successfully\n");
+
+		ret_value = copy_to_user((void *)&p_pch_phub_reqt->data,
+						 (void *)&data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : copy_to_user fail "
+					"returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		break;
+	case IOCTL_PHUB_WRITE_MAC_ADDR:
+		ret_value = copy_from_user((void *)&data,
+			   (void *)&p_pch_phub_reqt->data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : copy_from_user fail "
+					"returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		pch_phub_write_gbe_mac_addr(addr_offset, data);
+		dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_write_gbe_mac_addr successfully\n");
+		break;
+	default:
+		dev_dbg(dev_dbg, "pch_write_ioctl invalid "
+				"command returning=%d\n", -EINVAL);
+		ret_value = -EINVAL;
+		break;
+	}
+return_ioctrl:
+	dev_dbg(dev_dbg, "pch_write_ioctl returns=%d\n", ret_value);
+	return ret_value;
+}
+
+/*!
+  @ingroup	PHUB_PCILayerAPI
+  @fn		static int __init pch_phub_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
+	  pch_phub_pci_exit
+  */
+static int __init pch_phub_pci_init(void)
+{
+	s32 ret;
+	ret = pci_register_driver(&pch_phub_driver);
+	dev_dbg(dev_dbg, "pch_phub_pci_init : "
+			"Invoked pci_register_driver successfully   "
+			"returns = %d\n", ret);
+	return ret;
+}
+
+/*!
+  @ingroup	PHUB_PCILayerAPI
+  @fn		static void __exit pch_phub_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
+	  pch_phub_pci_init
+  */
+static void __exit pch_phub_pci_exit(void)
+{
+	pci_unregister_driver(&pch_phub_driver);
+	dev_dbg(dev_dbg, "pch_phub_pci_exit : "
+			"Invoked pci_unregister_driver successfully\n");
+}
+
+/*!
+  @ingroup	PHUB_PCILayerAPI
+  @fn		static int __devinit pch_phub_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
+	  pch_phub_pci_init
+  */
+static int __devinit pch_phub_probe(struct pci_dev *pdev,
+				       const struct pci_device_id *id)
+{
+
+	char *DRIVER_NAME = "pch_phub";
+	int ret;
+	unsigned int rom_size;
+
+	dev_dbg = &pdev->dev;
+
+	pch_phub_major_no = (pch_phub_major_no < 0 || pch_phub_major_no > 254) ?
+				0 : pch_phub_major_no;
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		dev_dbg(dev_dbg, "\npch_phub_probe : pci_enable_device FAILED");
+		goto err_probe;
+	}
+	dev_dbg(dev_dbg, "pch_phub_probe : "
+			"pci_enable_device returns %d\n", ret);
+
+	ret = pci_request_regions(pdev, DRIVER_NAME);
+	if (ret) {
+		dev_dbg(dev_dbg, "pch_phub_probe : pci_request_regions FAILED");
+		pci_disable_device(pdev);
+		goto err_probe;
+	}
+	dev_dbg(dev_dbg, "pch_phub_probe : "
+		"pci_request_regions returns %d\n", ret);
+
+	pch_phub_base_address = (unsigned long)pci_iomap(pdev, 1, 0);
+
+	if (pch_phub_base_address == 0) {
+		dev_dbg(dev_dbg, "pch_phub_probe : pci_iomap FAILED");
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		ret = -ENOMEM;
+		goto err_probe;
+	}
+	dev_dbg(dev_dbg, "pch_phub_probe : pci_iomap SUCCESS and value "
+		"in pch_phub_base_address variable is 0x%08x\n",
+		pch_phub_base_address);
+
+	pch_phub_extrom_base_address =
+	    (unsigned long)pci_map_rom(pdev, &rom_size);
+	if (pch_phub_extrom_base_address == 0) {
+		dev_dbg(dev_dbg, "pch_phub_probe : pci_map_rom FAILED");
+		pci_iounmap(pdev, (void *)pch_phub_base_address);
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		ret = -ENOMEM;
+		goto err_probe;
+	}
+	dev_dbg(dev_dbg, "pch_phub_probe : "
+		"pci_map_rom SUCCESS and value in "
+		"pch_phub_extrom_base_address variable is 0x%08x\n",
+		pch_phub_extrom_base_address);
+
+	if (pch_phub_major_no) {
+		pch_phub_dev_no = MKDEV(pch_phub_major_no, 0);
+		ret = register_chrdev_region(pch_phub_dev_no,
+					   PCH_MINOR_NOS, DRIVER_NAME);
+		if (ret) {
+			dev_dbg(dev_dbg, "pch_phub_probe : "
+				"register_chrdev_region FAILED");
+			pci_unmap_rom(pdev,
+					(void *)pch_phub_extrom_base_address);
+			pci_iounmap(pdev, (void *)pch_phub_base_address);
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			goto err_probe;
+		}
+		dev_dbg(dev_dbg, "pch_phub_probe : "
+				"register_chrdev_region returns %d\n", ret);
+	} else {
+		ret = alloc_chrdev_region(&pch_phub_dev_no, 0,
+						PCH_MINOR_NOS, DRIVER_NAME);
+		if (ret) {
+			dev_dbg(dev_dbg, "pch_phub_probe : "
+					"alloc_chrdev_region FAILED");
+			pci_unmap_rom(pdev,
+				      (void *)pch_phub_extrom_base_address);
+			pci_iounmap(pdev,
+				    (void *)pch_phub_base_address);
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			goto err_probe;
+		}
+		dev_dbg(dev_dbg, "pch_phub_probe : "
+			"alloc_chrdev_region returns %d\n", ret);
+	}
+
+	cdev_init(&pch_phub_dev, &pch_phub_fops);
+	dev_dbg(dev_dbg, "pch_phub_probe :  cdev_init invoked successfully\n");
+
+	pch_phub_dev.owner = THIS_MODULE;
+	pch_phub_dev.ops = &pch_phub_fops;
+
+	ret = cdev_add(&pch_phub_dev, pch_phub_dev_no, PCH_MINOR_NOS);
+	if (ret) {
+		dev_dbg(dev_dbg, "pch_phub_probe :  cdev_add FAILED");
+		unregister_chrdev_region(pch_phub_dev_no, PCH_MINOR_NOS);
+		pci_unmap_rom(pdev, (void *)pch_phub_extrom_base_address);
+		pci_iounmap(pdev, (void *)pch_phub_base_address);
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		goto err_probe;
+	}
+	dev_dbg(dev_dbg, "pch_phub_probe :  cdev_add returns %d\n", ret);
+
+#ifdef PCH_CAN_PCLK_50MHZ
+	/*set the clock config reg if CAN clock is 50Mhz */
+	dev_dbg(dev_dbg, "pch_phub_probe : invoking "
+		"pch_phub_read_modify_write_reg "
+		"to set CLKCFG reg for CAN clk 50Mhz\n");
+	pch_phub_read_modify_write_reg(CLKCFG_REG_OFFSET,
+					  CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK);
+#endif
+	/* set the prefech value */
+	PCH_WRITE_REG(0x000ffffa, 0x14);
+	/* set the interrupt delay value */
+	PCH_WRITE_REG(0x25, 0x44);
+	return 0;
+
+err_probe:
+	dev_dbg(dev_dbg, "pch_phub_probe returns %d\n", ret);
+	return ret;
+}
+
+/*!
+  @ingroup	PHUB_PCILayerAPI
+  @fn		static void __devexit pch_phub_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
+		pch_phub_pci_init
+  */
+static void __devexit pch_phub_remove(struct pci_dev *pdev)
+{
+
+	cdev_del(&pch_phub_dev);
+	dev_dbg(dev_dbg, "pch_phub_remove - cdev_del Invoked successfully\n");
+
+	unregister_chrdev_region(pch_phub_dev_no, PCH_MINOR_NOS);
+	dev_dbg(dev_dbg, "pch_phub_remove - "
+		"unregister_chrdev_region Invoked successfully\n");
+
+	pci_unmap_rom(pdev, (void *)pch_phub_extrom_base_address);
+
+	pci_iounmap(pdev, (void *)pch_phub_base_address);
+
+	dev_dbg(dev_dbg, "pch_phub_remove - "
+			"pci_iounmap Invoked successfully\n");
+
+	pci_release_regions(pdev);
+	dev_dbg(dev_dbg, "pch_phub_remove - "
+		"pci_release_regions Invoked successfully\n");
+
+	pci_disable_device(pdev);
+	dev_dbg(dev_dbg, "pch_phub_remove - "
+		"pci_disable_device Invoked successfully\n");
+
+}
+
+#ifdef CONFIG_PM
+
+/*!
+  @ingroup	PHUB_PCILayerAPI
+  @fn		static int pch_phub_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
+		pch_phub_pci_init
+		pch_phub_resume
+  */
+static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int ret;
+
+	pch_phub_suspended = true;	/* For blocking further IOCTLs */
+
+	pch_phub_save_reg_conf();
+	dev_dbg(dev_dbg, "pch_phub_suspend - "
+		"pch_phub_save_reg_conf Invoked successfully\n");
+
+	ret = pci_save_state(pdev);
+	if (ret) {
+		dev_dbg(dev_dbg,
+			" pch_phub_suspend -pci_save_state returns-%d\n", ret);
+		return ret;
+	}
+	dev_dbg(dev_dbg, "pch_phub_suspend - pci_save_state returns %d\n", ret);
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	dev_dbg(dev_dbg, "pch_phub_suspend - "
+			"pci_enable_wake Invoked successfully\n");
+
+	pci_disable_device(pdev);
+	dev_dbg(dev_dbg, "pch_phub_suspend - "
+			"pci_disable_device Invoked successfully\n");
+
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	dev_dbg(dev_dbg, "pch_phub_suspend - "
+			"pci_set_power_state Invoked successfully   "
+			"return = %d\n", 0);
+
+	return 0;
+}
+
+/*!
+  @ingroup	PHUB_PCILayerAPI
+  @fn		static int pch_phub_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
+		pch_phub_pci_init
+		pch_phub_suspend
+  */
+static int pch_phub_resume(struct pci_dev *pdev)
+{
+
+	int ret;
+
+	pci_set_power_state(pdev, PCI_D0);
+	dev_dbg(dev_dbg, "pch_phub_resume - "
+		"pci_set_power_state Invoked successfully\n");
+
+	pci_restore_state(pdev);
+	dev_dbg(dev_dbg, "pch_phub_resume - "
+		"pci_restore_state Invoked successfully\n");
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		dev_dbg(dev_dbg, "pch_phub_resume-pci_enable_device failed ");
+		return ret;
+	}
+
+	dev_dbg(dev_dbg, "pch_phub_resume - "
+			"pci_enable_device returns -%d\n", ret);
+
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	dev_dbg(dev_dbg, "pch_phub_resume - "
+			"pci_enable_wake Invoked successfully\n");
+
+	pch_phub_restore_reg_conf();
+	dev_dbg(dev_dbg, "pch_phub_resume - "
+		"pch_phub_restore_reg_conf Invoked successfully\n");
+
+	pch_phub_suspended = false;
+
+	dev_dbg(dev_dbg, "pch_phub_resume  returns- %d\n", 0);
+	return 0;
+}
+#endif /* CONFIG_PM */
diff --git a/linux-2.6.33.1/drivers/char/pch_phub/pch_phub.h b/linux-2.6.33.1/drivers/char/pch_phub/pch_phub.h
new file mode 100644
index 0000000..009ae1e
--- /dev/null
+++ b/linux-2.6.33.1/drivers/char/pch_phub/pch_phub.h
@@ -0,0 +1,182 @@
+#ifndef __PCH_PHUB_H__
+#define __PCH_PHUB_H__
+/*!
+ * @file pch_phub.h
+ * @brief Provides all the interfaces pertaining to the Packet Hub 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) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 04/14/2010
+ * modified:
+ *
+ */
+
+/*! @defgroup PHUB */
+/*! @defgroup PHUB_Global  				Global
+  @ingroup PHUB */
+/*! @defgroup PHUB_GlobalGeneral			General
+  @ingroup PHUB_Global */
+/*! @defgroup PHUB_GlobalResultCodes			StatusCodes
+  @ingroup PHUB_Global */
+/*! @defgroup PHUB_InterfaceLayer			InterfaceLayer
+  @ingroup PHUB */
+/*! @defgroup PHUB_InterfaceLayerAPI  			Providers
+  @ingroup PHUB_InterfaceLayer
+  */
+/*! @defgroup PHUB_InterfaceLayerNotifyRoutines  	Notifiers
+  @ingroup PHUB_InterfaceLayer
+  */
+/*! @defgroup PHUB_PCILayer				PCILayer
+  @ingroup PHUB */
+/*! @defgroup PHUB_PCILayerAPI  			Providers
+  @ingroup PHUB_PCILayer
+  */
+/*! @defgroup PHUB_PCILayerFacilitators  		Facilitators
+  @ingroup PHUB_PCILayer
+  */
+/*! @defgroup PHUB_HALLayer				HALLayer
+  @ingroup PHUB */
+/*! @defgroup PHUB_HALLayerAPI  			Providers
+  @ingroup PHUB_HALLayer
+  */
+/*! @defgroup PHUB_HALLayerFacilitators  		Facilitators
+  @ingroup PHUB_HALLayer
+  */
+/*! @defgroup PHUB_Utilities				Utilities
+  @ingroup PHUB */
+/*! @defgroup PHUB_UtilitiesAPI  			Providers
+  @ingroup PHUB_Utilities
+  */
+
+/*! @ingroup PHUB_InterfaceLayer
+  @def PHUB_IOCTL_MAGIC
+  @brief Outlines the ioctl magic.
+  */
+#define PHUB_IOCTL_MAGIC 		(0xf7)
+
+/*! @ingroup PHUB_InterfaceLayer
+  @def IOCTL_PHUB_READ_REG
+  @brief Outlines the read register function signature.
+  */
+#define IOCTL_PHUB_READ_REG (_IOW(PHUB_IOCTL_MAGIC, 1, unsigned long))
+
+/*! @ingroup PHUB_InterfaceLayer
+  @def IOCTL_PHUB_WRITE_REG
+  @brief Outlines the write register function signature.
+  */
+#define IOCTL_PHUB_WRITE_REG (_IOW(PHUB_IOCTL_MAGIC, 2, unsigned long))
+
+/*! @ingroup PHUB_InterfaceLayer
+  @def IOCTL_PHUB_READ_MODIFY_WRITE_REG
+  @brief Outlines the read, modify and write register function signature.
+  */
+#define IOCTL_PHUB_READ_MODIFY_WRITE_REG (_IOW(PHUB_IOCTL_MAGIC, 3,\
+								 unsigned long))
+
+/*! @ingroup PHUB_InterfaceLayer
+  @def IOCTL_PHUB_READ_OROM
+  @brief Outlines the read option rom function signature.
+  */
+#define IOCTL_PHUB_READ_OROM (_IOW(PHUB_IOCTL_MAGIC, 4, unsigned long))
+
+/*! @ingroup PHUB_InterfaceLayer
+  @def IOCTL_PHUB_WRITE_OROM
+  @brief Outlines the write option rom function signature.
+  */
+#define IOCTL_PHUB_WRITE_OROM (_IOW(PHUB_IOCTL_MAGIC, 5, unsigned long))
+
+/*! @ingroup PHUB_InterfaceLayer
+  @def IOCTL_PHUB_READ_MAC_ADDR
+  @brief Outlines the read mac address function signature.
+  */
+#define IOCTL_PHUB_READ_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 6, unsigned long))
+
+/*! @ingroup PHUB_InterfaceLayer
+  @def IOCTL_PHUB_WRITE_MAC_ADDR
+  @brief Outlines the write mac address function signature.
+  */
+#define IOCTL_PHUB_WRITE_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 7, unsigned long))
+
+
+/* Registers address offset */
+#define PCH_PHUB_PHUB_ID_REG			(0x0000)
+#define PCH_PHUB_QUEUE_PRI_VAL_REG			(0x0004)
+#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG		(0x0008)
+#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG		(0x000C)
+#define PCH_PHUB_COMP_RESP_TIMEOUT_REG		(0x0010)
+#define PCH_PHUB_BUS_SLAVE_CONTROL_REG		(0x0014)
+#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG		(0x0018)
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0		(0x0020)
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1		(0x0024)
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2		(0x0028)
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3		(0x002C)
+#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE	(0x0040)
+#define CLKCFG_REG_OFFSET           		(0x500)
+
+/*structures*/
+/*! @ingroup PHUB_InterfaceLayer
+  @struct pch_phub_reqt
+  @brief It is a structure used for perserving information related to the
+  Packet Hub request.
+  @note
+  The concerned details should be provided during the read register,
+   write register and read / modify / write register.
+  @see
+  pch_phub_ioctl
+  */
+struct pch_phub_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 PHUB_InterfaceLayerAPI
+  @fn nt pch_phub_open( struct inode *inode,struct file *file )
+  @brief  Provides the functionality of initialization of the module
+  */
+int pch_phub_open(struct inode *inode, struct file *file);
+
+/*! @ingroup PHUB_InterfaceLayerAPI
+  @fn int pch_phub_release(struct inode *inode,struct file *file)
+  @brief  Provides the functionality of releasing the module
+  */
+int pch_phub_release(struct inode *inode, struct file *file);
+
+/*! @ingroup PHUB_InterfaceLayerAPI
+  @fn int pch_phub_ioctl(struct inode * inode,struct file * file,
+							 unsigned int cmd,
+  unsigned long arg)
+  @brief  Provides the functionality of invoking various functionalities of
+								 the Packet Hub.
+  */
+int pch_phub_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		      unsigned long arg);
+
+/**global variables*/
+extern u32 pch_phub_base_address;	/* base address */
+extern s32 pch_phub_suspended;		/* suspend status */
+
+extern s32 pch_phub_opencount;
+extern spinlock_t pch_phub_lock;
+extern const struct file_operations pch_phub_fops;
+#endif
-- 1.6.2.2 

^ permalink raw reply related	[flat|nested] 45+ messages in thread
* [PATCH] Topcliff PHUB: Generate PacketHub driver
@ 2010-06-07 12:39 Masayuki Ohtak
  2010-06-07 15:05 ` Alan Cox
  2010-06-14 12:09 ` Masayuki Ohtak
  0 siblings, 2 replies; 45+ messages in thread
From: Masayuki Ohtak @ 2010-06-07 12:39 UTC (permalink / raw)
  To: Alan Cox; +Cc: Masayuki Ohtake, LKML, Andrew, Intel OTC, Wang, Qi, Wang, Yong Y

Hi Alan,

We have modified for the following your indication.
Please confirm.

> > +/*!

> > + * @ingroup	PHUB_PCILayerAPI

> > + * @fn		static void __exit pch_phub_pci_exit(void)

> > + * @brief	Provides the functionality of exiting the module

> > + * */



> Can we please do something about all this stuff first so the code is

> easier to review by those not familiar with the kernel format.



> I sent a bit of code out last time that did most of the work



> Alan


Thanks.
Masayuki Ohtake

Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
---
 linux-2.6.33.1/drivers/char/Kconfig             |   20 +
 linux-2.6.33.1/drivers/char/Makefile            |    4 +
 linux-2.6.33.1/drivers/char/pch_phub/Makefile   |   11 +
 linux-2.6.33.1/drivers/char/pch_phub/pch_phub.c | 1232 +++++++++++++++++++++++
 linux-2.6.33.1/drivers/char/pch_phub/pch_phub.h |   96 ++
 5 files changed, 1363 insertions(+), 0 deletions(-)
 create mode 100644 linux-2.6.33.1/drivers/char/pch_phub/Makefile
 create mode 100755 linux-2.6.33.1/drivers/char/pch_phub/pch_phub.c
 create mode 100755 linux-2.6.33.1/drivers/char/pch_phub/pch_phub.h

diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index e023682..16a8334 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -4,6 +4,26 @@
 
 menu "Character devices"
 
+config PCH_IEEE1588
+	tristate "PCH IEEE1588"
+	depends on PCI
+	help
+	  If you say yes to this option, support will be included for the
+	  PCH IEEE1588 Host controller.
+
+config PCH_PHUB
+        tristate "PCH PHUB"
+        depends on PCI
+        help
+          If you say yes to this option, support will be included for the
+          PCH Packet Hub Host controller.
+
+config PCH_CAN_PCLK_50MHZ
+	bool "CAN PCLK 50MHz"
+	depends on PCH_PHUB
+        help
+          If you say yes to this option, clock is set to 50MHz.(For CAN control)
+
 config VT
 	bool "Virtual terminal" if EMBEDDED
 	depends on !S390
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index f957edf..dc092d0 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -111,6 +111,10 @@ obj-$(CONFIG_PS3_FLASH)		+= ps3flash.o
 obj-$(CONFIG_JS_RTC)		+= js-rtc.o
 js-rtc-y = rtc.o
 
+obj-$(CONFIG_PCH_IEEE1588)		+= pch_ieee1588/
+
+obj-$(CONFIG_PCH_PHUB)	+= pch_phub/
+
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c
 
diff --git a/drivers/char/pch_phub/Makefile b/drivers/char/pch_phub/Makefile
new file mode 100644
index 0000000..bfe2a2b
--- /dev/null
+++ b/drivers/char/pch_phub/Makefile
@@ -0,0 +1,11 @@
+ifeq ($(CONFIG_PHUB_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o
+#to set CAN clock to 50Mhz
+ifdef CONFIG_PCH_CAN_PCLK_50MHZ
+EXTRA_CFLAGS +=-DPCH_CAN_PCLK_50MHZ
+endif
+
+pch_phub_drv-objs := pch_phub.o
diff --git a/drivers/char/pch_phub/pch_phub.c b/drivers/char/pch_phub/pch_phub.c
new file mode 100755
index 0000000..da5b92e
--- /dev/null
+++ b/drivers/char/pch_phub/pch_phub.c
@@ -0,0 +1,1232 @@
+/*!
+ * @file pch_phub.c
+ * @brief Provides all the implementation of the interfaces pertaining to
+ *		the Packet Hub 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) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 04/14/2010
+ * 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 <linux/pci.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+
+#include "pch_phub.h"
+
+/*--------------------------------------------
+	macros
+--------------------------------------------*/
+/* Status Register offset */
+#define PHUB_STATUS (0x00)
+/* Control Register offset */
+#define PHUB_CONTROL (0x04)
+/* Time out value for Status Register */
+#define PHUB_TIMEOUT (0x05)
+/* Enabling for writing ROM */
+#define PCH_PHUB_ROM_WRITE_ENABLE (0x01)
+/* Disabling for writing ROM */
+#define PCH_PHUB_ROM_WRITE_DISABLE (0x00)
+/* ROM data area start address offset */
+#define PCH_PHUB_ROM_START_ADDR (0x14)
+/* MAX number of INT_REDUCE_CONTROL registers */
+#define MAX_NUM_INT_REDUCE_CONTROL_REG (128)
+
+#define PCI_DEVICE_ID_PCH1_PHUB (0x8801)
+
+#define PCH_MINOR_NOS (1)
+#define CLKCFG_CAN_50MHZ (0x12000000)
+#define CLKCFG_CANCLK_MASK (0xFF000000)
+
+#define MODULE_NAME "pch_phub"
+
+#define PCH_READ_REG(a)	ioread32((pch_phub_base_address + a))
+
+#define PCH_WRITE_REG(a, b)	iowrite32(a, (pch_phub_base_address + b))
+
+/*--------------------------------------------
+	global variables
+--------------------------------------------*/
+struct pch_phub_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 PCH_CAN_PCLK_50MHZ
+	u32 clkcfg_reg;		/* CLK CFG register val */
+#endif
+} g_pch_phub_reg;
+
+s32 pch_phub_opencount;	/* check whether opened or not */
+u32 pch_phub_base_address;
+u32 pch_phub_extrom_base_address;
+s32 pch_phub_suspended;
+
+struct device *dev_dbg;
+
+DEFINE_SPINLOCK(pch_phub_lock);	/* for spin lock */
+
+/**
+ * file_operations structure initialization
+ */
+const struct file_operations pch_phub_fops = {
+	.owner = THIS_MODULE,
+	.open = pch_phub_open,
+	.release = pch_phub_release,
+	.ioctl = pch_phub_ioctl,
+};
+
+/* ToDo: major number allocation via module parameter */
+static dev_t pch_phub_dev_no;
+static int pch_phub_major_no;
+static struct cdev pch_phub_dev;
+
+
+/*--------------------------------------------
+	exported function prototypes
+--------------------------------------------*/
+static int __devinit pch_phub_probe(struct pci_dev *pdev, const
+				       struct pci_device_id *id);
+static void __devexit pch_phub_remove(struct pci_dev *pdev);
+static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state);
+static int pch_phub_resume(struct pci_dev *pdev);
+
+/*--------------------------------------------
+	structures
+--------------------------------------------*/
+static struct pci_device_id pch_phub_pcidev_id[] = {
+
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH1_PHUB)},
+	{0,}
+};
+
+
+static struct pci_driver pch_phub_driver = {
+	.name = "pch_phub",
+	.id_table = pch_phub_pcidev_id,
+	.probe = pch_phub_probe,
+	.remove = __devexit_p(pch_phub_remove),
+#ifdef CONFIG_PM
+	.suspend = pch_phub_suspend,
+	.resume = pch_phub_resume
+#endif
+};
+
+static int __init pch_phub_pci_init(void);
+static void __exit pch_phub_pci_exit(void);
+
+MODULE_DESCRIPTION("PCH PACKET HUB PCI Driver");
+MODULE_LICENSE("GPL");
+module_init(pch_phub_pci_init);
+module_exit(pch_phub_pci_exit);
+module_param(pch_phub_major_no, int, S_IRUSR | S_IWUSR);
+
+
+/*--------------------------------------------
+	functions implementations
+--------------------------------------------*/
+/** pch_phub_read_modify_write_reg - Implements the functionality of reading,
+ * 						modifying and writing register.
+ *  @reg_addr_offset:  Contains the register offset address value
+ *  @data:             Contains the writing value
+ *  @mask:             Contains the mask value
+ */
+void pch_phub_read_modify_write_reg(unsigned long reg_addr_offset,
+				       unsigned long data, unsigned long mask)
+{
+	unsigned long reg_addr = pch_phub_base_address + reg_addr_offset;
+	iowrite32(((ioread32((void __iomem *)reg_addr) & ~mask)) | data,
+			(void __iomem *)reg_addr);
+	return;
+}
+
+
+/** pch_phub_save_reg_conf - saves register configuration
+ */
+void pch_phub_save_reg_conf(void)
+{
+	u32 i = 0;
+
+	dev_dbg(dev_dbg, "pch_phub_save_reg_conf ENTRY\n");
+	/* to store contents of PHUB_ID register */
+	g_pch_phub_reg.phub_id_reg = PCH_READ_REG(PCH_PHUB_PHUB_ID_REG);
+	/* to store contents of QUEUE_PRI_VAL register */
+	g_pch_phub_reg.q_pri_val_reg = PCH_READ_REG(PCH_PHUB_QUEUE_PRI_VAL_REG);
+	/* to store contents of RC_QUEUE_MAXSIZE register */
+	g_pch_phub_reg.rc_q_maxsize_reg =
+	    PCH_READ_REG(PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
+	/* to store contents of BRI_QUEUE_MAXSIZE register */
+	g_pch_phub_reg.bri_q_maxsize_reg =
+	    PCH_READ_REG(PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
+	/* to store contents of COMP_RESP_TIMEOUT register */
+	g_pch_phub_reg.comp_resp_timeout_reg =
+	    PCH_READ_REG(PCH_PHUB_COMP_RESP_TIMEOUT_REG);
+	/* to store contents of BUS_SLAVE_CONTROL_REG register */
+	g_pch_phub_reg.bus_slave_control_reg =
+	    PCH_READ_REG(PCH_PHUB_BUS_SLAVE_CONTROL_REG);
+	/* to store contents of DEADLOCK_AVOID_TYPE register */
+	g_pch_phub_reg.deadlock_avoid_type_reg =
+	    PCH_READ_REG(PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
+	/* to store contents of INTPIN_REG_WPERMIT register 0 */
+	g_pch_phub_reg.intpin_reg_wpermit_reg0 =
+	    PCH_READ_REG(PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
+	/* to store contents of INTPIN_REG_WPERMIT register 1 */
+	g_pch_phub_reg.intpin_reg_wpermit_reg1 =
+	    PCH_READ_REG(PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
+	/* to store contents of INTPIN_REG_WPERMIT register 2 */
+	g_pch_phub_reg.intpin_reg_wpermit_reg2 =
+	    PCH_READ_REG(PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
+	/* to store contents of INTPIN_REG_WPERMIT register 3 */
+	g_pch_phub_reg.intpin_reg_wpermit_reg3 =
+	    PCH_READ_REG(PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
+	dev_dbg(dev_dbg, "pch_phub_save_reg_conf : "
+		"g_pch_phub_reg.phub_id_reg=%x, "
+		"g_pch_phub_reg.q_pri_val_reg=%x, "
+		"g_pch_phub_reg.rc_q_maxsize_reg=%x, "
+		"g_pch_phub_reg.bri_q_maxsize_reg=%x, "
+		"g_pch_phub_reg.comp_resp_timeout_reg=%x, "
+		"g_pch_phub_reg.bus_slave_control_reg=%x, "
+		"g_pch_phub_reg.deadlock_avoid_type_reg=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg0=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg1=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg2=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg3=%x\n",
+		g_pch_phub_reg.phub_id_reg,
+		g_pch_phub_reg.q_pri_val_reg,
+		g_pch_phub_reg.rc_q_maxsize_reg,
+		g_pch_phub_reg.bri_q_maxsize_reg,
+		g_pch_phub_reg.comp_resp_timeout_reg,
+		g_pch_phub_reg.bus_slave_control_reg,
+		g_pch_phub_reg.deadlock_avoid_type_reg,
+		g_pch_phub_reg.intpin_reg_wpermit_reg0,
+		g_pch_phub_reg.intpin_reg_wpermit_reg1,
+		g_pch_phub_reg.intpin_reg_wpermit_reg2,
+		g_pch_phub_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_pch_phub_reg.int_reduce_control_reg[i] =
+		    PCH_READ_REG(
+			PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+		dev_dbg(dev_dbg, "pch_phub_save_reg_conf : "
+			"g_pch_phub_reg.int_reduce_control_reg[%d]=%x\n",
+			i, g_pch_phub_reg.int_reduce_control_reg[i]);
+	}
+#ifdef PCH_CAN_PCLK_50MHZ
+	/* save clk cfg register */
+	g_pch_phub_reg.clkcfg_reg = PCH_READ_REG(CLKCFG_REG_OFFSET);
+#endif
+	return;
+}
+
+/** pch_phub_restore_reg_conf - restore register configuration
+ */
+
+void pch_phub_restore_reg_conf(void)
+{
+	u32 i = 0;
+
+	dev_dbg(dev_dbg, "pch_phub_restore_reg_conf ENTRY\n");
+	/* to store contents of PHUB_ID register */
+	PCH_WRITE_REG(g_pch_phub_reg.phub_id_reg, PCH_PHUB_PHUB_ID_REG);
+	/* to store contents of QUEUE_PRI_VAL register */
+	PCH_WRITE_REG(g_pch_phub_reg.q_pri_val_reg, PCH_PHUB_QUEUE_PRI_VAL_REG);
+	/* to store contents of RC_QUEUE_MAXSIZE register */
+	PCH_WRITE_REG(g_pch_phub_reg.rc_q_maxsize_reg,
+			PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
+	/* to store contents of BRI_QUEUE_MAXSIZE register */
+	PCH_WRITE_REG(g_pch_phub_reg.bri_q_maxsize_reg,
+			PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
+	/* to store contents of COMP_RESP_TIMEOUT register */
+	PCH_WRITE_REG(g_pch_phub_reg.comp_resp_timeout_reg,
+			PCH_PHUB_COMP_RESP_TIMEOUT_REG);
+	/* to store contents of BUS_SLAVE_CONTROL_REG register */
+	PCH_WRITE_REG(g_pch_phub_reg.bus_slave_control_reg,
+			PCH_PHUB_BUS_SLAVE_CONTROL_REG);
+	/* to store contents of DEADLOCK_AVOID_TYPE register */
+	PCH_WRITE_REG(g_pch_phub_reg.deadlock_avoid_type_reg,
+			PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
+	/* to store contents of INTPIN_REG_WPERMIT register 0 */
+	PCH_WRITE_REG(g_pch_phub_reg.intpin_reg_wpermit_reg0,
+			PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
+	/* to store contents of INTPIN_REG_WPERMIT register 1 */
+	PCH_WRITE_REG(g_pch_phub_reg.intpin_reg_wpermit_reg1,
+			PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
+	/* to store contents of INTPIN_REG_WPERMIT register 2 */
+	PCH_WRITE_REG(g_pch_phub_reg.intpin_reg_wpermit_reg2,
+			PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
+	/* to store contents of INTPIN_REG_WPERMIT register 3 */
+	PCH_WRITE_REG(g_pch_phub_reg.intpin_reg_wpermit_reg3,
+			PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
+	dev_dbg(dev_dbg, "pch_phub_save_reg_conf : "
+		"g_pch_phub_reg.phub_id_reg=%x, "
+		"g_pch_phub_reg.q_pri_val_reg=%x, "
+		"g_pch_phub_reg.rc_q_maxsize_reg=%x, "
+		"g_pch_phub_reg.bri_q_maxsize_reg=%x, "
+		"g_pch_phub_reg.comp_resp_timeout_reg=%x, "
+		"g_pch_phub_reg.bus_slave_control_reg=%x, "
+		"g_pch_phub_reg.deadlock_avoid_type_reg=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg0=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg1=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg2=%x, "
+		"g_pch_phub_reg.intpin_reg_wpermit_reg3=%x\n",
+		g_pch_phub_reg.phub_id_reg,
+		g_pch_phub_reg.q_pri_val_reg,
+		g_pch_phub_reg.rc_q_maxsize_reg,
+		g_pch_phub_reg.bri_q_maxsize_reg,
+		g_pch_phub_reg.comp_resp_timeout_reg,
+		g_pch_phub_reg.bus_slave_control_reg,
+		g_pch_phub_reg.deadlock_avoid_type_reg,
+		g_pch_phub_reg.intpin_reg_wpermit_reg0,
+		g_pch_phub_reg.intpin_reg_wpermit_reg1,
+		g_pch_phub_reg.intpin_reg_wpermit_reg2,
+		g_pch_phub_reg.intpin_reg_wpermit_reg3);
+	/* to store contents of INT_REDUCE_CONTROL register */
+	for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
+		PCH_WRITE_REG(g_pch_phub_reg.int_reduce_control_reg[i],
+			PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+		dev_dbg(dev_dbg, "pch_phub_save_reg_conf : "
+			"g_pch_phub_reg.int_reduce_control_reg[%d]=%x\n",
+			i, g_pch_phub_reg.int_reduce_control_reg[i]);
+	}
+
+#ifdef PCH_CAN_PCLK_50MHZ
+	/*restore the clock config reg */
+	PCH_WRITE_REG(g_pch_phub_reg.clkcfg_reg, CLKCFG_REG_OFFSET);
+#endif
+
+	return;
+}
+
+/** pch_phub_read_serial_rom - Implements the functionality of reading Serial
+ *  									 ROM.
+ *  @offset_address: Contains the Serial ROM address offset value
+ *  @data: Contains the Serial ROM value
+ */
+int pch_phub_read_serial_rom(unsigned long offset_address, unsigned char *data)
+{
+	unsigned long mem_addr = pch_phub_extrom_base_address + offset_address;
+
+	dev_dbg(dev_dbg,
+		"pch_phub_read_serial_rom:mem_addr=0x%08x\n", (u32)mem_addr);
+	*data = ioread8((void __iomem *)mem_addr);
+
+	return 0;
+}
+
+/** pch_phub_write_serial_rom - Implements the functionality of writing Serial
+ *  									 ROM.
+ *  @offset_address: Contains the Serial ROM address offset value
+ *  @data: Contains the Serial ROM value
+ */
+int pch_phub_write_serial_rom(unsigned long offset_address, unsigned char data)
+{
+	int retval = 0;
+	unsigned long mem_addr = pch_phub_extrom_base_address + offset_address;
+	int i = 0;
+	unsigned long word_data = 0;
+
+	dev_dbg(dev_dbg,
+		"pch_phub_write_serial_rom:mem_addr=0x%08x\n", (u32)mem_addr);
+	iowrite32(PCH_PHUB_ROM_WRITE_ENABLE, (void __iomem *)
+			(pch_phub_extrom_base_address + PHUB_CONTROL));
+
+	word_data = ioread32((void __iomem *)(mem_addr & 0xFFFFFFFC));
+	dev_dbg(dev_dbg, "word_data=0x%08x  data=0x%02x\n",
+		 (u32)word_data, data);
+	switch (mem_addr % 4) {
+	case 0:
+		word_data &= 0xFFFFFF00;
+		iowrite32((word_data | (unsigned long)data),
+				(void __iomem *)(mem_addr & 0xFFFFFFFC));
+		break;
+	case 1:
+		word_data &= 0xFFFF00FF;
+		iowrite32((word_data | ((unsigned long)data << 8)),
+				(void __iomem *)(mem_addr & 0xFFFFFFFC));
+		break;
+	case 2:
+		word_data &= 0xFF00FFFF;
+		iowrite32((word_data | ((unsigned long)data << 16)),
+				(void __iomem *)(mem_addr & 0xFFFFFFFC));
+		break;
+	case 3:
+		word_data &= 0x00FFFFFF;
+		iowrite32((word_data | ((unsigned long)data << 24)),
+				(void __iomem *)(mem_addr & 0xFFFFFFFC));
+		break;
+	}
+	while (0x00 !=
+	       ioread8((void __iomem *)
+			 (pch_phub_extrom_base_address + PHUB_STATUS))) {
+		msleep(1);
+		if (PHUB_TIMEOUT == i) {
+			retval = -EPERM;
+			break;
+		}
+		i++;
+	}
+
+	iowrite32(PCH_PHUB_ROM_WRITE_DISABLE, (void __iomem *)
+			(pch_phub_extrom_base_address + PHUB_CONTROL));
+
+	return retval;
+}
+
+/** pch_phub_read_serial_rom_val - Implements the functionality of reading
+ *  							 Serial ROM value.
+ *  @offset_address: Contains the Serial ROM address offset value
+ *  @data: Contains the Serial ROM value
+ */
+int pch_phub_read_serial_rom_val(unsigned long offset_address,
+				    unsigned char *data)
+{
+	int retval = 0;
+	unsigned long mem_addr;
+
+	mem_addr = (offset_address / 4 * 8) + 3 -
+			(offset_address % 4) + PCH_PHUB_ROM_START_ADDR;
+	retval = pch_phub_read_serial_rom(mem_addr, data);
+
+	return retval;
+}
+
+/** pch_phub_write_serial_rom_val - Implements the functionality of writing
+ *  							 Serial ROM value.
+ *  @offset_address: Contains the Serial ROM address offset value
+ *  @data: Contains the Serial ROM value
+ */
+int pch_phub_write_serial_rom_val(unsigned long offset_address,
+				     unsigned char data)
+{
+	int retval = 0;
+	unsigned long mem_addr;
+
+	mem_addr =
+	    (offset_address / 4 * 8) + 3 - (offset_address % 4) +
+	    PCH_PHUB_ROM_START_ADDR;
+	retval = pch_phub_write_serial_rom(mem_addr, data);
+
+	return retval;
+}
+
+/** pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration
+ *  						for Gigabit Ethernet MAC address
+ */
+int pch_phub_gbe_serial_rom_conf(void)
+{
+	int retval = 0;
+
+	retval |= pch_phub_write_serial_rom(0x0b, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x0a, 0x10);
+	retval |= pch_phub_write_serial_rom(0x09, 0x01);
+	retval |= pch_phub_write_serial_rom(0x08, 0x02);
+
+	retval |= pch_phub_write_serial_rom(0x0f, 0x00);
+	retval |= pch_phub_write_serial_rom(0x0e, 0x00);
+	retval |= pch_phub_write_serial_rom(0x0d, 0x00);
+	retval |= pch_phub_write_serial_rom(0x0c, 0x80);
+
+	retval |= pch_phub_write_serial_rom(0x13, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x12, 0x10);
+	retval |= pch_phub_write_serial_rom(0x11, 0x01);
+	retval |= pch_phub_write_serial_rom(0x10, 0x18);
+
+	retval |= pch_phub_write_serial_rom(0x1b, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x1a, 0x10);
+	retval |= pch_phub_write_serial_rom(0x19, 0x01);
+	retval |= pch_phub_write_serial_rom(0x18, 0x19);
+
+	retval |= pch_phub_write_serial_rom(0x23, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x22, 0x10);
+	retval |= pch_phub_write_serial_rom(0x21, 0x01);
+	retval |= pch_phub_write_serial_rom(0x20, 0x3a);
+
+	retval |= pch_phub_write_serial_rom(0x27, 0x01);
+	retval |= pch_phub_write_serial_rom(0x26, 0x00);
+	retval |= pch_phub_write_serial_rom(0x25, 0x00);
+	retval |= pch_phub_write_serial_rom(0x24, 0x00);
+
+	return retval;
+}
+/** pch_phub_read_gbe_mac_addr - Contains the Gigabit Ethernet MAC address
+ *  								offset value
+ *  @offset_address: Gigabit Ethernet MAC address offset value
+ *  @data: Contains the Gigabit Ethernet MAC address value
+ */
+int pch_phub_read_gbe_mac_addr(unsigned long offset_address,
+				  unsigned char *data)
+{
+	int retval = 0;
+
+	retval = pch_phub_read_serial_rom_val(offset_address, data);
+
+	return retval;
+}
+
+/** pch_phub_write_gbe_mac_addr - Write MAC address
+ *  @offset_address: Contains the Gigabit Ethernet MAC address offset value
+ *  @data: Contains the Gigabit Ethernet MAC address value
+ */
+int pch_phub_write_gbe_mac_addr(unsigned long offset_address,
+				   unsigned char data)
+{
+	int retval = 0;
+
+	retval = pch_phub_gbe_serial_rom_conf();
+	retval |= pch_phub_write_serial_rom_val(offset_address, data);
+
+	return retval;
+}
+
+/** pch_phub_open - Implements the Initializing and opening of the Packet Hub
+									 module.
+ *  @inode: Contains the reference of the inode structure
+ *  @file: Contains the reference of the file structure
+ */
+int pch_phub_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	spin_lock(&pch_phub_lock);
+	dev_dbg(dev_dbg, "pch_phub_open : open count value = %d",
+		  pch_phub_opencount);
+	if (pch_phub_opencount) {
+		dev_dbg(dev_dbg, "pch_phub_open :  device already opened\n");
+		ret = -EBUSY;
+	} else {
+		pch_phub_opencount++;
+		ret = 0;
+	}
+	spin_unlock(&pch_phub_lock);
+
+	dev_dbg(dev_dbg, "pch_phub_open returns=%d\n", ret);
+	return ret;
+}
+
+/** pch_phub_release - Implements the release functionality of the Packet Hub
+ *  									 module.
+ *  @inode: Contains the reference of the inode structure
+ *  @file: Contains the reference of the file structure
+ */
+int pch_phub_release(struct inode *inode, struct file *file)
+{
+	spin_lock(&pch_phub_lock);
+
+	if (pch_phub_opencount > 0)
+		pch_phub_opencount--;
+	spin_unlock(&pch_phub_lock);
+
+	dev_dbg(dev_dbg, "pch_phub_release : "
+		"pch_phub_opencount=%d  returning=%d\n",
+		pch_phub_opencount, 0);
+	return 0;
+}
+
+/** pch_phub_ioctl - Implements the various ioctl functionalities of the Packet
+ *  								 Hub module.
+ *  @inode: Contains the reference of the inode structure
+ *  @file: Contains the reference of the file structure
+ *  @cmd: Contains the command value
+ *  @arg: Contains the command argument value
+ */
+#if 0
+int pch_phub_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	int ret_value = 0;
+	struct pch_phub_reqt *p_pch_phub_reqt;
+	unsigned long addr_offset;
+	unsigned long data;
+	unsigned long mask;
+
+	do {
+		if (pch_phub_suspended == true) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"suspend initiated returning =%d\n",
+				-EPERM);
+			ret_value = -EPERM;
+			break;
+		}
+
+		p_pch_phub_reqt = (struct pch_phub_reqt *)arg;
+		ret_value =
+			copy_from_user((void *)&addr_offset,
+				(void *)&p_pch_phub_reqt->addr_offset,
+				sizeof(addr_offset));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_from_user fail returning =%d\n",
+				-EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		dev_dbg(dev_dbg, "pch_phub_ioctl : "
+			"copy_from_user returns =%d\n", ret_value);
+
+		/* Access area check */
+		switch (cmd) {
+		case IOCTL_PHUB_READ_REG:
+		case IOCTL_PHUB_WRITE_REG:
+		case IOCTL_PHUB_READ_MODIFY_WRITE_REG:
+			if (addr_offset >= 0x504)
+				ret_value = -EPERM;
+			break;
+		case IOCTL_PHUB_READ_OROM:
+		case IOCTL_PHUB_WRITE_OROM:
+		case IOCTL_PHUB_READ_MAC_ADDR:
+		case IOCTL_PHUB_WRITE_MAC_ADDR:
+			if (addr_offset >= 0x10000)
+				ret_value = -EPERM;
+			break;
+		}
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"access area is wrong returning =%d\n",
+				-EPERM);
+			break;
+		}
+		/* End of Access area check */
+
+		switch (cmd) {
+		case IOCTL_PHUB_READ_REG:
+			data = PCH_READ_REG(addr_offset);
+			dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+				"PCH_READ_REG successfully\n");
+
+			ret_value =
+			    copy_to_user((void *)&p_pch_phub_reqt->data,
+					 (void *)&data, sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_to_user fail returning =%d\n",
+					-EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			break;
+		case IOCTL_PHUB_WRITE_REG:
+			ret_value = copy_from_user((void *)&data,
+						(void *)&p_pch_phub_reqt->data,
+						sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_from_user fail returning =%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			PCH_WRITE_REG(data, addr_offset);
+			dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+				"PCH_WRITE_REG successfully\n");
+			break;
+		case IOCTL_PHUB_READ_MODIFY_WRITE_REG:
+			ret_value = copy_from_user((void *)&data,
+						   (void *)&p_pch_phub_reqt->
+						   data, sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+						"copy_from_user fail "
+						"returning =%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			ret_value = copy_from_user((void *)&mask,
+						   (void *)&p_pch_phub_reqt->
+						   mask, sizeof(mask));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_from_user fail "
+					"returning =%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			pch_phub_read_modify_write_reg(addr_offset, data, mask);
+			dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+				"pch_phub_read_modify_write_reg "
+				"successfully\n");
+			break;
+		case IOCTL_PHUB_READ_OROM:
+			ret_value = pch_phub_read_serial_rom(addr_offset,
+							(unsigned char *)&data);
+			if (ret_value) {
+				dev_dbg(dev_dbg,
+					"pch_phub_ioctl : Invoked "
+					"pch_phub_read_serial_rom "
+					"=%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			} else {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+					"pch_phub_read_serial_rom "
+					"successfully\n");
+			}
+			ret_value = copy_to_user((void *)&p_pch_phub_reqt->
+						 data, (void *)&data,
+						 sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_to_user fail returning "
+					"=%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			break;
+		case IOCTL_PHUB_WRITE_OROM:
+			ret_value =
+			    copy_from_user((void *)&data,
+					   (void *)&p_pch_phub_reqt->
+					   data, sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_from_user fail returning "
+					"=%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			ret_value =
+				pch_phub_write_serial_rom(addr_offset, data);
+			if (ret_value) {
+				dev_dbg(dev_dbg,
+					"pch_phub_ioctl : Invoked "
+					"pch_phub_write_serial_rom "
+					"=%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			} else {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+					"pch_phub_write_serial_rom "
+					"successfully\n");
+			}
+			break;
+		case IOCTL_PHUB_READ_MAC_ADDR:
+			pch_phub_read_gbe_mac_addr(addr_offset,
+					 (unsigned char *)&data);
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_read_gbe_mac_addr successfully\n");
+
+			ret_value =
+			    copy_to_user((void *)&p_pch_phub_reqt->data,
+					 (void *)&data, sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_to_user fail "
+					"returning =%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			break;
+		case IOCTL_PHUB_WRITE_MAC_ADDR:
+			ret_value =
+			    copy_from_user((void *)&data,
+					   (void *)&p_pch_phub_reqt->data,
+					   sizeof(data));
+			if (ret_value) {
+				dev_dbg(dev_dbg, "pch_phub_ioctl : "
+					"copy_from_user fail "
+					"returning =%d\n", -EFAULT);
+				ret_value = -EFAULT;
+				break;
+			}
+			pch_phub_write_gbe_mac_addr(addr_offset, data);
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+					"pch_phub_write_gbe_mac_addr "
+					"successfully\n");
+			break;
+		default:
+			dev_dbg(dev_dbg, "pch_write_ioctl invalid "
+				"command returning=%d\n", -EINVAL);
+			ret_value = -EINVAL;
+			break;
+		}
+		break;
+
+	} while (0);
+
+
+	dev_dbg(dev_dbg, "pch_write_ioctl returns=%d\n", ret_value);
+	return ret_value;
+}
+#endif
+int pch_phub_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	int ret_value = 0;
+	struct pch_phub_reqt *p_pch_phub_reqt;
+	unsigned long addr_offset;
+	unsigned long data;
+	unsigned long mask;
+
+	if (pch_phub_suspended == true) {
+		dev_dbg(dev_dbg, "pch_phub_ioctl : "
+			"suspend initiated returning =%d\n", -EPERM);
+		ret_value = -EPERM;
+		goto return_ioctrl;
+	}
+
+	p_pch_phub_reqt = (struct pch_phub_reqt *)arg;
+	ret_value = copy_from_user((void *)&addr_offset,
+				(void *)&p_pch_phub_reqt->addr_offset,
+				sizeof(addr_offset));
+	if (ret_value) {
+		dev_dbg(dev_dbg, "pch_phub_ioctl : "
+			"copy_from_user fail returning =%d\n", -EFAULT);
+		ret_value = -EFAULT;
+		goto return_ioctrl;
+	}
+	dev_dbg(dev_dbg, "pch_phub_ioctl : "
+		"copy_from_user returns =%d\n", ret_value);
+
+	/* Access area check */
+	switch (cmd) {
+	case IOCTL_PHUB_READ_REG:
+	case IOCTL_PHUB_WRITE_REG:
+	case IOCTL_PHUB_READ_MODIFY_WRITE_REG:
+		if (addr_offset >= 0x504)
+			ret_value = -EPERM;
+		break;
+	case IOCTL_PHUB_READ_OROM:
+	case IOCTL_PHUB_WRITE_OROM:
+	case IOCTL_PHUB_READ_MAC_ADDR:
+	case IOCTL_PHUB_WRITE_MAC_ADDR:
+		if (addr_offset >= 0x10000)
+			ret_value = -EPERM;
+		break;
+	}
+	if (ret_value) {
+		dev_dbg(dev_dbg, "pch_phub_ioctl : "
+			"access area is wrong returning =%d\n", -EPERM);
+		goto return_ioctrl;
+	}
+	/* End of Access area check */
+
+	switch (cmd) {
+	case IOCTL_PHUB_READ_REG:
+		data = PCH_READ_REG((void __iomem *)addr_offset);
+		dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+			"PCH_READ_REG successfully\n");
+
+		ret_value = copy_to_user((void *)&p_pch_phub_reqt->data,
+					 (void *)&data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_to_user fail returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		break;
+	case IOCTL_PHUB_WRITE_REG:
+		ret_value = copy_from_user((void *)&data,
+					(void *)&p_pch_phub_reqt->data,
+					sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_from_user fail returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		PCH_WRITE_REG(data, (void __iomem *)addr_offset);
+		dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+				"PCH_WRITE_REG successfully\n");
+		break;
+	case IOCTL_PHUB_READ_MODIFY_WRITE_REG:
+		ret_value = copy_from_user((void *)&data,
+			   (void *)&p_pch_phub_reqt->data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : copy_from_user fail "
+					"returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		ret_value = copy_from_user((void *)&mask,
+			   (void *)&p_pch_phub_reqt->mask, sizeof(mask));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : copy_from_user fail "
+					"returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		pch_phub_read_modify_write_reg(addr_offset,
+								 data, mask);
+		dev_dbg(dev_dbg, "pch_phub_ioctl  : Invoked "
+			"pch_phub_read_modify_write_reg successfully\n");
+		break;
+	case IOCTL_PHUB_READ_OROM:
+		ret_value = pch_phub_read_serial_rom(addr_offset,
+							(unsigned char *)&data);
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_read_serial_rom =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		} else {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_read_serial_rom successfully\n");
+		}
+		ret_value = copy_to_user((void *)&p_pch_phub_reqt->data,
+						(void *)&data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_to_user fail returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		break;
+	case IOCTL_PHUB_WRITE_OROM:
+		ret_value = copy_from_user((void *)&data,
+			   (void *)&p_pch_phub_reqt->data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : "
+				"copy_from_user fail returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		ret_value = pch_phub_write_serial_rom(addr_offset, data);
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_write_serial_rom =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		} else {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_write_serial_rom successfully\n");
+		}
+		break;
+	case IOCTL_PHUB_READ_MAC_ADDR:
+		pch_phub_read_gbe_mac_addr(addr_offset, (unsigned char *)&data);
+		dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_read_gbe_mac_addr successfully\n");
+
+		ret_value = copy_to_user((void *)&p_pch_phub_reqt->data,
+						 (void *)&data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : copy_to_user fail "
+					"returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		break;
+	case IOCTL_PHUB_WRITE_MAC_ADDR:
+		ret_value = copy_from_user((void *)&data,
+			   (void *)&p_pch_phub_reqt->data, sizeof(data));
+		if (ret_value) {
+			dev_dbg(dev_dbg, "pch_phub_ioctl : copy_from_user fail "
+					"returning =%d\n", -EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		pch_phub_write_gbe_mac_addr(addr_offset, data);
+		dev_dbg(dev_dbg, "pch_phub_ioctl : Invoked "
+				"pch_phub_write_gbe_mac_addr successfully\n");
+		break;
+	default:
+		dev_dbg(dev_dbg, "pch_write_ioctl invalid "
+				"command returning=%d\n", -EINVAL);
+		ret_value = -EINVAL;
+		break;
+	}
+return_ioctrl:
+	dev_dbg(dev_dbg, "pch_write_ioctl returns=%d\n", ret_value);
+	return ret_value;
+}
+
+/** pch_phub_pci_init - Implements the initialization functionality of
+ *  								 the module.
+ */
+static int __init pch_phub_pci_init(void)
+{
+	s32 ret;
+	ret = pci_register_driver(&pch_phub_driver);
+	dev_dbg(dev_dbg, "pch_phub_pci_init : "
+			"Invoked pci_register_driver successfully   "
+			"returns = %d\n", ret);
+	return ret;
+}
+
+/** pch_phub_pci_exit - Implements the exit functionality of the module.
+ */
+static void __exit pch_phub_pci_exit(void)
+{
+	pci_unregister_driver(&pch_phub_driver);
+	dev_dbg(dev_dbg, "pch_phub_pci_exit : "
+			"Invoked pci_unregister_driver successfully\n");
+}
+
+/** pch_phub_probe - Implements the probe functionality of the module.
+ *  @pdev: Contains the reference of the pci_dev structure
+ *  @id: Contains the reference of the pci_device_id structure
+ */
+static int __devinit pch_phub_probe(struct pci_dev *pdev,
+				       const struct pci_device_id *id)
+{
+
+	char *DRIVER_NAME = "pch_phub";
+	int ret;
+	unsigned int rom_size;
+
+	dev_dbg = &pdev->dev;
+
+	pch_phub_major_no = (pch_phub_major_no < 0 || pch_phub_major_no > 254) ?
+				0 : pch_phub_major_no;
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		dev_dbg(dev_dbg, "\npch_phub_probe : pci_enable_device FAILED");
+		goto err_probe;
+	}
+	dev_dbg(dev_dbg, "pch_phub_probe : "
+			"pci_enable_device returns %d\n", ret);
+
+	ret = pci_request_regions(pdev, DRIVER_NAME);
+	if (ret) {
+		dev_dbg(dev_dbg, "pch_phub_probe : pci_request_regions FAILED");
+		pci_disable_device(pdev);
+		goto err_probe;
+	}
+	dev_dbg(dev_dbg, "pch_phub_probe : "
+		"pci_request_regions returns %d\n", ret);
+
+	pch_phub_base_address = (unsigned long)pci_iomap(pdev, 1, 0);
+
+	if (pch_phub_base_address == 0) {
+		dev_dbg(dev_dbg, "pch_phub_probe : pci_iomap FAILED");
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		ret = -ENOMEM;
+		goto err_probe;
+	}
+	dev_dbg(dev_dbg, "pch_phub_probe : pci_iomap SUCCESS and value "
+		"in pch_phub_base_address variable is 0x%08x\n",
+		pch_phub_base_address);
+
+	pch_phub_extrom_base_address =
+	    (unsigned long)pci_map_rom(pdev, &rom_size);
+	if (pch_phub_extrom_base_address == 0) {
+		dev_dbg(dev_dbg, "pch_phub_probe : pci_map_rom FAILED");
+		pci_iounmap(pdev, (void *)pch_phub_base_address);
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		ret = -ENOMEM;
+		goto err_probe;
+	}
+	dev_dbg(dev_dbg, "pch_phub_probe : "
+		"pci_map_rom SUCCESS and value in "
+		"pch_phub_extrom_base_address variable is 0x%08x\n",
+		pch_phub_extrom_base_address);
+
+	if (pch_phub_major_no) {
+		pch_phub_dev_no = MKDEV(pch_phub_major_no, 0);
+		ret = register_chrdev_region(pch_phub_dev_no,
+					   PCH_MINOR_NOS, DRIVER_NAME);
+		if (ret) {
+			dev_dbg(dev_dbg, "pch_phub_probe : "
+				"register_chrdev_region FAILED");
+			pci_unmap_rom(pdev,
+					(void *)pch_phub_extrom_base_address);
+			pci_iounmap(pdev, (void *)pch_phub_base_address);
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			goto err_probe;
+		}
+		dev_dbg(dev_dbg, "pch_phub_probe : "
+				"register_chrdev_region returns %d\n", ret);
+	} else {
+		ret = alloc_chrdev_region(&pch_phub_dev_no, 0,
+						PCH_MINOR_NOS, DRIVER_NAME);
+		if (ret) {
+			dev_dbg(dev_dbg, "pch_phub_probe : "
+					"alloc_chrdev_region FAILED");
+			pci_unmap_rom(pdev,
+				      (void *)pch_phub_extrom_base_address);
+			pci_iounmap(pdev,
+				    (void *)pch_phub_base_address);
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			goto err_probe;
+		}
+		dev_dbg(dev_dbg, "pch_phub_probe : "
+			"alloc_chrdev_region returns %d\n", ret);
+	}
+
+	cdev_init(&pch_phub_dev, &pch_phub_fops);
+	dev_dbg(dev_dbg, "pch_phub_probe :  cdev_init invoked successfully\n");
+
+	pch_phub_dev.owner = THIS_MODULE;
+	pch_phub_dev.ops = &pch_phub_fops;
+
+	ret = cdev_add(&pch_phub_dev, pch_phub_dev_no, PCH_MINOR_NOS);
+	if (ret) {
+		dev_dbg(dev_dbg, "pch_phub_probe :  cdev_add FAILED");
+		unregister_chrdev_region(pch_phub_dev_no, PCH_MINOR_NOS);
+		pci_unmap_rom(pdev, (void *)pch_phub_extrom_base_address);
+		pci_iounmap(pdev, (void *)pch_phub_base_address);
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		goto err_probe;
+	}
+	dev_dbg(dev_dbg, "pch_phub_probe :  cdev_add returns %d\n", ret);
+
+#ifdef PCH_CAN_PCLK_50MHZ
+	/*set the clock config reg if CAN clock is 50Mhz */
+	dev_dbg(dev_dbg, "pch_phub_probe : invoking "
+		"pch_phub_read_modify_write_reg "
+		"to set CLKCFG reg for CAN clk 50Mhz\n");
+	pch_phub_read_modify_write_reg((unsigned long)CLKCFG_REG_OFFSET,
+					  CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK);
+#endif
+	/* set the prefech value */
+	PCH_WRITE_REG(0x000ffffa, (void __iomem *)0x14);
+	/* set the interrupt delay value */
+	PCH_WRITE_REG(0x25, (void __iomem *)0x44);
+	return 0;
+
+err_probe:
+	dev_dbg(dev_dbg, "pch_phub_probe returns %d\n", ret);
+	return ret;
+}
+
+/** pch_phub_remove - Implements the remove functionality of the module.
+ *  @pdev: Contains the reference of the pci_dev structure
+ */
+static void __devexit pch_phub_remove(struct pci_dev *pdev)
+{
+
+	cdev_del(&pch_phub_dev);
+	dev_dbg(dev_dbg, "pch_phub_remove - cdev_del Invoked successfully\n");
+
+	unregister_chrdev_region(pch_phub_dev_no, PCH_MINOR_NOS);
+	dev_dbg(dev_dbg, "pch_phub_remove - "
+		"unregister_chrdev_region Invoked successfully\n");
+
+	pci_unmap_rom(pdev, (void *)pch_phub_extrom_base_address);
+
+	pci_iounmap(pdev, (void *)pch_phub_base_address);
+
+	dev_dbg(dev_dbg, "pch_phub_remove - "
+			"pci_iounmap Invoked successfully\n");
+
+	pci_release_regions(pdev);
+	dev_dbg(dev_dbg, "pch_phub_remove - "
+		"pci_release_regions Invoked successfully\n");
+
+	pci_disable_device(pdev);
+	dev_dbg(dev_dbg, "pch_phub_remove - "
+		"pci_disable_device Invoked successfully\n");
+
+}
+
+#ifdef CONFIG_PM
+
+/** pch_phub_suspend - Implements the suspend functionality of the module.
+ *  @pdev: Contains the reference of the pci_dev structure
+ *  @state: Contains the reference of the pm_message_t structure
+ */
+static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int ret;
+
+	pch_phub_suspended = true;	/* For blocking further IOCTLs */
+
+	pch_phub_save_reg_conf();
+	dev_dbg(dev_dbg, "pch_phub_suspend - "
+		"pch_phub_save_reg_conf Invoked successfully\n");
+
+	ret = pci_save_state(pdev);
+	if (ret) {
+		dev_dbg(dev_dbg,
+			" pch_phub_suspend -pci_save_state returns-%d\n", ret);
+		return ret;
+	}
+	dev_dbg(dev_dbg, "pch_phub_suspend - pci_save_state returns %d\n", ret);
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	dev_dbg(dev_dbg, "pch_phub_suspend - "
+			"pci_enable_wake Invoked successfully\n");
+
+	pci_disable_device(pdev);
+	dev_dbg(dev_dbg, "pch_phub_suspend - "
+			"pci_disable_device Invoked successfully\n");
+
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	dev_dbg(dev_dbg, "pch_phub_suspend - "
+			"pci_set_power_state Invoked successfully   "
+			"return = %d\n", 0);
+
+	return 0;
+}
+
+/** pch_phub_resume - Implements the resume functionality of the module.
+ *  @pdev: Contains the reference of the pci_dev structure
+ */
+static int pch_phub_resume(struct pci_dev *pdev)
+{
+
+	int ret;
+
+	pci_set_power_state(pdev, PCI_D0);
+	dev_dbg(dev_dbg, "pch_phub_resume - "
+		"pci_set_power_state Invoked successfully\n");
+
+	pci_restore_state(pdev);
+	dev_dbg(dev_dbg, "pch_phub_resume - "
+		"pci_restore_state Invoked successfully\n");
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		dev_dbg(dev_dbg, "pch_phub_resume-pci_enable_device failed ");
+		return ret;
+	}
+
+	dev_dbg(dev_dbg, "pch_phub_resume - "
+			"pci_enable_device returns -%d\n", ret);
+
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	dev_dbg(dev_dbg, "pch_phub_resume - "
+			"pci_enable_wake Invoked successfully\n");
+
+	pch_phub_restore_reg_conf();
+	dev_dbg(dev_dbg, "pch_phub_resume - "
+		"pch_phub_restore_reg_conf Invoked successfully\n");
+
+	pch_phub_suspended = false;
+
+	dev_dbg(dev_dbg, "pch_phub_resume  returns- %d\n", 0);
+	return 0;
+}
+#endif /* CONFIG_PM */
diff --git a/drivers/char/pch_phub/pch_phub.h b/drivers/char/pch_phub/pch_phub.h
new file mode 100755
index 0000000..62ed819
--- /dev/null
+++ b/drivers/char/pch_phub/pch_phub.h
@@ -0,0 +1,96 @@
+#ifndef __PCH_PHUB_H__
+#define __PCH_PHUB_H__
+/*!
+ * @file pch_phub.h
+ * @brief Provides all the interfaces pertaining to the Packet Hub 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) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 04/14/2010
+ * modified:
+ *
+ */
+
+#define PHUB_IOCTL_MAGIC 		(0xf7)
+
+/*Outlines the read register function signature.  */
+#define IOCTL_PHUB_READ_REG (_IOW(PHUB_IOCTL_MAGIC, 1, unsigned long))
+
+/*Outlines the write register function signature. */
+#define IOCTL_PHUB_WRITE_REG (_IOW(PHUB_IOCTL_MAGIC, 2, unsigned long))
+
+/*Outlines the read, modify and write register function signature. */
+#define IOCTL_PHUB_READ_MODIFY_WRITE_REG (_IOW(PHUB_IOCTL_MAGIC, 3,\
+								 unsigned long))
+
+/*Outlines the read option rom function signature. */
+#define IOCTL_PHUB_READ_OROM (_IOW(PHUB_IOCTL_MAGIC, 4, unsigned long))
+
+/*Outlines the write option rom function signature. */
+#define IOCTL_PHUB_WRITE_OROM (_IOW(PHUB_IOCTL_MAGIC, 5, unsigned long))
+
+/*Outlines the read mac address function signature. */
+#define IOCTL_PHUB_READ_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 6, unsigned long))
+
+/*brief Outlines the write mac address function signature. */
+#define IOCTL_PHUB_WRITE_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 7, unsigned long))
+
+
+/* Registers address offset */
+#define PCH_PHUB_PHUB_ID_REG			(void __iomem *)(0x0000)
+#define PCH_PHUB_QUEUE_PRI_VAL_REG			(void __iomem *)(0x0004)
+#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG		(void __iomem *)(0x0008)
+#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG		(void __iomem *)(0x000C)
+#define PCH_PHUB_COMP_RESP_TIMEOUT_REG		(void __iomem *)(0x0010)
+#define PCH_PHUB_BUS_SLAVE_CONTROL_REG		(void __iomem *)(0x0014)
+#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG		(void __iomem *)(0x0018)
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0		(void __iomem *)(0x0020)
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1		(void __iomem *)(0x0024)
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2		(void __iomem *)(0x0028)
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3		(void __iomem *)(0x002C)
+#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE	(void __iomem *)(0x0040)
+#define CLKCFG_REG_OFFSET           		(void __iomem *)(0x500)
+
+/*structures*/
+/*It is a structure used for perserving information related to the
+ * 							 Packet Hub request.
+ */
+struct pch_phub_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 */
+int pch_phub_open(struct inode *inode, struct file *file);
+int pch_phub_release(struct inode *inode, struct file *file);
+int pch_phub_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		      unsigned long arg);
+
+/**global variables*/
+extern u32 pch_phub_base_address;	/* base address */
+extern s32 pch_phub_suspended;		/* suspend status */
+
+extern s32 pch_phub_opencount;
+extern spinlock_t pch_phub_lock;
+extern const struct file_operations pch_phub_fops;
+#endif
-- 
1.6.0.6

^ permalink raw reply related	[flat|nested] 45+ messages in thread
* Re: [PATCH] Topcliff PHUB: Generate PacketHub driver
@ 2010-06-08  5:00 Masayuki Ohtak
  2010-06-08  5:46 ` Masayuki Ohtake
                   ` (2 more replies)
  0 siblings, 3 replies; 45+ messages in thread
From: Masayuki Ohtak @ 2010-06-08  5:00 UTC (permalink / raw)
  To: Alan Cox; +Cc: LKML, Andrew, Intel OTC, Wang, Qi, Wang, Yong Y, Masayuki Ohtak

Hi Alan

We are now updating our Phub driver.

I have a questions for your comment.

(1)
>> +#ifdef PCH_CAN_PCLK_50MHZ
>> + /* save clk cfg register */
>> + g_pch_phub_reg.clkcfg_reg = PCH_READ_REG(CLKCFG_REG_OFFSET);
>> +#endif
> 
> This makes it hard to build one kernel for everything
We couldn't understand your intention.
Does the above mean we must not use "#ifdef PCH_CAN_PCLK_50MHZ"	in source code ?


BTW, We show our modification policy the following email with inline.
Please confirm it.
If there is any mistake, please inform us.


Thanks.  

Ohtake.


----- Original Message ----- 

From: "Alan Cox" <alan@lxorguk.ukuu.org.uk>

To: "Masayuki Ohtak" <masa-korg@dsn.okisemi.com>

Cc: "LKML" <linux-kernel@vger.kernel.org>; "Andrew" <andrew.chih.howe.khor@intel.com>; "Intel OTC" <joel.clark@intel.com>; "Wang, Qi" <qi.wang@intel.com>; "Wang, Yong Y" <yong.y.wang@intel.com>

Sent: Tuesday, June 08, 2010 12:05 AM

Subject: Re: [PATCH] Topcliff PHUB: Generate PacketHub driver





>O> +/* Status Register offset */

>> +#define PHUB_STATUS (0x00)

>> +/* Control Register offset */

>> +#define PHUB_CONTROL (0x04)

>> +/* Time out value for Status Register */

>> +#define PHUB_TIMEOUT (0x05)

>> +/* Enabling for writing ROM */

>> +#define PCH_PHUB_ROM_WRITE_ENABLE (0x01)

>> +/* Disabling for writing ROM */

>> +#define PCH_PHUB_ROM_WRITE_DISABLE (0x00)

>> +/* ROM data area start address offset */

>> +#define PCH_PHUB_ROM_START_ADDR (0x14)

>> +/* MAX number of INT_REDUCE_CONTROL registers */

>> +#define MAX_NUM_INT_REDUCE_CONTROL_REG (128)

>> +

>> +#define PCI_DEVICE_ID_PCH1_PHUB (0x8801)

>> +

>> +#define PCH_MINOR_NOS (1)

>> +#define CLKCFG_CAN_50MHZ (0x12000000)

>> +#define CLKCFG_CANCLK_MASK (0xFF000000)

> 

> Style: constants don't need brackets - might also look more Linux like

> tabbed out a bit

The above brackets are deleted



> 

>> +#define PCH_READ_REG(a) ioread32((pch_phub_base_address + a))

>> +

>> +#define PCH_WRITE_REG(a, b) iowrite32(a, (pch_phub_base_address + b))

> 

> These on the other hand do - but not where they are now

> 

> iowrite32((a), pcb_phub_base_address + (b))

> 

> (so that if a or b are expressions they are evaluated first)

Modify like below.

#define PCH_READ_REG(a) ioread32(pch_phub_base_address + (a))

#define PCH_WRITE_REG(a, b) iowrite32(a, pch_phub_base_address + (b))



> 

> 

>> +struct pch_phub_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 PCH_CAN_PCLK_50MHZ

>> + u32 clkcfg_reg; /* CLK CFG register val */

>> +#endif

>> +} g_pch_phub_reg;

> 

> Stylewise the kernel doesn't use the g_ convention that many Windows

> people do, so lose the g_

Delete prefix 'g_'.





> 

>> +s32 pch_phub_opencount; /* check whether opened or not */

>> +u32 pch_phub_base_address;

>> +u32 pch_phub_extrom_base_address;

>> +s32 pch_phub_suspended;

> 

> Any reason these can't be in the struct ?

Move the above 4 variables into 'struct pch_phub_reg_t'.



>> +

>> +struct device *dev_dbg;

> 

> Not a good name for a global variable as it will clash with others 

Modify to phub_dev_dbg.



> 

>> +DEFINE_SPINLOCK(pch_phub_lock); /* for spin lock */

> 

> Can this be static or in the struct ?

Modify lile below.

static DEFINE_SPINLOCK(pch_phub_lock); /* for spin lock */





> 

>> +

>> +/**

>> + * file_operations structure initialization

>> + */

>> +const struct file_operations pch_phub_fops = {

>> + .owner = THIS_MODULE,

>> + .open = pch_phub_open,

>> + .release = pch_phub_release,

>> + .ioctl = pch_phub_ioctl,

>> +};

> 

> static const ?

> 

Modify to 'static const'.





>> +/*--------------------------------------------

>> + exported function prototypes

>> +--------------------------------------------*/

> 

> They start 'static' I don't think they are exportdd !

Modify comment to 'Internal function prototypes'



> 

>> +static int __devinit pch_phub_probe(struct pci_dev *pdev, const

>> +        struct pci_device_id *id);

>> +static void __devexit pch_phub_remove(struct pci_dev *pdev);

>> +static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state);

>> +static int pch_phub_resume(struct pci_dev *pdev);

> 

>> +static struct pci_driver pch_phub_driver = {

>> + .name = "pch_phub",

>> + .id_table = pch_phub_pcidev_id,

>> + .probe = pch_phub_probe,

>> + .remove = __devexit_p(pch_phub_remove),

>> +#ifdef CONFIG_PM

>> + .suspend = pch_phub_suspend,

>> + .resume = pch_phub_resume

>> +#endif

>> +};

>> +

>> +static int __init pch_phub_pci_init(void);

>> +static void __exit pch_phub_pci_exit(void);

>> +

>> +MODULE_DESCRIPTION("PCH PACKET HUB PCI Driver");

>> +MODULE_LICENSE("GPL");

>> +module_init(pch_phub_pci_init);

>> +module_exit(pch_phub_pci_exit);

>> +module_param(pch_phub_major_no, int, S_IRUSR | S_IWUSR);

> 

> If you migrated the module registration/PCI registration to the bottom of

> the file you could avoid the forward declations and make the code easier

> to follow ?

Move the PCI registration code to the bottom of the file.



> 

>> +void pch_phub_read_modify_write_reg(unsigned long reg_addr_offset,

>> +        unsigned long data, unsigned long mask)

>> +{

>> + unsigned long reg_addr = pch_phub_base_address + reg_addr_offset;

>> + iowrite32(((ioread32((void __iomem *)reg_addr) & ~mask)) | data,

>> + (void __iomem *)reg_addr);

> 

> When you have that many casts in a line it's perhaps a hint you have the

> types wrong initially. At the very least reg_addr should be void __iomem,

> and probably pch_phub_base_address should be 

> 

> It would probably make sense to pass a pointer to your struct pch_hub_reg

> and use that to hold the base address. Then if you ever get a box with

> two in some future design it won't be a disaster

> 

>> +void pch_phub_save_reg_conf(void)

> 

> Ditto 

 reg_addr/pch_phub_base_address  are defined as 'void __iomem',



> 

>> +#ifdef PCH_CAN_PCLK_50MHZ

>> + /* save clk cfg register */

>> + g_pch_phub_reg.clkcfg_reg = PCH_READ_REG(CLKCFG_REG_OFFSET);

>> +#endif

> 

> This makes it hard to build one kernel for everything

???



> 

>> + return;

>> +}

> 

>> +void pch_phub_restore_reg_conf(void)

>> +{

>> + u32 i = 0;

> 

> Why = 0, if you do that here you may hide initialisation errors from

> future changes ?

Delete '=0'





> 

>> +/** pch_phub_read_serial_rom - Implements the functionality of reading Serial

>> + *  ROM.

>> + *  @offset_address: Contains the Serial ROM address offset value

>> + *  @data: Contains the Serial ROM value

>> + */

>> +int pch_phub_read_serial_rom(unsigned long offset_address, unsigned char *data)

>> +{

>> + unsigned long mem_addr = pch_phub_extrom_base_address + offset_address;

>> +

>> + dev_dbg(dev_dbg,

>> + "pch_phub_read_serial_rom:mem_addr=0x%08x\n", (u32)mem_addr);

>> + *data = ioread8((void __iomem *)mem_addr);

> 

> Same comments about casts

Please refer the above.(defined as 'void __iomem',)



> 

> 

> 

>> +int pch_phub_ioctl(struct inode *inode, struct file *file,

>> + unsigned int cmd, unsigned long arg)

>> +{

>> + int ret_value = 0;

>> + struct pch_phub_reqt *p_pch_phub_reqt;

>> + unsigned long addr_offset;

> 

> This will change size on 32/64bit boxes makign your copy a bit

> problematic 

Modify like belwo,

u64 addr_offset;





> 

>> + p_pch_phub_reqt = (struct pch_phub_reqt *)arg;

>> + ret_value = copy_from_user((void *)&addr_offset,

>> + (void *)&p_pch_phub_reqt->addr_offset,

>> + sizeof(addr_offset));

>> + if (ret_value) {

> 

>> + /* End of Access area check */

> 

> Remember here ioctl isn't single threaded so you may want to double check

> some of these

The above copy_from_user is Copy global variable to local variable.
Thus, We think this code has re-entrant.


> 

>> +struct pch_phub_reqt {

>> + unsigned long addr_offset; /*specifies the register address

>> + offset */

>> + unsigned long data; /*specifies the data */

>> + unsigned long mask; /*specifies the mask */

> 

> If they may need to be long make them u64. That way 32 and 64bit systems

> get the same ioctl structure and life is good.

Modify type of addr_offset to u64



> 

>> +};

>> +

>> +/* exported function prototypes */

>> +int pch_phub_open(struct inode *inode, struct file *file);

>> +int pch_phub_release(struct inode *inode, struct file *file);

>> +int pch_phub_ioctl(struct inode *inode, struct file *file, unsigned int cmd,

>> +       unsigned long arg);

> 

> You have various other functions that are not static - if they should be

> then make them static

Add static description for all of internal functions.





^ permalink raw reply	[flat|nested] 45+ messages in thread
* Re: [PATCH] Topcliff PHUB: Generate PacketHub driver
@ 2010-06-15  6:58 Masayuki Ohtake
  2010-06-15 10:37 ` Arnd Bergmann
  0 siblings, 1 reply; 45+ messages in thread
From: Masayuki Ohtake @ 2010-06-15  6:58 UTC (permalink / raw)
  To: Arnd Bergmann, Masayuki Ohtake
  Cc: Wang, Yong Y, Wang, Qi, Intel OTC, Andrew, LKML, Alan Cox

Hi Arnd,

I have additional question.
> - When the user does an llseek or pread, the *pos argument is not zero,
>   so you should return data from the middle, but you still return data
>   from the beginning.


Must a driver read/write method support '*pos' parameter ?
We think PHUB doesn't have to support '*pos',
and ,we think, PHUB OROM R/W function supports only whole of ROM data R/W is enough.
Please give us your opinion.

Thanks.
Ohtake

----- Original Message ----- 
From: "Masayuki Ohtake" <masa-korg@dsn.okisemi.com>
To: "Arnd Bergmann" <arnd@arndb.de>
Cc: "Alan Cox" <alan@lxorguk.ukuu.org.uk>; "LKML" <linux-kernel@vger.kernel.org>; "Andrew"
<andrew.chih.howe.khor@intel.com>; "Intel OTC" <joel.clark@intel.com>; "Wang, Qi" <qi.wang@intel.com>; "Wang, Yong Y"
<yong.y.wang@intel.com>
Sent: Tuesday, June 15, 2010 3:25 PM
Subject: Re: [PATCH] Topcliff PHUB: Generate PacketHub driver


> Hi Arnd,
>
> >> +#to set CAN clock to 50Mhz
> >> +ifdef CONFIG_PCH_CAN_PCLK_50MHZ
> >> +EXTRA_CFLAGS +=-DPCH_CAN_PCLK_50MHZ
> >> +endif
>
> >This should not be necessary. Just use CONFIG_PCH_CAN_PCLK_50MHZ directly
> >in the code instead of the extra PCH_CAN_PCLK_50MHZ macro.
>
> I have a question. I show the above reason.
> In case CAN is integrated as MODULE, macro name is CONFIG_PCH_CAN_PCLK_50MHZ_MODULE.
> On the other hand, integrated as built-in, CONFIG_PCH_CAN_PCLK_50MHZ.
> To prevent PHUB source code from integrated as MODULE or BUILT-IN,
> we re-define macro name in Makefile.
>
> If use CONFIG_PCH_CAN_PCLK_50MHZ directly in the source code,
> in case buit-in, behavior is not correct.
> But in case module, behavior is not correct.
>
> Please give us your opinion
>
> Thanks,
> Ohtake.
> ----- Original Message ----- 
> From: "Arnd Bergmann" <arnd@arndb.de>
> To: "Masayuki Ohtak" <masa-korg@dsn.okisemi.com>
> Cc: "Alan Cox" <alan@lxorguk.ukuu.org.uk>; "LKML" <linux-kernel@vger.kernel.org>; "Andrew"
> <andrew.chih.howe.khor@intel.com>; "Intel OTC" <joel.clark@intel.com>; "Wang, Qi" <qi.wang@intel.com>; "Wang, Yong Y"
> <yong.y.wang@intel.com>
> Sent: Monday, June 14, 2010 9:50 PM
> Subject: Re: [PATCH] Topcliff PHUB: Generate PacketHub driver
>
>
> > On Monday 14 June 2010, Masayuki Ohtak wrote:
> > > Hi we have modified for your comments.
> > > Please Confirm below.
> >
> > Looks much better. A few more comments about the new code:
> >
> > > +#to set CAN clock to 50Mhz
> > > +ifdef CONFIG_PCH_CAN_PCLK_50MHZ
> > > +EXTRA_CFLAGS +=-DPCH_CAN_PCLK_50MHZ
> > > +endif
> >
> > This should not be necessary. Just use CONFIG_PCH_CAN_PCLK_50MHZ directly
> > in the code instead of the extra PCH_CAN_PCLK_50MHZ macro.
> > > +
> > > +DEFINE_MUTEX(pch_phub_ioctl_mutex);
> >
> > This should probable be 'static DEFINE_MUTEX', since the symbol does not
> > need to be visible in the entire kernel.
> >
> >
> > > +/*--------------------------------------------
> > > + internal function prototypes
> > > +--------------------------------------------*/
> > > +static __s32 __devinit pch_phub_probe(struct pci_dev *pdev, const
> > > +        struct pci_device_id *id);
> > > +static void __devexit pch_phub_remove(struct pci_dev *pdev);
> > > +static __s32 pch_phub_suspend(struct pci_dev *pdev, pm_message_t state);
> > > +static __s32 pch_phub_resume(struct pci_dev *pdev);
> > > +static __s32 pch_phub_open(struct inode *inode, struct file *file);
> > > +static __s32 pch_phub_release(struct inode *inode, struct file *file);
> > > +static long pch_phub_ioctl(struct file *file, unsigned int cmd,
> > > + unsigned long arg);
> > > +static ssize_t pch_phub_read(struct file *, char __user *, size_t, loff_t *);
> > > +static ssize_t pch_phub_write(struct file *, const char __user *,
> > > + size_t, loff_t *);
> >
> > My general recommendation would be to reorder all the function
> > definitions so that you don't need any of these forward declarations.
> > That is the order used in most parts of the kernel (so you start reading
> > at the bottom), and it makes it easier to understand the structure of
> > the code IMHO.
> >
> > > +/** pch_phub_open - Implements the Initializing and opening of the Packet Hub
> > > + module.
> > > + *  @inode: Contains the reference of the inode structure
> > > + *  @file: Contains the reference of the file structure
> > > + */
> > > +static __s32 pch_phub_open(struct inode *inode, struct file *file)
> > > +{
> > > + __s32 ret;
> > > +
> > > + spin_lock(&pch_phub_lock);
> > > + if (pch_phub_reg.pch_phub_opencount) {
> > > + ret = -EBUSY;
> > > + } else {
> > > + pch_phub_reg.pch_phub_opencount++;
> > > + ret = 0;
> > > + }
> > > + spin_unlock(&pch_phub_lock);
> > > +
> > > + return ret;
> > > +}
> >
> > As far as I can tell, there is no longer a reason to prevent multiple
> > openers. Besides, even if there is only a single user, you might still
> > have concurrency problems, so the lock does not help and you could remove
> > the open function entirely.
> >
> > > +/** pch_phub_read - Implements the read functionality of the Packet Hub module.
> > > + *  @file: Contains the reference of the file structure
> > > + *  @buf: Usermode buffer pointer
> > > + *  @size: Usermode buffer size
> > > + *  @pos: Contains the reference of the file structure
> > > + */
> > > +
> > > +static ssize_t pch_phub_read(struct file *file, char __user *buf, size_t size,
> > > + loff_t *pos)
> > > +{
> > > + __u32 rom_signature = 0;
> > > + __u8 rom_length;
> > > + __s32 ret_value;
> > > + __u32 tmp;
> > > + __u8 data;
> > > + __u32 addr_offset = 0;
> > > +
> > > + /*Get Rom signature*/
> > > + pch_phub_read_serial_rom(0x80, (__u8 *)&rom_signature);
> > > + pch_phub_read_serial_rom(0x81, (__u8 *)&tmp);
> > > + rom_signature |= (tmp & 0xff) << 8;
> > > + if (rom_signature == 0xAA55) {
> > > + pch_phub_read_serial_rom(0x82, &rom_length);
> > > + if (size > (rom_length * 512)+1)
> > > + return -ENOMEM;
> > > +
> > > + for (addr_offset = 0;
> > > + addr_offset <= ((__u32)rom_length * 512);
> > > + addr_offset++) {
> > > + pch_phub_read_serial_rom(0x80 + addr_offset, &data);
> > > + ret_value = copy_to_user((void *)&buf[addr_offset],
> > > + (void *)&data, 1);
> > > + if (ret_value)
> > > + return -EFAULT;
> > > + }
> > > + } else {
> > > + return -ENOEXEC;
> > > + }
> > > +
> > > + return rom_length * 512 + 1;
> > > +}
> >
> > This function has multiple problems:
> >
> > - If the size argument is less than rom_length*512, you access past the
> >   user-provided buffer.
> > - When the user does an llseek or pread, the *pos argument is not zero,
> >   so you should return data from the middle, but you still return data
> >   from the beginning.
> > - You don't update the *pos argument with the new position, so you cannot
> >   continue the read where the first call left.
> > - Instead of returning -ENOMEM, you should just the data you have (or
> >   0 for end-of-file).
> > - ENOEXEC does not seem appropriate either: The user can just check
> >   these buffer for the signature here, so you just as well return
> >   whatever you find in the ROM.
> >
> > > +
> > > +/** pch_phub_write - Implements the write functionality of the Packet Hub
> > > + *  module.
> > > + *  @file: Contains the reference of the file structure
> > > + *  @buf: Usermode buffer pointer
> > > + *  @size: Usermode buffer size
> > > + *  @pos: Contains the reference of the file structure
> > > + */
> > > +static ssize_t pch_phub_write(struct file *file, const char __user *buf,
> > > + size_t size, loff_t *pos)
> > > +{
> > > + static __u8 data[PCH_PHUB_OROM_SIZE];
> > > + __s32 ret_value;
> > > + __u32 addr_offset = 0;
> > > +
> > > + if (size > PCH_PHUB_OROM_SIZE)
> > > + size = PCH_PHUB_OROM_SIZE;
> > > +
> > > + ret_value = copy_from_user(data, buf, size);
> > > + if (ret_value)
> > > + return -EFAULT;
> > > +
> > > + for (addr_offset = 0; addr_offset < size; addr_offset++) {
> > > + ret_value = pch_phub_write_serial_rom(0x80 + addr_offset,
> > > + data[addr_offset]);
> > > + }
> > > +
> > > + return size;
> > > +}
> >
> > This has the same problems, plus a buffer overflow: You must never have an
> > array of multiple kilobytes on the stack (data[PCH_PHUB_OROM_SIZE]), because
> > the stack itself is only a few kilobytes in the kernel. Better use a loop
> > with copy_from_user like the read function does.
> >
> > > +/** pch_phub_release - Implements the release functionality of the Packet Hub
> > > + *  module.
> > > + *  @inode: Contains the reference of the inode structure
> > > + *  @file: Contains the reference of the file structure
> > > + */
> > > +static __s32 pch_phub_release(struct inode *inode, struct file *file)
> > > +{
> > > + spin_lock(&pch_phub_lock);
> > > +
> > > + if (pch_phub_reg.pch_phub_opencount > 0)
> > > + pch_phub_reg.pch_phub_opencount--;
> > > + spin_unlock(&pch_phub_lock);
> > > +
> > > + return 0;
> > > +}
> >
> > When you remove the open function, this one can go away as well.
> >
> > > +/** pch_phub_ioctl - Implements the various ioctl functionalities of the Packet
> > > + *  Hub module.
> > > + *  @inode: Contains the reference of the inode structure
> > > + *  @file: Contains the reference of the file structure
> > > + *  @cmd: Contains the command value
> > > + *  @arg: Contains the command argument value
> > > + */
> > > +
> > > +
> > > +static long pch_phub_ioctl(struct file *file, unsigned int cmd,
> > > + unsigned long arg)
> > > +{
> > > + __s32 ret_value = 0;
> > > + struct pch_phub_reqt __user *p_pch_phub_reqt;
> > > + __u32 data;
> > > + __u32 mac_addr[2];
> > > + __s32 ret;
> > > + __u32 i;
> > > + void __user *varg = (void __user *)arg;
> > > +
> > > + ret = mutex_trylock(&pch_phub_ioctl_mutex);
> > > + if (ret == 0)
> > > + goto return_ioctrl;/*Can't get mutex lock*/
> >
> > mutex_trylock is probably not what you want, it returns immediately
> > when there is another function in the kernel.
> > mutex_lock_interruptible seems more appropriate, it will block
> > until the mutex is free or the process gets sent a signal,
> > which you should handle by returning -ERESTARTSYS.
> >
> > In either case, you must not jump to return_ioctrl here, because
> > that will try to release the mutex that you do not hold here,
> > causing a hang the next time you enter the function.
> >
> > > + if (pch_phub_reg.pch_phub_suspended == true) {
> > > + ret_value = -EPERM;
> > > + goto return_ioctrl;
> > > + }
> > > +
> > > + p_pch_phub_reqt = (struct pch_phub_reqt *)varg;
> > > +
> > > + if (ret_value)
> > > + goto return_ioctrl;
> >
> > is always zero here.
> >
> > > + /* End of Access area check */
> > > +
> > > +
> > > + switch (cmd) {
> > > +
> > > + case IOCTL_PHUB_READ_MAC_ADDR:
> > > + mac_addr[0] = 0;
> > > + mac_addr[1] = 0;
> > > + for (i = 0; i < 4; i++) {
> > > + pch_phub_read_gbe_mac_addr(i, (__u8 *)&data);
> > > + mac_addr[0] |= data << i*8;
> > > + }
> > > + for (; i < 6; i++) {
> > > + pch_phub_read_gbe_mac_addr(i, (__u8 *)&data);
> > > + mac_addr[1] |= data << (i-4)*8;
> > > + }
> > > +
> > > + ret_value = copy_to_user((void *)&p_pch_phub_reqt->data,
> > > + (void *)mac_addr, sizeof(mac_addr));
> >
> > p_pch_phub_reqt->data has multiple problems:
> >
> > - You have the typecast to (void *), which is wrong and unneeded.
> > - The data structure has no point at all any more when you use only one
> >   field.
> >
> > Just make this
> >
> > u8 mac_addr[6];
> > for (i = 0; i < 4; i++)
> > pch_phub_read_gbe_mac_addr(i, &mac_addr[i]);
> > ret_value = copy_to_user(varg, mac_addr, sizeof(mac_addr));
> >
> > > +#define PHUB_IOCTL_MAGIC (0xf7)
> > > +
> > > +/*Outlines the read register function signature.  */
> > > +#define IOCTL_PHUB_READ_REG (_IOW(PHUB_IOCTL_MAGIC, 1, __u32))
> > > +
> > > +/*Outlines the write register function signature. */
> > > +#define IOCTL_PHUB_WRITE_REG (_IOW(PHUB_IOCTL_MAGIC, 2, __u32))
> > > +
> > > +/*Outlines the read, modify and write register function signature. */
> > > +#define IOCTL_PHUB_READ_MODIFY_WRITE_REG (_IOW(PHUB_IOCTL_MAGIC, 3,\
> > > + __u32))
> > > +
> > > +/*Outlines the read option rom function signature. */
> > > +#define IOCTL_PHUB_READ_OROM (_IOW(PHUB_IOCTL_MAGIC, 4, __u32))
> > > +
> > > +/*Outlines the write option rom function signature. */
> > > +#define IOCTL_PHUB_WRITE_OROM (_IOW(PHUB_IOCTL_MAGIC, 5, __u32))
> >
> > These should all get removed now.
> >
> > > +/*Outlines the read mac address function signature. */
> > > +#define IOCTL_PHUB_READ_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 6, __u32))
> > > +
> > > +/*brief Outlines the write mac address function signature. */
> > > +#define IOCTL_PHUB_WRITE_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 7, __u32))
> >
> > IOCTL_PHUB_READ_MAC_ADDR needs _IOR instead of _IOW, and the type
> > is still wrong here. Your code currently has struct pch_phub_reqt
> > instead of __u32, and if you change the ioctl function as I explained
> > above, it should become
> >
> > #define IOCTL_PHUB_READ_MAC_ADDR (_IOR(PHUB_IOCTL_MAGIC, 6, __u8[6]))
> > #define IOCTL_PHUB_WRITE_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 7, __u8[6]))
> >
> > Arnd
> >
>
>



^ permalink raw reply	[flat|nested] 45+ messages in thread
* Re: [PATCH] Topcliff PHUB: Generate PacketHub driver
@ 2010-06-22  2:14 Masayuki Ohtake
  0 siblings, 0 replies; 45+ messages in thread
From: Masayuki Ohtake @ 2010-06-22  2:14 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Alan Cox, LKML, Andrew, Intel OTC, Wang, Qi, Wang, Yong Y

Hi Arnd,

Sorry, for late patch releasing.

I have modified like below.
We will release today.

>
> On Thursday 17 June 2010, Masayuki Ohtak wrote:
> > +
> > +#define PCH_READ_REG(a) ioread32(pch_phub_reg.pch_phub_base_address + (a))
> > +
> > +#define PCH_WRITE_REG(a, b) iowrite32((a), pch_phub_reg.pch_phub_base_address +\
> > + (b))
>
> I'd recommend just getting rid of these abstractions. You only use
> them in one or two functions each, so you can just as well add a local
> variable there and do
>
> void __iomem *p = pch_phub_reg.pch_phub_base_address;
> foo = ioread32(p + foo_offset);
> bar = ioread32(p + bar_offset);
> ...
>
> Not really important, but this way it would be more conventional
> without having to write extra code.
Modified like above.


>
> > +/*--------------------------------------------
> > + global variables
> > +--------------------------------------------*/
> > +/**
> > + * struct pch_phub_reg_t - PHUB register structure
> > + * @phub_id_reg: PHUB_ID register val
> > + * @q_pri_val_reg: QUEUE_PRI_VAL register val
> > + * @rc_q_maxsize_reg: RC_QUEUE_MAXSIZE register val
> > + * @bri_q_maxsize_reg: BRI_QUEUE_MAXSIZE register val
> > + * @comp_resp_timeout_reg: COMP_RESP_TIMEOUT register val
> > + * @bus_slave_control_reg: BUS_SLAVE_CONTROL_REG register val
> > + * @deadlock_avoid_type_reg:  DEADLOCK_AVOID_TYPE register val
> > + * @intpin_reg_wpermit_reg0:  INTPIN_REG_WPERMIT register 0 val
> > + * @intpin_reg_wpermit_reg1:  INTPIN_REG_WPERMIT register 1 val
> > + * @intpin_reg_wpermit_reg2:  INTPIN_REG_WPERMIT register 2 val
> > + * @intpin_reg_wpermit_reg3:  INTPIN_REG_WPERMIT register 3 val
> > + * @int_reduce_control_reg: INT_REDUCE_CONTROL registers val
> > + * @clkcfg_reg: CLK CFG register val
> > + * @pch_phub_base_address:  register base address
> > + * @pch_phub_extrom_base_address:  external rom base address
> > + * @pch_phub_suspended: PHUB status val
> > + */
> > +struct pch_phub_reg_t {
>
> It would be better to drop the _t postfix on the type name.
> By convention, we use this only for typedefs on simple data
> types like off_t but not for structures.
Deleted '_t' prefix

>
> > + __u32 phub_id_reg;
> > + __u32 q_pri_val_reg;
> > + __u32 rc_q_maxsize_reg;
>
> When I told you to change the ioctl arguments to use __u32 instead
> of u32, I was only referring to those parts that are in the user-visible
> section of the header file. While it does not hurt to use __u32 in
> the kernel, you should understand the distinction.
The following types are modified like below except user-visible secton '__u8 mac_addr[6].
__u32 -> unsigned int
__s32 -> int
__u8  -> unsigned char
__s8  -> char


>
> > +/** pch_phub_write - Implements the write functionality of the Packet Hub
> > + *  module.
> > + *  @file: Contains the reference of the file structure
> > + *  @buf: Usermode buffer pointer
> > + *  @size: Usermode buffer size
> > + *  @ppos: Contains the reference of the file structure
> > + */
> > +static ssize_t pch_phub_write(struct file *file, const char __user *buf,
> > + size_t size, loff_t *ppos)
> > +{
> > + static __u32 data;
>
> No need to make data static.
Deleted 'static'.

>
> > + __s32 ret_value;
> > + __u32 addr_offset = 0;
> > + loff_t pos = *ppos;
> > +
> > + if (pos < 0)
> > + return -EINVAL;
> > +
> > + for (addr_offset = 0; addr_offset < size; addr_offset++) {
> > + get_user(data, &buf[addr_offset]);
> > +
> > + ret_value = pch_phub_write_serial_rom(0x80 + addr_offset + pos,
> > + data);
> > + if (ret_value)
> > + return -EFAULT;
>
> You should return -EFAULT if the get_user() call fails, otherwise you have
> a possible security hole. If pch_phub_write_serial_rom fails, the correct
> return code would be -EIO.
Modified to care returned value of get_user.
Modified retunrn code of pch_phub_write_serial_rom to -EIO.

>
> > +/**
> > + * file_operations structure initialization
> > + */
> > +static const struct file_operations pch_phub_fops = {
> > + .owner = THIS_MODULE,
> > + .read = pch_phub_read,
> > + .write = pch_phub_write,
> > + .unlocked_ioctl = pch_phub_ioctl,
> > +};
>
> If would be good to add a line of
> .llseek = default_llseek,
> here. I have a patch to change the default llseek method to one
> that disallows seeking, so if you add this line, there is one
> less driver for me to patch.
Added a line of '.llseek = default_llseek'.

Thanks,
Ohtake

----- Original Message ----- 
From: "Masayuki Ohtake" <masa-korg@dsn.okisemi.com>
To: "Arnd Bergmann" <arnd@arndb.de>
Cc: "Wang, Yong Y" <yong.y.wang@intel.com>; "Wang, Qi" <qi.wang@intel.com>; "Intel OTC" <joel.clark@intel.com>; "Andrew"
<andrew.chih.howe.khor@intel.com>; "LKML" <linux-kernel@vger.kernel.org>; "Alan Cox" <alan@lxorguk.ukuu.org.uk>
Sent: Friday, June 18, 2010 8:49 AM
Subject: Re: [PATCH] Topcliff PHUB: Generate PacketHub driver


> Hi Arnd,
>
> I will modify for your comments by today or tomorrow.
>
> Thanks,
> Ohtake
>
> ----- Original Message ----- 
> From: "Arnd Bergmann" <arnd@arndb.de>
> To: "Masayuki Ohtak" <masa-korg@dsn.okisemi.com>
> Cc: "Alan Cox" <alan@lxorguk.ukuu.org.uk>; "LKML" <linux-kernel@vger.kernel.org>; "Andrew"
> <andrew.chih.howe.khor@intel.com>; "Intel OTC" <joel.clark@intel.com>; "Wang, Qi" <qi.wang@intel.com>; "Wang, Yong Y"
> <yong.y.wang@intel.com>
> Sent: Thursday, June 17, 2010 8:59 PM
> Subject: Re: [PATCH] Topcliff PHUB: Generate PacketHub driver
>
>
> > Looks almost good to me now. Some more details (only the -EFAULT return code
> > is a real issue, the other ones are cosmetic changes):
> >
> > On Thursday 17 June 2010, Masayuki Ohtak wrote:
> > > +
> > > +#define PCH_READ_REG(a) ioread32(pch_phub_reg.pch_phub_base_address + (a))
> > > +
> > > +#define PCH_WRITE_REG(a, b) iowrite32((a), pch_phub_reg.pch_phub_base_address +\
> > > + (b))
> >
> > I'd recommend just getting rid of these abstractions. You only use
> > them in one or two functions each, so you can just as well add a local
> > variable there and do
> >
> > void __iomem *p = pch_phub_reg.pch_phub_base_address;
> > foo = ioread32(p + foo_offset);
> > bar = ioread32(p + bar_offset);
> > ...
> >
> > Not really important, but this way it would be more conventional
> > without having to write extra code.
> >
> > > +/*--------------------------------------------
> > > + global variables
> > > +--------------------------------------------*/
> > > +/**
> > > + * struct pch_phub_reg_t - PHUB register structure
> > > + * @phub_id_reg: PHUB_ID register val
> > > + * @q_pri_val_reg: QUEUE_PRI_VAL register val
> > > + * @rc_q_maxsize_reg: RC_QUEUE_MAXSIZE register val
> > > + * @bri_q_maxsize_reg: BRI_QUEUE_MAXSIZE register val
> > > + * @comp_resp_timeout_reg: COMP_RESP_TIMEOUT register val
> > > + * @bus_slave_control_reg: BUS_SLAVE_CONTROL_REG register val
> > > + * @deadlock_avoid_type_reg:  DEADLOCK_AVOID_TYPE register val
> > > + * @intpin_reg_wpermit_reg0:  INTPIN_REG_WPERMIT register 0 val
> > > + * @intpin_reg_wpermit_reg1:  INTPIN_REG_WPERMIT register 1 val
> > > + * @intpin_reg_wpermit_reg2:  INTPIN_REG_WPERMIT register 2 val
> > > + * @intpin_reg_wpermit_reg3:  INTPIN_REG_WPERMIT register 3 val
> > > + * @int_reduce_control_reg: INT_REDUCE_CONTROL registers val
> > > + * @clkcfg_reg: CLK CFG register val
> > > + * @pch_phub_base_address:  register base address
> > > + * @pch_phub_extrom_base_address:  external rom base address
> > > + * @pch_phub_suspended: PHUB status val
> > > + */
> > > +struct pch_phub_reg_t {
> >
> > It would be better to drop the _t postfix on the type name.
> > By convention, we use this only for typedefs on simple data
> > types like off_t but not for structures.
> >
> > > + __u32 phub_id_reg;
> > > + __u32 q_pri_val_reg;
> > > + __u32 rc_q_maxsize_reg;
> >
> > When I told you to change the ioctl arguments to use __u32 instead
> > of u32, I was only referring to those parts that are in the user-visible
> > section of the header file. While it does not hurt to use __u32 in
> > the kernel, you should understand the distinction.
> >
> > > +/** pch_phub_write - Implements the write functionality of the Packet Hub
> > > + *  module.
> > > + *  @file: Contains the reference of the file structure
> > > + *  @buf: Usermode buffer pointer
> > > + *  @size: Usermode buffer size
> > > + *  @ppos: Contains the reference of the file structure
> > > + */
> > > +static ssize_t pch_phub_write(struct file *file, const char __user *buf,
> > > + size_t size, loff_t *ppos)
> > > +{
> > > + static __u32 data;
> >
> > No need to make data static.
> >
> > > + __s32 ret_value;
> > > + __u32 addr_offset = 0;
> > > + loff_t pos = *ppos;
> > > +
> > > + if (pos < 0)
> > > + return -EINVAL;
> > > +
> > > + for (addr_offset = 0; addr_offset < size; addr_offset++) {
> > > + get_user(data, &buf[addr_offset]);
> > > +
> > > + ret_value = pch_phub_write_serial_rom(0x80 + addr_offset + pos,
> > > + data);
> > > + if (ret_value)
> > > + return -EFAULT;
> >
> > You should return -EFAULT if the get_user() call fails, otherwise you have
> > a possible security hole. If pch_phub_write_serial_rom fails, the correct
> > return code would be -EIO.
> >
> > > +/**
> > > + * file_operations structure initialization
> > > + */
> > > +static const struct file_operations pch_phub_fops = {
> > > + .owner = THIS_MODULE,
> > > + .read = pch_phub_read,
> > > + .write = pch_phub_write,
> > > + .unlocked_ioctl = pch_phub_ioctl,
> > > +};
> >
> > If would be good to add a line of
> > .llseek = default_llseek,
> > here. I have a patch to change the default llseek method to one
> > that disallows seeking, so if you add this line, there is one
> > less driver for me to patch.
> >
> > Arnd
> >
>
>
>



^ permalink raw reply	[flat|nested] 45+ messages in thread
* Re: [PATCH] Topcliff PHUB: Generate PacketHub driver
@ 2010-06-22  5:33 Masayuki Ohtak
  2010-06-22 10:33 ` Masayuki Ohtak
                   ` (2 more replies)
  0 siblings, 3 replies; 45+ messages in thread
From: Masayuki Ohtak @ 2010-06-22  5:33 UTC (permalink / raw)
  To: Arnd Bergmann, Wang, Yong Y, Wang Qi"
  Cc: Intel OTC", Andrew", Alan Cox, LKML

Hi, Arnd and Yong Y

I have released Phub patch file.
Please confirm below.

Thanks, Ohtake.

Signed-off-by: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
---
 drivers/char/Kconfig             |   12 +
 drivers/char/Makefile            |    2 +
 drivers/char/pch_phub/Makefile   |    7 +
 drivers/char/pch_phub/pch_phub.c |  937 +++++++++++++++++++++++
 drivers/char/pch_phub/pch_phub.h |   58 ++
 5 files changed, 1016 insertions(+), 0 deletions(-)
 create mode 100644 drivers/char/pch_phub/Makefile
 create mode 100755 drivers/char/pch_phub/pch_phub.c
 create mode 100755 drivers/char/pch_phub/pch_phub.h

diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index e023682..7ff728a 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -4,6 +4,18 @@
 
 menu "Character devices"
 
+config PCH_PHUB
+	tristate "PCH PHUB"
+	depends on PCI
+	help
+	  If you say yes to this option, support will be included for the
+	  PCH Packet Hub Host controller.
+	  This driver is for PCH Packet hub driver for Topcliff.
+	  This driver is integrated as built-in.
+	  This driver can access GbE MAC address.
+	  This driver can access HW register.
+	  You can also be integrated as module.
+
 config VT
 	bool "Virtual terminal" if EMBEDDED
 	depends on !S390
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index f957edf..1e3eb6c 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH)		+= ps3flash.o
 obj-$(CONFIG_JS_RTC)		+= js-rtc.o
 js-rtc-y = rtc.o
 
+obj-$(CONFIG_PCH_PHUB)	+= pch_phub/
+
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c
 
diff --git a/drivers/char/pch_phub/Makefile b/drivers/char/pch_phub/Makefile
new file mode 100644
index 0000000..51ce785
--- /dev/null
+++ b/drivers/char/pch_phub/Makefile
@@ -0,0 +1,7 @@
+ifeq ($(CONFIG_PHUB_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_PCH_PHUB) += pch_phub_drv.o
+
+pch_phub_drv-objs := pch_phub.o
diff --git a/drivers/char/pch_phub/pch_phub.c b/drivers/char/pch_phub/pch_phub.c
new file mode 100755
index 0000000..6993182
--- /dev/null
+++ b/drivers/char/pch_phub/pch_phub.c
@@ -0,0 +1,937 @@
+/*!
+ * @file pch_phub.c
+ * @brief Provides all the implementation of the interfaces pertaining to
+ *		the Packet Hub 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) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 04/14/2010
+ * 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 <linux/pci.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+
+#include "pch_phub.h"
+
+/*--------------------------------------------
+	macros
+--------------------------------------------*/
+/* Status Register offset */
+#define PHUB_STATUS 0x00
+/* Control Register offset */
+#define PHUB_CONTROL 0x04
+/* Time out value for Status Register */
+#define PHUB_TIMEOUT 0x05
+/* Enabling for writing ROM */
+#define PCH_PHUB_ROM_WRITE_ENABLE 0x01
+/* Disabling for writing ROM */
+#define PCH_PHUB_ROM_WRITE_DISABLE 0x00
+/* ROM data area start address offset */
+#define PCH_PHUB_ROM_START_ADDR 0x14
+/* MAX number of INT_REDUCE_CONTROL registers */
+#define MAX_NUM_INT_REDUCE_CONTROL_REG 128
+
+#define PCI_DEVICE_ID_PCH1_PHUB 0x8801
+
+#define PCH_MINOR_NOS 1
+#define CLKCFG_CAN_50MHZ 0x12000000
+#define CLKCFG_CANCLK_MASK 0xFF000000
+
+#define MODULE_NAME "pch_phub"
+
+/*--------------------------------------------
+	global variables
+--------------------------------------------*/
+/**
+ * struct pch_phub_reg - PHUB register structure
+ * @phub_id_reg:		 PHUB_ID register val
+ * @q_pri_val_reg:		 QUEUE_PRI_VAL register val
+ * @rc_q_maxsize_reg:	 RC_QUEUE_MAXSIZE register val
+ * @bri_q_maxsize_reg:	 BRI_QUEUE_MAXSIZE register val
+ * @comp_resp_timeout_reg:	 COMP_RESP_TIMEOUT register val
+ * @bus_slave_control_reg:	 BUS_SLAVE_CONTROL_REG register val
+ * @deadlock_avoid_type_reg:  DEADLOCK_AVOID_TYPE register val
+ * @intpin_reg_wpermit_reg0:  INTPIN_REG_WPERMIT register 0 val
+ * @intpin_reg_wpermit_reg1:  INTPIN_REG_WPERMIT register 1 val
+ * @intpin_reg_wpermit_reg2:  INTPIN_REG_WPERMIT register 2 val
+ * @intpin_reg_wpermit_reg3:  INTPIN_REG_WPERMIT register 3 val
+ * @int_reduce_control_reg:	 INT_REDUCE_CONTROL registers val
+ * @clkcfg_reg:		 CLK CFG register val
+ * @pch_phub_base_address:  register base address
+ * @pch_phub_extrom_base_address:  external rom base address
+ * @pch_phub_suspended: PHUB status val
+ */
+struct pch_phub_reg {
+	unsigned int phub_id_reg;
+	unsigned int q_pri_val_reg;
+	unsigned int rc_q_maxsize_reg;
+	unsigned int bri_q_maxsize_reg;
+	unsigned int comp_resp_timeout_reg;
+	unsigned int bus_slave_control_reg;
+	unsigned int deadlock_avoid_type_reg;
+	unsigned int intpin_reg_wpermit_reg0;
+	unsigned int intpin_reg_wpermit_reg1;
+	unsigned int intpin_reg_wpermit_reg2;
+	unsigned int intpin_reg_wpermit_reg3;
+	unsigned int int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG];
+	unsigned int clkcfg_reg;
+	void __iomem *pch_phub_base_address;
+	void __iomem *pch_phub_extrom_base_address;
+	int pch_phub_suspended;
+} pch_phub_reg;
+
+static DEFINE_MUTEX(pch_phub_ioctl_mutex);
+
+/* ToDo: major number allocation via module parameter */
+static dev_t pch_phub_dev_no;
+static int pch_phub_major_no;
+static struct cdev pch_phub_dev;
+
+/*--------------------------------------------
+	functions implementations
+--------------------------------------------*/
+/** pch_phub_read_modify_write_reg - Implements the functionality of reading,
+ * 						modifying and writing register.
+ *  @reg_addr_offset:  Contains the register offset address value
+ *  @data:             Contains the writing value
+ *  @mask:             Contains the mask value
+ */
+static void pch_phub_read_modify_write_reg(unsigned int reg_addr_offset,
+				       unsigned int data, unsigned int mask)
+{
+	void __iomem *reg_addr = pch_phub_reg.pch_phub_base_address +\
+							 reg_addr_offset;
+	iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr);
+	return;
+}
+
+
+/** pch_phub_save_reg_conf - saves register configuration
+ */
+static void pch_phub_save_reg_conf(struct pci_dev *pdev)
+{
+	unsigned int i = 0;
+	void __iomem *p = pch_phub_reg.pch_phub_base_address;
+
+	dev_dbg(&pdev->dev, "pch_phub_save_reg_conf ENTRY\n");
+	/* to store contents of PHUB_ID register */
+	pch_phub_reg.phub_id_reg = ioread32(p + PCH_PHUB_PHUB_ID_REG);
+	/* to store contents of QUEUE_PRI_VAL register */
+	pch_phub_reg.q_pri_val_reg = ioread32(p + PCH_PHUB_QUEUE_PRI_VAL_REG);
+	/* to store contents of RC_QUEUE_MAXSIZE register */
+	pch_phub_reg.rc_q_maxsize_reg =
+	    ioread32(p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
+	/* to store contents of BRI_QUEUE_MAXSIZE register */
+	pch_phub_reg.bri_q_maxsize_reg =
+	    ioread32(p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
+	/* to store contents of COMP_RESP_TIMEOUT register */
+	pch_phub_reg.comp_resp_timeout_reg =
+	    ioread32(p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
+	/* to store contents of BUS_SLAVE_CONTROL_REG register */
+	pch_phub_reg.bus_slave_control_reg =
+	    ioread32(p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
+	/* to store contents of DEADLOCK_AVOID_TYPE register */
+	pch_phub_reg.deadlock_avoid_type_reg =
+	    ioread32(p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
+	/* to store contents of INTPIN_REG_WPERMIT register 0 */
+	pch_phub_reg.intpin_reg_wpermit_reg0 =
+	    ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
+	/* to store contents of INTPIN_REG_WPERMIT register 1 */
+	pch_phub_reg.intpin_reg_wpermit_reg1 =
+	    ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
+	/* to store contents of INTPIN_REG_WPERMIT register 2 */
+	pch_phub_reg.intpin_reg_wpermit_reg2 =
+	    ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
+	/* to store contents of INTPIN_REG_WPERMIT register 3 */
+	pch_phub_reg.intpin_reg_wpermit_reg3 =
+	    ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
+	dev_dbg(&pdev->dev, "pch_phub_save_reg_conf : "
+		"pch_phub_reg.phub_id_reg=%x, "
+		"pch_phub_reg.q_pri_val_reg=%x, "
+		"pch_phub_reg.rc_q_maxsize_reg=%x, "
+		"pch_phub_reg.bri_q_maxsize_reg=%x, "
+		"pch_phub_reg.comp_resp_timeout_reg=%x, "
+		"pch_phub_reg.bus_slave_control_reg=%x, "
+		"pch_phub_reg.deadlock_avoid_type_reg=%x, "
+		"pch_phub_reg.intpin_reg_wpermit_reg0=%x, "
+		"pch_phub_reg.intpin_reg_wpermit_reg1=%x, "
+		"pch_phub_reg.intpin_reg_wpermit_reg2=%x, "
+		"pch_phub_reg.intpin_reg_wpermit_reg3=%x\n",
+		pch_phub_reg.phub_id_reg,
+		pch_phub_reg.q_pri_val_reg,
+		pch_phub_reg.rc_q_maxsize_reg,
+		pch_phub_reg.bri_q_maxsize_reg,
+		pch_phub_reg.comp_resp_timeout_reg,
+		pch_phub_reg.bus_slave_control_reg,
+		pch_phub_reg.deadlock_avoid_type_reg,
+		pch_phub_reg.intpin_reg_wpermit_reg0,
+		pch_phub_reg.intpin_reg_wpermit_reg1,
+		pch_phub_reg.intpin_reg_wpermit_reg2,
+		pch_phub_reg.intpin_reg_wpermit_reg3);
+	/* to store contents of INT_REDUCE_CONTROL registers */
+	for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
+		pch_phub_reg.int_reduce_control_reg[i] =
+		    ioread32(p +
+			PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+		dev_dbg(&pdev->dev, "pch_phub_save_reg_conf : "
+			"pch_phub_reg.int_reduce_control_reg[%d]=%x\n",
+			i, pch_phub_reg.int_reduce_control_reg[i]);
+	}
+	/* save clk cfg register */
+	pch_phub_reg.clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET);
+
+	return;
+}
+
+/** pch_phub_restore_reg_conf - restore register configuration
+ */
+
+static void pch_phub_restore_reg_conf(struct pci_dev *pdev)
+{
+	unsigned int i;
+	void __iomem *p = pch_phub_reg.pch_phub_base_address;
+
+	dev_dbg(&pdev->dev, "pch_phub_restore_reg_conf ENTRY\n");
+	/* to store contents of PHUB_ID register */
+	iowrite32(pch_phub_reg.phub_id_reg, p + PCH_PHUB_PHUB_ID_REG);
+	/* to store contents of QUEUE_PRI_VAL register */
+	iowrite32(pch_phub_reg.q_pri_val_reg, p + PCH_PHUB_QUEUE_PRI_VAL_REG);
+	/* to store contents of RC_QUEUE_MAXSIZE register */
+	iowrite32(pch_phub_reg.rc_q_maxsize_reg,
+					p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
+	/* to store contents of BRI_QUEUE_MAXSIZE register */
+	iowrite32(pch_phub_reg.bri_q_maxsize_reg,
+					p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
+	/* to store contents of COMP_RESP_TIMEOUT register */
+	iowrite32(pch_phub_reg.comp_resp_timeout_reg,
+					p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
+	/* to store contents of BUS_SLAVE_CONTROL_REG register */
+	iowrite32(pch_phub_reg.bus_slave_control_reg,
+					p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
+	/* to store contents of DEADLOCK_AVOID_TYPE register */
+	iowrite32(pch_phub_reg.deadlock_avoid_type_reg,
+					p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
+	/* to store contents of INTPIN_REG_WPERMIT register 0 */
+	iowrite32(pch_phub_reg.intpin_reg_wpermit_reg0,
+					p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
+	/* to store contents of INTPIN_REG_WPERMIT register 1 */
+	iowrite32(pch_phub_reg.intpin_reg_wpermit_reg1,
+					p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
+	/* to store contents of INTPIN_REG_WPERMIT register 2 */
+	iowrite32(pch_phub_reg.intpin_reg_wpermit_reg2,
+					p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
+	/* to store contents of INTPIN_REG_WPERMIT register 3 */
+	iowrite32(pch_phub_reg.intpin_reg_wpermit_reg3,
+					p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
+	dev_dbg(&pdev->dev, "pch_phub_save_reg_conf : "
+		"pch_phub_reg.phub_id_reg=%x, "
+		"pch_phub_reg.q_pri_val_reg=%x, "
+		"pch_phub_reg.rc_q_maxsize_reg=%x, "
+		"pch_phub_reg.bri_q_maxsize_reg=%x, "
+		"pch_phub_reg.comp_resp_timeout_reg=%x, "
+		"pch_phub_reg.bus_slave_control_reg=%x, "
+		"pch_phub_reg.deadlock_avoid_type_reg=%x, "
+		"pch_phub_reg.intpin_reg_wpermit_reg0=%x, "
+		"pch_phub_reg.intpin_reg_wpermit_reg1=%x, "
+		"pch_phub_reg.intpin_reg_wpermit_reg2=%x, "
+		"pch_phub_reg.intpin_reg_wpermit_reg3=%x\n",
+		pch_phub_reg.phub_id_reg,
+		pch_phub_reg.q_pri_val_reg,
+		pch_phub_reg.rc_q_maxsize_reg,
+		pch_phub_reg.bri_q_maxsize_reg,
+		pch_phub_reg.comp_resp_timeout_reg,
+		pch_phub_reg.bus_slave_control_reg,
+		pch_phub_reg.deadlock_avoid_type_reg,
+		pch_phub_reg.intpin_reg_wpermit_reg0,
+		pch_phub_reg.intpin_reg_wpermit_reg1,
+		pch_phub_reg.intpin_reg_wpermit_reg2,
+		pch_phub_reg.intpin_reg_wpermit_reg3);
+	/* to store contents of INT_REDUCE_CONTROL register */
+	for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
+		iowrite32(pch_phub_reg.int_reduce_control_reg[i],
+			p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
+		dev_dbg(&pdev->dev, "pch_phub_save_reg_conf : "
+			"pch_phub_reg.int_reduce_control_reg[%d]=%x\n",
+			i, pch_phub_reg.int_reduce_control_reg[i]);
+	}
+
+	/*restore the clock config reg */
+	iowrite32(pch_phub_reg.clkcfg_reg, p + CLKCFG_REG_OFFSET);
+
+	return;
+}
+
+/** pch_phub_read_serial_rom - Implements the functionality of reading Serial
+ *  									 ROM.
+ *  @offset_address: Contains the Serial ROM address offset value
+ *  @data: Contains the Serial ROM value
+ */
+static int pch_phub_read_serial_rom(unsigned int offset_address,
+							 unsigned char *data)
+{
+	void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address +\
+								 offset_address;
+
+	*data = ioread8(mem_addr);
+
+	return 0;
+}
+
+/** pch_phub_write_serial_rom - Implements the functionality of writing Serial
+ *  									 ROM.
+ *  @offset_address: Contains the Serial ROM address offset value
+ *  @data: Contains the Serial ROM value
+ */
+static int pch_phub_write_serial_rom(unsigned int offset_address,
+							 unsigned char data)
+{
+	int retval = 0;
+	void __iomem *mem_addr = pch_phub_reg.pch_phub_extrom_base_address +\
+						 (offset_address & 0xFFFFFFFC);
+	int i = 0;
+	unsigned int word_data = 0;
+
+	iowrite32(PCH_PHUB_ROM_WRITE_ENABLE,
+			pch_phub_reg.pch_phub_extrom_base_address +\
+								 PHUB_CONTROL);
+
+	word_data = ioread32(mem_addr);
+
+	switch (offset_address % 4) {
+	case 0:
+		word_data &= 0xFFFFFF00;
+		iowrite32((word_data | (unsigned int)data),
+						mem_addr);
+		break;
+	case 1:
+		word_data &= 0xFFFF00FF;
+		iowrite32((word_data | ((unsigned int)data << 8)),
+						mem_addr);
+		break;
+	case 2:
+		word_data &= 0xFF00FFFF;
+		iowrite32((word_data | ((unsigned int)data << 16)),
+						mem_addr);
+		break;
+	case 3:
+		word_data &= 0x00FFFFFF;
+		iowrite32((word_data | ((unsigned int)data << 24)),
+						mem_addr);
+		break;
+	}
+	while (0x00 !=
+	       ioread8(pch_phub_reg.pch_phub_extrom_base_address +\
+							 PHUB_STATUS)) {
+		msleep(1);
+		if (PHUB_TIMEOUT == i) {
+			retval = -EPERM;
+			break;
+		}
+		i++;
+	}
+
+	iowrite32(PCH_PHUB_ROM_WRITE_DISABLE,
+			pch_phub_reg.pch_phub_extrom_base_address +\
+								 PHUB_CONTROL);
+
+	return retval;
+}
+
+/** pch_phub_read_serial_rom_val - Implements the functionality of reading
+ *  							 Serial ROM value.
+ *  @offset_address: Contains the Serial ROM address offset value
+ *  @data: Contains the Serial ROM value
+ */
+static int pch_phub_read_serial_rom_val(unsigned int offset_address,
+							 unsigned char *data)
+{
+	int retval = 0;
+	unsigned int mem_addr;
+
+	mem_addr = (offset_address / 4 * 8) + 3 -
+			(offset_address % 4) + PCH_PHUB_ROM_START_ADDR;
+	retval = pch_phub_read_serial_rom(mem_addr, data);
+
+	return retval;
+}
+
+/** pch_phub_write_serial_rom_val - Implements the functionality of writing
+ *  							 Serial ROM value.
+ *  @offset_address: Contains the Serial ROM address offset value
+ *  @data: Contains the Serial ROM value
+ */
+static int pch_phub_write_serial_rom_val(unsigned int offset_address,
+				     unsigned char data)
+{
+	int retval = 0;
+	unsigned int mem_addr;
+
+	mem_addr =
+	    (offset_address / 4 * 8) + 3 - (offset_address % 4) +
+	    PCH_PHUB_ROM_START_ADDR;
+	retval = pch_phub_write_serial_rom(mem_addr, data);
+
+	return retval;
+}
+
+/** pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration
+ *  						for Gigabit Ethernet MAC address
+ */
+static int pch_phub_gbe_serial_rom_conf(void)
+{
+	int retval = 0;
+
+	retval |= pch_phub_write_serial_rom(0x0b, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x0a, 0x10);
+	retval |= pch_phub_write_serial_rom(0x09, 0x01);
+	retval |= pch_phub_write_serial_rom(0x08, 0x02);
+
+	retval |= pch_phub_write_serial_rom(0x0f, 0x00);
+	retval |= pch_phub_write_serial_rom(0x0e, 0x00);
+	retval |= pch_phub_write_serial_rom(0x0d, 0x00);
+	retval |= pch_phub_write_serial_rom(0x0c, 0x80);
+
+	retval |= pch_phub_write_serial_rom(0x13, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x12, 0x10);
+	retval |= pch_phub_write_serial_rom(0x11, 0x01);
+	retval |= pch_phub_write_serial_rom(0x10, 0x18);
+
+	retval |= pch_phub_write_serial_rom(0x1b, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x1a, 0x10);
+	retval |= pch_phub_write_serial_rom(0x19, 0x01);
+	retval |= pch_phub_write_serial_rom(0x18, 0x19);
+
+	retval |= pch_phub_write_serial_rom(0x23, 0xbc);
+	retval |= pch_phub_write_serial_rom(0x22, 0x10);
+	retval |= pch_phub_write_serial_rom(0x21, 0x01);
+	retval |= pch_phub_write_serial_rom(0x20, 0x3a);
+
+	retval |= pch_phub_write_serial_rom(0x27, 0x01);
+	retval |= pch_phub_write_serial_rom(0x26, 0x00);
+	retval |= pch_phub_write_serial_rom(0x25, 0x00);
+	retval |= pch_phub_write_serial_rom(0x24, 0x00);
+
+	return retval;
+}
+
+/** pch_phub_read_gbe_mac_addr - Contains the Gigabit Ethernet MAC address
+ *  								offset value
+ *  @offset_address: Gigabit Ethernet MAC address offset value
+ *  @data: Contains the Gigabit Ethernet MAC address value
+ */
+static int pch_phub_read_gbe_mac_addr(unsigned int offset_address,
+							 unsigned char *data)
+{
+	int retval = 0;
+
+	retval = pch_phub_read_serial_rom_val(offset_address, data);
+
+	return retval;
+}
+
+/** pch_phub_write_gbe_mac_addr - Write MAC address
+ *  @offset_address: Contains the Gigabit Ethernet MAC address offset value
+ *  @data: Contains the Gigabit Ethernet MAC address value
+ */
+static int pch_phub_write_gbe_mac_addr(unsigned int offset_address,
+				   unsigned char data)
+{
+	int retval = 0;
+
+	retval = pch_phub_gbe_serial_rom_conf();
+	retval |= pch_phub_write_serial_rom_val(offset_address, data);
+
+	return retval;
+}
+
+/** pch_phub_read - Implements the read functionality of the Packet Hub module.
+ *  @file: Contains the reference of the file structure
+ *  @buf: Usermode buffer pointer
+ *  @size: Usermode buffer size
+ *  @ppos: Contains the reference of the file structure
+ */
+
+static ssize_t pch_phub_read(struct file *file, char __user *buf, size_t size,
+								 loff_t *ppos)
+{
+	unsigned int rom_signature = 0;
+	unsigned char rom_length;
+	int ret_value;
+	unsigned int tmp;
+	unsigned char data;
+	unsigned int addr_offset = 0;
+	unsigned int orom_size;
+	loff_t pos = *ppos;
+
+	if (pos < 0)
+		return -EINVAL;
+
+	/*Get Rom signature*/
+	pch_phub_read_serial_rom(0x80, (unsigned char *)&rom_signature);
+	pch_phub_read_serial_rom(0x81, (unsigned char *)&tmp);
+	rom_signature |= (tmp & 0xff) << 8;
+	if (rom_signature == 0xAA55) {
+		pch_phub_read_serial_rom(0x82, &rom_length);
+		orom_size = rom_length * 512;
+		if (orom_size < pos)
+			return 0;
+
+		for (addr_offset = 0; addr_offset < size; addr_offset++) {
+			pch_phub_read_serial_rom(0x80 + addr_offset + pos,
+									 &data);
+			ret_value = copy_to_user(&buf[addr_offset], &data, 1);
+			if (ret_value)
+				return -EFAULT;
+
+			if (orom_size < pos + addr_offset) {
+				*ppos += addr_offset;
+				return addr_offset;
+			}
+
+		}
+	} else {
+		return -ENOEXEC;
+	}
+	*ppos += addr_offset;
+	return addr_offset;
+}
+
+/** pch_phub_write - Implements the write functionality of the Packet Hub
+ *  									 module.
+ *  @file: Contains the reference of the file structure
+ *  @buf: Usermode buffer pointer
+ *  @size: Usermode buffer size
+ *  @ppos: Contains the reference of the file structure
+ */
+static ssize_t pch_phub_write(struct file *file, const char __user *buf,
+						 size_t size, loff_t *ppos)
+{
+	unsigned int data;
+	int ret_value;
+	unsigned int addr_offset = 0;
+	loff_t pos = *ppos;
+
+	if (pos < 0)
+		return -EINVAL;
+
+	for (addr_offset = 0; addr_offset < size; addr_offset++) {
+		ret_value = get_user(data, &buf[addr_offset]);
+		if (ret_value)
+			return -EFAULT;
+
+		ret_value = pch_phub_write_serial_rom(0x80 + addr_offset + pos,
+								 data);
+		if (ret_value)
+			return -EIO;
+
+		if (PCH_PHUB_OROM_SIZE < pos + addr_offset) {
+			*ppos += addr_offset;
+			return addr_offset;
+		}
+
+	}
+
+	*ppos += addr_offset;
+	return addr_offset;
+}
+
+
+/** pch_phub_ioctl - Implements the various ioctl functionalities of the Packet
+ *  								 Hub module.
+ *  @inode: Contains the reference of the inode structure
+ *  @file: Contains the reference of the file structure
+ *  @cmd: Contains the command value
+ *  @arg: Contains the command argument value
+ */
+
+
+static long pch_phub_ioctl(struct file *file, unsigned int cmd,
+							 unsigned long arg)
+{
+	int ret_value = 0;
+	__u8 mac_addr[6];
+	int ret;
+	unsigned int i;
+	void __user *varg = (void __user *)arg;
+
+	ret = mutex_lock_interruptible(&pch_phub_ioctl_mutex);
+	if (ret) {
+		ret_value = -ERESTARTSYS;
+		goto return_nomutex;
+	}
+
+	if (pch_phub_reg.pch_phub_suspended == true) {
+		ret_value = -EPERM;
+		goto return_ioctrl;
+	}
+
+	switch (cmd) {
+	case IOCTL_PHUB_READ_MAC_ADDR:
+		for (i = 0; i < 6; i++)
+			pch_phub_read_gbe_mac_addr(i, &mac_addr[i]);
+
+		ret_value = copy_to_user(varg,
+					 mac_addr, sizeof(mac_addr));
+		if (ret_value) {
+			ret_value = -EFAULT;
+			goto return_ioctrl;
+		}
+		break;
+
+	case IOCTL_PHUB_WRITE_MAC_ADDR:
+		ret_value = copy_from_user(mac_addr, varg, sizeof(mac_addr));
+
+		if (ret_value) {
+			ret_value = -EFAULT;
+			goto return_ioctrl;
+		}
+		for (i = 0; i < 6; i++)
+			pch_phub_write_gbe_mac_addr(i, mac_addr[i]);
+		break;
+
+	default:
+		ret_value = -EINVAL;
+		break;
+	}
+return_ioctrl:
+	mutex_unlock(&pch_phub_ioctl_mutex);
+return_nomutex:
+	return ret_value;
+}
+
+
+/**
+ * file_operations structure initialization
+ */
+static const struct file_operations pch_phub_fops = {
+	.owner = THIS_MODULE,
+	.read = pch_phub_read,
+	.write = pch_phub_write,
+	.unlocked_ioctl = pch_phub_ioctl,
+	.llseek = default_llseek
+};
+
+
+/** pch_phub_probe - Implements the probe functionality of the module.
+ *  @pdev: Contains the reference of the pci_dev structure
+ *  @id: Contains the reference of the pci_device_id structure
+ */
+static int __devinit pch_phub_probe(struct pci_dev *pdev,
+				       const struct pci_device_id *id)
+{
+	char *DRIVER_NAME = "pch_phub";
+	int ret;
+	unsigned int rom_size;
+
+	pch_phub_major_no = (pch_phub_major_no < 0 || pch_phub_major_no > 254) ?
+				0 : pch_phub_major_no;
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		dev_dbg(&pdev->dev,
+				"\npch_phub_probe : pci_enable_device FAILED");
+		goto err_probe;
+	}
+	dev_dbg(&pdev->dev, "pch_phub_probe : "
+			"pci_enable_device returns %d\n", ret);
+
+	ret = pci_request_regions(pdev, DRIVER_NAME);
+	if (ret) {
+		dev_dbg(&pdev->dev,
+				"pch_phub_probe : pci_request_regions FAILED");
+		pci_disable_device(pdev);
+		goto err_probe;
+	}
+	dev_dbg(&pdev->dev, "pch_phub_probe : "
+		"pci_request_regions returns %d\n", ret);
+
+	pch_phub_reg.pch_phub_base_address = \
+					(void __iomem *)pci_iomap(pdev, 1, 0);
+
+	if (pch_phub_reg.pch_phub_base_address == 0) {
+		dev_dbg(&pdev->dev, "pch_phub_probe : pci_iomap FAILED");
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		ret = -ENOMEM;
+		goto err_probe;
+	}
+	dev_dbg(&pdev->dev, "pch_phub_probe : pci_iomap SUCCESS and value "
+		"in pch_phub_base_address variable is 0x%08x\n",
+		(unsigned int)pch_phub_reg.pch_phub_base_address);
+
+	pch_phub_reg.pch_phub_extrom_base_address =
+	    (void __iomem *)pci_map_rom(pdev, &rom_size);
+	if (pch_phub_reg.pch_phub_extrom_base_address == 0) {
+		dev_dbg(&pdev->dev, "pch_phub_probe : pci_map_rom FAILED");
+		pci_iounmap(pdev, (void *)pch_phub_reg.pch_phub_base_address);
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		ret = -ENOMEM;
+		goto err_probe;
+	}
+	dev_dbg(&pdev->dev, "pch_phub_probe : "
+		"pci_map_rom SUCCESS and value in "
+		"pch_phub_extrom_base_address variable is 0x%08x\n",
+		(unsigned int)pch_phub_reg.pch_phub_extrom_base_address);
+
+	if (pch_phub_major_no) {
+		pch_phub_dev_no = MKDEV(pch_phub_major_no, 0);
+		ret = register_chrdev_region(pch_phub_dev_no,
+					   PCH_MINOR_NOS, DRIVER_NAME);
+		if (ret) {
+			dev_dbg(&pdev->dev, "pch_phub_probe : "
+				"register_chrdev_region FAILED");
+			pci_unmap_rom(pdev,
+			(void *)pch_phub_reg.pch_phub_extrom_base_address);
+			pci_iounmap(pdev,
+				(void *)pch_phub_reg.pch_phub_base_address);
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			goto err_probe;
+		}
+		dev_dbg(&pdev->dev, "pch_phub_probe : "
+				"register_chrdev_region returns %d\n", ret);
+	} else {
+		ret = alloc_chrdev_region(&pch_phub_dev_no, 0,
+						PCH_MINOR_NOS, DRIVER_NAME);
+		if (ret) {
+			dev_dbg(&pdev->dev, "pch_phub_probe : "
+					"alloc_chrdev_region FAILED");
+			pci_unmap_rom(pdev,
+			(void *)pch_phub_reg.pch_phub_extrom_base_address);
+			pci_iounmap(pdev,
+				    (void *)pch_phub_reg.pch_phub_base_address);
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			goto err_probe;
+		}
+		dev_dbg(&pdev->dev, "pch_phub_probe : "
+			"alloc_chrdev_region returns %d\n", ret);
+	}
+
+	cdev_init(&pch_phub_dev, &pch_phub_fops);
+	dev_dbg(&pdev->dev,
+			"pch_phub_probe :  cdev_init invoked successfully\n");
+
+	pch_phub_dev.owner = THIS_MODULE;
+	pch_phub_dev.ops = &pch_phub_fops;
+
+	ret = cdev_add(&pch_phub_dev, pch_phub_dev_no, PCH_MINOR_NOS);
+	if (ret) {
+		dev_dbg(&pdev->dev, "pch_phub_probe :  cdev_add FAILED");
+		unregister_chrdev_region(pch_phub_dev_no, PCH_MINOR_NOS);
+		pci_unmap_rom(pdev,
+			(void *)pch_phub_reg.pch_phub_extrom_base_address);
+		pci_iounmap(pdev, (void *)pch_phub_reg.pch_phub_base_address);
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		goto err_probe;
+	}
+	dev_dbg(&pdev->dev, "pch_phub_probe :  cdev_add returns %d\n", ret);
+
+	/*set the clock config reg if CAN clock is 50Mhz */
+	dev_dbg(&pdev->dev, "pch_phub_probe : invoking "
+		"pch_phub_read_modify_write_reg "
+		"to set CLKCFG reg for CAN clk 50Mhz\n");
+	pch_phub_read_modify_write_reg((unsigned int)CLKCFG_REG_OFFSET,
+					  CLKCFG_CAN_50MHZ, CLKCFG_CANCLK_MASK);
+
+	/* set the prefech value */
+	iowrite32(0x000ffffa, pch_phub_reg.pch_phub_base_address + 0x14);
+	/* set the interrupt delay value */
+	iowrite32(0x25, pch_phub_reg.pch_phub_base_address + 0x44);
+	return 0;
+
+err_probe:
+	dev_dbg(&pdev->dev, "pch_phub_probe returns %d\n", ret);
+	return ret;
+}
+
+/** pch_phub_remove - Implements the remove functionality of the module.
+ *  @pdev: Contains the reference of the pci_dev structure
+ */
+static void __devexit pch_phub_remove(struct pci_dev *pdev)
+{
+
+	cdev_del(&pch_phub_dev);
+	dev_dbg(&pdev->dev,
+			"pch_phub_remove - cdev_del Invoked successfully\n");
+
+	unregister_chrdev_region(pch_phub_dev_no, PCH_MINOR_NOS);
+	dev_dbg(&pdev->dev, "pch_phub_remove - "
+		"unregister_chrdev_region Invoked successfully\n");
+
+	pci_unmap_rom(pdev, (void *)pch_phub_reg.pch_phub_extrom_base_address);
+
+	pci_iounmap(pdev, (void *)pch_phub_reg.pch_phub_base_address);
+
+	dev_dbg(&pdev->dev, "pch_phub_remove - "
+			"pci_iounmap Invoked successfully\n");
+
+	pci_release_regions(pdev);
+	dev_dbg(&pdev->dev, "pch_phub_remove - "
+		"pci_release_regions Invoked successfully\n");
+
+	pci_disable_device(pdev);
+	dev_dbg(&pdev->dev, "pch_phub_remove - "
+		"pci_disable_device Invoked successfully\n");
+
+}
+
+#ifdef CONFIG_PM
+
+/** pch_phub_suspend - Implements the suspend functionality of the module.
+ *  @pdev: Contains the reference of the pci_dev structure
+ *  @state: Contains the reference of the pm_message_t structure
+ */
+static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int ret;
+
+	pch_phub_reg.pch_phub_suspended = true;/* For blocking further IOCTLs */
+
+	pch_phub_save_reg_conf(pdev);
+	dev_dbg(&pdev->dev, "pch_phub_suspend - "
+		"pch_phub_save_reg_conf Invoked successfully\n");
+
+	ret = pci_save_state(pdev);
+	if (ret) {
+		dev_dbg(&pdev->dev,
+			" pch_phub_suspend -pci_save_state returns-%d\n", ret);
+		return ret;
+	}
+	dev_dbg(&pdev->dev,
+			"pch_phub_suspend - pci_save_state returns %d\n", ret);
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	dev_dbg(&pdev->dev, "pch_phub_suspend - "
+			"pci_enable_wake Invoked successfully\n");
+
+	pci_disable_device(pdev);
+	dev_dbg(&pdev->dev, "pch_phub_suspend - "
+			"pci_disable_device Invoked successfully\n");
+
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	dev_dbg(&pdev->dev, "pch_phub_suspend - "
+			"pci_set_power_state Invoked successfully   "
+			"return = %d\n", 0);
+
+	return 0;
+}
+
+/** pch_phub_resume - Implements the resume functionality of the module.
+ *  @pdev: Contains the reference of the pci_dev structure
+ */
+static int pch_phub_resume(struct pci_dev *pdev)
+{
+
+	int ret;
+
+	pci_set_power_state(pdev, PCI_D0);
+	dev_dbg(&pdev->dev, "pch_phub_resume - "
+		"pci_set_power_state Invoked successfully\n");
+
+	pci_restore_state(pdev);
+	dev_dbg(&pdev->dev, "pch_phub_resume - "
+		"pci_restore_state Invoked successfully\n");
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		dev_dbg(&pdev->dev,
+				"pch_phub_resume-pci_enable_device failed ");
+		return ret;
+	}
+
+	dev_dbg(&pdev->dev, "pch_phub_resume - "
+			"pci_enable_device returns -%d\n", ret);
+
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	dev_dbg(&pdev->dev, "pch_phub_resume - "
+			"pci_enable_wake Invoked successfully\n");
+
+	pch_phub_restore_reg_conf(pdev);
+	dev_dbg(&pdev->dev, "pch_phub_resume - "
+		"pch_phub_restore_reg_conf Invoked successfully\n");
+
+	pch_phub_reg.pch_phub_suspended = false;
+
+	dev_dbg(&pdev->dev, "pch_phub_resume  returns- %d\n", 0);
+	return 0;
+}
+#endif /* CONFIG_PM */
+
+static struct pci_device_id pch_phub_pcidev_id[] = {
+
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH1_PHUB)},
+	{0,}
+};
+
+
+static struct pci_driver pch_phub_driver = {
+	.name = "pch_phub",
+	.id_table = pch_phub_pcidev_id,
+	.probe = pch_phub_probe,
+	.remove = __devexit_p(pch_phub_remove),
+#ifdef CONFIG_PM
+	.suspend = pch_phub_suspend,
+	.resume = pch_phub_resume
+#endif
+};
+
+/** pch_phub_pci_init - Implements the initialization functionality of
+ *  								 the module.
+ */
+static int __init pch_phub_pci_init(void)
+{
+	int ret;
+	ret = pci_register_driver(&pch_phub_driver);
+
+	return ret;
+}
+
+/** pch_phub_pci_exit - Implements the exit functionality of the module.
+ */
+static void __exit pch_phub_pci_exit(void)
+{
+	pci_unregister_driver(&pch_phub_driver);
+
+}
+
+module_init(pch_phub_pci_init);
+module_exit(pch_phub_pci_exit);
+module_param(pch_phub_major_no, int, S_IRUSR | S_IWUSR);
+
+MODULE_DESCRIPTION("PCH PACKET HUB PCI Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/char/pch_phub/pch_phub.h b/drivers/char/pch_phub/pch_phub.h
new file mode 100755
index 0000000..25d7c56
--- /dev/null
+++ b/drivers/char/pch_phub/pch_phub.h
@@ -0,0 +1,58 @@
+#ifndef __PCH_PHUB_H__
+#define __PCH_PHUB_H__
+/*!
+ * @file pch_phub.h
+ * @brief Provides all the interfaces pertaining to the Packet Hub 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) 2010 OKI SEMICONDUCTOR Co., LTD.
+ *
+ * created:
+ *	OKI SEMICONDUCTOR 04/14/2010
+ * modified:
+ *
+ */
+
+#define PHUB_IOCTL_MAGIC 		(0xf7)
+
+/*Outlines the read mac address function signature. */
+#define IOCTL_PHUB_READ_MAC_ADDR (_IOR(PHUB_IOCTL_MAGIC, 6, __u8[6]))
+
+/*brief Outlines the write mac address function signature. */
+#define IOCTL_PHUB_WRITE_MAC_ADDR (_IOW(PHUB_IOCTL_MAGIC, 7, __u8[6]))
+
+
+/* Registers address offset */
+#define PCH_PHUB_PHUB_ID_REG			0x0000
+#define PCH_PHUB_QUEUE_PRI_VAL_REG		0x0004
+#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG		0x0008
+#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG		0x000C
+#define PCH_PHUB_COMP_RESP_TIMEOUT_REG		0x0010
+#define PCH_PHUB_BUS_SLAVE_CONTROL_REG		0x0014
+#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG	0x0018
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0	0x0020
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1	0x0024
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2	0x0028
+#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3	0x002C
+#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE	0x0040
+#define CLKCFG_REG_OFFSET           		0x500
+
+#define PCH_PHUB_OROM_SIZE 15360
+
+#endif
-- 
1.6.0.6

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

end of thread, other threads:[~2010-07-01  4:09 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-04 10:16 [PATCH] Topcliff PHUB: Generate PacketHub driver Masayuki Ohtake
2010-06-04 12:00 ` Alan Cox
2010-06-07  7:53   ` Masayuki Ohtake
2010-06-07 13:37 ` Arnd Bergmann
2010-06-08  0:15   ` Masayuki Ohtake
2010-06-08  8:48   ` Masayuki Ohtake
2010-06-08  9:29     ` Arnd Bergmann
2010-06-09  0:14     ` Wang, Qi
  -- strict thread matches above, loose matches on Subject: below --
2010-06-07 12:39 Masayuki Ohtak
2010-06-07 15:05 ` Alan Cox
2010-06-08  0:19   ` Masayuki Ohtake
2010-06-14 12:09 ` Masayuki Ohtak
2010-06-14 12:50   ` Arnd Bergmann
2010-06-14 23:56     ` Masayuki Ohtake
2010-06-15  6:25     ` Masayuki Ohtake
2010-06-15 10:42       ` Arnd Bergmann
2010-06-15 12:12         ` Masayuki Ohtake
2010-06-17  2:43   ` Masayuki Ohtak
2010-06-17 11:59     ` Arnd Bergmann
2010-06-17 23:49       ` Masayuki Ohtake
2010-06-18  8:08     ` Wang, Yong Y
2010-06-18 11:39       ` Masayuki Ohtake
2010-06-08  5:00 Masayuki Ohtak
2010-06-08  5:46 ` Masayuki Ohtake
2010-06-08  8:01   ` Alan Cox
2010-06-08  7:20 ` Yong Wang
2010-06-08  8:09   ` Masayuki Ohtake
2010-06-08  8:04 ` Alan Cox
2010-06-15  6:58 Masayuki Ohtake
2010-06-15 10:37 ` Arnd Bergmann
2010-06-15 12:14   ` Masayuki Ohtake
2010-06-16  8:58   ` Masayuki Ohtake
2010-06-16 10:50     ` Arnd Bergmann
2010-06-17  0:17       ` Masayuki Ohtake
2010-06-22  2:14 Masayuki Ohtake
2010-06-22  5:33 Masayuki Ohtak
2010-06-22 10:33 ` Masayuki Ohtak
2010-06-22 22:12   ` Andrew Morton
2010-06-23  0:31     ` Masayuki Ohtake
2010-06-22 11:30 ` Arnd Bergmann
2010-06-22 13:52   ` Yong Wang
2010-06-29 23:31 ` Andy Isaacson
2010-06-30  5:58   ` Masayuki Ohtake
2010-06-30 18:28     ` Andy Isaacson
2010-07-01  4:08       ` Masayuki Ohtake

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox