diff options
-rw-r--r-- | drivers/gpio/gpiolib.c | 100 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.h | 3 |
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 | */ |
1461 | static int gpiod_request(struct gpio_desc *desc, const char *label) | 1461 | static 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 | } |
1513 | done: | 1499 | done: |
1500 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
1501 | return status; | ||
1502 | } | ||
1503 | |||
1504 | static 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 | |||
1524 | done: | ||
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 | } |
1524 | EXPORT_SYMBOL_GPL(gpio_request); | 1535 | EXPORT_SYMBOL_GPL(gpio_request); |
1525 | 1536 | ||
1526 | static void gpiod_free(struct gpio_desc *desc) | 1537 | static 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 | |||
1569 | static 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 | ||
1562 | void gpio_free(unsigned gpio) | 1577 | void gpio_free(unsigned gpio) |
@@ -1678,6 +1693,37 @@ const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset) | |||
1678 | } | 1693 | } |
1679 | EXPORT_SYMBOL_GPL(gpiochip_is_requested); | 1694 | EXPORT_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 | */ | ||
1707 | int 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 | */ | ||
1722 | void 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 | ||
46 | int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label); | ||
47 | void gpiochip_free_own_desc(struct gpio_desc *desc); | ||
48 | |||
46 | #endif /* GPIOLIB_H */ | 49 | #endif /* GPIOLIB_H */ |