Messages in this thread | | | From | Anand Ashok Dumbre <> | Subject | RE: [PATCH v2] iio: core: Fix IIO_VAL_FRACTIONAL calculation for negative values | Date | Mon, 31 Aug 2020 08:55:26 +0000 |
| |
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@kernel.org> > Sent: Saturday, August 29, 2020 4:19 PM > To: Anand Ashok Dumbre <ANANDASH@xilinx.com> > Cc: knaack.h@gmx.de; lars@metafoo.de; pmeerw@pmeerw.net; Michal > Simek <michals@xilinx.com>; git <git@xilinx.com>; linux- > iio@vger.kernel.org; linux-arm-kernel@lists.infradead.org; linux- > kernel@vger.kernel.org; Anand Ashok Dumbre <ANANDASH@xilinx.com> > 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@xilinx.com> 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@xilinx.com> > > 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);
| |