

From: Masayuki Ohtake <masa-korg@dsn.okisemi.com>
Subject: OKI Semiconductor PCH GPIO driver

This driver implements GPIO controls for PCH.

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

---
 drivers/gpio/Kconfig                     |    
 drivers/gpio/Makefile                    |     
 drivers/gpio/pch_gpio/Makefile           |     
 drivers/gpio/pch_gpio/pch_common.h       |  
 drivers/gpio/pch_gpio/pch_debug.h        |  
 drivers/gpio/pch_gpio/pch_gpio_hal.c     |  
 drivers/gpio/pch_gpio/pch_gpio_hal.h     |  
 drivers/gpio/pch_gpio/pch_gpio_main.c    |  
 drivers/gpio/pch_gpio/pch_gpio_main.h    |  
 drivers/gpio/pch_gpio/pch_gpio_pci.c     | 
+++++++++++++++++++++++++++++++ 10 files changed, yy insertions(+)(-)
diff -urN linux-2.6.33.1/drivers/gpio/Kconfig topcliff-2.6.33.1/drivers/gpio/Kconfig
--- linux-2.6.33.1/drivers/gpio/Kconfig	2010-03-16 01:09:39.000000000 +0900
+++ topcliff-2.6.33.1/drivers/gpio/Kconfig	2010-04-01 10:58:31.000000000 +0900
@@ -87,6 +87,13 @@
 
 comment "I2C GPIO expanders:"
 
+config PCH_GPIO
+	tristate "PCH GPIO"
+	depends on PCI
+	help
+	  If you say yes to this option, support will be included for the SMB
+	  PCH GPIO Host controller.
+
 config GPIO_MAX732X
 	tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
 	depends on I2C
diff -urN linux-2.6.33.1/drivers/gpio/Makefile topcliff-2.6.33.1/drivers/gpio/Makefile
--- linux-2.6.33.1/drivers/gpio/Makefile	2010-03-16 01:09:39.000000000 +0900
+++ topcliff-2.6.33.1/drivers/gpio/Makefile	2010-04-01 10:58:31.000000000 +0900
@@ -22,3 +22,4 @@
 obj-$(CONFIG_GPIO_BT8XX)	+= bt8xxgpio.o
 obj-$(CONFIG_GPIO_VR41XX)	+= vr41xx_giu.o
 obj-$(CONFIG_GPIO_WM831X)	+= wm831x-gpio.o
