diff options
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r-- | drivers/gpio/gpiolib.c | 567 |
1 files changed, 567 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c new file mode 100644 index 000000000000..d8db2f8ee411 --- /dev/null +++ b/drivers/gpio/gpiolib.c | |||
@@ -0,0 +1,567 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/irq.h> | ||
4 | #include <linux/spinlock.h> | ||
5 | |||
6 | #include <asm/gpio.h> | ||
7 | |||
8 | |||
9 | /* Optional implementation infrastructure for GPIO interfaces. | ||
10 | * | ||
11 | * Platforms may want to use this if they tend to use very many GPIOs | ||
12 | * that aren't part of a System-On-Chip core; or across I2C/SPI/etc. | ||
13 | * | ||
14 | * When kernel footprint or instruction count is an issue, simpler | ||
15 | * implementations may be preferred. The GPIO programming interface | ||
16 | * allows for inlining speed-critical get/set operations for common | ||
17 | * cases, so that access to SOC-integrated GPIOs can sometimes cost | ||
18 | * only an instruction or two per bit. | ||
19 | */ | ||
20 | |||
21 | |||
22 | /* When debugging, extend minimal trust to callers and platform code. | ||
23 | * Also emit diagnostic messages that may help initial bringup, when | ||
24 | * board setup or driver bugs are most common. | ||
25 | * | ||
26 | * Otherwise, minimize overhead in what may be bitbanging codepaths. | ||
27 | */ | ||
28 | #ifdef DEBUG | ||
29 | #define extra_checks 1 | ||
30 | #else | ||
31 | #define extra_checks 0 | ||
32 | #endif | ||
33 | |||
34 | /* gpio_lock prevents conflicts during gpio_desc[] table updates. | ||
35 | * While any GPIO is requested, its gpio_chip is not removable; | ||
36 | * each GPIO's "requested" flag serves as a lock and refcount. | ||
37 | */ | ||
38 | static DEFINE_SPINLOCK(gpio_lock); | ||
39 | |||
40 | struct gpio_desc { | ||
41 | struct gpio_chip *chip; | ||
42 | unsigned long flags; | ||
43 | /* flag symbols are bit numbers */ | ||
44 | #define FLAG_REQUESTED 0 | ||
45 | #define FLAG_IS_OUT 1 | ||
46 | |||
47 | #ifdef CONFIG_DEBUG_FS | ||
48 | const char *label; | ||
49 | #endif | ||
50 | }; | ||
51 | static struct gpio_desc gpio_desc[ARCH_NR_GPIOS]; | ||
52 | |||
53 | static inline void desc_set_label(struct gpio_desc *d, const char *label) | ||
54 | { | ||
55 | #ifdef CONFIG_DEBUG_FS | ||
56 | d->label = label; | ||
57 | #endif | ||
58 | } | ||
59 | |||
60 | /* Warn when drivers omit gpio_request() calls -- legal but ill-advised | ||
61 | * when setting direction, and otherwise illegal. Until board setup code | ||
62 | * and drivers use explicit requests everywhere (which won't happen when | ||
63 | * those calls have no teeth) we can't avoid autorequesting. This nag | ||
64 | * message should motivate switching to explicit requests... | ||
65 | */ | ||
66 | static void gpio_ensure_requested(struct gpio_desc *desc) | ||
67 | { | ||
68 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { | ||
69 | pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc)); | ||
70 | desc_set_label(desc, "[auto]"); | ||
71 | } | ||
72 | } | ||
73 | |||
74 | /* caller holds gpio_lock *OR* gpio is marked as requested */ | ||
75 | static inline struct gpio_chip *gpio_to_chip(unsigned gpio) | ||
76 | { | ||
77 | return gpio_desc[gpio].chip; | ||
78 | } | ||
79 | |||
80 | /** | ||
81 | * gpiochip_add() - register a gpio_chip | ||
82 | * @chip: the chip to register, with chip->base initialized | ||
83 | * Context: potentially before irqs or kmalloc will work | ||
84 | * | ||
85 | * Returns a negative errno if the chip can't be registered, such as | ||
86 | * because the chip->base is invalid or already associated with a | ||
87 | * different chip. Otherwise it returns zero as a success code. | ||
88 | */ | ||
89 | int gpiochip_add(struct gpio_chip *chip) | ||
90 | { | ||
91 | unsigned long flags; | ||
92 | int status = 0; | ||
93 | unsigned id; | ||
94 | |||
95 | /* NOTE chip->base negative is reserved to mean a request for | ||
96 | * dynamic allocation. We don't currently support that. | ||
97 | */ | ||
98 | |||
99 | if (chip->base < 0 || (chip->base + chip->ngpio) >= ARCH_NR_GPIOS) { | ||
100 | status = -EINVAL; | ||
101 | goto fail; | ||
102 | } | ||
103 | |||
104 | spin_lock_irqsave(&gpio_lock, flags); | ||
105 | |||
106 | /* these GPIO numbers must not be managed by another gpio_chip */ | ||
107 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | ||
108 | if (gpio_desc[id].chip != NULL) { | ||
109 | status = -EBUSY; | ||
110 | break; | ||
111 | } | ||
112 | } | ||
113 | if (status == 0) { | ||
114 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | ||
115 | gpio_desc[id].chip = chip; | ||
116 | gpio_desc[id].flags = 0; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
121 | fail: | ||
122 | /* failures here can mean systems won't boot... */ | ||
123 | if (status) | ||
124 | pr_err("gpiochip_add: gpios %d..%d (%s) not registered\n", | ||
125 | chip->base, chip->base + chip->ngpio, | ||
126 | chip->label ? : "generic"); | ||
127 | return status; | ||
128 | } | ||
129 | EXPORT_SYMBOL_GPL(gpiochip_add); | ||
130 | |||
131 | /** | ||
132 | * gpiochip_remove() - unregister a gpio_chip | ||
133 | * @chip: the chip to unregister | ||
134 | * | ||
135 | * A gpio_chip with any GPIOs still requested may not be removed. | ||
136 | */ | ||
137 | int gpiochip_remove(struct gpio_chip *chip) | ||
138 | { | ||
139 | unsigned long flags; | ||
140 | int status = 0; | ||
141 | unsigned id; | ||
142 | |||
143 | spin_lock_irqsave(&gpio_lock, flags); | ||
144 | |||
145 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | ||
146 | if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) { | ||
147 | status = -EBUSY; | ||
148 | break; | ||
149 | } | ||
150 | } | ||
151 | if (status == 0) { | ||
152 | for (id = chip->base; id < chip->base + chip->ngpio; id++) | ||
153 | gpio_desc[id].chip = NULL; | ||
154 | } | ||
155 | |||
156 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
157 | return status; | ||
158 | } | ||
159 | EXPORT_SYMBOL_GPL(gpiochip_remove); | ||
160 | |||
161 | |||
162 | /* These "optional" allocation calls help prevent drivers from stomping | ||
163 | * on each other, and help provide better diagnostics in debugfs. | ||
164 | * They're called even less than the "set direction" calls. | ||
165 | */ | ||
166 | int gpio_request(unsigned gpio, const char *label) | ||
167 | { | ||
168 | struct gpio_desc *desc; | ||
169 | int status = -EINVAL; | ||
170 | unsigned long flags; | ||
171 | |||
172 | spin_lock_irqsave(&gpio_lock, flags); | ||
173 | |||
174 | if (gpio >= ARCH_NR_GPIOS) | ||
175 | goto done; | ||
176 | desc = &gpio_desc[gpio]; | ||
177 | if (desc->chip == NULL) | ||
178 | goto done; | ||
179 | |||
180 | /* NOTE: gpio_request() can be called in early boot, | ||
181 | * before IRQs are enabled. | ||
182 | */ | ||
183 | |||
184 | if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { | ||
185 | desc_set_label(desc, label ? : "?"); | ||
186 | status = 0; | ||
187 | } else | ||
188 | status = -EBUSY; | ||
189 | |||
190 | done: | ||
191 | if (status) | ||
192 | pr_debug("gpio_request: gpio-%d (%s) status %d\n", | ||
193 | gpio, label ? : "?", status); | ||
194 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
195 | return status; | ||
196 | } | ||
197 | EXPORT_SYMBOL_GPL(gpio_request); | ||
198 | |||
199 | void gpio_free(unsigned gpio) | ||
200 | { | ||
201 | unsigned long flags; | ||
202 | struct gpio_desc *desc; | ||
203 | |||
204 | if (gpio >= ARCH_NR_GPIOS) { | ||
205 | WARN_ON(extra_checks); | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | spin_lock_irqsave(&gpio_lock, flags); | ||
210 | |||
211 | desc = &gpio_desc[gpio]; | ||
212 | if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) | ||
213 | desc_set_label(desc, NULL); | ||
214 | else | ||
215 | WARN_ON(extra_checks); | ||
216 | |||
217 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
218 | } | ||
219 | EXPORT_SYMBOL_GPL(gpio_free); | ||
220 | |||
221 | |||
222 | /** | ||
223 | * gpiochip_is_requested - return string iff signal was requested | ||
224 | * @chip: controller managing the signal | ||
225 | * @offset: of signal within controller's 0..(ngpio - 1) range | ||
226 | * | ||
227 | * Returns NULL if the GPIO is not currently requested, else a string. | ||
228 | * If debugfs support is enabled, the string returned is the label passed | ||
229 | * to gpio_request(); otherwise it is a meaningless constant. | ||
230 | * | ||
231 | * This function is for use by GPIO controller drivers. The label can | ||
232 | * help with diagnostics, and knowing that the signal is used as a GPIO | ||
233 | * can help avoid accidentally multiplexing it to another controller. | ||
234 | */ | ||
235 | const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset) | ||
236 | { | ||
237 | unsigned gpio = chip->base + offset; | ||
238 | |||
239 | if (gpio >= ARCH_NR_GPIOS || gpio_desc[gpio].chip != chip) | ||
240 | return NULL; | ||
241 | if (test_bit(FLAG_REQUESTED, &gpio_desc[gpio].flags) == 0) | ||
242 | return NULL; | ||
243 | #ifdef CONFIG_DEBUG_FS | ||
244 | return gpio_desc[gpio].label; | ||
245 | #else | ||
246 | return "?"; | ||
247 | #endif | ||
248 | } | ||
249 | EXPORT_SYMBOL_GPL(gpiochip_is_requested); | ||
250 | |||
251 | |||
252 | /* Drivers MUST set GPIO direction before making get/set calls. In | ||
253 | * some cases this is done in early boot, before IRQs are enabled. | ||
254 | * | ||
255 | * As a rule these aren't called more than once (except for drivers | ||
256 | * using the open-drain emulation idiom) so these are natural places | ||
257 | * to accumulate extra debugging checks. Note that we can't (yet) | ||
258 | * rely on gpio_request() having been called beforehand. | ||
259 | */ | ||
260 | |||
261 | int gpio_direction_input(unsigned gpio) | ||
262 | { | ||
263 | unsigned long flags; | ||
264 | struct gpio_chip *chip; | ||
265 | struct gpio_desc *desc = &gpio_desc[gpio]; | ||
266 | int status = -EINVAL; | ||
267 | |||
268 | spin_lock_irqsave(&gpio_lock, flags); | ||
269 | |||
270 | if (gpio >= ARCH_NR_GPIOS) | ||
271 | goto fail; | ||
272 | chip = desc->chip; | ||
273 | if (!chip || !chip->get || !chip->direction_input) | ||
274 | goto fail; | ||
275 | gpio -= chip->base; | ||
276 | if (gpio >= chip->ngpio) | ||
277 | goto fail; | ||
278 | gpio_ensure_requested(desc); | ||
279 | |||
280 | /* now we know the gpio is valid and chip won't vanish */ | ||
281 | |||
282 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
283 | |||
284 | might_sleep_if(extra_checks && chip->can_sleep); | ||
285 | |||
286 | status = chip->direction_input(chip, gpio); | ||
287 | if (status == 0) | ||
288 | clear_bit(FLAG_IS_OUT, &desc->flags); | ||
289 | return status; | ||
290 | fail: | ||
291 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
292 | if (status) | ||
293 | pr_debug("%s: gpio-%d status %d\n", | ||
294 | __FUNCTION__, gpio, status); | ||
295 | return status; | ||
296 | } | ||
297 | EXPORT_SYMBOL_GPL(gpio_direction_input); | ||
298 | |||
299 | int gpio_direction_output(unsigned gpio, int value) | ||
300 | { | ||
301 | unsigned long flags; | ||
302 | struct gpio_chip *chip; | ||
303 | struct gpio_desc *desc = &gpio_desc[gpio]; | ||
304 | int status = -EINVAL; | ||
305 | |||
306 | spin_lock_irqsave(&gpio_lock, flags); | ||
307 | |||
308 | if (gpio >= ARCH_NR_GPIOS) | ||
309 | goto fail; | ||
310 | chip = desc->chip; | ||
311 | if (!chip || !chip->set || !chip->direction_output) | ||
312 | goto fail; | ||
313 | gpio -= chip->base; | ||
314 | if (gpio >= chip->ngpio) | ||
315 | goto fail; | ||
316 | gpio_ensure_requested(desc); | ||
317 | |||
318 | /* now we know the gpio is valid and chip won't vanish */ | ||
319 | |||
320 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
321 | |||
322 | might_sleep_if(extra_checks && chip->can_sleep); | ||
323 | |||
324 | status = chip->direction_output(chip, gpio, value); | ||
325 | if (status == 0) | ||
326 | set_bit(FLAG_IS_OUT, &desc->flags); | ||
327 | return status; | ||
328 | fail: | ||
329 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
330 | if (status) | ||
331 | pr_debug("%s: gpio-%d status %d\n", | ||
332 | __FUNCTION__, gpio, status); | ||
333 | return status; | ||
334 | } | ||
335 | EXPORT_SYMBOL_GPL(gpio_direction_output); | ||
336 | |||
337 | |||
338 | /* I/O calls are only valid after configuration completed; the relevant | ||
339 | * "is this a valid GPIO" error checks should already have been done. | ||
340 | * | ||
341 | * "Get" operations are often inlinable as reading a pin value register, | ||
342 | * and masking the relevant bit in that register. | ||
343 | * | ||
344 | * When "set" operations are inlinable, they involve writing that mask to | ||
345 | * one register to set a low value, or a different register to set it high. | ||
346 | * Otherwise locking is needed, so there may be little value to inlining. | ||
347 | * | ||
348 | *------------------------------------------------------------------------ | ||
349 | * | ||
350 | * IMPORTANT!!! The hot paths -- get/set value -- assume that callers | ||
351 | * have requested the GPIO. That can include implicit requesting by | ||
352 | * a direction setting call. Marking a gpio as requested locks its chip | ||
353 | * in memory, guaranteeing that these table lookups need no more locking | ||
354 | * and that gpiochip_remove() will fail. | ||
355 | * | ||
356 | * REVISIT when debugging, consider adding some instrumentation to ensure | ||
357 | * that the GPIO was actually requested. | ||
358 | */ | ||
359 | |||
360 | /** | ||
361 | * __gpio_get_value() - return a gpio's value | ||
362 | * @gpio: gpio whose value will be returned | ||
363 | * Context: any | ||
364 | * | ||
365 | * This is used directly or indirectly to implement gpio_get_value(). | ||
366 | * It returns the zero or nonzero value provided by the associated | ||
367 | * gpio_chip.get() method; or zero if no such method is provided. | ||
368 | */ | ||
369 | int __gpio_get_value(unsigned gpio) | ||
370 | { | ||
371 | struct gpio_chip *chip; | ||
372 | |||
373 | chip = gpio_to_chip(gpio); | ||
374 | WARN_ON(extra_checks && chip->can_sleep); | ||
375 | return chip->get ? chip->get(chip, gpio - chip->base) : 0; | ||
376 | } | ||
377 | EXPORT_SYMBOL_GPL(__gpio_get_value); | ||
378 | |||
379 | /** | ||
380 | * __gpio_set_value() - assign a gpio's value | ||
381 | * @gpio: gpio whose value will be assigned | ||
382 | * @value: value to assign | ||
383 | * Context: any | ||
384 | * | ||
385 | * This is used directly or indirectly to implement gpio_set_value(). | ||
386 | * It invokes the associated gpio_chip.set() method. | ||
387 | */ | ||
388 | void __gpio_set_value(unsigned gpio, int value) | ||
389 | { | ||
390 | struct gpio_chip *chip; | ||
391 | |||
392 | chip = gpio_to_chip(gpio); | ||
393 | WARN_ON(extra_checks && chip->can_sleep); | ||
394 | chip->set(chip, gpio - chip->base, value); | ||
395 | } | ||
396 | EXPORT_SYMBOL_GPL(__gpio_set_value); | ||
397 | |||
398 | /** | ||
399 | * __gpio_cansleep() - report whether gpio value access will sleep | ||
400 | * @gpio: gpio in question | ||
401 | * Context: any | ||
402 | * | ||
403 | * This is used directly or indirectly to implement gpio_cansleep(). It | ||
404 | * returns nonzero if access reading or writing the GPIO value can sleep. | ||
405 | */ | ||
406 | int __gpio_cansleep(unsigned gpio) | ||
407 | { | ||
408 | struct gpio_chip *chip; | ||
409 | |||
410 | /* only call this on GPIOs that are valid! */ | ||
411 | chip = gpio_to_chip(gpio); | ||
412 | |||
413 | return chip->can_sleep; | ||
414 | } | ||
415 | EXPORT_SYMBOL_GPL(__gpio_cansleep); | ||
416 | |||
417 | |||
418 | |||
419 | /* There's no value in making it easy to inline GPIO calls that may sleep. | ||
420 | * Common examples include ones connected to I2C or SPI chips. | ||
421 | */ | ||
422 | |||
423 | int gpio_get_value_cansleep(unsigned gpio) | ||
424 | { | ||
425 | struct gpio_chip *chip; | ||
426 | |||
427 | might_sleep_if(extra_checks); | ||
428 | chip = gpio_to_chip(gpio); | ||
429 | return chip->get(chip, gpio - chip->base); | ||
430 | } | ||
431 | EXPORT_SYMBOL_GPL(gpio_get_value_cansleep); | ||
432 | |||
433 | void gpio_set_value_cansleep(unsigned gpio, int value) | ||
434 | { | ||
435 | struct gpio_chip *chip; | ||
436 | |||
437 | might_sleep_if(extra_checks); | ||
438 | chip = gpio_to_chip(gpio); | ||
439 | chip->set(chip, gpio - chip->base, value); | ||
440 | } | ||
441 | EXPORT_SYMBOL_GPL(gpio_set_value_cansleep); | ||
442 | |||
443 | |||
444 | #ifdef CONFIG_DEBUG_FS | ||
445 | |||
446 | #include <linux/debugfs.h> | ||
447 | #include <linux/seq_file.h> | ||
448 | |||
449 | |||
450 | static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | ||
451 | { | ||
452 | unsigned i; | ||
453 | unsigned gpio = chip->base; | ||
454 | struct gpio_desc *gdesc = &gpio_desc[gpio]; | ||
455 | int is_out; | ||
456 | |||
457 | for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) { | ||
458 | if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) | ||
459 | continue; | ||
460 | |||
461 | is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); | ||
462 | seq_printf(s, " gpio-%-3d (%-12s) %s %s", | ||
463 | gpio, gdesc->label, | ||
464 | is_out ? "out" : "in ", | ||
465 | chip->get | ||
466 | ? (chip->get(chip, i) ? "hi" : "lo") | ||
467 | : "? "); | ||
468 | |||
469 | if (!is_out) { | ||
470 | int irq = gpio_to_irq(gpio); | ||
471 | struct irq_desc *desc = irq_desc + irq; | ||
472 | |||
473 | /* This races with request_irq(), set_irq_type(), | ||
474 | * and set_irq_wake() ... but those are "rare". | ||
475 | * | ||
476 | * More significantly, trigger type flags aren't | ||
477 | * currently maintained by genirq. | ||
478 | */ | ||
479 | if (irq >= 0 && desc->action) { | ||
480 | char *trigger; | ||
481 | |||
482 | switch (desc->status & IRQ_TYPE_SENSE_MASK) { | ||
483 | case IRQ_TYPE_NONE: | ||
484 | trigger = "(default)"; | ||
485 | break; | ||
486 | case IRQ_TYPE_EDGE_FALLING: | ||
487 | trigger = "edge-falling"; | ||
488 | break; | ||
489 | case IRQ_TYPE_EDGE_RISING: | ||
490 | trigger = "edge-rising"; | ||
491 | break; | ||
492 | case IRQ_TYPE_EDGE_BOTH: | ||
493 | trigger = "edge-both"; | ||
494 | break; | ||
495 | case IRQ_TYPE_LEVEL_HIGH: | ||
496 | trigger = "level-high"; | ||
497 | break; | ||
498 | case IRQ_TYPE_LEVEL_LOW: | ||
499 | trigger = "level-low"; | ||
500 | break; | ||
501 | default: | ||
502 | trigger = "?trigger?"; | ||
503 | break; | ||
504 | } | ||
505 | |||
506 | seq_printf(s, " irq-%d %s%s", | ||
507 | irq, trigger, | ||
508 | (desc->status & IRQ_WAKEUP) | ||
509 | ? " wakeup" : ""); | ||
510 | } | ||
511 | } | ||
512 | |||
513 | seq_printf(s, "\n"); | ||
514 | } | ||
515 | } | ||
516 | |||
517 | static int gpiolib_show(struct seq_file *s, void *unused) | ||
518 | { | ||
519 | struct gpio_chip *chip = NULL; | ||
520 | unsigned gpio; | ||
521 | int started = 0; | ||
522 | |||
523 | /* REVISIT this isn't locked against gpio_chip removal ... */ | ||
524 | |||
525 | for (gpio = 0; gpio < ARCH_NR_GPIOS; gpio++) { | ||
526 | if (chip == gpio_desc[gpio].chip) | ||
527 | continue; | ||
528 | chip = gpio_desc[gpio].chip; | ||
529 | if (!chip) | ||
530 | continue; | ||
531 | |||
532 | seq_printf(s, "%sGPIOs %d-%d, %s%s:\n", | ||
533 | started ? "\n" : "", | ||
534 | chip->base, chip->base + chip->ngpio - 1, | ||
535 | chip->label ? : "generic", | ||
536 | chip->can_sleep ? ", can sleep" : ""); | ||
537 | started = 1; | ||
538 | if (chip->dbg_show) | ||
539 | chip->dbg_show(s, chip); | ||
540 | else | ||
541 | gpiolib_dbg_show(s, chip); | ||
542 | } | ||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | static int gpiolib_open(struct inode *inode, struct file *file) | ||
547 | { | ||
548 | return single_open(file, gpiolib_show, NULL); | ||
549 | } | ||
550 | |||
551 | static struct file_operations gpiolib_operations = { | ||
552 | .open = gpiolib_open, | ||
553 | .read = seq_read, | ||
554 | .llseek = seq_lseek, | ||
555 | .release = single_release, | ||
556 | }; | ||
557 | |||
558 | static int __init gpiolib_debugfs_init(void) | ||
559 | { | ||
560 | /* /sys/kernel/debug/gpio */ | ||
561 | (void) debugfs_create_file("gpio", S_IFREG | S_IRUGO, | ||
562 | NULL, NULL, &gpiolib_operations); | ||
563 | return 0; | ||
564 | } | ||
565 | subsys_initcall(gpiolib_debugfs_init); | ||
566 | |||
567 | #endif /* DEBUG_FS */ | ||