aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/gpio.txt10
-rw-r--r--drivers/gpio/gpiolib.c45
-rw-r--r--include/asm-generic/gpio.h8
-rw-r--r--include/linux/gpio.h11
4 files changed, 74 insertions, 0 deletions
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index e4b6985044a2..566edaa56a53 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -555,6 +555,11 @@ requested using gpio_request():
555 /* reverse gpio_export() */ 555 /* reverse gpio_export() */
556 void gpio_unexport(); 556 void gpio_unexport();
557 557
558 /* create a sysfs link to an exported GPIO node */
559 int gpio_export_link(struct device *dev, const char *name,
560 unsigned gpio)
561
562
558After a kernel driver requests a GPIO, it may only be made available in 563After a kernel driver requests a GPIO, it may only be made available in
559the sysfs interface by gpio_export(). The driver can control whether the 564the sysfs interface by gpio_export(). The driver can control whether the
560signal direction may change. This helps drivers prevent userspace code 565signal direction may change. This helps drivers prevent userspace code
@@ -563,3 +568,8 @@ from accidentally clobbering important system state.
563This explicit exporting can help with debugging (by making some kinds 568This explicit exporting can help with debugging (by making some kinds
564of experiments easier), or can provide an always-there interface that's 569of experiments easier), or can provide an always-there interface that's
565suitable for documenting as part of a board support package. 570suitable for documenting as part of a board support package.
571
572After the GPIO has been exported, gpio_export_link() allows creating
573symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
574use this to provide the interface under their own device in sysfs with
575a descriptive name.
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 51a8d4103be5..aef6b3d8e2cf 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -505,6 +505,51 @@ static int match_export(struct device *dev, void *data)
505} 505}
506 506
507/** 507/**
508 * gpio_export_link - create a sysfs link to an exported GPIO node
509 * @dev: device under which to create symlink
510 * @name: name of the symlink
511 * @gpio: gpio to create symlink to, already exported
512 *
513 * Set up a symlink from /sys/.../dev/name to /sys/class/gpio/gpioN
514 * node. Caller is responsible for unlinking.
515 *
516 * Returns zero on success, else an error.
517 */
518int gpio_export_link(struct device *dev, const char *name, unsigned gpio)
519{
520 struct gpio_desc *desc;
521 int status = -EINVAL;
522
523 if (!gpio_is_valid(gpio))
524 goto done;
525
526 mutex_lock(&sysfs_lock);
527
528 desc = &gpio_desc[gpio];
529
530 if (test_bit(FLAG_EXPORT, &desc->flags)) {
531 struct device *tdev;
532
533 tdev = class_find_device(&gpio_class, NULL, desc, match_export);
534 if (tdev != NULL) {
535 status = sysfs_create_link(&dev->kobj, &tdev->kobj,
536 name);
537 } else {
538 status = -ENODEV;
539 }
540 }
541
542 mutex_unlock(&sysfs_lock);
543
544done:
545 if (status)
546 pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
547
548 return status;
549}
550EXPORT_SYMBOL_GPL(gpio_export_link);
551
552/**
508 * gpio_unexport - reverse effect of gpio_export() 553 * gpio_unexport - reverse effect of gpio_export()
509 * @gpio: gpio to make unavailable 554 * @gpio: gpio to make unavailable
510 * 555 *
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index d6c379dc64fa..9cca3785cab8 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -141,6 +141,8 @@ extern int __gpio_to_irq(unsigned gpio);
141 * but more typically is configured entirely from userspace. 141 * but more typically is configured entirely from userspace.
142 */ 142 */
143extern int gpio_export(unsigned gpio, bool direction_may_change); 143extern int gpio_export(unsigned gpio, bool direction_may_change);
144extern int gpio_export_link(struct device *dev, const char *name,
145 unsigned gpio);
144extern void gpio_unexport(unsigned gpio); 146extern void gpio_unexport(unsigned gpio);
145 147
146#endif /* CONFIG_GPIO_SYSFS */ 148#endif /* CONFIG_GPIO_SYSFS */
@@ -185,6 +187,12 @@ static inline int gpio_export(unsigned gpio, bool direction_may_change)
185 return -ENOSYS; 187 return -ENOSYS;
186} 188}
187 189
190static inline int gpio_export_link(struct device *dev, const char *name,
191 unsigned gpio)
192{
193 return -ENOSYS;
194}
195
188static inline void gpio_unexport(unsigned gpio) 196static inline void gpio_unexport(unsigned gpio)
189{ 197{
190} 198}
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index e10c49a5b96e..059bd189d35d 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -12,6 +12,8 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14 14
15struct device;
16
15/* 17/*
16 * Some platforms don't support the GPIO programming interface. 18 * Some platforms don't support the GPIO programming interface.
17 * 19 *
@@ -89,6 +91,15 @@ static inline int gpio_export(unsigned gpio, bool direction_may_change)
89 return -EINVAL; 91 return -EINVAL;
90} 92}
91 93
94static inline int gpio_export_link(struct device *dev, const char *name,
95 unsigned gpio)
96{
97 /* GPIO can never have been exported */
98 WARN_ON(1);
99 return -EINVAL;
100}
101
102
92static inline void gpio_unexport(unsigned gpio) 103static inline void gpio_unexport(unsigned gpio)
93{ 104{
94 /* GPIO can never have been exported */ 105 /* GPIO can never have been exported */