diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 16:00:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 16:00:56 -0500 |
commit | b0885d01f9ab1274109c02942c881d598f939623 (patch) | |
tree | 8c0e33fa141f2732a5c8e0e2db8b457d5cd865f9 /drivers/gpio/gpiolib.c | |
parent | bad73c5aa069f1f14cc07ce7bbae8d463635560c (diff) | |
parent | fc13d5a5b17c657b7682c145d367dcb859c507d9 (diff) |
Merge tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6
Pull GPIO updates from Grant Likely:
"GPIO follow up patch and type change for v3.5 merge window
Primarily device driver additions, features and bug fixes. Not much
touching gpio common subsystem support. Should not be scary."
* tag 'gpio-for-linus' of git://git.secretlab.ca/git/linux-2.6: (34 commits)
gpio: Provide the STMPE GPIO driver with its own IRQ Domain
gpio: add TS-5500 DIO blocks support
gpio: pcf857x: use client->irq for gpio_to_irq()
gpio: stmpe: Add DT support for stmpe gpio
gpio: pl061 depends on ARM
gpio/pl061: remove old comment
gpio: SPEAr: add spi chipselect control driver
gpio: gpio-max710x: Support device tree probing
gpio: twl4030: Use only TWL4030_MODULE_LED for LED configuration
gpio: tegra: read output value when gpio is set in direction_out
gpio: pca953x: Add compatible strings to gpio-pca953x driver
gpio: pca953x: Register an IRQ domain
gpio: mvebu: Set free callback for gpio_chip
gpio: tegra: Drop exporting static functions
gpio: tegra: Staticize non-exported symbols
gpio: tegra: fix suspend/resume apis
gpio-pch: Set parent dev for gpio chip
gpio: em: Fix build errors
GPIO: clps711x: use platform_device_unregister in gpio_clps711x_init()
gpio/tc3589x: convert to use the simple irqdomain
...
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 124 |
1 files changed, 84 insertions, 40 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 58b9838801c0..199fca15f270 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -191,6 +191,32 @@ err: | |||
191 | return ret; | 191 | return ret; |
192 | } | 192 | } |
193 | 193 | ||
194 | /* caller ensures gpio is valid and requested, chip->get_direction may sleep */ | ||
195 | static int gpio_get_direction(unsigned gpio) | ||
196 | { | ||
197 | struct gpio_chip *chip; | ||
198 | struct gpio_desc *desc = &gpio_desc[gpio]; | ||
199 | int status = -EINVAL; | ||
200 | |||
201 | chip = gpio_to_chip(gpio); | ||
202 | gpio -= chip->base; | ||
203 | |||
204 | if (!chip->get_direction) | ||
205 | return status; | ||
206 | |||
207 | status = chip->get_direction(chip, gpio); | ||
208 | if (status > 0) { | ||
209 | /* GPIOF_DIR_IN, or other positive */ | ||
210 | status = 1; | ||
211 | clear_bit(FLAG_IS_OUT, &desc->flags); | ||
212 | } | ||
213 | if (status == 0) { | ||
214 | /* GPIOF_DIR_OUT */ | ||
215 | set_bit(FLAG_IS_OUT, &desc->flags); | ||
216 | } | ||
217 | return status; | ||
218 | } | ||
219 | |||
194 | #ifdef CONFIG_GPIO_SYSFS | 220 | #ifdef CONFIG_GPIO_SYSFS |
195 | 221 | ||
196 | /* lock protects against unexport_gpio() being called while | 222 | /* lock protects against unexport_gpio() being called while |
@@ -223,6 +249,7 @@ static ssize_t gpio_direction_show(struct device *dev, | |||
223 | struct device_attribute *attr, char *buf) | 249 | struct device_attribute *attr, char *buf) |
224 | { | 250 | { |
225 | const struct gpio_desc *desc = dev_get_drvdata(dev); | 251 | const struct gpio_desc *desc = dev_get_drvdata(dev); |
252 | unsigned gpio = desc - gpio_desc; | ||
226 | ssize_t status; | 253 | ssize_t status; |
227 | 254 | ||
228 | mutex_lock(&sysfs_lock); | 255 | mutex_lock(&sysfs_lock); |
@@ -230,6 +257,7 @@ static ssize_t gpio_direction_show(struct device *dev, | |||
230 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | 257 | if (!test_bit(FLAG_EXPORT, &desc->flags)) |
231 | status = -EIO; | 258 | status = -EIO; |
232 | else | 259 | else |
260 | gpio_get_direction(gpio); | ||
233 | status = sprintf(buf, "%s\n", | 261 | status = sprintf(buf, "%s\n", |
234 | test_bit(FLAG_IS_OUT, &desc->flags) | 262 | test_bit(FLAG_IS_OUT, &desc->flags) |
235 | ? "out" : "in"); | 263 | ? "out" : "in"); |
@@ -704,8 +732,9 @@ int gpio_export(unsigned gpio, bool direction_may_change) | |||
704 | { | 732 | { |
705 | unsigned long flags; | 733 | unsigned long flags; |
706 | struct gpio_desc *desc; | 734 | struct gpio_desc *desc; |
707 | int status = -EINVAL; | 735 | int status; |
708 | const char *ioname = NULL; | 736 | const char *ioname = NULL; |
737 | struct device *dev; | ||
709 | 738 | ||
710 | /* can't export until sysfs is available ... */ | 739 | /* can't export until sysfs is available ... */ |
711 | if (!gpio_class.p) { | 740 | if (!gpio_class.p) { |
@@ -713,59 +742,66 @@ int gpio_export(unsigned gpio, bool direction_may_change) | |||
713 | return -ENOENT; | 742 | return -ENOENT; |
714 | } | 743 | } |
715 | 744 | ||
716 | if (!gpio_is_valid(gpio)) | 745 | if (!gpio_is_valid(gpio)) { |
717 | goto done; | 746 | pr_debug("%s: gpio %d is not valid\n", __func__, gpio); |
747 | return -EINVAL; | ||
748 | } | ||
718 | 749 | ||
719 | mutex_lock(&sysfs_lock); | 750 | mutex_lock(&sysfs_lock); |
720 | 751 | ||
721 | spin_lock_irqsave(&gpio_lock, flags); | 752 | spin_lock_irqsave(&gpio_lock, flags); |
722 | desc = &gpio_desc[gpio]; | 753 | desc = &gpio_desc[gpio]; |
723 | if (test_bit(FLAG_REQUESTED, &desc->flags) | 754 | if (!test_bit(FLAG_REQUESTED, &desc->flags) || |
724 | && !test_bit(FLAG_EXPORT, &desc->flags)) { | 755 | test_bit(FLAG_EXPORT, &desc->flags)) { |
725 | status = 0; | 756 | spin_unlock_irqrestore(&gpio_lock, flags); |
726 | if (!desc->chip->direction_input | 757 | pr_debug("%s: gpio %d unavailable (requested=%d, exported=%d)\n", |
727 | || !desc->chip->direction_output) | 758 | __func__, gpio, |
728 | direction_may_change = false; | 759 | test_bit(FLAG_REQUESTED, &desc->flags), |
760 | test_bit(FLAG_EXPORT, &desc->flags)); | ||
761 | status = -EPERM; | ||
762 | goto fail_unlock; | ||
729 | } | 763 | } |
764 | |||
765 | if (!desc->chip->direction_input || !desc->chip->direction_output) | ||
766 | direction_may_change = false; | ||
730 | spin_unlock_irqrestore(&gpio_lock, flags); | 767 | spin_unlock_irqrestore(&gpio_lock, flags); |
731 | 768 | ||
732 | if (desc->chip->names && desc->chip->names[gpio - desc->chip->base]) | 769 | if (desc->chip->names && desc->chip->names[gpio - desc->chip->base]) |
733 | ioname = desc->chip->names[gpio - desc->chip->base]; | 770 | ioname = desc->chip->names[gpio - desc->chip->base]; |
734 | 771 | ||
735 | if (status == 0) { | 772 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), |
736 | struct device *dev; | 773 | desc, ioname ? ioname : "gpio%u", gpio); |
737 | 774 | if (IS_ERR(dev)) { | |
738 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), | 775 | status = PTR_ERR(dev); |
739 | desc, ioname ? ioname : "gpio%u", gpio); | 776 | goto fail_unlock; |
740 | if (!IS_ERR(dev)) { | ||
741 | status = sysfs_create_group(&dev->kobj, | ||
742 | &gpio_attr_group); | ||
743 | |||
744 | if (!status && direction_may_change) | ||
745 | status = device_create_file(dev, | ||
746 | &dev_attr_direction); | ||
747 | |||
748 | if (!status && gpio_to_irq(gpio) >= 0 | ||
749 | && (direction_may_change | ||
750 | || !test_bit(FLAG_IS_OUT, | ||
751 | &desc->flags))) | ||
752 | status = device_create_file(dev, | ||
753 | &dev_attr_edge); | ||
754 | |||
755 | if (status != 0) | ||
756 | device_unregister(dev); | ||
757 | } else | ||
758 | status = PTR_ERR(dev); | ||
759 | if (status == 0) | ||
760 | set_bit(FLAG_EXPORT, &desc->flags); | ||
761 | } | 777 | } |
762 | 778 | ||
763 | mutex_unlock(&sysfs_lock); | 779 | status = sysfs_create_group(&dev->kobj, &gpio_attr_group); |
764 | |||
765 | done: | ||
766 | if (status) | 780 | if (status) |
767 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | 781 | goto fail_unregister_device; |
768 | 782 | ||
783 | if (direction_may_change) { | ||
784 | status = device_create_file(dev, &dev_attr_direction); | ||
785 | if (status) | ||
786 | goto fail_unregister_device; | ||
787 | } | ||
788 | |||
789 | if (gpio_to_irq(gpio) >= 0 && (direction_may_change || | ||
790 | !test_bit(FLAG_IS_OUT, &desc->flags))) { | ||
791 | status = device_create_file(dev, &dev_attr_edge); | ||
792 | if (status) | ||
793 | goto fail_unregister_device; | ||
794 | } | ||
795 | |||
796 | set_bit(FLAG_EXPORT, &desc->flags); | ||
797 | mutex_unlock(&sysfs_lock); | ||
798 | return 0; | ||
799 | |||
800 | fail_unregister_device: | ||
801 | device_unregister(dev); | ||
802 | fail_unlock: | ||
803 | mutex_unlock(&sysfs_lock); | ||
804 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | ||
769 | return status; | 805 | return status; |
770 | } | 806 | } |
771 | EXPORT_SYMBOL_GPL(gpio_export); | 807 | EXPORT_SYMBOL_GPL(gpio_export); |
@@ -1075,6 +1111,7 @@ int gpiochip_add(struct gpio_chip *chip) | |||
1075 | * inputs (often with pullups enabled) so power | 1111 | * inputs (often with pullups enabled) so power |
1076 | * usage is minimized. Linux code should set the | 1112 | * usage is minimized. Linux code should set the |
1077 | * gpio direction first thing; but until it does, | 1113 | * gpio direction first thing; but until it does, |
1114 | * and in case chip->get_direction is not set, | ||
1078 | * we may expose the wrong direction in sysfs. | 1115 | * we may expose the wrong direction in sysfs. |
1079 | */ | 1116 | */ |
1080 | gpio_desc[id].flags = !chip->direction_input | 1117 | gpio_desc[id].flags = !chip->direction_input |
@@ -1304,9 +1341,15 @@ int gpio_request(unsigned gpio, const char *label) | |||
1304 | desc_set_label(desc, NULL); | 1341 | desc_set_label(desc, NULL); |
1305 | module_put(chip->owner); | 1342 | module_put(chip->owner); |
1306 | clear_bit(FLAG_REQUESTED, &desc->flags); | 1343 | clear_bit(FLAG_REQUESTED, &desc->flags); |
1344 | goto done; | ||
1307 | } | 1345 | } |
1308 | } | 1346 | } |
1309 | 1347 | if (chip->get_direction) { | |
1348 | /* chip->get_direction may sleep */ | ||
1349 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
1350 | gpio_get_direction(gpio); | ||
1351 | spin_lock_irqsave(&gpio_lock, flags); | ||
1352 | } | ||
1310 | done: | 1353 | done: |
1311 | if (status) | 1354 | if (status) |
1312 | pr_debug("gpio_request: gpio-%d (%s) status %d\n", | 1355 | pr_debug("gpio_request: gpio-%d (%s) status %d\n", |
@@ -1842,6 +1885,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
1842 | if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) | 1885 | if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) |
1843 | continue; | 1886 | continue; |
1844 | 1887 | ||
1888 | gpio_get_direction(gpio); | ||
1845 | is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); | 1889 | is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); |
1846 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s", | 1890 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s", |
1847 | gpio, gdesc->label, | 1891 | gpio, gdesc->label, |