[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <0fb0ddda50f7b204a28973933189993da42a8318.camel@microchip.com>
Date: Tue, 22 Oct 2024 08:52:50 +0000
From: <Victor.Duicu@...rochip.com>
To: <jic23@...nel.org>, <matteomartelli3@...il.com>, <lars@...afoo.de>
CC: <Marius.Cristea@...rochip.com>, <linux-kernel@...r.kernel.org>,
<linux-iio@...r.kernel.org>
Subject: Re: [PATCH v5] iio: adc: pac1921: Add ACPI support to Microchip
pac1921
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@...rochip.com (2024-10-18 14:06:24)
> > From: Victor Duicu <victor.duicu@...rochip.com>
> >
> > 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@...rochip.com>
> > ---
> >
> > 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
Powered by blists - more mailing lists