+obj-$(CONFIG_PCH_GPIO)	+= pch_gpio/
diff -urN linux-2.6.33.1/drivers/gpio/pch_gpio/Makefile topcliff-2.6.33.1/drivers/gpio/pch_gpio/Makefile
--- linux-2.6.33.1/drivers/gpio/pch_gpio/Makefile	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/gpio/pch_gpio/Makefile	2010-04-01 10:58:31.000000000 +0900
@@ -0,0 +1,7 @@
+ifeq ($(CONFIG_GPIO_DEBUG_CORE),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-$(CONFIG_PCH_GPIO) += pch_gpio.o
+pch_gpio-objs := pch_gpio_hal.o pch_gpio_main.o pch_gpio_pci.o
+
diff -urN linux-2.6.33.1/drivers/gpio/pch_gpio/pch_common.h topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_common.h
--- linux-2.6.33.1/drivers/gpio/pch_gpio/pch_common.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_common.h	2010-04-01 10:58:31.000000000 +0900
@@ -0,0 +1,146 @@
+/*!
+ * @file ioh_common.h
+ * @brief Provides the macro definitions used by all files.
+ * @version 1.0.0.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_COMMON_H__
+#define __IOH_COMMON_H__
+
+/*! @ingroup	Global
+@def		    IOH_WRITE8
+@brief			Macro for writing 8 bit data to an io/mem address
+*/
+#define IOH_WRITE8(val, addr)   iowrite8((val), (void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_LOG
+@brief			Macro for writing 16 bit data to an io/mem address
+*/
+#define IOH_WRITE16(val, addr)  iowrite16((val), (void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_LOG
+@brief			Macro for writing 32 bit data to an io/mem address
+*/
+#define IOH_WRITE32(val, addr)  iowrite32((val), (void __iomem *)(addr))
+
+/*! @ingroup	Global
+@def		    IOH_READ8
+@brief			Macro for reading 8 bit data from an io/mem address
+*/
+#define IOH_READ8(addr)   ioread8((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_READ16
+@brief			Macro for reading 16 bit data from an io/mem address
+*/
+#define IOH_READ16(addr)  ioread16((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_READ32
+@brief			Macro for reading 32 bit data from an io/mem address
+*/
+#define IOH_READ32(addr)  ioread32((void __iomem *)(addr))
+/*! @ingroup	Global
+@def		    IOH_WRITE32_F
+@brief			Macro for writing 32 bit data to an io/mem address
+*/
+#define IOH_WRITE32_F(val, addr) do \
+	{ IOH_WRITE32((val), (addr)); (void)IOH_READ32((addr)); } while (0);
+
+/*! @ingroup	Global
+@def		    IOH_WRITE_BYTE
+@brief			Macro for writing 1 byte data to an io/mem address
+*/
+#define IOH_WRITE_BYTE IOH_WRITE8
+/*! @ingroup	Global
+@def		    IOH_WRITE_WORD
+@brief			Macro for writing 1 word data to an io/mem address
+*/
+#define IOH_WRITE_WORD IOH_WRITE16
+/*! @ingroup	Global
+@def		    IOH_WRITE_LONG
+@brief			Macro for writing long data to an io/mem address
+*/
+#define IOH_WRITE_LONG IOH_WRITE32
+
+/*! @ingroup	Global
+@def		    IOH_READ_BYTE
+@brief			Macro for reading 1 byte data from an io/mem address
+*/
+#define IOH_READ_BYTE  IOH_READ8
+/*! @ingroup	Global
+@def		    IOH_READ_WORD
+@brief			Macro for reading 1 word data from an io/mem address
+*/
+#define IOH_READ_WORD  IOH_READ16
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			Macro for reading long data from an io/mem address
+*/
+#define IOH_READ_LONG  IOH_READ32
+
+/* Bit Manipulation Macros */
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to set a specified bit(mask) at the
+			specified address
+*/
+#define IOH_SET_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) |\
+							 (bitmask)), (addr))
+
+/*! @ingroup	Global
+@def	    IOH_READ_LONG
+@brief		macro to clear a specified bit(mask) at the specified address
+*/
+#define IOH_CLR_ADDR_BIT(addr, bitmask) IOH_WRITE_LONG((IOH_READ_LONG(addr) &\
+							 ~(bitmask)), (addr))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to set a specified bitmask for a variable
+*/
+#define IOH_SET_BITMSK(var, bitmask) ((var) |= (bitmask))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to clear a specified bitmask for a variable
+*/
+#define IOH_CLR_BITMSK(var, bitmask) ((var) &= (~(bitmask)))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to set a specified bit for a variable
+*/
+#define IOH_SET_BIT(var, bit) ((var) |= (1<<(bit)))
+
+/*! @ingroup	Global
+@def		    IOH_READ_LONG
+@brief			macro to clear a specified bit for a variable
+*/
+#define IOH_CLR_BIT(var, bit) ((var) &= ~(1<<(bit)))
+
+#endif
diff -urN linux-2.6.33.1/drivers/gpio/pch_gpio/pch_debug.h topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_debug.h
--- linux-2.6.33.1/drivers/gpio/pch_gpio/pch_debug.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_debug.h	2010-04-01 10:58:31.000000000 +0900
@@ -0,0 +1,60 @@
+/*!
+ * @file ioh_debug.h
+ * @brief Provides the macro definitions used for debugging.
+ * @version 1.0.0.0
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 03/07/2009
+ * modified:
+ *	WIPRO 05/08/2009
+ *
+ */
+
+#ifndef __IOH_DEBUG_H__
+#define __IOH_DEBUG_H__
+
+#ifdef MODULE
+#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n",\
+						 THIS_MODULE->name, ##args)
+#else
+#define IOH_LOG(level, fmt, args...) printk(level "%s:" fmt "\n" ,\
+							 __FILE__, ##args)
+#endif
+
+
+#ifdef DEBUG
+	#define IOH_DEBUG(fmt, args...) IOH_LOG(KERN_DEBUG, fmt, ##args)
+#else
+	#define IOH_DEBUG(fmt, args...)
+#endif
+
+#ifdef IOH_TRACE_ENABLED
+	#define IOH_TRACE IOH_DEBUG
+#else
+	#define IOH_TRACE(fmt, args...)
+#endif
+
+#define IOH_TRACE_ENTER IOH_TRACE("Enter %s", __func__)
+#define IOH_TRACE_EXIT 	IOH_TRACE("Exit %s", __func__)
+
+
+#endif
diff -urN linux-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_hal.c topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_hal.c
--- linux-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_hal.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_hal.c	2010-04-01 10:58:31.000000000 +0900
@@ -0,0 +1,595 @@
+/*!
+ * @file ioh_gpio_hal.c
+ * @brief Provides all the implementation of the interfaces pertaining to the
+ *  HAL.
+ * @version 0.92
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 02/20/2009
+ * modified:
+ *	WIPRO 01/05/2010
+ *	Added the interfaces provided by the gpio module.
+ *
+ */
+
+/*includes*/
+#include <linux/io.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_gpio_main.h"
+#include "pch_gpio_hal.h"
+
+/* mask for interrupt mode configuration */
+#define GPIO_INT_MODE_MSK (0xF)
+
+/* mask for interrupt mode bit position */
+#define GPIO_INT_MODE_POS (0x4)
+
+/* interrupt mode valid value */
+#define GPIO_INT_MODE_VALID (0x4)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		BITS_32
+	@brief 		Corresponds to the 32 bit position.
+*/
+#define BITS_32 			(32)
+
+
+/*!	@ingroup	GPIO_Global
+	@var		ioh_gpio_cbr
+	@brief	The global variable for storing the callback function pointer.
+	@remarks	This variable is used to store the function pointer
+				to the callback function of the GPIO module.
+
+	@see
+		- ioh_gpio_cb_register
+*/
+void (*ioh_gpio_cbr) (u32);
+
+/*! @ingroup 	GPIO_HALLayer
+	struct 		ioh_gpio_reg_data
+	@brief		The register data.
+*/
+struct ioh_gpio_reg_data {
+	u32 ien_reg;	/**< To store contents of IEN register. 	*/
+	u32 imask_reg;	/**< To store contents of IMASK register.	*/
+	u32 po_reg;	/**< To store contents of PO register. 		*/
+	u32 pm_reg;	/**< To store contents of PM register. 		*/
+	u32 im0_reg;	/**< To store contents of IM0 register. 	*/
+	u32 im1_reg;	/**< To store contents of IM1 register. 	*/
+} ioh_gpio_reg;
+
+/*functions implementations*/
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn  		void ioh_gpio_cb_register(void(*ioh_gpio_ptr)(u32))
+@brief		Registers the callback function.
+@remarks  	This function registers the callback function used
+		by the gpio module. The main task performed by this
+			function is:
+			- If the function argument is non NULL, update the
+				same in the global callback pointer variable
+				@ref ioh_gpio_cbr.
+@param  	ioh_gpio_cb_register 	[@ref INOUT]
+				Contains the reference of the function pointer
+@retval 	None
+@see
+				- ioh_gpio_int_mode
+*/
+void ioh_gpio_cb_register(void (*ioh_gpio_ptr) (u32))
+{
+	if (ioh_gpio_ptr != NULL) {
+
+		init_waitqueue_head(&ioh_gpio_event);
+		IOH_DEBUG
+		    (" In ioh_gpio_cb_register: value of ioh_gpio_ptr = %p\n",
+		     ioh_gpio_ptr);
+		ioh_gpio_cbr = ioh_gpio_ptr;
+		IOH_DEBUG("ioh_gpio_cb_register Registered callback\n");
+		IOH_DEBUG
+		    ("In ioh_gpio_cb_register : value of ioh_gpio_cbr =%p\n",
+		     ioh_gpio_cbr);
+	}
+
+}
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn  		void ioh_gpio_int_mode(struct ioh_gpio_reqt * gpio_reqt)
+@remarks  Implements the functionality of disabling or enabling interrupts.
+		The main tasks performed by this function are:
+		- If the request is for disabling the interrupts, then the
+		corresponding bits in the IEN register are set to 0.
+		- If the request is for enabling the interrupts, then the
+		corresponding bits in the IEN register are set to 1.
+
+@param  	gpio_reqt 				[@ref INOUT]
+			Contains the reference of the ioh_gpio_reqt structure
+@retval	s32
+		- @ref IOH_GPIO_SUCCESS	--> If the operation is successful.
+		- -EINVAL				-->	Failure.
+@see
+		- ioh_gpio_dir_mode
+*/
+s32 ioh_gpio_int_mode(struct ioh_gpio_reqt *gpio_reqt)
+{
+	u32 ioh_pins;
+	u32 base_addr;
+	u32 i;
+	u32 ien_val;
+	u64 temp;
+	u64 mode_val;
+
+	/* initialize locals */
+	ioh_pins = gpio_reqt->pins;
+	base_addr = ioh_gpio_base_address;
+	ien_val = IOH_READ_LONG(base_addr + IOH_IEN);
+
+	/* Disable applicable bits in IEN register */
+	ien_val &= (~ioh_pins);
+	IOH_WRITE_LONG(ien_val, (base_addr + IOH_IEN));
+	IOH_DEBUG("ioh_gpio_int_mode wrote  %x to IOH_IEN\n", ien_val);
+
+	/* Reading the modes of all the 12 pins. */
+	mode_val = ((((u64) IOH_READ_LONG(base_addr + IOH_IM1)) << BITS_32) |
+		    (IOH_READ_LONG(base_addr + IOH_IM0)));
+
+	/* enable interrupts */
+	if (gpio_reqt->enable == 1) {
+		IOH_DEBUG("ioh_gpio_int_mode Enabling interrupts\n");
+
+		for (i = 0; i < GPIO_NUM_PINS; i++) {
+			/*GPIO_NUM_PINS = max num. pins for the GPIO port. */
+			if (ioh_pins & (1 << i)) {
+				/*If interrupt for the pin has to be enabled. */
+				/* int. mode setting for each pin is specified
+								 by 3 bits
+				   000     Generates an interrupt
+							 at the falling edge.
+				   001     Generates an interrupt
+							 at the rising edge.
+				   010     Generates an interrupt
+						 at the input of a L level.
+				   011     Generates an interrupt
+						 at the input of a H level.
+				   100     Generates an interrupt
+				 at both edges (rising edge/falling edge).
+				 */
+				/* Clear the existing interrupt mode
+						 setting for the current pin. */
+				mode_val &=
+				    ~(((u64) GPIO_INT_MODE_MSK) <<
+				      (i * GPIO_INT_MODE_POS));
+
+				/* Update the new setting. */
+				temp =
+				    (gpio_reqt->
+				     mode) & (((u64) GPIO_INT_MODE_MSK) << (i *
+							    GPIO_INT_MODE_POS));
+
+				mode_val |= temp;
+
+				if (((temp >> (i * GPIO_INT_MODE_POS)) >
+				     GPIO_INT_MODE_VALID)) {
+					IOH_LOG(KERN_ERR,
+						"ioh_gpio_int_mode Invalid\
+						 mode selection for "
+						"pin %d\n", i);
+					return -EINVAL;
+				}
+				IOH_DEBUG
+				    ("ioh_gpio_int_mode Interrupt enabled\
+					 for pin %d \n",
+				     i);
+			} else {
+				IOH_DEBUG
+				    ("ioh_gpio_int_mode Interrupt not enabled\
+					 for pin %d \n",
+				     i);
+			}
+		}
+		/* Set the mode register IM0 */
+		IOH_WRITE_LONG(((u32) (mode_val & BIT_MASK_32)),
+			       (base_addr + IOH_IM0));
+		IOH_DEBUG("ioh_gpio_int_mode wrote  %x to IOH_IM0\n",
+			  ((u32) (mode_val & BIT_MASK_32)));
+
+		/* Set the mode register IM1 */
+		IOH_WRITE_LONG(((u32) (mode_val >> BITS_32)),
+			       (base_addr + IOH_IM1));
+		IOH_DEBUG("ioh_gpio_int_mode wrote  %x to IOH_IM1\n",
+			  ((u32) (mode_val >> BITS_32)));
+
+		/* Clear the status */
+		IOH_WRITE_LONG(ioh_pins, (base_addr + IOH_ICLR));
+		IOH_DEBUG("ioh_gpio_int_mode wrote  %x to IOH_ICLR\n",
+			  ioh_pins);
+		IOH_DEBUG("ioh_gpio_int_mode value in to IOH_ISTATUS %x\n",
+			  IOH_READ_LONG(base_addr + IOH_ISTATUS));
+
+		/* Clear the mask register */
+		IOH_WRITE_LONG(ioh_pins, (base_addr + IOH_IMASKCLR));
+		IOH_DEBUG("ioh_gpio_int_mode wrote  %x to IOH_IMASKCLR\n",
+			  ioh_pins);
+
+		ien_val = (ien_val | ioh_pins);
+
+		/*Enable applicable bits in  IEN register */
+		IOH_WRITE_LONG(ien_val, (base_addr + IOH_IEN));
+		IOH_DEBUG("ioh_gpio_int_mode wrote  %x to IOH_IEN\n", ien_val);
+
+	}
+
+	/* disable interrupts */
+	else {
+		IOH_DEBUG("ioh_gpio_int_mode Disabling interrupts\n");
+		/* Clear the status */
+		IOH_WRITE_LONG(ioh_pins, (base_addr + IOH_ICLR));
+		IOH_DEBUG("ioh_gpio_int_mode wrote  %x to IOH_ICLR\n",
+			  ioh_pins);
+
+		/* Set the mask register */
+		IOH_WRITE_LONG(ioh_pins, (base_addr + IOH_IMASK));
+		IOH_DEBUG("ioh_gpio_int_mode wrote  %x to IOH_IMASK\n",
+			  ioh_pins);
+
+		/* IEN bits are already disabled initially */
+
+	}
+	IOH_DEBUG("ioh_gpio_int_mode returning=%d\n", IOH_GPIO_SUCCESS);
+	return IOH_GPIO_SUCCESS;
+}
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn  		void ioh_gpio_dir_mode(struct ioh_gpio_reqt * gpio_reqt)
+@remarks  	Implements the functionalities for setting GPIO pin
+						 directions[input/output].
+	The main tasks performed by this function are:
+	-	Reads the current value of PM register
+	-	If input mode is specified @ref GPIO_IN, performs logical
+		AND between the present PM register value and the 1's
+		complement of gpio_reqt->pins (@ref ioh_gpio_reqt) and
+		updates the value in the PM register.
+	-	Else performs logical OR between the present PM register value
+		and gpio_reqt->pins (@ref ioh_gpio_reqt) and updates the value
+		in the PM register.
+
+@param  	gpio_reqt [@ref INOUT] Contains the reference of
+						 the ioh_gpio_reqt structure
+@retval		None
+@see
+		- ioh_gpio_read
+*/
+void ioh_gpio_dir_mode(struct ioh_gpio_reqt *gpio_reqt)
+{
+	u32 ioh_pm_regval;
+	u32 ioh_pins;
+	u32 base_addr;
+
+	base_addr = ioh_gpio_base_address;
+	ioh_pm_regval = IOH_READ_LONG(base_addr + IOH_PM);
+	ioh_pins = gpio_reqt->pins;
+
+	/* input mode */
+	if (gpio_reqt->mode == GPIO_IN) {
+		IOH_DEBUG("ioh_gpio_dir_mode GPIO_IN\n");
+		(ioh_pm_regval &= (~ioh_pins));
+	} else {
+		ioh_pm_regval |= ioh_pins;
+		IOH_DEBUG("ioh_gpio_dir_mode GPIO_OUT\n");
+	}
+
+	IOH_WRITE_LONG(ioh_pm_regval, (base_addr + IOH_PM));
+	IOH_DEBUG("ioh_gpio_dir_mode wrote %x to IOH_PM\n", ioh_pm_regval);
+}
+
+/*! @ingroup 	GPIO_HALLayerAPI
+	@fn  		int ioh_gpio_read(struct ioh_gpio_reqt * gpio_reqt)
+	@remarks  	Implements the register read functionality of the
+								 gpio module.
+			The main tasks performed by this function are:
+			-	Reads the value from PI[Port Input] Register.
+			Masks the value with 0xff and updates the value in
+			 gpio_reqt->pins
+			(@ref ioh_gpio_reqt).
+
+	@param  	gpio_reqt 			[@ref INOUT]
+			Contains the reference of the ioh_gpio_reqt structure
+	@retval		s32
+				- @ref	IOH_GPIO_SUCCESS	-->
+						If the operation is successful.
+	@see
+			- IOCTL_GPIO_READ
+*/
+s32 ioh_gpio_read(struct ioh_gpio_reqt *gpio_reqt)
+{
+
+	gpio_reqt->pins =
+	    (ioh_gpio_bit_mask & IOH_READ_LONG(ioh_gpio_base_address + IOH_PI));
+	return IOH_GPIO_SUCCESS;
+
+}
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn  		int ioh_gpio_write(struct ioh_gpio_reqt * gpio_reqt)
+@remarks  	Implements the register write functionality of the gpio module.
+		The main tasks performed by this function are:
+-	Masks gpio_reqt->pins (@ref ioh_gpio_reqt) with 0xFF to
+	retrieve the valid 8 bits.
+-	Reads the current value of PO register
+-	If (gpio_reqt->mode == GPIO_LOW), performs logical AND
+	between the present PM register value and the 1.s complement
+	of gpio_reqt->pins and updates the value in the PO register.
+-	Else, (gpio_reqt->mode != GPIO_LOW; implies Output High), performs
+	logical OR between the present PO register value and gpio_reqt->pins
+	and updates the value in the PO register.
+
+	@param  	gpio_reqt 		[@ref INOUT]
+			Contains the reference of the ioh_gpio_reqt structure
+	@retval	s32
+			- @ref	IOH_GPIO_SUCCESS
+					--> If the operation is successful.
+	@see
+				- IOCTL_GPIO_WRITE
+*/
+s32 ioh_gpio_write(struct ioh_gpio_reqt *gpio_reqt)
+{
+	u32 reg_val;
+
+	reg_val = IOH_READ_LONG(ioh_gpio_base_address + IOH_PO);
+
+	if (gpio_reqt->mode == GPIO_LOW) {
+		reg_val &= ~(gpio_reqt->pins);
+		IOH_DEBUG("ioh_gpio_write GPIO_LOW\n");
+	} else {
+		reg_val |= gpio_reqt->pins;
+		IOH_DEBUG("ioh_gpio_write GPIO_HIGH\n");
+	}
+
+	IOH_WRITE_LONG(reg_val, ioh_gpio_base_address + IOH_PO);
+	IOH_DEBUG("ioh_gpio_write writing value=%x\n", reg_val);
+
+	IOH_DEBUG("ioh_gpio_write returning %d\n", IOH_GPIO_SUCCESS);
+	return IOH_GPIO_SUCCESS;
+}
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn 		irqreturn_t ioh_gpio_handler(int irq,void * pData)
+@remarks  Implements the interrupt handler functionality of the gpio module.
+The main tasks performed by this function are:
+-	Reads the IDISP register
+-	If IDISP register content is zero, then returns IRQ_NONE.
+-	Else clears the Interrupt status by writing to the ICLR register,
+	invokes the call back function specified by @ref ioh_gpio_cbr
+	with the value of IDISP as parameter and returns IRQ_HANDLED.
+
+@param  	irq 	[@ref INOUT] 	Contains the irq value
+@param  	pData 	[@ref INOUT] 	Contains the reference to the base
+								gpio address.
+@retval irqreturn_t
+	- IRQ_HANDLED			--> If GPIO hardware is responsible
+							for the interrupt.
+	- IRQ_NONE			--> Non-GPIO interrupt.
+*/
+irqreturn_t ioh_gpio_handler(int irq, void *pData)
+{
+	irqreturn_t ret = IRQ_NONE;
+	u32 base_addr = ioh_gpio_base_address;
+	u32 ioh_idisp_regval;
+
+	ioh_idisp_regval =
+	    (ioh_gpio_bit_mask & IOH_READ_LONG(base_addr + IOH_IDISP));
+	if (ioh_idisp_regval != 0) {
+		/*invoke the callback */
+		(*ioh_gpio_cbr) (ioh_idisp_regval);
+
+		IOH_DEBUG
+		    ("ioh_gpio_handler : ioh_gpio_cb invoked successfully %d\n",
+		     ret);
+		/*clear the interrupt */
+		IOH_LOG(KERN_ERR, "Value at idisp 8 = %x",
+			(IOH_READ_LONG(base_addr + IOH_IDISP)));
+		IOH_LOG(KERN_ERR, "Value at pin   8 = %x",
+			((IOH_READ_LONG(base_addr + IOH_PI) & 0x80)));
+
+		IOH_WRITE_LONG(ioh_idisp_regval, (base_addr + IOH_ICLR));
+
+		ret = IRQ_HANDLED;
+		IOH_DEBUG("ioh_gpio_handler returns IRQ_HANDLED\n");
+	} else {
+
+		IOH_DEBUG("ioh_gpio_handler returns IRQ_NONE\n");
+	}
+	return ret;
+}
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn  		void ioh_gpio_cb(u32 value)
+@brief		The interrupt handler callback function.
+@remarks  	The main tasks performed by this function are:
+		-	Updates the GPIO event flag with the parameter value.
+			This sets the appropriate event flag bits based on the
+			bits set in IDISP register.
+		-	Wakes up the blocking ioctl call @ref IOCTL_GPIO_NOTIFY.
+
+@param  	value		[@ref INOUT] 		Contains the value data
+@retval 	None
+@see
+			- ioh_gpio_cb_register
+*/
+void ioh_gpio_cb(u32 value)
+{
+	/* update the event flag */
+	ioh_gpio_event_flag = value;
+
+	IOH_DEBUG
+	    ("ioh_gpio_cb : event flag value = %x\tIDISP register value = %x\n",
+	     ioh_gpio_event_flag,
+	     (IOH_READ_LONG(ioh_gpio_base_address + IOH_IDISP)));
+	wake_up_interruptible(&ioh_gpio_event);
+}
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn  		void ioh_gpio_save_reg_conf(void)
+@remarks  	Save register configuration and disable interrupts.
+		The main tasks performed by this function are:
+		-	Read the registers PM, PO, IEN, IM0, IM1 and IMASK
+			and stores the values for further use.
+		-	Disables the interrupts by clearing IEN register.
+
+@param 		None
+@retval  	None
+@see
+		- ioh_gpio_suspend
+*/
+void ioh_gpio_save_reg_conf(void)
+{
+	u32 base_addr = ioh_gpio_base_address;
+	IOH_DEBUG("ioh_gpio_save_reg_conf ENTRY\n");
+	/* to store contents of IEN register */
+	ioh_gpio_reg.ien_reg = IOH_READ_LONG(base_addr + IOH_IEN);
+
+	/* to store contents of IMASK register */
+	ioh_gpio_reg.imask_reg = IOH_READ_LONG(base_addr + IOH_IMASK);
+
+	/* to store contents of PO register */
+	ioh_gpio_reg.po_reg = IOH_READ_LONG(base_addr + IOH_PO);
+
+	/* to store contents of PM register */
+	ioh_gpio_reg.pm_reg = IOH_READ_LONG(base_addr + IOH_PM);
+
+	/* to store contents of IM0 register */
+	ioh_gpio_reg.im0_reg = IOH_READ_LONG(base_addr + IOH_IM0);
+
+	/* to store contents of IM1 register */
+	ioh_gpio_reg.im1_reg = IOH_READ_LONG(base_addr + IOH_IM1);
+
+	IOH_DEBUG
+	    ("ioh_gpio_save_reg_conf : IOH_IEN=%x, IOH_IMASK=%x, IOH_PO=%x,"
+	     "IOH_PM=%x, IOH_IM0=%x, IOH_IM1=%x\n",
+	     IOH_READ_LONG(base_addr + IOH_IEN),
+	     IOH_READ_LONG(base_addr + IOH_IMASK),
+	     IOH_READ_LONG(base_addr + IOH_PO),
+	     IOH_READ_LONG(base_addr + IOH_PM),
+	     IOH_READ_LONG(base_addr + IOH_IM0),
+	     IOH_READ_LONG(base_addr + IOH_IM1));
+
+	IOH_DEBUG("ioh_gpio_save_reg_conf : ioh_gpio_reg.ien_reg=%x, "
+		  "ioh_gpio_reg.imask_reg=%x, ioh_gpio_reg.po_reg=%x,\
+			 ioh_gpio_reg.pm_reg=%x,"
+		  "ioh_gpio_reg.im0_reg=%x, ioh_gpio_reg.im1_reg=%x\n",
+		  ioh_gpio_reg.ien_reg, ioh_gpio_reg.imask_reg,
+		  ioh_gpio_reg.po_reg, ioh_gpio_reg.pm_reg,
+		  ioh_gpio_reg.im0_reg, ioh_gpio_reg.im1_reg);
+
+	/* Disable all gpio interrupts */
+	IOH_WRITE_LONG(0, (base_addr + IOH_IEN));
+	IOH_DEBUG("ioh_gpio_save_reg_conf disabled interrupts\n");
+}
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn  		void ioh_gpio_restore_reg_conf(void)
+@remarks 	This function restores the register configuration of the
+		GPIO device. The main task performed by this function
+		is:
+		-	Restores the previous register values into the registers
+			PM, PO, IEN, IM0, IM1 and IMASK.
+
+@param 		None
+@retval  	None
+@see
+		- ioh_gpio_resume
+*/
+void ioh_gpio_restore_reg_conf(void)
+{
+	u32 base_addr = ioh_gpio_base_address;
+	IOH_DEBUG("ioh_gpio_restore_reg_conf ENTRY\n");
+	/* to store contents of IEN register */
+	IOH_WRITE_LONG(ioh_gpio_reg.ien_reg, base_addr + IOH_IEN);
+
+	/* to store contents of IMASK register */
+	IOH_WRITE_LONG(ioh_gpio_reg.imask_reg, base_addr + IOH_IMASK);
+
+	/* to store contents of IMASK register */
+	IOH_WRITE_LONG(~ioh_gpio_reg.imask_reg, base_addr + IOH_IMASKCLR);
+
+	/* to store contents of PO register */
+	IOH_WRITE_LONG(ioh_gpio_reg.po_reg, base_addr + IOH_PO);
+
+	/* to store contents of PM register */
+	IOH_WRITE_LONG(ioh_gpio_reg.pm_reg, base_addr + IOH_PM);
+
+	/* to store contents of IM0 register */
+	IOH_WRITE_LONG(ioh_gpio_reg.im0_reg, base_addr + IOH_IM0);
+
+	/* to store contents of IM1 register */
+	IOH_WRITE_LONG(ioh_gpio_reg.im1_reg, base_addr + IOH_IM1);
+
+	IOH_DEBUG
+	    ("ioh_gpio_save_reg_conf : ioh_gpio_reg.ien_reg=%x,\
+		 ioh_gpio_reg.imask_reg=%x,"\
+	     "ioh_gpio_reg.po_reg=%x, ioh_gpio_reg.pm_reg=%x,\
+		 ioh_gpio_reg.im0_reg=%x,"\
+	     "ioh_gpio_reg.im1_reg=%x\n", ioh_gpio_reg.ien_reg,
+	     ioh_gpio_reg.imask_reg, ioh_gpio_reg.po_reg, ioh_gpio_reg.pm_reg,
+	     ioh_gpio_reg.im0_reg, ioh_gpio_reg.im1_reg);
+
+	IOH_DEBUG
+	    ("ioh_gpio_save_reg_conf : IOH_IEN=%x, IOH_IMASK=%x, IOH_PO=%x,\
+	 IOH_PM=%x, IOH_IM0=%x, IOH_IM1=%x\n",\
+	     IOH_READ_LONG(base_addr + IOH_IEN),
+	     IOH_READ_LONG(base_addr + IOH_IMASK),
+	     IOH_READ_LONG(base_addr + IOH_PO),
+	     IOH_READ_LONG(base_addr + IOH_PM),
+	     IOH_READ_LONG(base_addr + IOH_IM0),
+	     IOH_READ_LONG(base_addr + IOH_IM1));
+
+	IOH_DEBUG("ioh_gpio_restore_reg_conf enabled interrupts\n");
+}
+
+/*! @ingroup 	GPIO_HALLayerAPI
+	@fn  		u32 ioh_gpio_readreg(int offset)
+	@brief		Reads the register.
+	@remarks  	This function reads the register located at
+				the passed offset and returns the read value.
+	@param 		Offset		[@reg IN]	The offset to be read.
+	@retval  u32	--> Register value
+
+*/
+u32 ioh_gpio_readreg(int offset)
+{
+	u32 reg_val;
+	reg_val = (IOH_READ_LONG(ioh_gpio_base_address + offset));
+	IOH_DEBUG("ioh_gpio_readreg read reg=%x,value=%x\n",
+		  (ioh_gpio_base_address + offset), reg_val);
+	return reg_val;
+}
+
+int ioh_gpio_writereg(int offset, u32 val)
+{
+	IOH_WRITE_LONG(val, ioh_gpio_base_address + offset);
+	IOH_DEBUG("%s read reg=%x,value=%x\n", __func__,
+		  (ioh_gpio_base_address + offset), val);
+	return 0;
+}
diff -urN linux-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_hal.h topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_hal.h
--- linux-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_hal.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_hal.h	2010-04-01 10:58:31.000000000 +0900
@@ -0,0 +1,170 @@
+/*!
+ * @file ioh_gpio_hal.h
+ * @brief Provides all the interfaces pertaining to the HAL.
+ * @version 0.92
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 02/20/2009
+ * modified:
+ *	WIPRO 01/05/2010
+ *	Added the interfaces provided by the HAL.
+ *
+ */
+
+#ifndef __IOH_GPIO_HAL_H__
+#define __IOH_GPIO_HAL_H__
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_IEN
+	@brief 		Offset for IEN register.
+*/
+#define IOH_IEN 			(0x00)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_ISTATUS
+	@brief 		Offset for ISTATUS register.
+*/
+#define IOH_ISTATUS 	(0x04)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_IDISP
+	@brief 		Offset for IDISP register.
+*/
+#define IOH_IDISP 		(0x08)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_ICLR
+	@brief 		Offset for ICLR register.
+*/
+#define IOH_ICLR 		(0x0C)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_IMASK
+	@brief 		Offset for IMASK register.
+*/
+#define IOH_IMASK 		(0x10)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_IMASKCLR
+	@brief 		Offset for IMASKCLR register.
+*/
+#define IOH_IMASKCLR 	(0x14)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_PO
+	@brief 		Offset for IMASKCLR register.
+*/
+#define IOH_PO 			(0x18)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_PI
+	@brief 		Offset for PI register.
+*/
+#define IOH_PI 			(0x1C)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_PM
+	@brief 		Offset for PM register.
+*/
+#define IOH_PM 			(0x20)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_IM0
+	@brief 		Offset for IM0 register.
+*/
+#define IOH_IM0 			(0x24)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_IM1
+	@brief 		Offset for IM1 register.
+*/
+#define IOH_IM1 			(0x28)
+
+/* exported function prototypes */
+/*! @ingroup 	GPIO_HALLayerAPI
+	@fn 		void ioh_gpio_cb(int)
+	@brief  	Interrupt handler callback function
+*/
+void ioh_gpio_cb(u32);
+
+/*! @ingroup 	GPIO_HALLayerAPI
+	@fn 		void ioh_gpio_cb_register(void(*ioh_gpio_cbr)(u32))
+	@brief 		Interrupt handler callback register function
+*/
+void ioh_gpio_cb_register(void (*ioh_gpio_cbr) (u32));
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn 		s32 ioh_gpio_int_mode(struct ioh_gpio_reqt * gpio_reqt)
+@brief 	This function sets the interrupt mode for each of the GPIO input pins
+*/
+s32 ioh_gpio_int_mode(struct ioh_gpio_reqt *gpio_reqt);
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn 	void ioh_gpio_dir_mode(struct ioh_gpio_reqt * gpio_reqt)
+@brief  Provides the functionality of setting gpio pin directions[input/output]
+*/
+void ioh_gpio_dir_mode(struct ioh_gpio_reqt *gpio_reqt);
+
+/*! @ingroup 	GPIO_HALLayerAPI
+	@fn 		s32 ioh_gpio_read(struct ioh_gpio_reqt * gpio_reqt)
+	@brief  	Provides the functionality of reading GPIO pin status
+*/
+s32 ioh_gpio_read(struct ioh_gpio_reqt *gpio_reqt);
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn 		s32 ioh_gpio_write(struct ioh_gpio_reqt * gpio_reqt)
+@brief  	Provides the functionality of writing data to the GPIO port
+*/
+s32 ioh_gpio_write(struct ioh_gpio_reqt *gpio_reqt);
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn 		irqreturn_t ioh_gpio_handler(int irq,void * pData)
+@brief  	Provides the functionality of handling interrupts from GPIO h/w
+*/
+irqreturn_t ioh_gpio_handler(int irq, void *pData);
+
+/*! @ingroup 	GPIO_HALLayerAPI
+@fn 		void ioh_gpio_save_reg_conf(void)
+@brief  	Saves register configuration and also disables GPIO interrupts
+*/
+void ioh_gpio_save_reg_conf(void);
+
+/*! @ingroup 	GPIO_HALLayerAPI
+	@fn 		void ioh_gpio_restore_reg_conf(void)
+	@brief  	Restores register configuration
+*/
+void ioh_gpio_restore_reg_conf(void);
+
+/*! @ingroup 	GPIO_HALLayerAPI
+	@fn 		u32 ioh_gpio_readreg(int offset)
+	@brief  	Function to read the value of a GPIO register
+*/
+u32 ioh_gpio_readreg(int offset);
+int ioh_gpio_writereg(int offset, u32 val);
+
+/* global variables */
+extern u32 ioh_gpio_base_address;
+extern u32 ioh_gpio_event_flag;
+extern wait_queue_head_t ioh_gpio_event;
+extern u32 ioh_gpio_bit_mask;
+
+#endif
diff -urN linux-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_main.c topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_main.c
--- linux-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_main.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_main.c	2010-04-01 11:41:01.000000000 +0900
@@ -0,0 +1,420 @@
+/*!
+ * @file ioh_gpio_main.c
+ * @brief Provides all the implementation of the interfaces pertaining to the
+ * GPIO module.
+ * @version 0.92
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 02/20/2009
+ * modified:
+ *	WIPRO 01/05/2010
+ *	Added the interfaces provided by the GPIO module.
+ *
+ */
+
+/* includes */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/uaccess.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_gpio_main.h"
+#include "pch_gpio_hal.h"
+
+#define MODULE_NAME "ioh_gpio"
+
+DEFINE_SPINLOCK(ioh_gpio_lock); /* for spin lock */
+u32 ioh_gpio_event_flag;				/* flag for event */
+s32 ioh_gpio_opencount;		/* check whether opened or not */
+
+/*spinlock_t ioh_gpio_lock = SPIN_LOCK_UNLOCKED;	 for spin lock */
+wait_queue_head_t ioh_gpio_event;	/* wait queue head */
+
+/*! @ingroup 	GPIO_InterfaceLayerFacilitators
+	@struct		ioh_gpio_fops
+	@brief  	Instance of the Kernel structure file_operations.
+*/
+const struct file_operations ioh_gpio_fops = {
+	.owner = THIS_MODULE,
+	.open = ioh_gpio_open,
+	.release = ioh_gpio_release,
+	.ioctl = ioh_gpio_ioctl,
+};
+
+/*function implementations*/
+
+/*! @ingroup 	GPIO_InterfaceLayerAPI
+@fn  		int ioh_gpio_open( struct inode *inode,struct file *file)
+@remarks  	The main tasks performed by this function are:
+-	Ensures that the device is not opened before by checking the open count.
+	If it is already opened, then returns EBUSY status code.
+-	Registers the interrupt handler by invoking request_irq.
+	If this fails then returns its error code.
+	Otherwise returns @ref IOH_GPIO_SUCCESS
+
+@param  inode 	[@ref INOUT] 	Contains the reference of the inode structure
+@param  file 	[@ref INOUT] 	Contains the reference of the file structure
+@retval	int
+	- @ref IOH_GPIO_SUCCESS		--> If operation is successful.
+	- -EBUSY			--> If already opened/ request_irq
+							error status code.
+	- -EINVAL			--> request_irq error status code.
+	- -ENOMEM			--> request_irq error status code.
+	- -ENOSYS			-->	request_irq error status code.
+
+@see
+	- ioh_gpio_fops
+*/
+int ioh_gpio_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	spin_lock(&ioh_gpio_lock);
+	IOH_DEBUG("ioh_gpio_open : open count value = %d", ioh_gpio_opencount);
+	if (ioh_gpio_opencount) {
+		IOH_LOG(KERN_ERR, "ioh_gpio_open :  device already opened\n");
+		ret = -EBUSY;
+	} else {
+
+		ret =
+		    (request_irq
+		     (ioh_gpio_irq, &ioh_gpio_handler, IRQF_SHARED, MODULE_NAME,
+		      (void *)ioh_gpio_base_address));
+		if (ret) {
+			IOH_LOG(KERN_ERR,
+				"ioh_gpio_open : request_irq failed\n");
+		} else {
+			ioh_gpio_opencount++;
+			IOH_DEBUG
+			    ("ioh_gpio_open : request_irq invoked\
+							 successfully\n");
+			ret = IOH_GPIO_SUCCESS;
+		}
+	}
+	spin_unlock(&ioh_gpio_lock);
+
+	IOH_DEBUG("ioh_gpio_open returns=%d\n", ret);
+	return ret;
+}
+
+/*! @ingroup 	GPIO_InterfaceLayerAPI
+@fn  		int ioh_gpio_release(struct inode *inode,struct file *file)
+@remarks  	The main tasks performed by this function are:
+-Ensures that device is opened successfully by checking the open count value.
+	If it is not opened, then returns with IOH_GPIO_SUCCESS status code.
+-Disables interrupts for all pins by using @ref ioh_gpio_int_mode
+	API.
+-Un-registers interrupt handler and returns @ref IOH_GPIO_SUCCESS.
+
+@param  inode 	[@ref INOUT] 	Contains the reference of the inode structure
+@param  file 	[@ref INOUT] 	Contains the reference of the file structure
+@retval int
+			- @ref IOH_GPIO_SUCCESS		-->
+						 If the operation is successful.
+@see
+		- ioh_gpio_fops
+*/
+int ioh_gpio_release(struct inode *inode, struct file *file)
+{
+	struct ioh_gpio_reqt req;
+	spin_lock(&ioh_gpio_lock);
+
+	if (ioh_gpio_opencount > 0) {
+		memset(&req, 0, sizeof(req));
+		req.pins = IOH_GPIO_ALL_PINS;
+
+		/* disable interrupts for all gpio pins */
+		(void)ioh_gpio_int_mode(&req);
+
+		free_irq(ioh_gpio_irq, (void *)ioh_gpio_base_address);
+		IOH_DEBUG("ioh_gpio_release : free_irq invoked successfully");
+
+		ioh_gpio_opencount--;
+	}
+	spin_unlock(&ioh_gpio_lock);
+
+	IOH_DEBUG("ioh_gpio_release : ioh_gpio_opencount =%d\n",
+		  ioh_gpio_opencount);
+
+	IOH_DEBUG("ioh_gpio_release returning=%d\n", IOH_GPIO_SUCCESS);
+	return IOH_GPIO_SUCCESS;
+}
+
+/*! @ingroup 	GPIO_InterfaceLayerAPI
+@fn  		int ioh_gpio_ioctl(struct inode * inode,struct file * file,
+					unsigned int cmd,unsigned long arg)
+@remarks  	The main tasks performed by this function are:
+	-	Copies the arg from user space to kernel space.
+		If this fails, returns EFAULT status code.
+	-	Checks the cmd specified. If not a valid command,
+		returns EINVAL status code.
+	-	Verifies the validity of the command argument based on
+		the operation requested. If invalid, returns EINVAL.
+	-	Performs the requested action based on the ioctl command,
+		by calling the appropriate HAL API functions.
+	-	Returns @ref IOH_GPIO_SUCCESS if the command is completed
+		successfully.
+
+@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 int
+- @ref IOH_GPIO_SUCCES		--> If the operation is successful.
+- -EFAULT			--> wait_event_interruptible API
+					is interrupted by a signal.
+- -ERESTARTSYS 			-->	wait_event_interruptible API
+						is interrupted by a signal.
+- -EINVAL					--> Invalid address/parameter.
+
+@see
+		- ioh_gpio_fops
+*/
+int ioh_gpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		   unsigned long arg)
+{
+
+	struct ioh_gpio_reqt gpio_reqt;
+	s32 ret_value;
+
+	IOH_DEBUG(KERN_INFO"%s:cmd = 0x%x\n", __func__, cmd);
+	IOH_DEBUG(KERN_INFO"%s: IOCTL_GPIO_INT_ENABLE= 0x%x\n", __func__,
+	       IOCTL_GPIO_INT_ENABLE);
+	IOH_DEBUG(KERN_INFO"%s: IOCTL_GPIO_INT_DISABLE= 0x%x\n", __func__,
+	       IOCTL_GPIO_INT_DISABLE);
+	IOH_DEBUG(KERN_INFO"%s: IOCTL_GPIO_DIRECTION= 0x%x\n", __func__,
+	       IOCTL_GPIO_DIRECTION);
+	IOH_DEBUG(KERN_INFO"%s: IOCTL_GPIO_WRITE= 0x%x\n", __func__,
+							 IOCTL_GPIO_WRITE);
+	IOH_DEBUG(KERN_INFO"%s: IOCTL_GPIO_READ= 0x%x\n", __func__,
+							 IOCTL_GPIO_READ);
+	IOH_DEBUG(KERN_INFO"%s: IOCTL_GPIO_NOTIFY= 0x%x\n", __func__,
+	       IOCTL_GPIO_NOTIFY);
+
+	do {
+		if (ioh_gpio_suspended == true) {
+			IOH_LOG(KERN_ERR,
+				"ioh_gpio_ioctl : suspend initiated returning\
+				 =%d\n",
+				IOH_GPIO_FAIL);
+			ret_value = IOH_GPIO_FAIL;
+			break;
+		}
+
+		ret_value =
+		    copy_from_user(&gpio_reqt, (void *)arg,
+				   sizeof(struct ioh_gpio_reqt));
+		if (ret_value) {
+			IOH_LOG(KERN_ERR,
+				"ioh_gpio_ioctl : copy_from_user fail returning\
+				 =%d\n",
+				-EFAULT);
+			ret_value = -EFAULT;
+			break;
+		}
+		IOH_DEBUG("ioh_gpio_ioctl  : copy_from_user returns =%d\n",
+			  ret_value);
+
+		if (((gpio_reqt.enable) > 1)
+		    || ((gpio_reqt.pins) > GPIO_MAX_PINS_MASK)
+		    || ((gpio_reqt.port) > GPIO_NUM_PORT_MAX)) {
+			IOH_LOG(KERN_ERR,
+				"ioh_gpio_ioctl : Invalid parameter\
+				 returning=%d\n",
+				-EINVAL);
+			ret_value = -EINVAL;
+			break;
+		}
+		switch (cmd) {
+		case IOCTL_GPIO_INT_ENABLE:
+			{
+
+				if (gpio_reqt.enable == 0) {
+					ret_value = -EINVAL;
+					IOH_DEBUG
+					    ("ioh_gpio_ioctl : Invalid\
+						 parameter in enable\n");
+				} else {
+					ret_value =
+					    ioh_gpio_int_mode(&gpio_reqt);
+					IOH_DEBUG
+					    ("ioh_gpio_ioctl  : Invoked\
+					 ioh_gpio_int_mode successfully\n");
+				}
+				break;
+			}
+
+		case IOCTL_GPIO_INT_DISABLE:
+			{
+				if (gpio_reqt.enable != 0) {
+					ret_value = -EINVAL;
+					IOH_DEBUG
+					    ("ioh_gpio_ioctl : Invalid\
+						 parameter in enable\n");
+				} else {
+					ret_value =
+					    ioh_gpio_int_mode(&gpio_reqt);
+					IOH_DEBUG
+					    ("ioh_gpio_ioctl  : Invoked\
+					 ioh_gpio_int_mode successfully\n");
+				}
+				break;
+			}
+
+		case IOCTL_GPIO_DIRECTION:
+			{
+				if ((gpio_reqt.mode > 1)) {
+
+					IOH_DEBUG
+					    ("ioh_gpio_ioctl : Invalid\
+								 direction\n");
+					ret_value = -EINVAL;
+				} else {
+					ioh_gpio_dir_mode(&gpio_reqt);
+					IOH_DEBUG
+					    ("ioh_gpio_ioctl : Invoked\
+					 ioh_gpio_dir_mode successfully\n");
+					ret_value = IOH_GPIO_SUCCESS;
+				}
+				break;
+			}
+
+		case IOCTL_GPIO_WRITE:
+			{
+				ret_value = ioh_gpio_write(&gpio_reqt);
+				IOH_DEBUG
+				    ("ioh_gpio_ioctl : Invoked\
+					 ioh_gpio_write_mode successfully\n");
+				break;
+			}
+
+		case IOCTL_GPIO_READ:
+			{
+				(void)ioh_gpio_read(&gpio_reqt);
+				IOH_DEBUG
+				    ("ioh_gpio_ioctl : Invoked\
+					 ioh_gpio_read_mode successfully\n");
+				ret_value =
+				    copy_to_user((void *)arg, &gpio_reqt,
+						 sizeof(struct ioh_gpio_reqt));
+
+				if (ret_value) {
+					IOH_LOG(KERN_ERR,
+						"ioh_gpio_ioctl copy_to_user\
+						 failed returning=%d\n",
+						-EFAULT);
+					ret_value = -EFAULT;
+				} else {
+					IOH_DEBUG
+					    ("ioh_gpio_ioctl copy_to_user\
+						 returns=%d\n",
+					     ret_value);
+					ret_value = IOH_GPIO_SUCCESS;
+				}
+				break;
+			}
+
+		case IOCTL_GPIO_NOTIFY:
+			{
+				ioh_gpio_event_flag = 0;
+				if ((((ioh_gpio_readreg(IOH_IEN)) &
+				      (gpio_reqt.pins)) != (gpio_reqt.pins))
+				    ||
+				    (((ioh_gpio_readreg(IOH_PM) &
+				       (gpio_reqt.pins)) != false))) {
+					/* if interrupts are not enabled on the
+					 pins for which notify is requested */
+					/* or the pins are not in input mode */
+					IOH_DEBUG
+					    ("ioh_gpio_ioctl GPIO pins not in\
+						 input mode or interrupts\
+								 not enabled!");
+					ret_value = -EINVAL;
+				} else {
+					ret_value =
+					    wait_event_interruptible
+					    (ioh_gpio_event,
+					     (ioh_gpio_event_flag & gpio_reqt.
+					      pins) != 0);
+					if (ret_value) {
+						IOH_LOG(KERN_ERR,
+							"ioh_gpio_ioctl wait_ev\
+							ent_interruptible\
+							 failed returning=%d\n",
+							-ERESTARTSYS);
+						ret_value = -ERESTARTSYS;
+					} else {
+						IOH_DEBUG
+						    ("ioh_gpio_ioctl wait_event\
+						_interruptible returns=%d\n",
+						     ret_value);
+						(void)ioh_gpio_read(&gpio_reqt);
+						ret_value =
+						    copy_to_user((void *)arg,
+								 &gpio_reqt,
+								 sizeof(struct
+								ioh_gpio_reqt));
+						if (ret_value) {
+							IOH_LOG(KERN_ERR,
+								"ioh_gpio_ioctl\
+								 copy_to_user\
+								 failed returni\
+								ng=%d\n",
+								-EFAULT);
+							ret_value = -EFAULT;
+						} else {
+							IOH_DEBUG
+							    ("ioh_gpio_ioctl\
+							 copy_to_user\
+							 returns=%d\n",
+							     ret_value);
+							ret_value =
+							    IOH_GPIO_SUCCESS;
+						}
+					}
+				}
+				break;
+			}
+
+		default:
+			{
+				IOH_LOG(KERN_ERR,
+					"ioh_gpio_ioctl invalid command\
+					 returning=%d\n",
+					-EINVAL);
+				ret_value = -EINVAL;
+				break;
+			}
+		}
+		break;
+
+	} while (0);
+	IOH_LOG(KERN_ERR, "ioh_gpio_ioctl returns=%d\n", ret_value);
+	return ret_value;
+}
diff -urN linux-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_main.h topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_main.h
--- linux-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_main.h	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_main.h	2010-04-01 10:58:31.000000000 +0900
@@ -0,0 +1,686 @@
+#ifndef __IOH_GPIO_MAIN_H__
+#define __IOH_GPIO_MAIN_H__
+/*!
+ * @file ioh_gpio_main.h
+ * @brief Provides all the interfaces pertaining to the GPIO module.
+ * @version 0.92
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+*/
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 02/20/2009
+ * modified:
+ *	WIPRO 01/05/2010
+ *	Added the interfaces provided by the gpio module.
+ *
+*/
+
+/*! @defgroup GPIO*/
+/*! @defgroup GPIO_Global
+	@ingroup GPIO*/
+
+/* @defgroup GlobalGeneral
+	@ingroup GPIO_Global*/
+/* @defgroup GlobalResultCodes
+	@ingroup GPIO_Global*/
+
+/*! @defgroup GPIO_InterfaceLayer
+	@ingroup GPIO*/
+/*! @defgroup GPIO_InterfaceLayerAPI
+	@ingroup GPIO_InterfaceLayer
+*/
+
+/* @defgroup InterfaceLayerNotifyRoutines
+	@ingroup GPIO_InterfaceLayer
+*/
+
+/*! @defgroup GPIO_PCILayer
+	@ingroup GPIO*/
+/*! @defgroup GPIO_PCILayerAPI
+	@ingroup GPIO_PCILayer
+*/
+/*! @defgroup GPIO_PCILayerFacilitators
+	@ingroup GPIO_PCILayer
+*/
+/*! @defgroup GPIO_HALLayer
+	@ingroup GPIO*/
+/*! @defgroup GPIO_HALLayerAPI
+	@ingroup GPIO_HALLayer
+*/
+
+/* @defgroup HALLayerFacilitators
+	@ingroup GPIO_HALLayer
+*/
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		GPIO_IOCTL_MAGIC
+	@brief 		The ioctl magic number.
+*/
+#define GPIO_IOCTL_MAGIC 		(0xf7)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOCTL_GPIO_INT_ENABLE
+	@brief 		IOCTL for GPIO interrupt enable.
+*/
+#define IOCTL_GPIO_INT_ENABLE (_IOW(GPIO_IOCTL_MAGIC, 1, struct ioh_gpio_reqt))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOCTL_GPIO_INT_DISABLE
+	@brief 		IOCTL for GPIO interrupt disable.
+*/
+#define IOCTL_GPIO_INT_DISABLE (_IOW(GPIO_IOCTL_MAGIC, 2, struct ioh_gpio_reqt))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOCTL_GPIO_DIRECTION
+	@brief 		IOCTL for GPIO direction setting.
+*/
+#define IOCTL_GPIO_DIRECTION (_IOW(GPIO_IOCTL_MAGIC, 3, struct ioh_gpio_reqt))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOCTL_GPIO_WRITE
+	@brief 		IOCTL for GPIO write.
+*/
+#define IOCTL_GPIO_WRITE (_IOW(GPIO_IOCTL_MAGIC, 4, struct ioh_gpio_reqt))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOCTL_GPIO_READ
+	@brief 		IOCTL for GPIO read.
+*/
+#define IOCTL_GPIO_READ (_IOR(GPIO_IOCTL_MAGIC, 5, struct ioh_gpio_reqt))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOCTL_GPIO_NOTIFY
+	@brief 		IOCTL for GPIO pin status change notification.
+*/
+#define IOCTL_GPIO_NOTIFY (_IOR(GPIO_IOCTL_MAGIC, 6, struct ioh_gpio_reqt))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN0
+	@brief 		GPIO PIN 0
+*/
+#define IOH_GPIO_PIN0 	(0x1)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN1
+	@brief 		GPIO PIN 1
+*/
+#define IOH_GPIO_PIN1	(0x2)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN2
+	@brief 		GPIO PIN 2
+*/
+#define IOH_GPIO_PIN2	(0x4)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN3
+	@brief 		GPIO PIN 3
+*/
+#define IOH_GPIO_PIN3 	(0x8)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN4
+	@brief 		GPIO PIN 4
+*/
+#define IOH_GPIO_PIN4 	(0x10)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN5
+	@brief 		GPIO PIN 5
+*/
+#define IOH_GPIO_PIN5	(0x20)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN6
+	@brief 		GPIO PIN 6
+*/
+#define IOH_GPIO_PIN6 	(0x40)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN7
+	@brief 		GPIO PIN 7
+*/
+#define IOH_GPIO_PIN7 	(0x80)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN8
+	@brief 		GPIO PIN 8
+*/
+#define IOH_GPIO_PIN8 		(0x100)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN9
+	@brief 		GPIO PIN 9
+*/
+#define IOH_GPIO_PIN9 		(0x200)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN10
+	@brief 		GPIO PIN 10
+*/
+#define IOH_GPIO_PIN10 		(0x400)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_PIN11
+	@brief 		GPIO PIN 11
+*/
+#define IOH_GPIO_PIN11 		(0x800)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_ALL_PINS
+	@brief 		Mask for GPIO pins 0 to 11
+*/
+#define IOH_GPIO_ALL_PINS 	(IOH_GPIO_PIN0 | IOH_GPIO_PIN1 | IOH_GPIO_PIN2\
+| IOH_GPIO_PIN3 | IOH_GPIO_PIN4 | IOH_GPIO_PIN5 | IOH_GPIO_PIN6 | IOH_GPIO_PIN7\
+| IOH_GPIO_PIN8 | IOH_GPIO_PIN9 | IOH_GPIO_PIN10 | IOH_GPIO_PIN11)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN0
+	@brief		Falling Edge interrupt on Pin0
+*/
+#define INT_FL_EDG_PIN0 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN1
+	@brief		Falling Edge interrupt on Pin1
+*/
+#define INT_FL_EDG_PIN1 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN2
+	@brief		Falling Edge interrupt on Pin2
+*/
+#define INT_FL_EDG_PIN2 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN3
+	@brief		Falling Edge interrupt on Pin3
+*/
+#define INT_FL_EDG_PIN3 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN4
+	@brief		Falling Edge interrupt on Pin4
+*/
+#define INT_FL_EDG_PIN4 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN5
+	@brief		Falling Edge interrupt on Pin5
+*/
+#define INT_FL_EDG_PIN5 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN6
+	@brief		Falling Edge interrupt on Pin6
+*/
+#define INT_FL_EDG_PIN6 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN7
+	@brief		Falling Edge interrupt on Pin7
+*/
+#define INT_FL_EDG_PIN7 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN8
+	@brief		Falling Edge interrupt on Pin8
+*/
+#define INT_FL_EDG_PIN8 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN9
+	@brief		Falling Edge interrupt on Pin9
+*/
+#define INT_FL_EDG_PIN9 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN10
+	@brief		Falling Edge interrupt on Pin10
+*/
+#define INT_FL_EDG_PIN10 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_EDG_PIN11
+	@brief		Falling Edge interrupt on Pin11
+*/
+#define INT_FL_EDG_PIN11 (0x0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN0
+	@brief		Rising Edge interrupt on Pin0
+*/
+#define INT_RS_EDG_PIN0 (0x1)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN1
+	@brief		Rising Edge interrupt on Pin1
+*/
+#define INT_RS_EDG_PIN1 (0x10)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN2
+	@brief		Rising Edge interrupt on Pin2
+*/
+#define INT_RS_EDG_PIN2 (0x100)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN3
+	@brief		Rising Edge interrupt on Pin3
+*/
+#define INT_RS_EDG_PIN3 (0x1000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN4
+	@brief		Rising Edge interrupt on Pin4
+*/
+#define INT_RS_EDG_PIN4 (0x10000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN5
+	@brief		Rising Edge interrupt on Pin5
+*/
+#define INT_RS_EDG_PIN5 (0x100000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN6
+	@brief		Rising Edge interrupt on Pin6
+*/
+#define INT_RS_EDG_PIN6 (0x1000000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN7
+	@brief		Rising Edge interrupt on Pin7
+*/
+#define INT_RS_EDG_PIN7 (0x10000000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN8
+	@brief		Rising Edge interrupt on Pin8
+*/
+#define INT_RS_EDG_PIN8 ((0x100000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN9
+	@brief		Rising Edge interrupt on Pin9
+*/
+#define INT_RS_EDG_PIN9 ((0x1000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN10
+	@brief		Rising Edge interrupt on Pin10
+*/
+#define INT_RS_EDG_PIN10 ((0x10000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_RS_EDG_PIN11
+	@brief		Rising Edge interrupt on Pin11
+*/
+#define INT_RS_EDG_PIN11 ((0x100000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN0
+	@brief		Low Level Interrupt on Pin0
+*/
+#define INT_LVL_LO_PIN0 (0x2)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN1
+	@brief		Low Level Interrupt on Pin1
+*/
+#define INT_LVL_LO_PIN1 (0x20)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN2
+	@brief		Low Level Interrupt on Pin2
+*/
+#define INT_LVL_LO_PIN2 (0x200)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN3
+	@brief		Low Level Interrupt on Pin3
+*/
+#define INT_LVL_LO_PIN3 (0x2000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN4
+	@brief		Low Level Interrupt on Pin4
+*/
+#define INT_LVL_LO_PIN4 (0x20000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN5
+	@brief		Low Level Interrupt on Pin5
+*/
+#define INT_LVL_LO_PIN5 (0x200000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN6
+	@brief		Low Level Interrupt on Pin6
+*/
+#define INT_LVL_LO_PIN6 (0x2000000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN7
+	@brief		Low Level Interrupt on Pin7
+*/
+#define INT_LVL_LO_PIN7 (0x20000000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN8
+	@brief		Low Level Interrupt on Pin8
+*/
+#define INT_LVL_LO_PIN8 ((0x200000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN9
+	@brief		Low Level Interrupt on Pin9
+*/
+#define INT_LVL_LO_PIN9 ((0x2000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN10
+	@brief		Low Level Interrupt on Pin10
+*/
+#define INT_LVL_LO_PIN10 ((0x20000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_LO_PIN11
+	@brief		Low Level Interrupt on Pin11
+*/
+#define INT_LVL_LO_PIN11 ((0x200000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN0
+	@brief		High Level Interrupt on Pin0
+*/
+#define INT_LVL_HI_PIN0 (0x3)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN1
+	@brief		High Level Interrupt on Pin1
+*/
+#define INT_LVL_HI_PIN1 (0x30)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN2
+	@brief		High Level Interrupt on Pin2
+*/
+#define INT_LVL_HI_PIN2 (0x300)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN3
+	@brief		High Level Interrupt on Pin3
+*/
+#define INT_LVL_HI_PIN3 (0x3000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN4
+	@brief		High Level Interrupt on Pin4
+*/
+#define INT_LVL_HI_PIN4 (0x30000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN5
+	@brief		High Level Interrupt on Pin5
+*/
+#define INT_LVL_HI_PIN5 (0x300000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN6
+	@brief		High Level Interrupt on Pin6
+*/
+#define INT_LVL_HI_PIN6 (0x3000000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN7
+	@brief		High Level Interrupt on Pin7
+*/
+#define INT_LVL_HI_PIN7 (0x30000000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN8
+	@brief		High Level Interrupt on Pin8
+*/
+#define INT_LVL_HI_PIN8 ((0x300000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN9
+	@brief		High Level Interrupt on Pin9
+*/
+#define INT_LVL_HI_PIN9 ((0x3000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN10
+	@brief		High Level Interrupt on Pin10
+*/
+#define INT_LVL_HI_PIN10 ((0x30000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_LVL_HI_PIN11
+	@brief		High Level Interrupt on Pin11
+*/
+#define INT_LVL_HI_PIN11 ((0x300000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN0
+	@brief		Falling and rising Edge on Pin0
+*/
+#define INT_FL_RS_EDG_PIN0 (0x4)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN1
+	@brief		Falling and rising Edge on Pin1
+*/
+#define INT_FL_RS_EDG_PIN1 (0x40)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN2
+	@brief		Falling and rising Edge on Pin2
+*/
+#define INT_FL_RS_EDG_PIN2 (0x400)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN3
+	@brief		Falling and rising Edge on Pin3
+*/
+#define INT_FL_RS_EDG_PIN3 (0x4000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN4
+	@brief		Falling and rising Edge on Pin4
+*/
+#define INT_FL_RS_EDG_PIN4 (0x40000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN5
+	@brief		Falling and rising Edge on Pin5
+*/
+#define INT_FL_RS_EDG_PIN5 (0x400000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN6
+	@brief		Falling and rising Edge on Pin6
+*/
+#define INT_FL_RS_EDG_PIN6 (0x4000000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN7
+	@brief		Falling and rising Edge on Pin7
+*/
+#define INT_FL_RS_EDG_PIN7 (0x40000000)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN8
+	@brief		Falling and rising Edge on Pin8
+*/
+#define INT_FL_RS_EDG_PIN8 ((0x400000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN9
+	@brief		Falling and rising Edge on Pin9
+*/
+#define INT_FL_RS_EDG_PIN9 ((0x4000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN10
+	@brief		Falling and rising Edge on Pin10
+*/
+#define INT_FL_RS_EDG_PIN10 ((0x40000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		INT_FL_RS_EDG_PIN11
+	@brief		Falling and rising Edge on Pin11
+*/
+#define INT_FL_RS_EDG_PIN11 ((0x400000000000ULL))
+
+/*! @ingroup 	GPIO_InterfaceLayer
+
+	@def		GPIO_MAX_PINS_MASK
+	@brief		Mask used for all pins.
+*/
+#define GPIO_MAX_PINS_MASK (0xFFF)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		GPIO_NUM_PORT_MAX
+	@brief		Maximum number of ports.
+*/
+#define GPIO_NUM_PORT_MAX (0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		GPIO_NUM_PINS
+	@brief 		Specifies number of GPIO PINS
+*/
+#define GPIO_NUM_PINS 	(12)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		GPIO_IN
+	@brief		Specifies GPIO input mode.
+*/
+#define GPIO_IN 	(0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		GPIO_OUT
+	@brief		Specifies GPIO output mode.
+*/
+#define GPIO_OUT (1)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		GPIO_HIGH
+	@brief		Specifies GPIO HIGH level.
+*/
+#define GPIO_HIGH (1)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		GPIO_LOW
+	@brief		Specifies GPIO LOW level.
+*/
+#define GPIO_LOW (0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_SUCCESS
+	@brief 		Specifies GPIO SUCCESS STATUS CODE
+*/
+#define IOH_GPIO_SUCCESS 	(0)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		IOH_GPIO_FAIL
+	@brief 		Specifies GPIO ERROR STATUS CODE
+*/
+#define IOH_GPIO_FAIL 		(-1)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def		BIT_MASK_16
+	@brief 		Mask for 16 bits
+*/
+#define BIT_MASK_16		(0xFFFF)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		BIT_MASK_8
+	@brief 		Mask for 8 bits
+*/
+#define BIT_MASK_8		(0xFF)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		BIT_MASK_12
+	@brief 		Mask for 12 bits
+*/
+#define BIT_MASK_12		(0xFFF)
+
+/*! @ingroup 	GPIO_InterfaceLayer
+	@def 		BIT_MASK_32
+	@brief 		Maks value for 32 bits.
+*/
+#define BIT_MASK_32 	(0xFFFFFFFF)
+
+/*structures*/
+/*! @ingroup 	GPIO_InterfaceLayer
+@struct 	ioh_gpio_reqt
+@brief 		This structure specifies information such the GPIO port, pins,
+		 interrupt and direction
+		mode details associated with a user request. The GPIO port
+		 status is also returned to
+		the user using this structure.
+@see
+		- ioh_gpio_int_mode
+		- ioh_gpio_dir_mode
+		- ioh_gpio_read
+		- ioh_gpio_write
+*/
+struct ioh_gpio_reqt {
+	unsigned long port;	/**< Specifies the port.		*/
+	unsigned long pins;	/**< Specifies the pins. 		*/
+	unsigned long long mode;/**< Specifies the direction/interrupt mode.*/
+	unsigned long enable;	/**< Interrupt enable/disable.	*/
+};
+
+extern s32 ioh_gpio_opencount;
+extern spinlock_t ioh_gpio_lock;
+extern const struct file_operations ioh_gpio_fops;
+
+/* exported function prototypes*/
+/*! @ingroup 	GPIO_InterfaceLayerAPI
+@fn 		int ioh_gpio_open( struct inode *inode,struct file *file )
+@brief  	This function is invoked when a process opens the device node
+*/
+int ioh_gpio_open(struct inode *inode, struct file *file);
+
+/*! @ingroup 	GPIO_InterfaceLayerAPI
+@fn 		int ioh_gpio_release(struct inode *inode,struct file *file)
+@brief  	This function is invoked when a process closes the device node
+*/
+int ioh_gpio_release(struct inode *inode, struct file *file);
+
+/*! @ingroup 	GPIO_InterfaceLayerAPI
+@fn int ioh_gpio_ioctl(struct inode * inode,struct file * file,unsigned int cmd,
+	unsigned long arg)
+@brief This function is registered at the driver initialization point
+	 (module_init)
+	and invoked when user process invokes an ioctl call on the device.
+*/
+int ioh_gpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		   unsigned long arg);
+
+/* global variables*/
+extern u32 ioh_gpio_base_address;	/* base address*/
+extern u32 ioh_gpio_irq;	/* irq number*/
+extern s32 ioh_gpio_suspended;	/* suspend status*/
+
+#endif
diff -urN linux-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_pci.c topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_pci.c
--- linux-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_pci.c	1970-01-01 09:00:00.000000000 +0900
+++ topcliff-2.6.33.1/drivers/gpio/pch_gpio/pch_gpio_pci.c	2010-04-01 10:58:31.000000000 +0900
@@ -0,0 +1,537 @@
+/*!
+ * @file ioh_gpio_pci.c
+ * @brief Provides all the implementation of the interfaces pertaining to the
+ * 						 pci and gpio registrations.
+ * @version 0.92
+ * @section
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+/*
+ * History:
+ * Copyright (C) 2008 OKI SEMICONDUCTOR Co., LTD.
+ * All rights reserved.
+ *
+ * created:
+ *	WIPRO 02/20/2009
+ * modified:
+ *	WIPRO 01/05/2010
+ *	Added the interfaces provided by the gpio module.
+ *
+ */
+/*includes*/
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+
+#include "pch_common.h"
+#include "pch_debug.h"
+#include "pch_gpio_main.h"
+#include "pch_gpio_hal.h"
+
+/*macros*/
+/*! @ingroup 	GPIO_PCILayer
+	@def 		PCI_VENDOR_ID_IOH
+	@brief 		Outlines the PCI Vendor ID.
+*/
+#define PCI_VENDOR_ID_IOH 			(0x10DB)
+
+/*! @ingroup 	GPIO_PCILayer
+	@def 		PCI_DEVICE_ID_GE_GPIO
+	@brief 		Outlines the PCI Device ID for IOH GPIO.
+*/
+/* #define PCI_DEVICE_ID_GE_GPIO        (0x8000)*/
+#define PCI_DEVICE_ID_GE_GPIO 		(0x8803)	/* OKISEMI for LSI */
+
+/*! @ingroup 	GPIO_PCILayer
+	@def 	 	PCI_DEVICE_ID_MP_GPIO
+	@brief 	 	Outlines the PCI Device ID for MP GPIO.
+*/
+#define PCI_DEVICE_ID_MP_GPIO 	(0x8004)
+
+/*! @ingroup 	GPIO_PCILayer
+	@def 		PCI_DEVICE_ID_IVI_GPIO
+	@brief 		Outlines the PCI Device ID for IVI GPIO.
+*/
+#define PCI_DEVICE_ID_IVI_GPIO 	(0x8001)
+
+/*! @ingroup 	GPIO_PCILayer
+	@def 		IOH_MINOR_NOS
+	@brief 		Outlines the GPIO minor number limit.
+*/
+#define IOH_MINOR_NOS 		(1)
+
+/* Global variables*/
+u32 ioh_gpio_base_address;
+u32 ioh_gpio_irq;
+s32 ioh_gpio_suspended;
+
+/* Major number allocation via module parameter */
+static dev_t ioh_gpio_dev_no;
+static int ioh_gpio_major_no;
+static struct cdev ioh_gpio_dev;
+
+u32 ioh_gpio_bit_mask;
+
+/*! @ingroup 	GPIO_PCILayerAPI
+	@fn 		static s32 __devinit ioh_gpio_probe
+					(struct pci_dev* ioh_pci_dev,
+					const struct pci_device_id* pci_id)
+	@brief  	Provides the functionality of probing the module.
+*/
+static int __devinit ioh_gpio_probe(struct pci_dev *pdev, const
+				    struct pci_device_id *id);
+
+/*! @ingroup 	GPIO_PCILayerAPI
+	@fn 		static void __devexit ioh_gpio_remove
+					(struct pci_dev * ioh_pci_dev)
+	@brief  	Provides the functionality of removing the module.
+*/
+static void __devexit ioh_gpio_remove(struct pci_dev *pdev);
+
+/*! @ingroup 	GPIO_PCILayerAPI
+	@fn 		static s32 ioh_gpio_suspend(struct pci_dev* pDev,
+							pm_message_t state)
+	@brief  	Provides the functionality of suspending the module.
+*/
+static int ioh_gpio_suspend(struct pci_dev *pdev, pm_message_t state);
+
+/*! @ingroup 	GPIO_PCILayerAPI
+	@fn 		static s32 ioh_gpio_resume(struct pci_dev* pDev)
+	@brief  	Provides the functionalities of resuming the module.
+*/
+static int ioh_gpio_resume(struct pci_dev *pdev);
+
+/*structures*/
+/*! @ingroup 	GPIO_PCILayerFacilitators
+@static 	struct pci_device_id
+@brief 		It is a structure used for preserving information related to the
+			device id.
+@note
+The concerned details should be provided as a reference in the pci driver
+structure.
+
+@see
+		- ioh_gpio_driver
+
+*/
+static struct pci_device_id ioh_gpio_pcidev_id[] = {
+
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_GE_GPIO)},
+	{PCI_DEVICE(PCI_VENDOR_ID_IOH, PCI_DEVICE_ID_MP_GPIO)},
+	{PCI_DEVICE(PCI_VENDOR_ID_IOH, PCI_DEVICE_ID_IVI_GPIO)},
+	{0,}
+};
+
+/*! @ingroup 	GPIO_PCILayerFacilitators
+@struct 	ioh_gpio_driver
+@brief 	This structure specifies the pci driver methods pertaining to
+								 GPIO module.
+@see
+		- ioh_gpio_pci_init
+		- ioh_gpio_pci_exit
+*/
+static struct pci_driver ioh_gpio_driver = {
+	.name = "ioh_gpio_empty",
+	.id_table = ioh_gpio_pcidev_id,
+	.probe = ioh_gpio_probe,
+	.remove = __devexit_p(ioh_gpio_remove),
+#ifdef CONFIG_PM
+	.suspend = ioh_gpio_suspend,	/* OKISEMI for PM bug fix */
+	.resume = ioh_gpio_resume	/* OKISEMI for PM bug fix */
+#endif
+};
+
+/*! @ingroup 	GPIO_PCILayerAPI
+	@fn 		static int __init ioh_gpio_pci_init(void)
+	@brief  	Provides the functionality of initializing the module
+*/
+static int __init ioh_gpio_pci_init(void);
+/*! @ingroup 	GPIO_PCILayerAPI
+	@fn 		static void __exit ioh_gpio_pci_exit(void)
+	@brief  	Provides the functionality of exiting the module
+*/
+static void __exit ioh_gpio_pci_exit(void);
+
+MODULE_DESCRIPTION("IOH GPIO PCI Driver");
+MODULE_LICENSE("GPL");
+module_init(ioh_gpio_pci_init);
+module_exit(ioh_gpio_pci_exit);
+module_param(ioh_gpio_major_no, int, S_IRUSR | S_IWUSR);
+
+/*function implementations*/
+
+/*! @ingroup 	GPIO_PCILayerAPI
+@fn  		static int __init ioh_gpio_pci_init(void)
+@remarks  	Implements the initialization functionality of the module.
+			The main task performed by this function is:
+			- Register the module as PCI Driver.
+
+@param  	None
+@retval 	int
+			- @ref IOH_GPIO_SUCCESS	-->	Loading successful.
+			- -EEXIST		--> pci_register_driver failed.
+			- -EINVAL		--> pci_register_driver failed.
+			- -ENOMEM 		--> pci_register_driver failed.
+*/
+static int __init ioh_gpio_pci_init(void)
+{
+	s32 ret;
+	ret = pci_register_driver(&ioh_gpio_driver);
+	IOH_DEBUG
+	    ("ioh_gpio_pci_init : Invoked pci_register_driver successfully\n");
+	IOH_DEBUG("ioh_gpio_pci_init returns -%d\n", ret);
+	return ret;
+}
+
+/*! @ingroup 	GPIO_PCILayerAPI
+	@fn  		static void __exit ioh_gpio_pci_exit(void)
+	@remarks  	Implements the exit functionality of the module.
+				The main task performed by this function is:
+				- Un-register the module as a PCI Driver.
+
+	@param  	None
+	@retval		None
+*/
+static void __exit ioh_gpio_pci_exit(void)
+{
+	pci_unregister_driver(&ioh_gpio_driver);
+	IOH_DEBUG
+	    ("ioh_gpio_pci_exit : Invoked pci_unregister_driver\
+							 successfully\n");
+}
+
+/*! @ingroup 	GPIO_PCILayerAPI
+@fn  		static int __devinit ioh_gpio_probe(struct pci_dev* pdev,
+						const struct pci_device_id* id)
+@remarks  Implements the probe functionality of the module.
+	 This function is invoked
+	when a PCI device with the Vendor and Device ID supported by this module
+	is detected. The main tasks performed by this function are:
+	- Enables the device.
+	- Acquires the device resources and the remapped base address of
+	the device.
+	- Registers a character device driver for the user space application
+	to interact with the system.
+	- Registers the callback function.
+@note	This function is invoked by the Kernel subsystem when a PCI device
+			with a supported vendor ID and Device ID is detected.
+
+@param  pdev 	[@ref INOUT] 	Contains the reference of the pci_dev structure
+@param  id 	[@ref IN] Contains the reference of the pci_device_id structure
+@retval	int
+		- @ref IOH_GPIO_SUCCESS		-->	Operation successful.
+		- -EIO		-->	pci_enable_device error status code.
+		- -EINVAL	--> pci_enable_device error status code.
+		- -EBUSY	--> pci_request_regions/ alloc_chrdev_region
+							error status code.
+		- -ENOMEM	--> pci_iomap/alloc_chrdev_region/cdev_add
+							error status code.
+
+@see
+			- ioh_gpio_driver
+*/
+static int __devinit ioh_gpio_probe(struct pci_dev *pdev,
+				    const struct pci_device_id *id)
+{
+
+	char *DRIVER_NAME = "ioh_gpio";
+	int ret;
+	ioh_gpio_bit_mask =
+	    (pdev->device ==
+	     PCI_DEVICE_ID_IVI_GPIO) ? BIT_MASK_16 : BIT_MASK_12;
+	IOH_DEBUG("ioh_gpio_probe : The value of ioh_gpio_bit_mask is: %x\n",
+		  ioh_gpio_bit_mask);
+
+	ioh_gpio_major_no = (ioh_gpio_major_no < 0
+			     || ioh_gpio_major_no >
+			     254) ? 0 : ioh_gpio_major_no;
+
+	do {
+
+		ret = pci_enable_device(pdev);
+		if (ret) {
+			IOH_LOG(KERN_ERR,
+				"\nioh_gpio_probe : pci_enable_device FAILED");
+			break;
+		}
+		IOH_DEBUG("ioh_gpio_probe : pci_enable_device returns %d\n",
+			  ret);
+
+		ret = pci_request_regions(pdev, DRIVER_NAME);
+		if (ret) {
+			IOH_LOG(KERN_ERR,
+				"ioh_gpio_probe : pci_request_regions FAILED");
+			pci_disable_device(pdev);
+			break;
+		}
+		IOH_DEBUG("ioh_gpio_probe : pci_request_regions returns %d\n",
+			  ret);
+
+		ioh_gpio_base_address = (unsigned long)pci_iomap(pdev, 1, 0);
+
+		if (ioh_gpio_base_address == 0) {
+			IOH_LOG(KERN_ERR, "ioh_gpio_probe : pci_iomap FAILED");
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			ret = -ENOMEM;
+			break;
+		}
+
+		IOH_DEBUG
+		    ("ioh_gpio_probe : pci_iomap SUCCESS and value in\
+							 ioh_gpio_base_address"
+		     "variable is %d\n", ioh_gpio_base_address);
+
+		if (ioh_gpio_major_no) {
+			ioh_gpio_dev_no = MKDEV(ioh_gpio_major_no, 0);
+			ret =
+			    register_chrdev_region(ioh_gpio_dev_no,
+						   IOH_MINOR_NOS, DRIVER_NAME);
+			if (ret) {
+				IOH_LOG(KERN_ERR,
+					"ioh_gpio_probe :  register_chrdev_\
+							region FAILED");
+				pci_iounmap(pdev,
+					    (void *)ioh_gpio_base_address);
+				pci_release_regions(pdev);
+				pci_disable_device(pdev);
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_gpio_probe :  register_chrdev_region\
+							 returns %d\n",
+			     ret);
+		} else {
+			ret =
+			    alloc_chrdev_region(&ioh_gpio_dev_no, 0,
+						IOH_MINOR_NOS, DRIVER_NAME);
+			if (ret) {
+				IOH_LOG(KERN_ERR,
+					"ioh_gpio_probe :  alloc_chrdev_region\
+								 FAILED");
+				pci_iounmap(pdev,
+					    (void *)ioh_gpio_base_address);
+				pci_release_regions(pdev);
+				pci_disable_device(pdev);
+				break;
+			}
+			IOH_DEBUG
+			    ("ioh_gpio_probe :  alloc_chrdev_region\
+				 returns %d\n",
+			     ret);
+		}
+
+		cdev_init(&ioh_gpio_dev, &ioh_gpio_fops);
+		IOH_DEBUG("ioh_gpio_probe :  cdev_init invoked successfully\n");
+
+		ioh_gpio_dev.owner = THIS_MODULE;
+		ioh_gpio_dev.ops = &ioh_gpio_fops;
+
+		ret = cdev_add(&ioh_gpio_dev, ioh_gpio_dev_no, IOH_MINOR_NOS);
+		if (ret) {
+			IOH_LOG(KERN_ERR, "ioh_gpio_probe :  cdev_add FAILED");
+			unregister_chrdev_region(ioh_gpio_dev_no,
+						 IOH_MINOR_NOS);
+			pci_iounmap(pdev, (void *)ioh_gpio_base_address);
+			pci_release_regions(pdev);
+			pci_disable_device(pdev);
+			break;
+		}
+		IOH_DEBUG("ioh_gpio_probe :  cdev_add returns- %d\n", ret);
+
+		ioh_gpio_cb_register(ioh_gpio_cb);
+		ioh_gpio_irq = pdev->irq;
+		IOH_DEBUG("ioh_gpio_probe returns %d\n", IOH_GPIO_SUCCESS);
+		device_set_wakeup_enable(&pdev->dev, 1);
+		return IOH_GPIO_SUCCESS;
+	} while (0);
+	IOH_DEBUG("ioh_gpio_probe returns %d\n", ret);
+	return ret;
+}
+
+/*! @ingroup 	GPIO_PCILayerAPI
+@fn  		static void __devexit ioh_gpio_remove(struct pci_dev * pdev)
+@remarks  	Implements the remove functionality of the module.
+The main tasks performed by this function are:
+-Disables the interrupts by invoking @ref ioh_gpio_int_mode API.
+-Removes the device from the system using cdev_del API
+-Un-registers the char device number by invoking unregister_chrdev_region API.
+-Releases the IO memory using pci_iounmap API
+-Releases the resources acquired using pci_release_regions API
+-Disables the pci device using pci_disable_device API
+
+@param  pdev [@ref INOUT] Contains the reference of the pci_dev structure
+@retval		None
+@see
+			- ioh_gpio_driver
+*/
+static void __devexit ioh_gpio_remove(struct pci_dev *pdev)
+{
+
+	struct ioh_gpio_reqt req;
+	memset(&req, 0, sizeof(req));
+	req.pins = IOH_GPIO_ALL_PINS;
+	/* disable interrupts for all gpio pins */
+	(void)ioh_gpio_int_mode(&req);
+
+	cdev_del(&ioh_gpio_dev);
+	IOH_DEBUG("ioh_gpio_remove - cdev_del Invoked successfully\n");
+
+	unregister_chrdev_region(ioh_gpio_dev_no, IOH_MINOR_NOS);
+	IOH_DEBUG
+	    ("ioh_gpio_remove - unregister_chrdev_region Invoked\
+							 successfully\n");
+
+	pci_iounmap(pdev, (void *)ioh_gpio_base_address);
+
+	IOH_DEBUG("ioh_gpio_remove - pci_iounmap Invoked successfully\n");
+
+	pci_release_regions(pdev);
+	IOH_DEBUG
+	    ("ioh_gpio_remove - pci_release_regions Invoked successfully\n");
+
+	pci_disable_device(pdev);
+	IOH_DEBUG
+	    ("ioh_gpio_remove - pci_disable_device Invoked successfully\n");
+
+}
+
+#ifdef CONFIG_PM
+
+/*! @ingroup 	GPIO_PCILayerAPI
+@fn 	static s32 ioh_gpio_suspend(struct pci_dev* pdev,pm_message_t state)
+@remarks  	Implements the suspend functionality of the module. The main
+tasks performed by this function are:
+-	Saves the current pin configuration by invoking
+	@ref ioh_gpio_save_reg_conf API.
+-	Invokes pci_enable_wake with the enable parameter as 0,
+	so as to ensure that the device has its "wake" ability disabled
+-	Saves the current state by invoking pci_save_state API.
+	If it fails then return with its error code.
+-	Disables PCI device by invoking pci_disable_device API.
+-	Sets the power state to low power mode by invoking
+	pci_set_power_state API and return @ref IOH_GPIO_SUCCESS status code.
+
+@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	int
+		- @ref IOH_GPIO_SUCCESS	-->	Operation successful.
+		- -ENOMEM		--> pci_save_state error status code.
+@see
+	- ioh_gpio_driver
+
+*/
+static int ioh_gpio_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int ret;
+
+	ioh_gpio_suspended = true;	/* For blocking further IOCTLs */
+
+	ioh_gpio_save_reg_conf();
+	IOH_DEBUG
+	   ("ioh_gpio_suspend - ioh_gpio_save_reg_conf Invoked successfully\n");
+	ioh_gpio_restore_reg_conf();
+
+	ret = pci_save_state(pdev);
+	if (ret) {
+		IOH_LOG(KERN_ERR,
+			" ioh_gpio_suspend -pci_save_state returns-%d\n", ret);
+		return ret;
+	}
+
+	IOH_DEBUG("ioh_gpio_suspend - pci_save_state returns %d\n", ret);
+
+	pci_disable_device(pdev);
+	IOH_DEBUG
+	    ("ioh_gpio_suspend - pci_disable_device Invoked successfully\n");
+
+	pci_set_power_state(pdev, PCI_D0);
+	IOH_DEBUG
+	    ("ioh_gpio_suspend - pci_set_power_state Invoked successfully\n");
+
+	ret = pci_enable_wake(pdev, PCI_D0, 1);
+	if (!ret) {
+		IOH_DEBUG
+		  ("ioh_gpio_suspend - pci_enable_wake Invoked successfully\n");
+	} else {
+		IOH_DEBUG("ioh_gpio_suspend - pci_enable_wake failed\n");
+	}
+	IOH_LOG(KERN_ERR, "ioh_gpio_suspend - return %d\n", IOH_GPIO_SUCCESS);
+
+	return IOH_GPIO_SUCCESS;
+}
+
+/*! @ingroup 	GPIO_PCILayerAPI
+@fn 		static s32 ioh_gpio_resume(struct pci_dev* pdev)
+@remarks  	Implements the resume functionality of the module. The main
+tasks performed by this function are:
+-Changes the power state of the device to D0 using pci_set_power_state API.
+-Invokes pci_restore_state API to restore the PCI register state
+-Invokes pci_enable_device API to enable the PCI device.
+If it fails, then return its error code.
+-To ensure that the device has its "wake" ability disabled,
+invokes pci_enable_wake with the enable parameter as 0
+-Invokes @ref ioh_gpio_restore_reg_conf API to restore the GPIO register
+configuration values and returns @ref IOH_GPIO_SUCCESS status code.
+
+@param  pdev [@ref INOUT] Contains the reference of the pci_dev structure
+@retval	int
+		- @ref IOH_GPIO_SUCCESS		--> Operation successful.
+		- -EIO 			--> pci_enable_device error status code.
+		- -EINVAL		--> pci_enable_device error status code.
+
+@see
+		- ioh_gpio_driver
+
+*/
+static int ioh_gpio_resume(struct pci_dev *pdev)
+{
+
+	int ret;
+
+	ret = pci_enable_wake(pdev, PCI_D0, 0);
+	IOH_LOG(KERN_ERR,
+		"ioh_gpio_resume - pci_set_power_state Invoked successfully\n");
+
+	pci_set_power_state(pdev, PCI_D0);
+	IOH_DEBUG
+	    ("ioh_gpio_resume - pci_set_power_state Invoked successfully\n");
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		IOH_LOG(KERN_ERR, "ioh_gpio_resume-pci_enable_device failed ");
+		return ret;
+	}
+
+	IOH_DEBUG("ioh_gpio_resume - pci_enable_device returns -%d\n", ret);
+
+	pci_restore_state(pdev);
+	IOH_DEBUG("ioh_gpio_resume - pci_restore_state Invoked successfully\n");
+
+	ioh_gpio_writereg(0x3c, 0x00000001);	/*reset*/
+	ioh_gpio_writereg(0x3c, 0x00000000);
+	ioh_gpio_restore_reg_conf();
+	ioh_gpio_suspended = false;
+
+	IOH_DEBUG("ioh_gpio_resume  returns- %d\n", IOH_GPIO_SUCCESS);
+	return IOH_GPIO_SUCCESS;
+}
+
+#endif
