diff options
-rw-r--r-- | Documentation/gpio.txt | 4 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 91 | ||||
-rw-r--r-- | include/asm-generic/gpio.h | 9 |
3 files changed, 91 insertions, 13 deletions
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index 8a7c45956d24..b1b988701247 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt | |||
@@ -240,6 +240,10 @@ signal, or (b) something wrongly believes it's safe to remove drivers | |||
240 | needed to manage a signal that's in active use. That is, requesting a | 240 | needed to manage a signal that's in active use. That is, requesting a |
241 | GPIO can serve as a kind of lock. | 241 | GPIO can serve as a kind of lock. |
242 | 242 | ||
243 | Some platforms may also use knowledge about what GPIOs are active for | ||
244 | power management, such as by powering down unused chip sectors and, more | ||
245 | easily, gating off unused clocks. | ||
246 | |||
243 | These two calls are optional because not not all current Linux platforms | 247 | These two calls are optional because not not all current Linux platforms |
244 | offer such functionality in their GPIO support; a valid implementation | 248 | offer such functionality in their GPIO support; a valid implementation |
245 | could return success for all gpio_request() calls. Unlike the other calls, | 249 | could return success for all gpio_request() calls. Unlike the other calls, |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 29a7e6b1be5d..9112830107a5 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -67,17 +67,28 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label) | |||
67 | * when setting direction, and otherwise illegal. Until board setup code | 67 | * when setting direction, and otherwise illegal. Until board setup code |
68 | * and drivers use explicit requests everywhere (which won't happen when | 68 | * and drivers use explicit requests everywhere (which won't happen when |
69 | * those calls have no teeth) we can't avoid autorequesting. This nag | 69 | * those calls have no teeth) we can't avoid autorequesting. This nag |
70 | * message should motivate switching to explicit requests... | 70 | * message should motivate switching to explicit requests... so should |
71 | * the weaker cleanup after faults, compared to gpio_request(). | ||
71 | */ | 72 | */ |
72 | static void gpio_ensure_requested(struct gpio_desc *desc) | 73 | static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset) |
73 | { | 74 | { |
74 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { | 75 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { |
75 | pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc)); | 76 | struct gpio_chip *chip = desc->chip; |
77 | int gpio = chip->base + offset; | ||
78 | |||
79 | if (!try_module_get(chip->owner)) { | ||
80 | pr_err("GPIO-%d: module can't be gotten \n", gpio); | ||
81 | clear_bit(FLAG_REQUESTED, &desc->flags); | ||
82 | /* lose */ | ||
83 | return -EIO; | ||
84 | } | ||
85 | pr_warning("GPIO-%d autorequested\n", gpio); | ||
76 | desc_set_label(desc, "[auto]"); | 86 | desc_set_label(desc, "[auto]"); |
77 | if (!try_module_get(desc->chip->owner)) | 87 | /* caller must chip->request() w/o spinlock */ |
78 | pr_err("GPIO-%d: module can't be gotten \n", | 88 | if (chip->request) |
79 | (int)(desc - gpio_desc)); | 89 | return 1; |
80 | } | 90 | } |
91 | return 0; | ||
81 | } | 92 | } |
82 | 93 | ||
83 | /* caller holds gpio_lock *OR* gpio is marked as requested */ | 94 | /* caller holds gpio_lock *OR* gpio is marked as requested */ |
@@ -752,6 +763,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove); | |||
752 | int gpio_request(unsigned gpio, const char *label) | 763 | int gpio_request(unsigned gpio, const char *label) |
753 | { | 764 | { |
754 | struct gpio_desc *desc; | 765 | struct gpio_desc *desc; |
766 | struct gpio_chip *chip; | ||
755 | int status = -EINVAL; | 767 | int status = -EINVAL; |
756 | unsigned long flags; | 768 | unsigned long flags; |
757 | 769 | ||
@@ -760,14 +772,15 @@ int gpio_request(unsigned gpio, const char *label) | |||
760 | if (!gpio_is_valid(gpio)) | 772 | if (!gpio_is_valid(gpio)) |
761 | goto done; | 773 | goto done; |
762 | desc = &gpio_desc[gpio]; | 774 | desc = &gpio_desc[gpio]; |
763 | if (desc->chip == NULL) | 775 | chip = desc->chip; |
776 | if (chip == NULL) | ||
764 | goto done; | 777 | goto done; |
765 | 778 | ||
766 | if (!try_module_get(desc->chip->owner)) | 779 | if (!try_module_get(chip->owner)) |
767 | goto done; | 780 | goto done; |
768 | 781 | ||
769 | /* NOTE: gpio_request() can be called in early boot, | 782 | /* NOTE: gpio_request() can be called in early boot, |
770 | * before IRQs are enabled. | 783 | * before IRQs are enabled, for non-sleeping (SOC) GPIOs. |
771 | */ | 784 | */ |
772 | 785 | ||
773 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { | 786 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { |
@@ -775,7 +788,20 @@ int gpio_request(unsigned gpio, const char *label) | |||
775 | status = 0; | 788 | status = 0; |
776 | } else { | 789 | } else { |
777 | status = -EBUSY; | 790 | status = -EBUSY; |
778 | module_put(desc->chip->owner); | 791 | module_put(chip->owner); |
792 | } | ||
793 | |||
794 | if (chip->request) { | ||
795 | /* chip->request may sleep */ | ||
796 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
797 | status = chip->request(chip, gpio - chip->base); | ||
798 | spin_lock_irqsave(&gpio_lock, flags); | ||
799 | |||
800 | if (status < 0) { | ||
801 | desc_set_label(desc, NULL); | ||
802 | module_put(chip->owner); | ||
803 | clear_bit(FLAG_REQUESTED, &desc->flags); | ||
804 | } | ||
779 | } | 805 | } |
780 | 806 | ||
781 | done: | 807 | done: |
@@ -791,6 +817,7 @@ void gpio_free(unsigned gpio) | |||
791 | { | 817 | { |
792 | unsigned long flags; | 818 | unsigned long flags; |
793 | struct gpio_desc *desc; | 819 | struct gpio_desc *desc; |
820 | struct gpio_chip *chip; | ||
794 | 821 | ||
795 | might_sleep(); | 822 | might_sleep(); |
796 | 823 | ||
@@ -804,9 +831,17 @@ void gpio_free(unsigned gpio) | |||
804 | spin_lock_irqsave(&gpio_lock, flags); | 831 | spin_lock_irqsave(&gpio_lock, flags); |
805 | 832 | ||
806 | desc = &gpio_desc[gpio]; | 833 | desc = &gpio_desc[gpio]; |
807 | if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) { | 834 | chip = desc->chip; |
835 | if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) { | ||
836 | if (chip->free) { | ||
837 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
838 | might_sleep_if(extra_checks && chip->can_sleep); | ||
839 | chip->free(chip, gpio - chip->base); | ||
840 | spin_lock_irqsave(&gpio_lock, flags); | ||
841 | } | ||
808 | desc_set_label(desc, NULL); | 842 | desc_set_label(desc, NULL); |
809 | module_put(desc->chip->owner); | 843 | module_put(desc->chip->owner); |
844 | clear_bit(FLAG_REQUESTED, &desc->flags); | ||
810 | } else | 845 | } else |
811 | WARN_ON(extra_checks); | 846 | WARN_ON(extra_checks); |
812 | 847 | ||
@@ -871,7 +906,9 @@ int gpio_direction_input(unsigned gpio) | |||
871 | gpio -= chip->base; | 906 | gpio -= chip->base; |
872 | if (gpio >= chip->ngpio) | 907 | if (gpio >= chip->ngpio) |
873 | goto fail; | 908 | goto fail; |
874 | gpio_ensure_requested(desc); | 909 | status = gpio_ensure_requested(desc, gpio); |
910 | if (status < 0) | ||
911 | goto fail; | ||
875 | 912 | ||
876 | /* now we know the gpio is valid and chip won't vanish */ | 913 | /* now we know the gpio is valid and chip won't vanish */ |
877 | 914 | ||
@@ -879,9 +916,22 @@ int gpio_direction_input(unsigned gpio) | |||
879 | 916 | ||
880 | might_sleep_if(extra_checks && chip->can_sleep); | 917 | might_sleep_if(extra_checks && chip->can_sleep); |
881 | 918 | ||
919 | if (status) { | ||
920 | status = chip->request(chip, gpio); | ||
921 | if (status < 0) { | ||
922 | pr_debug("GPIO-%d: chip request fail, %d\n", | ||
923 | chip->base + gpio, status); | ||
924 | /* and it's not available to anyone else ... | ||
925 | * gpio_request() is the fully clean solution. | ||
926 | */ | ||
927 | goto lose; | ||
928 | } | ||
929 | } | ||
930 | |||
882 | status = chip->direction_input(chip, gpio); | 931 | status = chip->direction_input(chip, gpio); |
883 | if (status == 0) | 932 | if (status == 0) |
884 | clear_bit(FLAG_IS_OUT, &desc->flags); | 933 | clear_bit(FLAG_IS_OUT, &desc->flags); |
934 | lose: | ||
885 | return status; | 935 | return status; |
886 | fail: | 936 | fail: |
887 | spin_unlock_irqrestore(&gpio_lock, flags); | 937 | spin_unlock_irqrestore(&gpio_lock, flags); |
@@ -909,7 +959,9 @@ int gpio_direction_output(unsigned gpio, int value) | |||
909 | gpio -= chip->base; | 959 | gpio -= chip->base; |
910 | if (gpio >= chip->ngpio) | 960 | if (gpio >= chip->ngpio) |
911 | goto fail; | 961 | goto fail; |
912 | gpio_ensure_requested(desc); | 962 | status = gpio_ensure_requested(desc, gpio); |
963 | if (status < 0) | ||
964 | goto fail; | ||
913 | 965 | ||
914 | /* now we know the gpio is valid and chip won't vanish */ | 966 | /* now we know the gpio is valid and chip won't vanish */ |
915 | 967 | ||
@@ -917,9 +969,22 @@ int gpio_direction_output(unsigned gpio, int value) | |||
917 | 969 | ||
918 | might_sleep_if(extra_checks && chip->can_sleep); | 970 | might_sleep_if(extra_checks && chip->can_sleep); |
919 | 971 | ||
972 | if (status) { | ||
973 | status = chip->request(chip, gpio); | ||
974 | if (status < 0) { | ||
975 | pr_debug("GPIO-%d: chip request fail, %d\n", | ||
976 | chip->base + gpio, status); | ||
977 | /* and it's not available to anyone else ... | ||
978 | * gpio_request() is the fully clean solution. | ||
979 | */ | ||
980 | goto lose; | ||
981 | } | ||
982 | } | ||
983 | |||
920 | status = chip->direction_output(chip, gpio, value); | 984 | status = chip->direction_output(chip, gpio, value); |
921 | if (status == 0) | 985 | if (status == 0) |
922 | set_bit(FLAG_IS_OUT, &desc->flags); | 986 | set_bit(FLAG_IS_OUT, &desc->flags); |
987 | lose: | ||
923 | return status; | 988 | return status; |
924 | fail: | 989 | fail: |
925 | spin_unlock_irqrestore(&gpio_lock, flags); | 990 | spin_unlock_irqrestore(&gpio_lock, flags); |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 04cb1d175df1..81797ec9ab29 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
@@ -35,6 +35,10 @@ struct module; | |||
35 | * @label: for diagnostics | 35 | * @label: for diagnostics |
36 | * @dev: optional device providing the GPIOs | 36 | * @dev: optional device providing the GPIOs |
37 | * @owner: helps prevent removal of modules exporting active GPIOs | 37 | * @owner: helps prevent removal of modules exporting active GPIOs |
38 | * @request: optional hook for chip-specific activation, such as | ||
39 | * enabling module power and clock; may sleep | ||
40 | * @free: optional hook for chip-specific deactivation, such as | ||
41 | * disabling module power and clock; may sleep | ||
38 | * @direction_input: configures signal "offset" as input, or returns error | 42 | * @direction_input: configures signal "offset" as input, or returns error |
39 | * @get: returns value for signal "offset"; for output signals this | 43 | * @get: returns value for signal "offset"; for output signals this |
40 | * returns either the value actually sensed, or zero | 44 | * returns either the value actually sensed, or zero |
@@ -67,6 +71,11 @@ struct gpio_chip { | |||
67 | struct device *dev; | 71 | struct device *dev; |
68 | struct module *owner; | 72 | struct module *owner; |
69 | 73 | ||
74 | int (*request)(struct gpio_chip *chip, | ||
75 | unsigned offset); | ||
76 | void (*free)(struct gpio_chip *chip, | ||
77 | unsigned offset); | ||
78 | |||
70 | int (*direction_input)(struct gpio_chip *chip, | 79 | int (*direction_input)(struct gpio_chip *chip, |
71 | unsigned offset); | 80 | unsigned offset); |
72 | int (*get)(struct gpio_chip *chip, | 81 | int (*get)(struct gpio_chip *chip, |