Hi Jonathan, I encountered this when I was developing a new driver. If you look at the function where this is used, all other IIO_VAL_MICRO and NANO have this fix added at some point. Thanks, Anand > -----Original Message----- > From: Jonathan Cameron <jic23@xxxxxxxxxx> > Sent: Saturday, August 29, 2020 4:19 PM > To: Anand Ashok Dumbre <ANANDASH@xxxxxxxxxx> > Cc: knaack.h@xxxxxx; lars@xxxxxxxxxx; pmeerw@xxxxxxxxxx; Michal > Simek <michals@xxxxxxxxxx>; git <git@xxxxxxxxxx>; linux- > iio@xxxxxxxxxxxxxxx; linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; linux- > kernel@xxxxxxxxxxxxxxx; Anand Ashok Dumbre <ANANDASH@xxxxxxxxxx> > Subject: Re: [PATCH v2] iio: core: Fix IIO_VAL_FRACTIONAL calculation for > negative values > > On Wed, 26 Aug 2020 11:14:36 -0700 > Anand Ashok Dumbre <anand.ashok.dumbre@xxxxxxxxxx> wrote: > > > Fixes IIO_VAL_FRACTIONAL for case when the result is negative and > > exponent is 0. > > > > example: if the result is -0.75, tmp0 will be 0 and tmp1 = 75 This > > causes the output to lose sign because of %d in snprintf which works > > for tmp0 <= -1. > > > > Signed-off-by: Anand Ashok Dumbre <anand.ashok.dumbre@xxxxxxxxxx> > > Looks good. Just one last thing. > > Is this actually hit in an existing driver? I'm just wondering how far back we > need to push it in stable etc. > > Thanks, > > Jonathan > > > --- > > changes since v1: > > Changed -%d to -0 to make the fix clearer. > > Removed the email footer. > > Updated the commit description with an example > > -- > > drivers/iio/industrialio-core.c | 8 ++++++-- > > 1 file changed, 6 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/iio/industrialio-core.c > > b/drivers/iio/industrialio-core.c index cdcd16f1..a239fa2 100644 > > --- a/drivers/iio/industrialio-core.c > > +++ b/drivers/iio/industrialio-core.c > > @@ -592,6 +592,7 @@ static ssize_t __iio_format_value(char *buf, > > size_t len, unsigned int type, { > > unsigned long long tmp; > > int tmp0, tmp1; > > + s64 tmp2; > > bool scale_db = false; > > > > switch (type) { > > @@ -614,10 +615,13 @@ static ssize_t __iio_format_value(char *buf, > size_t len, unsigned int type, > > else > > return scnprintf(buf, len, "%d.%09u", vals[0], vals[1]); > > case IIO_VAL_FRACTIONAL: > > - tmp = div_s64((s64)vals[0] * 1000000000LL, vals[1]); > > + tmp2 = div_s64((s64)vals[0] * 1000000000LL, vals[1]); > > tmp1 = vals[1]; > > tmp0 = (int)div_s64_rem(tmp, 1000000000, &tmp1); > > - return scnprintf(buf, len, "%d.%09u", tmp0, abs(tmp1)); > > + if ((tmp2 < 0) && (tmp0 == 0)) > > + return snprintf(buf, len, "-0.%09u", abs(tmp1)); > > + else > > + return snprintf(buf, len, "%d.%09u", tmp0, > abs(tmp1)); > > case IIO_VAL_FRACTIONAL_LOG2: > > tmp = shift_right((s64)vals[0] * 1000000000LL, vals[1]); > > tmp0 = (int)div_s64_rem(tmp, 1000000000LL, &tmp1);