diff options
-rw-r--r-- | drivers/gpio/gpiolib.c | 15 | ||||
-rw-r--r-- | include/asm-generic/gpio.h | 2 |
2 files changed, 14 insertions, 3 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index d8db2f8ee411..eb75d12e83b7 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -68,6 +68,9 @@ static void gpio_ensure_requested(struct gpio_desc *desc) | |||
68 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { | 68 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { |
69 | pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc)); | 69 | pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc)); |
70 | desc_set_label(desc, "[auto]"); | 70 | desc_set_label(desc, "[auto]"); |
71 | if (!try_module_get(desc->chip->owner)) | ||
72 | pr_err("GPIO-%d: module can't be gotten \n", | ||
73 | (int)(desc - gpio_desc)); | ||
71 | } | 74 | } |
72 | } | 75 | } |
73 | 76 | ||
@@ -177,6 +180,9 @@ int gpio_request(unsigned gpio, const char *label) | |||
177 | if (desc->chip == NULL) | 180 | if (desc->chip == NULL) |
178 | goto done; | 181 | goto done; |
179 | 182 | ||
183 | if (!try_module_get(desc->chip->owner)) | ||
184 | goto done; | ||
185 | |||
180 | /* NOTE: gpio_request() can be called in early boot, | 186 | /* NOTE: gpio_request() can be called in early boot, |
181 | * before IRQs are enabled. | 187 | * before IRQs are enabled. |
182 | */ | 188 | */ |
@@ -184,8 +190,10 @@ int gpio_request(unsigned gpio, const char *label) | |||
184 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { | 190 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { |
185 | desc_set_label(desc, label ? : "?"); | 191 | desc_set_label(desc, label ? : "?"); |
186 | status = 0; | 192 | status = 0; |
187 | } else | 193 | } else { |
188 | status = -EBUSY; | 194 | status = -EBUSY; |
195 | module_put(desc->chip->owner); | ||
196 | } | ||
189 | 197 | ||
190 | done: | 198 | done: |
191 | if (status) | 199 | if (status) |
@@ -209,9 +217,10 @@ void gpio_free(unsigned gpio) | |||
209 | spin_lock_irqsave(&gpio_lock, flags); | 217 | spin_lock_irqsave(&gpio_lock, flags); |
210 | 218 | ||
211 | desc = &gpio_desc[gpio]; | 219 | desc = &gpio_desc[gpio]; |
212 | if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) | 220 | if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) { |
213 | desc_set_label(desc, NULL); | 221 | desc_set_label(desc, NULL); |
214 | else | 222 | module_put(desc->chip->owner); |
223 | } else | ||
215 | WARN_ON(extra_checks); | 224 | WARN_ON(extra_checks); |
216 | 225 | ||
217 | spin_unlock_irqrestore(&gpio_lock, flags); | 226 | spin_unlock_irqrestore(&gpio_lock, flags); |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index f29a502f4a6c..7e77b6ff45bb 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #endif | 17 | #endif |
18 | 18 | ||
19 | struct seq_file; | 19 | struct seq_file; |
20 | struct module; | ||
20 | 21 | ||
21 | /** | 22 | /** |
22 | * struct gpio_chip - abstract a GPIO controller | 23 | * struct gpio_chip - abstract a GPIO controller |
@@ -48,6 +49,7 @@ struct seq_file; | |||
48 | */ | 49 | */ |
49 | struct gpio_chip { | 50 | struct gpio_chip { |
50 | char *label; | 51 | char *label; |
52 | struct module *owner; | ||
51 | 53 | ||
52 | int (*direction_input)(struct gpio_chip *chip, | 54 | int (*direction_input)(struct gpio_chip *chip, |
53 | unsigned offset); | 55 | unsigned offset); |