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: Nuno Sa <nuno.sa@analog.com> Link: https://lore.kernel.org/r/20240224123215.161469-2-jic23@kernel.org Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user