2018-11-06 15:11:42 +03:00
// SPDX-License-Identifier: GPL-2.0
2010-10-28 02:33:21 +04:00
/*
2011-10-28 04:23:33 +04:00
* Copyright ( C ) 2011 LAPIS Semiconductor Co . , Ltd .
2010-10-28 02:33:21 +04:00
*/
2020-04-14 20:48:57 +03:00
# include <linux/bits.h>
2018-05-24 15:29:30 +03:00
# include <linux/gpio/driver.h>
2011-07-21 04:19:59 +04:00
# include <linux/interrupt.h>
# include <linux/irq.h>
2018-09-04 14:26:25 +03:00
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/pci.h>
2014-05-27 17:15:21 +04:00
# include <linux/slab.h>
2011-07-21 04:19:59 +04:00
# define PCH_EDGE_FALLING 0
2020-04-14 20:48:57 +03:00
# define PCH_EDGE_RISING 1
# define PCH_LEVEL_L 2
# define PCH_LEVEL_H 3
# define PCH_EDGE_BOTH 4
# define PCH_IM_MASK GENMASK(2, 0)
2011-07-21 04:19:59 +04:00
# define PCH_IRQ_BASE 24
2010-10-28 02:33:21 +04:00
struct pch_regs {
u32 ien ;
u32 istatus ;
u32 idisp ;
u32 iclr ;
u32 imask ;
u32 imaskclr ;
u32 po ;
u32 pi ;
u32 pm ;
u32 im0 ;
u32 im1 ;
2011-07-21 04:19:58 +04:00
u32 reserved [ 3 ] ;
u32 gpio_use_sel ;
2010-10-28 02:33:21 +04:00
u32 reset ;
} ;
2011-07-21 04:19:57 +04:00
enum pch_type_t {
INTEL_EG20T_PCH ,
2011-10-28 04:23:33 +04:00
OKISEMI_ML7223m_IOH , /* LAPIS Semiconductor ML7223 IOH PCIe Bus-m */
OKISEMI_ML7223n_IOH /* LAPIS Semiconductor ML7223 IOH PCIe Bus-n */
2011-07-21 04:19:57 +04:00
} ;
/* Specifies number of GPIO PINS */
static int gpio_pins [ ] = {
[ INTEL_EG20T_PCH ] = 12 ,
[ OKISEMI_ML7223m_IOH ] = 8 ,
[ OKISEMI_ML7223n_IOH ] = 8 ,
} ;
2010-10-28 02:33:21 +04:00
/**
* struct pch_gpio_reg_data - The register store data .
2011-07-21 04:19:59 +04:00
* @ ien_reg : To store contents of IEN register .
* @ imask_reg : To store contents of IMASK register .
2010-10-28 02:33:21 +04:00
* @ po_reg : To store contents of PO register .
* @ pm_reg : To store contents of PM register .
2011-07-21 04:19:58 +04:00
* @ im0_reg : To store contents of IM0 register .
* @ im1_reg : To store contents of IM1 register .
* @ gpio_use_sel_reg : To store contents of GPIO_USE_SEL register .
* ( Only ML7223 Bus - n )
2010-10-28 02:33:21 +04:00
*/
struct pch_gpio_reg_data {
2011-07-21 04:19:59 +04:00
u32 ien_reg ;
u32 imask_reg ;
2010-10-28 02:33:21 +04:00
u32 po_reg ;
u32 pm_reg ;
2011-07-21 04:19:58 +04:00
u32 im0_reg ;
u32 im1_reg ;
u32 gpio_use_sel_reg ;
2010-10-28 02:33:21 +04:00
} ;
/**
* struct pch_gpio - GPIO private data structure .
* @ base : PCI base address of Memory mapped I / O register .
* @ reg : Memory mapped PCH GPIO register list .
* @ dev : Pointer to device structure .
* @ gpio : Data for GPIO infrastructure .
* @ pch_gpio_reg : Memory mapped Register data is saved here
* when suspend .
2011-07-21 04:19:59 +04:00
* @ lock : Used for register access protection
* @ irq_base : Save base of IRQ number for interrupt
2011-07-21 04:19:57 +04:00
* @ ioh : IOH ID
2012-07-29 06:55:54 +04:00
* @ spinlock : Used for register access protection
2010-10-28 02:33:21 +04:00
*/
struct pch_gpio {
void __iomem * base ;
struct pch_regs __iomem * reg ;
struct device * dev ;
struct gpio_chip gpio ;
struct pch_gpio_reg_data pch_gpio_reg ;
2011-07-21 04:19:59 +04:00
int irq_base ;
2011-07-21 04:19:57 +04:00
enum pch_type_t ioh ;
2011-07-21 04:19:55 +04:00
spinlock_t spinlock ;
2010-10-28 02:33:21 +04:00
} ;
2020-07-21 17:50:45 +03:00
static void pch_gpio_set ( struct gpio_chip * gpio , unsigned int nr , int val )
2010-10-28 02:33:21 +04:00
{
u32 reg_val ;
2015-12-07 13:34:53 +03:00
struct pch_gpio * chip = gpiochip_get_data ( gpio ) ;
2012-07-29 06:55:54 +04:00
unsigned long flags ;
2010-10-28 02:33:21 +04:00
2012-07-29 06:55:54 +04:00
spin_lock_irqsave ( & chip - > spinlock , flags ) ;
2010-10-28 02:33:21 +04:00
reg_val = ioread32 ( & chip - > reg - > po ) ;
if ( val )
2020-04-14 20:48:57 +03:00
reg_val | = BIT ( nr ) ;
2010-10-28 02:33:21 +04:00
else
2020-04-14 20:48:57 +03:00
reg_val & = ~ BIT ( nr ) ;
2010-10-28 02:33:21 +04:00
iowrite32 ( reg_val , & chip - > reg - > po ) ;
2012-07-29 06:55:54 +04:00
spin_unlock_irqrestore ( & chip - > spinlock , flags ) ;
2010-10-28 02:33:21 +04:00
}
2020-07-21 17:50:45 +03:00
static int pch_gpio_get ( struct gpio_chip * gpio , unsigned int nr )
2010-10-28 02:33:21 +04:00
{
2015-12-07 13:34:53 +03:00
struct pch_gpio * chip = gpiochip_get_data ( gpio ) ;
2010-10-28 02:33:21 +04:00
2020-04-14 20:48:57 +03:00
return ! ! ( ioread32 ( & chip - > reg - > pi ) & BIT ( nr ) ) ;
2010-10-28 02:33:21 +04:00
}
2020-07-21 17:50:45 +03:00
static int pch_gpio_direction_output ( struct gpio_chip * gpio , unsigned int nr ,
2010-10-28 02:33:21 +04:00
int val )
{
2015-12-07 13:34:53 +03:00
struct pch_gpio * chip = gpiochip_get_data ( gpio ) ;
2010-10-28 02:33:21 +04:00
u32 pm ;
u32 reg_val ;
2012-07-29 06:55:54 +04:00
unsigned long flags ;
2010-10-28 02:33:21 +04:00
2012-07-29 06:55:54 +04:00
spin_lock_irqsave ( & chip - > spinlock , flags ) ;
2010-10-28 02:33:21 +04:00
reg_val = ioread32 ( & chip - > reg - > po ) ;
if ( val )
2020-04-14 20:48:57 +03:00
reg_val | = BIT ( nr ) ;
2010-10-28 02:33:21 +04:00
else
2020-04-14 20:48:57 +03:00
reg_val & = ~ BIT ( nr ) ;
2011-03-25 18:04:00 +03:00
iowrite32 ( reg_val , & chip - > reg - > po ) ;
2014-03-25 13:32:47 +04:00
2020-04-14 20:48:57 +03:00
pm = ioread32 ( & chip - > reg - > pm ) ;
pm & = BIT ( gpio_pins [ chip - > ioh ] ) - 1 ;
pm | = BIT ( nr ) ;
2014-03-25 13:32:47 +04:00
iowrite32 ( pm , & chip - > reg - > pm ) ;
2012-07-29 06:55:54 +04:00
spin_unlock_irqrestore ( & chip - > spinlock , flags ) ;
2010-10-28 02:33:21 +04:00
return 0 ;
}
2020-07-21 17:50:45 +03:00
static int pch_gpio_direction_input ( struct gpio_chip * gpio , unsigned int nr )
2010-10-28 02:33:21 +04:00
{
2015-12-07 13:34:53 +03:00
struct pch_gpio * chip = gpiochip_get_data ( gpio ) ;
2010-10-28 02:33:21 +04:00
u32 pm ;
2012-07-29 06:55:54 +04:00
unsigned long flags ;
2010-10-28 02:33:21 +04:00
2012-07-29 06:55:54 +04:00
spin_lock_irqsave ( & chip - > spinlock , flags ) ;
2020-04-14 20:48:57 +03:00
pm = ioread32 ( & chip - > reg - > pm ) ;
pm & = BIT ( gpio_pins [ chip - > ioh ] ) - 1 ;
pm & = ~ BIT ( nr ) ;
2010-10-28 02:33:21 +04:00
iowrite32 ( pm , & chip - > reg - > pm ) ;
2012-07-29 06:55:54 +04:00
spin_unlock_irqrestore ( & chip - > spinlock , flags ) ;
2010-10-28 02:33:21 +04:00
return 0 ;
}
/*
* Save register configuration and disable interrupts .
*/
2018-11-07 22:19:45 +03:00
static void __maybe_unused pch_gpio_save_reg_conf ( struct pch_gpio * chip )
2010-10-28 02:33:21 +04:00
{
2011-07-21 04:19:59 +04:00
chip - > pch_gpio_reg . ien_reg = ioread32 ( & chip - > reg - > ien ) ;
chip - > pch_gpio_reg . imask_reg = ioread32 ( & chip - > reg - > imask ) ;
2010-10-28 02:33:21 +04:00
chip - > pch_gpio_reg . po_reg = ioread32 ( & chip - > reg - > po ) ;
chip - > pch_gpio_reg . pm_reg = ioread32 ( & chip - > reg - > pm ) ;
2011-07-21 04:19:58 +04:00
chip - > pch_gpio_reg . im0_reg = ioread32 ( & chip - > reg - > im0 ) ;
if ( chip - > ioh = = INTEL_EG20T_PCH )
chip - > pch_gpio_reg . im1_reg = ioread32 ( & chip - > reg - > im1 ) ;
if ( chip - > ioh = = OKISEMI_ML7223n_IOH )
2018-11-07 22:19:45 +03:00
chip - > pch_gpio_reg . gpio_use_sel_reg = ioread32 ( & chip - > reg - > gpio_use_sel ) ;
2010-10-28 02:33:21 +04:00
}
/*
* This function restores the register configuration of the GPIO device .
*/
2018-11-07 22:19:45 +03:00
static void __maybe_unused pch_gpio_restore_reg_conf ( struct pch_gpio * chip )
2010-10-28 02:33:21 +04:00
{
2011-07-21 04:19:59 +04:00
iowrite32 ( chip - > pch_gpio_reg . ien_reg , & chip - > reg - > ien ) ;
iowrite32 ( chip - > pch_gpio_reg . imask_reg , & chip - > reg - > imask ) ;
2010-10-28 02:33:21 +04:00
/* to store contents of PO register */
iowrite32 ( chip - > pch_gpio_reg . po_reg , & chip - > reg - > po ) ;
/* to store contents of PM register */
iowrite32 ( chip - > pch_gpio_reg . pm_reg , & chip - > reg - > pm ) ;
2011-07-21 04:19:58 +04:00
iowrite32 ( chip - > pch_gpio_reg . im0_reg , & chip - > reg - > im0 ) ;
if ( chip - > ioh = = INTEL_EG20T_PCH )
iowrite32 ( chip - > pch_gpio_reg . im1_reg , & chip - > reg - > im1 ) ;
if ( chip - > ioh = = OKISEMI_ML7223n_IOH )
2018-11-07 22:19:45 +03:00
iowrite32 ( chip - > pch_gpio_reg . gpio_use_sel_reg , & chip - > reg - > gpio_use_sel ) ;
2010-10-28 02:33:21 +04:00
}
2020-07-21 17:50:45 +03:00
static int pch_gpio_to_irq ( struct gpio_chip * gpio , unsigned int offset )
2011-07-21 04:19:59 +04:00
{
2015-12-07 13:34:53 +03:00
struct pch_gpio * chip = gpiochip_get_data ( gpio ) ;
2020-07-21 17:50:46 +03:00
2011-07-21 04:19:59 +04:00
return chip - > irq_base + offset ;
}
2010-10-28 02:33:21 +04:00
static void pch_gpio_setup ( struct pch_gpio * chip )
{
struct gpio_chip * gpio = & chip - > gpio ;
gpio - > label = dev_name ( chip - > dev ) ;
2015-11-04 11:56:26 +03:00
gpio - > parent = chip - > dev ;
2010-10-28 02:33:21 +04:00
gpio - > owner = THIS_MODULE ;
gpio - > direction_input = pch_gpio_direction_input ;
gpio - > get = pch_gpio_get ;
gpio - > direction_output = pch_gpio_direction_output ;
gpio - > set = pch_gpio_set ;
gpio - > base = - 1 ;
2011-07-21 04:19:57 +04:00
gpio - > ngpio = gpio_pins [ chip - > ioh ] ;
2013-12-04 17:42:46 +04:00
gpio - > can_sleep = false ;
2011-07-21 04:19:59 +04:00
gpio - > to_irq = pch_gpio_to_irq ;
}
static int pch_irq_type ( struct irq_data * d , unsigned int type )
{
struct irq_chip_generic * gc = irq_data_get_irq_chip_data ( d ) ;
struct pch_gpio * chip = gc - > private ;
2012-04-28 12:13:45 +04:00
u32 im , im_pos , val ;
u32 __iomem * im_reg ;
unsigned long flags ;
int ch , irq = d - > irq ;
2011-07-21 04:19:59 +04:00
ch = irq - chip - > irq_base ;
2020-04-14 20:48:59 +03:00
if ( irq < chip - > irq_base + 8 ) {
2011-07-21 04:19:59 +04:00
im_reg = & chip - > reg - > im0 ;
2020-04-14 20:48:59 +03:00
im_pos = ch - 0 ;
2011-07-21 04:19:59 +04:00
} else {
im_reg = & chip - > reg - > im1 ;
im_pos = ch - 8 ;
}
2018-12-07 18:33:07 +03:00
dev_dbg ( chip - > dev , " irq=%d type=%d ch=%d pos=%d \n " , irq , type , ch , im_pos ) ;
2011-07-21 04:19:59 +04:00
switch ( type ) {
case IRQ_TYPE_EDGE_RISING :
val = PCH_EDGE_RISING ;
break ;
case IRQ_TYPE_EDGE_FALLING :
val = PCH_EDGE_FALLING ;
break ;
case IRQ_TYPE_EDGE_BOTH :
val = PCH_EDGE_BOTH ;
break ;
case IRQ_TYPE_LEVEL_HIGH :
val = PCH_LEVEL_H ;
break ;
case IRQ_TYPE_LEVEL_LOW :
val = PCH_LEVEL_L ;
break ;
default :
2020-04-14 20:48:59 +03:00
return 0 ;
2011-07-21 04:19:59 +04:00
}
2020-04-14 20:48:59 +03:00
spin_lock_irqsave ( & chip - > spinlock , flags ) ;
2011-07-21 04:19:59 +04:00
/* Set interrupt mode */
im = ioread32 ( im_reg ) & ~ ( PCH_IM_MASK < < ( im_pos * 4 ) ) ;
iowrite32 ( im | ( val < < ( im_pos * 4 ) ) , im_reg ) ;
2012-04-28 12:13:45 +04:00
/* And the handler */
2020-04-14 20:49:00 +03:00
if ( type & IRQ_TYPE_LEVEL_MASK )
2015-06-23 16:52:40 +03:00
irq_set_handler_locked ( d , handle_level_irq ) ;
2020-04-14 20:49:00 +03:00
else if ( type & IRQ_TYPE_EDGE_BOTH )
2015-06-23 16:52:40 +03:00
irq_set_handler_locked ( d , handle_edge_irq ) ;
2011-07-21 04:19:59 +04:00
spin_unlock_irqrestore ( & chip - > spinlock , flags ) ;
return 0 ;
}
static void pch_irq_unmask ( struct irq_data * d )
{
struct irq_chip_generic * gc = irq_data_get_irq_chip_data ( d ) ;
struct pch_gpio * chip = gc - > private ;
2020-04-14 20:48:57 +03:00
iowrite32 ( BIT ( d - > irq - chip - > irq_base ) , & chip - > reg - > imaskclr ) ;
2011-07-21 04:19:59 +04:00
}
static void pch_irq_mask ( struct irq_data * d )
{
struct irq_chip_generic * gc = irq_data_get_irq_chip_data ( d ) ;
struct pch_gpio * chip = gc - > private ;
2020-04-14 20:48:57 +03:00
iowrite32 ( BIT ( d - > irq - chip - > irq_base ) , & chip - > reg - > imask ) ;
2011-07-21 04:19:59 +04:00
}
2012-04-28 12:13:45 +04:00
static void pch_irq_ack ( struct irq_data * d )
{
struct irq_chip_generic * gc = irq_data_get_irq_chip_data ( d ) ;
struct pch_gpio * chip = gc - > private ;
2020-04-14 20:48:57 +03:00
iowrite32 ( BIT ( d - > irq - chip - > irq_base ) , & chip - > reg - > iclr ) ;
2012-04-28 12:13:45 +04:00
}
2011-07-21 04:19:59 +04:00
static irqreturn_t pch_gpio_handler ( int irq , void * dev_id )
{
struct pch_gpio * chip = dev_id ;
2018-11-06 15:38:55 +03:00
unsigned long reg_val = ioread32 ( & chip - > reg - > istatus ) ;
2020-04-14 20:48:58 +03:00
int i ;
2011-07-21 04:19:59 +04:00
2020-07-01 18:20:46 +03:00
dev_vdbg ( chip - > dev , " irq=%d status=0x%lx \n " , irq , reg_val ) ;
2020-04-14 20:48:58 +03:00
reg_val & = BIT ( gpio_pins [ chip - > ioh ] ) - 1 ;
2020-07-01 18:20:46 +03:00
2020-04-14 20:48:58 +03:00
for_each_set_bit ( i , & reg_val , gpio_pins [ chip - > ioh ] )
2018-11-06 15:38:55 +03:00
generic_handle_irq ( chip - > irq_base + i ) ;
2020-04-14 20:48:58 +03:00
return IRQ_RETVAL ( reg_val ) ;
2011-07-21 04:19:59 +04:00
}
2017-05-25 11:37:36 +03:00
static int pch_gpio_alloc_generic_chip ( struct pch_gpio * chip ,
unsigned int irq_start ,
unsigned int num )
2011-07-21 04:19:59 +04:00
{
struct irq_chip_generic * gc ;
struct irq_chip_type * ct ;
2017-08-09 15:25:05 +03:00
int rv ;
2011-07-21 04:19:59 +04:00
2017-08-09 15:25:05 +03:00
gc = devm_irq_alloc_generic_chip ( chip - > dev , " pch_gpio " , 1 , irq_start ,
chip - > base , handle_simple_irq ) ;
2017-05-25 11:37:36 +03:00
if ( ! gc )
return - ENOMEM ;
2011-07-21 04:19:59 +04:00
gc - > private = chip ;
ct = gc - > chip_types ;
2012-04-28 12:13:45 +04:00
ct - > chip . irq_ack = pch_irq_ack ;
2011-07-21 04:19:59 +04:00
ct - > chip . irq_mask = pch_irq_mask ;
ct - > chip . irq_unmask = pch_irq_unmask ;
ct - > chip . irq_set_type = pch_irq_type ;
2017-08-09 15:25:05 +03:00
rv = devm_irq_setup_generic_chip ( chip - > dev , gc , IRQ_MSK ( num ) ,
IRQ_GC_INIT_MASK_CACHE ,
IRQ_NOREQUEST | IRQ_NOPROBE , 0 ) ;
2017-05-25 11:37:36 +03:00
2017-08-09 15:25:05 +03:00
return rv ;
2010-10-28 02:33:21 +04:00
}
2012-11-19 22:22:34 +04:00
static int pch_gpio_probe ( struct pci_dev * pdev ,
2010-10-28 02:33:21 +04:00
const struct pci_device_id * id )
{
s32 ret ;
struct pch_gpio * chip ;
2011-07-21 04:19:59 +04:00
int irq_base ;
2010-10-28 02:33:21 +04:00
2018-11-07 22:18:04 +03:00
chip = devm_kzalloc ( & pdev - > dev , sizeof ( * chip ) , GFP_KERNEL ) ;
2010-10-28 02:33:21 +04:00
if ( chip = = NULL )
return - ENOMEM ;
chip - > dev = & pdev - > dev ;
2018-11-07 22:18:04 +03:00
ret = pcim_enable_device ( pdev ) ;
2010-10-28 02:33:21 +04:00
if ( ret ) {
2018-12-07 18:33:07 +03:00
dev_err ( & pdev - > dev , " pci_enable_device FAILED " ) ;
2018-11-07 22:18:04 +03:00
return ret ;
2010-10-28 02:33:21 +04:00
}
2020-04-14 20:48:57 +03:00
ret = pcim_iomap_regions ( pdev , BIT ( 1 ) , KBUILD_MODNAME ) ;
2010-10-28 02:33:21 +04:00
if ( ret ) {
dev_err ( & pdev - > dev , " pci_request_regions FAILED-%d " , ret ) ;
2018-11-07 22:18:04 +03:00
return ret ;
2010-10-28 02:33:21 +04:00
}
2018-11-07 22:18:04 +03:00
chip - > base = pcim_iomap_table ( pdev ) [ 1 ] ;
2010-10-28 02:33:21 +04:00
2011-07-21 04:19:57 +04:00
if ( pdev - > device = = 0x8803 )
chip - > ioh = INTEL_EG20T_PCH ;
else if ( pdev - > device = = 0x8014 )
chip - > ioh = OKISEMI_ML7223m_IOH ;
else if ( pdev - > device = = 0x8043 )
chip - > ioh = OKISEMI_ML7223n_IOH ;
2010-10-28 02:33:21 +04:00
chip - > reg = chip - > base ;
pci_set_drvdata ( pdev , chip ) ;
2012-02-01 06:51:53 +04:00
spin_lock_init ( & chip - > spinlock ) ;
2010-10-28 02:33:21 +04:00
pch_gpio_setup ( chip ) ;
2018-11-07 22:29:53 +03:00
2018-11-07 22:18:04 +03:00
ret = devm_gpiochip_add_data ( & pdev - > dev , & chip - > gpio , chip ) ;
2010-10-28 02:33:21 +04:00
if ( ret ) {
dev_err ( & pdev - > dev , " PCH gpio: Failed to register GPIO \n " ) ;
2018-11-07 22:18:04 +03:00
return ret ;
2010-10-28 02:33:21 +04:00
}
2017-03-04 19:23:32 +03:00
irq_base = devm_irq_alloc_descs ( & pdev - > dev , - 1 , 0 ,
gpio_pins [ chip - > ioh ] , NUMA_NO_NODE ) ;
2011-07-21 04:19:59 +04:00
if ( irq_base < 0 ) {
dev_warn ( & pdev - > dev , " PCH gpio: Failed to get IRQ base num \n " ) ;
chip - > irq_base = - 1 ;
2018-11-07 22:18:04 +03:00
return 0 ;
2011-07-21 04:19:59 +04:00
}
chip - > irq_base = irq_base ;
2012-04-28 12:13:45 +04:00
/* Mask all interrupts, but enable them */
2020-04-14 20:48:57 +03:00
iowrite32 ( BIT ( gpio_pins [ chip - > ioh ] ) - 1 , & chip - > reg - > imask ) ;
iowrite32 ( BIT ( gpio_pins [ chip - > ioh ] ) - 1 , & chip - > reg - > ien ) ;
2012-04-28 12:13:45 +04:00
2017-03-04 19:23:32 +03:00
ret = devm_request_irq ( & pdev - > dev , pdev - > irq , pch_gpio_handler ,
IRQF_SHARED , KBUILD_MODNAME , chip ) ;
2018-11-07 22:18:04 +03:00
if ( ret ) {
2018-12-07 18:33:07 +03:00
dev_err ( & pdev - > dev , " request_irq failed \n " ) ;
2018-11-07 22:18:04 +03:00
return ret ;
2011-07-21 04:19:59 +04:00
}
2018-11-07 22:18:04 +03:00
return pch_gpio_alloc_generic_chip ( chip , irq_base , gpio_pins [ chip - > ioh ] ) ;
2010-10-28 02:33:21 +04:00
}
2018-11-07 22:19:45 +03:00
static int __maybe_unused pch_gpio_suspend ( struct device * dev )
2010-10-28 02:33:21 +04:00
{
2019-07-23 11:39:24 +03:00
struct pch_gpio * chip = dev_get_drvdata ( dev ) ;
2011-07-21 04:19:55 +04:00
unsigned long flags ;
2010-10-28 02:33:21 +04:00
2011-07-21 04:19:55 +04:00
spin_lock_irqsave ( & chip - > spinlock , flags ) ;
2010-10-28 02:33:21 +04:00
pch_gpio_save_reg_conf ( chip ) ;
2011-07-21 04:19:55 +04:00
spin_unlock_irqrestore ( & chip - > spinlock , flags ) ;
2010-10-28 02:33:21 +04:00
return 0 ;
}
2018-11-07 22:19:45 +03:00
static int __maybe_unused pch_gpio_resume ( struct device * dev )
2010-10-28 02:33:21 +04:00
{
2019-07-23 11:39:24 +03:00
struct pch_gpio * chip = dev_get_drvdata ( dev ) ;
2011-07-21 04:19:55 +04:00
unsigned long flags ;
2010-10-28 02:33:21 +04:00
2011-07-21 04:19:55 +04:00
spin_lock_irqsave ( & chip - > spinlock , flags ) ;
2010-10-28 02:33:21 +04:00
iowrite32 ( 0x01 , & chip - > reg - > reset ) ;
iowrite32 ( 0x00 , & chip - > reg - > reset ) ;
pch_gpio_restore_reg_conf ( chip ) ;
2011-07-21 04:19:55 +04:00
spin_unlock_irqrestore ( & chip - > spinlock , flags ) ;
2010-10-28 02:33:21 +04:00
return 0 ;
}
2018-11-07 22:19:45 +03:00
static SIMPLE_DEV_PM_OPS ( pch_gpio_pm_ops , pch_gpio_suspend , pch_gpio_resume ) ;
2010-10-28 02:33:21 +04:00
2013-12-03 03:08:45 +04:00
static const struct pci_device_id pch_gpio_pcidev_id [ ] = {
2010-10-28 02:33:21 +04:00
{ PCI_DEVICE ( PCI_VENDOR_ID_INTEL , 0x8803 ) } ,
2011-05-09 14:58:49 +04:00
{ PCI_DEVICE ( PCI_VENDOR_ID_ROHM , 0x8014 ) } ,
2011-07-21 04:19:56 +04:00
{ PCI_DEVICE ( PCI_VENDOR_ID_ROHM , 0x8043 ) } ,
2011-10-28 04:23:32 +04:00
{ PCI_DEVICE ( PCI_VENDOR_ID_ROHM , 0x8803 ) } ,
2010-10-28 02:33:21 +04:00
{ 0 , }
} ;
2011-03-12 01:58:30 +03:00
MODULE_DEVICE_TABLE ( pci , pch_gpio_pcidev_id ) ;
2010-10-28 02:33:21 +04:00
static struct pci_driver pch_gpio_driver = {
. name = " pch_gpio " ,
. id_table = pch_gpio_pcidev_id ,
. probe = pch_gpio_probe ,
2018-11-07 22:19:45 +03:00
. driver = {
. pm = & pch_gpio_pm_ops ,
} ,
2010-10-28 02:33:21 +04:00
} ;
2012-04-06 16:13:30 +04:00
module_pci_driver ( pch_gpio_driver ) ;
2010-10-28 02:33:21 +04:00
MODULE_DESCRIPTION ( " PCH GPIO PCI Driver " ) ;
2018-11-06 15:11:42 +03:00
MODULE_LICENSE ( " GPL v2 " ) ;