From: Masayuki Ohtake Subject: OKI Semiconductor PCH GPIO driver This driver implements GPIO controls for PCH. Signed-off-by: Masayuki Ohtake Acked-by: Wang Qi --- 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 +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include + +#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