2008-02-05 09:28:20 +03:00
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/irq.h>
# include <linux/spinlock.h>
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
# include <linux/device.h>
# include <linux/err.h>
# include <linux/debugfs.h>
# include <linux/seq_file.h>
# include <linux/gpio.h>
2008-02-05 09:28:20 +03:00
/* Optional implementation infrastructure for GPIO interfaces.
*
* Platforms may want to use this if they tend to use very many GPIOs
* that aren ' t part of a System - On - Chip core ; or across I2C / SPI / etc .
*
* When kernel footprint or instruction count is an issue , simpler
* implementations may be preferred . The GPIO programming interface
* allows for inlining speed - critical get / set operations for common
* cases , so that access to SOC - integrated GPIOs can sometimes cost
* only an instruction or two per bit .
*/
/* When debugging, extend minimal trust to callers and platform code.
* Also emit diagnostic messages that may help initial bringup , when
* board setup or driver bugs are most common .
*
* Otherwise , minimize overhead in what may be bitbanging codepaths .
*/
# ifdef DEBUG
# define extra_checks 1
# else
# define extra_checks 0
# endif
/* gpio_lock prevents conflicts during gpio_desc[] table updates.
* While any GPIO is requested , its gpio_chip is not removable ;
* each GPIO ' s " requested " flag serves as a lock and refcount .
*/
static DEFINE_SPINLOCK ( gpio_lock ) ;
struct gpio_desc {
struct gpio_chip * chip ;
unsigned long flags ;
/* flag symbols are bit numbers */
# define FLAG_REQUESTED 0
# define FLAG_IS_OUT 1
2008-04-28 13:14:47 +04:00
# define FLAG_RESERVED 2
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
# define FLAG_EXPORT 3 /* protected by sysfs_lock */
# define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */
2008-02-05 09:28:20 +03:00
# ifdef CONFIG_DEBUG_FS
const char * label ;
# endif
} ;
static struct gpio_desc gpio_desc [ ARCH_NR_GPIOS ] ;
static inline void desc_set_label ( struct gpio_desc * d , const char * label )
{
# ifdef CONFIG_DEBUG_FS
d - > label = label ;
# endif
}
/* Warn when drivers omit gpio_request() calls -- legal but ill-advised
* when setting direction , and otherwise illegal . Until board setup code
* and drivers use explicit requests everywhere ( which won ' t happen when
* those calls have no teeth ) we can ' t avoid autorequesting . This nag
* message should motivate switching to explicit requests . . .
*/
static void gpio_ensure_requested ( struct gpio_desc * desc )
{
if ( test_and_set_bit ( FLAG_REQUESTED , & desc - > flags ) = = 0 ) {
pr_warning ( " GPIO-%d autorequested \n " , ( int ) ( desc - gpio_desc ) ) ;
desc_set_label ( desc , " [auto] " ) ;
2008-04-28 13:14:44 +04:00
if ( ! try_module_get ( desc - > chip - > owner ) )
pr_err ( " GPIO-%d: module can't be gotten \n " ,
( int ) ( desc - gpio_desc ) ) ;
2008-02-05 09:28:20 +03:00
}
}
/* caller holds gpio_lock *OR* gpio is marked as requested */
static inline struct gpio_chip * gpio_to_chip ( unsigned gpio )
{
return gpio_desc [ gpio ] . chip ;
}
2008-04-28 13:14:46 +04:00
/* dynamic allocation of GPIOs, e.g. on a hotplugged device */
static int gpiochip_find_base ( int ngpio )
{
int i ;
int spare = 0 ;
int base = - ENOSPC ;
for ( i = ARCH_NR_GPIOS - 1 ; i > = 0 ; i - - ) {
2008-04-28 13:14:47 +04:00
struct gpio_desc * desc = & gpio_desc [ i ] ;
struct gpio_chip * chip = desc - > chip ;
2008-04-28 13:14:46 +04:00
2008-04-28 13:14:47 +04:00
if ( ! chip & & ! test_bit ( FLAG_RESERVED , & desc - > flags ) ) {
2008-04-28 13:14:46 +04:00
spare + + ;
if ( spare = = ngpio ) {
base = i ;
break ;
}
} else {
spare = 0 ;
2008-04-28 13:14:47 +04:00
if ( chip )
i - = chip - > ngpio - 1 ;
2008-04-28 13:14:46 +04:00
}
}
if ( gpio_is_valid ( base ) )
pr_debug ( " %s: found new base at %d \n " , __func__ , base ) ;
return base ;
}
2008-04-28 13:14:47 +04:00
/**
* gpiochip_reserve ( ) - reserve range of gpios to use with platform code only
* @ start : starting gpio number
* @ ngpio : number of gpios to reserve
* Context : platform init , potentially before irqs or kmalloc will work
*
* Returns a negative errno if any gpio within the range is already reserved
* or registered , else returns zero as a success code . Use this function
* to mark a range of gpios as unavailable for dynamic gpio number allocation ,
* for example because its driver support is not yet loaded .
*/
int __init gpiochip_reserve ( int start , int ngpio )
{
int ret = 0 ;
unsigned long flags ;
int i ;
2008-05-24 00:04:44 +04:00
if ( ! gpio_is_valid ( start ) | | ! gpio_is_valid ( start + ngpio - 1 ) )
2008-04-28 13:14:47 +04:00
return - EINVAL ;
spin_lock_irqsave ( & gpio_lock , flags ) ;
for ( i = start ; i < start + ngpio ; i + + ) {
struct gpio_desc * desc = & gpio_desc [ i ] ;
if ( desc - > chip | | test_bit ( FLAG_RESERVED , & desc - > flags ) ) {
ret = - EBUSY ;
goto err ;
}
set_bit ( FLAG_RESERVED , & desc - > flags ) ;
}
pr_debug ( " %s: reserved gpios from %d to %d \n " ,
__func__ , start , start + ngpio - 1 ) ;
err :
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
return ret ;
}
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
# ifdef CONFIG_GPIO_SYSFS
/* lock protects against unexport_gpio() being called while
* sysfs files are active .
*/
static DEFINE_MUTEX ( sysfs_lock ) ;
/*
* / sys / class / gpio / gpioN . . . only for GPIOs that are exported
* / direction
* * MAY BE OMITTED if kernel won ' t allow direction changes
* * is read / write as " in " or " out "
* * may also be written as " high " or " low " , initializing
* output value as specified ( " out " implies " low " )
* / value
* * always readable , subject to hardware behavior
* * may be writable , as zero / nonzero
*
* REVISIT there will likely be an attribute for configuring async
* notifications , e . g . to specify polling interval or IRQ trigger type
* that would for example trigger a poll ( ) on the " value " .
*/
static ssize_t gpio_direction_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
const struct gpio_desc * desc = dev_get_drvdata ( dev ) ;
ssize_t status ;
mutex_lock ( & sysfs_lock ) ;
if ( ! test_bit ( FLAG_EXPORT , & desc - > flags ) )
status = - EIO ;
else
status = sprintf ( buf , " %s \n " ,
test_bit ( FLAG_IS_OUT , & desc - > flags )
? " out " : " in " ) ;
mutex_unlock ( & sysfs_lock ) ;
return status ;
}
static ssize_t gpio_direction_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t size )
{
const struct gpio_desc * desc = dev_get_drvdata ( dev ) ;
unsigned gpio = desc - gpio_desc ;
ssize_t status ;
mutex_lock ( & sysfs_lock ) ;
if ( ! test_bit ( FLAG_EXPORT , & desc - > flags ) )
status = - EIO ;
else if ( sysfs_streq ( buf , " high " ) )
status = gpio_direction_output ( gpio , 1 ) ;
else if ( sysfs_streq ( buf , " out " ) | | sysfs_streq ( buf , " low " ) )
status = gpio_direction_output ( gpio , 0 ) ;
else if ( sysfs_streq ( buf , " in " ) )
status = gpio_direction_input ( gpio ) ;
else
status = - EINVAL ;
mutex_unlock ( & sysfs_lock ) ;
return status ? : size ;
}
static const DEVICE_ATTR ( direction , 0644 ,
gpio_direction_show , gpio_direction_store ) ;
static ssize_t gpio_value_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
const struct gpio_desc * desc = dev_get_drvdata ( dev ) ;
unsigned gpio = desc - gpio_desc ;
ssize_t status ;
mutex_lock ( & sysfs_lock ) ;
if ( ! test_bit ( FLAG_EXPORT , & desc - > flags ) )
status = - EIO ;
else
status = sprintf ( buf , " %d \n " , gpio_get_value_cansleep ( gpio ) ) ;
mutex_unlock ( & sysfs_lock ) ;
return status ;
}
static ssize_t gpio_value_store ( struct device * dev ,
struct device_attribute * attr , const char * buf , size_t size )
{
const struct gpio_desc * desc = dev_get_drvdata ( dev ) ;
unsigned gpio = desc - gpio_desc ;
ssize_t status ;
mutex_lock ( & sysfs_lock ) ;
if ( ! test_bit ( FLAG_EXPORT , & desc - > flags ) )
status = - EIO ;
else if ( ! test_bit ( FLAG_IS_OUT , & desc - > flags ) )
status = - EPERM ;
else {
long value ;
status = strict_strtol ( buf , 0 , & value ) ;
if ( status = = 0 ) {
gpio_set_value_cansleep ( gpio , value ! = 0 ) ;
status = size ;
}
}
mutex_unlock ( & sysfs_lock ) ;
return status ;
}
static /*const*/ DEVICE_ATTR ( value , 0644 ,
gpio_value_show , gpio_value_store ) ;
static const struct attribute * gpio_attrs [ ] = {
& dev_attr_direction . attr ,
& dev_attr_value . attr ,
NULL ,
} ;
static const struct attribute_group gpio_attr_group = {
. attrs = ( struct attribute * * ) gpio_attrs ,
} ;
/*
* / sys / class / gpio / gpiochipN /
* / base . . . matching gpio_chip . base ( N )
* / label . . . matching gpio_chip . label
* / ngpio . . . matching gpio_chip . ngpio
*/
static ssize_t chip_base_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
const struct gpio_chip * chip = dev_get_drvdata ( dev ) ;
return sprintf ( buf , " %d \n " , chip - > base ) ;
}
static DEVICE_ATTR ( base , 0444 , chip_base_show , NULL ) ;
static ssize_t chip_label_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
const struct gpio_chip * chip = dev_get_drvdata ( dev ) ;
return sprintf ( buf , " %s \n " , chip - > label ? : " " ) ;
}
static DEVICE_ATTR ( label , 0444 , chip_label_show , NULL ) ;
static ssize_t chip_ngpio_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
const struct gpio_chip * chip = dev_get_drvdata ( dev ) ;
return sprintf ( buf , " %u \n " , chip - > ngpio ) ;
}
static DEVICE_ATTR ( ngpio , 0444 , chip_ngpio_show , NULL ) ;
static const struct attribute * gpiochip_attrs [ ] = {
& dev_attr_base . attr ,
& dev_attr_label . attr ,
& dev_attr_ngpio . attr ,
NULL ,
} ;
static const struct attribute_group gpiochip_attr_group = {
. attrs = ( struct attribute * * ) gpiochip_attrs ,
} ;
/*
* / sys / class / gpio / export . . . write - only
* integer N . . . number of GPIO to export ( full access )
* / sys / class / gpio / unexport . . . write - only
* integer N . . . number of GPIO to unexport
*/
static ssize_t export_store ( struct class * class , const char * buf , size_t len )
{
long gpio ;
int status ;
status = strict_strtol ( buf , 0 , & gpio ) ;
if ( status < 0 )
goto done ;
/* No extra locking here; FLAG_SYSFS just signifies that the
* request and export were done by on behalf of userspace , so
* they may be undone on its behalf too .
*/
status = gpio_request ( gpio , " sysfs " ) ;
if ( status < 0 )
goto done ;
status = gpio_export ( gpio , true ) ;
if ( status < 0 )
gpio_free ( gpio ) ;
else
set_bit ( FLAG_SYSFS , & gpio_desc [ gpio ] . flags ) ;
done :
if ( status )
pr_debug ( " %s: status %d \n " , __func__ , status ) ;
return status ? : len ;
}
static ssize_t unexport_store ( struct class * class , const char * buf , size_t len )
{
long gpio ;
int status ;
status = strict_strtol ( buf , 0 , & gpio ) ;
if ( status < 0 )
goto done ;
status = - EINVAL ;
/* reject bogus commands (gpio_unexport ignores them) */
if ( ! gpio_is_valid ( gpio ) )
goto done ;
/* No extra locking here; FLAG_SYSFS just signifies that the
* request and export were done by on behalf of userspace , so
* they may be undone on its behalf too .
*/
if ( test_and_clear_bit ( FLAG_SYSFS , & gpio_desc [ gpio ] . flags ) ) {
status = 0 ;
gpio_free ( gpio ) ;
}
done :
if ( status )
pr_debug ( " %s: status %d \n " , __func__ , status ) ;
return status ? : len ;
}
static struct class_attribute gpio_class_attrs [ ] = {
__ATTR ( export , 0200 , NULL , export_store ) ,
__ATTR ( unexport , 0200 , NULL , unexport_store ) ,
__ATTR_NULL ,
} ;
static struct class gpio_class = {
. name = " gpio " ,
. owner = THIS_MODULE ,
. class_attrs = gpio_class_attrs ,
} ;
/**
* gpio_export - export a GPIO through sysfs
* @ gpio : gpio to make available , already requested
* @ direction_may_change : true if userspace may change gpio direction
* Context : arch_initcall or later
*
* When drivers want to make a GPIO accessible to userspace after they
* have requested it - - perhaps while debugging , or as part of their
* public interface - - they may use this routine . If the GPIO can
* change direction ( some can ' t ) and the caller allows it , userspace
* will see " direction " sysfs attribute which may be used to change
* the gpio ' s direction . A " value " attribute will always be provided .
*
* Returns zero on success , else an error .
*/
int gpio_export ( unsigned gpio , bool direction_may_change )
{
unsigned long flags ;
struct gpio_desc * desc ;
int status = - EINVAL ;
/* can't export until sysfs is available ... */
if ( ! gpio_class . p ) {
pr_debug ( " %s: called too early! \n " , __func__ ) ;
return - ENOENT ;
}
if ( ! gpio_is_valid ( gpio ) )
goto done ;
mutex_lock ( & sysfs_lock ) ;
spin_lock_irqsave ( & gpio_lock , flags ) ;
desc = & gpio_desc [ gpio ] ;
if ( test_bit ( FLAG_REQUESTED , & desc - > flags )
& & ! test_bit ( FLAG_EXPORT , & desc - > flags ) ) {
status = 0 ;
if ( ! desc - > chip - > direction_input
| | ! desc - > chip - > direction_output )
direction_may_change = false ;
}
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
if ( status = = 0 ) {
struct device * dev ;
dev = device_create ( & gpio_class , desc - > chip - > dev , MKDEV ( 0 , 0 ) ,
desc , " gpio%d " , gpio ) ;
if ( dev ) {
if ( direction_may_change )
status = sysfs_create_group ( & dev - > kobj ,
& gpio_attr_group ) ;
else
status = device_create_file ( dev ,
& dev_attr_value ) ;
if ( status ! = 0 )
device_unregister ( dev ) ;
} else
status = - ENODEV ;
if ( status = = 0 )
set_bit ( FLAG_EXPORT , & desc - > flags ) ;
}
mutex_unlock ( & sysfs_lock ) ;
done :
if ( status )
pr_debug ( " %s: gpio%d status %d \n " , __func__ , gpio , status ) ;
return status ;
}
EXPORT_SYMBOL_GPL ( gpio_export ) ;
static int match_export ( struct device * dev , void * data )
{
return dev_get_drvdata ( dev ) = = data ;
}
/**
* gpio_unexport - reverse effect of gpio_export ( )
* @ gpio : gpio to make unavailable
*
* This is implicit on gpio_free ( ) .
*/
void gpio_unexport ( unsigned gpio )
{
struct gpio_desc * desc ;
int status = - EINVAL ;
if ( ! gpio_is_valid ( gpio ) )
goto done ;
mutex_lock ( & sysfs_lock ) ;
desc = & gpio_desc [ gpio ] ;
if ( test_bit ( FLAG_EXPORT , & desc - > flags ) ) {
struct device * dev = NULL ;
dev = class_find_device ( & gpio_class , NULL , desc , match_export ) ;
if ( dev ) {
clear_bit ( FLAG_EXPORT , & desc - > flags ) ;
put_device ( dev ) ;
device_unregister ( dev ) ;
status = 0 ;
} else
status = - ENODEV ;
}
mutex_unlock ( & sysfs_lock ) ;
done :
if ( status )
pr_debug ( " %s: gpio%d status %d \n " , __func__ , gpio , status ) ;
}
EXPORT_SYMBOL_GPL ( gpio_unexport ) ;
static int gpiochip_export ( struct gpio_chip * chip )
{
int status ;
struct device * dev ;
/* Many systems register gpio chips for SOC support very early,
* before driver model support is available . In those cases we
* export this later , in gpiolib_sysfs_init ( ) . . . here we just
* verify that _some_ field of gpio_class got initialized .
*/
if ( ! gpio_class . p )
return 0 ;
/* use chip->base for the ID; it's already known to be unique */
mutex_lock ( & sysfs_lock ) ;
dev = device_create ( & gpio_class , chip - > dev , MKDEV ( 0 , 0 ) , chip ,
" gpiochip%d " , chip - > base ) ;
if ( dev ) {
status = sysfs_create_group ( & dev - > kobj ,
& gpiochip_attr_group ) ;
} else
status = - ENODEV ;
chip - > exported = ( status = = 0 ) ;
mutex_unlock ( & sysfs_lock ) ;
if ( status ) {
unsigned long flags ;
unsigned gpio ;
spin_lock_irqsave ( & gpio_lock , flags ) ;
gpio = chip - > base ;
while ( gpio_desc [ gpio ] . chip = = chip )
gpio_desc [ gpio + + ] . chip = NULL ;
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
pr_debug ( " %s: chip %s status %d \n " , __func__ ,
chip - > label , status ) ;
}
return status ;
}
static void gpiochip_unexport ( struct gpio_chip * chip )
{
int status ;
struct device * dev ;
mutex_lock ( & sysfs_lock ) ;
dev = class_find_device ( & gpio_class , NULL , chip , match_export ) ;
if ( dev ) {
put_device ( dev ) ;
device_unregister ( dev ) ;
chip - > exported = 0 ;
status = 0 ;
} else
status = - ENODEV ;
mutex_unlock ( & sysfs_lock ) ;
if ( status )
pr_debug ( " %s: chip %s status %d \n " , __func__ ,
chip - > label , status ) ;
}
static int __init gpiolib_sysfs_init ( void )
{
int status ;
unsigned long flags ;
unsigned gpio ;
status = class_register ( & gpio_class ) ;
if ( status < 0 )
return status ;
/* Scan and register the gpio_chips which registered very
* early ( e . g . before the class_register above was called ) .
*
* We run before arch_initcall ( ) so chip - > dev nodes can have
* registered , and so arch_initcall ( ) can always gpio_export ( ) .
*/
spin_lock_irqsave ( & gpio_lock , flags ) ;
for ( gpio = 0 ; gpio < ARCH_NR_GPIOS ; gpio + + ) {
struct gpio_chip * chip ;
chip = gpio_desc [ gpio ] . chip ;
if ( ! chip | | chip - > exported )
continue ;
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
status = gpiochip_export ( chip ) ;
spin_lock_irqsave ( & gpio_lock , flags ) ;
}
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
return status ;
}
postcore_initcall ( gpiolib_sysfs_init ) ;
# else
static inline int gpiochip_export ( struct gpio_chip * chip )
{
return 0 ;
}
static inline void gpiochip_unexport ( struct gpio_chip * chip )
{
}
# endif /* CONFIG_GPIO_SYSFS */
2008-02-05 09:28:20 +03:00
/**
* gpiochip_add ( ) - register a gpio_chip
* @ chip : the chip to register , with chip - > base initialized
* Context : potentially before irqs or kmalloc will work
*
* Returns a negative errno if the chip can ' t be registered , such as
* because the chip - > base is invalid or already associated with a
* different chip . Otherwise it returns zero as a success code .
2008-04-28 13:14:46 +04:00
*
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
* When gpiochip_add ( ) is called very early during boot , so that GPIOs
* can be freely used , the chip - > dev device must be registered before
* the gpio framework ' s arch_initcall ( ) . Otherwise sysfs initialization
* for GPIOs will fail rudely .
*
2008-04-28 13:14:46 +04:00
* If chip - > base is negative , this requests dynamic assignment of
* a range of valid GPIOs .
2008-02-05 09:28:20 +03:00
*/
int gpiochip_add ( struct gpio_chip * chip )
{
unsigned long flags ;
int status = 0 ;
unsigned id ;
2008-04-28 13:14:46 +04:00
int base = chip - > base ;
2008-02-05 09:28:20 +03:00
2008-05-24 00:04:44 +04:00
if ( ( ! gpio_is_valid ( base ) | | ! gpio_is_valid ( base + chip - > ngpio - 1 ) )
2008-04-28 13:14:46 +04:00
& & base > = 0 ) {
2008-02-05 09:28:20 +03:00
status = - EINVAL ;
goto fail ;
}
spin_lock_irqsave ( & gpio_lock , flags ) ;
2008-04-28 13:14:46 +04:00
if ( base < 0 ) {
base = gpiochip_find_base ( chip - > ngpio ) ;
if ( base < 0 ) {
status = base ;
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
goto unlock ;
2008-04-28 13:14:46 +04:00
}
chip - > base = base ;
}
2008-02-05 09:28:20 +03:00
/* these GPIO numbers must not be managed by another gpio_chip */
2008-04-28 13:14:46 +04:00
for ( id = base ; id < base + chip - > ngpio ; id + + ) {
2008-02-05 09:28:20 +03:00
if ( gpio_desc [ id ] . chip ! = NULL ) {
status = - EBUSY ;
break ;
}
}
if ( status = = 0 ) {
2008-04-28 13:14:46 +04:00
for ( id = base ; id < base + chip - > ngpio ; id + + ) {
2008-02-05 09:28:20 +03:00
gpio_desc [ id ] . chip = chip ;
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
/* REVISIT: most hardware initializes GPIOs as
* inputs ( often with pullups enabled ) so power
* usage is minimized . Linux code should set the
* gpio direction first thing ; but until it does ,
* we may expose the wrong direction in sysfs .
*/
gpio_desc [ id ] . flags = ! chip - > direction_input
? ( 1 < < FLAG_IS_OUT )
: 0 ;
2008-02-05 09:28:20 +03:00
}
}
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
unlock :
2008-02-05 09:28:20 +03:00
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
if ( status = = 0 )
status = gpiochip_export ( chip ) ;
2008-02-05 09:28:20 +03:00
fail :
/* failures here can mean systems won't boot... */
if ( status )
pr_err ( " gpiochip_add: gpios %d..%d (%s) not registered \n " ,
2008-05-24 00:04:44 +04:00
chip - > base , chip - > base + chip - > ngpio - 1 ,
2008-02-05 09:28:20 +03:00
chip - > label ? : " generic " ) ;
return status ;
}
EXPORT_SYMBOL_GPL ( gpiochip_add ) ;
/**
* gpiochip_remove ( ) - unregister a gpio_chip
* @ chip : the chip to unregister
*
* A gpio_chip with any GPIOs still requested may not be removed .
*/
int gpiochip_remove ( struct gpio_chip * chip )
{
unsigned long flags ;
int status = 0 ;
unsigned id ;
spin_lock_irqsave ( & gpio_lock , flags ) ;
for ( id = chip - > base ; id < chip - > base + chip - > ngpio ; id + + ) {
if ( test_bit ( FLAG_REQUESTED , & gpio_desc [ id ] . flags ) ) {
status = - EBUSY ;
break ;
}
}
if ( status = = 0 ) {
for ( id = chip - > base ; id < chip - > base + chip - > ngpio ; id + + )
gpio_desc [ id ] . chip = NULL ;
}
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
if ( status = = 0 )
gpiochip_unexport ( chip ) ;
2008-02-05 09:28:20 +03:00
return status ;
}
EXPORT_SYMBOL_GPL ( gpiochip_remove ) ;
/* These "optional" allocation calls help prevent drivers from stomping
* on each other , and help provide better diagnostics in debugfs .
* They ' re called even less than the " set direction " calls .
*/
int gpio_request ( unsigned gpio , const char * label )
{
struct gpio_desc * desc ;
int status = - EINVAL ;
unsigned long flags ;
spin_lock_irqsave ( & gpio_lock , flags ) ;
2008-04-28 13:14:46 +04:00
if ( ! gpio_is_valid ( gpio ) )
2008-02-05 09:28:20 +03:00
goto done ;
desc = & gpio_desc [ gpio ] ;
if ( desc - > chip = = NULL )
goto done ;
2008-04-28 13:14:44 +04:00
if ( ! try_module_get ( desc - > chip - > owner ) )
goto done ;
2008-02-05 09:28:20 +03:00
/* NOTE: gpio_request() can be called in early boot,
* before IRQs are enabled .
*/
if ( test_and_set_bit ( FLAG_REQUESTED , & desc - > flags ) = = 0 ) {
desc_set_label ( desc , label ? : " ? " ) ;
status = 0 ;
2008-04-28 13:14:44 +04:00
} else {
2008-02-05 09:28:20 +03:00
status = - EBUSY ;
2008-04-28 13:14:44 +04:00
module_put ( desc - > chip - > owner ) ;
}
2008-02-05 09:28:20 +03:00
done :
if ( status )
pr_debug ( " gpio_request: gpio-%d (%s) status %d \n " ,
gpio , label ? : " ? " , status ) ;
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
return status ;
}
EXPORT_SYMBOL_GPL ( gpio_request ) ;
void gpio_free ( unsigned gpio )
{
unsigned long flags ;
struct gpio_desc * desc ;
2008-04-28 13:14:46 +04:00
if ( ! gpio_is_valid ( gpio ) ) {
2008-02-05 09:28:20 +03:00
WARN_ON ( extra_checks ) ;
return ;
}
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
gpio_unexport ( gpio ) ;
2008-02-05 09:28:20 +03:00
spin_lock_irqsave ( & gpio_lock , flags ) ;
desc = & gpio_desc [ gpio ] ;
2008-04-28 13:14:44 +04:00
if ( desc - > chip & & test_and_clear_bit ( FLAG_REQUESTED , & desc - > flags ) ) {
2008-02-05 09:28:20 +03:00
desc_set_label ( desc , NULL ) ;
2008-04-28 13:14:44 +04:00
module_put ( desc - > chip - > owner ) ;
} else
2008-02-05 09:28:20 +03:00
WARN_ON ( extra_checks ) ;
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
}
EXPORT_SYMBOL_GPL ( gpio_free ) ;
/**
* gpiochip_is_requested - return string iff signal was requested
* @ chip : controller managing the signal
* @ offset : of signal within controller ' s 0. . ( ngpio - 1 ) range
*
* Returns NULL if the GPIO is not currently requested , else a string .
* If debugfs support is enabled , the string returned is the label passed
* to gpio_request ( ) ; otherwise it is a meaningless constant .
*
* This function is for use by GPIO controller drivers . The label can
* help with diagnostics , and knowing that the signal is used as a GPIO
* can help avoid accidentally multiplexing it to another controller .
*/
const char * gpiochip_is_requested ( struct gpio_chip * chip , unsigned offset )
{
unsigned gpio = chip - > base + offset ;
2008-04-28 13:14:46 +04:00
if ( ! gpio_is_valid ( gpio ) | | gpio_desc [ gpio ] . chip ! = chip )
2008-02-05 09:28:20 +03:00
return NULL ;
if ( test_bit ( FLAG_REQUESTED , & gpio_desc [ gpio ] . flags ) = = 0 )
return NULL ;
# ifdef CONFIG_DEBUG_FS
return gpio_desc [ gpio ] . label ;
# else
return " ? " ;
# endif
}
EXPORT_SYMBOL_GPL ( gpiochip_is_requested ) ;
/* Drivers MUST set GPIO direction before making get/set calls. In
* some cases this is done in early boot , before IRQs are enabled .
*
* As a rule these aren ' t called more than once ( except for drivers
* using the open - drain emulation idiom ) so these are natural places
* to accumulate extra debugging checks . Note that we can ' t ( yet )
* rely on gpio_request ( ) having been called beforehand .
*/
int gpio_direction_input ( unsigned gpio )
{
unsigned long flags ;
struct gpio_chip * chip ;
struct gpio_desc * desc = & gpio_desc [ gpio ] ;
int status = - EINVAL ;
spin_lock_irqsave ( & gpio_lock , flags ) ;
2008-04-28 13:14:46 +04:00
if ( ! gpio_is_valid ( gpio ) )
2008-02-05 09:28:20 +03:00
goto fail ;
chip = desc - > chip ;
if ( ! chip | | ! chip - > get | | ! chip - > direction_input )
goto fail ;
gpio - = chip - > base ;
if ( gpio > = chip - > ngpio )
goto fail ;
gpio_ensure_requested ( desc ) ;
/* now we know the gpio is valid and chip won't vanish */
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
might_sleep_if ( extra_checks & & chip - > can_sleep ) ;
status = chip - > direction_input ( chip , gpio ) ;
if ( status = = 0 )
clear_bit ( FLAG_IS_OUT , & desc - > flags ) ;
return status ;
fail :
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
if ( status )
pr_debug ( " %s: gpio-%d status %d \n " ,
2008-04-30 11:54:57 +04:00
__func__ , gpio , status ) ;
2008-02-05 09:28:20 +03:00
return status ;
}
EXPORT_SYMBOL_GPL ( gpio_direction_input ) ;
int gpio_direction_output ( unsigned gpio , int value )
{
unsigned long flags ;
struct gpio_chip * chip ;
struct gpio_desc * desc = & gpio_desc [ gpio ] ;
int status = - EINVAL ;
spin_lock_irqsave ( & gpio_lock , flags ) ;
2008-04-28 13:14:46 +04:00
if ( ! gpio_is_valid ( gpio ) )
2008-02-05 09:28:20 +03:00
goto fail ;
chip = desc - > chip ;
if ( ! chip | | ! chip - > set | | ! chip - > direction_output )
goto fail ;
gpio - = chip - > base ;
if ( gpio > = chip - > ngpio )
goto fail ;
gpio_ensure_requested ( desc ) ;
/* now we know the gpio is valid and chip won't vanish */
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
might_sleep_if ( extra_checks & & chip - > can_sleep ) ;
status = chip - > direction_output ( chip , gpio , value ) ;
if ( status = = 0 )
set_bit ( FLAG_IS_OUT , & desc - > flags ) ;
return status ;
fail :
spin_unlock_irqrestore ( & gpio_lock , flags ) ;
if ( status )
pr_debug ( " %s: gpio-%d status %d \n " ,
2008-04-30 11:54:57 +04:00
__func__ , gpio , status ) ;
2008-02-05 09:28:20 +03:00
return status ;
}
EXPORT_SYMBOL_GPL ( gpio_direction_output ) ;
/* I/O calls are only valid after configuration completed; the relevant
* " is this a valid GPIO " error checks should already have been done .
*
* " Get " operations are often inlinable as reading a pin value register ,
* and masking the relevant bit in that register .
*
* When " set " operations are inlinable , they involve writing that mask to
* one register to set a low value , or a different register to set it high .
* Otherwise locking is needed , so there may be little value to inlining .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* IMPORTANT ! ! ! The hot paths - - get / set value - - assume that callers
* have requested the GPIO . That can include implicit requesting by
* a direction setting call . Marking a gpio as requested locks its chip
* in memory , guaranteeing that these table lookups need no more locking
* and that gpiochip_remove ( ) will fail .
*
* REVISIT when debugging , consider adding some instrumentation to ensure
* that the GPIO was actually requested .
*/
/**
* __gpio_get_value ( ) - return a gpio ' s value
* @ gpio : gpio whose value will be returned
* Context : any
*
* This is used directly or indirectly to implement gpio_get_value ( ) .
* It returns the zero or nonzero value provided by the associated
* gpio_chip . get ( ) method ; or zero if no such method is provided .
*/
int __gpio_get_value ( unsigned gpio )
{
struct gpio_chip * chip ;
chip = gpio_to_chip ( gpio ) ;
WARN_ON ( extra_checks & & chip - > can_sleep ) ;
return chip - > get ? chip - > get ( chip , gpio - chip - > base ) : 0 ;
}
EXPORT_SYMBOL_GPL ( __gpio_get_value ) ;
/**
* __gpio_set_value ( ) - assign a gpio ' s value
* @ gpio : gpio whose value will be assigned
* @ value : value to assign
* Context : any
*
* This is used directly or indirectly to implement gpio_set_value ( ) .
* It invokes the associated gpio_chip . set ( ) method .
*/
void __gpio_set_value ( unsigned gpio , int value )
{
struct gpio_chip * chip ;
chip = gpio_to_chip ( gpio ) ;
WARN_ON ( extra_checks & & chip - > can_sleep ) ;
chip - > set ( chip , gpio - chip - > base , value ) ;
}
EXPORT_SYMBOL_GPL ( __gpio_set_value ) ;
/**
* __gpio_cansleep ( ) - report whether gpio value access will sleep
* @ gpio : gpio in question
* Context : any
*
* This is used directly or indirectly to implement gpio_cansleep ( ) . It
* returns nonzero if access reading or writing the GPIO value can sleep .
*/
int __gpio_cansleep ( unsigned gpio )
{
struct gpio_chip * chip ;
/* only call this on GPIOs that are valid! */
chip = gpio_to_chip ( gpio ) ;
return chip - > can_sleep ;
}
EXPORT_SYMBOL_GPL ( __gpio_cansleep ) ;
/* There's no value in making it easy to inline GPIO calls that may sleep.
* Common examples include ones connected to I2C or SPI chips .
*/
int gpio_get_value_cansleep ( unsigned gpio )
{
struct gpio_chip * chip ;
might_sleep_if ( extra_checks ) ;
chip = gpio_to_chip ( gpio ) ;
return chip - > get ( chip , gpio - chip - > base ) ;
}
EXPORT_SYMBOL_GPL ( gpio_get_value_cansleep ) ;
void gpio_set_value_cansleep ( unsigned gpio , int value )
{
struct gpio_chip * chip ;
might_sleep_if ( extra_checks ) ;
chip = gpio_to_chip ( gpio ) ;
chip - > set ( chip , gpio - chip - > base , value ) ;
}
EXPORT_SYMBOL_GPL ( gpio_set_value_cansleep ) ;
# ifdef CONFIG_DEBUG_FS
static void gpiolib_dbg_show ( struct seq_file * s , struct gpio_chip * chip )
{
unsigned i ;
unsigned gpio = chip - > base ;
struct gpio_desc * gdesc = & gpio_desc [ gpio ] ;
int is_out ;
for ( i = 0 ; i < chip - > ngpio ; i + + , gpio + + , gdesc + + ) {
if ( ! test_bit ( FLAG_REQUESTED , & gdesc - > flags ) )
continue ;
is_out = test_bit ( FLAG_IS_OUT , & gdesc - > flags ) ;
seq_printf ( s , " gpio-%-3d (%-12s) %s %s " ,
gpio , gdesc - > label ,
is_out ? " out " : " in " ,
chip - > get
? ( chip - > get ( chip , i ) ? " hi " : " lo " )
: " ? " ) ;
if ( ! is_out ) {
int irq = gpio_to_irq ( gpio ) ;
struct irq_desc * desc = irq_desc + irq ;
/* This races with request_irq(), set_irq_type(),
* and set_irq_wake ( ) . . . but those are " rare " .
*
* More significantly , trigger type flags aren ' t
* currently maintained by genirq .
*/
if ( irq > = 0 & & desc - > action ) {
char * trigger ;
switch ( desc - > status & IRQ_TYPE_SENSE_MASK ) {
case IRQ_TYPE_NONE :
trigger = " (default) " ;
break ;
case IRQ_TYPE_EDGE_FALLING :
trigger = " edge-falling " ;
break ;
case IRQ_TYPE_EDGE_RISING :
trigger = " edge-rising " ;
break ;
case IRQ_TYPE_EDGE_BOTH :
trigger = " edge-both " ;
break ;
case IRQ_TYPE_LEVEL_HIGH :
trigger = " level-high " ;
break ;
case IRQ_TYPE_LEVEL_LOW :
trigger = " level-low " ;
break ;
default :
trigger = " ?trigger? " ;
break ;
}
seq_printf ( s , " irq-%d %s%s " ,
irq , trigger ,
( desc - > status & IRQ_WAKEUP )
? " wakeup " : " " ) ;
}
}
seq_printf ( s , " \n " ) ;
}
}
static int gpiolib_show ( struct seq_file * s , void * unused )
{
struct gpio_chip * chip = NULL ;
unsigned gpio ;
int started = 0 ;
/* REVISIT this isn't locked against gpio_chip removal ... */
2008-04-28 13:14:46 +04:00
for ( gpio = 0 ; gpio_is_valid ( gpio ) ; gpio + + ) {
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
struct device * dev ;
2008-02-05 09:28:20 +03:00
if ( chip = = gpio_desc [ gpio ] . chip )
continue ;
chip = gpio_desc [ gpio ] . chip ;
if ( ! chip )
continue ;
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
seq_printf ( s , " %sGPIOs %d-%d " ,
2008-02-05 09:28:20 +03:00
started ? " \n " : " " ,
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-07-25 12:46:07 +04:00
chip - > base , chip - > base + chip - > ngpio - 1 ) ;
dev = chip - > dev ;
if ( dev )
seq_printf ( s , " , %s/%s " ,
dev - > bus ? dev - > bus - > name : " no-bus " ,
dev - > bus_id ) ;
if ( chip - > label )
seq_printf ( s , " , %s " , chip - > label ) ;
if ( chip - > can_sleep )
seq_printf ( s , " , can sleep " ) ;
seq_printf ( s , " : \n " ) ;
2008-02-05 09:28:20 +03:00
started = 1 ;
if ( chip - > dbg_show )
chip - > dbg_show ( s , chip ) ;
else
gpiolib_dbg_show ( s , chip ) ;
}
return 0 ;
}
static int gpiolib_open ( struct inode * inode , struct file * file )
{
return single_open ( file , gpiolib_show , NULL ) ;
}
static struct file_operations gpiolib_operations = {
. open = gpiolib_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
} ;
static int __init gpiolib_debugfs_init ( void )
{
/* /sys/kernel/debug/gpio */
( void ) debugfs_create_file ( " gpio " , S_IFREG | S_IRUGO ,
NULL , NULL , & gpiolib_operations ) ;
return 0 ;
}
subsys_initcall ( gpiolib_debugfs_init ) ;
# endif /* DEBUG_FS */