2018-09-25 10:08:48 +03:00
/* SPDX-License-Identifier: GPL-2.0 */
2011-12-21 00:40:21 +04:00
/*
2018-09-25 10:08:48 +03:00
* devres . c - managed gpio resources
2011-12-21 00:40:21 +04:00
* This file is based on kernel / irq / devres . c
*
2016-12-20 21:57:55 +03:00
* Copyright ( c ) 2011 John Crispin < john @ phrozen . org >
2011-12-21 00:40:21 +04:00
*/
# include <linux/module.h>
2013-10-21 02:14:58 +04:00
# include <linux/err.h>
2011-12-21 00:40:21 +04:00
# include <linux/gpio.h>
2013-10-21 02:14:58 +04:00
# include <linux/gpio/consumer.h>
2011-12-21 00:40:21 +04:00
# include <linux/device.h>
# include <linux/gfp.h>
2017-01-03 20:00:20 +03:00
# include "gpiolib.h"
2013-10-17 21:21:38 +04:00
static void devm_gpiod_release ( struct device * dev , void * res )
{
struct gpio_desc * * desc = res ;
gpiod_put ( * desc ) ;
}
static int devm_gpiod_match ( struct device * dev , void * res , void * data )
{
struct gpio_desc * * this = res , * * gpio = data ;
return * this = = * gpio ;
}
2015-02-11 19:28:02 +03:00
static void devm_gpiod_release_array ( struct device * dev , void * res )
{
struct gpio_descs * * descs = res ;
gpiod_put_array ( * descs ) ;
}
static int devm_gpiod_match_array ( struct device * dev , void * res , void * data )
{
struct gpio_descs * * this = res , * * gpios = data ;
return * this = = * gpios ;
}
2013-10-17 21:21:38 +04:00
/**
* devm_gpiod_get - Resource - managed gpiod_get ( )
* @ dev : GPIO consumer
* @ con_id : function within the GPIO consumer
2014-07-25 18:38:36 +04:00
* @ flags : optional GPIO initialization flags
2013-10-17 21:21:38 +04:00
*
* Managed gpiod_get ( ) . GPIO descriptors returned from this function are
* automatically disposed on driver detach . See gpiod_get ( ) for detailed
* information about behavior and return values .
*/
2015-02-11 13:52:37 +03:00
struct gpio_desc * __must_check devm_gpiod_get ( struct device * dev ,
2014-07-25 18:38:36 +04:00
const char * con_id ,
enum gpiod_flags flags )
2013-10-17 21:21:38 +04:00
{
2014-07-25 18:38:36 +04:00
return devm_gpiod_get_index ( dev , con_id , 0 , flags ) ;
2013-10-17 21:21:38 +04:00
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpiod_get ) ;
2013-10-17 21:21:38 +04:00
2014-04-25 19:10:06 +04:00
/**
* devm_gpiod_get_optional - Resource - managed gpiod_get_optional ( )
* @ dev : GPIO consumer
* @ con_id : function within the GPIO consumer
2014-07-25 18:38:36 +04:00
* @ flags : optional GPIO initialization flags
2014-04-25 19:10:06 +04:00
*
* Managed gpiod_get_optional ( ) . GPIO descriptors returned from this function
* are automatically disposed on driver detach . See gpiod_get_optional ( ) for
* detailed information about behavior and return values .
*/
2015-02-11 13:52:37 +03:00
struct gpio_desc * __must_check devm_gpiod_get_optional ( struct device * dev ,
2014-07-25 18:38:36 +04:00
const char * con_id ,
enum gpiod_flags flags )
2014-04-25 19:10:06 +04:00
{
2014-07-25 18:38:36 +04:00
return devm_gpiod_get_index_optional ( dev , con_id , 0 , flags ) ;
2014-04-25 19:10:06 +04:00
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpiod_get_optional ) ;
2014-04-25 19:10:06 +04:00
2013-10-17 21:21:38 +04:00
/**
* devm_gpiod_get_index - Resource - managed gpiod_get_index ( )
* @ dev : GPIO consumer
* @ con_id : function within the GPIO consumer
* @ idx : index of the GPIO to obtain in the consumer
2014-07-25 18:38:36 +04:00
* @ flags : optional GPIO initialization flags
2013-10-17 21:21:38 +04:00
*
* Managed gpiod_get_index ( ) . GPIO descriptors returned from this function are
* automatically disposed on driver detach . See gpiod_get_index ( ) for detailed
* information about behavior and return values .
*/
2015-02-11 13:52:37 +03:00
struct gpio_desc * __must_check devm_gpiod_get_index ( struct device * dev ,
2013-10-17 21:21:38 +04:00
const char * con_id ,
2014-07-25 18:38:36 +04:00
unsigned int idx ,
enum gpiod_flags flags )
2013-10-17 21:21:38 +04:00
{
struct gpio_desc * * dr ;
struct gpio_desc * desc ;
2018-12-06 15:43:45 +03:00
desc = gpiod_get_index ( dev , con_id , idx , flags ) ;
if ( IS_ERR ( desc ) )
return desc ;
/*
* For non - exclusive GPIO descriptors , check if this descriptor is
* already under resource management by this device .
*/
if ( flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE ) {
struct devres * dres ;
dres = devres_find ( dev , devm_gpiod_release ,
devm_gpiod_match , & desc ) ;
if ( dres )
return desc ;
}
2014-07-29 19:16:48 +04:00
dr = devres_alloc ( devm_gpiod_release , sizeof ( struct gpio_desc * ) ,
2013-10-17 21:21:38 +04:00
GFP_KERNEL ) ;
2018-12-06 15:43:45 +03:00
if ( ! dr ) {
gpiod_put ( desc ) ;
2013-10-17 21:21:38 +04:00
return ERR_PTR ( - ENOMEM ) ;
}
* dr = desc ;
devres_add ( dev , dr ) ;
2013-10-21 02:14:57 +04:00
return desc ;
2013-10-17 21:21:38 +04:00
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpiod_get_index ) ;
2013-10-17 21:21:38 +04:00
2014-10-21 15:33:59 +04:00
/**
2019-09-13 06:22:38 +03:00
* devm_fwnode_gpiod_get_index - get a GPIO descriptor from a given node
2014-10-21 15:33:59 +04:00
* @ dev : GPIO consumer
2019-09-13 06:22:38 +03:00
* @ fwnode : firmware node containing GPIO reference
2015-01-22 00:33:46 +03:00
* @ con_id : function within the GPIO consumer
2017-02-02 16:53:11 +03:00
* @ index : index of the GPIO to obtain in the consumer
2017-01-09 17:02:28 +03:00
* @ flags : GPIO initialization flags
2017-07-24 17:57:24 +03:00
* @ label : label to attach to the requested GPIO
2014-10-21 15:33:59 +04:00
*
* GPIO descriptors returned from this function are automatically disposed on
* driver detach .
2017-01-09 17:02:28 +03:00
*
2017-02-28 18:03:12 +03:00
* On successful request the GPIO pin is configured in accordance with
2017-01-09 17:02:28 +03:00
* provided @ flags .
2014-10-21 15:33:59 +04:00
*/
2019-09-13 06:22:38 +03:00
struct gpio_desc * devm_fwnode_gpiod_get_index ( struct device * dev ,
struct fwnode_handle * fwnode ,
const char * con_id , int index ,
enum gpiod_flags flags ,
const char * label )
2014-10-21 15:33:59 +04:00
{
struct gpio_desc * * dr ;
struct gpio_desc * desc ;
dr = devres_alloc ( devm_gpiod_release , sizeof ( struct gpio_desc * ) ,
GFP_KERNEL ) ;
if ( ! dr )
return ERR_PTR ( - ENOMEM ) ;
2019-09-13 06:22:39 +03:00
desc = fwnode_gpiod_get_index ( fwnode , con_id , index , flags , label ) ;
2014-10-21 15:33:59 +04:00
if ( IS_ERR ( desc ) ) {
devres_free ( dr ) ;
return desc ;
}
* dr = desc ;
devres_add ( dev , dr ) ;
return desc ;
}
2019-09-13 06:22:38 +03:00
EXPORT_SYMBOL_GPL ( devm_fwnode_gpiod_get_index ) ;
2014-10-21 15:33:59 +04:00
2014-04-25 19:10:06 +04:00
/**
* devm_gpiod_get_index_optional - Resource - managed gpiod_get_index_optional ( )
* @ dev : GPIO consumer
* @ con_id : function within the GPIO consumer
* @ index : index of the GPIO to obtain in the consumer
2014-07-25 18:38:36 +04:00
* @ flags : optional GPIO initialization flags
2014-04-25 19:10:06 +04:00
*
* Managed gpiod_get_index_optional ( ) . GPIO descriptors returned from this
* function are automatically disposed on driver detach . See
* gpiod_get_index_optional ( ) for detailed information about behavior and
* return values .
*/
2015-02-11 13:52:37 +03:00
struct gpio_desc * __must_check devm_gpiod_get_index_optional ( struct device * dev ,
2014-04-25 19:10:06 +04:00
const char * con_id ,
2014-07-25 18:38:36 +04:00
unsigned int index ,
2015-02-11 13:52:37 +03:00
enum gpiod_flags flags )
2014-04-25 19:10:06 +04:00
{
struct gpio_desc * desc ;
2014-07-25 18:38:36 +04:00
desc = devm_gpiod_get_index ( dev , con_id , index , flags ) ;
2020-10-21 17:25:28 +03:00
if ( gpiod_not_found ( desc ) )
return NULL ;
2014-04-25 19:10:06 +04:00
return desc ;
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpiod_get_index_optional ) ;
2014-04-25 19:10:06 +04:00
2015-02-11 19:28:02 +03:00
/**
* devm_gpiod_get_array - Resource - managed gpiod_get_array ( )
* @ dev : GPIO consumer
* @ con_id : function within the GPIO consumer
* @ flags : optional GPIO initialization flags
*
* Managed gpiod_get_array ( ) . GPIO descriptors returned from this function are
* automatically disposed on driver detach . See gpiod_get_array ( ) for detailed
* information about behavior and return values .
*/
struct gpio_descs * __must_check devm_gpiod_get_array ( struct device * dev ,
const char * con_id ,
enum gpiod_flags flags )
{
struct gpio_descs * * dr ;
struct gpio_descs * descs ;
dr = devres_alloc ( devm_gpiod_release_array ,
sizeof ( struct gpio_descs * ) , GFP_KERNEL ) ;
if ( ! dr )
return ERR_PTR ( - ENOMEM ) ;
descs = gpiod_get_array ( dev , con_id , flags ) ;
if ( IS_ERR ( descs ) ) {
devres_free ( dr ) ;
return descs ;
}
* dr = descs ;
devres_add ( dev , dr ) ;
return descs ;
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpiod_get_array ) ;
2015-02-11 19:28:02 +03:00
/**
* devm_gpiod_get_array_optional - Resource - managed gpiod_get_array_optional ( )
* @ dev : GPIO consumer
* @ con_id : function within the GPIO consumer
* @ flags : optional GPIO initialization flags
*
* Managed gpiod_get_array_optional ( ) . GPIO descriptors returned from this
* function are automatically disposed on driver detach .
* See gpiod_get_array_optional ( ) for detailed information about behavior and
* return values .
*/
struct gpio_descs * __must_check
devm_gpiod_get_array_optional ( struct device * dev , const char * con_id ,
enum gpiod_flags flags )
{
struct gpio_descs * descs ;
descs = devm_gpiod_get_array ( dev , con_id , flags ) ;
2020-10-21 17:25:28 +03:00
if ( gpiod_not_found ( descs ) )
2015-02-11 19:28:02 +03:00
return NULL ;
return descs ;
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpiod_get_array_optional ) ;
2015-02-11 19:28:02 +03:00
2013-10-17 21:21:38 +04:00
/**
* devm_gpiod_put - Resource - managed gpiod_put ( )
2017-07-24 17:57:24 +03:00
* @ dev : GPIO consumer
2013-10-17 21:21:38 +04:00
* @ desc : GPIO descriptor to dispose of
*
* Dispose of a GPIO descriptor obtained with devm_gpiod_get ( ) or
* devm_gpiod_get_index ( ) . Normally this function will not be called as the GPIO
* will be disposed of by the resource management code .
*/
void devm_gpiod_put ( struct device * dev , struct gpio_desc * desc )
{
WARN_ON ( devres_release ( dev , devm_gpiod_release , devm_gpiod_match ,
& desc ) ) ;
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpiod_put ) ;
2013-10-17 21:21:38 +04:00
2018-12-06 15:43:46 +03:00
/**
* devm_gpiod_unhinge - Remove resource management from a gpio descriptor
* @ dev : GPIO consumer
* @ desc : GPIO descriptor to remove resource management from
*
* Remove resource management from a GPIO descriptor . This is needed when
* you want to hand over lifecycle management of a descriptor to another
* mechanism .
*/
void devm_gpiod_unhinge ( struct device * dev , struct gpio_desc * desc )
{
int ret ;
if ( IS_ERR_OR_NULL ( desc ) )
return ;
ret = devres_destroy ( dev , devm_gpiod_release ,
devm_gpiod_match , & desc ) ;
/*
* If the GPIO descriptor is requested as nonexclusive , we
* may call this function several times on the same descriptor
* so it is OK if devres_destroy ( ) returns - ENOENT .
*/
if ( ret = = - ENOENT )
return ;
/* Anything else we should warn about */
WARN_ON ( ret ) ;
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpiod_unhinge ) ;
2018-12-06 15:43:46 +03:00
2015-02-11 19:28:02 +03:00
/**
* devm_gpiod_put_array - Resource - managed gpiod_put_array ( )
2017-07-24 17:57:24 +03:00
* @ dev : GPIO consumer
2015-02-11 19:28:02 +03:00
* @ descs : GPIO descriptor array to dispose of
*
* Dispose of an array of GPIO descriptors obtained with devm_gpiod_get_array ( ) .
* Normally this function will not be called as the GPIOs will be disposed of
* by the resource management code .
*/
void devm_gpiod_put_array ( struct device * dev , struct gpio_descs * descs )
{
WARN_ON ( devres_release ( dev , devm_gpiod_release_array ,
devm_gpiod_match_array , & descs ) ) ;
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpiod_put_array ) ;
2015-02-11 19:28:02 +03:00
2011-12-21 00:40:21 +04:00
static void devm_gpio_release ( struct device * dev , void * res )
{
unsigned * gpio = res ;
gpio_free ( * gpio ) ;
}
/**
2013-06-04 19:48:36 +04:00
* devm_gpio_request - request a GPIO for a managed device
* @ dev : device to request the GPIO for
* @ gpio : GPIO to allocate
* @ label : the name of the requested GPIO
2011-12-21 00:40:21 +04:00
*
* Except for the extra @ dev argument , this function takes the
* same arguments and performs the same function as
* gpio_request ( ) . GPIOs requested with this function will be
* automatically freed on driver detach .
*/
int devm_gpio_request ( struct device * dev , unsigned gpio , const char * label )
{
unsigned * dr ;
int rc ;
dr = devres_alloc ( devm_gpio_release , sizeof ( unsigned ) , GFP_KERNEL ) ;
if ( ! dr )
return - ENOMEM ;
rc = gpio_request ( gpio , label ) ;
if ( rc ) {
devres_free ( dr ) ;
return rc ;
}
* dr = gpio ;
devres_add ( dev , dr ) ;
return 0 ;
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpio_request ) ;
2011-12-21 00:40:21 +04:00
2012-05-02 15:46:46 +04:00
/**
* devm_gpio_request_one - request a single GPIO with initial setup
* @ dev : device to request for
* @ gpio : the GPIO number
* @ flags : GPIO configuration as specified by GPIOF_ *
* @ label : a literal description string of this GPIO
*/
int devm_gpio_request_one ( struct device * dev , unsigned gpio ,
unsigned long flags , const char * label )
{
unsigned * dr ;
int rc ;
dr = devres_alloc ( devm_gpio_release , sizeof ( unsigned ) , GFP_KERNEL ) ;
if ( ! dr )
return - ENOMEM ;
rc = gpio_request_one ( gpio , flags , label ) ;
if ( rc ) {
devres_free ( dr ) ;
return rc ;
}
* dr = gpio ;
devres_add ( dev , dr ) ;
return 0 ;
}
2019-09-06 11:45:39 +03:00
EXPORT_SYMBOL_GPL ( devm_gpio_request_one ) ;
2012-05-02 15:46:46 +04:00
2020-11-10 12:39:21 +03:00
static void devm_gpio_chip_release ( void * data )
2020-03-13 11:15:22 +03:00
{
2020-11-10 12:39:21 +03:00
struct gpio_chip * gc = data ;
2020-03-13 11:15:22 +03:00
gpiochip_remove ( gc ) ;
}
/**
2020-07-31 15:38:36 +03:00
* devm_gpiochip_add_data_with_key ( ) - Resource managed gpiochip_add_data_with_key ( )
2020-03-13 11:15:22 +03:00
* @ dev : pointer to the device that gpio_chip belongs to .
* @ gc : the GPIO chip to register
* @ data : driver - private data associated with this chip
2020-07-31 15:38:36 +03:00
* @ lock_key : lockdep class for IRQ lock
* @ request_key : lockdep class for IRQ request
2020-03-13 11:15:22 +03:00
*
* Context : potentially before irqs will work
*
* The gpio chip automatically be released when the device is unbound .
*
* Returns :
* A negative errno if the chip can ' t be registered , such as because the
* gc - > base is invalid or already associated with a different chip .
* Otherwise it returns zero as a success code .
*/
2020-07-31 15:38:36 +03:00
int devm_gpiochip_add_data_with_key ( struct device * dev , struct gpio_chip * gc , void * data ,
struct lock_class_key * lock_key ,
struct lock_class_key * request_key )
2020-03-13 11:15:22 +03:00
{
int ret ;
2020-07-31 15:38:36 +03:00
ret = gpiochip_add_data_with_key ( gc , data , lock_key , request_key ) ;
2020-11-10 12:39:21 +03:00
if ( ret < 0 )
2020-03-13 11:15:22 +03:00
return ret ;
2020-11-10 12:39:21 +03:00
return devm_add_action_or_reset ( dev , devm_gpio_chip_release , gc ) ;
2020-03-13 11:15:22 +03:00
}
2020-07-31 15:38:36 +03:00
EXPORT_SYMBOL_GPL ( devm_gpiochip_add_data_with_key ) ;