aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpio/gpiolib.c15
-rw-r--r--include/asm-generic/gpio.h2
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
190done: 198done:
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
19struct seq_file; 19struct seq_file;
20struct 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 */
49struct gpio_chip { 50struct 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);