[PATCH 01/11] Input: iqs7222 - drop unused device node references

Jeff LaBundy
2022-09-08T13:17:09Z

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@labundy.com>
---
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