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 never calls fwnode_handle_put(). This patch adds the missing calls. Fixes: e505edaedcb9 ("Input: add support for Azoteq IQS7222A/B/C") Signed-off-by: Jeff LaBundy <jeff@xxxxxxxxxxx> --- drivers/input/misc/iqs7222.c | 134 ++++++++++++++++++++++++----------- 1 file changed, 91 insertions(+), 43 deletions(-) diff --git a/drivers/input/misc/iqs7222.c b/drivers/input/misc/iqs7222.c index b2e8097a2e6d..04c1050d845c 100644 --- a/drivers/input/misc/iqs7222.c +++ b/drivers/input/misc/iqs7222.c @@ -1703,7 +1703,7 @@ static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index) IQS7222_REG_GRP_CYCLE, IQS7222_REG_KEY_NONE); if (error) - return error; + goto put_cycle_node; if (!cycle_node) return 0; @@ -1714,17 +1714,19 @@ static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index) * CTx pins (CTx0-8). */ if (!fwnode_property_present(cycle_node, "azoteq,tx-enable")) - return 0; + goto put_cycle_node; count = fwnode_property_count_u32(cycle_node, "azoteq,tx-enable"); if (count < 0) { dev_err(&client->dev, "Failed to count %s CTx pins: %d\n", fwnode_get_name(cycle_node), count); - return count; + error = count; + goto put_cycle_node; } else if (count > ARRAY_SIZE(pins)) { dev_err(&client->dev, "Invalid number of %s CTx pins\n", fwnode_get_name(cycle_node)); - return -EINVAL; + error = -EINVAL; + goto put_cycle_node; } error = fwnode_property_read_u32_array(cycle_node, "azoteq,tx-enable", @@ -1732,7 +1734,7 @@ static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index) if (error) { dev_err(&client->dev, "Failed to read %s CTx pins: %d\n", fwnode_get_name(cycle_node), error); - return error; + goto put_cycle_node; } cycle_setup[1] &= ~GENMASK(7 + ARRAY_SIZE(pins) - 1, 7); @@ -1741,13 +1743,17 @@ static int iqs7222_parse_cycle(struct iqs7222_private *iqs7222, int cycle_index) if (pins[i] > 8) { dev_err(&client->dev, "Invalid %s CTx pin: %u\n", fwnode_get_name(cycle_node), pins[i]); - return -EINVAL; + error = -EINVAL; + goto put_cycle_node; } cycle_setup[1] |= BIT(pins[i] + 7); } - return 0; +put_cycle_node: + fwnode_handle_put(cycle_node); + + return error; } static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) @@ -1766,7 +1772,7 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) IQS7222_REG_GRP_CHAN, IQS7222_REG_KEY_NONE); if (error) - return error; + goto put_chan_node; if (!chan_node) return 0; @@ -1793,14 +1799,15 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) dev_err(&client->dev, "Failed to read %s reference channel: %d\n", fwnode_get_name(chan_node), error); - return error; + goto put_chan_node; } if (val >= ext_chan) { dev_err(&client->dev, "Invalid %s reference channel: %u\n", fwnode_get_name(chan_node), val); - return -EINVAL; + error = -EINVAL; + goto put_chan_node; } ref_setup = iqs7222->chan_setup[val]; @@ -1818,7 +1825,8 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) dev_err(&client->dev, "Invalid %s reference weight: %u\n", fwnode_get_name(chan_node), val); - return -EINVAL; + error = -EINVAL; + goto put_chan_node; } chan_setup[5] = val; @@ -1851,12 +1859,14 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) dev_err(&client->dev, "Failed to count %s CRx pins: %d\n", fwnode_get_name(chan_node), count); - return count; + error = count; + goto put_chan_node; } else if (count > ARRAY_SIZE(pins)) { dev_err(&client->dev, "Invalid number of %s CRx pins\n", fwnode_get_name(chan_node)); - return -EINVAL; + error = -EINVAL; + goto put_chan_node; } error = fwnode_property_read_u32_array(chan_node, @@ -1866,7 +1876,7 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) dev_err(&client->dev, "Failed to read %s CRx pins: %d\n", fwnode_get_name(chan_node), error); - return error; + goto put_chan_node; } chan_setup[0] &= ~GENMASK(4 + ARRAY_SIZE(pins) - 1, 4); @@ -1878,7 +1888,8 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) dev_err(&client->dev, "Invalid %s CRx pin: %u\n", fwnode_get_name(chan_node), pins[i]); - return -EINVAL; + error = -EINVAL; + goto put_chan_node; } chan_setup[0] |= BIT(pins[i] + 4 - min_crx); @@ -1897,14 +1908,18 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) error = iqs7222_parse_props(iqs7222, &event_node, chan_index, IQS7222_REG_GRP_BTN, iqs7222_kp_events[i].reg_key); - if (error) - return error; + if (error) { + fwnode_handle_put(event_node); + goto put_chan_node; + } error = iqs7222_gpio_select(iqs7222, event_node, BIT(chan_index), dev_desc->touch_link - (i ? 0 : 2)); - if (error) - return error; + if (error) { + fwnode_handle_put(event_node); + goto put_chan_node; + } if (!fwnode_property_read_u32(event_node, "azoteq,timeout-press-ms", @@ -1922,7 +1937,9 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) dev_err(&client->dev, "Invalid %s press timeout: %u\n", fwnode_get_name(chan_node), val); - return -EINVAL; + error = -EINVAL; + fwnode_handle_put(event_node); + goto put_chan_node; } *setup &= ~(U8_MAX << i * 8); @@ -1934,7 +1951,8 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) if (error) { dev_err(&client->dev, "Failed to read %s code: %d\n", fwnode_get_name(chan_node), error); - return error; + fwnode_handle_put(event_node); + goto put_chan_node; } iqs7222->kp_code[chan_index][i] = val; @@ -1948,19 +1966,24 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) dev_err(&client->dev, "Failed to read %s input type: %d\n", fwnode_get_name(chan_node), error); - return error; + fwnode_handle_put(event_node); + goto put_chan_node; } if (val != EV_KEY && val != EV_SW) { dev_err(&client->dev, "Invalid %s input type: %u\n", fwnode_get_name(chan_node), val); - return -EINVAL; + error = -EINVAL; + fwnode_handle_put(event_node); + goto put_chan_node; } iqs7222->kp_type[chan_index][i] = val; } + fwnode_handle_put(event_node); + /* * Reference channels can opt out of event reporting by using * KEY_RESERVED in place of a true key or switch code. @@ -1983,9 +2006,14 @@ static int iqs7222_parse_chan(struct iqs7222_private *iqs7222, int chan_index) * The following call handles a special pair of properties that apply * to a channel node, but reside within the button (event) group. */ - return iqs7222_parse_props(iqs7222, &chan_node, chan_index, - IQS7222_REG_GRP_BTN, - IQS7222_REG_KEY_DEBOUNCE); + error = iqs7222_parse_props(iqs7222, &chan_node, chan_index, + IQS7222_REG_GRP_BTN, + IQS7222_REG_KEY_DEBOUNCE); + +put_chan_node: + fwnode_handle_put(chan_node); + + return error; } static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) @@ -2004,7 +2032,7 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) IQS7222_REG_GRP_SLDR, IQS7222_REG_KEY_NONE); if (error) - return error; + goto put_sldr_node; if (!sldr_node) return 0; @@ -2018,11 +2046,13 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) if (count < 0) { dev_err(&client->dev, "Failed to count %s channels: %d\n", fwnode_get_name(sldr_node), count); - return count; + error = count; + goto put_sldr_node; } else if (count < 3 || count > ARRAY_SIZE(chan_sel)) { dev_err(&client->dev, "Invalid number of %s channels\n", fwnode_get_name(sldr_node)); - return -EINVAL; + error = -EINVAL; + goto put_sldr_node; } error = fwnode_property_read_u32_array(sldr_node, @@ -2031,7 +2061,7 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) if (error) { dev_err(&client->dev, "Failed to read %s channels: %d\n", fwnode_get_name(sldr_node), error); - return error; + goto put_sldr_node; } /* @@ -2052,7 +2082,8 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) if (chan_sel[i] >= ext_chan) { dev_err(&client->dev, "Invalid %s channel: %u\n", fwnode_get_name(sldr_node), chan_sel[i]); - return -EINVAL; + error = -EINVAL; + goto put_sldr_node; } /* @@ -2071,7 +2102,8 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) if (!val || val > dev_desc->sldr_res) { dev_err(&client->dev, "Invalid %s size: %u\n", fwnode_get_name(sldr_node), val); - return -EINVAL; + error = -EINVAL; + goto put_sldr_node; } if (reg_offset) { @@ -2087,7 +2119,8 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) if (val > (reg_offset ? U16_MAX : U8_MAX * 4)) { dev_err(&client->dev, "Invalid %s top speed: %u\n", fwnode_get_name(sldr_node), val); - return -EINVAL; + error = -EINVAL; + goto put_sldr_node; } if (reg_offset) { @@ -2142,8 +2175,10 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) reg_offset ? IQS7222_REG_KEY_RESERVED : iqs7222_sl_events[i].reg_key); - if (error) - return error; + if (error) { + fwnode_handle_put(event_node); + goto put_sldr_node; + } /* * The press/release event does not expose a direct GPIO link, @@ -2155,8 +2190,10 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) : sldr_setup[3 + reg_offset], i ? 1568 + sldr_index * 30 : sldr_setup[4 + reg_offset]); - if (error) - return error; + if (error) { + fwnode_handle_put(event_node); + goto put_sldr_node; + } if (!reg_offset) sldr_setup[9] |= iqs7222_sl_events[i].enable; @@ -2166,12 +2203,15 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) if (error) { dev_err(&client->dev, "Failed to read %s code: %d\n", fwnode_get_name(sldr_node), error); - return error; + fwnode_handle_put(event_node); + goto put_sldr_node; } iqs7222->sl_code[sldr_index][i] = val; input_set_capability(iqs7222->keypad, EV_KEY, val); + fwnode_handle_put(event_node); + if (!dev_desc->event_offset) continue; @@ -2192,11 +2232,16 @@ static int iqs7222_parse_sldr(struct iqs7222_private *iqs7222, int sldr_index) * The following call handles a special pair of properties that shift * to make room for a wheel enable control in the case of IQS7222C. */ - return iqs7222_parse_props(iqs7222, &sldr_node, sldr_index, - IQS7222_REG_GRP_SLDR, - dev_desc->wheel_enable ? - IQS7222_REG_KEY_WHEEL : - IQS7222_REG_KEY_NO_WHEEL); + error = iqs7222_parse_props(iqs7222, &sldr_node, sldr_index, + IQS7222_REG_GRP_SLDR, + dev_desc->wheel_enable ? + IQS7222_REG_KEY_WHEEL : + IQS7222_REG_KEY_NO_WHEEL); + +put_sldr_node: + fwnode_handle_put(sldr_node); + + return error; } static int iqs7222_parse_all(struct iqs7222_private *iqs7222) @@ -2232,6 +2277,9 @@ static int iqs7222_parse_all(struct iqs7222_private *iqs7222) error = iqs7222_parse_props(iqs7222, &gpio_node, i, IQS7222_REG_GRP_GPIO, IQS7222_REG_KEY_NONE); + if (gpio_node) + fwnode_handle_put(gpio_node); + if (error) return error; -- 2.25.1