regulator: twl: Fix checking voltage range in twl6030smps_set_voltage()
Subsystems (2)
PATCH 1/2 regulator: twl: Fix checking voltage range in twl6030smps_set_voltage()
The voltage selection logic is supposed to find the samllest voltage falls within specified range. When using equation to calculate vsel, we need to ensure the requested min_uV meet the range of using the equation. Otherwise we may select a voltage that is out of specified range.
For example, in the case vsel = 62 means select voltage of 2100000uV. What we want is to ensure the requested min_uV <= 2100000 rather than checking max_uV >= 2100000. And this also means in the case min_uV > 2100000, vsel = 62 does not meet the request.
Also calling twl6030smps_list_voltage() for all cases to ensure the selected voltage still in bounds.
--- drivers/regulator/twl-regulator.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-)
drivers/regulator/twl-regulator.c +16 -20
@@ -760,32 +760,28 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned int *selector) {struct twlreg_info *info =rdev_get_drvdata (rdev); -int vsel =0 ; +int vsel =0 , calc_uV;switch (info->flags) {case 0 :if (min_uV ==0 ) vsel =0 ;else if ((min_uV >=600000 ) && (min_uV <=1300000 )) { -int calc_uV; vsel =DIV_ROUND_UP (min_uV -600000 ,12500 ); vsel++; - calc_uV =twl6030smps_list_voltage (rdev, vsel); -if (calc_uV > max_uV) -return -EINVAL ; }/* Values 1..57 for vsel are linear and can be calculated * values 58..62 are non linear. */ -else if ((min_uV >1900000 ) && (max_uV >=2100000 )) +else if ((min_uV >1900000 ) && (min_uV <=2100000 )) vsel =62 ; -else if ((min_uV >1800000 ) && (max_uV >=1900000 )) +else if ((min_uV >1800000 ) && (min_uV <=1900000 )) vsel =61 ; -else if ((min_uV >1500000 ) && (max_uV >=1800000 )) +else if ((min_uV >1500000 ) && (min_uV <=1800000 )) vsel =60 ; -else if ((min_uV >1350000 ) && (max_uV >=1500000 )) +else if ((min_uV >1350000 ) && (min_uV <=1500000 )) vsel =59 ; -else if ((min_uV >1300000 ) && (max_uV >=1350000 )) +else if ((min_uV >1300000 ) && (min_uV <=1350000 )) vsel =58 ;else return -EINVAL ;
@@ -794,25 +790,21 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,if (min_uV ==0 ) vsel =0 ;else if ((min_uV >=700000 ) && (min_uV <=1420000 )) { -int calc_uV; vsel =DIV_ROUND_UP (min_uV -700000 ,12500 ); vsel++; - calc_uV =twl6030smps_list_voltage (rdev, vsel); -if (calc_uV > max_uV) -return -EINVAL ; }/* Values 1..57 for vsel are linear and can be calculated * values 58..62 are non linear. */ -else if ((min_uV >1900000 ) && (max_uV >=2100000 )) +else if ((min_uV >1900000 ) && (min_uV <=2100000 )) vsel =62 ; -else if ((min_uV >1800000 ) && (max_uV >=1900000 )) +else if ((min_uV >1800000 ) && (min_uV <=1900000 )) vsel =61 ; -else if ((min_uV >1350000 ) && (max_uV >=1800000 )) +else if ((min_uV >1350000 ) && (min_uV <=1800000 )) vsel =60 ; -else if ((min_uV >1350000 ) && (max_uV >=1500000 )) +else if ((min_uV >1350000 ) && (min_uV <=1500000 )) vsel =59 ; -else if ((min_uV >1300000 ) && (max_uV >=1350000 )) +else if ((min_uV >1300000 ) && (min_uV <=1350000 )) vsel =58 ;else return -EINVAL ;
@@ -828,13 +820,17 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,case SMPS_OFFSET_EN |SMPS_EXTENDED_EN :if (min_uV ==0 ) { vsel =0 ; - }else if ((min_uV >=2161000 ) && (max_uV <=4321000 )) { + }else if ((min_uV >=2161000 ) && (min_uV <=4321000 )) { vsel =DIV_ROUND_UP (min_uV -2161000 ,38600 ); vsel++; }break ; } + calc_uV =twl6030smps_list_voltage (rdev, vsel); +if (calc_uV > max_uV) +return -EINVAL ; + *selector = vsel; return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS,
Signature · 1 line
1.7.9.5
PATCH 2/2 regulator: twl: Convert twlsmps_ops to get_voltage_sel and map_voltage
--- drivers/regulator/twl-regulator.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
drivers/regulator/twl-regulator.c +13 -11
@@ -755,12 +755,11 @@ static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index)return voltage; } -static int -twl6030smps_set_voltage (struct regulator_dev *rdev,int min_uV,int max_uV, -unsigned int *selector) +static int twl6030smps_map_voltage (struct regulator_dev *rdev,int min_uV, +int max_uV) { -struct twlreg_info *info =rdev_get_drvdata (rdev); -int vsel =0 , calc_uV; +struct twlreg_info *info =rdev_get_drvdata (rdev); +int vsel =0 ;switch (info->flags) {case 0 :
@@ -827,14 +826,16 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,break ; } - calc_uV =twl6030smps_list_voltage (rdev, vsel); -if (calc_uV > max_uV) -return -EINVAL ; +return vsel; +} - *selector = vsel; +static int twl6030smps_set_voltage_sel (struct regulator_dev *rdev, +unsigned int selector) +{ +struct twlreg_info *info =rdev_get_drvdata (rdev);return twlreg_write (info,TWL_MODULE_PM_RECEIVER ,VREG_VOLTAGE_SMPS , - vsel); + selector); }static int twl6030smps_get_voltage_sel (struct regulator_dev *rdev)
@@ -846,8 +847,9 @@ static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)static struct regulator_ops twlsmps_ops = { .list_voltage = twl6030smps_list_voltage, + .map_voltage = twl6030smps_map_voltage, - .set_voltage = twl6030smps_set_voltage, + .set_voltage_sel = twl6030smps_set_voltage_sel, .get_voltage_sel = twl6030smps_get_voltage_sel, .enable = twl6030reg_enable,
Signature · 1 line
1.7.9.5
Re: [PATCH RFT 2/2] regulator: twl: Convert twlsmps_ops to get_voltage_sel and map_voltage
Copying Graeme and linux-omap list.
Quoted 59 lines · Axel Lin
Signed-off-by Axel Lin<[email protected]>--- drivers/regulator/twl-regulator.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)drivers/regulator/twl-regulator.c +13
-11@@ -755,12 +755,11 @@ static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index)return voltage; } -static int -twl6030smps_set_voltage (struct regulator_dev *rdev,int min_uV,int max_uV, -unsigned int *selector) +static int twl6030smps_map_voltage (struct regulator_dev *rdev,int min_uV, +int max_uV) { -struct twlreg_info *info =rdev_get_drvdata (rdev); -int vsel =0 , calc_uV; +struct twlreg_info *info =rdev_get_drvdata (rdev); +int vsel =0 ;switch (info->flags) {case 0 :@@ -827,14 +826,16 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,break ; } - calc_uV =twl6030smps_list_voltage (rdev, vsel); -if (calc_uV> max_uV) -return -EINVAL ; +return vsel; +} - *selector = vsel; +static int twl6030smps_set_voltage_sel (struct regulator_dev *rdev, +unsigned int selector) +{ +struct twlreg_info *info =rdev_get_drvdata (rdev);return twlreg_write (info,TWL_MODULE_PM_RECEIVER ,VREG_VOLTAGE_SMPS , - vsel); + selector); }static int twl6030smps_get_voltage_sel (struct regulator_dev *rdev)@@ -846,8 +847,9 @@ static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)static struct regulator_ops twlsmps_ops = { .list_voltage = twl6030smps_list_voltage, + .map_voltage = twl6030smps_map_voltage, - .set_voltage = twl6030smps_set_voltage, + .set_voltage_sel = twl6030smps_set_voltage_sel, .get_voltage_sel = twl6030smps_get_voltage_sel, .enable = twl6030reg_enable,
Copying Graeme and linux-omap list.
Quoted 111 lines · Axel Lin
The voltage selection logic is supposed to find the samllest voltage falls within specified range. When using equation to calculate vsel, we need to ensure the requested
min_uVmeet the range of using the equation. Otherwise we may select a voltage that is out of specified range.For example, in the case vsel = 62 means select voltage of 2100000uV. What we want is to ensure the requested min_uV<= 2100000 rather than checking max_uV>= 2100000. And this also means in the case
min_uV> 2100000, vsel = 62 does not meet the request.Also calling
twl6030smps_list_voltage()for all cases to ensure the selected voltage still in bounds.Signed-off-by Axel Lin<[email protected]>--- drivers/regulator/twl-regulator.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-)drivers/regulator/twl-regulator.c +16
-20@@ -760,32 +760,28 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned int *selector) {struct twlreg_info *info =rdev_get_drvdata (rdev); -int vsel =0 ; +int vsel =0 , calc_uV;switch (info->flags) {case 0 :if (min_uV ==0 ) vsel =0 ;else if ((min_uV>=600000 )&& (min_uV<=1300000 )) { -int calc_uV; vsel =DIV_ROUND_UP (min_uV -600000 ,12500 ); vsel++; - calc_uV =twl6030smps_list_voltage (rdev, vsel); -if (calc_uV> max_uV) -return -EINVAL ; }/* Values 1..57 for vsel are linear and can be calculated * values 58..62 are non linear. */ -else if ((min_uV>1900000 )&& (max_uV>=2100000 )) +else if ((min_uV>1900000 )&& (min_uV<=2100000 )) vsel =62 ; -else if ((min_uV>1800000 )&& (max_uV>=1900000 )) +else if ((min_uV>1800000 )&& (min_uV<=1900000 )) vsel =61 ; -else if ((min_uV>1500000 )&& (max_uV>=1800000 )) +else if ((min_uV>1500000 )&& (min_uV<=1800000 )) vsel =60 ; -else if ((min_uV>1350000 )&& (max_uV>=1500000 )) +else if ((min_uV>1350000 )&& (min_uV<=1500000 )) vsel =59 ; -else if ((min_uV>1300000 )&& (max_uV>=1350000 )) +else if ((min_uV>1300000 )&& (min_uV<=1350000 )) vsel =58 ;else return -EINVAL ;@@ -794,25 +790,21 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,if (min_uV ==0 ) vsel =0 ;else if ((min_uV>=700000 )&& (min_uV<=1420000 )) { -int calc_uV; vsel =DIV_ROUND_UP (min_uV -700000 ,12500 ); vsel++; - calc_uV =twl6030smps_list_voltage (rdev, vsel); -if (calc_uV> max_uV) -return -EINVAL ; }/* Values 1..57 for vsel are linear and can be calculated * values 58..62 are non linear. */ -else if ((min_uV>1900000 )&& (max_uV>=2100000 )) +else if ((min_uV>1900000 )&& (min_uV<=2100000 )) vsel =62 ; -else if ((min_uV>1800000 )&& (max_uV>=1900000 )) +else if ((min_uV>1800000 )&& (min_uV<=1900000 )) vsel =61 ; -else if ((min_uV>1350000 )&& (max_uV>=1800000 )) +else if ((min_uV>1350000 )&& (min_uV<=1800000 )) vsel =60 ; -else if ((min_uV>1350000 )&& (max_uV>=1500000 )) +else if ((min_uV>1350000 )&& (min_uV<=1500000 )) vsel =59 ; -else if ((min_uV>1300000 )&& (max_uV>=1350000 )) +else if ((min_uV>1300000 )&& (min_uV<=1350000 )) vsel =58 ;else return -EINVAL ;@@ -828,13 +820,17 @@ twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,case SMPS_OFFSET_EN |SMPS_EXTENDED_EN :if (min_uV ==0 ) { vsel =0 ; - }else if ((min_uV>=2161000 )&& (max_uV<=4321000 )) { + }else if ((min_uV>=2161000 )&& (min_uV<=4321000 )) { vsel =DIV_ROUND_UP (min_uV -2161000 ,38600 ); vsel++; }break ; } + calc_uV =twl6030smps_list_voltage (rdev, vsel); +if (calc_uV> max_uV) +return -EINVAL ; + *selector = vsel; return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS,
Mark Brown
AppliedQuoted 4 lines · Axel Lin
The voltage selection logic is supposed to find the samllest voltage falls within specified range. When using equation to calculate vsel, we need to ensure the requested
min_uVmeet the range of using the equation. Otherwise we may select a voltage that is out of specified range.
Applied both, thanks.