2011-12-21 00:40:21 +04:00
/*
* drivers / gpio / devres . c - managed gpio resources
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
* This file is based on kernel / irq / devres . c
*
* Copyright ( c ) 2011 John Crispin < blogic @ openwrt . org >
*/
# 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>
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
}
2015-02-11 13:52:37 +03:00
EXPORT_SYMBOL ( 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
}
2015-02-11 13:52:37 +03:00
EXPORT_SYMBOL ( 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 ;
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 ) ;
if ( ! dr )
return ERR_PTR ( - ENOMEM ) ;
2014-07-25 18:38:36 +04:00
desc = gpiod_get_index ( dev , con_id , idx , flags ) ;
2013-10-17 21:21:38 +04:00
if ( IS_ERR ( desc ) ) {
devres_free ( dr ) ;
return desc ;
}
* dr = desc ;
devres_add ( dev , dr ) ;
2013-10-21 02:14:57 +04:00
return desc ;
2013-10-17 21:21:38 +04:00
}
2015-02-11 13:52:37 +03:00
EXPORT_SYMBOL ( devm_gpiod_get_index ) ;
2013-10-17 21:21:38 +04:00
2014-10-21 15:33:59 +04:00
/**
* devm_get_gpiod_from_child - get a GPIO descriptor from a device ' s child node
* @ dev : GPIO consumer
2015-01-22 00:33:46 +03:00
* @ con_id : function within the GPIO consumer
2014-10-21 15:33:59 +04:00
* @ child : firmware node ( child of @ dev )
*
* GPIO descriptors returned from this function are automatically disposed on
* driver detach .
*/
struct gpio_desc * devm_get_gpiod_from_child ( struct device * dev ,
2015-01-22 00:33:46 +03:00
const char * con_id ,
2014-10-21 15:33:59 +04:00
struct fwnode_handle * child )
{
2015-03-11 14:21:17 +03:00
static const char * const suffixes [ ] = { " gpios " , " gpio " } ;
2015-01-22 00:33:46 +03:00
char prop_name [ 32 ] ; /* 32 is max size of property name */
2014-10-21 15:33:59 +04:00
struct gpio_desc * * dr ;
struct gpio_desc * desc ;
2015-01-22 00:33:46 +03:00
unsigned int i ;
2014-10-21 15:33:59 +04:00
dr = devres_alloc ( devm_gpiod_release , sizeof ( struct gpio_desc * ) ,
GFP_KERNEL ) ;
if ( ! dr )
return ERR_PTR ( - ENOMEM ) ;
2015-01-22 00:33:46 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( suffixes ) ; i + + ) {
if ( con_id )
snprintf ( prop_name , sizeof ( prop_name ) , " %s-%s " ,
con_id , suffixes [ i ] ) ;
else
snprintf ( prop_name , sizeof ( prop_name ) , " %s " ,
suffixes [ i ] ) ;
desc = fwnode_get_named_gpiod ( child , prop_name ) ;
2016-02-19 13:00:50 +03:00
if ( ! IS_ERR ( desc ) | | ( PTR_ERR ( desc ) ! = - ENOENT ) )
2015-01-22 00:33:46 +03:00
break ;
}
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 ;
}
EXPORT_SYMBOL ( devm_get_gpiod_from_child ) ;
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 ) ;
2014-04-25 19:10:06 +04:00
if ( IS_ERR ( desc ) ) {
if ( PTR_ERR ( desc ) = = - ENOENT )
return NULL ;
}
return desc ;
}
2015-02-11 13:52:37 +03:00
EXPORT_SYMBOL ( 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 ;
}
EXPORT_SYMBOL ( devm_gpiod_get_array ) ;
/**
* 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 ) ;
if ( IS_ERR ( descs ) & & ( PTR_ERR ( descs ) = = - ENOENT ) )
return NULL ;
return descs ;
}
EXPORT_SYMBOL ( devm_gpiod_get_array_optional ) ;
2013-10-17 21:21:38 +04:00
/**
* devm_gpiod_put - Resource - managed gpiod_put ( )
* @ 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 ) ) ;
}
EXPORT_SYMBOL ( devm_gpiod_put ) ;
2015-02-11 19:28:02 +03:00
/**
* devm_gpiod_put_array - Resource - managed gpiod_put_array ( )
* @ 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 ) ) ;
}
EXPORT_SYMBOL ( devm_gpiod_put_array ) ;
2013-10-17 21:21:38 +04: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 ) ;
}
static int devm_gpio_match ( struct device * dev , void * res , void * data )
{
unsigned * this = res , * gpio = data ;
return * this = = * 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 .
*
* If an GPIO allocated with this function needs to be freed
* separately , devm_gpio_free ( ) must be used .
*/
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 ;
}
EXPORT_SYMBOL ( devm_gpio_request ) ;
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 ;
}
2012-06-08 03:56:09 +04:00
EXPORT_SYMBOL ( devm_gpio_request_one ) ;
2012-05-02 15:46:46 +04:00
2011-12-21 00:40:21 +04:00
/**
2013-06-04 19:48:36 +04:00
* devm_gpio_free - free a GPIO
* @ dev : device to free GPIO for
* @ gpio : GPIO to free
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_free ( ) .
* This function instead of gpio_free ( ) should be used to manually
* free GPIOs allocated with devm_gpio_request ( ) .
*/
void devm_gpio_free ( struct device * dev , unsigned int gpio )
{
2012-05-03 21:15:14 +04:00
WARN_ON ( devres_release ( dev , devm_gpio_release , devm_gpio_match ,
2011-12-21 00:40:21 +04:00
& gpio ) ) ;
}
EXPORT_SYMBOL ( devm_gpio_free ) ;