2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2008-04-05 00:55:41 +09:00
/*
* A gpio chip driver for TXx9 SoCs
*
* Copyright ( C ) 2008 Atsushi Nemoto < anemo @ mba . ocn . ne . jp >
*/
# include <linux/init.h>
# include <linux/spinlock.h>
2015-12-08 14:33:54 +01:00
# include <linux/gpio/driver.h>
2008-04-05 00:55:41 +09:00
# include <linux/errno.h>
# include <linux/io.h>
# include <asm/txx9pio.h>
static DEFINE_SPINLOCK ( txx9_gpio_lock ) ;
static struct txx9_pio_reg __iomem * txx9_pioptr ;
static int txx9_gpio_get ( struct gpio_chip * chip , unsigned int offset )
{
2015-12-22 15:41:01 +01:00
return ! ! ( __raw_readl ( & txx9_pioptr - > din ) & ( 1 < < offset ) ) ;
2008-04-05 00:55:41 +09:00
}
static void txx9_gpio_set_raw ( unsigned int offset , int value )
{
u32 val ;
val = __raw_readl ( & txx9_pioptr - > dout ) ;
if ( value )
val | = 1 < < offset ;
else
val & = ~ ( 1 < < offset ) ;
__raw_writel ( val , & txx9_pioptr - > dout ) ;
}
static void txx9_gpio_set ( struct gpio_chip * chip , unsigned int offset ,
int value )
{
unsigned long flags ;
spin_lock_irqsave ( & txx9_gpio_lock , flags ) ;
txx9_gpio_set_raw ( offset , value ) ;
mmiowb ( ) ;
spin_unlock_irqrestore ( & txx9_gpio_lock , flags ) ;
}
static int txx9_gpio_dir_in ( struct gpio_chip * chip , unsigned int offset )
{
2008-07-10 01:02:08 +09:00
unsigned long flags ;
spin_lock_irqsave ( & txx9_gpio_lock , flags ) ;
2008-04-05 00:55:41 +09:00
__raw_writel ( __raw_readl ( & txx9_pioptr - > dir ) & ~ ( 1 < < offset ) ,
& txx9_pioptr - > dir ) ;
mmiowb ( ) ;
2008-07-10 01:02:08 +09:00
spin_unlock_irqrestore ( & txx9_gpio_lock , flags ) ;
2008-04-05 00:55:41 +09:00
return 0 ;
}
static int txx9_gpio_dir_out ( struct gpio_chip * chip , unsigned int offset ,
int value )
{
2008-07-10 01:02:08 +09:00
unsigned long flags ;
spin_lock_irqsave ( & txx9_gpio_lock , flags ) ;
2008-04-05 00:55:41 +09:00
txx9_gpio_set_raw ( offset , value ) ;
__raw_writel ( __raw_readl ( & txx9_pioptr - > dir ) | ( 1 < < offset ) ,
& txx9_pioptr - > dir ) ;
mmiowb ( ) ;
2008-07-10 01:02:08 +09:00
spin_unlock_irqrestore ( & txx9_gpio_lock , flags ) ;
2008-04-05 00:55:41 +09:00
return 0 ;
}
static struct gpio_chip txx9_gpio_chip = {
. get = txx9_gpio_get ,
. set = txx9_gpio_set ,
. direction_input = txx9_gpio_dir_in ,
. direction_output = txx9_gpio_dir_out ,
. label = " TXx9 " ,
} ;
int __init txx9_gpio_init ( unsigned long baseaddr ,
unsigned int base , unsigned int num )
{
txx9_pioptr = ioremap ( baseaddr , sizeof ( struct txx9_pio_reg ) ) ;
if ( ! txx9_pioptr )
return - ENODEV ;
txx9_gpio_chip . base = base ;
txx9_gpio_chip . ngpio = num ;
2015-12-08 14:33:54 +01:00
return gpiochip_add_data ( & txx9_gpio_chip , NULL ) ;
2008-04-05 00:55:41 +09:00
}