Commit 0769746183caff9d4334be48c7b0e7d2ec8716c4

Authored by Jani Nikula
Committed by Linus Torvalds
1 parent 35570ac603

gpiolib: add support for changing value polarity in sysfs

Drivers may use gpiolib sysfs as part of their public user space
interface. The GPIO number and polarity might change from board to
board. The gpio_export_link() call can be used to hide the GPIO number
from user space. Add support for also hiding the GPIO line polarity
changes from user space.

Signed-off-by: Jani Nikula <ext-jani.1.nikula@nokia.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 4 changed files with 176 additions and 12 deletions Side-by-side Diff

Documentation/gpio.txt
... ... @@ -531,6 +531,13 @@
531 531 This file exists only if the pin can be configured as an
532 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 541 GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
535 542 controller implementing GPIOs starting at #42) and have the following
536 543 read-only attributes:
... ... @@ -566,6 +573,8 @@
566 573 int gpio_export_link(struct device *dev, const char *name,
567 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 579 After a kernel driver requests a GPIO, it may only be made available in
571 580 the sysfs interface by gpio_export(). The driver can control whether the
... ... @@ -580,4 +589,10 @@
580 589 symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
581 590 use this to provide the interface under their own device in sysfs with
582 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.
drivers/gpio/gpiolib.c
... ... @@ -53,6 +53,7 @@
53 53 #define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */
54 54 #define FLAG_TRIG_FALL 5 /* trigger on falling edge */
55 55 #define FLAG_TRIG_RISE 6 /* trigger on rising edge */
  56 +#define FLAG_ACTIVE_LOW 7 /* sysfs value has active low */
56 57  
57 58 #define PDESC_ID_SHIFT 16 /* add new flags before this one */
58 59  
... ... @@ -210,6 +211,11 @@
210 211 * * configures behavior of poll(2) on /value
211 212 * * available only if pin can generate IRQs on input
212 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 221 static ssize_t gpio_direction_show(struct device *dev,
... ... @@ -255,7 +261,7 @@
255 261 return status ? : size;
256 262 }
257 263  
258   -static const DEVICE_ATTR(direction, 0644,
  264 +static /* const */ DEVICE_ATTR(direction, 0644,
259 265 gpio_direction_show, gpio_direction_store);
260 266  
261 267 static ssize_t gpio_value_show(struct device *dev,
262 268  
263 269  
... ... @@ -267,11 +273,18 @@
267 273  
268 274 mutex_lock(&sysfs_lock);
269 275  
270   - if (!test_bit(FLAG_EXPORT, &desc->flags))
  276 + if (!test_bit(FLAG_EXPORT, &desc->flags)) {
271 277 status = -EIO;
272   - else
273   - status = sprintf(buf, "%d\n", !!gpio_get_value_cansleep(gpio));
  278 + } else {
  279 + int value;
274 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 + }
  287 +
275 288 mutex_unlock(&sysfs_lock);
276 289 return status;
277 290 }
... ... @@ -294,6 +307,8 @@
294 307  
295 308 status = strict_strtol(buf, 0, &value);
296 309 if (status == 0) {
  310 + if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
  311 + value = !value;
297 312 gpio_set_value_cansleep(gpio, value != 0);
298 313 status = size;
299 314 }
... ... @@ -303,7 +318,7 @@
303 318 return status;
304 319 }
305 320  
306   -static /*const*/ DEVICE_ATTR(value, 0644,
  321 +static const DEVICE_ATTR(value, 0644,
307 322 gpio_value_show, gpio_value_store);
308 323  
309 324 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
310 325  
... ... @@ -352,9 +367,11 @@
352 367  
353 368 irq_flags = IRQF_SHARED;
354 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 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 376 if (!pdesc) {
360 377 pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL);
361 378  
362 379  
... ... @@ -475,9 +492,79 @@
475 492  
476 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 565 static const struct attribute *gpio_attrs[] = {
479   - &dev_attr_direction.attr,
480 566 &dev_attr_value.attr,
  567 + &dev_attr_active_low.attr,
481 568 NULL,
482 569 };
483 570  
484 571  
485 572  
... ... @@ -662,12 +749,12 @@
662 749 dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
663 750 desc, ioname ? ioname : "gpio%d", gpio);
664 751 if (!IS_ERR(dev)) {
665   - if (direction_may_change)
666   - status = sysfs_create_group(&dev->kobj,
  752 + status = sysfs_create_group(&dev->kobj,
667 753 &gpio_attr_group);
668   - else
  754 +
  755 + if (!status && direction_may_change)
669 756 status = device_create_file(dev,
670   - &dev_attr_value);
  757 + &dev_attr_direction);
671 758  
672 759 if (!status && gpio_to_irq(gpio) >= 0
673 760 && (direction_may_change
674 761  
... ... @@ -744,7 +831,56 @@
744 831 }
745 832 EXPORT_SYMBOL_GPL(gpio_export_link);
746 833  
  834 +
747 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 +
  883 +/**
748 884 * gpio_unexport - reverse effect of gpio_export()
749 885 * @gpio: gpio to make unavailable
750 886 *
... ... @@ -1094,6 +1230,7 @@
1094 1230 }
1095 1231 desc_set_label(desc, NULL);
1096 1232 module_put(desc->chip->owner);
  1233 + clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
1097 1234 clear_bit(FLAG_REQUESTED, &desc->flags);
1098 1235 } else
1099 1236 WARN_ON(extra_checks);
include/asm-generic/gpio.h
... ... @@ -145,6 +145,7 @@
145 145 extern int gpio_export(unsigned gpio, bool direction_may_change);
146 146 extern int gpio_export_link(struct device *dev, const char *name,
147 147 unsigned gpio);
  148 +extern int gpio_sysfs_set_active_low(unsigned gpio, int value);
148 149 extern void gpio_unexport(unsigned gpio);
149 150  
150 151 #endif /* CONFIG_GPIO_SYSFS */
... ... @@ -193,6 +194,11 @@
193 194  
194 195 static inline int gpio_export_link(struct device *dev, const char *name,
195 196 unsigned gpio)
  197 +{
  198 + return -ENOSYS;
  199 +}
  200 +
  201 +static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
196 202 {
197 203 return -ENOSYS;
198 204 }
include/linux/gpio.h
... ... @@ -99,6 +99,12 @@
99 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 109 static inline void gpio_unexport(unsigned gpio)
104 110 {