aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorRyan Mallon <rmallon@gmail.com>2012-10-21 20:39:12 -0400
committerLinus Walleij <linus.walleij@linaro.org>2012-10-22 18:13:36 -0400
commitfc4e2514995d9cd7f3e1a67098ce65d72acf8ec7 (patch)
tree05cb8ff2fbf178fd5282e970173cac05f6e6c132 /drivers/gpio/gpiolib.c
parent67a0d4993d85ee2f42c9909127794553df69dd59 (diff)
gpiolib: Refactor gpio_export
The gpio_export function uses nested if statements and the status variable to handle the failure cases. This makes the function logic difficult to follow. Refactor the code to abort immediately on failure using goto. This makes the code slightly longer, but significantly reduces the nesting and number of split lines and makes the code easier to read. Signed-off-by: Ryan Mallon <rmallon@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c85
1 files changed, 46 insertions, 39 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 5d6c71edc739..d5f9742d9ac1 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -702,8 +702,9 @@ int gpio_export(unsigned gpio, bool direction_may_change)
702{ 702{
703 unsigned long flags; 703 unsigned long flags;
704 struct gpio_desc *desc; 704 struct gpio_desc *desc;
705 int status = -EINVAL; 705 int status;
706 const char *ioname = NULL; 706 const char *ioname = NULL;
707 struct device *dev;
707 708
708 /* can't export until sysfs is available ... */ 709 /* can't export until sysfs is available ... */
709 if (!gpio_class.p) { 710 if (!gpio_class.p) {
@@ -711,59 +712,65 @@ int gpio_export(unsigned gpio, bool direction_may_change)
711 return -ENOENT; 712 return -ENOENT;
712 } 713 }
713 714
714 if (!gpio_is_valid(gpio)) 715 if (!gpio_is_valid(gpio)) {
715 goto done; 716 pr_debug("%s: gpio %d is not valid\n", __func__, gpio);
717 return -EINVAL;
718 }
716 719
717 mutex_lock(&sysfs_lock); 720 mutex_lock(&sysfs_lock);
718 721
719 spin_lock_irqsave(&gpio_lock, flags); 722 spin_lock_irqsave(&gpio_lock, flags);
720 desc = &gpio_desc[gpio]; 723 desc = &gpio_desc[gpio];
721 if (test_bit(FLAG_REQUESTED, &desc->flags) 724 if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
722 && !test_bit(FLAG_EXPORT, &desc->flags)) { 725 test_bit(FLAG_EXPORT, &desc->flags)) {
723 status = 0; 726 spin_unlock_irqrestore(&gpio_lock, flags);
724 if (!desc->chip->direction_input 727 pr_debug("%s: gpio %d unavailable (requested=%d, exported=%d)\n",
725 || !desc->chip->direction_output) 728 __func__, gpio,
726 direction_may_change = false; 729 test_bit(FLAG_REQUESTED, &desc->flags),
730 test_bit(FLAG_EXPORT, &desc->flags));
731 return -EPERM;
727 } 732 }
733
734 if (!desc->chip->direction_input || !desc->chip->direction_output)
735 direction_may_change = false;
728 spin_unlock_irqrestore(&gpio_lock, flags); 736 spin_unlock_irqrestore(&gpio_lock, flags);
729 737
730 if (desc->chip->names && desc->chip->names[gpio - desc->chip->base]) 738 if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])
731 ioname = desc->chip->names[gpio - desc->chip->base]; 739 ioname = desc->chip->names[gpio - desc->chip->base];
732 740
733 if (status == 0) { 741 dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
734 struct device *dev; 742 desc, ioname ? ioname : "gpio%u", gpio);
735 743 if (IS_ERR(dev)) {
736 dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), 744 status = PTR_ERR(dev);
737 desc, ioname ? ioname : "gpio%u", gpio); 745 goto fail_unlock;
738 if (!IS_ERR(dev)) {
739 status = sysfs_create_group(&dev->kobj,
740 &gpio_attr_group);
741
742 if (!status && direction_may_change)
743 status = device_create_file(dev,
744 &dev_attr_direction);
745
746 if (!status && gpio_to_irq(gpio) >= 0
747 && (direction_may_change
748 || !test_bit(FLAG_IS_OUT,
749 &desc->flags)))
750 status = device_create_file(dev,
751 &dev_attr_edge);
752
753 if (status != 0)
754 device_unregister(dev);
755 } else
756 status = PTR_ERR(dev);
757 if (status == 0)
758 set_bit(FLAG_EXPORT, &desc->flags);
759 } 746 }
760 747
761 mutex_unlock(&sysfs_lock); 748 status = sysfs_create_group(&dev->kobj, &gpio_attr_group);
762
763done:
764 if (status) 749 if (status)
765 pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); 750 goto fail_unregister_device;
751
752 if (direction_may_change) {
753 status = device_create_file(dev, &dev_attr_direction);
754 if (status)
755 goto fail_unregister_device;
756 }
766 757
758 if (gpio_to_irq(gpio) >= 0 && (direction_may_change ||
759 !test_bit(FLAG_IS_OUT, &desc->flags))) {
760 status = device_create_file(dev, &dev_attr_edge);
761 if (status)
762 goto fail_unregister_device;
763 }
764
765 set_bit(FLAG_EXPORT, &desc->flags);
766 mutex_unlock(&sysfs_lock);
767 return 0;
768
769fail_unregister_device:
770 device_unregister(dev);
771fail_unlock:
772 mutex_unlock(&sysfs_lock);
773 pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);
767 return status; 774 return status;
768} 775}
769EXPORT_SYMBOL_GPL(gpio_export); 776EXPORT_SYMBOL_GPL(gpio_export);