aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJani Nikula <ext-jani.1.nikula@nokia.com>2009-12-15 19:46:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-16 10:20:01 -0500
commit0769746183caff9d4334be48c7b0e7d2ec8716c4 (patch)
treee23768be82bd84cf8331709ecc1fd36c3d468f33 /drivers
parent35570ac6039ef490b9c5abde1fee4803a39bf4e1 (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/gpiolib.c161
1 files changed, 149 insertions, 12 deletions
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
215static ssize_t gpio_direction_show(struct device *dev, 221static 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
258static const DEVICE_ATTR(direction, 0644, 264static /* const */ DEVICE_ATTR(direction, 0644,
259 gpio_direction_show, gpio_direction_store); 265 gpio_direction_show, gpio_direction_store);
260 266
261static ssize_t gpio_value_show(struct device *dev, 267static 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
306static /*const*/ DEVICE_ATTR(value, 0644, 321static const DEVICE_ATTR(value, 0644,
307 gpio_value_show, gpio_value_store); 322 gpio_value_show, gpio_value_store);
308 323
309static irqreturn_t gpio_sysfs_irq(int irq, void *priv) 324static 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
476static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store); 493static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store);
477 494
495static 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
520static 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
539static 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
562static const DEVICE_ATTR(active_low, 0644,
563 gpio_active_low_show, gpio_active_low_store);
564
478static const struct attribute *gpio_attrs[] = { 565static 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}
745EXPORT_SYMBOL_GPL(gpio_export_link); 832EXPORT_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 */
847int 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
872unlock:
873 mutex_unlock(&sysfs_lock);
874
875done:
876 if (status)
877 pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
878
879 return status;
880}
881EXPORT_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);