Commit 8ca555bd authored by Jonathan Cameron's avatar Jonathan Cameron

iio: temp: ltc2983: Use __free(fwnode_handle) and device_for_each_node_scoped()

This use of the new cleanup.h scope based freeing infrastructure allows
us to exit directly from error conditions and in the good path with
the reference obtained from fwnode_find_reference() (which may be an error
pointer) automatically released.

Similarly the _scoped() version of device_for_each_child_node()
removes the need for the manual calling of fwnode_handl_put() in
paths where the code exits the loop early.

Tidy up some unusual indentation in a dev_dbg() whilst here.
Reviewed-by: default avatarNuno Sa <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20240224123215.161469-2-jic23@kernel.orgSigned-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent e1186ee3
......@@ -657,7 +657,6 @@ ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data
const struct ltc2983_sensor *sensor)
{
struct ltc2983_thermocouple *thermo;
struct fwnode_handle *ref;
u32 oc_current;
int ret;
......@@ -704,7 +703,8 @@ ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data
return ERR_PTR(-EINVAL);
}
ref = fwnode_find_reference(child, "adi,cold-junction-handle", 0);
struct fwnode_handle *ref __free(fwnode_handle) =
fwnode_find_reference(child, "adi,cold-junction-handle", 0);
if (IS_ERR(ref)) {
ref = NULL;
} else {
......@@ -715,7 +715,7 @@ ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data
* the error right away.
*/
dev_err(&st->spi->dev, "Property reg must be given\n");
goto fail;
return ERR_PTR(ret);
}
}
......@@ -726,22 +726,15 @@ ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data
thermo->custom = __ltc2983_custom_sensor_new(st, child,
propname, false,
16384, true);
if (IS_ERR(thermo->custom)) {
ret = PTR_ERR(thermo->custom);
goto fail;
}
if (IS_ERR(thermo->custom))
return ERR_CAST(thermo->custom);
}
/* set common parameters */
thermo->sensor.fault_handler = ltc2983_thermocouple_fault_handler;
thermo->sensor.assign_chan = ltc2983_thermocouple_assign_chan;
fwnode_handle_put(ref);
return &thermo->sensor;
fail:
fwnode_handle_put(ref);
return ERR_PTR(ret);
}
static struct ltc2983_sensor *
......@@ -751,14 +744,14 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
struct ltc2983_rtd *rtd;
int ret = 0;
struct device *dev = &st->spi->dev;
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);
ref = fwnode_find_reference(child, "adi,rsense-handle", 0);
struct fwnode_handle *ref __free(fwnode_handle) =
fwnode_find_reference(child, "adi,rsense-handle", 0);
if (IS_ERR(ref)) {
dev_err(dev, "Property adi,rsense-handle missing or invalid");
return ERR_CAST(ref);
......@@ -767,7 +760,7 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
ret = fwnode_property_read_u32(ref, "reg", &rtd->r_sense_chan);
if (ret) {
dev_err(dev, "Property reg must be given\n");
goto fail;
return ERR_PTR(ret);
}
ret = fwnode_property_read_u32(child, "adi,number-of-wires", &n_wires);
......@@ -788,8 +781,7 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
break;
default:
dev_err(dev, "Invalid number of wires:%u\n", n_wires);
ret = -EINVAL;
goto fail;
return ERR_PTR(-EINVAL);
}
}
......@@ -799,8 +791,7 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
if (n_wires == 2 || n_wires == 3) {
dev_err(dev,
"Rotation not allowed for 2/3 Wire RTDs");
ret = -EINVAL;
goto fail;
return ERR_PTR(-EINVAL);
}
rtd->sensor_config |= LTC2983_RTD_C_ROTATE(1);
} else {
......@@ -830,16 +821,14 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
"Invalid rsense chann:%d to use in kelvin rsense",
rtd->r_sense_chan);
ret = -EINVAL;
goto fail;
return ERR_PTR(-EINVAL);
}
if (sensor->chan < min || sensor->chan > max) {
dev_err(dev, "Invalid chann:%d for the rtd config",
sensor->chan);
ret = -EINVAL;
goto fail;
return ERR_PTR(-EINVAL);
}
} else {
/* same as differential case */
......@@ -847,8 +836,7 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
dev_err(&st->spi->dev,
"Invalid chann:%d for RTD", sensor->chan);
ret = -EINVAL;
goto fail;
return ERR_PTR(-EINVAL);
}
}
......@@ -857,10 +845,8 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
rtd->custom = __ltc2983_custom_sensor_new(st, child,
"adi,custom-rtd",
false, 2048, false);
if (IS_ERR(rtd->custom)) {
ret = PTR_ERR(rtd->custom);
goto fail;
}
if (IS_ERR(rtd->custom))
return ERR_CAST(rtd->custom);
}
/* set common parameters */
......@@ -902,18 +888,13 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
dev_err(&st->spi->dev,
"Invalid value for excitation current(%u)",
excitation_current);
ret = -EINVAL;
goto fail;
return ERR_PTR(-EINVAL);
}
}
fwnode_property_read_u32(child, "adi,rtd-curve", &rtd->rtd_curve);
fwnode_handle_put(ref);
return &rtd->sensor;
fail:
fwnode_handle_put(ref);
return ERR_PTR(ret);
}
static struct ltc2983_sensor *
......@@ -922,7 +903,6 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
{
struct ltc2983_thermistor *thermistor;
struct device *dev = &st->spi->dev;
struct fwnode_handle *ref;
u32 excitation_current = 0;
int ret = 0;
......@@ -930,7 +910,8 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
if (!thermistor)
return ERR_PTR(-ENOMEM);
ref = fwnode_find_reference(child, "adi,rsense-handle", 0);
struct fwnode_handle *ref __free(fwnode_handle) =
fwnode_find_reference(child, "adi,rsense-handle", 0);
if (IS_ERR(ref)) {
dev_err(dev, "Property adi,rsense-handle missing or invalid");
return ERR_CAST(ref);
......@@ -939,7 +920,7 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
ret = fwnode_property_read_u32(ref, "reg", &thermistor->r_sense_chan);
if (ret) {
dev_err(dev, "rsense channel must be configured...\n");
goto fail;
return ERR_PTR(ret);
}
if (fwnode_property_read_bool(child, "adi,single-ended")) {
......@@ -959,8 +940,7 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
dev_err(&st->spi->dev,
"Invalid chann:%d for differential thermistor",
sensor->chan);
ret = -EINVAL;
goto fail;
return ERR_PTR(-EINVAL);
}
/* check custom sensor */
......@@ -979,10 +959,8 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
propname,
steinhart,
64, false);
if (IS_ERR(thermistor->custom)) {
ret = PTR_ERR(thermistor->custom);
goto fail;
}
if (IS_ERR(thermistor->custom))
return ERR_CAST(thermistor->custom);
}
/* set common parameters */
thermistor->sensor.fault_handler = ltc2983_common_fault_handler;
......@@ -1006,8 +984,7 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
LTC2983_SENSOR_THERMISTOR_STEINHART) {
dev_err(&st->spi->dev,
"Auto Range not allowed for custom sensors\n");
ret = -EINVAL;
goto fail;
return ERR_PTR(-EINVAL);
}
thermistor->excitation_current = 0x0c;
break;
......@@ -1048,16 +1025,11 @@ ltc2983_thermistor_new(const struct fwnode_handle *child, struct ltc2983_data *s
dev_err(&st->spi->dev,
"Invalid value for excitation current(%u)",
excitation_current);
ret = -EINVAL;
goto fail;
return ERR_PTR(-EINVAL);
}
}
fwnode_handle_put(ref);
return &thermistor->sensor;
fail:
fwnode_handle_put(ref);
return ERR_PTR(ret);
}
static struct ltc2983_sensor *
......@@ -1350,8 +1322,7 @@ static irqreturn_t ltc2983_irq_handler(int irq, void *data)
static int ltc2983_parse_fw(struct ltc2983_data *st)
{
struct device *dev = &st->spi->dev;
struct fwnode_handle *child;
int ret = 0, chan = 0, channel_avail_mask = 0;
int ret, chan = 0, channel_avail_mask = 0;
device_property_read_u32(dev, "adi,mux-delay-config-us", &st->mux_delay_config);
......@@ -1369,38 +1340,35 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
return -ENOMEM;
st->iio_channels = st->num_channels;
device_for_each_child_node(dev, child) {
device_for_each_child_node_scoped(dev, child) {
struct ltc2983_sensor sensor;
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;
}
if (ret)
return dev_err_probe(dev, ret,
"reg property must given for child nodes\n");
/* check if we have a valid channel */
if (sensor.chan < LTC2983_MIN_CHANNELS_NR ||
sensor.chan > st->info->max_channels_nr) {
ret = -EINVAL;
dev_err(dev, "chan:%d must be from %u to %u\n", sensor.chan,
LTC2983_MIN_CHANNELS_NR, st->info->max_channels_nr);
goto put_child;
} else if (channel_avail_mask & BIT(sensor.chan)) {
ret = -EINVAL;
dev_err(dev, "chan:%d already in use\n", sensor.chan);
goto put_child;
}
sensor.chan > st->info->max_channels_nr)
return dev_err_probe(dev, -EINVAL,
"chan:%d must be from %u to %u\n",
sensor.chan,
LTC2983_MIN_CHANNELS_NR,
st->info->max_channels_nr);
if (channel_avail_mask & BIT(sensor.chan))
return dev_err_probe(dev, -EINVAL,
"chan:%d already in use\n",
sensor.chan);
ret = fwnode_property_read_u32(child, "adi,sensor-type", &sensor.type);
if (ret) {
dev_err(dev,
if (ret)
return dev_err_probe(dev, ret,
"adi,sensor-type property must given for child nodes\n");
goto put_child;
}
dev_dbg(dev, "Create new sensor, type %u, chann %u",
sensor.type,
sensor.chan);
sensor.type, sensor.chan);
if (sensor.type >= LTC2983_SENSOR_THERMOCOUPLE &&
sensor.type <= LTC2983_SENSOR_THERMOCOUPLE_CUSTOM) {
......@@ -1427,17 +1395,15 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
sensor.type == LTC2983_SENSOR_ACTIVE_TEMP) {
st->sensors[chan] = ltc2983_temp_new(child, st, &sensor);
} else {
dev_err(dev, "Unknown sensor type %d\n", sensor.type);
ret = -EINVAL;
goto put_child;
return dev_err_probe(dev, -EINVAL,
"Unknown sensor type %d\n",
sensor.type);
}
if (IS_ERR(st->sensors[chan])) {
dev_err(dev, "Failed to create sensor %ld",
PTR_ERR(st->sensors[chan]));
ret = PTR_ERR(st->sensors[chan]);
goto put_child;
}
if (IS_ERR(st->sensors[chan]))
return dev_err_probe(dev, PTR_ERR(st->sensors[chan]),
"Failed to create sensor\n");
/* set generic sensor parameters */
st->sensors[chan]->chan = sensor.chan;
st->sensors[chan]->type = sensor.type;
......@@ -1447,9 +1413,6 @@ static int ltc2983_parse_fw(struct ltc2983_data *st)
}
return 0;
put_child:
fwnode_handle_put(child);
return ret;
}
static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment