diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 229 |
1 files changed, 214 insertions, 15 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 50de0f5750d8..eb0c3fe44b29 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/seq_file.h> | 9 | #include <linux/seq_file.h> |
10 | #include <linux/gpio.h> | 10 | #include <linux/gpio.h> |
11 | #include <linux/idr.h> | 11 | #include <linux/idr.h> |
12 | #include <linux/slab.h> | ||
12 | 13 | ||
13 | 14 | ||
14 | /* Optional implementation infrastructure for GPIO interfaces. | 15 | /* Optional implementation infrastructure for GPIO interfaces. |
@@ -53,6 +54,7 @@ struct gpio_desc { | |||
53 | #define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */ | 54 | #define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */ |
54 | #define FLAG_TRIG_FALL 5 /* trigger on falling edge */ | 55 | #define FLAG_TRIG_FALL 5 /* trigger on falling edge */ |
55 | #define FLAG_TRIG_RISE 6 /* trigger on rising edge */ | 56 | #define FLAG_TRIG_RISE 6 /* trigger on rising edge */ |
57 | #define FLAG_ACTIVE_LOW 7 /* sysfs value has active low */ | ||
56 | 58 | ||
57 | #define PDESC_ID_SHIFT 16 /* add new flags before this one */ | 59 | #define PDESC_ID_SHIFT 16 /* add new flags before this one */ |
58 | 60 | ||
@@ -210,6 +212,11 @@ static DEFINE_MUTEX(sysfs_lock); | |||
210 | * * configures behavior of poll(2) on /value | 212 | * * configures behavior of poll(2) on /value |
211 | * * available only if pin can generate IRQs on input | 213 | * * available only if pin can generate IRQs on input |
212 | * * is read/write as "none", "falling", "rising", or "both" | 214 | * * is read/write as "none", "falling", "rising", or "both" |
215 | * /active_low | ||
216 | * * configures polarity of /value | ||
217 | * * is read/write as zero/nonzero | ||
218 | * * also affects existing and subsequent "falling" and "rising" | ||
219 | * /edge configuration | ||
213 | */ | 220 | */ |
214 | 221 | ||
215 | static ssize_t gpio_direction_show(struct device *dev, | 222 | static ssize_t gpio_direction_show(struct device *dev, |
@@ -255,7 +262,7 @@ static ssize_t gpio_direction_store(struct device *dev, | |||
255 | return status ? : size; | 262 | return status ? : size; |
256 | } | 263 | } |
257 | 264 | ||
258 | static const DEVICE_ATTR(direction, 0644, | 265 | static /* const */ DEVICE_ATTR(direction, 0644, |
259 | gpio_direction_show, gpio_direction_store); | 266 | gpio_direction_show, gpio_direction_store); |
260 | 267 | ||
261 | static ssize_t gpio_value_show(struct device *dev, | 268 | static ssize_t gpio_value_show(struct device *dev, |
@@ -267,10 +274,17 @@ static ssize_t gpio_value_show(struct device *dev, | |||
267 | 274 | ||
268 | mutex_lock(&sysfs_lock); | 275 | mutex_lock(&sysfs_lock); |
269 | 276 | ||
270 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | 277 | if (!test_bit(FLAG_EXPORT, &desc->flags)) { |
271 | status = -EIO; | 278 | status = -EIO; |
272 | else | 279 | } else { |
273 | status = sprintf(buf, "%d\n", !!gpio_get_value_cansleep(gpio)); | 280 | int value; |
281 | |||
282 | value = !!gpio_get_value_cansleep(gpio); | ||
283 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | ||
284 | value = !value; | ||
285 | |||
286 | status = sprintf(buf, "%d\n", value); | ||
287 | } | ||
274 | 288 | ||
275 | mutex_unlock(&sysfs_lock); | 289 | mutex_unlock(&sysfs_lock); |
276 | return status; | 290 | return status; |
@@ -294,6 +308,8 @@ static ssize_t gpio_value_store(struct device *dev, | |||
294 | 308 | ||
295 | status = strict_strtol(buf, 0, &value); | 309 | status = strict_strtol(buf, 0, &value); |
296 | if (status == 0) { | 310 | if (status == 0) { |
311 | if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) | ||
312 | value = !value; | ||
297 | gpio_set_value_cansleep(gpio, value != 0); | 313 | gpio_set_value_cansleep(gpio, value != 0); |
298 | status = size; | 314 | status = size; |
299 | } | 315 | } |
@@ -303,7 +319,7 @@ static ssize_t gpio_value_store(struct device *dev, | |||
303 | return status; | 319 | return status; |
304 | } | 320 | } |
305 | 321 | ||
306 | static /*const*/ DEVICE_ATTR(value, 0644, | 322 | static const DEVICE_ATTR(value, 0644, |
307 | gpio_value_show, gpio_value_store); | 323 | gpio_value_show, gpio_value_store); |
308 | 324 | ||
309 | static irqreturn_t gpio_sysfs_irq(int irq, void *priv) | 325 | static irqreturn_t gpio_sysfs_irq(int irq, void *priv) |
@@ -352,9 +368,11 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, | |||
352 | 368 | ||
353 | irq_flags = IRQF_SHARED; | 369 | irq_flags = IRQF_SHARED; |
354 | if (test_bit(FLAG_TRIG_FALL, &gpio_flags)) | 370 | if (test_bit(FLAG_TRIG_FALL, &gpio_flags)) |
355 | irq_flags |= IRQF_TRIGGER_FALLING; | 371 | irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? |
372 | IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING; | ||
356 | if (test_bit(FLAG_TRIG_RISE, &gpio_flags)) | 373 | if (test_bit(FLAG_TRIG_RISE, &gpio_flags)) |
357 | irq_flags |= IRQF_TRIGGER_RISING; | 374 | irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ? |
375 | IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING; | ||
358 | 376 | ||
359 | if (!pdesc) { | 377 | if (!pdesc) { |
360 | pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL); | 378 | pdesc = kmalloc(sizeof(*pdesc), GFP_KERNEL); |
@@ -398,7 +416,8 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, | |||
398 | return 0; | 416 | return 0; |
399 | 417 | ||
400 | free_sd: | 418 | free_sd: |
401 | sysfs_put(pdesc->value_sd); | 419 | if (pdesc) |
420 | sysfs_put(pdesc->value_sd); | ||
402 | free_id: | 421 | free_id: |
403 | idr_remove(&pdesc_idr, id); | 422 | idr_remove(&pdesc_idr, id); |
404 | desc->flags &= GPIO_FLAGS_MASK; | 423 | desc->flags &= GPIO_FLAGS_MASK; |
@@ -475,9 +494,79 @@ found: | |||
475 | 494 | ||
476 | static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store); | 495 | static DEVICE_ATTR(edge, 0644, gpio_edge_show, gpio_edge_store); |
477 | 496 | ||
497 | static int sysfs_set_active_low(struct gpio_desc *desc, struct device *dev, | ||
498 | int value) | ||
499 | { | ||
500 | int status = 0; | ||
501 | |||
502 | if (!!test_bit(FLAG_ACTIVE_LOW, &desc->flags) == !!value) | ||
503 | return 0; | ||
504 | |||
505 | if (value) | ||
506 | set_bit(FLAG_ACTIVE_LOW, &desc->flags); | ||
507 | else | ||
508 | clear_bit(FLAG_ACTIVE_LOW, &desc->flags); | ||
509 | |||
510 | /* reconfigure poll(2) support if enabled on one edge only */ | ||
511 | if (dev != NULL && (!!test_bit(FLAG_TRIG_RISE, &desc->flags) ^ | ||
512 | !!test_bit(FLAG_TRIG_FALL, &desc->flags))) { | ||
513 | unsigned long trigger_flags = desc->flags & GPIO_TRIGGER_MASK; | ||
514 | |||
515 | gpio_setup_irq(desc, dev, 0); | ||
516 | status = gpio_setup_irq(desc, dev, trigger_flags); | ||
517 | } | ||
518 | |||
519 | return status; | ||
520 | } | ||
521 | |||
522 | static ssize_t gpio_active_low_show(struct device *dev, | ||
523 | struct device_attribute *attr, char *buf) | ||
524 | { | ||
525 | const struct gpio_desc *desc = dev_get_drvdata(dev); | ||
526 | ssize_t status; | ||
527 | |||
528 | mutex_lock(&sysfs_lock); | ||
529 | |||
530 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | ||
531 | status = -EIO; | ||
532 | else | ||
533 | status = sprintf(buf, "%d\n", | ||
534 | !!test_bit(FLAG_ACTIVE_LOW, &desc->flags)); | ||
535 | |||
536 | mutex_unlock(&sysfs_lock); | ||
537 | |||
538 | return status; | ||
539 | } | ||
540 | |||
541 | static ssize_t gpio_active_low_store(struct device *dev, | ||
542 | struct device_attribute *attr, const char *buf, size_t size) | ||
543 | { | ||
544 | struct gpio_desc *desc = dev_get_drvdata(dev); | ||
545 | ssize_t status; | ||
546 | |||
547 | mutex_lock(&sysfs_lock); | ||
548 | |||
549 | if (!test_bit(FLAG_EXPORT, &desc->flags)) { | ||
550 | status = -EIO; | ||
551 | } else { | ||
552 | long value; | ||
553 | |||
554 | status = strict_strtol(buf, 0, &value); | ||
555 | if (status == 0) | ||
556 | status = sysfs_set_active_low(desc, dev, value != 0); | ||
557 | } | ||
558 | |||
559 | mutex_unlock(&sysfs_lock); | ||
560 | |||
561 | return status ? : size; | ||
562 | } | ||
563 | |||
564 | static const DEVICE_ATTR(active_low, 0644, | ||
565 | gpio_active_low_show, gpio_active_low_store); | ||
566 | |||
478 | static const struct attribute *gpio_attrs[] = { | 567 | static const struct attribute *gpio_attrs[] = { |
479 | &dev_attr_direction.attr, | ||
480 | &dev_attr_value.attr, | 568 | &dev_attr_value.attr, |
569 | &dev_attr_active_low.attr, | ||
481 | NULL, | 570 | NULL, |
482 | }; | 571 | }; |
483 | 572 | ||
@@ -536,7 +625,9 @@ static const struct attribute_group gpiochip_attr_group = { | |||
536 | * /sys/class/gpio/unexport ... write-only | 625 | * /sys/class/gpio/unexport ... write-only |
537 | * integer N ... number of GPIO to unexport | 626 | * integer N ... number of GPIO to unexport |
538 | */ | 627 | */ |
539 | static ssize_t export_store(struct class *class, const char *buf, size_t len) | 628 | static ssize_t export_store(struct class *class, |
629 | struct class_attribute *attr, | ||
630 | const char *buf, size_t len) | ||
540 | { | 631 | { |
541 | long gpio; | 632 | long gpio; |
542 | int status; | 633 | int status; |
@@ -566,7 +657,9 @@ done: | |||
566 | return status ? : len; | 657 | return status ? : len; |
567 | } | 658 | } |
568 | 659 | ||
569 | static ssize_t unexport_store(struct class *class, const char *buf, size_t len) | 660 | static ssize_t unexport_store(struct class *class, |
661 | struct class_attribute *attr, | ||
662 | const char *buf, size_t len) | ||
570 | { | 663 | { |
571 | long gpio; | 664 | long gpio; |
572 | int status; | 665 | int status; |
@@ -662,12 +755,12 @@ int gpio_export(unsigned gpio, bool direction_may_change) | |||
662 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), | 755 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), |
663 | desc, ioname ? ioname : "gpio%d", gpio); | 756 | desc, ioname ? ioname : "gpio%d", gpio); |
664 | if (!IS_ERR(dev)) { | 757 | if (!IS_ERR(dev)) { |
665 | if (direction_may_change) | 758 | status = sysfs_create_group(&dev->kobj, |
666 | status = sysfs_create_group(&dev->kobj, | ||
667 | &gpio_attr_group); | 759 | &gpio_attr_group); |
668 | else | 760 | |
761 | if (!status && direction_may_change) | ||
669 | status = device_create_file(dev, | 762 | status = device_create_file(dev, |
670 | &dev_attr_value); | 763 | &dev_attr_direction); |
671 | 764 | ||
672 | if (!status && gpio_to_irq(gpio) >= 0 | 765 | if (!status && gpio_to_irq(gpio) >= 0 |
673 | && (direction_may_change | 766 | && (direction_may_change |
@@ -744,6 +837,53 @@ done: | |||
744 | } | 837 | } |
745 | EXPORT_SYMBOL_GPL(gpio_export_link); | 838 | EXPORT_SYMBOL_GPL(gpio_export_link); |
746 | 839 | ||
840 | |||
841 | /** | ||
842 | * gpio_sysfs_set_active_low - set the polarity of gpio sysfs value | ||
843 | * @gpio: gpio to change | ||
844 | * @value: non-zero to use active low, i.e. inverted values | ||
845 | * | ||
846 | * Set the polarity of /sys/class/gpio/gpioN/value sysfs attribute. | ||
847 | * The GPIO does not have to be exported yet. If poll(2) support has | ||
848 | * been enabled for either rising or falling edge, it will be | ||
849 | * reconfigured to follow the new polarity. | ||
850 | * | ||
851 | * Returns zero on success, else an error. | ||
852 | */ | ||
853 | int gpio_sysfs_set_active_low(unsigned gpio, int value) | ||
854 | { | ||
855 | struct gpio_desc *desc; | ||
856 | struct device *dev = NULL; | ||
857 | int status = -EINVAL; | ||
858 | |||
859 | if (!gpio_is_valid(gpio)) | ||
860 | goto done; | ||
861 | |||
862 | mutex_lock(&sysfs_lock); | ||
863 | |||
864 | desc = &gpio_desc[gpio]; | ||
865 | |||
866 | if (test_bit(FLAG_EXPORT, &desc->flags)) { | ||
867 | dev = class_find_device(&gpio_class, NULL, desc, match_export); | ||
868 | if (dev == NULL) { | ||
869 | status = -ENODEV; | ||
870 | goto unlock; | ||
871 | } | ||
872 | } | ||
873 | |||
874 | status = sysfs_set_active_low(desc, dev, value); | ||
875 | |||
876 | unlock: | ||
877 | mutex_unlock(&sysfs_lock); | ||
878 | |||
879 | done: | ||
880 | if (status) | ||
881 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | ||
882 | |||
883 | return status; | ||
884 | } | ||
885 | EXPORT_SYMBOL_GPL(gpio_sysfs_set_active_low); | ||
886 | |||
747 | /** | 887 | /** |
748 | * gpio_unexport - reverse effect of gpio_export() | 888 | * gpio_unexport - reverse effect of gpio_export() |
749 | * @gpio: gpio to make unavailable | 889 | * @gpio: gpio to make unavailable |
@@ -1094,6 +1234,7 @@ void gpio_free(unsigned gpio) | |||
1094 | } | 1234 | } |
1095 | desc_set_label(desc, NULL); | 1235 | desc_set_label(desc, NULL); |
1096 | module_put(desc->chip->owner); | 1236 | module_put(desc->chip->owner); |
1237 | clear_bit(FLAG_ACTIVE_LOW, &desc->flags); | ||
1097 | clear_bit(FLAG_REQUESTED, &desc->flags); | 1238 | clear_bit(FLAG_REQUESTED, &desc->flags); |
1098 | } else | 1239 | } else |
1099 | WARN_ON(extra_checks); | 1240 | WARN_ON(extra_checks); |
@@ -1102,6 +1243,64 @@ void gpio_free(unsigned gpio) | |||
1102 | } | 1243 | } |
1103 | EXPORT_SYMBOL_GPL(gpio_free); | 1244 | EXPORT_SYMBOL_GPL(gpio_free); |
1104 | 1245 | ||
1246 | /** | ||
1247 | * gpio_request_one - request a single GPIO with initial configuration | ||
1248 | * @gpio: the GPIO number | ||
1249 | * @flags: GPIO configuration as specified by GPIOF_* | ||
1250 | * @label: a literal description string of this GPIO | ||
1251 | */ | ||
1252 | int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) | ||
1253 | { | ||
1254 | int err; | ||
1255 | |||
1256 | err = gpio_request(gpio, label); | ||
1257 | if (err) | ||
1258 | return err; | ||
1259 | |||
1260 | if (flags & GPIOF_DIR_IN) | ||
1261 | err = gpio_direction_input(gpio); | ||
1262 | else | ||
1263 | err = gpio_direction_output(gpio, | ||
1264 | (flags & GPIOF_INIT_HIGH) ? 1 : 0); | ||
1265 | |||
1266 | return err; | ||
1267 | } | ||
1268 | EXPORT_SYMBOL_GPL(gpio_request_one); | ||
1269 | |||
1270 | /** | ||
1271 | * gpio_request_array - request multiple GPIOs in a single call | ||
1272 | * @array: array of the 'struct gpio' | ||
1273 | * @num: how many GPIOs in the array | ||
1274 | */ | ||
1275 | int gpio_request_array(struct gpio *array, size_t num) | ||
1276 | { | ||
1277 | int i, err; | ||
1278 | |||
1279 | for (i = 0; i < num; i++, array++) { | ||
1280 | err = gpio_request_one(array->gpio, array->flags, array->label); | ||
1281 | if (err) | ||
1282 | goto err_free; | ||
1283 | } | ||
1284 | return 0; | ||
1285 | |||
1286 | err_free: | ||
1287 | while (i--) | ||
1288 | gpio_free((--array)->gpio); | ||
1289 | return err; | ||
1290 | } | ||
1291 | EXPORT_SYMBOL_GPL(gpio_request_array); | ||
1292 | |||
1293 | /** | ||
1294 | * gpio_free_array - release multiple GPIOs in a single call | ||
1295 | * @array: array of the 'struct gpio' | ||
1296 | * @num: how many GPIOs in the array | ||
1297 | */ | ||
1298 | void gpio_free_array(struct gpio *array, size_t num) | ||
1299 | { | ||
1300 | while (num--) | ||
1301 | gpio_free((array++)->gpio); | ||
1302 | } | ||
1303 | EXPORT_SYMBOL_GPL(gpio_free_array); | ||
1105 | 1304 | ||
1106 | /** | 1305 | /** |
1107 | * gpiochip_is_requested - return string iff signal was requested | 1306 | * gpiochip_is_requested - return string iff signal was requested |