diff mbox series

[v4,3/3] iio: temperature: ltc2983: Make use of device properties

Message ID 20220304180257.80298-3-andriy.shevchenko@linux.intel.com (mailing list archive)
State Superseded
Headers show
Series [v4,1/3] iio: temperature: ltc2983: Don't hard code defined constants in messages | expand

Commit Message

Andy Shevchenko March 4, 2022, 6:02 p.m. UTC
Convert the module to be property provider agnostic and allow
it to be used on non-OF platforms.

The conversion slightly changes the logic behind property reading for
the configuration values. Original code allocates just as much memory
as needed. Then for each separate 32- or 64-bit value it reads it from
the property and converts to a raw one which will be fed to the sensor.
In the new code we allocate the amount of memory needed to retrieve all
values at once from the property and then convert them as required.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Nuno Sá <nuno.sa@analog.com>
---
v4: added checks for error pointer (Nuno), added Tb tag (Nuno)
v3: no changes

 drivers/iio/temperature/ltc2983.c | 209 +++++++++++++++---------------
 1 file changed, 106 insertions(+), 103 deletions(-)

Comments

Andy Shevchenko March 4, 2022, 6:28 p.m. UTC | #1
On Fri, Mar 04, 2022 at 08:02:57PM +0200, Andy Shevchenko wrote:
> Convert the module to be property provider agnostic and allow
> it to be used on non-OF platforms.
> 
> The conversion slightly changes the logic behind property reading for
> the configuration values. Original code allocates just as much memory
> as needed. Then for each separate 32- or 64-bit value it reads it from
> the property and converts to a raw one which will be fed to the sensor.
> In the new code we allocate the amount of memory needed to retrieve all
> values at once from the property and then convert them as required.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Tested-by: Nuno Sá <nuno.sa@analog.com>
> ---
> v4: added checks for error pointer (Nuno), added Tb tag (Nuno)
> v3: no changes

Forgot to add, that this patch should work without fwnode fix.
To test fwnode fix, the part of the NULLifying ref should be
(temporary) dropped.
Nuno Sá March 5, 2022, 12:39 p.m. UTC | #2
On Fri, 2022-03-04 at 20:02 +0200, Andy Shevchenko wrote:
> Convert the module to be property provider agnostic and allow
> it to be used on non-OF platforms.
> 
> The conversion slightly changes the logic behind property reading for
> the configuration values. Original code allocates just as much memory
> as needed. Then for each separate 32- or 64-bit value it reads it
> from
> the property and converts to a raw one which will be fed to the
> sensor.
> In the new code we allocate the amount of memory needed to retrieve
> all
> values at once from the property and then convert them as required.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Tested-by: Nuno Sá <nuno.sa@analog.com>
> ---
> v4: added checks for error pointer (Nuno), added Tb tag (Nuno)
> v3: no changes
> 

Hi Andy,

Just small observation/question from my side...

