diff options
author | David Brownell <dbrownell@users.sourceforge.net> | 2008-07-25 04:46:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-25 13:53:30 -0400 |
commit | d8f388d8dc8d4f36539dd37c1fff62cc404ea0fc (patch) | |
tree | df8603775c889f29f8a03c77b9f7913bfd90d296 | |
parent | 8b6dd986823a8d92ed9f54baa5cef8604d9d9d44 (diff) |
gpio: sysfs interface
This adds a simple sysfs interface for GPIOs.
/sys/class/gpio
/export ... asks the kernel to export a GPIO to userspace
/unexport ... to return a GPIO to the kernel
/gpioN ... for each exported GPIO #N
/value ... always readable, writes fail for input GPIOs
/direction ... r/w as: in, out (default low); write high, low
/gpiochipN ... for each gpiochip; #N is its first GPIO
/base ... (r/o) same as N
/label ... (r/o) descriptive, not necessarily unique
/ngpio ... (r/o) number of GPIOs; numbered N .. N+(ngpio - 1)
GPIOs claimed by kernel code may be exported by its owner using a new
gpio_export() call, which should be most useful for driver debugging.
Such exports may optionally be done without a "direction" attribute.
Userspace may ask to take over a GPIO by writing to a sysfs control file,
helping to cope with incomplete board support or other "one-off"
requirements that don't merit full kernel support:
echo 23 > /sys/class/gpio/export
... will gpio_request(23, "sysfs") and gpio_export(23);
use /sys/class/gpio/gpio-23/direction to (re)configure it,
when that GPIO can be used as both input and output.
echo 23 > /sys/class/gpio/unexport
... will gpio_free(23), when it was exported as above
The extra D-space footprint is a few hundred bytes, except for the sysfs
resources associated with each exported GPIO. The additional I-space
footprint is about two thirds of the current size of gpiolib (!). Since
no /dev node creation is involved, no "udev" support is needed.
Related changes:
* This adds a device pointer to "struct gpio_chip". When GPIO
providers initialize that, sysfs gpio class devices become children of
that device instead of being "virtual" devices.
* The (few) gpio_chip providers which have such a device node have
been updated.
* Some gpio_chip drivers also needed to update their module "owner"
field ... for which missing kerneldoc was added.
* Some gpio_chips don't support input GPIOs. Those GPIOs are now
flagged appropriately when the chip is registered.
Based on previous patches, and discussion both on and off LKML.
A Documentation/ABI/testing/sysfs-gpio update is ready to submit once this
merges to mainline.
[akpm@linux-foundation.org: a few maintenance build fixes]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Guennadi Liakhovetski <g.liakhovetski@pengutronix.de>
Cc: Greg KH <greg@kroah.com>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | Documentation/gpio.txt | 123 | ||||
-rw-r--r-- | arch/arm/plat-omap/gpio.c | 3 | ||||
-rw-r--r-- | arch/avr32/mach-at32ap/pio.c | 2 | ||||
-rw-r--r-- | drivers/gpio/Kconfig | 15 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 536 | ||||
-rw-r--r-- | drivers/gpio/mcp23s08.c | 1 | ||||
-rw-r--r-- | drivers/gpio/pca953x.c | 1 | ||||
-rw-r--r-- | drivers/gpio/pcf857x.c | 1 | ||||
-rw-r--r-- | drivers/i2c/chips/tps65010.c | 2 | ||||
-rw-r--r-- | drivers/mfd/htc-egpio.c | 2 | ||||
-rw-r--r-- | include/asm-generic/gpio.h | 33 | ||||
-rw-r--r-- | include/linux/gpio.h | 13 |
12 files changed, 712 insertions, 20 deletions
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index c35ca9e40d4c..8b69811a9642 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt | |||
@@ -347,15 +347,12 @@ necessarily be nonportable. | |||
347 | Dynamic definition of GPIOs is not currently standard; for example, as | 347 | Dynamic definition of GPIOs is not currently standard; for example, as |
348 | a side effect of configuring an add-on board with some GPIO expanders. | 348 | a side effect of configuring an add-on board with some GPIO expanders. |
349 | 349 | ||
350 | These calls are purely for kernel space, but a userspace API could be built | ||
351 | on top of them. | ||
352 | |||
353 | 350 | ||
354 | GPIO implementor's framework (OPTIONAL) | 351 | GPIO implementor's framework (OPTIONAL) |
355 | ======================================= | 352 | ======================================= |
356 | As noted earlier, there is an optional implementation framework making it | 353 | As noted earlier, there is an optional implementation framework making it |
357 | easier for platforms to support different kinds of GPIO controller using | 354 | easier for platforms to support different kinds of GPIO controller using |
358 | the same programming interface. | 355 | the same programming interface. This framework is called "gpiolib". |
359 | 356 | ||
360 | As a debugging aid, if debugfs is available a /sys/kernel/debug/gpio file | 357 | As a debugging aid, if debugfs is available a /sys/kernel/debug/gpio file |
361 | will be found there. That will list all the controllers registered through | 358 | will be found there. That will list all the controllers registered through |
@@ -439,4 +436,120 @@ becomes available. That may mean the device should not be registered until | |||
439 | calls for that GPIO can work. One way to address such dependencies is for | 436 | calls for that GPIO can work. One way to address such dependencies is for |
440 | such gpio_chip controllers to provide setup() and teardown() callbacks to | 437 | such gpio_chip controllers to provide setup() and teardown() callbacks to |
441 | board specific code; those board specific callbacks would register devices | 438 | board specific code; those board specific callbacks would register devices |
442 | once all the necessary resources are available. | 439 | once all the necessary resources are available, and remove them later when |
440 | the GPIO controller device becomes unavailable. | ||
441 | |||
442 | |||
443 | Sysfs Interface for Userspace (OPTIONAL) | ||
444 | ======================================== | ||
445 | Platforms which use the "gpiolib" implementors framework may choose to | ||
446 | configure a sysfs user interface to GPIOs. This is different from the | ||
447 | debugfs interface, since it provides control over GPIO direction and | ||
448 | value instead of just showing a gpio state summary. Plus, it could be | ||
449 | present on production systems without debugging support. | ||
450 | |||
451 | Given approprate hardware documentation for the system, userspace could | ||
452 | know for example that GPIO #23 controls the write protect line used to | ||
453 | protect boot loader segments in flash memory. System upgrade procedures | ||
454 | may need to temporarily remove that protection, first importing a GPIO, | ||
455 | then changing its output state, then updating the code before re-enabling | ||
456 | the write protection. In normal use, GPIO #23 would never be touched, | ||
457 | and the kernel would have no need to know about it. | ||
458 | |||
459 | Again depending on appropriate hardware documentation, on some systems | ||
460 | userspace GPIO can be used to determine system configuration data that | ||
461 | standard kernels won't know about. And for some tasks, simple userspace | ||
462 | GPIO drivers could be all that the system really needs. | ||
463 | |||
464 | Note that standard kernel drivers exist for common "LEDs and Buttons" | ||
465 | GPIO tasks: "leds-gpio" and "gpio_keys", respectively. Use those | ||
466 | instead of talking directly to the GPIOs; they integrate with kernel | ||
467 | frameworks better than your userspace code could. | ||
468 | |||
469 | |||
470 | Paths in Sysfs | ||
471 | -------------- | ||
472 | There are three kinds of entry in /sys/class/gpio: | ||
473 | |||
474 | - Control interfaces used to get userspace control over GPIOs; | ||
475 | |||
476 | - GPIOs themselves; and | ||
477 | |||
478 | - GPIO controllers ("gpio_chip" instances). | ||
479 | |||
480 | That's in addition to standard files including the "device" symlink. | ||
481 | |||
482 | The control interfaces are write-only: | ||
483 | |||
484 | /sys/class/gpio/ | ||
485 | |||
486 | "export" ... Userspace may ask the kernel to export control of | ||
487 | a GPIO to userspace by writing its number to this file. | ||
488 | |||
489 | Example: "echo 19 > export" will create a "gpio19" node | ||
490 | for GPIO #19, if that's not requested by kernel code. | ||
491 | |||
492 | "unexport" ... Reverses the effect of exporting to userspace. | ||
493 | |||
494 | Example: "echo 19 > unexport" will remove a "gpio19" | ||
495 | node exported using the "export" file. | ||
496 | |||
497 | GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42) | ||
498 | and have the following read/write attributes: | ||
499 | |||
500 | /sys/class/gpio/gpioN/ | ||
501 | |||
502 | "direction" ... reads as either "in" or "out". This value may | ||
503 | normally be written. Writing as "out" defaults to | ||
504 | initializing the value as low. To ensure glitch free | ||
505 | operation, values "low" and "high" may be written to | ||
506 | configure the GPIO as an output with that initial value. | ||
507 | |||
508 | Note that this attribute *will not exist* if the kernel | ||
509 | doesn't support changing the direction of a GPIO, or | ||
510 | it was exported by kernel code that didn't explicitly | ||
511 | allow userspace to reconfigure this GPIO's direction. | ||
512 | |||
513 | "value" ... reads as either 0 (low) or 1 (high). If the GPIO | ||
514 | is configured as an output, this value may be written; | ||
515 | any nonzero value is treated as high. | ||
516 | |||
517 | GPIO controllers have paths like /sys/class/gpio/chipchip42/ (for the | ||
518 | controller implementing GPIOs starting at #42) and have the following | ||
519 | read-only attributes: | ||
520 | |||
521 | /sys/class/gpio/gpiochipN/ | ||
522 | |||
523 | "base" ... same as N, the first GPIO managed by this chip | ||
524 | |||
525 | "label" ... provided for diagnostics (not always unique) | ||
526 | |||
527 | "ngpio" ... how many GPIOs this manges (N to N + ngpio - 1) | ||
528 | |||
529 | Board documentation should in most cases cover what GPIOs are used for | ||
530 | what purposes. However, those numbers are not always stable; GPIOs on | ||
531 | a daughtercard might be different depending on the base board being used, | ||
532 | or other cards in the stack. In such cases, you may need to use the | ||
533 | gpiochip nodes (possibly in conjunction with schematics) to determine | ||
534 | the correct GPIO number to use for a given signal. | ||
535 | |||
536 | |||
537 | Exporting from Kernel code | ||
538 | -------------------------- | ||
539 | Kernel code can explicitly manage exports of GPIOs which have already been | ||
540 | requested using gpio_request(): | ||
541 | |||
542 | /* export the GPIO to userspace */ | ||
543 | int gpio_export(unsigned gpio, bool direction_may_change); | ||
544 | |||
545 | /* reverse gpio_export() */ | ||
546 | void gpio_unexport(); | ||
547 | |||
548 | After a kernel driver requests a GPIO, it may only be made available in | ||
549 | the sysfs interface by gpio_export(). The driver can control whether the | ||
550 | signal direction may change. This helps drivers prevent userspace code | ||
551 | from accidentally clobbering important system state. | ||
552 | |||
553 | This explicit exporting can help with debugging (by making some kinds | ||
554 | of experiments easier), or can provide an always-there interface that's | ||
555 | suitable for documenting as part of a board support package. | ||
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 1903a3491ee9..d8e9c2c3f0f6 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c | |||
@@ -1488,6 +1488,9 @@ static int __init _omap_gpio_init(void) | |||
1488 | bank->chip.set = gpio_set; | 1488 | bank->chip.set = gpio_set; |
1489 | if (bank_is_mpuio(bank)) { | 1489 | if (bank_is_mpuio(bank)) { |
1490 | bank->chip.label = "mpuio"; | 1490 | bank->chip.label = "mpuio"; |
1491 | #ifdef CONFIG_ARCH_OMAP1 | ||
1492 | bank->chip.dev = &omap_mpuio_device.dev; | ||
1493 | #endif | ||
1491 | bank->chip.base = OMAP_MPUIO(0); | 1494 | bank->chip.base = OMAP_MPUIO(0); |
1492 | } else { | 1495 | } else { |
1493 | bank->chip.label = "gpio"; | 1496 | bank->chip.label = "gpio"; |
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index 60da03ba7117..296294f8ed81 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c | |||
@@ -360,6 +360,8 @@ static int __init pio_probe(struct platform_device *pdev) | |||
360 | pio->chip.label = pio->name; | 360 | pio->chip.label = pio->name; |
361 | pio->chip.base = pdev->id * 32; | 361 | pio->chip.base = pdev->id * 32; |
362 | pio->chip.ngpio = 32; | 362 | pio->chip.ngpio = 32; |
363 | pio->chip.dev = &pdev->dev; | ||
364 | pio->chip.owner = THIS_MODULE; | ||
363 | 365 | ||
364 | pio->chip.direction_input = direction_input; | 366 | pio->chip.direction_input = direction_input; |
365 | pio->chip.get = gpio_get; | 367 | pio->chip.get = gpio_get; |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index fced1909cbba..6ec0e35b98e3 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -23,6 +23,21 @@ config DEBUG_GPIO | |||
23 | slower. The diagnostics help catch the type of setup errors | 23 | slower. The diagnostics help catch the type of setup errors |
24 | that are most common when setting up new platforms or boards. | 24 | that are most common when setting up new platforms or boards. |
25 | 25 | ||
26 | config GPIO_SYSFS | ||
27 | bool "/sys/class/gpio/... (sysfs interface)" | ||
28 | depends on SYSFS && EXPERIMENTAL | ||
29 | help | ||
30 | Say Y here to add a sysfs interface for GPIOs. | ||
31 | |||
32 | This is mostly useful to work around omissions in a system's | ||
33 | kernel support. Those are common in custom and semicustom | ||
34 | hardware assembled using standard kernels with a minimum of | ||
35 | custom patches. In those cases, userspace code may import | ||
36 | a given GPIO from the kernel, if no kernel driver requested it. | ||
37 | |||
38 | Kernel drivers may also request that a particular GPIO be | ||
39 | exported to userspace; this can be useful when debugging. | ||
40 | |||
26 | # put expanders in the right section, in alphabetical order | 41 | # put expanders in the right section, in alphabetical order |
27 | 42 | ||
28 | comment "I2C GPIO expanders:" | 43 | comment "I2C GPIO expanders:" |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index beaf6b3a37dc..8d2940517c99 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -2,8 +2,11 @@ | |||
2 | #include <linux/module.h> | 2 | #include <linux/module.h> |
3 | #include <linux/irq.h> | 3 | #include <linux/irq.h> |
4 | #include <linux/spinlock.h> | 4 | #include <linux/spinlock.h> |
5 | 5 | #include <linux/device.h> | |
6 | #include <asm/gpio.h> | 6 | #include <linux/err.h> |
7 | #include <linux/debugfs.h> | ||
8 | #include <linux/seq_file.h> | ||
9 | #include <linux/gpio.h> | ||
7 | 10 | ||
8 | 11 | ||
9 | /* Optional implementation infrastructure for GPIO interfaces. | 12 | /* Optional implementation infrastructure for GPIO interfaces. |
@@ -44,6 +47,8 @@ struct gpio_desc { | |||
44 | #define FLAG_REQUESTED 0 | 47 | #define FLAG_REQUESTED 0 |
45 | #define FLAG_IS_OUT 1 | 48 | #define FLAG_IS_OUT 1 |
46 | #define FLAG_RESERVED 2 | 49 | #define FLAG_RESERVED 2 |
50 | #define FLAG_EXPORT 3 /* protected by sysfs_lock */ | ||
51 | #define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control */ | ||
47 | 52 | ||
48 | #ifdef CONFIG_DEBUG_FS | 53 | #ifdef CONFIG_DEBUG_FS |
49 | const char *label; | 54 | const char *label; |
@@ -151,6 +156,482 @@ err: | |||
151 | return ret; | 156 | return ret; |
152 | } | 157 | } |
153 | 158 | ||
159 | #ifdef CONFIG_GPIO_SYSFS | ||
160 | |||
161 | /* lock protects against unexport_gpio() being called while | ||
162 | * sysfs files are active. | ||
163 | */ | ||
164 | static DEFINE_MUTEX(sysfs_lock); | ||
165 | |||
166 | /* | ||
167 | * /sys/class/gpio/gpioN... only for GPIOs that are exported | ||
168 | * /direction | ||
169 | * * MAY BE OMITTED if kernel won't allow direction changes | ||
170 | * * is read/write as "in" or "out" | ||
171 | * * may also be written as "high" or "low", initializing | ||
172 | * output value as specified ("out" implies "low") | ||
173 | * /value | ||
174 | * * always readable, subject to hardware behavior | ||
175 | * * may be writable, as zero/nonzero | ||
176 | * | ||
177 | * REVISIT there will likely be an attribute for configuring async | ||
178 | * notifications, e.g. to specify polling interval or IRQ trigger type | ||
179 | * that would for example trigger a poll() on the "value". | ||
180 | */ | ||
181 | |||
182 | static ssize_t gpio_direction_show(struct device *dev, | ||
183 | struct device_attribute *attr, char *buf) | ||
184 | { | ||
185 | const struct gpio_desc *desc = dev_get_drvdata(dev); | ||
186 | ssize_t status; | ||
187 | |||
188 | mutex_lock(&sysfs_lock); | ||
189 | |||
190 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | ||
191 | status = -EIO; | ||
192 | else | ||
193 | status = sprintf(buf, "%s\n", | ||
194 | test_bit(FLAG_IS_OUT, &desc->flags) | ||
195 | ? "out" : "in"); | ||
196 | |||
197 | mutex_unlock(&sysfs_lock); | ||
198 | return status; | ||
199 | } | ||
200 | |||
201 | static ssize_t gpio_direction_store(struct device *dev, | ||
202 | struct device_attribute *attr, const char *buf, size_t size) | ||
203 | { | ||
204 | const struct gpio_desc *desc = dev_get_drvdata(dev); | ||
205 | unsigned gpio = desc - gpio_desc; | ||
206 | ssize_t status; | ||
207 | |||
208 | mutex_lock(&sysfs_lock); | ||
209 | |||
210 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | ||
211 | status = -EIO; | ||
212 | else if (sysfs_streq(buf, "high")) | ||
213 | status = gpio_direction_output(gpio, 1); | ||
214 | else if (sysfs_streq(buf, "out") || sysfs_streq(buf, "low")) | ||
215 | status = gpio_direction_output(gpio, 0); | ||
216 | else if (sysfs_streq(buf, "in")) | ||
217 | status = gpio_direction_input(gpio); | ||
218 | else | ||
219 | status = -EINVAL; | ||
220 | |||
221 | mutex_unlock(&sysfs_lock); | ||
222 | return status ? : size; | ||
223 | } | ||
224 | |||
225 | static const DEVICE_ATTR(direction, 0644, | ||
226 | gpio_direction_show, gpio_direction_store); | ||
227 | |||
228 | static ssize_t gpio_value_show(struct device *dev, | ||
229 | struct device_attribute *attr, char *buf) | ||
230 | { | ||
231 | const struct gpio_desc *desc = dev_get_drvdata(dev); | ||
232 | unsigned gpio = desc - gpio_desc; | ||
233 | ssize_t status; | ||
234 | |||
235 | mutex_lock(&sysfs_lock); | ||
236 | |||
237 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | ||
238 | status = -EIO; | ||
239 | else | ||
240 | status = sprintf(buf, "%d\n", gpio_get_value_cansleep(gpio)); | ||
241 | |||
242 | mutex_unlock(&sysfs_lock); | ||
243 | return status; | ||
244 | } | ||
245 | |||
246 | static ssize_t gpio_value_store(struct device *dev, | ||
247 | struct device_attribute *attr, const char *buf, size_t size) | ||
248 | { | ||
249 | const struct gpio_desc *desc = dev_get_drvdata(dev); | ||
250 | unsigned gpio = desc - gpio_desc; | ||
251 | ssize_t status; | ||
252 | |||
253 | mutex_lock(&sysfs_lock); | ||
254 | |||
255 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | ||
256 | status = -EIO; | ||
257 | else if (!test_bit(FLAG_IS_OUT, &desc->flags)) | ||
258 | status = -EPERM; | ||
259 | else { | ||
260 | long value; | ||
261 | |||
262 | status = strict_strtol(buf, 0, &value); | ||
263 | if (status == 0) { | ||
264 | gpio_set_value_cansleep(gpio, value != 0); | ||
265 | status = size; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | mutex_unlock(&sysfs_lock); | ||
270 | return status; | ||
271 | } | ||
272 | |||
273 | static /*const*/ DEVICE_ATTR(value, 0644, | ||
274 | gpio_value_show, gpio_value_store); | ||
275 | |||
276 | static const struct attribute *gpio_attrs[] = { | ||
277 | &dev_attr_direction.attr, | ||
278 | &dev_attr_value.attr, | ||
279 | NULL, | ||
280 | }; | ||
281 | |||
282 | static const struct attribute_group gpio_attr_group = { | ||
283 | .attrs = (struct attribute **) gpio_attrs, | ||
284 | }; | ||
285 | |||
286 | /* | ||
287 | * /sys/class/gpio/gpiochipN/ | ||
288 | * /base ... matching gpio_chip.base (N) | ||
289 | * /label ... matching gpio_chip.label | ||
290 | * /ngpio ... matching gpio_chip.ngpio | ||
291 | */ | ||
292 | |||
293 | static ssize_t chip_base_show(struct device *dev, | ||
294 | struct device_attribute *attr, char *buf) | ||
295 | { | ||
296 | const struct gpio_chip *chip = dev_get_drvdata(dev); | ||
297 | |||
298 | return sprintf(buf, "%d\n", chip->base); | ||
299 | } | ||
300 | static DEVICE_ATTR(base, 0444, chip_base_show, NULL); | ||
301 | |||
302 | static ssize_t chip_label_show(struct device *dev, | ||
303 | struct device_attribute *attr, char *buf) | ||
304 | { | ||
305 | const struct gpio_chip *chip = dev_get_drvdata(dev); | ||
306 | |||
307 | return sprintf(buf, "%s\n", chip->label ? : ""); | ||
308 | } | ||
309 | static DEVICE_ATTR(label, 0444, chip_label_show, NULL); | ||
310 | |||
311 | static ssize_t chip_ngpio_show(struct device *dev, | ||
312 | struct device_attribute *attr, char *buf) | ||
313 | { | ||
314 | const struct gpio_chip *chip = dev_get_drvdata(dev); | ||
315 | |||
316 | return sprintf(buf, "%u\n", chip->ngpio); | ||
317 | } | ||
318 | static DEVICE_ATTR(ngpio, 0444, chip_ngpio_show, NULL); | ||
319 | |||
320 | static const struct attribute *gpiochip_attrs[] = { | ||
321 | &dev_attr_base.attr, | ||
322 | &dev_attr_label.attr, | ||
323 | &dev_attr_ngpio.attr, | ||
324 | NULL, | ||
325 | }; | ||
326 | |||
327 | static const struct attribute_group gpiochip_attr_group = { | ||
328 | .attrs = (struct attribute **) gpiochip_attrs, | ||
329 | }; | ||
330 | |||
331 | /* | ||
332 | * /sys/class/gpio/export ... write-only | ||
333 | * integer N ... number of GPIO to export (full access) | ||
334 | * /sys/class/gpio/unexport ... write-only | ||
335 | * integer N ... number of GPIO to unexport | ||
336 | */ | ||
337 | static ssize_t export_store(struct class *class, const char *buf, size_t len) | ||
338 | { | ||
339 | long gpio; | ||
340 | int status; | ||
341 | |||
342 | status = strict_strtol(buf, 0, &gpio); | ||
343 | if (status < 0) | ||
344 | goto done; | ||
345 | |||
346 | /* No extra locking here; FLAG_SYSFS just signifies that the | ||
347 | * request and export were done by on behalf of userspace, so | ||
348 | * they may be undone on its behalf too. | ||
349 | */ | ||
350 | |||
351 | status = gpio_request(gpio, "sysfs"); | ||
352 | if (status < 0) | ||
353 | goto done; | ||
354 | |||
355 | status = gpio_export(gpio, true); | ||
356 | if (status < 0) | ||
357 | gpio_free(gpio); | ||
358 | else | ||
359 | set_bit(FLAG_SYSFS, &gpio_desc[gpio].flags); | ||
360 | |||
361 | done: | ||
362 | if (status) | ||
363 | pr_debug("%s: status %d\n", __func__, status); | ||
364 | return status ? : len; | ||
365 | } | ||
366 | |||
367 | static ssize_t unexport_store(struct class *class, const char *buf, size_t len) | ||
368 | { | ||
369 | long gpio; | ||
370 | int status; | ||
371 | |||
372 | status = strict_strtol(buf, 0, &gpio); | ||
373 | if (status < 0) | ||
374 | goto done; | ||
375 | |||
376 | status = -EINVAL; | ||
377 | |||
378 | /* reject bogus commands (gpio_unexport ignores them) */ | ||
379 | if (!gpio_is_valid(gpio)) | ||
380 | goto done; | ||
381 | |||
382 | /* No extra locking here; FLAG_SYSFS just signifies that the | ||
383 | * request and export were done by on behalf of userspace, so | ||
384 | * they may be undone on its behalf too. | ||
385 | */ | ||
386 | if (test_and_clear_bit(FLAG_SYSFS, &gpio_desc[gpio].flags)) { | ||
387 | status = 0; | ||
388 | gpio_free(gpio); | ||
389 | } | ||
390 | done: | ||
391 | if (status) | ||
392 | pr_debug("%s: status %d\n", __func__, status); | ||
393 | return status ? : len; | ||
394 | } | ||
395 | |||
396 | static struct class_attribute gpio_class_attrs[] = { | ||
397 | __ATTR(export, 0200, NULL, export_store), | ||
398 | __ATTR(unexport, 0200, NULL, unexport_store), | ||
399 | __ATTR_NULL, | ||
400 | }; | ||
401 | |||
402 | static struct class gpio_class = { | ||
403 | .name = "gpio", | ||
404 | .owner = THIS_MODULE, | ||
405 | |||
406 | .class_attrs = gpio_class_attrs, | ||
407 | }; | ||
408 | |||
409 | |||
410 | /** | ||
411 | * gpio_export - export a GPIO through sysfs | ||
412 | * @gpio: gpio to make available, already requested | ||
413 | * @direction_may_change: true if userspace may change gpio direction | ||
414 | * Context: arch_initcall or later | ||
415 | * | ||
416 | * When drivers want to make a GPIO accessible to userspace after they | ||
417 | * have requested it -- perhaps while debugging, or as part of their | ||
418 | * public interface -- they may use this routine. If the GPIO can | ||
419 | * change direction (some can't) and the caller allows it, userspace | ||
420 | * will see "direction" sysfs attribute which may be used to change | ||
421 | * the gpio's direction. A "value" attribute will always be provided. | ||
422 | * | ||
423 | * Returns zero on success, else an error. | ||
424 | */ | ||
425 | int gpio_export(unsigned gpio, bool direction_may_change) | ||
426 | { | ||
427 | unsigned long flags; | ||
428 | struct gpio_desc *desc; | ||
429 | int status = -EINVAL; | ||
430 | |||
431 | /* can't export until sysfs is available ... */ | ||
432 | if (!gpio_class.p) { | ||
433 | pr_debug("%s: called too early!\n", __func__); | ||
434 | return -ENOENT; | ||
435 | } | ||
436 | |||
437 | if (!gpio_is_valid(gpio)) | ||
438 | goto done; | ||
439 | |||
440 | mutex_lock(&sysfs_lock); | ||
441 | |||
442 | spin_lock_irqsave(&gpio_lock, flags); | ||
443 | desc = &gpio_desc[gpio]; | ||
444 | if (test_bit(FLAG_REQUESTED, &desc->flags) | ||
445 | && !test_bit(FLAG_EXPORT, &desc->flags)) { | ||
446 | status = 0; | ||
447 | if (!desc->chip->direction_input | ||
448 | || !desc->chip->direction_output) | ||
449 | direction_may_change = false; | ||
450 | } | ||
451 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
452 | |||
453 | if (status == 0) { | ||
454 | struct device *dev; | ||
455 | |||
456 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), | ||
457 | desc, "gpio%d", gpio); | ||
458 | if (dev) { | ||
459 | if (direction_may_change) | ||
460 | status = sysfs_create_group(&dev->kobj, | ||
461 | &gpio_attr_group); | ||
462 | else | ||
463 | status = device_create_file(dev, | ||
464 | &dev_attr_value); | ||
465 | if (status != 0) | ||
466 | device_unregister(dev); | ||
467 | } else | ||
468 | status = -ENODEV; | ||
469 | if (status == 0) | ||
470 | set_bit(FLAG_EXPORT, &desc->flags); | ||
471 | } | ||
472 | |||
473 | mutex_unlock(&sysfs_lock); | ||
474 | |||
475 | done: | ||
476 | if (status) | ||
477 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | ||
478 | |||
479 | return status; | ||
480 | } | ||
481 | EXPORT_SYMBOL_GPL(gpio_export); | ||
482 | |||
483 | static int match_export(struct device *dev, void *data) | ||
484 | { | ||
485 | return dev_get_drvdata(dev) == data; | ||
486 | } | ||
487 | |||
488 | /** | ||
489 | * gpio_unexport - reverse effect of gpio_export() | ||
490 | * @gpio: gpio to make unavailable | ||
491 | * | ||
492 | * This is implicit on gpio_free(). | ||
493 | */ | ||
494 | void gpio_unexport(unsigned gpio) | ||
495 | { | ||
496 | struct gpio_desc *desc; | ||
497 | int status = -EINVAL; | ||
498 | |||
499 | if (!gpio_is_valid(gpio)) | ||
500 | goto done; | ||
501 | |||
502 | mutex_lock(&sysfs_lock); | ||
503 | |||
504 | desc = &gpio_desc[gpio]; | ||
505 | if (test_bit(FLAG_EXPORT, &desc->flags)) { | ||
506 | struct device *dev = NULL; | ||
507 | |||
508 | dev = class_find_device(&gpio_class, NULL, desc, match_export); | ||
509 | if (dev) { | ||
510 | clear_bit(FLAG_EXPORT, &desc->flags); | ||
511 | put_device(dev); | ||
512 | device_unregister(dev); | ||
513 | status = 0; | ||
514 | } else | ||
515 | status = -ENODEV; | ||
516 | } | ||
517 | |||
518 | mutex_unlock(&sysfs_lock); | ||
519 | done: | ||
520 | if (status) | ||
521 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | ||
522 | } | ||
523 | EXPORT_SYMBOL_GPL(gpio_unexport); | ||
524 | |||
525 | static int gpiochip_export(struct gpio_chip *chip) | ||
526 | { | ||
527 | int status; | ||
528 | struct device *dev; | ||
529 | |||
530 | /* Many systems register gpio chips for SOC support very early, | ||
531 | * before driver model support is available. In those cases we | ||
532 | * export this later, in gpiolib_sysfs_init() ... here we just | ||
533 | * verify that _some_ field of gpio_class got initialized. | ||
534 | */ | ||
535 | if (!gpio_class.p) | ||
536 | return 0; | ||
537 | |||
538 | /* use chip->base for the ID; it's already known to be unique */ | ||
539 | mutex_lock(&sysfs_lock); | ||
540 | dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip, | ||
541 | "gpiochip%d", chip->base); | ||
542 | if (dev) { | ||
543 | status = sysfs_create_group(&dev->kobj, | ||
544 | &gpiochip_attr_group); | ||
545 | } else | ||
546 | status = -ENODEV; | ||
547 | chip->exported = (status == 0); | ||
548 | mutex_unlock(&sysfs_lock); | ||
549 | |||
550 | if (status) { | ||
551 | unsigned long flags; | ||
552 | unsigned gpio; | ||
553 | |||
554 | spin_lock_irqsave(&gpio_lock, flags); | ||
555 | gpio = chip->base; | ||
556 | while (gpio_desc[gpio].chip == chip) | ||
557 | gpio_desc[gpio++].chip = NULL; | ||
558 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
559 | |||
560 | pr_debug("%s: chip %s status %d\n", __func__, | ||
561 | chip->label, status); | ||
562 | } | ||
563 | |||
564 | return status; | ||
565 | } | ||
566 | |||
567 | static void gpiochip_unexport(struct gpio_chip *chip) | ||
568 | { | ||
569 | int status; | ||
570 | struct device *dev; | ||
571 | |||
572 | mutex_lock(&sysfs_lock); | ||
573 | dev = class_find_device(&gpio_class, NULL, chip, match_export); | ||
574 | if (dev) { | ||
575 | put_device(dev); | ||
576 | device_unregister(dev); | ||
577 | chip->exported = 0; | ||
578 | status = 0; | ||
579 | } else | ||
580 | status = -ENODEV; | ||
581 | mutex_unlock(&sysfs_lock); | ||
582 | |||
583 | if (status) | ||
584 | pr_debug("%s: chip %s status %d\n", __func__, | ||
585 | chip->label, status); | ||
586 | } | ||
587 | |||
588 | static int __init gpiolib_sysfs_init(void) | ||
589 | { | ||
590 | int status; | ||
591 | unsigned long flags; | ||
592 | unsigned gpio; | ||
593 | |||
594 | status = class_register(&gpio_class); | ||
595 | if (status < 0) | ||
596 | return status; | ||
597 | |||
598 | /* Scan and register the gpio_chips which registered very | ||
599 | * early (e.g. before the class_register above was called). | ||
600 | * | ||
601 | * We run before arch_initcall() so chip->dev nodes can have | ||
602 | * registered, and so arch_initcall() can always gpio_export(). | ||
603 | */ | ||
604 | spin_lock_irqsave(&gpio_lock, flags); | ||
605 | for (gpio = 0; gpio < ARCH_NR_GPIOS; gpio++) { | ||
606 | struct gpio_chip *chip; | ||
607 | |||
608 | chip = gpio_desc[gpio].chip; | ||
609 | if (!chip || chip->exported) | ||
610 | continue; | ||
611 | |||
612 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
613 | status = gpiochip_export(chip); | ||
614 | spin_lock_irqsave(&gpio_lock, flags); | ||
615 | } | ||
616 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
617 | |||
618 | |||
619 | return status; | ||
620 | } | ||
621 | postcore_initcall(gpiolib_sysfs_init); | ||
622 | |||
623 | #else | ||
624 | static inline int gpiochip_export(struct gpio_chip *chip) | ||
625 | { | ||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static inline void gpiochip_unexport(struct gpio_chip *chip) | ||
630 | { | ||
631 | } | ||
632 | |||
633 | #endif /* CONFIG_GPIO_SYSFS */ | ||
634 | |||
154 | /** | 635 | /** |
155 | * gpiochip_add() - register a gpio_chip | 636 | * gpiochip_add() - register a gpio_chip |
156 | * @chip: the chip to register, with chip->base initialized | 637 | * @chip: the chip to register, with chip->base initialized |
@@ -160,6 +641,11 @@ err: | |||
160 | * because the chip->base is invalid or already associated with a | 641 | * because the chip->base is invalid or already associated with a |
161 | * different chip. Otherwise it returns zero as a success code. | 642 | * different chip. Otherwise it returns zero as a success code. |
162 | * | 643 | * |
644 | * When gpiochip_add() is called very early during boot, so that GPIOs | ||
645 | * can be freely used, the chip->dev device must be registered before | ||
646 | * the gpio framework's arch_initcall(). Otherwise sysfs initialization | ||
647 | * for GPIOs will fail rudely. | ||
648 | * | ||
163 | * If chip->base is negative, this requests dynamic assignment of | 649 | * If chip->base is negative, this requests dynamic assignment of |
164 | * a range of valid GPIOs. | 650 | * a range of valid GPIOs. |
165 | */ | 651 | */ |
@@ -182,7 +668,7 @@ int gpiochip_add(struct gpio_chip *chip) | |||
182 | base = gpiochip_find_base(chip->ngpio); | 668 | base = gpiochip_find_base(chip->ngpio); |
183 | if (base < 0) { | 669 | if (base < 0) { |
184 | status = base; | 670 | status = base; |
185 | goto fail_unlock; | 671 | goto unlock; |
186 | } | 672 | } |
187 | chip->base = base; | 673 | chip->base = base; |
188 | } | 674 | } |
@@ -197,12 +683,23 @@ int gpiochip_add(struct gpio_chip *chip) | |||
197 | if (status == 0) { | 683 | if (status == 0) { |
198 | for (id = base; id < base + chip->ngpio; id++) { | 684 | for (id = base; id < base + chip->ngpio; id++) { |
199 | gpio_desc[id].chip = chip; | 685 | gpio_desc[id].chip = chip; |
200 | gpio_desc[id].flags = 0; | 686 | |
687 | /* REVISIT: most hardware initializes GPIOs as | ||
688 | * inputs (often with pullups enabled) so power | ||
689 | * usage is minimized. Linux code should set the | ||
690 | * gpio direction first thing; but until it does, | ||
691 | * we may expose the wrong direction in sysfs. | ||
692 | */ | ||
693 | gpio_desc[id].flags = !chip->direction_input | ||
694 | ? (1 << FLAG_IS_OUT) | ||
695 | : 0; | ||
201 | } | 696 | } |
202 | } | 697 | } |
203 | 698 | ||
204 | fail_unlock: | 699 | unlock: |
205 | spin_unlock_irqrestore(&gpio_lock, flags); | 700 | spin_unlock_irqrestore(&gpio_lock, flags); |
701 | if (status == 0) | ||
702 | status = gpiochip_export(chip); | ||
206 | fail: | 703 | fail: |
207 | /* failures here can mean systems won't boot... */ | 704 | /* failures here can mean systems won't boot... */ |
208 | if (status) | 705 | if (status) |
@@ -239,6 +736,10 @@ int gpiochip_remove(struct gpio_chip *chip) | |||
239 | } | 736 | } |
240 | 737 | ||
241 | spin_unlock_irqrestore(&gpio_lock, flags); | 738 | spin_unlock_irqrestore(&gpio_lock, flags); |
739 | |||
740 | if (status == 0) | ||
741 | gpiochip_unexport(chip); | ||
742 | |||
242 | return status; | 743 | return status; |
243 | } | 744 | } |
244 | EXPORT_SYMBOL_GPL(gpiochip_remove); | 745 | EXPORT_SYMBOL_GPL(gpiochip_remove); |
@@ -296,6 +797,8 @@ void gpio_free(unsigned gpio) | |||
296 | return; | 797 | return; |
297 | } | 798 | } |
298 | 799 | ||
800 | gpio_unexport(gpio); | ||
801 | |||
299 | spin_lock_irqsave(&gpio_lock, flags); | 802 | spin_lock_irqsave(&gpio_lock, flags); |
300 | 803 | ||
301 | desc = &gpio_desc[gpio]; | 804 | desc = &gpio_desc[gpio]; |
@@ -534,10 +1037,6 @@ EXPORT_SYMBOL_GPL(gpio_set_value_cansleep); | |||
534 | 1037 | ||
535 | #ifdef CONFIG_DEBUG_FS | 1038 | #ifdef CONFIG_DEBUG_FS |
536 | 1039 | ||
537 | #include <linux/debugfs.h> | ||
538 | #include <linux/seq_file.h> | ||
539 | |||
540 | |||
541 | static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | 1040 | static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) |
542 | { | 1041 | { |
543 | unsigned i; | 1042 | unsigned i; |
@@ -614,17 +1113,28 @@ static int gpiolib_show(struct seq_file *s, void *unused) | |||
614 | /* REVISIT this isn't locked against gpio_chip removal ... */ | 1113 | /* REVISIT this isn't locked against gpio_chip removal ... */ |
615 | 1114 | ||
616 | for (gpio = 0; gpio_is_valid(gpio); gpio++) { | 1115 | for (gpio = 0; gpio_is_valid(gpio); gpio++) { |
1116 | struct device *dev; | ||
1117 | |||
617 | if (chip == gpio_desc[gpio].chip) | 1118 | if (chip == gpio_desc[gpio].chip) |
618 | continue; | 1119 | continue; |
619 | chip = gpio_desc[gpio].chip; | 1120 | chip = gpio_desc[gpio].chip; |
620 | if (!chip) | 1121 | if (!chip) |
621 | continue; | 1122 | continue; |
622 | 1123 | ||
623 | seq_printf(s, "%sGPIOs %d-%d, %s%s:\n", | 1124 | seq_printf(s, "%sGPIOs %d-%d", |
624 | started ? "\n" : "", | 1125 | started ? "\n" : "", |
625 | chip->base, chip->base + chip->ngpio - 1, | 1126 | chip->base, chip->base + chip->ngpio - 1); |
626 | chip->label ? : "generic", | 1127 | dev = chip->dev; |
627 | chip->can_sleep ? ", can sleep" : ""); | 1128 | if (dev) |
1129 | seq_printf(s, ", %s/%s", | ||
1130 | dev->bus ? dev->bus->name : "no-bus", | ||
1131 | dev->bus_id); | ||
1132 | if (chip->label) | ||
1133 | seq_printf(s, ", %s", chip->label); | ||
1134 | if (chip->can_sleep) | ||
1135 | seq_printf(s, ", can sleep"); | ||
1136 | seq_printf(s, ":\n"); | ||
1137 | |||
628 | started = 1; | 1138 | started = 1; |
629 | if (chip->dbg_show) | 1139 | if (chip->dbg_show) |
630 | chip->dbg_show(s, chip); | 1140 | chip->dbg_show(s, chip); |
diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c index 7f92fdd5f0e2..7efd7d3a81f9 100644 --- a/drivers/gpio/mcp23s08.c +++ b/drivers/gpio/mcp23s08.c | |||
@@ -239,6 +239,7 @@ static int mcp23s08_probe(struct spi_device *spi) | |||
239 | mcp->chip.base = pdata->base; | 239 | mcp->chip.base = pdata->base; |
240 | mcp->chip.ngpio = 8; | 240 | mcp->chip.ngpio = 8; |
241 | mcp->chip.can_sleep = 1; | 241 | mcp->chip.can_sleep = 1; |
242 | mcp->chip.dev = &spi->dev; | ||
242 | mcp->chip.owner = THIS_MODULE; | 243 | mcp->chip.owner = THIS_MODULE; |
243 | 244 | ||
244 | spi_set_drvdata(spi, mcp); | 245 | spi_set_drvdata(spi, mcp); |
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index a380730b61ab..cc8468692ae0 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
@@ -188,6 +188,7 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) | |||
188 | gc->base = chip->gpio_start; | 188 | gc->base = chip->gpio_start; |
189 | gc->ngpio = gpios; | 189 | gc->ngpio = gpios; |
190 | gc->label = chip->client->name; | 190 | gc->label = chip->client->name; |
191 | gc->dev = &chip->client->dev; | ||
191 | gc->owner = THIS_MODULE; | 192 | gc->owner = THIS_MODULE; |
192 | } | 193 | } |
193 | 194 | ||
diff --git a/drivers/gpio/pcf857x.c b/drivers/gpio/pcf857x.c index d25d356c4f20..fc9c6ae739ee 100644 --- a/drivers/gpio/pcf857x.c +++ b/drivers/gpio/pcf857x.c | |||
@@ -200,6 +200,7 @@ static int pcf857x_probe(struct i2c_client *client, | |||
200 | 200 | ||
201 | gpio->chip.base = pdata->gpio_base; | 201 | gpio->chip.base = pdata->gpio_base; |
202 | gpio->chip.can_sleep = 1; | 202 | gpio->chip.can_sleep = 1; |
203 | gpio->chip.dev = &client->dev; | ||
203 | gpio->chip.owner = THIS_MODULE; | 204 | gpio->chip.owner = THIS_MODULE; |
204 | 205 | ||
205 | /* NOTE: the OnSemi jlc1562b is also largely compatible with | 206 | /* NOTE: the OnSemi jlc1562b is also largely compatible with |
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c index 85949685191b..cf02e8fceb42 100644 --- a/drivers/i2c/chips/tps65010.c +++ b/drivers/i2c/chips/tps65010.c | |||
@@ -636,6 +636,8 @@ static int tps65010_probe(struct i2c_client *client, | |||
636 | tps->outmask = board->outmask; | 636 | tps->outmask = board->outmask; |
637 | 637 | ||
638 | tps->chip.label = client->name; | 638 | tps->chip.label = client->name; |
639 | tps->chip.dev = &client->dev; | ||
640 | tps->chip.owner = THIS_MODULE; | ||
639 | 641 | ||
640 | tps->chip.set = tps65010_gpio_set; | 642 | tps->chip.set = tps65010_gpio_set; |
641 | tps->chip.direction_output = tps65010_output; | 643 | tps->chip.direction_output = tps65010_output; |
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index 8872cc077519..6be43172dc65 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c | |||
@@ -318,6 +318,8 @@ static int __init egpio_probe(struct platform_device *pdev) | |||
318 | ei->chip[i].dev = &(pdev->dev); | 318 | ei->chip[i].dev = &(pdev->dev); |
319 | chip = &(ei->chip[i].chip); | 319 | chip = &(ei->chip[i].chip); |
320 | chip->label = "htc-egpio"; | 320 | chip->label = "htc-egpio"; |
321 | chip->dev = &pdev->dev; | ||
322 | chip->owner = THIS_MODULE; | ||
321 | chip->get = egpio_get; | 323 | chip->get = egpio_get; |
322 | chip->set = egpio_set; | 324 | chip->set = egpio_set; |
323 | chip->direction_input = egpio_direction_input; | 325 | chip->direction_input = egpio_direction_input; |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 6be061d09da9..1beff5166e53 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
@@ -32,6 +32,8 @@ struct module; | |||
32 | /** | 32 | /** |
33 | * struct gpio_chip - abstract a GPIO controller | 33 | * struct gpio_chip - abstract a GPIO controller |
34 | * @label: for diagnostics | 34 | * @label: for diagnostics |
35 | * @dev: optional device providing the GPIOs | ||
36 | * @owner: helps prevent removal of modules exporting active GPIOs | ||
35 | * @direction_input: configures signal "offset" as input, or returns error | 37 | * @direction_input: configures signal "offset" as input, or returns error |
36 | * @get: returns value for signal "offset"; for output signals this | 38 | * @get: returns value for signal "offset"; for output signals this |
37 | * returns either the value actually sensed, or zero | 39 | * returns either the value actually sensed, or zero |
@@ -59,6 +61,7 @@ struct module; | |||
59 | */ | 61 | */ |
60 | struct gpio_chip { | 62 | struct gpio_chip { |
61 | char *label; | 63 | char *label; |
64 | struct device *dev; | ||
62 | struct module *owner; | 65 | struct module *owner; |
63 | 66 | ||
64 | int (*direction_input)(struct gpio_chip *chip, | 67 | int (*direction_input)(struct gpio_chip *chip, |
@@ -74,6 +77,7 @@ struct gpio_chip { | |||
74 | int base; | 77 | int base; |
75 | u16 ngpio; | 78 | u16 ngpio; |
76 | unsigned can_sleep:1; | 79 | unsigned can_sleep:1; |
80 | unsigned exported:1; | ||
77 | }; | 81 | }; |
78 | 82 | ||
79 | extern const char *gpiochip_is_requested(struct gpio_chip *chip, | 83 | extern const char *gpiochip_is_requested(struct gpio_chip *chip, |
@@ -108,7 +112,18 @@ extern void __gpio_set_value(unsigned gpio, int value); | |||
108 | extern int __gpio_cansleep(unsigned gpio); | 112 | extern int __gpio_cansleep(unsigned gpio); |
109 | 113 | ||
110 | 114 | ||
111 | #else | 115 | #ifdef CONFIG_GPIO_SYSFS |
116 | |||
117 | /* | ||
118 | * A sysfs interface can be exported by individual drivers if they want, | ||
119 | * but more typically is configured entirely from userspace. | ||
120 | */ | ||
121 | extern int gpio_export(unsigned gpio, bool direction_may_change); | ||
122 | extern void gpio_unexport(unsigned gpio); | ||
123 | |||
124 | #endif /* CONFIG_GPIO_SYSFS */ | ||
125 | |||
126 | #else /* !CONFIG_HAVE_GPIO_LIB */ | ||
112 | 127 | ||
113 | static inline int gpio_is_valid(int number) | 128 | static inline int gpio_is_valid(int number) |
114 | { | 129 | { |
@@ -137,6 +152,20 @@ static inline void gpio_set_value_cansleep(unsigned gpio, int value) | |||
137 | gpio_set_value(gpio, value); | 152 | gpio_set_value(gpio, value); |
138 | } | 153 | } |
139 | 154 | ||
140 | #endif | 155 | #endif /* !CONFIG_HAVE_GPIO_LIB */ |
156 | |||
157 | #ifndef CONFIG_GPIO_SYSFS | ||
158 | |||
159 | /* sysfs support is only available with gpiolib, where it's optional */ | ||
160 | |||
161 | static inline int gpio_export(unsigned gpio, bool direction_may_change) | ||
162 | { | ||
163 | return -ENOSYS; | ||
164 | } | ||
165 | |||
166 | static inline void gpio_unexport(unsigned gpio) | ||
167 | { | ||
168 | } | ||
169 | #endif /* CONFIG_GPIO_SYSFS */ | ||
141 | 170 | ||
142 | #endif /* _ASM_GENERIC_GPIO_H */ | 171 | #endif /* _ASM_GENERIC_GPIO_H */ |
diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 98be6c5762b9..730a20b83576 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h | |||
@@ -79,6 +79,19 @@ static inline void gpio_set_value_cansleep(unsigned gpio, int value) | |||
79 | WARN_ON(1); | 79 | WARN_ON(1); |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline int gpio_export(unsigned gpio, bool direction_may_change) | ||
83 | { | ||
84 | /* GPIO can never have been requested or set as {in,out}put */ | ||
85 | WARN_ON(1); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | |||
89 | static inline void gpio_unexport(unsigned gpio) | ||
90 | { | ||
91 | /* GPIO can never have been exported */ | ||
92 | WARN_ON(1); | ||
93 | } | ||
94 | |||
82 | static inline int gpio_to_irq(unsigned gpio) | 95 | static inline int gpio_to_irq(unsigned gpio) |
83 | { | 96 | { |
84 | /* GPIO can never have been requested or set as input */ | 97 | /* GPIO can never have been requested or set as input */ |