diff options
| -rw-r--r-- | drivers/regulator/core.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 71d6adc4eeab..57d434d3145a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -1529,6 +1529,42 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev) | |||
| 1529 | } | 1529 | } |
| 1530 | } | 1530 | } |
| 1531 | 1531 | ||
| 1532 | /** | ||
| 1533 | * Balance enable_count of each GPIO and actual GPIO pin control. | ||
| 1534 | * GPIO is enabled in case of initial use. (enable_count is 0) | ||
| 1535 | * GPIO is disabled when it is not shared any more. (enable_count <= 1) | ||
| 1536 | */ | ||
| 1537 | static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) | ||
| 1538 | { | ||
| 1539 | struct regulator_enable_gpio *pin = rdev->ena_pin; | ||
| 1540 | |||
| 1541 | if (!pin) | ||
| 1542 | return -EINVAL; | ||
| 1543 | |||
| 1544 | if (enable) { | ||
| 1545 | /* Enable GPIO at initial use */ | ||
| 1546 | if (pin->enable_count == 0) | ||
| 1547 | gpio_set_value_cansleep(pin->gpio, | ||
| 1548 | !pin->ena_gpio_invert); | ||
| 1549 | |||
| 1550 | pin->enable_count++; | ||
| 1551 | } else { | ||
| 1552 | if (pin->enable_count > 1) { | ||
| 1553 | pin->enable_count--; | ||
| 1554 | return 0; | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | /* Disable GPIO if not used */ | ||
| 1558 | if (pin->enable_count <= 1) { | ||
| 1559 | gpio_set_value_cansleep(pin->gpio, | ||
| 1560 | pin->ena_gpio_invert); | ||
| 1561 | pin->enable_count = 0; | ||
| 1562 | } | ||
| 1563 | } | ||
| 1564 | |||
| 1565 | return 0; | ||
| 1566 | } | ||
| 1567 | |||
| 1532 | static int _regulator_do_enable(struct regulator_dev *rdev) | 1568 | static int _regulator_do_enable(struct regulator_dev *rdev) |
| 1533 | { | 1569 | { |
| 1534 | int ret, delay; | 1570 | int ret, delay; |
| @@ -1544,9 +1580,10 @@ static int _regulator_do_enable(struct regulator_dev *rdev) | |||
| 1544 | 1580 | ||
| 1545 | trace_regulator_enable(rdev_get_name(rdev)); | 1581 | trace_regulator_enable(rdev_get_name(rdev)); |
| 1546 | 1582 | ||
| 1547 | if (rdev->ena_gpio) { | 1583 | if (rdev->ena_pin) { |
| 1548 | gpio_set_value_cansleep(rdev->ena_gpio, | 1584 | ret = regulator_ena_gpio_ctrl(rdev, true); |
| 1549 | !rdev->ena_gpio_invert); | 1585 | if (ret < 0) |
| 1586 | return ret; | ||
| 1550 | rdev->ena_gpio_state = 1; | 1587 | rdev->ena_gpio_state = 1; |
| 1551 | } else if (rdev->desc->ops->enable) { | 1588 | } else if (rdev->desc->ops->enable) { |
| 1552 | ret = rdev->desc->ops->enable(rdev); | 1589 | ret = rdev->desc->ops->enable(rdev); |
| @@ -1648,9 +1685,10 @@ static int _regulator_do_disable(struct regulator_dev *rdev) | |||
| 1648 | 1685 | ||
| 1649 | trace_regulator_disable(rdev_get_name(rdev)); | 1686 | trace_regulator_disable(rdev_get_name(rdev)); |
| 1650 | 1687 | ||
| 1651 | if (rdev->ena_gpio) { | 1688 | if (rdev->ena_pin) { |
| 1652 | gpio_set_value_cansleep(rdev->ena_gpio, | 1689 | ret = regulator_ena_gpio_ctrl(rdev, false); |
| 1653 | rdev->ena_gpio_invert); | 1690 | if (ret < 0) |
| 1691 | return ret; | ||
| 1654 | rdev->ena_gpio_state = 0; | 1692 | rdev->ena_gpio_state = 0; |
| 1655 | 1693 | ||
| 1656 | } else if (rdev->desc->ops->disable) { | 1694 | } else if (rdev->desc->ops->disable) { |
