summaryrefslogtreecommitdiff
path: root/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-gpio.patch
diff options
context:
space:
mode:
authorJoshua Lock <josh@linux.intel.com>2010-05-18 14:51:13 +0100
committerJoshua Lock <josh@linux.intel.com>2010-05-19 12:20:16 +0100
commit5e8c7c54a9b297dae0081dd19a7bb94e23040a3d (patch)
tree948e3642c1bf426870b83c72c68c997dce66766c /meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-gpio.patch
parent5e07bc91281969d54896dd0a13e3d6134e432027 (diff)
downloadopenembedded-core-5e8c7c54a9b297dae0081dd19a7bb94e23040a3d.tar.gz
openembedded-core-5e8c7c54a9b297dae0081dd19a7bb94e23040a3d.tar.bz2
openembedded-core-5e8c7c54a9b297dae0081dd19a7bb94e23040a3d.zip
linux-moblin: add 2.6.33.2 kernel from MeeGo 1.0
Signed-off-by: Joshua Lock <josh@linux.intel.com>
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-gpio.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-gpio.patch2700
1 files changed, 2700 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-gpio.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-gpio.patch
new file mode 100644
index 0000000000..c57f949078
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-pch-gpio.patch
@@ -0,0 +1,2700 @@
+
+
+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