lkml.org 
[lkml]   [2009]   [Apr]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[PATCH] gpiolib: Introduce a GPIO "port" concept
Date
From
gpiolib: Introduce a GPIO "port" concept.

Some drivers will use all the GPIOs in a given GPIOLIB chip as
a port. Allow them to request/free these GPIOs with a single
call. For both functions any valid GPIO in the chip needs to
be passed.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>

---

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 51a8d41..cd16e83 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -49,6 +49,7 @@ struct gpio_desc {
#define FLAG_RESERVED 2
#define FLAG_EXPORT 3 /* protected by sysfs_lock */
#define FLAG_SYSFS 4 /* exported via /sys/class/gpio/control
*/
+#define FLAG_IS_PORT 5

#ifdef CONFIG_DEBUG_FS
const char *label;
@@ -859,6 +860,84 @@ void gpio_free(unsigned gpio)
}
EXPORT_SYMBOL_GPL(gpio_free);

+int gpio_port_request(unsigned gpio, const char *label)
+{
+ struct gpio_desc *desc;
+ struct gpio_chip *chip;
+ int status = -EINVAL;
+ unsigned long flags;
+ unsigned _gpio;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ if (!gpio_is_valid(gpio))
+ goto done;
+ desc = &gpio_desc[gpio];
+ chip = desc->chip;
+ if (chip == NULL)
+ goto done;
+
+ for (_gpio = chip->base; _gpio < chip->base + chip->ngpio;
_gpio++) {
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ status = gpio_request(_gpio, label);
+ if (status < 0)
+ goto err;
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ desc = &gpio_desc[_gpio];
+ set_bit(FLAG_IS_PORT, &desc->flags);
+ }
+ spin_unlock_irqrestore(&gpio_lock, flags);
+
+ return 0;
+
+err:
+ /* free any GPIOs that may have been successfully requested */
+ for ( ; _gpio >= chip->base; _gpio--)
+ gpio_free(_gpio);
+ spin_lock_irqsave(&gpio_lock, flags);
+done:
+ pr_debug("gpio_port_request: gpio-%d (%s) status %d\n",
+ gpio, label ? : "?", status);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ return status;
+}
+EXPORT_SYMBOL_GPL(gpio_port_request);
+
+void gpio_port_free(unsigned gpio)
+{
+ unsigned long flags;
+ struct gpio_desc *desc;
+ struct gpio_chip *chip;
+ unsigned _gpio;
+
+ might_sleep();
+
+ if (!gpio_is_valid(gpio)) {
+ WARN_ON(extra_checks);
+ return;
+ }
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ desc = &gpio_desc[gpio];
+ chip = desc->chip;
+
+ for (_gpio = chip->base; _gpio < chip->base + chip->ngpio;
_gpio++) {
+ desc = &gpio_desc[_gpio];
+ if (!test_bit(FLAG_IS_PORT, &desc->flags))
+ WARN_ON(extra_checks);
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ gpio_free(_gpio);
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ clear_bit(FLAG_IS_PORT, &desc->flags);
+ }
+ spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL_GPL(gpio_port_free);
+

/**
* gpiochip_is_requested - return string iff signal was requested
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index d6c379d..9f7ebd5 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -116,6 +116,9 @@ extern int __must_check gpiochip_remove(struct
gpio_chip *chip);
extern int gpio_request(unsigned gpio, const char *label);
extern void gpio_free(unsigned gpio);

+extern int gpio_port_request(unsigned gpio, const char *label);
+extern void gpio_port_free(unsigned gpio);
+
extern int gpio_direction_input(unsigned gpio);
extern int gpio_direction_output(unsigned gpio, int value);
[unhandled content-type:application/octet-stream]
\
 
 \ /
  Last update: 2009-04-20 21:03    [W:0.770 / U:0.528 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site