Re: [PATCH v5] iio: adc: pac1921: Add ACPI support to Microchip pac1921

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 2024-10-18 at 17:47 +0200, Matteo Martelli wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you
> know the content is safe
> 
> Quoting victor.duicu@xxxxxxxxxxxxx (2024-10-18 14:06:24)
> > From: Victor Duicu <victor.duicu@xxxxxxxxxxxxx>
> > 
> > This driver implements ACPI support to Microchip pac1921.
> > The driver can read shunt resistor value and label from ACPI table.
> > 
> > Signed-off-by: Victor Duicu <victor.duicu@xxxxxxxxxxxxx>
> > ---
> > 
> > The patch was tested on minnowboard and sama5.
> > 
> > Differences related to previous versions:
> > v5:
> 
> I think v4 was cleaner. Are the following changes necessary?
> 
> > - set maximum acceptable value of shunt resistor to 2KOHM in
> > devicetree,
> > ACPI table and user input. The chosen value is lesser than INT_MAX,
> > which is about 2.1KOHM.
> 
> I would personally keep INT_MAX since the limitation is only given by
> the types
> used in the current conversions (see pac1921_calc_scale()) rather
> than being a
> specific PAC1921 hardware limitation. Otherwise I would extend the
> comment on
> top of those two definitions explaining why that's the maximum.

Will set maximum acceptable value to INT_MAX.

> > - in pac1921_match_acpi_device and pac1921_parse_of_fw change to
> > only
> >   read 32b values for resistor shunt.
> > 
> 
> I think that in pac1921_match_acpi_device(), the u64 temp var was
> introduced to
> address the possible overflow coming from the u64 rez-
> >package.elements[0].integer.value
> and to safely perform a sanity check. I don't think we can trust
> blindly that
> the ACPI table always has a valid 32bit value in that field.

If the ACPI table has revision set to 1, all values higher than 32b
will be truncated to 32b.

> pac1921_parse_of_fw() doesn't look changed compared to v4, you
> already switched
> back to device_property_read_u32, if it's what you are referring to.

Yes, in v4 I changed pac1921_parse_of_fw and in v5 I changed
pac1921_match_acpi_device. I changed both back to 32b in order
to be consistent.

> > 
> > v4:
> > - change name of pac1921_shunt_is_valid to
> > pac1921_shunt_is_invalid.
> > - fix coding style.
> > - in pac1921_parse_of_fw change back to device_property_read_u32.
> > 
> > 
> >  drivers/iio/adc/pac1921.c | 109 +++++++++++++++++++++++++++++++++-
> > ----
> >  1 file changed, 96 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/pac1921.c b/drivers/iio/adc/pac1921.c
> > index a96fae546bc1..9622b0da6196 100644
> > --- a/drivers/iio/adc/pac1921.c
> > +++ b/drivers/iio/adc/pac1921.c
> > @@ -67,6 +67,13 @@ enum pac1921_mxsl {
> >  #define PAC1921_DEFAULT_DI_GAIN                0 /* 2^(value): 1x
> > gain (HW default) */
> >  #define PAC1921_DEFAULT_NUM_SAMPLES    0 /* 2^(value): 1 sample
> > (HW default) */
> > 
> > 
> > 
> > @@ -791,9 +803,13 @@ static ssize_t
> > pac1921_write_shunt_resistor(struct iio_dev *indio_dev,
> >         ret = iio_str_to_fixpoint(buf, 100000, &val, &val_fract);
> >         if (ret)
> >                 return ret;
> > +
> > +       /* This check is to ensure val*MICRO won't overflow*/
> > +       if (val < 0 || val > PAC1921_MAX_SHUNT_VALUE_OHMS)
> > +               return -EINVAL;
> > 
> >         rshunt_uohm = val * MICRO + val_fract;
> > -       if (rshunt_uohm == 0 || rshunt_uohm > INT_MAX)
> > +       if (pac1921_shunt_is_invalid(rshunt_uohm))
> >                 return -EINVAL;
> > 
> 
> In v3 you added the (u64)val cast to solve the multiplication
> overflow. Wasn't
> that enough? However, if this is for better clarity I am fine with
> it.

The cast to 64b was removed in order to be consistent
with dt and ACPI that will read only 32b values.

> >         guard(mutex)(&priv->lock);
> > @@ -1150,6 +1166,71 @@ static void pac1921_regulator_disable(void
> > *data)
> >         regulator_disable(regulator);
> >  }
> > 
> > +/*
> > + * documentation related to the ACPI device definition
> > + *
> > https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ApplicationNotes/ApplicationNotes/PAC193X-Integration-Notes-for-Microsoft-Windows-10-and-Windows-11-Driver-Support-DS00002534.pdf
> > + */
> > +static int pac1921_match_acpi_device(struct i2c_client *client,
> > struct pac1921_priv *priv,
> > +                                    struct iio_dev *indio_dev)
> > +{
> > +       acpi_handle handle;
> > +       union acpi_object *rez;
> > +       guid_t guid;
> > +       char *label;
> > +       u32 temp;
> > +
> > +       guid_parse(PAC1921_DSM_UUID, &guid);
> > +       handle = ACPI_HANDLE(&client->dev);
> > +
> > +       rez = acpi_evaluate_dsm(handle, &guid, 1,
> > PAC1921_ACPI_GET_UOHMS_VALS, NULL);
> > +       if (!rez)
> > +               return dev_err_probe(&client->dev, -EINVAL,
> > +                                    "Could not read shunt from
> > ACPI table\n");
> > +
> > +       temp = rez->package.elements[0].integer.value;
> 
> I don't think we can trust rez->package.elements[0].integer.value to
> always be
> in 32bit boundaries. But if that's the case then the temp var looks
> unnecessary.

Will remove the temp var in the next version.

> > +       ACPI_FREE(rez);
> > +
> > +       if (pac1921_shunt_is_invalid(temp))
> > +               return dev_err_probe(&client->dev, -EINVAL,
> > "Invalid shunt resistor\n");
> > +
> > +       priv->rshunt_uohm = temp;
> > +       pac1921_calc_current_scales(priv);
> > +
> > +       rez = acpi_evaluate_dsm(handle, &guid, 1,
> > PAC1921_ACPI_GET_LABEL, NULL);
> > +       if (!rez)
> > +               return dev_err_probe(&client->dev, -EINVAL,
> > +                                    "Could not read label from
> > ACPI table\n");
> > +
> > +       label = devm_kmemdup(&client->dev, rez->package.elements-
> > >string.pointer,
> > +                            (size_t)rez->package.elements-
> > >string.length + 1,
> > +                            GFP_KERNEL);
> > +       label[rez->package.elements->string.length] = '\0';
> > +       indio_dev->label = label;
> > +       ACPI_FREE(rez);
> > +
> > +       return 0;
> > +}
> > 
> > --
> > 2.43.0
> > 
> 
> Best regards,
> Matteo Martelli





[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux