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