diff options
-rw-r--r-- | Documentation/gpio.txt | 15 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 161 | ||||
-rw-r--r-- | include/asm-generic/gpio.h | 6 | ||||
-rw-r--r-- | include/linux/gpio.h | 6 |
4 files changed, 176 insertions, 12 deletions
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index e4e7daed2ba8..1866c27eec69 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt | |||
@@ -531,6 +531,13 @@ and have the following read/write attributes: | |||
531 | This file exists only if the pin can be configured as an | 531 | This file exists only if the pin can be configured as an |
532 | interrupt generating input pin. | 532 | interrupt generating input pin. |
533 | 533 | ||
534 | "active_low" ... reads as either 0 (false) or 1 (true). Write | ||
535 | any nonzero value to invert the value attribute both | ||
536 | for reading and writing. Existing and subsequent | ||
537 | poll(2) support configuration via the edge attribute | ||
538 | for "rising" and "falling" edges will follow this | ||
539 | setting. | ||
540 | |||
534 | GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the | 541 | GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the |
535 | controller implementing GPIOs starting at #42) and have the following | 542 | controller implementing GPIOs starting at #42) and have the following |
536 | read-only attributes: | 543 | read-only attributes: |
@@ -566,6 +573,8 @@ requested using gpio_request(): | |||
566 | int gpio_export_link(struct device *dev, const char *name, | 573 | int gpio_export_link(struct device *dev, const char *name, |
567 | unsigned gpio) | 574 | unsigned gpio) |
568 | 575 | ||
576 | /* change the polarity of a GPIO node in sysfs */ | ||
577 | int gpio_sysfs_set_active_low(unsigned gpio, int value); | ||
569 | 578 | ||
570 | After a kernel driver requests a GPIO, it may only be made available in | 579 | After a kernel driver requests a GPIO, it may only be made available in |
571 | the sysfs interface by gpio_export(). The driver can control whether the | 580 | the sysfs interface by gpio_export(). The driver can control whether the |
@@ -580,3 +589,9 @@ After the GPIO has been exported, gpio_export_link() allows creating | |||
580 | symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can | 589 | symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can |
581 | use this to provide the interface under their own device in sysfs with | 590 | use this to provide the interface under their own device in sysfs with |
582 | a descriptive name. | 591 | a descriptive name. |
592 | |||
593 | Drivers can use gpio_sysfs_set_active_low() to hide GPIO line polarity | ||
594 | differences between boards from user space. This only affects the | ||
595 | sysfs interface. Polarity change can be done both before and after | ||
596 | gpio_export(), and previously enabled poll(2) support for either | ||
597 | rising or falling edge will be reconfigured to follow this setting. | ||
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 50de0f5750d8..a25ad284a272 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -53,6 +53,7 @@ struct gpio_desc { | |||
53 | #define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */ | 53 | #define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */ |
54 | #define FLAG_TRIG_FALL 5 /* trigger on falling edge */ | 54 | #define FLAG_TRIG_FALL 5 /* trigger on falling edge */ |
55 | #define FLAG_TRIG_RISE 6 /* trigger on rising edge */ | 55 | #define FLAG_TRIG_RISE 6 /* trigger on rising edge */ |
56 | #define FLAG_ACTIVE_LOW 7 /* sysfs value has active low */ | ||
56 | 57 | ||
57 | #define PDESC_ID_SHIFT 16 /* add new flags before this one */ | 58 | #define PDESC_ID_SHIFT 16 /* add new flags before this one */ |
58 | 59 | ||
@@ -210,6 +211,11 @@ static DEFINE_MUTEX(sysfs_lock); | |||
210 | * * configures behavior of poll(2) on /value | 211 | * * configures behavior of poll(2) on /value |
211 | * * available only if pin can generate IRQs on input | 212 | * * available only if pin can generate IRQs on input |
212 | * * is read/write as "none", "falling", "rising", or "both" | 213 | * * is read/write as "none", "falling", "rising", or "both" |
214 | * /active_low | ||
215 | * * configures polarity of /value | ||
216 | * * is read/write as zero/nonzero | ||
217 | * * also affects existing and subsequent "falling" and "rising" | ||
218 | * /edge configuration | ||
213 | */ | 219 | */ |
214 | 220 | ||
215 | static ssize_t gpio_direction_show(struct device *dev, | 221 | static ssize_t gpio_direction_show(struct device *dev, |
@@ -255,7 +261,7 @@ static ssize_t gpio_direction_store(struct device *dev, | |||
255 | return status ? : size; | 261 | return status ? : size; |
256 | } | 262 | } |
257 | 263 | ||
258 | static const DEVICE_ATTR(direction, 0644, | 264 | static /* const */ DEVICE_ATTR(direction, 0644, |
259 | gpio_direction_show, gpio_direction_store); | 265 | gpio_direction_show, gpio_direction_store); |
260 | 266 | ||
261 | static ssize_t gpio_value_show(struct device *dev, | 267 | static ssize_t gpio_value_show(struct device *dev, |
@@ -267,10 +273,17 @@ static ssize_t gpio_value_show(struct device *dev, | |||
267 | 273 | ||
268 | mutex_lock(&sysfs_lock); | 274 | mutex_lock(&sysfs_lock); |
269 | 275 | ||
270 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | 276 | if (!test_bit(FLAG_EXPORT, &desc->flags)) { |
271 | status = -EIO; | 277 | status = -EIO; |
272 | else | 278 | } else { |
273 | status = sprintf(buf, "%d\n", !!gpio_get_value_cansleep(gpio)); | 279 | int value; |
280 | |||
281 | value = !!gpio_get_value_cansleep(gpio); | ||
282 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | ||
283 | value = !value; | ||
284 | |||
285 | status = sprintf(buf, "%d\n", value); | ||
286 | } | ||
274 | 287 | ||
275 | mutex_unlock(&sysfs_lock); | 288 | mutex_unlock(&sysfs_lock); |
276 | return status; | 289 | return status; |
@@ -294,6 +307,8 @@ static ssize_t gpio_value_store(struct device *dev, | |||
294 | 307 | ||
295 | status = strict_strtol(buf, 0, &value); | 308 | status = strict_strtol(buf, 0, &value); |
296 | if (status == 0) { | 309 | if (status == 0) { |
310 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | ||
311 | value = !value; | ||
297 | gpio_set_value_cansleep(gpio, value != 0); | 312 | gpio_set_value_cansleep(gpio, value != 0); |
298 | status = size; | 313 | status = size; |
299 | } | 314 | } |
@@ -303,7 +318,7 @@ static ssize_t gpio_value_store(struct device *dev, | |||
303 | return status; | 318 | return status; |
304 | } | 319 | } |
305 | 320 | ||
306 | static /*const*/ DEVICE_ATTR(value, 0644, | 321 | static const DEVICE_ATTR(value, 0644, |
307 | gpio_value_show, gpio_value_store); | 322 | gpio_value_show, gpio_value_store); |
308 | 323 | ||
309 | static irqreturn_t gpio_sysfs_irq(int irq, void *priv) | 324 | static irqreturn_t gpio_sysfs_irq(int irq, void *priv) |
@@ -352,9 +367,11 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, | |||
352 | 367 | ||
353 | irq_flags = IRQF_SHARED; | 368 | irq_flags = IRQF_SHARED; |
354 | if (test_bit(FLAG_TRIG_FALL, &gpio_flags)) | 369 | if (test_bit(FLAG_TRIG_FALL, &gpio_flags)) |
355 | irq_flags |= IRQF_TRIGGER_FALLING; | 370 | irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? |
371 | IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING; | ||
356 | if (test_bit(FLAG_TRIG_RISE, &gpio_flags)) | 372 | if (test_bit(FLAG_TRIG_RISE, &gpio_flags)) |
357 | irq_flags |= IRQF_TRIGGER_RISING; | 373 | irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? |
374 | IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; | ||
358 | 375 | ||
359 | if (!pdesc) { | 376 | if (!pdesc) { |
360 | pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL); | 377 | pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL); |
@@ -475,9 +492,79 @@ found: | |||
475 | 492 | ||
476 | static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store); | 493 | static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store); |
477 | 494 | ||
495 | static int sysfs_set_active_low(struct gpio_desc *desc, struct device *dev, | ||
496 | int value) | ||
497 | { | ||
498 | int status = 0; | ||
499 | |||
500 | if (!!test_bit(FLAG_ACTIVE_LOW, &desc->flags) == !!value) | ||
501 | return 0; | ||
502 | |||
503 | if (value) | ||
504 | set_bit(FLAG_ACTIVE_LOW, &desc->flags); | ||
505 | else | ||
506 | clear_bit(FLAG_ACTIVE_LOW, &desc->flags); | ||
507 | |||
508 | /* reconfigure poll(2) support if enabled on one edge only */ | ||
509 | if (dev != NULL && (!!test_bit(FLAG_TRIG_RISE, &desc->flags) ^ | ||
510 | !!test_bit(FLAG_TRIG_FALL, &desc->flags))) { | ||
511 | unsigned long trigger_flags = desc->flags & GPIO_TRIGGER_MASK; | ||
512 | |||
513 | gpio_setup_irq(desc, dev, 0); | ||
514 | status = gpio_setup_irq(desc, dev, trigger_flags); | ||
515 | } | ||
516 | |||
517 | return status; | ||
518 | } | ||
519 | |||
520 | static ssize_t gpio_active_low_show(struct device *dev, | ||
521 | struct device_attribute *attr, char *buf) | ||
522 | { | ||
523 | const struct gpio_desc *desc = dev_get_drvdata(dev); | ||
524 | ssize_t status; | ||
525 | |||
526 | mutex_lock(&sysfs_lock); | ||
527 | |||
528 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | ||
529 | status = -EIO; | ||
530 | else | ||
531 | status = sprintf(buf, "%d\n", | ||
532 | !!test_bit(FLAG_ACTIVE_LOW, &desc->flags)); | ||
533 | |||
534 | mutex_unlock(&sysfs_lock); | ||
535 | |||
536 | return status; | ||
537 | } | ||
538 | |||
539 | static ssize_t gpio_active_low_store(struct device *dev, | ||
540 | struct device_attribute *attr, const char *buf, size_t size) | ||
541 | { | ||
542 | struct gpio_desc *desc = dev_get_drvdata(dev); | ||
543 | ssize_t status; | ||
544 | |||
545 | mutex_lock(&sysfs_lock); | ||
546 | |||
547 | if (!test_bit(FLAG_EXPORT, &desc->flags)) { | ||
548 | status = -EIO; | ||
549 | } else { | ||
550 | long value; | ||
551 | |||
552 | status = strict_strtol(buf, 0, &value); | ||
553 | if (status == 0) | ||
554 | status = sysfs_set_active_low(desc, dev, value != 0); | ||
555 | } | ||
556 | |||
557 | mutex_unlock(&sysfs_lock); | ||
558 | |||
559 | return status ? : size; | ||
560 | } | ||
561 | |||
562 | static const DEVICE_ATTR(active_low, 0644, | ||
563 | gpio_active_low_show, gpio_active_low_store); | ||
564 | |||
478 | static const struct attribute *gpio_attrs[] = { | 565 | static const struct attribute *gpio_attrs[] = { |
479 | &dev_attr_direction.attr, | ||
480 | &dev_attr_value.attr, | 566 | &dev_attr_value.attr, |
567 | &dev_attr_active_low.attr, | ||
481 | NULL, | 568 | NULL, |
482 | }; | 569 | }; |
483 | 570 | ||
@@ -662,12 +749,12 @@ int gpio_export(unsigned gpio, bool direction_may_change) | |||
662 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), | 749 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), |
663 | desc, ioname ? ioname : "gpio%d", gpio); | 750 | desc, ioname ? ioname : "gpio%d", gpio); |
664 | if (!IS_ERR(dev)) { | 751 | if (!IS_ERR(dev)) { |
665 | if (direction_may_change) | 752 | status = sysfs_create_group(&dev->kobj, |
666 | status = sysfs_create_group(&dev->kobj, | ||
667 | &gpio_attr_group); | 753 | &gpio_attr_group); |
668 | else | 754 | |
755 | if (!status && direction_may_change) | ||
669 | status = device_create_file(dev, | 756 | status = device_create_file(dev, |
670 | &dev_attr_value); | 757 | &dev_attr_direction); |
671 | 758 | ||
672 | if (!status && gpio_to_irq(gpio) >= 0 | 759 | if (!status && gpio_to_irq(gpio) >= 0 |
673 | && (direction_may_change | 760 | && (direction_may_change |
@@ -744,6 +831,55 @@ done: | |||
744 | } | 831 | } |
745 | EXPORT_SYMBOL_GPL(gpio_export_link); | 832 | EXPORT_SYMBOL_GPL(gpio_export_link); |
746 | 833 | ||
834 | |||
835 | /** | ||
836 | * gpio_sysfs_set_active_low - set the polarity of gpio sysfs value | ||
837 | * @gpio: gpio to change | ||
838 | * @value: non-zero to use active low, i.e. inverted values | ||
839 | * | ||
840 | * Set the polarity of /sys/class/gpio/gpioN/value sysfs attribute. | ||
841 | * The GPIO does not have to be exported yet. If poll(2) support has | ||
842 | * been enabled for either rising or falling edge, it will be | ||
843 | * reconfigured to follow the new polarity. | ||
844 | * | ||
845 | * Returns zero on success, else an error. | ||
846 | */ | ||
847 | int gpio_sysfs_set_active_low(unsigned gpio, int value) | ||
848 | { | ||
849 | struct gpio_desc *desc; | ||
850 | struct device *dev = NULL; | ||
851 | int status = -EINVAL; | ||
852 | |||
853 | if (!gpio_is_valid(gpio)) | ||
854 | goto done; | ||
855 | |||
856 | mutex_lock(&sysfs_lock); | ||
857 | |||
858 | desc = &gpio_desc[gpio]; | ||
859 | |||
860 | if (test_bit(FLAG_EXPORT, &desc->flags)) { | ||
861 | struct device *dev; | ||
862 | |||
863 | dev = class_find_device(&gpio_class, NULL, desc, match_export); | ||
864 | if (dev == NULL) { | ||
865 | status = -ENODEV; | ||
866 | goto unlock; | ||
867 | } | ||
868 | } | ||
869 | |||
870 | status = sysfs_set_active_low(desc, dev, value); | ||
871 | |||
872 | unlock: | ||
873 | mutex_unlock(&sysfs_lock); | ||
874 | |||
875 | done: | ||
876 | if (status) | ||
877 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | ||
878 | |||
879 | return status; | ||
880 | } | ||
881 | EXPORT_SYMBOL_GPL(gpio_sysfs_set_active_low); | ||
882 | |||
747 | /** | 883 | /** |
748 | * gpio_unexport - reverse effect of gpio_export() | 884 | * gpio_unexport - reverse effect of gpio_export() |
749 | * @gpio: gpio to make unavailable | 885 | * @gpio: gpio to make unavailable |
@@ -1094,6 +1230,7 @@ void gpio_free(unsigned gpio) | |||
1094 | } | 1230 | } |
1095 | desc_set_label(desc, NULL); | 1231 | desc_set_label(desc, NULL); |
1096 | module_put(desc->chip->owner); | 1232 | module_put(desc->chip->owner); |
1233 | clear_bit(FLAG_ACTIVE_LOW, &desc->flags); | ||
1097 | clear_bit(FLAG_REQUESTED, &desc->flags); | 1234 | clear_bit(FLAG_REQUESTED, &desc->flags); |
1098 | } else | 1235 | } else |
1099 | WARN_ON(extra_checks); | 1236 | WARN_ON(extra_checks); |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 204bed37e82d..485eeb6c4ef3 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
@@ -145,6 +145,7 @@ extern int __gpio_to_irq(unsigned gpio); | |||
145 | extern int gpio_export(unsigned gpio, bool direction_may_change); | 145 | extern int gpio_export(unsigned gpio, bool direction_may_change); |
146 | extern int gpio_export_link(struct device *dev, const char *name, | 146 | extern int gpio_export_link(struct device *dev, const char *name, |
147 | unsigned gpio); | 147 | unsigned gpio); |
148 | extern int gpio_sysfs_set_active_low(unsigned gpio, int value); | ||
148 | extern void gpio_unexport(unsigned gpio); | 149 | extern void gpio_unexport(unsigned gpio); |
149 | 150 | ||
150 | #endif /* CONFIG_GPIO_SYSFS */ | 151 | #endif /* CONFIG_GPIO_SYSFS */ |
@@ -197,6 +198,11 @@ static inline int gpio_export_link(struct device *dev, const char *name, | |||
197 | return -ENOSYS; | 198 | return -ENOSYS; |
198 | } | 199 | } |
199 | 200 | ||
201 | static inline int gpio_sysfs_set_active_low(unsigned gpio, int value) | ||
202 | { | ||
203 | return -ENOSYS; | ||
204 | } | ||
205 | |||
200 | static inline void gpio_unexport(unsigned gpio) | 206 | static inline void gpio_unexport(unsigned gpio) |
201 | { | 207 | { |
202 | } | 208 | } |
diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 059bd189d35d..4e949a5b5b85 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h | |||
@@ -99,6 +99,12 @@ static inline int gpio_export_link(struct device *dev, const char *name, | |||
99 | return -EINVAL; | 99 | return -EINVAL; |
100 | } | 100 | } |
101 | 101 | ||
102 | static inline int gpio_sysfs_set_active_low(unsigned gpio, int value) | ||
103 | { | ||
104 | /* GPIO can never have been requested */ | ||
105 | WARN_ON(1); | ||
106 | return -EINVAL; | ||
107 | } | ||
102 | 108 | ||
103 | static inline void gpio_unexport(unsigned gpio) | 109 | static inline void gpio_unexport(unsigned gpio) |
104 | { | 110 | { |