>  drivers/iio/temperature/ltc2983.c | 209 +++++++++++++++-------------
> --
>  1 file changed, 106 insertions(+), 103 deletions(-)
> 
> diff --git a/drivers/iio/temperature/ltc2983.c
> b/drivers/iio/temperature/ltc2983.c
> index 636bbc9011b9..6971e8828d44 100644
> --- a/drivers/iio/temperature/ltc2983.c
> +++ b/drivers/iio/temperature/ltc2983.c
> @@ -12,11 +12,15 @@
>  #include <linux/iio/iio.h>
>  #include <linux/interrupt.h>
>  #include <linux/list.h>
> +#include <linux/mod_devicetable.h>
>  #include <linux/module.h>
> -#include <linux/of_gpio.h>
> +#include <linux/property.h>
>  #include <linux/regmap.h>
>  #include <linux/spi/spi.h>
>  
> +#include <asm/byteorder.h>
> +#include <asm/unaligned.h>
> +
>  /* register map */
>  #define LTC2983_STATUS_REG                     0x0000
>  #define LTC2983_TEMP_RES_START_REG             0x0010
> @@ -219,7 +223,7 @@ struct ltc2983_sensor {
>  
>  struct ltc2983_custom_sensor {
>         /* raw table sensor data */
> -       u8 *table;
> +       void *table;
>         size_t size;
>         /* address offset */
>         s8 offset;
> @@ -377,25 +381,25 @@ static int
> __ltc2983_chan_custom_sensor_assign(struct ltc2983_data *st,
>         return regmap_bulk_write(st->regmap, reg, custom->table,
> custom->size);
>  }
>  
> -static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new(
> -                                               struct ltc2983_data
> *st,
> -                                               const struct
> device_node *np,
> -                                               const char *propname,
> -                                               const bool
> is_steinhart,
> -                                               const u32 resolution,
> -                                               const bool
> has_signed)
> +static struct ltc2983_custom_sensor *
> +__ltc2983_custom_sensor_new(struct ltc2983_data *st, const struct
> fwnode_handle *fn,
> +                           const char *propname, const bool
> is_steinhart,
> +                           const u32 resolution, const bool
> has_signed)
>  {
>         struct ltc2983_custom_sensor *new_custom;
> -       u8 index, n_entries, tbl = 0;
>         struct device *dev = &st->spi->dev;
>         /*
>          * For custom steinhart, the full u32 is taken. For all the
> others
>          * the MSB is discarded.
>          */
>         const u8 n_size = is_steinhart ? 4 : 3;
> -       const u8 e_size = is_steinhart ? sizeof(u32) : sizeof(u64);
> +       u8 index, n_entries;
> +       int ret;
>  
> -       n_entries = of_property_count_elems_of_size(np, propname,
> e_size);
> +       if (is_steinhart)
> +               n_entries = fwnode_property_count_u32(fn, propname);
> +       else
> +               n_entries = fwnode_property_count_u64(fn, propname);
>         /* n_entries must be an even number */
>         if (!n_entries || (n_entries % 2) != 0) {
>                 dev_err(dev, "Number of entries either 0 or not
> even\n");
> @@ -423,21 +427,33 @@ static struct ltc2983_custom_sensor
> *__ltc2983_custom_sensor_new(
>         }
>  
>         /* allocate the table */
> -       new_custom->table = devm_kzalloc(dev, new_custom->size,
> GFP_KERNEL);
> +       if (is_steinhart)
> +               new_custom->table = devm_kcalloc(dev, n_entries,
> sizeof(u32), GFP_KERNEL);
> +       else
> +               new_custom->table = devm_kcalloc(dev, n_entries,
> sizeof(u64), GFP_KERNEL);
>         if (!new_custom->table)
>                 return ERR_PTR(-ENOMEM);
>  
> -       for (index = 0; index < n_entries; index++) {
> -               u64 temp = 0, j;
> -               /*
> -                * Steinhart sensors are configured with raw values
> in the
> -                * devicetree. For the other sensors we must convert
> the
> -                * value to raw. The odd index's correspond to
> temperarures
> -                * and always have 1/1024 of resolution. Temperatures
> also
> -                * come in kelvin, so signed values is not possible
> -                */
> -               if (!is_steinhart) {
> -                       of_property_read_u64_index(np, propname,
> index, &temp);
> +       /*
> +        * Steinhart sensors are configured with raw values in the
> firmware
> +        * node. For the other sensors we must convert the value to
> raw.
> +        * The odd index's correspond to temperatures and always have
> 1/1024
> +        * of resolution. Temperatures also come in Kelvin, so signed
> values
> +        * are not possible.
> +        */
> +       if (is_steinhart) {
> +               ret = fwnode_property_read_u32_array(fn, propname,
> new_custom->table, n_entries);
> +               if (ret < 0)
> +                       return ERR_PTR(ret);
> +
> +               cpu_to_be32_array(new_custom->table, new_custom-
> >table, n_entries);
> +       } else {
> +               ret = fwnode_property_read_u64_array(fn, propname,
> new_custom->table, n_entries);
> +               if (ret < 0)
> +                       return ERR_PTR(ret);
> +
> +               for (index = 0; index < n_entries; index++) {
> +                       u64 temp = ((u64 *)new_custom->table)[index];
>  
>                         if ((index % 2) != 0)
>                                 temp = __convert_to_raw(temp, 1024);
> @@ -445,16 +461,9 @@ static struct ltc2983_custom_sensor
> *__ltc2983_custom_sensor_new(
>                                 temp = __convert_to_raw_sign(temp,
> resolution);
>                         else
>                                 temp = __convert_to_raw(temp,
> resolution);
> -               } else {
> -                       u32 t32;
>  
> -                       of_property_read_u32_index(np, propname,
> index, &t32);
> -                       temp = t32;
> +                       put_unaligned_be24(temp, new_custom->table +
> index * 3);
>                 }
> -
> -               for (j = 0; j < n_size; j++)
> -                       new_custom->table[tbl++] =
> -                               temp >> (8 * (n_size - j - 1));
>         }
>  
>         new_custom->is_steinhart = is_steinhart;
> @@ -597,13 +606,12 @@ static int ltc2983_adc_assign_chan(struct
> ltc2983_data *st,
>         return __ltc2983_chan_assign_common(st, sensor, chan_val);
>  }
>  
> -static struct ltc2983_sensor *ltc2983_thermocouple_new(
> -                                       const struct device_node
> *child,
> -                                       struct ltc2983_data *st,
> -                                       const struct ltc2983_sensor
> *sensor)
> +static struct ltc2983_sensor *
> +ltc2983_thermocouple_new(const struct fwnode_handle *child, struct
> ltc2983_data *st,
> +                        const struct ltc2983_sensor *sensor)
>  {
>         struct ltc2983_thermocouple *thermo;
> -       struct device_node *phandle;
> +       struct fwnode_handle *ref;
>         u32 oc_current;
>         int ret;
>  
> @@ -611,11 +619,10 @@ static struct ltc2983_sensor
> *ltc2983_thermocouple_new(
>         if (!thermo)
>                 return ERR_PTR(-ENOMEM);
>  
> -       if (of_property_read_bool(child, "adi,single-ended"))
> +       if (fwnode_property_read_bool(child, "adi,single-ended"))
>                 thermo->sensor_config = LTC2983_THERMOCOUPLE_SGL(1);
>  
> -       ret = of_property_read_u32(child, "adi,sensor-oc-current-
> microamp",
> -                                  &oc_current);
> +       ret = fwnode_property_read_u32(child, "adi,sensor-oc-current-
> microamp", &oc_current);
>         if (!ret) {
>                 switch (oc_current) {
>                 case 10:
> @@ -651,10 +658,11 @@ static struct ltc2983_sensor
> *ltc2983_thermocouple_new(
>                 return ERR_PTR(-EINVAL);
>         }
>  
> -       phandle = of_parse_phandle(child, "adi,cold-junction-handle",
> 0);
> -       if (phandle) {
> -               ret = of_property_read_u32(phandle, "reg",
> -                                          &thermo-
> >cold_junction_chan);
> +       ref = fwnode_find_reference(child, "adi,cold-junction-
> handle", 0);
> +       if (IS_ERR_OR_NULL(ref)) {
> +               ref = NULL;
> +       } else {
> +               ret = fwnode_property_read_u32(ref, "reg", &thermo-
> >cold_junction_chan);
>                 if (ret) {
>                         /*
>                          * This would be catched later but we can
> just return
> @@ -682,41 +690,41 @@ static struct ltc2983_sensor
> *ltc2983_thermocouple_new(
>         thermo->sensor.fault_handler =
> ltc2983_thermocouple_fault_handler;
>         thermo->sensor.assign_chan =
> ltc2983_thermocouple_assign_chan;
>  
> -       of_node_put(phandle);
> +       fwnode_handle_put(ref);
>         return &thermo->sensor;
>  
>  fail:
> -       of_node_put(phandle);
> +       fwnode_handle_put(ref);
>         return ERR_PTR(ret);
>  }
>  
> -static struct ltc2983_sensor *ltc2983_rtd_new(const struct
> device_node *child,
> -                                         struct ltc2983_data *st,
> -                                         const struct ltc2983_sensor
> *sensor)
> +static struct ltc2983_sensor *
> +ltc2983_rtd_new(const struct fwnode_handle *child, struct
> ltc2983_data *st,
> +               const struct ltc2983_sensor *sensor)
>  {
>         struct ltc2983_rtd *rtd;
>         int ret = 0;
>         struct device *dev = &st->spi->dev;
> -       struct device_node *phandle;
> +       struct fwnode_handle *ref;
>         u32 excitation_current = 0, n_wires = 0;
>  
>         rtd = devm_kzalloc(dev, sizeof(*rtd), GFP_KERNEL);
>         if (!rtd)
>                 return ERR_PTR(-ENOMEM);
>  
> -       phandle = of_parse_phandle(child, "adi,rsense-handle", 0);
> -       if (!phandle) {
> +       ref = fwnode_find_reference(child, "adi,rsense-handle", 0);
> +       if (IS_ERR_OR_NULL(ref)) {
>                 dev_err(dev, "Property adi,rsense-handle missing or
> invalid");

I'm wondering... Is there any way for NULL being returned? Looking at
the API, it seems it always return error pointers... Also, all the
current users of fwnode_find_reference() only care to check for error
pointers...

Or is this just personal preference and you being prepared for any
potential change in the API? Note that Im fine with this as-is...

Anyways, will try to re-test this Monday...

- Nuno Sá
Nuno Sa March 7, 2022, 4:09 p.m. UTC | #3
> From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Sent: Friday, March 4, 2022 7:03 PM
> To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>; linux-
> iio@vger.kernel.org; linux-kernel@vger.kernel.org
> Cc: Sa, Nuno <Nuno.Sa@analog.com>; Jonathan Cameron
> <jic23@kernel.org>; Lars-Peter Clausen <lars@metafoo.de>
> Subject: [PATCH v4 3/3] iio: temperature: ltc2983: Make use of device
> properties
> 
> [External]
> 
> Convert the module to be property provider agnostic and allow
> it to be used on non-OF platforms.
> 
> The conversion slightly changes the logic behind property reading for
> the configuration values. Original code allocates just as much memory
> as needed. Then for each separate 32- or 64-bit value it reads it from
> the property and converts to a raw one which will be fed to the sensor.
> In the new code we allocate the amount of memory needed to
> retrieve all
> values at once from the property and then convert them as required.
> 
> Signed-off-by: Andy Shevchenko
> <andriy.shevchenko@linux.intel.com>
> Tested-by: Nuno Sá <nuno.sa@analog.com>
> ---
> v4: added checks for error pointer (Nuno), added Tb tag (Nuno)
> v3: no changes
> 

Hi Andy,

So the patch now just works after applying. Also, removed the
if()...else() in ltc2983_thermocouple_new() and turned it into

if (!IS_ERR_OR_NULL(ref)) {
   ...
}

and applied your fwnode fix and things work....

- Nuno Sá
Nuno Sa March 7, 2022, 4:19 p.m. UTC | #4
> From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Sent: Friday, March 4, 2022 7:03 PM
> To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>; linux-
> iio@vger.kernel.org; linux-kernel@vger.kernel.org
> Cc: Sa, Nuno <Nuno.Sa@analog.com>; Jonathan Cameron
> <jic23@kernel.org>; Lars-Peter Clausen <lars@metafoo.de>
> Subject: [PATCH v4 3/3] iio: temperature: ltc2983: Make use of device
> properties
> 
> [External]
> 
> Convert the module to be property provider agnostic and allow
> it to be used on non-OF platforms.
> 
> The conversion slightly changes the logic behind property reading for
> the configuration values. Original code allocates just as much memory
> as needed. Then for each separate 32- or 64-bit value it reads it from
> the property and converts to a raw one which will be fed to the sensor.
> In the new code we allocate the amount of memory needed to
> retrieve all
> values at once from the property and then convert them as required.
> 
> Signed-off-by: Andy Shevchenko
> <andriy.shevchenko@linux.intel.com>
> Tested-by: Nuno Sá <nuno.sa@analog.com>
> ---

Even though I had a small note on this particular patch, consider:

Reviewed-by: Nuno Sá <nuno.sa@analog.com>

for the whole series...

- Nuno Sá
diff mbox series

Patch

diff --git a/drivers/iio/temperature/ltc2983.c b/drivers/iio/temperature/ltc2983.c
index 636bbc9011b9..6971e8828d44 100644
--- a/drivers/iio/temperature/ltc2983.c
+++ b/drivers/iio/temperature/ltc2983.c
@@ -12,11 +12,15 @@ 
 #include <linux/iio/iio.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
-#include <linux/of_gpio.h>
+#include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/spi/spi.h>
 
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
+
 /* register map */
 #define LTC2983_STATUS_REG			0x0000
 #define LTC2983_TEMP_RES_START_REG		0x0010
@@ -219,7 +223,7 @@  struct ltc2983_sensor {
 
 struct ltc2983_custom_sensor {
 	/* raw table sensor data */
-	u8 *table;
+	void *table;
 	size_t size;
 	/* address offset */
 	s8 offset;
@@ -377,25 +381,25 @@  static int __ltc2983_chan_custom_sensor_assign(struct ltc2983_data *st,
 	return regmap_bulk_write(st->regmap, reg, custom->table, custom->size);
 }
 
-static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new(
-						struct ltc2983_data *st,
-						const struct device_node *np,
-						const char *propname,
-						const bool is_steinhart,
-						const u32 resolution,
-						const bool has_signed)
+static struct ltc2983_custom_sensor *
+__ltc2983_custom_sensor_new(struct ltc2983_data *st, const struct fwnode_handle *fn,
+			    const char *propname, const bool is_steinhart,
+			    const u32 resolution, const bool has_signed)
 {
 	struct ltc2983_custom_sensor *new_custom;
-	u8 index, n_entries, tbl = 0;
 	struct device *dev = &st->spi->dev;
 	/*
 	 * For custom steinhart, the full u32 is taken. For all the others
 	 * the MSB is discarded.
 	 */
 	const u8 n_size = is_steinhart ? 4 : 3;
-	const u8 e_size = is_steinhart ? sizeof(u32) : sizeof(u64);
+	u8 index, n_entries;
+	int ret;
 
-	n_entries = of_property_count_elems_of_size(np, propname, e_size);
+	if (is_steinhart)
+		n_entries = fwnode_property_count_u32(fn, propname);
+	else
+		n_entries = fwnode_property_count_u64(fn, propname);
 	/* n_entries must be an even number */
 	if (!n_entries || (n_entries % 2) != 0) {
 		dev_err(dev, "Number of entries either 0 or not even\n");
@@ -423,21 +427,33 @@  static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new(
 	}
 
 	/* allocate the table */
-	new_custom->table = devm_kzalloc(dev, new_custom->size, GFP_KERNEL);
+	if (is_steinhart)
+		new_custom->table = devm_kcalloc(dev, n_entries, sizeof(u32), GFP_KERNEL);
+	else
+		new_custom->table = devm_kcalloc(dev, n_entries, sizeof(u64), GFP_KERNEL);
 	if (!new_custom->table)
 		return ERR_PTR(-ENOMEM);
 
-	for (index = 0; index < n_entries; index++) {
-		u64 temp = 0, j;
-		/*
-		 * Steinhart sensors are configured with raw values in the
-		 * devicetree. For the other sensors we must convert the
-		 * value to raw. The odd index's correspond to temperarures
-		 * and always have 1/1024 of resolution. Temperatures also
-		 * come in kelvin, so signed values is not possible
-		 */
-		if (!is_steinhart) {
-			of_property_read_u64_index(np, propname, index, &temp);
+	/*
+	 * Steinhart sensors are configured with raw values in the firmware
+	 * node. For the other sensors we must convert the value to raw.
+	 * The odd index's correspond to temperatures and always have 1/1024
+	 * of resolution. Temperatures also come in Kelvin, so signed values
+	 * are not possible.
+	 */
+	if (is_steinhart) {
+		ret = fwnode_property_read_u32_array(fn, propname, new_custom->table, n_entries);
+		if (ret < 0)
+			return ERR_PTR(ret);
+
+		cpu_to_be32_array(new_custom->table, new_custom->table, n_entries);
+	} else {
+		ret = fwnode_property_read_u64_array(fn, propname, new_custom->table, n_entries);
+		if (ret < 0)
+			return ERR_PTR(ret);
+
+		for (index = 0; index < n_entries; index++) {
+			u64 temp = ((u64 *)new_custom->table)[index];
 
 			if ((index % 2) != 0)
 				temp = __convert_to_raw(temp, 1024);
@@ -445,16 +461,9 @@  static struct ltc2983_custom_sensor *__ltc2983_custom_sensor_new(
 				temp = __convert_to_raw_sign(temp, resolution);
 			else
 				temp = __convert_to_raw(temp, resolution);
-		} else {
-			u32 t32;
 
-			of_property_read_u32_index(np, propname, index, &t32);
-			temp = t32;
+			put_unaligned_be24(temp, new_custom->table + index * 3);
 		}
-
-		for (j = 0; j < n_size; j++)
-			new_custom->table[tbl++] =
-				temp >> (8 * (n_size - j - 1));
 	}
 
 	new_custom->is_steinhart = is_steinhart;
@@ -597,13 +606,12 @@  static int ltc2983_adc_assign_chan(struct ltc2983_data *st,
 	return __ltc2983_chan_assign_common(st, sensor, chan_val);
 }
 
-static struct ltc2983_sensor *ltc2983_thermocouple_new(
-					const struct device_node *child,
-					struct ltc2983_data *st,
-					const struct ltc2983_sensor *sensor)
+static struct ltc2983_sensor *
+ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data *st,
+			 const struct ltc2983_sensor *sensor)
 {
 	struct ltc2983_thermocouple *thermo;
-	struct device_node *phandle;
+	struct fwnode_handle *ref;
 	u32 oc_current;
 	int ret;
 
@@ -611,11 +619,10 @@  static struct ltc2983_sensor *ltc2983_thermocouple_new(
 	if (!thermo)
 		return ERR_PTR(-ENOMEM);
 
-	if (of_property_read_bool(child, "adi,single-ended"))
+	if (fwnode_property_read_bool(child, "adi,single-ended"))
 		thermo->sensor_config = LTC2983_THERMOCOUPLE_SGL(1);
 
-	ret = of_property_read_u32(child, "adi,sensor-oc-current-microamp",
-				   &oc_current);
+	ret = fwnode_property_read_u32(child, "adi,sensor-oc-current-microamp", &oc_current);
 	if (!ret) {
 		switch (oc_current) {
 		case 10:
@@ -651,10 +658,11 @@  static struct ltc2983_sensor *ltc2983_thermocouple_new(
 		return ERR_PTR(-EINVAL);
 	}
 
-	phandle = of_parse_phandle(child, "adi,cold-junction-handle", 0);
-	if (phandle) {
-		ret = of_property_read_u32(phandle, "reg",
-					   &thermo->cold_junction_chan);
+	ref = fwnode_find_reference(child, "adi,cold-junction-handle", 0);
+	if (IS_ERR_OR_NULL(ref)) {
+		ref = NULL;
+	} else {
+		ret = fwnode_property_read_u32(ref, "reg", &thermo->cold_junction_chan);
 		if (ret) {
 			/*
 			 * This would be catched later but we can just return
@@ -682,41 +690,41 @@  static struct ltc2983_sensor *ltc2983_thermocouple_new(
 	thermo->sensor.fault_handler = ltc2983_thermocouple_fault_handler;
 	thermo->sensor.assign_chan = ltc2983_thermocouple_assign_chan;
 
-	of_node_put(phandle);
+	fwnode_handle_put(ref);
 	return &thermo->sensor;
 
 fail:
-	of_node_put(phandle);
+	fwnode_handle_put(ref);
 	return ERR_PTR(ret);
 }
 
-static struct ltc2983_sensor *ltc2983_rtd_new(const struct device_node *child,
-					  struct ltc2983_data *st,
-					  const struct ltc2983_sensor *sensor)
+static struct ltc2983_sensor *
+ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
+		const struct ltc2983_sensor *sensor)
 {
 	struct ltc2983_rtd *rtd;
 	int ret = 0;
 	struct device *dev = &st->spi->dev;
-	struct device_node *phandle;
+	struct fwnode_handle *ref;
 	u32 excitation_current = 0, n_wires = 0;
 
 	rtd = devm_kzalloc(dev, sizeof(*rtd), GFP_KERNEL);
 	if (!rtd)
 		return ERR_PTR(-ENOMEM);
 
-	phandle = of_parse_phandle(child, "adi,rsense-handle", 0);
-	if (!phandle) {
+	ref = fwnode_find_reference(child, "adi,rsense-handle", 0);
+	if (IS_ERR_OR_NULL(ref)) {
 		dev_err(dev, "Property adi,rsense-handle missing or invalid");
-		return ERR_PTR(-EINVAL);
+		return ref ? ERR_CAST(ref) : ERR_PTR(-EINVAL);
 	}
 
-	ret = of_property_read_u32(phandle, "reg", &rtd->r_sense_chan);
+	ret = fwnode_property_read_u32(ref, "reg", &rtd->r_sense_chan);
 	if (ret) {
 		dev_err(dev, "Property reg must be given\n");
 		goto fail;
 	}
 
-	ret = of_property_read_u32(child, "adi,number-of-wires", &n_wires);
+	ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires);
 	if (!ret) {
 		switch (n_wires) {
 		case 2:
@@ -739,9 +747,9 @@  static struct ltc2983_sensor *ltc2983_rtd_new(const struct device_node *child,
 		}
 	}
 
-	if (of_property_read_bool(child, "adi,rsense-share")) {
+	if (fwnode_property_read_bool(child, "adi,rsense-share")) {
 		/* Current rotation is only available with rsense sharing */
-		if (of_property_read_bool(child, "adi,current-rotate")) {
+		if (fwnode_property_read_bool(child, "adi,current-rotate")) {
 			if (n_wires == 2 || n_wires == 3) {
 				dev_err(dev,
 					"Rotation not allowed for 2/3 Wire RTDs");
@@ -813,8 +821,8 @@  static struct ltc2983_sensor *ltc2983_rtd_new(const struct device_node *child,
 	rtd->sensor.fault_handler = ltc2983_common_fault_handler;
 	rtd->sensor.assign_chan = ltc2983_rtd_assign_chan;
 
-	ret = of_property_read_u32(child, "adi,excitation-current-microamp",
-				   &excitation_current);
+	ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp",
+				       &excitation_current);
 	if (ret) {
 		/* default to 5uA */
 		rtd->excitation_current = 1;
@@ -853,23 +861,22 @@  static struct ltc2983_sensor *ltc2983_rtd_new(const struct device_node *child,
 		}
 	}
 
-	of_property_read_u32(child, "adi,rtd-curve", &rtd->rtd_curve);
+	fwnode_property_read_u32(child, "adi,rtd-curve", &rtd->rtd_curve);
 
-	of_node_put(phandle);
+	fwnode_handle_put(ref);
 	return &rtd->sensor;
 fail:
-	of_node_put(phandle);
+	fwnode_handle_put(ref);
 	return ERR_PTR(ret);
 }
 
-static struct ltc2983_sensor *ltc2983_thermistor_new(
-					const struct device_node *child,
-					struct ltc2983_data *st,
-					const struct ltc2983_sensor *sensor)
+static struct ltc2983_sensor *
+ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *st,
+		       const struct ltc2983_sensor *sensor)
 {
 	struct ltc2983_thermistor *thermistor;
 	struct device *dev = &st->spi->dev;
-	struct device_node *phandle;
+	struct fwnode_handle *ref;
 	u32 excitation_current = 0;
 	int ret = 0;
 
@@ -877,23 +884,23 @@  static struct ltc2983_sensor *ltc2983_thermistor_new(
 	if (!thermistor)
 		return ERR_PTR(-ENOMEM);
 
-	phandle = of_parse_phandle(child, "adi,rsense-handle", 0);
-	if (!phandle) {
+	ref = fwnode_find_reference(child, "adi,rsense-handle", 0);
+	if (IS_ERR_OR_NULL(ref)) {
 		dev_err(dev, "Property adi,rsense-handle missing or invalid");
-		return ERR_PTR(-EINVAL);
+		return ref ? ERR_CAST(ref) : ERR_PTR(-EINVAL);
 	}
 
-	ret = of_property_read_u32(phandle, "reg", &thermistor->r_sense_chan);
+	ret = fwnode_property_read_u32(ref, "reg", &thermistor->r_sense_chan);
 	if (ret) {
 		dev_err(dev, "rsense channel must be configured...\n");
 		goto fail;
 	}
 
-	if (of_property_read_bool(child, "adi,single-ended")) {
+	if (fwnode_property_read_bool(child, "adi,single-ended")) {
 		thermistor->sensor_config = LTC2983_THERMISTOR_SGL(1);
-	} else if (of_property_read_bool(child, "adi,rsense-share")) {
+	} else if (fwnode_property_read_bool(child, "adi,rsense-share")) {
 		/* rotation is only possible if sharing rsense */
-		if (of_property_read_bool(child, "adi,current-rotate"))
+		if (fwnode_property_read_bool(child, "adi,current-rotate"))
 			thermistor->sensor_config =
 						LTC2983_THERMISTOR_C_ROTATE(1);
 		else
@@ -935,8 +942,8 @@  static struct ltc2983_sensor *ltc2983_thermistor_new(
 	thermistor->sensor.fault_handler = ltc2983_common_fault_handler;
 	thermistor->sensor.assign_chan = ltc2983_thermistor_assign_chan;
 
-	ret = of_property_read_u32(child, "adi,excitation-current-nanoamp",
-				   &excitation_current);
+	ret = fwnode_property_read_u32(child, "adi,excitation-current-nanoamp",
+				       &excitation_current);
 	if (ret) {
 		/* Auto range is not allowed for custom sensors */
 		if (sensor->type >= LTC2983_SENSOR_THERMISTOR_STEINHART)
@@ -1000,17 +1007,16 @@  static struct ltc2983_sensor *ltc2983_thermistor_new(
 		}
 	}
 
-	of_node_put(phandle);
+	fwnode_handle_put(ref);
 	return &thermistor->sensor;
 fail:
-	of_node_put(phandle);
+	fwnode_handle_put(ref);
 	return ERR_PTR(ret);
 }
 
-static struct ltc2983_sensor *ltc2983_diode_new(
-					const struct device_node *child,
-					const struct ltc2983_data *st,
-					const struct ltc2983_sensor *sensor)
+static struct ltc2983_sensor *
+ltc2983_diode_new(const struct fwnode_handle *child, const struct ltc2983_data *st,
+		  const struct ltc2983_sensor *sensor)
 {
 	struct ltc2983_diode *diode;
 	u32 temp = 0, excitation_current = 0;
@@ -1020,13 +1026,13 @@  static struct ltc2983_sensor *ltc2983_diode_new(
 	if (!diode)
 		return ERR_PTR(-ENOMEM);
 
-	if (of_property_read_bool(child, "adi,single-ended"))
+	if (fwnode_property_read_bool(child, "adi,single-ended"))
 		diode->sensor_config = LTC2983_DIODE_SGL(1);
 
-	if (of_property_read_bool(child, "adi,three-conversion-cycles"))
+	if (fwnode_property_read_bool(child, "adi,three-conversion-cycles"))
 		diode->sensor_config |= LTC2983_DIODE_3_CONV_CYCLE(1);
 
-	if (of_property_read_bool(child, "adi,average-on"))
+	if (fwnode_property_read_bool(child, "adi,average-on"))
 		diode->sensor_config |= LTC2983_DIODE_AVERAGE_ON(1);
 
 	/* validate channel index */
@@ -1041,8 +1047,8 @@  static struct ltc2983_sensor *ltc2983_diode_new(
 	diode->sensor.fault_handler = ltc2983_common_fault_handler;
 	diode->sensor.assign_chan = ltc2983_diode_assign_chan;
 
-	ret = of_property_read_u32(child, "adi,excitation-current-microamp",
-				   &excitation_current);
+	ret = fwnode_property_read_u32(child, "adi,excitation-current-microamp",
+				       &excitation_current);
 	if (!ret) {
 		switch (excitation_current) {
 		case 10:
@@ -1065,7 +1071,7 @@  static struct ltc2983_sensor *ltc2983_diode_new(
 		}
 	}
 
-	of_property_read_u32(child, "adi,ideal-factor-value", &temp);
+	fwnode_property_read_u32(child, "adi,ideal-factor-value", &temp);
 
 	/* 2^20 resolution */
 	diode->ideal_factor_value = __convert_to_raw(temp, 1048576);
@@ -1073,7 +1079,7 @@  static struct ltc2983_sensor *ltc2983_diode_new(
 	return &diode->sensor;
 }
 
-static struct ltc2983_sensor *ltc2983_r_sense_new(struct device_node *child,
+static struct ltc2983_sensor *ltc2983_r_sense_new(struct fwnode_handle *child,
 					struct ltc2983_data *st,
 					const struct ltc2983_sensor *sensor)
 {
@@ -1092,7 +1098,7 @@  static struct ltc2983_sensor *ltc2983_r_sense_new(struct device_node *child,
 		return ERR_PTR(-EINVAL);
 	}
 
-	ret = of_property_read_u32(child, "adi,rsense-val-milli-ohms", &temp);
+	ret = fwnode_property_read_u32(child, "adi,rsense-val-milli-ohms", &temp);
 	if (ret) {
 		dev_err(&st->spi->dev, "Property adi,rsense-val-milli-ohms missing\n");
 		return ERR_PTR(-EINVAL);
@@ -1111,7 +1117,7 @@  static struct ltc2983_sensor *ltc2983_r_sense_new(struct device_node *child,
 	return &rsense->sensor;
 }
 
-static struct ltc2983_sensor *ltc2983_adc_new(struct device_node *child,
+static struct ltc2983_sensor *ltc2983_adc_new(struct fwnode_handle *child,
 					 struct ltc2983_data *st,
 					 const struct ltc2983_sensor *sensor)
 {
@@ -1121,7 +1127,7 @@  static struct ltc2983_sensor *ltc2983_adc_new(struct device_node *child,
 	if (!adc)
 		return ERR_PTR(-ENOMEM);
 
-	if (of_property_read_bool(child, "adi,single-ended"))
+	if (fwnode_property_read_bool(child, "adi,single-ended"))
 		adc->single_ended = true;
 
 	if (!adc->single_ended &&
@@ -1265,17 +1271,15 @@  static irqreturn_t ltc2983_irq_handler(int irq, void *data)
 
 static int ltc2983_parse_dt(struct ltc2983_data *st)
 {
-	struct device_node *child;
 	struct device *dev = &st->spi->dev;
+	struct fwnode_handle *child;
 	int ret = 0, chan = 0, channel_avail_mask = 0;
 
-	of_property_read_u32(dev->of_node, "adi,mux-delay-config-us",
-			     &st->mux_delay_config);
+	device_property_read_u32(dev, "adi,mux-delay-config-us", &st->mux_delay_config);
 
-	of_property_read_u32(dev->of_node, "adi,filter-notch-freq",
-			     &st->filter_notch_freq);
+	device_property_read_u32(dev, "adi,filter-notch-freq", &st->filter_notch_freq);
 
-	st->num_channels = of_get_available_child_count(dev->of_node);
+	st->num_channels = device_get_child_node_count(dev);
 	if (!st->num_channels) {
 		dev_err(&st->spi->dev, "At least one channel must be given!");
 		return -EINVAL;
@@ -1287,10 +1291,10 @@  static int ltc2983_parse_dt(struct ltc2983_data *st)
 		return -ENOMEM;
 
 	st->iio_channels = st->num_channels;
-	for_each_available_child_of_node(dev->of_node, child) {
+	device_for_each_child_node(dev, child) {
 		struct ltc2983_sensor sensor;
 
-		ret = of_property_read_u32(child, "reg", &sensor.chan);
+		ret = fwnode_property_read_u32(child, "reg", &sensor.chan);
 		if (ret) {
 			dev_err(dev, "reg property must given for child nodes\n");
 			goto put_child;
@@ -1309,8 +1313,7 @@  static int ltc2983_parse_dt(struct ltc2983_data *st)
 			goto put_child;
 		}
 
-		ret = of_property_read_u32(child, "adi,sensor-type",
-					       &sensor.type);
+		ret = fwnode_property_read_u32(child, "adi,sensor-type", &sensor.type);
 		if (ret) {
 			dev_err(dev,
 				"adi,sensor-type property must given for child nodes\n");
@@ -1364,7 +1367,7 @@  static int ltc2983_parse_dt(struct ltc2983_data *st)
 
 	return 0;
 put_child:
-	of_node_put(child);
+	fwnode_handle_put(child);
 	return ret;
 }