aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2014-03-10 08:54:50 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-03-13 05:32:18 -0400
commit77c2d7929d7d7f0e391b17f85d2d954912ed0590 (patch)
treecc6672e8cd2f087064a510941fcb2ff3fe73c1e6 /drivers/gpio
parent7b7f588b50d49717d8e635452590338e28d39197 (diff)
gpiolib: Allow GPIO chips to request their own GPIOs
Sometimes it is useful to allow GPIO chips themselves to request GPIOs they own through gpiolib API. One use case is ACPI ASL code that should be able to toggle GPIOs through GPIO operation regions. We can't use gpio_request() because it will pin the module to the kernel forever (it calls try_module_get()). To solve this we move module refcount manipulation to gpiod_request() and let __gpiod_request() handle the actual request. This changes the sequence a bit as now try_module_get() is called outside of gpio_lock (I think this is safe, try_module_get() handles serialization it needs already). Then we provide gpiolib internal functions gpiochip_request/free_own_desc() that do the same as gpio_request() but don't manipulate module refrence count. This allows the GPIO chip driver to request and free descriptors it owns without being pinned to the kernel forever. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpiolib.c100
-rw-r--r--drivers/gpio/gpiolib.h3
2 files changed, 76 insertions, 27 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index aa6a11b452e2..8fbc67a88465 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1458,26 +1458,14 @@ EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
1458 * on each other, and help provide better diagnostics in debugfs. 1458 * on each other, and help provide better diagnostics in debugfs.
1459 * They're called even less than the "set direction" calls. 1459 * They're called even less than the "set direction" calls.
1460 */ 1460 */
1461static int gpiod_request(struct gpio_desc *desc, const char *label) 1461static int __gpiod_request(struct gpio_desc *desc, const char *label)
1462{ 1462{
1463 struct gpio_chip *chip; 1463 struct gpio_chip *chip = desc->chip;
1464 int status = -EPROBE_DEFER; 1464 int status;
1465 unsigned long flags; 1465 unsigned long flags;
1466 1466
1467 if (!desc) {
1468 pr_warn("%s: invalid GPIO\n", __func__);
1469 return -EINVAL;
1470 }
1471
1472 spin_lock_irqsave(&gpio_lock, flags); 1467 spin_lock_irqsave(&gpio_lock, flags);
1473 1468
1474 chip = desc->chip;
1475 if (chip == NULL)
1476 goto done;
1477
1478 if (!try_module_get(chip->owner))
1479 goto done;
1480
1481 /* NOTE: gpio_request() can be called in early boot, 1469 /* NOTE: gpio_request() can be called in early boot,
1482 * before IRQs are enabled, for non-sleeping (SOC) GPIOs. 1470 * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
1483 */ 1471 */
@@ -1487,7 +1475,6 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
1487 status = 0; 1475 status = 0;
1488 } else { 1476 } else {
1489 status = -EBUSY; 1477 status = -EBUSY;
1490 module_put(chip->owner);
1491 goto done; 1478 goto done;
1492 } 1479 }
1493 1480
@@ -1499,7 +1486,6 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
1499 1486
1500 if (status < 0) { 1487 if (status < 0) {
1501 desc_set_label(desc, NULL); 1488 desc_set_label(desc, NULL);
1502 module_put(chip->owner);
1503 clear_bit(FLAG_REQUESTED, &desc->flags); 1489 clear_bit(FLAG_REQUESTED, &desc->flags);
1504 goto done; 1490 goto done;
1505 } 1491 }
@@ -1511,9 +1497,34 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
1511 spin_lock_irqsave(&gpio_lock, flags); 1497 spin_lock_irqsave(&gpio_lock, flags);
1512 } 1498 }
1513done: 1499done:
1500 spin_unlock_irqrestore(&gpio_lock, flags);
1501 return status;
1502}
1503
1504static int gpiod_request(struct gpio_desc *desc, const char *label)
1505{
1506 int status = -EPROBE_DEFER;
1507 struct gpio_chip *chip;
1508
1509 if (!desc) {
1510 pr_warn("%s: invalid GPIO\n", __func__);
1511 return -EINVAL;
1512 }
1513
1514 chip = desc->chip;
1515 if (!chip)
1516 goto done;
1517
1518 if (try_module_get(chip->owner)) {
1519 status = __gpiod_request(desc, label);
1520 if (status < 0)
1521 module_put(chip->owner);
1522 }
1523
1524done:
1514 if (status) 1525 if (status)
1515 gpiod_dbg(desc, "%s: status %d\n", __func__, status); 1526 gpiod_dbg(desc, "%s: status %d\n", __func__, status);
1516 spin_unlock_irqrestore(&gpio_lock, flags); 1527
1517 return status; 1528 return status;
1518} 1529}
1519 1530
@@ -1523,18 +1534,14 @@ int gpio_request(unsigned gpio, const char *label)
1523} 1534}
1524EXPORT_SYMBOL_GPL(gpio_request); 1535EXPORT_SYMBOL_GPL(gpio_request);
1525 1536
1526static void gpiod_free(struct gpio_desc *desc) 1537static bool __gpiod_free(struct gpio_desc *desc)
1527{ 1538{
1539 bool ret = false;
1528 unsigned long flags; 1540 unsigned long flags;
1529 struct gpio_chip *chip; 1541 struct gpio_chip *chip;
1530 1542
1531 might_sleep(); 1543 might_sleep();
1532 1544
1533 if (!desc) {
1534 WARN_ON(extra_checks);
1535 return;
1536 }
1537
1538 gpiod_unexport(desc); 1545 gpiod_unexport(desc);
1539 1546
1540 spin_lock_irqsave(&gpio_lock, flags); 1547 spin_lock_irqsave(&gpio_lock, flags);
@@ -1548,15 +1555,23 @@ static void gpiod_free(struct gpio_desc *desc)
1548 spin_lock_irqsave(&gpio_lock, flags); 1555 spin_lock_irqsave(&gpio_lock, flags);
1549 } 1556 }
1550 desc_set_label(desc, NULL); 1557 desc_set_label(desc, NULL);
1551 module_put(desc->chip->owner);
1552 clear_bit(FLAG_ACTIVE_LOW, &desc->flags); 1558 clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
1553 clear_bit(FLAG_REQUESTED, &desc->flags); 1559 clear_bit(FLAG_REQUESTED, &desc->flags);
1554 clear_bit(FLAG_OPEN_DRAIN, &desc->flags); 1560 clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
1555 clear_bit(FLAG_OPEN_SOURCE, &desc->flags); 1561 clear_bit(FLAG_OPEN_SOURCE, &desc->flags);
1556 } else 1562 ret = true;
1557 WARN_ON(extra_checks); 1563 }
1558 1564
1559 spin_unlock_irqrestore(&gpio_lock, flags); 1565 spin_unlock_irqrestore(&gpio_lock, flags);
1566 return ret;
1567}
1568
1569static void gpiod_free(struct gpio_desc *desc)
1570{
1571 if (desc && __gpiod_free(desc))
1572 module_put(desc->chip->owner);
1573 else
1574 WARN_ON(extra_checks);
1560} 1575}
1561 1576
1562void gpio_free(unsigned gpio) 1577void gpio_free(unsigned gpio)
@@ -1678,6 +1693,37 @@ const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset)
1678} 1693}
1679EXPORT_SYMBOL_GPL(gpiochip_is_requested); 1694EXPORT_SYMBOL_GPL(gpiochip_is_requested);
1680 1695
1696/**
1697 * gpiochip_request_own_desc - Allow GPIO chip to request its own descriptor
1698 * @desc: GPIO descriptor to request
1699 * @label: label for the GPIO
1700 *
1701 * Function allows GPIO chip drivers to request and use their own GPIO
1702 * descriptors via gpiolib API. Difference to gpiod_request() is that this
1703 * function will not increase reference count of the GPIO chip module. This
1704 * allows the GPIO chip module to be unloaded as needed (we assume that the
1705 * GPIO chip driver handles freeing the GPIOs it has requested).
1706 */
1707int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label)
1708{
1709 if (!desc || !desc->chip)
1710 return -EINVAL;
1711
1712 return __gpiod_request(desc, label);
1713}
1714
1715/**
1716 * gpiochip_free_own_desc - Free GPIO requested by the chip driver
1717 * @desc: GPIO descriptor to free
1718 *
1719 * Function frees the given GPIO requested previously with
1720 * gpiochip_request_own_desc().
1721 */
1722void gpiochip_free_own_desc(struct gpio_desc *desc)
1723{
1724 if (desc)
1725 __gpiod_free(desc);
1726}
1681 1727
1682/* Drivers MUST set GPIO direction before making get/set calls. In 1728/* Drivers MUST set GPIO direction before making get/set calls. In
1683 * some cases this is done in early boot, before IRQs are enabled. 1729 * some cases this is done in early boot, before IRQs are enabled.
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 82be586c1f90..cf092941a9fd 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -43,4 +43,7 @@ acpi_get_gpiod_by_index(struct device *dev, int index,
43} 43}
44#endif 44#endif
45 45
46int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label);
47void gpiochip_free_own_desc(struct gpio_desc *desc);
48
46#endif /* GPIOLIB_H */ 49#endif /* GPIOLIB_H */