aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/core.c112
1 files changed, 35 insertions, 77 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index e225711bb8bc..0e0d8297dc8e 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -658,23 +658,32 @@ static struct class regulator_class = {
658 658
659/* Calculate the new optimum regulator operating mode based on the new total 659/* Calculate the new optimum regulator operating mode based on the new total
660 * consumer load. All locks held by caller */ 660 * consumer load. All locks held by caller */
661static void drms_uA_update(struct regulator_dev *rdev) 661static int drms_uA_update(struct regulator_dev *rdev)
662{ 662{
663 struct regulator *sibling; 663 struct regulator *sibling;
664 int current_uA = 0, output_uV, input_uV, err; 664 int current_uA = 0, output_uV, input_uV, err;
665 unsigned int mode; 665 unsigned int mode;
666 666
667 /*
668 * first check to see if we can set modes at all, otherwise just
669 * tell the consumer everything is OK.
670 */
667 err = regulator_check_drms(rdev); 671 err = regulator_check_drms(rdev);
668 if (err < 0 || !rdev->desc->ops->get_optimum_mode || 672 if (err < 0)
669 (!rdev->desc->ops->get_voltage && 673 return 0;
670 !rdev->desc->ops->get_voltage_sel) || 674
671 !rdev->desc->ops->set_mode) 675 if (!rdev->desc->ops->get_optimum_mode)
672 return; 676 return 0;
677
678 if (!rdev->desc->ops->set_mode)
679 return -EINVAL;
673 680
674 /* get output voltage */ 681 /* get output voltage */
675 output_uV = _regulator_get_voltage(rdev); 682 output_uV = _regulator_get_voltage(rdev);
676 if (output_uV <= 0) 683 if (output_uV <= 0) {
677 return; 684 rdev_err(rdev, "invalid output voltage found\n");
685 return -EINVAL;
686 }
678 687
679 /* get input voltage */ 688 /* get input voltage */
680 input_uV = 0; 689 input_uV = 0;
@@ -682,8 +691,10 @@ static void drms_uA_update(struct regulator_dev *rdev)
682 input_uV = regulator_get_voltage(rdev->supply); 691 input_uV = regulator_get_voltage(rdev->supply);
683 if (input_uV <= 0) 692 if (input_uV <= 0)
684 input_uV = rdev->constraints->input_uV; 693 input_uV = rdev->constraints->input_uV;
685 if (input_uV <= 0) 694 if (input_uV <= 0) {
686 return; 695 rdev_err(rdev, "invalid input voltage found\n");
696 return -EINVAL;
697 }
687 698
688 /* calc total requested load */ 699 /* calc total requested load */
689 list_for_each_entry(sibling, &rdev->consumer_list, list) 700 list_for_each_entry(sibling, &rdev->consumer_list, list)
@@ -695,8 +706,17 @@ static void drms_uA_update(struct regulator_dev *rdev)
695 706
696 /* check the new mode is allowed */ 707 /* check the new mode is allowed */
697 err = regulator_mode_constrain(rdev, &mode); 708 err = regulator_mode_constrain(rdev, &mode);
698 if (err == 0) 709 if (err < 0) {
699 rdev->desc->ops->set_mode(rdev, mode); 710 rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
711 current_uA, input_uV, output_uV);
712 return err;
713 }
714
715 err = rdev->desc->ops->set_mode(rdev, mode);
716 if (err < 0)
717 rdev_err(rdev, "failed to set optimum mode %x\n", mode);
718
719 return err;
700} 720}
701 721
702static int suspend_set_state(struct regulator_dev *rdev, 722static int suspend_set_state(struct regulator_dev *rdev,
@@ -3024,75 +3044,13 @@ EXPORT_SYMBOL_GPL(regulator_get_mode);
3024int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) 3044int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
3025{ 3045{
3026 struct regulator_dev *rdev = regulator->rdev; 3046 struct regulator_dev *rdev = regulator->rdev;
3027 struct regulator *consumer; 3047 int ret;
3028 int ret, output_uV, input_uV = 0, total_uA_load = 0;
3029 unsigned int mode;
3030
3031 if (rdev->supply)
3032 input_uV = regulator_get_voltage(rdev->supply);
3033 3048
3034 mutex_lock(&rdev->mutex); 3049 mutex_lock(&rdev->mutex);
3035
3036 /*
3037 * first check to see if we can set modes at all, otherwise just
3038 * tell the consumer everything is OK.
3039 */
3040 regulator->uA_load = uA_load; 3050 regulator->uA_load = uA_load;
3041 ret = regulator_check_drms(rdev); 3051 ret = drms_uA_update(rdev);
3042 if (ret < 0) {
3043 ret = 0;
3044 goto out;
3045 }
3046
3047 if (!rdev->desc->ops->get_optimum_mode)
3048 goto out;
3049
3050 /*
3051 * we can actually do this so any errors are indicators of
3052 * potential real failure.
3053 */
3054 ret = -EINVAL;
3055
3056 if (!rdev->desc->ops->set_mode)
3057 goto out;
3058
3059 /* get output voltage */
3060 output_uV = _regulator_get_voltage(rdev);
3061 if (output_uV <= 0) {
3062 rdev_err(rdev, "invalid output voltage found\n");
3063 goto out;
3064 }
3065
3066 /* No supply? Use constraint voltage */
3067 if (input_uV <= 0)
3068 input_uV = rdev->constraints->input_uV;
3069 if (input_uV <= 0) {
3070 rdev_err(rdev, "invalid input voltage found\n");
3071 goto out;
3072 }
3073
3074 /* calc total requested load for this regulator */
3075 list_for_each_entry(consumer, &rdev->consumer_list, list)
3076 total_uA_load += consumer->uA_load;
3077
3078 mode = rdev->desc->ops->get_optimum_mode(rdev,
3079 input_uV, output_uV,
3080 total_uA_load);
3081 ret = regulator_mode_constrain(rdev, &mode);
3082 if (ret < 0) {
3083 rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
3084 total_uA_load, input_uV, output_uV);
3085 goto out;
3086 }
3087
3088 ret = rdev->desc->ops->set_mode(rdev, mode);
3089 if (ret < 0) {
3090 rdev_err(rdev, "failed to set optimum mode %x\n", mode);
3091 goto out;
3092 }
3093 ret = mode;
3094out:
3095 mutex_unlock(&rdev->mutex); 3052 mutex_unlock(&rdev->mutex);
3053
3096 return ret; 3054 return ret;
3097} 3055}
3098EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); 3056EXPORT_SYMBOL_GPL(regulator_set_optimum_mode);