aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpiolib.c
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 /drivers/gpio/gpiolib.c
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>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c168
1 files changed, 168 insertions, 0 deletions
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 */