aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRojhalat Ibrahim <imr@rtschenk.de>2014-11-04 11:12:06 -0500
committerLinus Walleij <linus.walleij@linaro.org>2014-11-27 09:01:18 -0500
commit5f42424354f5b0ca5413b4fb8528d150692c85b7 (patch)
tree23ba183fa9976595adda4bceb006842a15eb3e19
parentb5b7b487431b01619f2947d91dadd7c7a233692e (diff)
gpiolib: allow simultaneous setting of multiple GPIO outputs
Introduce new functions gpiod_set_array & gpiod_set_raw_array to the consumer interface which allow setting multiple outputs with just one function call. Also add an optional set_multiple function to the driver interface. Without an implementation of that function in the chip driver outputs are set sequentially. Implementing the set_multiple function in a chip driver allows for: - Improved performance for certain use cases. The original motivation for this was the task of configuring an FPGA. In that specific case, where 9 GPIO lines have to be set many times, configuration time goes down from 48 s to 20 s when using the new function. - Simultaneous glitch-free setting of multiple pins on any kind of parallel bus attached to GPIOs provided they all reside on the same chip and bank. Limitations: Performance is only improved for normal high-low outputs. Open drain and open source outputs are always set separately from each other. Those kinds of outputs could probably be accelerated in a similar way if we could forgo the error checking when setting GPIO directions. Change log: v6: - rebase on current linux-gpio devel branch v5: - check can_sleep property per chip - remove superfluous checks - supplement documentation v4: - add gpiod_set_array function for setting logical values - change interface of the set_multiple driver function to use unsigned long as type for the bit fields - use generic bitops (which also use unsigned long for bit fields) - do not use ARCH_NR_GPIOS any more v3: - add documentation - change commit message v2: - use descriptor interface - allow arbitrary groups of GPIOs spanning multiple chips Signed-off-by: Rojhalat Ibrahim <imr@rtschenk.de> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Mark Brown <broonie@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--Documentation/gpio/consumer.txt27
-rw-r--r--drivers/gpio/gpiolib.c168
-rw-r--r--include/linux/gpio/consumer.h38
-rw-r--r--include/linux/gpio/driver.h4
4 files changed, 237 insertions, 0 deletions
diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt
index 6ce544191ca6..c67f806401a5 100644
--- a/Documentation/gpio/consumer.txt
+++ b/Documentation/gpio/consumer.txt
@@ -199,6 +199,33 @@ The active-low state of a GPIO can also be queried using the following call:
199Note that these functions should only be used with great moderation ; a driver 199Note that these functions should only be used with great moderation ; a driver
200should not have to care about the physical line level. 200should not have to care about the physical line level.
201 201
202
203Set multiple GPIO outputs with a single function call
204-----------------------------------------------------
205The following functions set the output values of an array of GPIOs:
206
207 void gpiod_set_array(unsigned int array_size,
208 struct gpio_desc **desc_array,
209 int *value_array)
210 void gpiod_set_raw_array(unsigned int array_size,
211 struct gpio_desc **desc_array,
212 int *value_array)
213 void gpiod_set_array_cansleep(unsigned int array_size,
214 struct gpio_desc **desc_array,
215 int *value_array)
216 void gpiod_set_raw_array_cansleep(unsigned int array_size,
217 struct gpio_desc **desc_array,
218 int *value_array)
219
220The array can be an arbitrary set of GPIOs. The functions will try to set
221GPIOs belonging to the same bank or chip simultaneously if supported by the
222corresponding chip driver. In that case a significantly improved performance
223can be expected. If simultaneous setting is not possible the GPIOs will be set
224sequentially.
225Note that for optimal performance GPIOs belonging to the same chip should be
226contiguous within the array of descriptors.
227
228
202GPIOs mapped to IRQs 229GPIOs mapped to IRQs
203-------------------- 230--------------------
204GPIO lines can quite often be used as IRQs. You can get the IRQ number 231GPIO lines can quite often be used as IRQs. You can get the IRQ number
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 50e18a4b3a9f..eb739a51e774 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1254,6 +1254,88 @@ static void _gpiod_set_raw_value(struct gpio_desc *desc, bool value)
1254 chip->set(chip, gpio_chip_hwgpio(desc), value); 1254 chip->set(chip, gpio_chip_hwgpio(desc), value);
1255} 1255}
1256 1256
1257/*
1258 * set multiple outputs on the same chip;
1259 * use the chip's set_multiple function if available;
1260 * otherwise set the outputs sequentially;
1261 * @mask: bit mask array; one bit per output; BITS_PER_LONG bits per word
1262 * defines which outputs are to be changed
1263 * @bits: bit value array; one bit per output; BITS_PER_LONG bits per word
1264 * defines the values the outputs specified by mask are to be set to
1265 */
1266static void gpio_chip_set_multiple(struct gpio_chip *chip,
1267 unsigned long *mask, unsigned long *bits)
1268{
1269 if (chip->set_multiple) {
1270 chip->set_multiple(chip, mask, bits);
1271 } else {
1272 int i;
1273 for (i = 0; i < chip->ngpio; i++) {
1274 if (mask[BIT_WORD(i)] == 0) {
1275 /* no more set bits in this mask word;
1276 * skip ahead to the next word */
1277 i = (BIT_WORD(i) + 1) * BITS_PER_LONG - 1;
1278 continue;
1279 }
1280 /* set outputs if the corresponding mask bit is set */
1281 if (__test_and_clear_bit(i, mask)) {
1282 chip->set(chip, i, test_bit(i, bits));
1283 }
1284 }
1285 }
1286}
1287
1288static void gpiod_set_array_priv(bool raw, bool can_sleep,
1289 unsigned int array_size,
1290 struct gpio_desc **desc_array,
1291 int *value_array)
1292{
1293 int i = 0;
1294
1295 while (i < array_size) {
1296 struct gpio_chip *chip = desc_array[i]->chip;
1297 unsigned long mask[BITS_TO_LONGS(chip->ngpio)];
1298 unsigned long bits[BITS_TO_LONGS(chip->ngpio)];
1299 int count = 0;
1300
1301 if (!can_sleep) {
1302 WARN_ON(chip->can_sleep);
1303 }
1304 memset(mask, 0, sizeof(mask));
1305 do {
1306 struct gpio_desc *desc = desc_array[i];
1307 int hwgpio = gpio_chip_hwgpio(desc);
1308 int value = value_array[i];
1309
1310 if (!raw && test_bit(FLAG_ACTIVE_LOW, &desc->flags))
1311 value = !value;
1312 trace_gpio_value(desc_to_gpio(desc), 0, value);
1313 /*
1314 * collect all normal outputs belonging to the same chip
1315 * open drain and open source outputs are set individually
1316 */
1317 if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) {
1318 _gpio_set_open_drain_value(desc,value);
1319 } else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) {
1320 _gpio_set_open_source_value(desc, value);
1321 } else {
1322 __set_bit(hwgpio, mask);
1323 if (value) {
1324 __set_bit(hwgpio, bits);
1325 } else {
1326 __clear_bit(hwgpio, bits);
1327 }
1328 count++;
1329 }
1330 i++;
1331 } while ((i < array_size) && (desc_array[i]->chip == chip));
1332 /* push collected bits to outputs */
1333 if (count != 0) {
1334 gpio_chip_set_multiple(chip, mask, bits);
1335 }
1336 }
1337}
1338
1257/** 1339/**
1258 * gpiod_set_raw_value() - assign a gpio's raw value 1340 * gpiod_set_raw_value() - assign a gpio's raw value
1259 * @desc: gpio whose value will be assigned 1341 * @desc: gpio whose value will be assigned
@@ -1299,6 +1381,48 @@ void gpiod_set_value(struct gpio_desc *desc, int value)
1299EXPORT_SYMBOL_GPL(gpiod_set_value); 1381EXPORT_SYMBOL_GPL(gpiod_set_value);
1300 1382
1301/** 1383/**
1384 * gpiod_set_raw_array() - assign values to an array of GPIOs
1385 * @array_size: number of elements in the descriptor / value arrays
1386 * @desc_array: array of GPIO descriptors whose values will be assigned
1387 * @value_array: array of values to assign
1388 *
1389 * Set the raw values of the GPIOs, i.e. the values of the physical lines
1390 * without regard for their ACTIVE_LOW status.
1391 *
1392 * This function should be called from contexts where we cannot sleep, and will
1393 * complain if the GPIO chip functions potentially sleep.
1394 */
1395void gpiod_set_raw_array(unsigned int array_size,
1396 struct gpio_desc **desc_array, int *value_array)
1397{
1398 if (!desc_array)
1399 return;
1400 gpiod_set_array_priv(true, false, array_size, desc_array, value_array);
1401}
1402EXPORT_SYMBOL_GPL(gpiod_set_raw_array);
1403
1404/**
1405 * gpiod_set_array() - assign values to an array of GPIOs
1406 * @array_size: number of elements in the descriptor / value arrays
1407 * @desc_array: array of GPIO descriptors whose values will be assigned
1408 * @value_array: array of values to assign
1409 *
1410 * Set the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
1411 * into account.
1412 *
1413 * This function should be called from contexts where we cannot sleep, and will
1414 * complain if the GPIO chip functions potentially sleep.
1415 */
1416void gpiod_set_array(unsigned int array_size,
1417 struct gpio_desc **desc_array, int *value_array)
1418{
1419 if (!desc_array)
1420 return;
1421 gpiod_set_array_priv(false, false, array_size, desc_array, value_array);
1422}
1423EXPORT_SYMBOL_GPL(gpiod_set_array);
1424
1425/**
1302 * gpiod_cansleep() - report whether gpio value access may sleep 1426 * gpiod_cansleep() - report whether gpio value access may sleep
1303 * @desc: gpio to check 1427 * @desc: gpio to check
1304 * 1428 *
@@ -1458,6 +1582,50 @@ void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
1458EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep); 1582EXPORT_SYMBOL_GPL(gpiod_set_value_cansleep);
1459 1583
1460/** 1584/**
1585 * gpiod_set_raw_array_cansleep() - assign values to an array of GPIOs
1586 * @array_size: number of elements in the descriptor / value arrays
1587 * @desc_array: array of GPIO descriptors whose values will be assigned
1588 * @value_array: array of values to assign
1589 *
1590 * Set the raw values of the GPIOs, i.e. the values of the physical lines
1591 * without regard for their ACTIVE_LOW status.
1592 *
1593 * This function is to be called from contexts that can sleep.
1594 */
1595void gpiod_set_raw_array_cansleep(unsigned int array_size,
1596 struct gpio_desc **desc_array,
1597 int *value_array)
1598{
1599 might_sleep_if(extra_checks);
1600 if (!desc_array)
1601 return;
1602 gpiod_set_array_priv(true, true, array_size, desc_array, value_array);
1603}
1604EXPORT_SYMBOL_GPL(gpiod_set_raw_array_cansleep);
1605
1606/**
1607 * gpiod_set_array_cansleep() - assign values to an array of GPIOs
1608 * @array_size: number of elements in the descriptor / value arrays
1609 * @desc_array: array of GPIO descriptors whose values will be assigned
1610 * @value_array: array of values to assign
1611 *
1612 * Set the logical values of the GPIOs, i.e. taking their ACTIVE_LOW status
1613 * into account.
1614 *
1615 * This function is to be called from contexts that can sleep.
1616 */
1617void gpiod_set_array_cansleep(unsigned int array_size,
1618 struct gpio_desc **desc_array,
1619 int *value_array)
1620{
1621 might_sleep_if(extra_checks);
1622 if (!desc_array)
1623 return;
1624 gpiod_set_array_priv(false, true, array_size, desc_array, value_array);
1625}
1626EXPORT_SYMBOL_GPL(gpiod_set_array_cansleep);
1627
1628/**
1461 * gpiod_add_lookup_table() - register GPIO device consumers 1629 * gpiod_add_lookup_table() - register GPIO device consumers
1462 * @table: table of consumers to register 1630 * @table: table of consumers to register
1463 */ 1631 */
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index 12f146fa6604..83c0a61c605d 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -74,14 +74,24 @@ int gpiod_direction_output_raw(struct gpio_desc *desc, int value);
74/* Value get/set from non-sleeping context */ 74/* Value get/set from non-sleeping context */
75int gpiod_get_value(const struct gpio_desc *desc); 75int gpiod_get_value(const struct gpio_desc *desc);
76void gpiod_set_value(struct gpio_desc *desc, int value); 76void gpiod_set_value(struct gpio_desc *desc, int value);
77void gpiod_set_array(unsigned int array_size,
78 struct gpio_desc **desc_array, int *value_array);
77int gpiod_get_raw_value(const struct gpio_desc *desc); 79int gpiod_get_raw_value(const struct gpio_desc *desc);
78void gpiod_set_raw_value(struct gpio_desc *desc, int value); 80void gpiod_set_raw_value(struct gpio_desc *desc, int value);
81void gpiod_set_raw_array(unsigned int array_size,
82 struct gpio_desc **desc_array, int *value_array);
79 83
80/* Value get/set from sleeping context */ 84/* Value get/set from sleeping context */
81int gpiod_get_value_cansleep(const struct gpio_desc *desc); 85int gpiod_get_value_cansleep(const struct gpio_desc *desc);
82void gpiod_set_value_cansleep(struct gpio_desc *desc, int value); 86void gpiod_set_value_cansleep(struct gpio_desc *desc, int value);
87void gpiod_set_array_cansleep(unsigned int array_size,
88 struct gpio_desc **desc_array,
89 int *value_array);
83int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc); 90int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc);
84void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value); 91void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value);
92void gpiod_set_raw_array_cansleep(unsigned int array_size,
93 struct gpio_desc **desc_array,
94 int *value_array);
85 95
86int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce); 96int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
87 97
@@ -210,6 +220,13 @@ static inline void gpiod_set_value(struct gpio_desc *desc, int value)
210 /* GPIO can never have been requested */ 220 /* GPIO can never have been requested */
211 WARN_ON(1); 221 WARN_ON(1);
212} 222}
223static inline void gpiod_set_array(unsigned int array_size,
224 struct gpio_desc **desc_array,
225 int *value_array)
226{
227 /* GPIO can never have been requested */
228 WARN_ON(1);
229}
213static inline int gpiod_get_raw_value(const struct gpio_desc *desc) 230static inline int gpiod_get_raw_value(const struct gpio_desc *desc)
214{ 231{
215 /* GPIO can never have been requested */ 232 /* GPIO can never have been requested */
@@ -221,6 +238,13 @@ static inline void gpiod_set_raw_value(struct gpio_desc *desc, int value)
221 /* GPIO can never have been requested */ 238 /* GPIO can never have been requested */
222 WARN_ON(1); 239 WARN_ON(1);
223} 240}
241static inline void gpiod_set_raw_array(unsigned int array_size,
242 struct gpio_desc **desc_array,
243 int *value_array)
244{
245 /* GPIO can never have been requested */
246 WARN_ON(1);
247}
224 248
225static inline int gpiod_get_value_cansleep(const struct gpio_desc *desc) 249static inline int gpiod_get_value_cansleep(const struct gpio_desc *desc)
226{ 250{
@@ -233,6 +257,13 @@ static inline void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
233 /* GPIO can never have been requested */ 257 /* GPIO can never have been requested */
234 WARN_ON(1); 258 WARN_ON(1);
235} 259}
260static inline void gpiod_set_array_cansleep(unsigned int array_size,
261 struct gpio_desc **desc_array,
262 int *value_array)
263{
264 /* GPIO can never have been requested */
265 WARN_ON(1);
266}
236static inline int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc) 267static inline int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
237{ 268{
238 /* GPIO can never have been requested */ 269 /* GPIO can never have been requested */
@@ -245,6 +276,13 @@ static inline void gpiod_set_raw_value_cansleep(struct gpio_desc *desc,
245 /* GPIO can never have been requested */ 276 /* GPIO can never have been requested */
246 WARN_ON(1); 277 WARN_ON(1);
247} 278}
279static inline void gpiod_set_raw_array_cansleep(unsigned int array_size,
280 struct gpio_desc **desc_array,
281 int *value_array)
282{
283 /* GPIO can never have been requested */
284 WARN_ON(1);
285}
248 286
249static inline int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) 287static inline int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
250{ 288{
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h
index ff200a75501e..c497c62889d1 100644
--- a/include/linux/gpio/driver.h
+++ b/include/linux/gpio/driver.h
@@ -32,6 +32,7 @@ struct seq_file;
32 * @get: returns value for signal "offset"; for output signals this 32 * @get: returns value for signal "offset"; for output signals this
33 * returns either the value actually sensed, or zero 33 * returns either the value actually sensed, or zero
34 * @set: assigns output value for signal "offset" 34 * @set: assigns output value for signal "offset"
35 * @set_multiple: assigns output values for multiple signals defined by "mask"
35 * @set_debounce: optional hook for setting debounce time for specified gpio in 36 * @set_debounce: optional hook for setting debounce time for specified gpio in
36 * interrupt triggered gpio chips 37 * interrupt triggered gpio chips
37 * @to_irq: optional hook supporting non-static gpio_to_irq() mappings; 38 * @to_irq: optional hook supporting non-static gpio_to_irq() mappings;
@@ -89,6 +90,9 @@ struct gpio_chip {
89 unsigned offset); 90 unsigned offset);
90 void (*set)(struct gpio_chip *chip, 91 void (*set)(struct gpio_chip *chip,
91 unsigned offset, int value); 92 unsigned offset, int value);
93 void (*set_multiple)(struct gpio_chip *chip,
94 unsigned long *mask,
95 unsigned long *bits);
92 int (*set_debounce)(struct gpio_chip *chip, 96 int (*set_debounce)(struct gpio_chip *chip,
93 unsigned offset, 97 unsigned offset,
94 unsigned debounce); 98 unsigned debounce);