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 >
*
* 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 ; either version 2 of the License , or
* ( at your option ) any later version .
*/
2011-07-26 13:53:52 +04:00
# include <linux/gpio.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>
# include <asm/mach/irq.h>
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 ;
} ;
2010-05-02 02:37:51 +04:00
# define chip2controller(chip) \
2010-05-02 02:37:52 +04:00
container_of ( chip , struct davinci_gpio_controller , chip )
2010-05-02 02:37:51 +04:00
2010-05-02 02:37:52 +04:00
static struct davinci_gpio_controller chips [ DIV_ROUND_UP ( DAVINCI_N_GPIO , 32 ) ] ;
2010-05-08 01:06:32 +04:00
static void __iomem * gpio_base ;
2007-07-10 16:03:43 +04:00
2010-05-02 02:37:52 +04:00
static struct davinci_gpio_regs __iomem __init * gpio2regs ( unsigned gpio )
2007-07-10 16:03:43 +04:00
{
2010-05-02 02:37:53 +04:00
void __iomem * ptr ;
if ( gpio < 32 * 1 )
2010-05-08 01:06:32 +04:00
ptr = gpio_base + 0x10 ;
2010-05-02 02:37:53 +04:00
else if ( gpio < 32 * 2 )
2010-05-08 01:06:32 +04:00
ptr = gpio_base + 0x38 ;
2010-05-02 02:37:53 +04:00
else if ( gpio < 32 * 3 )
2010-05-08 01:06:32 +04:00
ptr = gpio_base + 0x60 ;
2010-05-02 02:37:53 +04:00
else if ( gpio < 32 * 4 )
2010-05-08 01:06:32 +04:00
ptr = gpio_base + 0x88 ;
2010-05-02 02:37:53 +04:00
else if ( gpio < 32 * 5 )
2010-05-08 01:06:32 +04:00
ptr = gpio_base + 0xb0 ;
2010-05-02 02:37:53 +04:00
else
ptr = NULL ;
return ptr ;
2007-07-10 16:03:43 +04:00
}
2010-05-02 02:37:52 +04:00
static inline struct davinci_gpio_regs __iomem * irq2regs ( int irq )
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
2011-03-24 15:25:22 +03:00
g = ( __force struct davinci_gpio_regs __iomem * ) irq_get_chip_data ( irq ) ;
2010-02-26 03:49:56 +03:00
return g ;
}
2009-05-11 22:04:53 +04:00
static int __init davinci_gpio_irq_setup ( void ) ;
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
{
2010-05-02 02:37:52 +04:00
struct davinci_gpio_controller * d = chip2controller ( chip ) ;
struct davinci_gpio_regs __iomem * g = d - > regs ;
2010-05-02 02:37:55 +04:00
unsigned long flags ;
2008-09-08 10:41:04 +04:00
u32 temp ;
2010-05-02 02:37:51 +04:00
u32 mask = 1 < < offset ;
2007-07-10 16:03:43 +04:00
2010-05-02 02:37:55 +04:00
spin_lock_irqsave ( & d - > lock , flags ) ;
2008-09-08 10:41:04 +04:00
temp = __raw_readl ( & g - > dir ) ;
2010-05-02 02:37:51 +04:00
if ( out ) {
temp & = ~ mask ;
__raw_writel ( mask , value ? & g - > set_data : & g - > clr_data ) ;
} else {
temp | = mask ;
}
2008-09-08 10:41:04 +04:00
__raw_writel ( 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
{
2010-05-02 02:37:52 +04:00
struct davinci_gpio_controller * d = chip2controller ( chip ) ;
struct davinci_gpio_regs __iomem * g = d - > regs ;
2007-07-10 16:03:43 +04:00
2008-09-08 10:41:04 +04:00
return ( 1 < < offset ) & __raw_readl ( & 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
{
2010-05-02 02:37:52 +04:00
struct davinci_gpio_controller * d = chip2controller ( chip ) ;
struct davinci_gpio_regs __iomem * g = d - > regs ;
2007-07-10 16:03:43 +04:00
2008-09-08 10:41:04 +04:00
__raw_writel ( ( 1 < < offset ) , value ? & g - > set_data : & g - > clr_data ) ;
}
static int __init davinci_gpio_setup ( void )
{
int i , base ;
2009-04-15 23:40:35 +04:00
unsigned ngpio ;
struct davinci_soc_info * soc_info = & davinci_soc_info ;
2010-05-02 02:37:53 +04:00
struct davinci_gpio_regs * regs ;
2008-09-08 10:41:04 +04:00
2010-05-02 02:37:54 +04:00
if ( soc_info - > gpio_type ! = GPIO_TYPE_DAVINCI )
return 0 ;
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 .
*/
2009-04-15 23:40:35 +04:00
ngpio = soc_info - > gpio_num ;
if ( ngpio = = 0 ) {
2008-12-07 22:46:23 +03:00
pr_err ( " GPIO setup: how many GPIOs? \n " ) ;
return - EINVAL ;
}
if ( WARN_ON ( DAVINCI_N_GPIO < ngpio ) )
ngpio = DAVINCI_N_GPIO ;
2010-05-08 01:06:32 +04:00
gpio_base = ioremap ( soc_info - > gpio_base , SZ_4K ) ;
if ( WARN_ON ( ! gpio_base ) )
return - ENOMEM ;
2008-12-07 22:46:23 +03:00
for ( i = 0 , base = 0 ; base < ngpio ; i + + , base + = 32 ) {
2008-09-08 10:41:04 +04:00
chips [ i ] . chip . label = " DaVinci " ;
chips [ i ] . chip . direction_input = davinci_direction_in ;
chips [ i ] . chip . get = davinci_gpio_get ;
chips [ i ] . chip . direction_output = davinci_direction_out ;
chips [ i ] . chip . set = davinci_gpio_set ;
chips [ i ] . chip . base = base ;
2008-12-07 22:46:23 +03:00
chips [ i ] . chip . ngpio = ngpio - base ;
2008-09-08 10:41:04 +04:00
if ( chips [ i ] . chip . ngpio > 32 )
chips [ i ] . chip . ngpio = 32 ;
2010-05-02 02:37:55 +04:00
spin_lock_init ( & chips [ i ] . lock ) ;
2010-05-02 02:37:53 +04:00
regs = gpio2regs ( base ) ;
chips [ i ] . regs = regs ;
chips [ i ] . set_data = & regs - > set_data ;
chips [ i ] . clr_data = & regs - > clr_data ;
chips [ i ] . in_data = & regs - > in_data ;
2008-09-08 10:41:04 +04:00
gpiochip_add ( & chips [ i ] . chip ) ;
}
2007-07-10 16:03:43 +04:00
2010-05-02 02:37:53 +04:00
soc_info - > gpio_ctlrs = chips ;
soc_info - > gpio_ctlrs_num = DIV_ROUND_UP ( ngpio , 32 ) ;
2009-05-11 22:04:53 +04:00
davinci_gpio_irq_setup ( ) ;
2007-07-10 16:03:43 +04:00
return 0 ;
}
2008-09-08 10:41:04 +04:00
pure_initcall ( davinci_gpio_setup ) ;
2007-07-10 16:03:43 +04:00
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
{
2010-11-29 12:27:27 +03:00
struct davinci_gpio_regs __iomem * g = irq2regs ( d - > irq ) ;
2011-03-24 15:25:22 +03:00
u32 mask = ( u32 ) irq_data_get_irq_handler_data ( d ) ;
2007-07-10 16:03:43 +04:00
__raw_writel ( mask , & g - > clr_falling ) ;
__raw_writel ( mask , & g - > clr_rising ) ;
}
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
{
2010-11-29 12:27:27 +03:00
struct davinci_gpio_regs __iomem * g = irq2regs ( d - > irq ) ;
2011-03-24 15:25:22 +03:00
u32 mask = ( u32 ) 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 )
2007-07-10 16:03:43 +04:00
__raw_writel ( mask , & g - > set_falling ) ;
2009-05-05 00:14:27 +04:00
if ( status & IRQ_TYPE_EDGE_RISING )
2007-07-10 16:03:43 +04:00
__raw_writel ( mask , & g - > set_rising ) ;
}
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
} ;
static void
gpio_irq_handler ( unsigned irq , struct irq_desc * desc )
{
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 ;
2011-07-12 01:03:11 +04:00
struct davinci_gpio_controller * d ;
2007-07-10 16:03:43 +04:00
2011-07-12 01:03:11 +04:00
d = ( struct davinci_gpio_controller * ) irq_desc_get_handler_data ( desc ) ;
g = ( struct davinci_gpio_regs __iomem * ) d - > regs ;
2011-06-06 13:51:43 +04:00
2007-07-10 16:03:43 +04:00
/* we only care about one bank */
if ( irq & 1 )
mask < < = 16 ;
/* temporarily mask (level sensitive) parent IRQ */
2010-11-29 12:27:27 +03:00
desc - > irq_data . chip - > irq_mask ( & desc - > irq_data ) ;
desc - > irq_data . chip - > irq_ack ( & desc - > irq_data ) ;
2007-07-10 16:03:43 +04:00
while ( 1 ) {
u32 status ;
int n ;
int res ;
/* ack any irqs */
status = __raw_readl ( & g - > intstat ) & mask ;
if ( ! status )
break ;
__raw_writel ( status , & g - > intstat ) ;
/* now demux them to the right lowlevel handler */
2011-07-12 01:03:11 +04:00
n = d - > irq_base ;
if ( irq & 1 ) {
n + = 16 ;
status > > = 16 ;
}
2007-07-10 16:03:43 +04:00
while ( status ) {
res = ffs ( status ) ;
n + = res ;
2008-10-09 16:36:24 +04:00
generic_handle_irq ( n - 1 ) ;
2007-07-10 16:03:43 +04:00
status > > = res ;
}
}
2010-11-29 12:27:27 +03:00
desc - > irq_data . chip - > irq_unmask ( & desc - > irq_data ) ;
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 )
{
2010-05-02 02:37:52 +04:00
struct davinci_gpio_controller * d = chip2controller ( chip ) ;
2009-06-26 04:01:31 +04:00
if ( d - > irq_base > = 0 )
return d - > irq_base + offset ;
else
return - ENODEV ;
}
static int gpio_to_irq_unbanked ( struct gpio_chip * chip , unsigned offset )
{
struct davinci_soc_info * soc_info = & davinci_soc_info ;
/* NOTE: we assume for now that only irqs in the first gpio_chip
* can provide direct - mapped IRQs to AINTC ( up to 32 GPIOs ) .
*/
if ( offset < soc_info - > gpio_unbanked )
return soc_info - > gpio_irq + offset ;
else
return - ENODEV ;
}
2010-11-29 12:27:27 +03:00
static int gpio_irq_type_unbanked ( struct irq_data * d , unsigned trigger )
2009-06-26 04:01:31 +04:00
{
2010-11-29 12:27:27 +03:00
struct davinci_gpio_regs __iomem * g = irq2regs ( d - > irq ) ;
2011-03-24 15:25:22 +03:00
u32 mask = ( u32 ) irq_data_get_irq_handler_data ( d ) ;
2009-06-26 04:01:31 +04:00
if ( trigger & ~ ( IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING ) )
return - EINVAL ;
__raw_writel ( mask , ( trigger & IRQ_TYPE_EDGE_FALLING )
? & g - > set_falling : & g - > clr_falling ) ;
__raw_writel ( mask , ( trigger & IRQ_TYPE_EDGE_RISING )
? & g - > set_rising : & g - > clr_rising ) ;
return 0 ;
}
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
*/
static int __init davinci_gpio_irq_setup ( void )
{
unsigned gpio , irq , bank ;
struct clk * clk ;
2008-12-07 22:46:23 +03:00
u32 binten = 0 ;
2009-04-15 23:40:35 +04:00
unsigned ngpio , bank_irq ;
struct davinci_soc_info * soc_info = & davinci_soc_info ;
2010-05-02 02:37:52 +04:00
struct davinci_gpio_regs __iomem * g ;
2009-04-15 23:40:35 +04:00
ngpio = soc_info - > gpio_num ;
2008-12-07 22:46:23 +03:00
2009-04-15 23:40:35 +04:00
bank_irq = soc_info - > gpio_irq ;
if ( bank_irq = = 0 ) {
2008-12-07 22:46:23 +03:00
printk ( KERN_ERR " Don't know first GPIO bank IRQ. \n " ) ;
return - EINVAL ;
}
2007-07-10 16:03:43 +04:00
clk = clk_get ( NULL , " gpio " ) ;
if ( IS_ERR ( clk ) ) {
printk ( KERN_ERR " 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
}
clk_enable ( clk ) ;
2009-06-26 04:01:31 +04:00
/* Arrange gpio_to_irq() support, handling either direct IRQs or
* 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 .
*/
for ( gpio = 0 , bank = 0 ; gpio < ngpio ; bank + + , gpio + = 32 ) {
chips [ bank ] . chip . to_irq = gpio_to_irq_banked ;
chips [ bank ] . irq_base = soc_info - > gpio_unbanked
? - EINVAL
: ( soc_info - > intc_irq_num + gpio ) ;
}
/*
* 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 .
*/
if ( soc_info - > gpio_unbanked ) {
static struct irq_chip gpio_irqchip_unbanked ;
/* pass "bank 0" GPIO IRQs to AINTC */
chips [ 0 ] . chip . to_irq = gpio_to_irq_unbanked ;
binten = BIT ( 0 ) ;
/* AINTC handles mask/unmask; GPIO handles triggering */
irq = bank_irq ;
2011-03-24 14:47:04 +03:00
gpio_irqchip_unbanked = * irq_get_chip ( irq ) ;
2009-06-26 04:01:31 +04:00
gpio_irqchip_unbanked . name = " GPIO-AINTC " ;
2010-11-29 12:27:27 +03:00
gpio_irqchip_unbanked . irq_set_type = gpio_irq_type_unbanked ;
2009-06-26 04:01:31 +04:00
/* default trigger: both edges */
2010-05-02 02:37:52 +04:00
g = gpio2regs ( 0 ) ;
2009-06-26 04:01:31 +04:00
__raw_writel ( ~ 0 , & g - > set_falling ) ;
__raw_writel ( ~ 0 , & g - > set_rising ) ;
/* set the direct IRQs up to use that irqchip */
for ( gpio = 0 ; gpio < soc_info - > gpio_unbanked ; gpio + + , irq + + ) {
2011-03-24 15:25:22 +03:00
irq_set_chip ( irq , & gpio_irqchip_unbanked ) ;
irq_set_handler_data ( irq , ( void * ) __gpio_mask ( gpio ) ) ;
irq_set_chip_data ( irq , ( __force void * ) g ) ;
2011-03-24 14:47:04 +03:00
irq_set_status_flags ( irq , 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 .
*/
2008-12-07 22:46:23 +03:00
for ( gpio = 0 , irq = gpio_to_irq ( 0 ) , bank = 0 ;
gpio < ngpio ;
bank + + , bank_irq + + ) {
2007-07-10 16:03:43 +04:00
unsigned i ;
2009-06-26 04:01:31 +04:00
/* disabled by default, enabled only as needed */
2010-05-02 02:37:52 +04:00
g = gpio2regs ( gpio ) ;
2007-07-10 16:03:43 +04:00
__raw_writel ( ~ 0 , & g - > clr_falling ) ;
__raw_writel ( ~ 0 , & g - > clr_rising ) ;
/* set up all irqs in this bank */
2011-03-24 15:25:22 +03:00
irq_set_chained_handler ( bank_irq , gpio_irq_handler ) ;
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 .
*/
irq_set_handler_data ( bank_irq , & chips [ gpio / 32 ] ) ;
2007-07-10 16:03:43 +04:00
2008-12-07 22:46:23 +03:00
for ( i = 0 ; i < 16 & & gpio < ngpio ; i + + , irq + + , gpio + + ) {
2011-03-24 15:25:22 +03:00
irq_set_chip ( irq , & gpio_irqchip ) ;
irq_set_chip_data ( irq , ( __force void * ) g ) ;
irq_set_handler_data ( irq , ( void * ) __gpio_mask ( gpio ) ) ;
irq_set_handler ( irq , handle_simple_irq ) ;
2007-07-10 16:03:43 +04:00
set_irq_flags ( irq , IRQF_VALID ) ;
}
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 :
2007-07-10 16:03:43 +04:00
/* BINTEN -- per-bank interrupt enable. genirq would also let these
* bits be set / cleared dynamically .
*/
2010-05-08 01:06:32 +04:00
__raw_writel ( binten , gpio_base + 0x08 ) ;
2007-07-10 16:03:43 +04:00
printk ( KERN_INFO " DaVinci: %d gpio irqs \n " , irq - gpio_to_irq ( 0 ) ) ;
return 0 ;
}