Re: [PATCH v3 03/10] iio: inkern: make a best effort on offset calculation

From: Liam Beguin
Date: Sun Jul 04 2021 - 14:03:59 EST


On Sun Jul 4, 2021 at 12:26 PM EDT, Jonathan Cameron wrote:
> On Wed, 30 Jun 2021 21:00:27 -0400
> Liam Beguin <liambeguin@xxxxxxxxx> wrote:
>
> > From: Liam Beguin <lvb@xxxxxxxxxx>
> >
> > iio_convert_raw_to_processed_unlocked() assumes the offset is an
> > integer. Make a best effort to get a valid offset value for fractional
> > cases without breaking implicit truncations.
> >
> > Fixes: 48e44ce0f881 ("iio:inkern: Add function to read the processed value")
> > Signed-off-by: Liam Beguin <lvb@xxxxxxxxxx>

Hi Jonathan,

Thanks for taking the time to review this again.

> Looks good, but a few really minor comments / questions inline.
>
> Thanks,
>
> Jonathan
>
> > ---
> > drivers/iio/inkern.c | 36 +++++++++++++++++++++++++++++++-----
> > 1 file changed, 31 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
> > index b69027690ed5..e1712c1099c5 100644
> > --- a/drivers/iio/inkern.c
> > +++ b/drivers/iio/inkern.c
> > @@ -578,13 +578,39 @@ EXPORT_SYMBOL_GPL(iio_read_channel_average_raw);
> > static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
> > int raw, int *processed, unsigned int scale)
> > {
> > - int scale_type, scale_val, scale_val2, offset;
> > + int scale_type, scale_val, scale_val2;
> > + int offset_type, offset_val, offset_val2;
> > s64 raw64 = raw;
> > - int ret;
> > + int tmp;
> >
> > - ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_OFFSET);
> > - if (ret >= 0)
> > - raw64 += offset;
> > + offset_type = iio_channel_read(chan, &offset_val, &offset_val2,
> > + IIO_CHAN_INFO_OFFSET);
> > + if (offset_type >= 0) {
> > + switch (offset_type) {
> > + case IIO_VAL_INT:
> > + break;
> > + case IIO_VAL_INT_PLUS_MICRO:
> > + fallthrough;
>
> I'm fairly sure you don't need to mark fallthroughs in the case where
> there is nothing in the case statement at all. That case is assumed
> to be deliberate by the various static checkers. I am seeing a few
> examples as you have it here in kernel, but it certainly isn't
> particularly common
> so I'm assuming those where the result of people falsely thinking it was
> necessary
> or the outcomes of code changes in the surrounding code.
>

I thought it was always required with `-Wimplicit-fallthrough`.
Building without it gives no warnings, and after looking into it a
little, I found a bugzilla thread[1] that confirms what you're saying.
Thanks for pointing that out.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=7652

> > + case IIO_VAL_INT_PLUS_NANO:
> > + /*
> > + * Both IIO_VAL_INT_PLUS_MICRO and IIO_VAL_INT_PLUS_NANO
> > + * implicitely truncate the offset to it's integer form.
> > + */
> > + break;
> > + case IIO_VAL_FRACTIONAL:
> > + tmp = offset_val / offset_val2;
> > + offset_val = tmp;
>
> What benefit do we get from the local variable?
> offset_val /= offset_val2; would be alternative.
>

Apologies for that, will fix!

Thanks,
Liam

> > + break;
> > + case IIO_VAL_FRACTIONAL_LOG2:
> > + tmp = offset_val / (1 << offset_val2);
> > + offset_val = tmp;
> > + break;
> > + default:
> > + return -EINVAL;
> > + }
> > +
> > + raw64 += offset_val;
> > + }
> >
> > scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
> > IIO_CHAN_INFO_SCALE);