Commit 3e45f1d1155894e6f4291f5536b224874d52d8e2

Authored by Eric Miao
Committed by Linus Torvalds
1 parent 62fecb70cf

gpio: introduce gpio_request_one() and friends

gpio_request() without initial configuration of the GPIO is normally
useless, introduce gpio_request_one() together with GPIOF_ flags for
input/output direction and initial output level.

gpio_{request,free}_array() for multiple GPIOs.

Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Ben Nizette <bn@niasdigital.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 3 changed files with 148 additions and 0 deletions Side-by-side Diff

Documentation/gpio.txt
... ... @@ -253,6 +253,70 @@
253 253 Also note that it's your responsibility to have stopped using a GPIO
254 254 before you free it.
255 255  
  256 +Considering in most cases GPIOs are actually configured right after they
  257 +are claimed, three additional calls are defined:
  258 +
  259 + /* request a single GPIO, with initial configuration specified by
  260 + * 'flags', identical to gpio_request() wrt other arguments and
  261 + * return value
  262 + */
  263 + int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
  264 +
  265 + /* request multiple GPIOs in a single call
  266 + */
  267 + int gpio_request_array(struct gpio *array, size_t num);
  268 +
  269 + /* release multiple GPIOs in a single call
  270 + */
  271 + void gpio_free_array(struct gpio *array, size_t num);
  272 +
  273 +where 'flags' is currently defined to specify the following properties:
  274 +
  275 + * GPIOF_DIR_IN - to configure direction as input
  276 + * GPIOF_DIR_OUT - to configure direction as output
  277 +
  278 + * GPIOF_INIT_LOW - as output, set initial level to LOW
  279 + * GPIOF_INIT_HIGH - as output, set initial level to HIGH
  280 +
  281 +since GPIOF_INIT_* are only valid when configured as output, so group valid
  282 +combinations as:
  283 +
  284 + * GPIOF_IN - configure as input
  285 + * GPIOF_OUT_INIT_LOW - configured as output, initial level LOW
  286 + * GPIOF_OUT_INIT_HIGH - configured as output, initial level HIGH
  287 +
  288 +In the future, these flags can be extended to support more properties such
  289 +as open-drain status.
  290 +
  291 +Further more, to ease the claim/release of multiple GPIOs, 'struct gpio' is
  292 +introduced to encapsulate all three fields as:
  293 +
  294 + struct gpio {
  295 + unsigned gpio;
  296 + unsigned long flags;
  297 + const char *label;
  298 + };
  299 +
  300 +A typical example of usage:
  301 +
  302 + static struct gpio leds_gpios[] = {
  303 + { 32, GPIOF_OUT_INIT_HIGH, "Power LED" }, /* default to ON */
  304 + { 33, GPIOF_OUT_INIT_LOW, "Green LED" }, /* default to OFF */
  305 + { 34, GPIOF_OUT_INIT_LOW, "Red LED" }, /* default to OFF */
  306 + { 35, GPIOF_OUT_INIT_LOW, "Blue LED" }, /* default to OFF */
  307 + { ... },
  308 + };
  309 +
  310 + err = gpio_request_one(31, GPIOF_IN, "Reset Button");
  311 + if (err)
  312 + ...
  313 +
  314 + err = gpio_request_array(leds_gpios, ARRAY_SIZE(leds_gpios));
  315 + if (err)
  316 + ...
  317 +
  318 + gpio_free_array(leds_gpios, ARRAY_SIZE(leds_gpios));
  319 +
256 320  
257 321 GPIOs mapped to IRQs
258 322 --------------------
drivers/gpio/gpiolib.c
... ... @@ -1237,6 +1237,64 @@
1237 1237 }
1238 1238 EXPORT_SYMBOL_GPL(gpio_free);
1239 1239  
  1240 +/**
  1241 + * gpio_request_one - request a single GPIO with initial configuration
  1242 + * @gpio: the GPIO number
  1243 + * @flags: GPIO configuration as specified by GPIOF_*
  1244 + * @label: a literal description string of this GPIO
  1245 + */
  1246 +int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
  1247 +{
  1248 + int err;
  1249 +
  1250 + err = gpio_request(gpio, label);
  1251 + if (err)
  1252 + return err;
  1253 +
  1254 + if (flags & GPIOF_DIR_IN)
  1255 + err = gpio_direction_input(gpio);
  1256 + else
  1257 + err = gpio_direction_output(gpio,
  1258 + (flags & GPIOF_INIT_HIGH) ? 1 : 0);
  1259 +
  1260 + return err;
  1261 +}
  1262 +EXPORT_SYMBOL_GPL(gpio_request_one);
  1263 +
  1264 +/**
  1265 + * gpio_request_array - request multiple GPIOs in a single call
  1266 + * @array: array of the 'struct gpio'
  1267 + * @num: how many GPIOs in the array
  1268 + */
  1269 +int gpio_request_array(struct gpio *array, size_t num)
  1270 +{
  1271 + int i, err;
  1272 +
  1273 + for (i = 0; i < num; i++, array++) {
  1274 + err = gpio_request_one(array->gpio, array->flags, array->label);
  1275 + if (err)
  1276 + goto err_free;
  1277 + }
  1278 + return 0;
  1279 +
  1280 +err_free:
  1281 + while (i--)
  1282 + gpio_free((--array)->gpio);
  1283 + return err;
  1284 +}
  1285 +EXPORT_SYMBOL_GPL(gpio_request_array);
  1286 +
  1287 +/**
  1288 + * gpio_free_array - release multiple GPIOs in a single call
  1289 + * @array: array of the 'struct gpio'
  1290 + * @num: how many GPIOs in the array
  1291 + */
  1292 +void gpio_free_array(struct gpio *array, size_t num)
  1293 +{
  1294 + while (num--)
  1295 + gpio_free((array++)->gpio);
  1296 +}
  1297 +EXPORT_SYMBOL_GPL(gpio_free_array);
1240 1298  
1241 1299 /**
1242 1300 * gpiochip_is_requested - return string iff signal was requested
include/asm-generic/gpio.h
... ... @@ -136,6 +136,32 @@
136 136  
137 137 extern int __gpio_to_irq(unsigned gpio);
138 138  
  139 +#define GPIOF_DIR_OUT (0 << 0)
  140 +#define GPIOF_DIR_IN (1 << 0)
  141 +
  142 +#define GPIOF_INIT_LOW (0 << 1)
  143 +#define GPIOF_INIT_HIGH (1 << 1)
  144 +
  145 +#define GPIOF_IN (GPIOF_DIR_IN)
  146 +#define GPIOF_OUT_INIT_LOW (GPIOF_DIR_OUT | GPIOF_INIT_LOW)
  147 +#define GPIOF_OUT_INIT_HIGH (GPIOF_DIR_OUT | GPIOF_INIT_HIGH)
  148 +
  149 +/**
  150 + * struct gpio - a structure describing a GPIO with configuration
  151 + * @gpio: the GPIO number
  152 + * @flags: GPIO configuration as specified by GPIOF_*
  153 + * @label: a literal description string of this GPIO
  154 + */
  155 +struct gpio {
  156 + unsigned gpio;
  157 + unsigned long flags;
  158 + const char *label;
  159 +};
  160 +
  161 +extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
  162 +extern int gpio_request_array(struct gpio *array, size_t num);
  163 +extern void gpio_free_array(struct gpio *array, size_t num);
  164 +
139 165 #ifdef CONFIG_GPIO_SYSFS
140 166  
141 167 /*