2020-07-24 12:22:44

by Chunyan Zhang

[permalink] [raw]
Subject: [PATCH v2 0/2] fix an overflow error on sc27xx power supply

From: Chunyan Zhang <[email protected]>

The patch 2/2 fixes an overflow error by changing to 64-bit divide operations.
In order to avoid compile error on 32-bit architectures, this patchset
also introduced a new 64-bit helper in patch 1/2.

Changes since v1: (https://lkml.org/lkml/2020/7/17/63)
- Added new help macro DIV_S64_ROUND_CLOSEST;
- Fixed an error reported by kernel test robot <[email protected]>.

Chunyan Zhang (2):
math64: New DIV_S64_ROUND_CLOSEST helper
power: supply: sc27xx: prevent adc * 1000 from overflow

drivers/power/supply/sc27xx_fuel_gauge.c | 9 +++++----
include/linux/math64.h | 19 +++++++++++++++++++
2 files changed, 24 insertions(+), 4 deletions(-)

--
2.20.1


2020-07-24 12:23:44

by Chunyan Zhang

[permalink] [raw]
Subject: [PATCH v2 2/2] power: supply: sc27xx: prevent adc * 1000 from overflow

From: Chunyan Zhang <[email protected]>

The input parameter is int type, cause adc * 1000 could overflow.
Change to use s64 to avoid this issue.

Signed-off-by: Chen Yongzhi <[email protected]>
Signed-off-by: Chunyan Zhang <[email protected]>
---
drivers/power/supply/sc27xx_fuel_gauge.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c
index be42e814ea34..9c627618c224 100644
--- a/drivers/power/supply/sc27xx_fuel_gauge.c
+++ b/drivers/power/supply/sc27xx_fuel_gauge.c
@@ -5,6 +5,7 @@
#include <linux/iio/consumer.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
+#include <linux/math64.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of.h>
@@ -133,14 +134,14 @@ static const char * const sc27xx_charger_supply_name[] = {
"sc2723_charger",
};

-static int sc27xx_fgu_adc_to_current(struct sc27xx_fgu_data *data, int adc)
+static int sc27xx_fgu_adc_to_current(struct sc27xx_fgu_data *data, s64 adc)
{
- return DIV_ROUND_CLOSEST(adc * 1000, data->cur_1000ma_adc);
+ return DIV_S64_ROUND_CLOSEST(adc * 1000, data->cur_1000ma_adc);
}

-static int sc27xx_fgu_adc_to_voltage(struct sc27xx_fgu_data *data, int adc)
+static int sc27xx_fgu_adc_to_voltage(struct sc27xx_fgu_data *data, s64 adc)
{
- return DIV_ROUND_CLOSEST(adc * 1000, data->vol_1000mv_adc);
+ return DIV_S64_ROUND_CLOSEST(adc * 1000, data->vol_1000mv_adc);
}

static int sc27xx_fgu_voltage_to_adc(struct sc27xx_fgu_data *data, int vol)
--
2.20.1

2020-07-24 12:25:06

by Chunyan Zhang

[permalink] [raw]
Subject: [PATCH v2 1/2] math64: New DIV_S64_ROUND_CLOSEST helper

From: Chunyan Zhang <[email protected]>

Provide DIV_S64_ROUND_CLOSEST helper which uses div_s64 to perform
division rounded to the closest integer using signed 64bit
dividend and signed 32bit divisor.

Signed-off-by: Chunyan Zhang <[email protected]>
---
include/linux/math64.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/include/linux/math64.h b/include/linux/math64.h
index 11a267413e8e..cd0693989436 100644
--- a/include/linux/math64.h
+++ b/include/linux/math64.h
@@ -279,4 +279,23 @@ static inline u64 mul_u64_u32_div(u64 a, u32 mul, u32 divisor)
#define DIV64_U64_ROUND_CLOSEST(dividend, divisor) \
({ u64 _tmp = (divisor); div64_u64((dividend) + _tmp / 2, _tmp); })

+/*
+ * DIV_S64_ROUND_CLOSEST - signed 64bit divide with 32bit divisor rounded to nearest integer
+ * @dividend: signed 64bit dividend
+ * @divisor: signed 32bit divisor
+ *
+ * Divide signed 64bit dividend by signed 32bit divisor
+ * and round to closest integer.
+ *
+ * Return: dividend / divisor rounded to nearest integer
+ */
+#define DIV_S64_ROUND_CLOSEST(dividend, divisor)( \
+{ \
+ s64 __x = (dividend); \
+ s32 __d = (divisor); \
+ ((__x > 0) == (__d > 0)) ? \
+ div_s64((__x + (__d / 2)), __d) : \
+ div_s64((__x - (__d / 2)), __d); \
+} \
+)
#endif /* _LINUX_MATH64_H */
--
2.20.1

2020-07-27 23:17:48

by Sebastian Reichel

[permalink] [raw]
Subject: Re: [PATCH v2 0/2] fix an overflow error on sc27xx power supply

Hi,

On Fri, Jul 24, 2020 at 08:21:46PM +0800, Chunyan Zhang wrote:
> From: Chunyan Zhang <[email protected]>
>
> The patch 2/2 fixes an overflow error by changing to 64-bit divide operations.
> In order to avoid compile error on 32-bit architectures, this patchset
> also introduced a new 64-bit helper in patch 1/2.
>
> Changes since v1: (https://lkml.org/lkml/2020/7/17/63)
> - Added new help macro DIV_S64_ROUND_CLOSEST;
> - Fixed an error reported by kernel test robot <[email protected]>.
>
> Chunyan Zhang (2):
> math64: New DIV_S64_ROUND_CLOSEST helper
> power: supply: sc27xx: prevent adc * 1000 from overflow
>
> drivers/power/supply/sc27xx_fuel_gauge.c | 9 +++++----
> include/linux/math64.h | 19 +++++++++++++++++++
> 2 files changed, 24 insertions(+), 4 deletions(-)

Thanks, queued.

-- Sebastian


Attachments:
(No filename) (868.00 B)
signature.asc (849.00 B)
Download all attachments