aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/core.c')
-rw-r--r--drivers/regulator/core.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 48385318175a..419805cdd9d7 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -77,6 +77,7 @@ struct regulator {
77 struct device *dev; 77 struct device *dev;
78 struct list_head list; 78 struct list_head list;
79 unsigned int always_on:1; 79 unsigned int always_on:1;
80 unsigned int bypass:1;
80 int uA_load; 81 int uA_load;
81 int min_uV; 82 int min_uV;
82 int max_uV; 83 int max_uV;
@@ -394,6 +395,9 @@ static ssize_t regulator_status_show(struct device *dev,
394 case REGULATOR_STATUS_STANDBY: 395 case REGULATOR_STATUS_STANDBY:
395 label = "standby"; 396 label = "standby";
396 break; 397 break;
398 case REGULATOR_STATUS_BYPASS:
399 label = "bypass";
400 break;
397 case REGULATOR_STATUS_UNDEFINED: 401 case REGULATOR_STATUS_UNDEFINED:
398 label = "undefined"; 402 label = "undefined";
399 break; 403 break;
@@ -585,6 +589,27 @@ static ssize_t regulator_suspend_standby_state_show(struct device *dev,
585static DEVICE_ATTR(suspend_standby_state, 0444, 589static DEVICE_ATTR(suspend_standby_state, 0444,
586 regulator_suspend_standby_state_show, NULL); 590 regulator_suspend_standby_state_show, NULL);
587 591
592static ssize_t regulator_bypass_show(struct device *dev,
593 struct device_attribute *attr, char *buf)
594{
595 struct regulator_dev *rdev = dev_get_drvdata(dev);
596 const char *report;
597 bool bypass;
598 int ret;
599
600 ret = rdev->desc->ops->get_bypass(rdev, &bypass);
601
602 if (ret != 0)
603 report = "unknown";
604 else if (bypass)
605 report = "enabled";
606 else
607 report = "disabled";
608
609 return sprintf(buf, "%s\n", report);
610}
611static DEVICE_ATTR(bypass, 0444,
612 regulator_bypass_show, NULL);
588 613
589/* 614/*
590 * These are the only attributes are present for all regulators. 615 * These are the only attributes are present for all regulators.
@@ -2674,6 +2699,100 @@ out:
2674EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); 2699EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);
2675 2700
2676/** 2701/**
2702 * regulator_set_bypass_regmap - Default set_bypass() using regmap
2703 *
2704 * @rdev: device to operate on.
2705 * @enable: state to set.
2706 */
2707int regulator_set_bypass_regmap(struct regulator_dev *rdev, bool enable)
2708{
2709 unsigned int val;
2710
2711 if (enable)
2712 val = rdev->desc->bypass_mask;
2713 else
2714 val = 0;
2715
2716 return regmap_update_bits(rdev->regmap, rdev->desc->bypass_reg,
2717 rdev->desc->bypass_mask, val);
2718}
2719EXPORT_SYMBOL_GPL(regulator_set_bypass_regmap);
2720
2721/**
2722 * regulator_get_bypass_regmap - Default get_bypass() using regmap
2723 *
2724 * @rdev: device to operate on.
2725 * @enable: current state.
2726 */
2727int regulator_get_bypass_regmap(struct regulator_dev *rdev, bool *enable)
2728{
2729 unsigned int val;
2730 int ret;
2731
2732 ret = regmap_read(rdev->regmap, rdev->desc->bypass_reg, &val);
2733 if (ret != 0)
2734 return ret;
2735
2736 *enable = val & rdev->desc->bypass_mask;
2737
2738 return 0;
2739}
2740EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
2741
2742/**
2743 * regulator_allow_bypass - allow the regulator to go into bypass mode
2744 *
2745 * @regulator: Regulator to configure
2746 * @allow: enable or disable bypass mode
2747 *
2748 * Allow the regulator to go into bypass mode if all other consumers
2749 * for the regulator also enable bypass mode and the machine
2750 * constraints allow this. Bypass mode means that the regulator is
2751 * simply passing the input directly to the output with no regulation.
2752 */
2753int regulator_allow_bypass(struct regulator *regulator, bool enable)
2754{
2755 struct regulator_dev *rdev = regulator->rdev;
2756 int ret = 0;
2757
2758 if (!rdev->desc->ops->set_bypass)
2759 return 0;
2760
2761 if (rdev->constraints &&
2762 !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS))
2763 return 0;
2764
2765 mutex_lock(&rdev->mutex);
2766
2767 if (enable && !regulator->bypass) {
2768 rdev->bypass_count++;
2769
2770 if (rdev->bypass_count == rdev->open_count) {
2771 ret = rdev->desc->ops->set_bypass(rdev, enable);
2772 if (ret != 0)
2773 rdev->bypass_count--;
2774 }
2775
2776 } else if (!enable && regulator->bypass) {
2777 rdev->bypass_count--;
2778
2779 if (rdev->bypass_count != rdev->open_count) {
2780 ret = rdev->desc->ops->set_bypass(rdev, enable);
2781 if (ret != 0)
2782 rdev->bypass_count++;
2783 }
2784 }
2785
2786 if (ret == 0)
2787 regulator->bypass = enable;
2788
2789 mutex_unlock(&rdev->mutex);
2790
2791 return ret;
2792}
2793EXPORT_SYMBOL_GPL(regulator_allow_bypass);
2794
2795/**
2677 * regulator_register_notifier - register regulator event notifier 2796 * regulator_register_notifier - register regulator event notifier
2678 * @regulator: regulator source 2797 * @regulator: regulator source
2679 * @nb: notifier block 2798 * @nb: notifier block
@@ -3036,6 +3155,11 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
3036 if (status < 0) 3155 if (status < 0)
3037 return status; 3156 return status;
3038 } 3157 }
3158 if (ops->get_bypass) {
3159 status = device_create_file(dev, &dev_attr_bypass);
3160 if (status < 0)
3161 return status;
3162 }
3039 3163
3040 /* some attributes are type-specific */ 3164 /* some attributes are type-specific */
3041 if (rdev->desc->type == REGULATOR_CURRENT) { 3165 if (rdev->desc->type == REGULATOR_CURRENT) {
@@ -3124,6 +3248,8 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
3124 &rdev->use_count); 3248 &rdev->use_count);
3125 debugfs_create_u32("open_count", 0444, rdev->debugfs, 3249 debugfs_create_u32("open_count", 0444, rdev->debugfs,
3126 &rdev->open_count); 3250 &rdev->open_count);
3251 debugfs_create_u32("bypass_count", 0444, rdev->debugfs,
3252 &rdev->bypass_count);
3127} 3253}
3128 3254
3129/** 3255/**