2023-03-15 19:06:47 +08:00
// SPDX-License-Identifier: GPL-2.0-only
2016-04-06 20:34:53 +08:00
/*
* GPIO Driver for Loongson 1 SoC
*
2023-03-15 19:06:47 +08:00
* Copyright ( C ) 2015 - 2023 Keguang Zhang < keguang . zhang @ gmail . com >
2016-04-06 20:34:53 +08:00
*/
2016-09-12 18:16:29 -04:00
# include <linux/module.h>
2016-04-06 20:34:53 +08:00
# include <linux/gpio/driver.h>
# include <linux/platform_device.h>
2017-10-20 14:42:01 +02:00
# include <linux/bitops.h>
2016-04-06 20:34:53 +08:00
/* Loongson 1 GPIO Register Definitions */
# define GPIO_CFG 0x0
# define GPIO_DIR 0x10
# define GPIO_DATA 0x20
# define GPIO_OUTPUT 0x30
2023-03-15 19:06:48 +08:00
struct ls1x_gpio_chip {
struct gpio_chip gc ;
void __iomem * reg_base ;
} ;
2016-04-06 20:34:53 +08:00
static int ls1x_gpio_request ( struct gpio_chip * gc , unsigned int offset )
{
2023-03-15 19:06:48 +08:00
struct ls1x_gpio_chip * ls1x_gc = gpiochip_get_data ( gc ) ;
2016-04-06 20:34:53 +08:00
unsigned long flags ;
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave ( & gc - > bgpio_lock , flags ) ;
2023-03-15 19:06:48 +08:00
__raw_writel ( __raw_readl ( ls1x_gc - > reg_base + GPIO_CFG ) | BIT ( offset ) ,
ls1x_gc - > reg_base + GPIO_CFG ) ;
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore ( & gc - > bgpio_lock , flags ) ;
2016-04-06 20:34:53 +08:00
return 0 ;
}
static void ls1x_gpio_free ( struct gpio_chip * gc , unsigned int offset )
{
2023-03-15 19:06:48 +08:00
struct ls1x_gpio_chip * ls1x_gc = gpiochip_get_data ( gc ) ;
2016-04-06 20:34:53 +08:00
unsigned long flags ;
2022-04-19 09:28:10 +08:00
raw_spin_lock_irqsave ( & gc - > bgpio_lock , flags ) ;
2023-03-15 19:06:48 +08:00
__raw_writel ( __raw_readl ( ls1x_gc - > reg_base + GPIO_CFG ) & ~ BIT ( offset ) ,
ls1x_gc - > reg_base + GPIO_CFG ) ;
2022-04-19 09:28:10 +08:00
raw_spin_unlock_irqrestore ( & gc - > bgpio_lock , flags ) ;
2016-04-06 20:34:53 +08:00
}
static int ls1x_gpio_probe ( struct platform_device * pdev )
{
struct device * dev = & pdev - > dev ;
2023-03-15 19:06:48 +08:00
struct ls1x_gpio_chip * ls1x_gc ;
2016-04-06 20:34:53 +08:00
int ret ;
2023-03-15 19:06:48 +08:00
ls1x_gc = devm_kzalloc ( dev , sizeof ( * ls1x_gc ) , GFP_KERNEL ) ;
if ( ! ls1x_gc )
2016-04-06 20:34:53 +08:00
return - ENOMEM ;
2023-03-15 19:06:48 +08:00
ls1x_gc - > reg_base = devm_platform_ioremap_resource ( pdev , 0 ) ;
if ( IS_ERR ( ls1x_gc - > reg_base ) )
return PTR_ERR ( ls1x_gc - > reg_base ) ;
2016-04-06 20:34:53 +08:00
2023-03-15 19:06:48 +08:00
ret = bgpio_init ( & ls1x_gc - > gc , dev , 4 , ls1x_gc - > reg_base + GPIO_DATA ,
ls1x_gc - > reg_base + GPIO_OUTPUT , NULL ,
NULL , ls1x_gc - > reg_base + GPIO_DIR , 0 ) ;
2016-04-06 20:34:53 +08:00
if ( ret )
goto err ;
2023-03-15 19:06:48 +08:00
ls1x_gc - > gc . owner = THIS_MODULE ;
ls1x_gc - > gc . request = ls1x_gpio_request ;
ls1x_gc - > gc . free = ls1x_gpio_free ;
2023-03-15 19:06:49 +08:00
/*
* Clear ngpio to let gpiolib get the correct number
* by reading ngpios property
*/
ls1x_gc - > gc . ngpio = 0 ;
2016-04-06 20:34:53 +08:00
2023-03-15 19:06:48 +08:00
ret = devm_gpiochip_add_data ( dev , & ls1x_gc - > gc , ls1x_gc ) ;
2016-04-06 20:34:53 +08:00
if ( ret )
goto err ;
2023-03-15 19:06:48 +08:00
platform_set_drvdata ( pdev , ls1x_gc ) ;
2023-03-15 19:06:49 +08:00
dev_info ( dev , " GPIO controller registered with %d pins \n " ,
ls1x_gc - > gc . ngpio ) ;
2016-04-06 20:34:53 +08:00
return 0 ;
err :
2023-03-15 19:06:49 +08:00
dev_err ( dev , " failed to register GPIO controller \n " ) ;
2016-04-06 20:34:53 +08:00
return ret ;
}
2023-03-15 19:06:49 +08:00
static const struct of_device_id ls1x_gpio_dt_ids [ ] = {
{ . compatible = " loongson,ls1x-gpio " } ,
{ /* sentinel */ }
} ;
MODULE_DEVICE_TABLE ( of , ls1x_gpio_dt_ids ) ;
2016-04-06 20:34:53 +08:00
static struct platform_driver ls1x_gpio_driver = {
. probe = ls1x_gpio_probe ,
. driver = {
. name = " ls1x-gpio " ,
2023-03-15 19:06:49 +08:00
. of_match_table = ls1x_gpio_dt_ids ,
2016-04-06 20:34:53 +08:00
} ,
} ;
module_platform_driver ( ls1x_gpio_driver ) ;
2023-03-15 19:06:47 +08:00
MODULE_AUTHOR ( " Keguang Zhang <keguang.zhang@gmail.com> " ) ;
2016-04-06 20:34:53 +08:00
MODULE_DESCRIPTION ( " Loongson1 GPIO driver " ) ;
MODULE_LICENSE ( " GPL " ) ;