gpiolib: allow exported GPIO nodes to be named using sysfs links

Commit 926b663ce8 (gpiolib: allow GPIOs to
be named) already provides naming on the chip level. This patch provides
more flexibility by allowing multiple names where ever in sysfs on a per
GPIO basis.

Adapted from David Brownell's comments on a similar concept:
http://lkml.org/lkml/2009/4/20/203.

[randy.dunlap@oracle.com: fix build for CONFIG_GENERIC_GPIO=n]
Signed-off-by: Jani Nikula <ext-jani.1.nikula@nokia.com>
Acked-by: David Brownell <david-b@pacbell.net>
Cc: Daniel Silverstone <dsilvers@simtec.co.uk>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Jani Nikula 2009-09-22 16:46:33 -07:00 committed by Linus Torvalds
parent d8c1acb166
commit a4177ee7f1
4 changed files with 74 additions and 0 deletions

View File

@ -555,6 +555,11 @@ requested using gpio_request():
/* reverse gpio_export() */ /* reverse gpio_export() */
void gpio_unexport(); void gpio_unexport();
/* create a sysfs link to an exported GPIO node */
int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
After a kernel driver requests a GPIO, it may only be made available in After a kernel driver requests a GPIO, it may only be made available in
the sysfs interface by gpio_export(). The driver can control whether the the sysfs interface by gpio_export(). The driver can control whether the
signal direction may change. This helps drivers prevent userspace code signal direction may change. This helps drivers prevent userspace code
@ -563,3 +568,8 @@ from accidentally clobbering important system state.
This explicit exporting can help with debugging (by making some kinds This explicit exporting can help with debugging (by making some kinds
of experiments easier), or can provide an always-there interface that's of experiments easier), or can provide an always-there interface that's
suitable for documenting as part of a board support package. suitable for documenting as part of a board support package.
After the GPIO has been exported, gpio_export_link() allows creating
symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
use this to provide the interface under their own device in sysfs with
a descriptive name.

View File

@ -504,6 +504,51 @@ static int match_export(struct device *dev, void *data)
return dev_get_drvdata(dev) == data; return dev_get_drvdata(dev) == data;
} }
/**
* gpio_export_link - create a sysfs link to an exported GPIO node
* @dev: device under which to create symlink
* @name: name of the symlink
* @gpio: gpio to create symlink to, already exported
*
* Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN
* node. Caller is responsible for unlinking.
*
* Returns zero on success, else an error.
*/
int gpio_export_link(struct device *dev, const char *name, 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 *tdev;
tdev = class_find_device(&gpio_class, NULL, desc, match_export);
if (tdev != NULL) {
status = sysfs_create_link(&dev->kobj, &tdev->kobj,
name);
} else {
status = -ENODEV;
}
}
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_link);
/** /**
* gpio_unexport - reverse effect of gpio_export() * gpio_unexport - reverse effect of gpio_export()
* @gpio: gpio to make unavailable * @gpio: gpio to make unavailable

View File

@ -141,6 +141,8 @@ extern int __gpio_to_irq(unsigned gpio);
* but more typically is configured entirely from userspace. * but more typically is configured entirely from userspace.
*/ */
extern int gpio_export(unsigned gpio, bool direction_may_change); extern int gpio_export(unsigned gpio, bool direction_may_change);
extern int gpio_export_link(struct device *dev, const char *name,
unsigned gpio);
extern void gpio_unexport(unsigned gpio); extern void gpio_unexport(unsigned gpio);
#endif /* CONFIG_GPIO_SYSFS */ #endif /* CONFIG_GPIO_SYSFS */
@ -185,6 +187,12 @@ static inline int gpio_export(unsigned gpio, bool direction_may_change)
return -ENOSYS; return -ENOSYS;
} }
static inline int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
{
return -ENOSYS;
}
static inline void gpio_unexport(unsigned gpio) static inline void gpio_unexport(unsigned gpio)
{ {
} }

View File

@ -12,6 +12,8 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/errno.h> #include <linux/errno.h>
struct device;
/* /*
* Some platforms don't support the GPIO programming interface. * Some platforms don't support the GPIO programming interface.
* *
@ -89,6 +91,15 @@ static inline int gpio_export(unsigned gpio, bool direction_may_change)
return -EINVAL; return -EINVAL;
} }
static inline int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
{
/* GPIO can never have been exported */
WARN_ON(1);
return -EINVAL;
}
static inline void gpio_unexport(unsigned gpio) static inline void gpio_unexport(unsigned gpio)
{ {
/* GPIO can never have been exported */ /* GPIO can never have been exported */