2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2007-07-10 16:03:43 +04:00
/*
* TI DaVinci GPIO Support
*
2008-09-08 10:41:04 +04:00
* Copyright ( c ) 2006 - 2007 David Brownell
2007-07-10 16:03:43 +04:00
* Copyright ( c ) 2007 , MontaVista Software , Inc . < source @ mvista . com >
*/
2018-08-31 22:13:26 +03:00
2018-01-14 04:05:38 +03:00
# include <linux/gpio/driver.h>
2007-07-10 16:03:43 +04:00
# include <linux/errno.h>
# include <linux/kernel.h>
# include <linux/clk.h>
# include <linux/err.h>
# include <linux/io.h>
2013-08-18 09:18:58 +04:00
# include <linux/irq.h>
2013-11-21 22:15:27 +04:00
# include <linux/irqdomain.h>
2013-11-21 22:15:29 +04:00
# include <linux/module.h>
# include <linux/of.h>
# include <linux/of_device.h>
2018-01-22 02:09:40 +03:00
# include <linux/pinctrl/consumer.h>
2013-08-18 09:18:58 +04:00
# include <linux/platform_device.h>
# include <linux/platform_data/gpio-davinci.h>
2013-11-26 23:40:09 +04:00
# include <linux/irqchip/chained_irq.h>
2018-08-31 22:13:26 +03:00
# include <linux/spinlock.h>
2022-06-13 08:43:10 +03:00
# include <linux/pm_runtime.h>
2018-08-31 22:13:26 +03:00
# include <asm-generic/gpio.h>
# define MAX_REGS_BANKS 5
# define MAX_INT_PER_BANK 32
2007-07-10 16:03:43 +04:00
2010-05-02 02:37:53 +04:00
struct davinci_gpio_regs {
u32 dir ;
u32 out_data ;
u32 set_data ;
u32 clr_data ;
u32 in_data ;
u32 set_rising ;
u32 clr_rising ;
u32 set_falling ;
u32 clr_falling ;
u32 intstat ;
} ;
2014-02-13 19:58:45 +04:00
typedef struct irq_chip * ( * gpio_get_irq_chip_cb_t ) ( unsigned int irq ) ;
2013-08-18 09:18:57 +04:00
# define BINTEN 0x8 /* GPIO Interrupt Per-Bank Enable Register */
2010-05-08 01:06:32 +04:00
static void __iomem * gpio_base ;
2017-01-17 19:19:11 +03:00
static unsigned int offset_array [ 5 ] = { 0x10 , 0x38 , 0x60 , 0x88 , 0xb0 } ;
2007-07-10 16:03:43 +04:00
2018-08-31 22:13:26 +03:00
struct davinci_gpio_irq_data {
void __iomem * regs ;
struct davinci_gpio_controller * chip ;
int bank_num ;
} ;
struct davinci_gpio_controller {
struct gpio_chip chip ;
struct irq_domain * irq_domain ;
/* Serialize access to GPIO registers */
spinlock_t lock ;
void __iomem * regs [ MAX_REGS_BANKS ] ;
int gpio_unbanked ;
int irqs [ MAX_INT_PER_BANK ] ;
2022-06-13 08:43:10 +03:00
struct davinci_gpio_regs context [ MAX_REGS_BANKS ] ;
u32 binten_context ;
2018-08-31 22:13:26 +03:00
} ;
static inline u32 __gpio_mask ( unsigned gpio )
{
return 1 < < ( gpio % 32 ) ;
}
2015-07-13 02:18:56 +03:00
static inline struct davinci_gpio_regs __iomem * irq2regs ( struct irq_data * d )
2010-02-26 03:49:56 +03:00
{
2010-05-02 02:37:52 +04:00
struct davinci_gpio_regs __iomem * g ;
2010-02-26 03:49:56 +03:00
2015-07-13 02:18:56 +03:00
g = ( __force struct davinci_gpio_regs __iomem * ) irq_data_get_irq_chip_data ( d ) ;
2010-02-26 03:49:56 +03:00
return g ;
}
2018-06-13 06:40:37 +03:00
static int davinci_gpio_irq_setup ( struct platform_device * pdev ) ;
2008-09-08 10:41:04 +04:00
/*--------------------------------------------------------------------------*/
2010-05-02 02:38:27 +04:00
/* board setup code *MUST* setup pinmux and enable the GPIO clock. */
2010-05-02 02:37:51 +04:00
static inline int __davinci_direction ( struct gpio_chip * chip ,
unsigned offset , bool out , int value )
2007-07-10 16:03:43 +04:00
{
2015-12-04 18:25:04 +03:00
struct davinci_gpio_controller * d = gpiochip_get_data ( chip ) ;
2017-01-13 07:20:12 +03:00
struct davinci_gpio_regs __iomem * g ;
2010-05-02 02:37:55 +04:00
unsigned long flags ;
2008-09-08 10:41:04 +04:00
u32 temp ;
2017-01-13 07:20:12 +03:00
int bank = offset / 32 ;
u32 mask = __gpio_mask ( offset ) ;
2007-07-10 16:03:43 +04:00
2017-01-13 07:20:12 +03:00
g = d - > regs [ bank ] ;
2010-05-02 02:37:55 +04:00
spin_lock_irqsave ( & d - > lock , flags ) ;
2013-12-11 21:52:07 +04:00
temp = readl_relaxed ( & g - > dir ) ;
2010-05-02 02:37:51 +04:00
if ( out ) {
temp & = ~ mask ;
2013-12-11 21:52:07 +04:00
writel_relaxed ( mask , value ? & g - > set_data : & g - > clr_data ) ;
2010-05-02 02:37:51 +04:00
} else {
temp | = mask ;
}
2013-12-11 21:52:07 +04:00
writel_relaxed ( temp , & g - > dir ) ;
2010-05-02 02:37:55 +04:00
spin_unlock_irqrestore ( & d - > lock , flags ) ;
2007-07-10 16:03:43 +04:00
2008-09-08 10:41:04 +04:00
return 0 ;
}
2007-07-10 16:03:43 +04:00
2010-05-02 02:37:51 +04:00
static int davinci_direction_in ( struct gpio_chip * chip , unsigned offset )
{
return __davinci_direction ( chip , offset , false , 0 ) ;
}
static int
davinci_direction_out ( struct gpio_chip * chip , unsigned offset , int value )
{
return __davinci_direction ( chip , offset , true , value ) ;
}
2007-07-10 16:03:43 +04:00
/*
* Read the pin ' s value ( works even if it ' s set up as output ) ;
* returns zero / nonzero .
*
* Note that changes are synched to the GPIO clock , so reading values back
* right after you ' ve set them may give old values .
*/
2008-09-08 10:41:04 +04:00
static int davinci_gpio_get ( struct gpio_chip * chip , unsigned offset )
2007-07-10 16:03:43 +04:00
{
2015-12-04 18:25:04 +03:00
struct davinci_gpio_controller * d = gpiochip_get_data ( chip ) ;
2017-01-13 07:20:12 +03:00
struct davinci_gpio_regs __iomem * g ;
int bank = offset / 32 ;
2007-07-10 16:03:43 +04:00
2017-01-13 07:20:12 +03:00
g = d - > regs [ bank ] ;
return ! ! ( __gpio_mask ( offset ) & readl_relaxed ( & g - > in_data ) ) ;
2007-07-10 16:03:43 +04:00
}
2008-09-08 10:41:04 +04:00
/*
* Assuming the pin is muxed as a gpio output , set its output value .
*/
static void
davinci_gpio_set ( struct gpio_chip * chip , unsigned offset , int value )
2007-07-10 16:03:43 +04:00
{
2015-12-04 18:25:04 +03:00
struct davinci_gpio_controller * d = gpiochip_get_data ( chip ) ;
2017-01-13 07:20:12 +03:00
struct davinci_gpio_regs __iomem * g ;
int bank = offset / 32 ;
2007-07-10 16:03:43 +04:00
2017-01-13 07:20:12 +03:00
g = d - > regs [ bank ] ;
writel_relaxed ( __gpio_mask ( offset ) ,
value ? & g - > set_data : & g - > clr_data ) ;
2008-09-08 10:41:04 +04:00
}
2013-11-21 22:15:29 +04:00
static struct davinci_gpio_platform_data *
davinci_gpio_get_pdata ( struct platform_device * pdev )
{
struct device_node * dn = pdev - > dev . of_node ;
struct davinci_gpio_platform_data * pdata ;
int ret ;
u32 val ;
if ( ! IS_ENABLED ( CONFIG_OF ) | | ! pdev - > dev . of_node )
2015-11-23 18:23:18 +03:00
return dev_get_platdata ( & pdev - > dev ) ;
2013-11-21 22:15:29 +04:00
pdata = devm_kzalloc ( & pdev - > dev , sizeof ( * pdata ) , GFP_KERNEL ) ;
if ( ! pdata )
return NULL ;
ret = of_property_read_u32 ( dn , " ti,ngpio " , & val ) ;
if ( ret )
goto of_err ;
pdata - > ngpio = val ;
ret = of_property_read_u32 ( dn , " ti,davinci-gpio-unbanked " , & val ) ;
if ( ret )
goto of_err ;
pdata - > gpio_unbanked = val ;
return pdata ;
of_err :
dev_err ( & pdev - > dev , " Populating pdata from DT failed: err %d \n " , ret ) ;
return NULL ;
}
2013-08-18 09:18:58 +04:00
static int davinci_gpio_probe ( struct platform_device * pdev )
2008-09-08 10:41:04 +04:00
{
2018-08-31 22:13:24 +03:00
int bank , i , ret = 0 ;
2018-06-13 06:40:37 +03:00
unsigned int ngpio , nbank , nirq ;
2013-08-18 09:18:58 +04:00
struct davinci_gpio_controller * chips ;
struct davinci_gpio_platform_data * pdata ;
struct device * dev = & pdev - > dev ;
2013-11-21 22:15:29 +04:00
pdata = davinci_gpio_get_pdata ( pdev ) ;
2013-08-18 09:18:58 +04:00
if ( ! pdata ) {
dev_err ( dev , " No platform data found \n " ) ;
return - EINVAL ;
}
2010-05-02 02:37:54 +04:00
2013-11-21 22:15:29 +04:00
dev - > platform_data = pdata ;
2009-04-15 23:40:35 +04:00
/*
* The gpio banks conceptually expose a segmented bitmap ,
2008-12-07 22:46:23 +03:00
* and " ngpio " is one more than the largest zero - based
* bit index that ' s valid .
*/
2013-08-18 09:18:58 +04:00
ngpio = pdata - > ngpio ;
2009-04-15 23:40:35 +04:00
if ( ngpio = = 0 ) {
2013-08-18 09:18:58 +04:00
dev_err ( dev , " How many GPIOs? \n " ) ;
2008-12-07 22:46:23 +03:00
return - EINVAL ;
}
2018-06-13 06:40:37 +03:00
/*
* If there are unbanked interrupts then the number of
* interrupts is equal to number of gpios else all are banked so
* number of interrupts is equal to number of banks ( each with 16 gpios )
*/
if ( pdata - > gpio_unbanked )
nirq = pdata - > gpio_unbanked ;
else
nirq = DIV_ROUND_UP ( ngpio , 16 ) ;
2018-08-31 22:13:24 +03:00
chips = devm_kzalloc ( dev , sizeof ( * chips ) , GFP_KERNEL ) ;
2014-04-29 12:33:26 +04:00
if ( ! chips )
2010-05-08 01:06:32 +04:00
return - ENOMEM ;
2013-08-18 09:18:58 +04:00
2019-02-20 14:12:40 +03:00
gpio_base = devm_platform_ioremap_resource ( pdev , 0 ) ;
2013-08-18 09:18:58 +04:00
if ( IS_ERR ( gpio_base ) )
return PTR_ERR ( gpio_base ) ;
2010-05-08 01:06:32 +04:00
2018-06-13 06:40:37 +03:00
for ( i = 0 ; i < nirq ; i + + ) {
chips - > irqs [ i ] = platform_get_irq ( pdev , i ) ;
2020-08-27 23:08:23 +03:00
if ( chips - > irqs [ i ] < 0 )
return dev_err_probe ( dev , chips - > irqs [ i ] , " IRQ not populated \n " ) ;
2018-06-13 06:40:36 +03:00
}
2018-08-31 22:13:23 +03:00
chips - > chip . label = dev_name ( dev ) ;
2008-09-08 10:41:04 +04:00
2017-01-13 07:20:12 +03:00
chips - > chip . direction_input = davinci_direction_in ;
chips - > chip . get = davinci_gpio_get ;
chips - > chip . direction_output = davinci_direction_out ;
chips - > chip . set = davinci_gpio_set ;
2008-09-08 10:41:04 +04:00
2017-01-13 07:20:12 +03:00
chips - > chip . ngpio = ngpio ;
2018-11-21 12:35:17 +03:00
chips - > chip . base = pdata - > no_auto_base ? pdata - > base : - 1 ;
2008-09-08 10:41:04 +04:00
2013-11-21 22:15:29 +04:00
# ifdef CONFIG_OF_GPIO
2017-01-13 07:20:12 +03:00
chips - > chip . of_gpio_n_cells = 2 ;
chips - > chip . parent = dev ;
2020-04-01 23:05:26 +03:00
chips - > chip . request = gpiochip_generic_request ;
chips - > chip . free = gpiochip_generic_free ;
2013-11-21 22:15:29 +04:00
# endif
2017-01-13 07:20:12 +03:00
spin_lock_init ( & chips - > lock ) ;
2008-09-08 10:41:04 +04:00
2018-08-31 22:13:24 +03:00
nbank = DIV_ROUND_UP ( ngpio , 32 ) ;
for ( bank = 0 ; bank < nbank ; bank + + )
2017-01-13 07:20:12 +03:00
chips - > regs [ bank ] = gpio_base + offset_array [ bank ] ;
2007-07-10 16:03:43 +04:00
2017-07-20 12:42:16 +03:00
ret = devm_gpiochip_add_data ( dev , & chips - > chip , chips ) ;
if ( ret )
2018-08-31 22:13:23 +03:00
return ret ;
2017-07-20 12:42:16 +03:00
2013-08-18 09:18:58 +04:00
platform_set_drvdata ( pdev , chips ) ;
2018-06-13 06:40:37 +03:00
ret = davinci_gpio_irq_setup ( pdev ) ;
2017-07-20 12:42:17 +03:00
if ( ret )
2018-08-31 22:13:23 +03:00
return ret ;
2017-07-20 12:42:17 +03:00
2007-07-10 16:03:43 +04:00
return 0 ;
}
2008-09-08 10:41:04 +04:00
/*--------------------------------------------------------------------------*/
2007-07-10 16:03:43 +04:00
/*
* We expect irqs will normally be set up as input pins , but they can also be
* used as output pins . . . which is convenient for testing .
*
2008-12-07 22:46:23 +03:00
* NOTE : The first few GPIOs also have direct INTC hookups in addition
2009-06-26 04:01:31 +04:00
* to their GPIOBNK0 irq , with a bit less overhead .
2007-07-10 16:03:43 +04:00
*
2008-12-07 22:46:23 +03:00
* All those INTC hookups ( direct , plus several IRQ banks ) can also
2007-07-10 16:03:43 +04:00
* serve as EDMA event triggers .
*/
2010-11-29 12:27:27 +03:00
static void gpio_irq_disable ( struct irq_data * d )
2007-07-10 16:03:43 +04:00
{
2015-07-13 02:18:56 +03:00
struct davinci_gpio_regs __iomem * g = irq2regs ( d ) ;
2019-06-05 11:02:57 +03:00
uintptr_t mask = ( uintptr_t ) irq_data_get_irq_handler_data ( d ) ;
2007-07-10 16:03:43 +04:00
2013-12-11 21:52:07 +04:00
writel_relaxed ( mask , & g - > clr_falling ) ;
writel_relaxed ( mask , & g - > clr_rising ) ;
2007-07-10 16:03:43 +04:00
}
2010-11-29 12:27:27 +03:00
static void gpio_irq_enable ( struct irq_data * d )
2007-07-10 16:03:43 +04:00
{
2015-07-13 02:18:56 +03:00
struct davinci_gpio_regs __iomem * g = irq2regs ( d ) ;
2019-06-05 11:02:57 +03:00
uintptr_t mask = ( uintptr_t ) irq_data_get_irq_handler_data ( d ) ;
2011-03-24 14:47:04 +03:00
unsigned status = irqd_get_trigger_type ( d ) ;
2007-07-10 16:03:43 +04:00
2009-05-05 00:14:27 +04:00
status & = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING ;
if ( ! status )
status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING ;
if ( status & IRQ_TYPE_EDGE_FALLING )
2013-12-11 21:52:07 +04:00
writel_relaxed ( mask , & g - > set_falling ) ;
2009-05-05 00:14:27 +04:00
if ( status & IRQ_TYPE_EDGE_RISING )
2013-12-11 21:52:07 +04:00
writel_relaxed ( mask , & g - > set_rising ) ;
2007-07-10 16:03:43 +04:00
}
2010-11-29 12:27:27 +03:00
static int gpio_irq_type ( struct irq_data * d , unsigned trigger )
2007-07-10 16:03:43 +04:00
{
if ( trigger & ~ ( IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING ) )
return - EINVAL ;
return 0 ;
}
static struct irq_chip gpio_irqchip = {
. name = " GPIO " ,
2010-11-29 12:27:27 +03:00
. irq_enable = gpio_irq_enable ,
. irq_disable = gpio_irq_disable ,
. irq_set_type = gpio_irq_type ,
2011-03-24 14:47:04 +03:00
. flags = IRQCHIP_SET_TYPE_MASKED ,
2007-07-10 16:03:43 +04:00
} ;
2015-09-14 11:42:37 +03:00
static void gpio_irq_handler ( struct irq_desc * desc )
2007-07-10 16:03:43 +04:00
{
2011-06-06 13:51:43 +04:00
struct davinci_gpio_regs __iomem * g ;
2007-07-10 16:03:43 +04:00
u32 mask = 0xffff ;
2017-01-13 07:20:12 +03:00
int bank_num ;
2011-07-12 01:03:11 +04:00
struct davinci_gpio_controller * d ;
2017-01-13 07:20:12 +03:00
struct davinci_gpio_irq_data * irqdata ;
2007-07-10 16:03:43 +04:00
2017-01-13 07:20:12 +03:00
irqdata = ( struct davinci_gpio_irq_data * ) irq_desc_get_handler_data ( desc ) ;
bank_num = irqdata - > bank_num ;
g = irqdata - > regs ;
d = irqdata - > chip ;
2011-06-06 13:51:43 +04:00
2007-07-10 16:03:43 +04:00
/* we only care about one bank */
2017-01-13 07:20:12 +03:00
if ( ( bank_num % 2 ) = = 1 )
2007-07-10 16:03:43 +04:00
mask < < = 16 ;
/* temporarily mask (level sensitive) parent IRQ */
2013-11-26 23:40:09 +04:00
chained_irq_enter ( irq_desc_get_chip ( desc ) , desc ) ;
2007-07-10 16:03:43 +04:00
while ( 1 ) {
u32 status ;
2013-11-21 22:15:27 +04:00
int bit ;
2017-01-13 07:20:12 +03:00
irq_hw_number_t hw_irq ;
2007-07-10 16:03:43 +04:00
/* ack any irqs */
2013-12-11 21:52:07 +04:00
status = readl_relaxed ( & g - > intstat ) & mask ;
2007-07-10 16:03:43 +04:00
if ( ! status )
break ;
2013-12-11 21:52:07 +04:00
writel_relaxed ( status , & g - > intstat ) ;
2007-07-10 16:03:43 +04:00
/* now demux them to the right lowlevel handler */
2011-07-12 01:03:11 +04:00
2007-07-10 16:03:43 +04:00
while ( status ) {
2013-11-21 22:15:27 +04:00
bit = __ffs ( status ) ;
status & = ~ BIT ( bit ) ;
2017-01-13 07:20:12 +03:00
/* Max number of gpios per controller is 144 so
* hw_irq will be in [ 0. .143 ]
*/
hw_irq = ( bank_num / 2 ) * 32 + bit ;
2021-05-04 19:42:18 +03:00
generic_handle_domain_irq ( d - > irq_domain , hw_irq ) ;
2007-07-10 16:03:43 +04:00
}
}
2013-11-26 23:40:09 +04:00
chained_irq_exit ( irq_desc_get_chip ( desc ) , desc ) ;
2007-07-10 16:03:43 +04:00
/* now it may re-trigger */
}
2009-06-26 04:01:31 +04:00
static int gpio_to_irq_banked ( struct gpio_chip * chip , unsigned offset )
{
2015-12-04 18:25:04 +03:00
struct davinci_gpio_controller * d = gpiochip_get_data ( chip ) ;
2009-06-26 04:01:31 +04:00
2013-12-18 14:07:51 +04:00
if ( d - > irq_domain )
2017-01-13 07:20:12 +03:00
return irq_create_mapping ( d - > irq_domain , offset ) ;
2013-12-18 14:07:51 +04:00
else
return - ENXIO ;
2009-06-26 04:01:31 +04:00
}
static int gpio_to_irq_unbanked ( struct gpio_chip * chip , unsigned offset )
{
2015-12-04 18:25:04 +03:00
struct davinci_gpio_controller * d = gpiochip_get_data ( chip ) ;
2009-06-26 04:01:31 +04:00
2013-08-18 09:18:57 +04:00
/*
* NOTE : we assume for now that only irqs in the first gpio_chip
2009-06-26 04:01:31 +04:00
* can provide direct - mapped IRQs to AINTC ( up to 32 GPIOs ) .
*/
2013-11-08 10:45:55 +04:00
if ( offset < d - > gpio_unbanked )
2018-06-13 06:40:37 +03:00
return d - > irqs [ offset ] ;
2009-06-26 04:01:31 +04:00
else
return - ENODEV ;
}
2012-03-11 16:46:11 +04:00
static int gpio_irq_type_unbanked ( struct irq_data * data , unsigned trigger )
2009-06-26 04:01:31 +04:00
{
2012-03-11 16:46:11 +04:00
struct davinci_gpio_controller * d ;
struct davinci_gpio_regs __iomem * g ;
2018-06-13 06:40:37 +03:00
u32 mask , i ;
2012-03-11 16:46:11 +04:00
2015-06-01 11:05:19 +03:00
d = ( struct davinci_gpio_controller * ) irq_data_get_irq_handler_data ( data ) ;
2017-11-10 14:13:17 +03:00
g = ( struct davinci_gpio_regs __iomem * ) d - > regs [ 0 ] ;
2018-06-13 06:40:37 +03:00
for ( i = 0 ; i < MAX_INT_PER_BANK ; i + + )
if ( data - > irq = = d - > irqs [ i ] )
break ;
if ( i = = MAX_INT_PER_BANK )
return - EINVAL ;
mask = __gpio_mask ( i ) ;
2009-06-26 04:01:31 +04:00
if ( trigger & ~ ( IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING ) )
return - EINVAL ;
2013-12-11 21:52:07 +04:00
writel_relaxed ( mask , ( trigger & IRQ_TYPE_EDGE_FALLING )
2009-06-26 04:01:31 +04:00
? & g - > set_falling : & g - > clr_falling ) ;
2013-12-11 21:52:07 +04:00
writel_relaxed ( mask , ( trigger & IRQ_TYPE_EDGE_RISING )
2009-06-26 04:01:31 +04:00
? & g - > set_rising : & g - > clr_rising ) ;
return 0 ;
}
2013-11-21 22:15:27 +04:00
static int
davinci_gpio_irq_map ( struct irq_domain * d , unsigned int irq ,
irq_hw_number_t hw )
{
2017-01-17 19:19:11 +03:00
struct davinci_gpio_controller * chips =
( struct davinci_gpio_controller * ) d - > host_data ;
2017-01-13 07:20:12 +03:00
struct davinci_gpio_regs __iomem * g = chips - > regs [ hw / 32 ] ;
2013-11-21 22:15:27 +04:00
irq_set_chip_and_handler_name ( irq , & gpio_irqchip , handle_simple_irq ,
" davinci_gpio " ) ;
irq_set_irq_type ( irq , IRQ_TYPE_NONE ) ;
irq_set_chip_data ( irq , ( __force void * ) g ) ;
2019-06-05 11:02:57 +03:00
irq_set_handler_data ( irq , ( void * ) ( uintptr_t ) __gpio_mask ( hw ) ) ;
2013-11-21 22:15:27 +04:00
return 0 ;
}
static const struct irq_domain_ops davinci_gpio_irq_ops = {
. map = davinci_gpio_irq_map ,
. xlate = irq_domain_xlate_onetwocell ,
} ;
2014-02-13 19:58:45 +04:00
static struct irq_chip * davinci_gpio_get_irq_chip ( unsigned int irq )
{
static struct irq_chip_type gpio_unbanked ;
2015-12-30 17:16:38 +03:00
gpio_unbanked = * irq_data_get_chip_type ( irq_get_irq_data ( irq ) ) ;
2014-02-13 19:58:45 +04:00
return & gpio_unbanked . chip ;
} ;
static struct irq_chip * keystone_gpio_get_irq_chip ( unsigned int irq )
{
static struct irq_chip gpio_unbanked ;
gpio_unbanked = * irq_get_chip ( irq ) ;
return & gpio_unbanked ;
} ;
static const struct of_device_id davinci_gpio_ids [ ] ;
2007-07-10 16:03:43 +04:00
/*
2008-12-07 22:46:23 +03:00
* NOTE : for suspend / resume , probably best to make a platform_device with
* suspend_late / resume_resume calls hooking into results of the set_wake ( )
2007-07-10 16:03:43 +04:00
* calls . . . so if no gpios are wakeup events the clock can be disabled ,
* with outputs left at previously set levels , and so that VDD3P3V . IOPWDN0
2008-12-07 22:46:23 +03:00
* ( dm6446 ) can be set appropriately for GPIOV33 pins .
2007-07-10 16:03:43 +04:00
*/
2018-06-13 06:40:37 +03:00
static int davinci_gpio_irq_setup ( struct platform_device * pdev )
2007-07-10 16:03:43 +04:00
{
2014-02-15 17:12:05 +04:00
unsigned gpio , bank ;
int irq ;
2017-05-23 12:18:57 +03:00
int ret ;
2007-07-10 16:03:43 +04:00
struct clk * clk ;
2008-12-07 22:46:23 +03:00
u32 binten = 0 ;
2018-06-13 06:40:36 +03:00
unsigned ngpio ;
2013-08-18 09:18:58 +04:00
struct device * dev = & pdev - > dev ;
struct davinci_gpio_controller * chips = platform_get_drvdata ( pdev ) ;
struct davinci_gpio_platform_data * pdata = dev - > platform_data ;
struct davinci_gpio_regs __iomem * g ;
2013-12-18 14:07:51 +04:00
struct irq_domain * irq_domain = NULL ;
2014-02-13 19:58:45 +04:00
const struct of_device_id * match ;
struct irq_chip * irq_chip ;
2017-01-13 07:20:12 +03:00
struct davinci_gpio_irq_data * irqdata ;
2014-02-13 19:58:45 +04:00
gpio_get_irq_chip_cb_t gpio_get_irq_chip ;
/*
* Use davinci_gpio_get_irq_chip by default to handle non DT cases
*/
gpio_get_irq_chip = davinci_gpio_get_irq_chip ;
match = of_match_device ( of_match_ptr ( davinci_gpio_ids ) ,
dev ) ;
if ( match )
gpio_get_irq_chip = ( gpio_get_irq_chip_cb_t ) match - > data ;
2009-04-15 23:40:35 +04:00
2013-08-18 09:18:58 +04:00
ngpio = pdata - > ngpio ;
2007-07-10 16:03:43 +04:00
2013-08-18 09:18:58 +04:00
clk = devm_clk_get ( dev , " gpio " ) ;
2007-07-10 16:03:43 +04:00
if ( IS_ERR ( clk ) ) {
2017-07-20 12:42:18 +03:00
dev_err ( dev , " Error %ld getting gpio clock \n " , PTR_ERR ( clk ) ) ;
2008-12-07 22:46:23 +03:00
return PTR_ERR ( clk ) ;
2007-07-10 16:03:43 +04:00
}
2018-06-13 06:40:37 +03:00
2017-05-23 12:18:57 +03:00
ret = clk_prepare_enable ( clk ) ;
if ( ret )
return ret ;
2007-07-10 16:03:43 +04:00
2013-12-18 14:07:51 +04:00
if ( ! pdata - > gpio_unbanked ) {
2017-03-04 19:23:36 +03:00
irq = devm_irq_alloc_descs ( dev , - 1 , 0 , ngpio , 0 ) ;
2013-12-18 14:07:51 +04:00
if ( irq < 0 ) {
dev_err ( dev , " Couldn't allocate IRQ numbers \n " ) ;
2017-05-23 12:18:57 +03:00
clk_disable_unprepare ( clk ) ;
2013-12-18 14:07:51 +04:00
return irq ;
}
2013-11-21 22:15:27 +04:00
2016-01-28 16:38:50 +03:00
irq_domain = irq_domain_add_legacy ( dev - > of_node , ngpio , irq , 0 ,
2013-12-18 14:07:51 +04:00
& davinci_gpio_irq_ops ,
chips ) ;
if ( ! irq_domain ) {
dev_err ( dev , " Couldn't register an IRQ domain \n " ) ;
2017-05-23 12:18:57 +03:00
clk_disable_unprepare ( clk ) ;
2013-12-18 14:07:51 +04:00
return - ENODEV ;
}
2013-11-21 22:15:27 +04:00
}
2013-08-18 09:18:57 +04:00
/*
* Arrange gpio_to_irq ( ) support , handling either direct IRQs or
2009-06-26 04:01:31 +04:00
* banked IRQs . Having GPIOs in the first GPIO bank use direct
* IRQs , while the others use banked IRQs , would need some setup
* tweaks to recognize hardware which can do that .
*/
2017-01-13 07:20:12 +03:00
chips - > chip . to_irq = gpio_to_irq_banked ;
chips - > irq_domain = irq_domain ;
2009-06-26 04:01:31 +04:00
/*
* AINTC can handle direct / unbanked IRQs for GPIOs , with the GPIO
* controller only handling trigger modes . We currently assume no
* IRQ mux conflicts ; gpio_irq_type_unbanked ( ) is only for GPIOs .
*/
2013-08-18 09:18:58 +04:00
if ( pdata - > gpio_unbanked ) {
2009-06-26 04:01:31 +04:00
/* pass "bank 0" GPIO IRQs to AINTC */
2017-01-13 07:20:12 +03:00
chips - > chip . to_irq = gpio_to_irq_unbanked ;
chips - > gpio_unbanked = pdata - > gpio_unbanked ;
2015-07-02 21:31:30 +03:00
binten = GENMASK ( pdata - > gpio_unbanked / 16 , 0 ) ;
2009-06-26 04:01:31 +04:00
/* AINTC handles mask/unmask; GPIO handles triggering */
2018-06-13 06:40:37 +03:00
irq = chips - > irqs [ 0 ] ;
2014-02-13 19:58:45 +04:00
irq_chip = gpio_get_irq_chip ( irq ) ;
irq_chip - > name = " GPIO-AINTC " ;
irq_chip - > irq_set_type = gpio_irq_type_unbanked ;
2009-06-26 04:01:31 +04:00
/* default trigger: both edges */
2017-01-13 07:20:12 +03:00
g = chips - > regs [ 0 ] ;
2013-12-11 21:52:07 +04:00
writel_relaxed ( ~ 0 , & g - > set_falling ) ;
writel_relaxed ( ~ 0 , & g - > set_rising ) ;
2009-06-26 04:01:31 +04:00
/* set the direct IRQs up to use that irqchip */
2018-06-13 06:40:37 +03:00
for ( gpio = 0 ; gpio < pdata - > gpio_unbanked ; gpio + + ) {
irq_set_chip ( chips - > irqs [ gpio ] , irq_chip ) ;
irq_set_handler_data ( chips - > irqs [ gpio ] , chips ) ;
irq_set_status_flags ( chips - > irqs [ gpio ] ,
IRQ_TYPE_EDGE_BOTH ) ;
2009-06-26 04:01:31 +04:00
}
goto done ;
}
/*
* Or , AINTC can handle IRQs for banks of 16 GPIO IRQs , which we
* then chain through our own handler .
*/
2018-06-13 06:40:37 +03:00
for ( gpio = 0 , bank = 0 ; gpio < ngpio ; bank + + , gpio + = 16 ) {
2017-01-17 19:19:11 +03:00
/* disabled by default, enabled only as needed
* There are register sets for 32 GPIOs . 2 banks of 16
* GPIOs are covered by each set of registers hence divide by 2
*/
2017-01-13 07:20:12 +03:00
g = chips - > regs [ bank / 2 ] ;
2013-12-11 21:52:07 +04:00
writel_relaxed ( ~ 0 , & g - > clr_falling ) ;
writel_relaxed ( ~ 0 , & g - > clr_rising ) ;
2007-07-10 16:03:43 +04:00
2011-07-12 01:03:11 +04:00
/*
* Each chip handles 32 gpios , and each irq bank consists of 16
* gpio irqs . Pass the irq bank ' s corresponding controller to
* the chained irq handler .
*/
2017-01-13 07:20:12 +03:00
irqdata = devm_kzalloc ( & pdev - > dev ,
sizeof ( struct
davinci_gpio_irq_data ) ,
GFP_KERNEL ) ;
2017-05-23 12:18:57 +03:00
if ( ! irqdata ) {
clk_disable_unprepare ( clk ) ;
2017-01-13 07:20:12 +03:00
return - ENOMEM ;
2017-05-23 12:18:57 +03:00
}
2017-01-13 07:20:12 +03:00
irqdata - > regs = g ;
irqdata - > bank_num = bank ;
irqdata - > chip = chips ;
2018-06-13 06:40:37 +03:00
irq_set_chained_handler_and_data ( chips - > irqs [ bank ] ,
gpio_irq_handler , irqdata ) ;
2007-07-10 16:03:43 +04:00
2008-12-07 22:46:23 +03:00
binten | = BIT ( bank ) ;
2007-07-10 16:03:43 +04:00
}
2009-06-26 04:01:31 +04:00
done :
2013-08-18 09:18:57 +04:00
/*
* BINTEN - - per - bank interrupt enable . genirq would also let these
2007-07-10 16:03:43 +04:00
* bits be set / cleared dynamically .
*/
2013-12-11 21:52:07 +04:00
writel_relaxed ( binten , gpio_base + BINTEN ) ;
2007-07-10 16:03:43 +04:00
return 0 ;
}
2013-08-18 09:18:58 +04:00
2022-06-13 08:43:10 +03:00
static void davinci_gpio_save_context ( struct davinci_gpio_controller * chips ,
u32 nbank )
{
struct davinci_gpio_regs __iomem * g ;
struct davinci_gpio_regs * context ;
u32 bank ;
void __iomem * base ;
base = chips - > regs [ 0 ] - offset_array [ 0 ] ;
chips - > binten_context = readl_relaxed ( base + BINTEN ) ;
for ( bank = 0 ; bank < nbank ; bank + + ) {
g = chips - > regs [ bank ] ;
context = & chips - > context [ bank ] ;
context - > dir = readl_relaxed ( & g - > dir ) ;
context - > set_data = readl_relaxed ( & g - > set_data ) ;
context - > set_rising = readl_relaxed ( & g - > set_rising ) ;
context - > set_falling = readl_relaxed ( & g - > set_falling ) ;
}
/* Clear Bank interrupt enable bit */
writel_relaxed ( 0 , base + BINTEN ) ;
/* Clear all interrupt status registers */
writel_relaxed ( GENMASK ( 31 , 0 ) , & g - > intstat ) ;
}
static void davinci_gpio_restore_context ( struct davinci_gpio_controller * chips ,
u32 nbank )
{
struct davinci_gpio_regs __iomem * g ;
struct davinci_gpio_regs * context ;
u32 bank ;
void __iomem * base ;
base = chips - > regs [ 0 ] - offset_array [ 0 ] ;
if ( readl_relaxed ( base + BINTEN ) ! = chips - > binten_context )
writel_relaxed ( chips - > binten_context , base + BINTEN ) ;
for ( bank = 0 ; bank < nbank ; bank + + ) {
g = chips - > regs [ bank ] ;
context = & chips - > context [ bank ] ;
if ( readl_relaxed ( & g - > dir ) ! = context - > dir )
writel_relaxed ( context - > dir , & g - > dir ) ;
if ( readl_relaxed ( & g - > set_data ) ! = context - > set_data )
writel_relaxed ( context - > set_data , & g - > set_data ) ;
if ( readl_relaxed ( & g - > set_rising ) ! = context - > set_rising )
writel_relaxed ( context - > set_rising , & g - > set_rising ) ;
if ( readl_relaxed ( & g - > set_falling ) ! = context - > set_falling )
writel_relaxed ( context - > set_falling , & g - > set_falling ) ;
}
}
static int davinci_gpio_suspend ( struct device * dev )
{
struct davinci_gpio_controller * chips = dev_get_drvdata ( dev ) ;
struct davinci_gpio_platform_data * pdata = dev_get_platdata ( dev ) ;
u32 nbank = DIV_ROUND_UP ( pdata - > ngpio , 32 ) ;
davinci_gpio_save_context ( chips , nbank ) ;
return 0 ;
}
static int davinci_gpio_resume ( struct device * dev )
{
struct davinci_gpio_controller * chips = dev_get_drvdata ( dev ) ;
struct davinci_gpio_platform_data * pdata = dev_get_platdata ( dev ) ;
u32 nbank = DIV_ROUND_UP ( pdata - > ngpio , 32 ) ;
davinci_gpio_restore_context ( chips , nbank ) ;
return 0 ;
}
DEFINE_SIMPLE_DEV_PM_OPS ( davinci_gpio_dev_pm_ops , davinci_gpio_suspend ,
davinci_gpio_resume ) ;
2013-11-21 22:15:29 +04:00
static const struct of_device_id davinci_gpio_ids [ ] = {
2014-02-13 19:58:45 +04:00
{ . compatible = " ti,keystone-gpio " , keystone_gpio_get_irq_chip } ,
2019-06-05 11:02:58 +03:00
{ . compatible = " ti,am654-gpio " , keystone_gpio_get_irq_chip } ,
2014-02-13 19:58:45 +04:00
{ . compatible = " ti,dm6441-gpio " , davinci_gpio_get_irq_chip } ,
2013-11-21 22:15:29 +04:00
{ /* sentinel */ } ,
} ;
MODULE_DEVICE_TABLE ( of , davinci_gpio_ids ) ;
2013-08-18 09:18:58 +04:00
static struct platform_driver davinci_gpio_driver = {
. probe = davinci_gpio_probe ,
. driver = {
2013-11-21 22:15:29 +04:00
. name = " davinci_gpio " ,
2022-06-13 08:43:10 +03:00
. pm = pm_sleep_ptr ( & davinci_gpio_dev_pm_ops ) ,
2013-11-21 22:15:29 +04:00
. of_match_table = of_match_ptr ( davinci_gpio_ids ) ,
2013-08-18 09:18:58 +04:00
} ,
} ;
/**
* GPIO driver registration needs to be done before machine_init functions
* access GPIO . Hence davinci_gpio_drv_reg ( ) is a postcore_initcall .
*/
static int __init davinci_gpio_drv_reg ( void )
{
return platform_driver_register ( & davinci_gpio_driver ) ;
}
postcore_initcall ( davinci_gpio_drv_reg ) ;
2022-11-07 20:29:21 +03:00
static void __exit davinci_gpio_exit ( void )
{
platform_driver_unregister ( & davinci_gpio_driver ) ;
}
module_exit ( davinci_gpio_exit ) ;
MODULE_AUTHOR ( " Jan Kotas <jank@cadence.com> " ) ;
MODULE_DESCRIPTION ( " DAVINCI GPIO driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS ( " platform:gpio-davinci " ) ;