| From da4410d4078ba4ead9d6f1027d6db77c5a74ecee Mon Sep 17 00:00:00 2001 |
| From: Tobias Jordan <kernel@cdqe.de> |
| Date: Sat, 26 Sep 2020 18:19:46 +0200 |
| Subject: iio: adc: gyroadc: fix leak of device node iterator |
| |
| From: Tobias Jordan <kernel@cdqe.de> |
| |
| commit da4410d4078ba4ead9d6f1027d6db77c5a74ecee upstream. |
| |
| Add missing of_node_put calls when exiting the for_each_child_of_node |
| loop in rcar_gyroadc_parse_subdevs early. |
| |
| Also add goto-exception handling for the error paths in that loop. |
| |
| Fixes: 059c53b32329 ("iio: adc: Add Renesas GyroADC driver") |
| Signed-off-by: Tobias Jordan <kernel@cdqe.de> |
| Link: https://lore.kernel.org/r/20200926161946.GA10240@agrajag.zerfleddert.de |
| Cc: <Stable@vger.kernel.org> |
| Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/iio/adc/rcar-gyroadc.c | 21 +++++++++++++++------ |
| 1 file changed, 15 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/iio/adc/rcar-gyroadc.c |
| +++ b/drivers/iio/adc/rcar-gyroadc.c |
| @@ -357,7 +357,7 @@ static int rcar_gyroadc_parse_subdevs(st |
| num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_3); |
| break; |
| default: |
| - return -EINVAL; |
| + goto err_e_inval; |
| } |
| |
| /* |
| @@ -374,7 +374,7 @@ static int rcar_gyroadc_parse_subdevs(st |
| dev_err(dev, |
| "Failed to get child reg property of ADC \"%pOFn\".\n", |
| child); |
| - return ret; |
| + goto err_of_node_put; |
| } |
| |
| /* Channel number is too high. */ |
| @@ -382,7 +382,7 @@ static int rcar_gyroadc_parse_subdevs(st |
| dev_err(dev, |
| "Only %i channels supported with %pOFn, but reg = <%i>.\n", |
| num_channels, child, reg); |
| - return -EINVAL; |
| + goto err_e_inval; |
| } |
| } |
| |
| @@ -391,7 +391,7 @@ static int rcar_gyroadc_parse_subdevs(st |
| dev_err(dev, |
| "Channel %i uses different ADC mode than the rest.\n", |
| reg); |
| - return -EINVAL; |
| + goto err_e_inval; |
| } |
| |
| /* Channel is valid, grab the regulator. */ |
| @@ -401,7 +401,8 @@ static int rcar_gyroadc_parse_subdevs(st |
| if (IS_ERR(vref)) { |
| dev_dbg(dev, "Channel %i 'vref' supply not connected.\n", |
| reg); |
| - return PTR_ERR(vref); |
| + ret = PTR_ERR(vref); |
| + goto err_of_node_put; |
| } |
| |
| priv->vref[reg] = vref; |
| @@ -425,8 +426,10 @@ static int rcar_gyroadc_parse_subdevs(st |
| * attached to the GyroADC at a time, so if we found it, |
| * we can stop parsing here. |
| */ |
| - if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) |
| + if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) { |
| + of_node_put(child); |
| break; |
| + } |
| } |
| |
| if (first) { |
| @@ -435,6 +438,12 @@ static int rcar_gyroadc_parse_subdevs(st |
| } |
| |
| return 0; |
| + |
| +err_e_inval: |
| + ret = -EINVAL; |
| +err_of_node_put: |
| + of_node_put(child); |
| + return ret; |
| } |
| |
| static void rcar_gyroadc_deinit_supplies(struct iio_dev *indio_dev) |