Each call to device/fwnode_get_named_child_node() must be matched with a call to fwnode_handle_put() once the corresponding node is no longer in use. This ensures a reference count remains balanced in the case of dynamic device tree support. Currently, the driver does not call fwnode_handle_put() on nested event nodes. This patch solves this problem by adding the missing instances of fwnode_handle_put(). As part of this change, the logic which parses each channel's key code is gently refactored in order to reduce the number of places from which fwnode_handle_put() is called. Fixes: 04e49867fad1 ("Input: add support for Azoteq IQS269A") Signed-off-by: Jeff LaBundy <jeff@xxxxxxxxxxx> --- drivers/input/misc/iqs269a.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/input/misc/iqs269a.c b/drivers/input/misc/iqs269a.c index a348247d3d38..5620a009bf55 100644 --- a/drivers/input/misc/iqs269a.c +++ b/drivers/input/misc/iqs269a.c @@ -694,7 +694,8 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269, dev_err(&client->dev, "Invalid channel %u threshold: %u\n", reg, val); - return -EINVAL; + error = -EINVAL; + break; } ch_reg->thresh[iqs269_events[i].th_offs] = val; @@ -707,7 +708,8 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269, dev_err(&client->dev, "Invalid channel %u hysteresis: %u\n", reg, val); - return -EINVAL; + error = -EINVAL; + break; } if (i == IQS269_EVENT_DEEP_DN || @@ -721,8 +723,19 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269, } } - if (fwnode_property_read_u32(ev_node, "linux,code", &val)) + error = fwnode_property_read_u32(ev_node, "linux,code", &val); + if (error && error != -EINVAL) { + dev_err(&client->dev, + "Failed to read channel %u code: %d\n", reg, + error); + break; + } + + fwnode_handle_put(ev_node); + if (error) { + error = 0; continue; + } switch (reg) { case IQS269_CHx_HALL_ACTIVE: @@ -744,7 +757,10 @@ static int iqs269_parse_chan(struct iqs269_private *iqs269, iqs269->sys_reg.event_mask &= ~iqs269_events[i].mask; } - return 0; + if (error) + fwnode_handle_put(ev_node); + + return error; } static int iqs269_parse_prop(struct iqs269_private *iqs269) -- 2.34.1