@ -20,13 +20,15 @@
# include <linux/io.h>
# include <linux/ioport.h>
# include <linux/gpio.h>
# include <linux/platform_data/gpio-ath79.h>
# include <linux/of_device.h>
# include <asm/mach-ath79/ar71xx_regs.h>
# include <asm/mach-ath79/ath79.h>
# include "common.h"
static void __iomem * ath79_gpio_base ;
static unsigned long ath79_gpio_count ;
static u32 ath79_gpio_count ;
static DEFINE_SPINLOCK ( ath79_gpio_lock ) ;
static void __ath79_gpio_set_value ( unsigned gpio , int value )
@ -178,39 +180,72 @@ void ath79_gpio_function_disable(u32 mask)
ath79_gpio_function_setup ( 0 , mask ) ;
}
void __init ath79_gpio_init ( void )
static const struct of_device_id ath79_gpio_of_match [ ] = {
{ . compatible = " qca,ar7100-gpio " } ,
{ . compatible = " qca,ar9340-gpio " } ,
{ } ,
} ;
static int ath79_gpio_probe ( struct platform_device * pdev )
{
struct ath79_gpio_platform_data * pdata = pdev - > dev . platform_data ;
struct device_node * np = pdev - > dev . of_node ;
struct resource * res ;
bool oe_inverted ;
int err ;
if ( soc_is_ar71xx ( ) )
ath79_gpio_count = AR71XX_GPIO_COUNT ;
else if ( soc_is_ar7240 ( ) )
ath79_gpio_count = AR7240_GPIO_COUNT ;
else if ( soc_is_ar7241 ( ) | | soc_is_ar7242 ( ) )
ath79_gpio_count = AR7241_GPIO_COUNT ;
else if ( soc_is_ar913x ( ) )
ath79_gpio_count = AR913X_GPIO_COUNT ;
else if ( soc_is_ar933x ( ) )
ath79_gpio_count = AR933X_GPIO_COUNT ;
else if ( soc_is_ar934x ( ) )
ath79_gpio_count = AR934X_GPIO_COUNT ;
else if ( soc_is_qca955x ( ) )
ath79_gpio_count = QCA955X_GPIO_COUNT ;
else
BUG ( ) ;
if ( np ) {
err = of_property_read_u32 ( np , " ngpios " , & ath79_gpio_count ) ;
if ( err ) {
dev_err ( & pdev - > dev , " ngpios property is not valid \n " ) ;
return err ;
}
if ( ath79_gpio_count > = 32 ) {
dev_err ( & pdev - > dev , " ngpios must be less than 32 \n " ) ;
return - EINVAL ;
}
oe_inverted = of_device_is_compatible ( np , " qca,ar9340-gpio " ) ;
} else if ( pdata ) {
ath79_gpio_count = pdata - > ngpios ;
oe_inverted = pdata - > oe_inverted ;
} else {
dev_err ( & pdev - > dev , " No DT node or platform data found \n " ) ;
return - EINVAL ;
}
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
ath79_gpio_base = devm_ioremap_nocache (
& pdev - > dev , res - > start , resource_size ( res ) ) ;
if ( ! ath79_gpio_base )
return - ENOMEM ;
ath79_gpio_base = ioremap_nocache ( AR71XX_GPIO_BASE , AR71XX_GPIO_SIZE ) ;
ath79_gpio_chip . dev = & pdev - > dev ;
ath79_gpio_chip . ngpio = ath79_gpio_count ;
if ( soc_is_ar934x ( ) | | soc_is_qca955x ( ) ) {
if ( oe_inverted ) {
ath79_gpio_chip . direction_input = ar934x_gpio_direction_input ;
ath79_gpio_chip . direction_output = ar934x_gpio_direction_output ;
}
err = gpiochip_add ( & ath79_gpio_chip ) ;
if ( err )
panic ( " cannot add AR71xx GPIO chip, error=%d " , err ) ;
if ( err ) {
dev_err ( & pdev - > dev ,
" cannot add AR71xx GPIO chip, error=%d " , err ) ;
return err ;
}
return 0 ;
}
static struct platform_driver ath79_gpio_driver = {
. driver = {
. name = " ath79-gpio " ,
. of_match_table = ath79_gpio_of_match ,
} ,
. probe = ath79_gpio_probe ,
} ;
module_platform_driver ( ath79_gpio_driver ) ;
int gpio_get_value ( unsigned gpio )
{
if ( gpio < ath79_gpio_count )