2011-06-05 04:38:28 +04:00
/*
2014-01-17 19:30:01 +04:00
* Intel MID GPIO driver
2011-06-05 04:38:28 +04:00
*
2016-07-06 12:50:13 +03:00
* Copyright ( c ) 2008 - 2014 , 2016 Intel Corporation .
2009-09-23 03:46:36 +04:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* 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 .
*/
/* Supports:
* Moorestown platform Langwell chip .
2010-05-27 01:42:25 +04:00
* Medfield platform Penwell chip .
2013-10-05 00:01:42 +04:00
* Clovertrail platform Cloverview chip .
2009-09-23 03:46:36 +04:00
*/
# include <linux/delay.h>
# include <linux/init.h>
2016-07-06 12:50:13 +03:00
# include <linux/interrupt.h>
2009-09-23 03:46:36 +04:00
# include <linux/io.h>
2014-05-29 18:55:55 +04:00
# include <linux/gpio/driver.h>
2016-07-06 12:50:13 +03:00
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/pci.h>
# include <linux/platform_device.h>
2011-05-10 17:23:45 +04:00
# include <linux/pm_runtime.h>
2016-07-06 12:50:13 +03:00
# include <linux/slab.h>
# include <linux/stddef.h>
2009-09-23 03:46:36 +04:00
2013-10-05 00:01:42 +04:00
# define INTEL_MID_IRQ_TYPE_EDGE (1 << 0)
# define INTEL_MID_IRQ_TYPE_LEVEL (1 << 1)
2013-10-05 00:01:40 +04:00
2010-05-27 01:42:25 +04:00
/*
* Langwell chip has 64 pins and thus there are 2 32 bit registers to control
* each feature , while Penwell chip has 96 pins for each block , and need 3 32 bit
* registers to control them , so we only define the order here instead of a
* structure , to get a bit offset for a pin ( use GPDR as an example ) :
*
* nreg = ngpio / 32 ;
* reg = offset / 32 ;
* bit = offset % 32 ;
* reg_addr = reg_base + GPDR * nreg * 4 + reg * 4 ;
*
* so the bit of reg_addr is to control pin offset ' s GPDR feature
*/
enum GPIO_REG {
GPLR = 0 , /* pin level read-only */
GPDR , /* pin direction */
GPSR , /* pin set */
GPCR , /* pin clear */
GRER , /* rising edge detect */
GFER , /* falling edge detect */
GEDR , /* edge detect result */
2011-10-03 15:36:07 +04:00
GAFR , /* alt function */
2009-09-23 03:46:36 +04:00
} ;
2013-10-05 00:01:42 +04:00
/* intel_mid gpio driver data */
struct intel_mid_gpio_ddata {
2013-10-05 00:01:40 +04:00
u16 ngpio ; /* number of gpio pins */
u32 chip_irq_type ; /* chip interrupt type */
} ;
2013-10-05 00:01:42 +04:00
struct intel_mid_gpio {
2009-09-23 03:46:36 +04:00
struct gpio_chip chip ;
2013-05-22 14:20:11 +04:00
void __iomem * reg_base ;
2009-09-23 03:46:36 +04:00
spinlock_t lock ;
2011-05-10 17:23:45 +04:00
struct pci_dev * pdev ;
2009-09-23 03:46:36 +04:00
} ;
2010-05-27 01:42:25 +04:00
static void __iomem * gpio_reg ( struct gpio_chip * chip , unsigned offset ,
2013-05-22 14:20:14 +04:00
enum GPIO_REG reg_type )
2009-09-23 03:46:36 +04:00
{
2015-12-06 12:55:28 +03:00
struct intel_mid_gpio * priv = gpiochip_get_data ( chip ) ;
2010-05-27 01:42:25 +04:00
unsigned nreg = chip - > ngpio / 32 ;
2009-09-23 03:46:36 +04:00
u8 reg = offset / 32 ;
2010-05-27 01:42:25 +04:00
2013-10-05 00:01:42 +04:00
return priv - > reg_base + reg_type * nreg * 4 + reg * 4 ;
2010-05-27 01:42:25 +04:00
}
2011-10-03 15:36:07 +04:00
static void __iomem * gpio_reg_2bit ( struct gpio_chip * chip , unsigned offset ,
enum GPIO_REG reg_type )
{
2015-12-06 12:55:28 +03:00
struct intel_mid_gpio * priv = gpiochip_get_data ( chip ) ;
2011-10-03 15:36:07 +04:00
unsigned nreg = chip - > ngpio / 32 ;
u8 reg = offset / 16 ;
2013-10-05 00:01:42 +04:00
return priv - > reg_base + reg_type * nreg * 4 + reg * 4 ;
2011-10-03 15:36:07 +04:00
}
2013-10-05 00:01:42 +04:00
static int intel_gpio_request ( struct gpio_chip * chip , unsigned offset )
2011-10-03 15:36:07 +04:00
{
void __iomem * gafr = gpio_reg_2bit ( chip , offset , GAFR ) ;
u32 value = readl ( gafr ) ;
int shift = ( offset % 16 ) < < 1 , af = ( value > > shift ) & 3 ;
if ( af ) {
value & = ~ ( 3 < < shift ) ;
writel ( value , gafr ) ;
}
return 0 ;
}
2013-10-05 00:01:42 +04:00
static int intel_gpio_get ( struct gpio_chip * chip , unsigned offset )
2010-05-27 01:42:25 +04:00
{
void __iomem * gplr = gpio_reg ( chip , offset , GPLR ) ;
2009-09-23 03:46:36 +04:00
2015-12-21 13:00:56 +03:00
return ! ! ( readl ( gplr ) & BIT ( offset % 32 ) ) ;
2009-09-23 03:46:36 +04:00
}
2013-10-05 00:01:42 +04:00
static void intel_gpio_set ( struct gpio_chip * chip , unsigned offset , int value )
2009-09-23 03:46:36 +04:00
{
void __iomem * gpsr , * gpcr ;
if ( value ) {
2010-05-27 01:42:25 +04:00
gpsr = gpio_reg ( chip , offset , GPSR ) ;
2009-09-23 03:46:36 +04:00
writel ( BIT ( offset % 32 ) , gpsr ) ;
} else {
2010-05-27 01:42:25 +04:00
gpcr = gpio_reg ( chip , offset , GPCR ) ;
2009-09-23 03:46:36 +04:00
writel ( BIT ( offset % 32 ) , gpcr ) ;
}
}
2013-10-05 00:01:42 +04:00
static int intel_gpio_direction_input ( struct gpio_chip * chip , unsigned offset )
2009-09-23 03:46:36 +04:00
{
2015-12-06 12:55:28 +03:00
struct intel_mid_gpio * priv = gpiochip_get_data ( chip ) ;
2010-05-27 01:42:25 +04:00
void __iomem * gpdr = gpio_reg ( chip , offset , GPDR ) ;
2009-09-23 03:46:36 +04:00
u32 value ;
unsigned long flags ;
2013-10-05 00:01:42 +04:00
if ( priv - > pdev )
pm_runtime_get ( & priv - > pdev - > dev ) ;
2011-05-10 17:23:45 +04:00
2013-10-05 00:01:42 +04:00
spin_lock_irqsave ( & priv - > lock , flags ) ;
2009-09-23 03:46:36 +04:00
value = readl ( gpdr ) ;
value & = ~ BIT ( offset % 32 ) ;
writel ( value , gpdr ) ;
2013-10-05 00:01:42 +04:00
spin_unlock_irqrestore ( & priv - > lock , flags ) ;
2011-05-10 17:23:45 +04:00
2013-10-05 00:01:42 +04:00
if ( priv - > pdev )
pm_runtime_put ( & priv - > pdev - > dev ) ;
2011-05-10 17:23:45 +04:00
2009-09-23 03:46:36 +04:00
return 0 ;
}
2013-10-05 00:01:42 +04:00
static int intel_gpio_direction_output ( struct gpio_chip * chip ,
2009-09-23 03:46:36 +04:00
unsigned offset , int value )
{
2015-12-06 12:55:28 +03:00
struct intel_mid_gpio * priv = gpiochip_get_data ( chip ) ;
2010-05-27 01:42:25 +04:00
void __iomem * gpdr = gpio_reg ( chip , offset , GPDR ) ;
2009-09-23 03:46:36 +04:00
unsigned long flags ;
2013-10-05 00:01:42 +04:00
intel_gpio_set ( chip , offset , value ) ;
2011-05-10 17:23:45 +04:00
2013-10-05 00:01:42 +04:00
if ( priv - > pdev )
pm_runtime_get ( & priv - > pdev - > dev ) ;
2011-05-10 17:23:45 +04:00
2013-10-05 00:01:42 +04:00
spin_lock_irqsave ( & priv - > lock , flags ) ;
2009-09-23 03:46:36 +04:00
value = readl ( gpdr ) ;
2011-04-09 06:49:08 +04:00
value | = BIT ( offset % 32 ) ;
2009-09-23 03:46:36 +04:00
writel ( value , gpdr ) ;
2013-10-05 00:01:42 +04:00
spin_unlock_irqrestore ( & priv - > lock , flags ) ;
2011-05-10 17:23:45 +04:00
2013-10-05 00:01:42 +04:00
if ( priv - > pdev )
pm_runtime_put ( & priv - > pdev - > dev ) ;
2011-05-10 17:23:45 +04:00
2009-09-23 03:46:36 +04:00
return 0 ;
}
2013-10-05 00:01:42 +04:00
static int intel_mid_irq_type ( struct irq_data * d , unsigned type )
2009-09-23 03:46:36 +04:00
{
2014-05-29 18:55:55 +04:00
struct gpio_chip * gc = irq_data_get_irq_chip_data ( d ) ;
2015-12-06 12:55:28 +03:00
struct intel_mid_gpio * priv = gpiochip_get_data ( gc ) ;
2012-05-02 12:15:50 +04:00
u32 gpio = irqd_to_hwirq ( d ) ;
2009-09-23 03:46:36 +04:00
unsigned long flags ;
u32 value ;
2013-10-05 00:01:42 +04:00
void __iomem * grer = gpio_reg ( & priv - > chip , gpio , GRER ) ;
void __iomem * gfer = gpio_reg ( & priv - > chip , gpio , GFER ) ;
2009-09-23 03:46:36 +04:00
2013-10-05 00:01:42 +04:00
if ( gpio > = priv - > chip . ngpio )
2009-09-23 03:46:36 +04:00
return - EINVAL ;
2011-05-10 17:23:45 +04:00
2013-10-05 00:01:42 +04:00
if ( priv - > pdev )
pm_runtime_get ( & priv - > pdev - > dev ) ;
2011-05-10 17:23:45 +04:00
2013-10-05 00:01:42 +04:00
spin_lock_irqsave ( & priv - > lock , flags ) ;
2009-09-23 03:46:36 +04:00
if ( type & IRQ_TYPE_EDGE_RISING )
value = readl ( grer ) | BIT ( gpio % 32 ) ;
else
value = readl ( grer ) & ( ~ BIT ( gpio % 32 ) ) ;
writel ( value , grer ) ;
if ( type & IRQ_TYPE_EDGE_FALLING )
value = readl ( gfer ) | BIT ( gpio % 32 ) ;
else
value = readl ( gfer ) & ( ~ BIT ( gpio % 32 ) ) ;
writel ( value , gfer ) ;
2013-10-05 00:01:42 +04:00
spin_unlock_irqrestore ( & priv - > lock , flags ) ;
2009-09-23 03:46:36 +04:00
2013-10-05 00:01:42 +04:00
if ( priv - > pdev )
pm_runtime_put ( & priv - > pdev - > dev ) ;
2011-05-10 17:23:45 +04:00
2009-09-23 03:46:36 +04:00
return 0 ;
2010-10-28 02:33:22 +04:00
}
2009-09-23 03:46:36 +04:00
2013-10-05 00:01:42 +04:00
static void intel_mid_irq_unmask ( struct irq_data * d )
2009-09-23 03:46:36 +04:00
{
2010-10-28 02:33:22 +04:00
}
2009-09-23 03:46:36 +04:00
2013-10-05 00:01:42 +04:00
static void intel_mid_irq_mask ( struct irq_data * d )
2009-09-23 03:46:36 +04:00
{
2010-10-28 02:33:22 +04:00
}
2009-09-23 03:46:36 +04:00
2013-10-05 00:01:42 +04:00
static struct irq_chip intel_mid_irqchip = {
. name = " INTEL_MID-GPIO " ,
. irq_mask = intel_mid_irq_mask ,
. irq_unmask = intel_mid_irq_unmask ,
. irq_set_type = intel_mid_irq_type ,
2009-09-23 03:46:36 +04:00
} ;
2013-10-05 00:01:42 +04:00
static const struct intel_mid_gpio_ddata gpio_lincroft = {
2013-10-05 00:01:40 +04:00
. ngpio = 64 ,
} ;
2013-10-05 00:01:42 +04:00
static const struct intel_mid_gpio_ddata gpio_penwell_aon = {
2013-10-05 00:01:40 +04:00
. ngpio = 96 ,
2013-10-05 00:01:42 +04:00
. chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE ,
2013-10-05 00:01:40 +04:00
} ;
2013-10-05 00:01:42 +04:00
static const struct intel_mid_gpio_ddata gpio_penwell_core = {
2013-10-05 00:01:40 +04:00
. ngpio = 96 ,
2013-10-05 00:01:42 +04:00
. chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE ,
2013-10-05 00:01:40 +04:00
} ;
2013-10-05 00:01:42 +04:00
static const struct intel_mid_gpio_ddata gpio_cloverview_aon = {
2013-10-05 00:01:40 +04:00
. ngpio = 96 ,
2013-10-05 00:01:42 +04:00
. chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE | INTEL_MID_IRQ_TYPE_LEVEL ,
2013-10-05 00:01:40 +04:00
} ;
2013-10-05 00:01:42 +04:00
static const struct intel_mid_gpio_ddata gpio_cloverview_core = {
2013-10-05 00:01:40 +04:00
. ngpio = 96 ,
2013-10-05 00:01:42 +04:00
. chip_irq_type = INTEL_MID_IRQ_TYPE_EDGE ,
2013-10-05 00:01:40 +04:00
} ;
2013-12-03 03:08:45 +04:00
static const struct pci_device_id intel_gpio_ids [ ] = {
2013-10-05 00:01:40 +04:00
{
/* Lincroft */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x080f ) ,
. driver_data = ( kernel_ulong_t ) & gpio_lincroft ,
} ,
{
/* Penwell AON */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x081f ) ,
. driver_data = ( kernel_ulong_t ) & gpio_penwell_aon ,
} ,
{
/* Penwell Core */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x081a ) ,
. driver_data = ( kernel_ulong_t ) & gpio_penwell_core ,
} ,
{
/* Cloverview Aon */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x08eb ) ,
. driver_data = ( kernel_ulong_t ) & gpio_cloverview_aon ,
} ,
{
/* Cloverview Core */
PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x08f7 ) ,
. driver_data = ( kernel_ulong_t ) & gpio_cloverview_core ,
} ,
{ 0 }
2009-09-23 03:46:36 +04:00
} ;
2013-10-05 00:01:42 +04:00
MODULE_DEVICE_TABLE ( pci , intel_gpio_ids ) ;
2009-09-23 03:46:36 +04:00
2015-09-14 11:42:37 +03:00
static void intel_mid_irq_handler ( struct irq_desc * desc )
2009-09-23 03:46:36 +04:00
{
2014-05-29 18:55:55 +04:00
struct gpio_chip * gc = irq_desc_get_handler_data ( desc ) ;
2015-12-06 12:55:28 +03:00
struct intel_mid_gpio * priv = gpiochip_get_data ( gc ) ;
2011-03-17 22:32:49 +03:00
struct irq_data * data = irq_desc_get_irq_data ( desc ) ;
struct irq_chip * chip = irq_data_get_irq_chip ( data ) ;
2011-03-17 22:32:58 +03:00
u32 base , gpio , mask ;
2011-03-17 22:32:55 +03:00
unsigned long pending ;
2009-09-23 03:46:36 +04:00
void __iomem * gedr ;
/* check GPIO controller to check which pin triggered the interrupt */
2013-10-05 00:01:42 +04:00
for ( base = 0 ; base < priv - > chip . ngpio ; base + = 32 ) {
gedr = gpio_reg ( & priv - > chip , base , GEDR ) ;
2012-05-10 14:01:22 +04:00
while ( ( pending = readl ( gedr ) ) ) {
2011-07-08 13:02:18 +04:00
gpio = __ffs ( pending ) ;
2011-03-17 22:32:58 +03:00
mask = BIT ( gpio ) ;
/* Clear before handling so we can't lose an edge */
writel ( mask , gedr ) ;
2014-05-29 18:55:55 +04:00
generic_handle_irq ( irq_find_mapping ( gc - > irqdomain ,
2012-05-02 12:15:50 +04:00
base + gpio ) ) ;
2011-03-17 22:32:55 +03:00
}
2009-09-23 03:46:36 +04:00
}
2011-01-26 02:07:15 +03:00
2011-03-17 22:32:49 +03:00
chip - > irq_eoi ( data ) ;
2009-09-23 03:46:36 +04:00
}
2013-10-05 00:01:42 +04:00
static void intel_mid_irq_init_hw ( struct intel_mid_gpio * priv )
2012-04-05 13:15:17 +04:00
{
void __iomem * reg ;
unsigned base ;
2013-10-05 00:01:42 +04:00
for ( base = 0 ; base < priv - > chip . ngpio ; base + = 32 ) {
2012-04-05 13:15:17 +04:00
/* Clear the rising-edge detect register */
2013-10-05 00:01:42 +04:00
reg = gpio_reg ( & priv - > chip , base , GRER ) ;
2012-04-05 13:15:17 +04:00
writel ( 0 , reg ) ;
/* Clear the falling-edge detect register */
2013-10-05 00:01:42 +04:00
reg = gpio_reg ( & priv - > chip , base , GFER ) ;
2012-04-05 13:15:17 +04:00
writel ( 0 , reg ) ;
/* Clear the edge detect status register */
2013-10-05 00:01:42 +04:00
reg = gpio_reg ( & priv - > chip , base , GEDR ) ;
2012-04-05 13:15:17 +04:00
writel ( ~ 0 , reg ) ;
}
}
2013-10-05 00:01:42 +04:00
static int intel_gpio_runtime_idle ( struct device * dev )
2011-05-10 17:23:45 +04:00
{
2014-02-01 01:08:01 +04:00
int err = pm_schedule_suspend ( dev , 500 ) ;
return err ? : - EBUSY ;
2011-05-10 17:23:45 +04:00
}
2013-10-05 00:01:42 +04:00
static const struct dev_pm_ops intel_gpio_pm_ops = {
SET_RUNTIME_PM_OPS ( NULL , NULL , intel_gpio_runtime_idle )
2011-05-10 17:23:45 +04:00
} ;
2013-10-05 00:01:42 +04:00
static int intel_gpio_probe ( struct pci_dev * pdev ,
2013-05-22 14:20:11 +04:00
const struct pci_device_id * id )
2009-09-23 03:46:36 +04:00
{
2013-05-22 14:20:11 +04:00
void __iomem * base ;
2013-10-05 00:01:42 +04:00
struct intel_mid_gpio * priv ;
2009-09-23 03:46:36 +04:00
u32 gpio_base ;
2013-05-07 03:11:03 +04:00
u32 irq_base ;
2012-08-05 13:52:34 +04:00
int retval ;
2013-10-05 00:01:42 +04:00
struct intel_mid_gpio_ddata * ddata =
( struct intel_mid_gpio_ddata * ) id - > driver_data ;
2009-09-23 03:46:36 +04:00
2013-05-22 14:20:12 +04:00
retval = pcim_enable_device ( pdev ) ;
2009-09-23 03:46:36 +04:00
if ( retval )
2012-04-05 13:15:15 +04:00
return retval ;
2009-09-23 03:46:36 +04:00
2013-05-22 14:20:12 +04:00
retval = pcim_iomap_regions ( pdev , 1 < < 0 | 1 < < 1 , pci_name ( pdev ) ) ;
2009-09-23 03:46:36 +04:00
if ( retval ) {
2013-05-22 14:20:12 +04:00
dev_err ( & pdev - > dev , " I/O memory mapping error \n " ) ;
return retval ;
2009-09-23 03:46:36 +04:00
}
2013-05-22 14:20:11 +04:00
2013-05-22 14:20:12 +04:00
base = pcim_iomap_table ( pdev ) [ 1 ] ;
2013-05-22 14:20:11 +04:00
irq_base = readl ( base ) ;
gpio_base = readl ( sizeof ( u32 ) + base ) ;
2009-09-23 03:46:36 +04:00
/* release the IO mapping, since we already get the info from bar1 */
2013-05-22 14:20:12 +04:00
pcim_iounmap_regions ( pdev , 1 < < 1 ) ;
2009-09-23 03:46:36 +04:00
2013-10-05 00:01:42 +04:00
priv = devm_kzalloc ( & pdev - > dev , sizeof ( * priv ) , GFP_KERNEL ) ;
if ( ! priv ) {
2013-05-22 14:20:13 +04:00
dev_err ( & pdev - > dev , " can't allocate chip data \n " ) ;
2013-05-22 14:20:12 +04:00
return - ENOMEM ;
2009-09-23 03:46:36 +04:00
}
2012-04-05 13:15:16 +04:00
2013-10-05 00:01:42 +04:00
priv - > reg_base = pcim_iomap_table ( pdev ) [ 0 ] ;
priv - > chip . label = dev_name ( & pdev - > dev ) ;
2015-11-04 11:56:26 +03:00
priv - > chip . parent = & pdev - > dev ;
2013-10-05 00:01:42 +04:00
priv - > chip . request = intel_gpio_request ;
priv - > chip . direction_input = intel_gpio_direction_input ;
priv - > chip . direction_output = intel_gpio_direction_output ;
priv - > chip . get = intel_gpio_get ;
priv - > chip . set = intel_gpio_set ;
priv - > chip . base = gpio_base ;
priv - > chip . ngpio = ddata - > ngpio ;
2013-12-04 17:42:46 +04:00
priv - > chip . can_sleep = false ;
2013-10-05 00:01:42 +04:00
priv - > pdev = pdev ;
spin_lock_init ( & priv - > lock ) ;
pci_set_drvdata ( pdev , priv ) ;
2016-06-19 23:49:57 +03:00
retval = devm_gpiochip_add_data ( & pdev - > dev , & priv - > chip , priv ) ;
2009-09-23 03:46:36 +04:00
if ( retval ) {
2013-05-22 14:20:13 +04:00
dev_err ( & pdev - > dev , " gpiochip_add error %d \n " , retval ) ;
2013-05-22 14:20:12 +04:00
return retval ;
2009-09-23 03:46:36 +04:00
}
2012-04-05 13:15:17 +04:00
2014-05-29 18:55:55 +04:00
retval = gpiochip_irqchip_add ( & priv - > chip ,
& intel_mid_irqchip ,
irq_base ,
handle_simple_irq ,
IRQ_TYPE_NONE ) ;
if ( retval ) {
dev_err ( & pdev - > dev ,
" could not connect irqchip to gpiochip \n " ) ;
return retval ;
}
2013-10-05 00:01:42 +04:00
intel_mid_irq_init_hw ( priv ) ;
2012-04-05 13:15:17 +04:00
2014-05-29 18:55:55 +04:00
gpiochip_set_chained_irqchip ( & priv - > chip ,
& intel_mid_irqchip ,
pdev - > irq ,
intel_mid_irq_handler ) ;
2009-09-23 03:46:36 +04:00
2011-05-10 17:23:45 +04:00
pm_runtime_put_noidle ( & pdev - > dev ) ;
pm_runtime_allow ( & pdev - > dev ) ;
2012-04-05 13:15:15 +04:00
return 0 ;
2009-09-23 03:46:36 +04:00
}
2013-10-05 00:01:42 +04:00
static struct pci_driver intel_gpio_driver = {
. name = " intel_mid_gpio " ,
. id_table = intel_gpio_ids ,
. probe = intel_gpio_probe ,
2011-05-10 17:23:45 +04:00
. driver = {
2013-10-05 00:01:42 +04:00
. pm = & intel_gpio_pm_ops ,
2011-05-10 17:23:45 +04:00
} ,
2009-09-23 03:46:36 +04:00
} ;
2013-10-05 00:01:42 +04:00
static int __init intel_gpio_init ( void )
2009-09-23 03:46:36 +04:00
{
2013-10-05 00:01:42 +04:00
return pci_register_driver ( & intel_gpio_driver ) ;
2009-09-23 03:46:36 +04:00
}
2013-10-05 00:01:42 +04:00
device_initcall ( intel_gpio_init ) ;