diff options
author | Lu Hongfei <luhongfei@vivo.com> | 2023-06-12 21:34:52 +0800 |
---|---|---|
committer | Bjorn Andersson <andersson@kernel.org> | 2023-09-19 11:34:12 -0700 |
commit | 5692aeea5bcb9331e956628c3bc8fc9afcc9765d (patch) | |
tree | 2ea02f064fb9b78d4e969257c8258d1845d4cc45 /drivers/soc/qcom | |
parent | d74612b6da61aeb32e81bcf762b8be4e3c41bda5 (diff) | |
download | linux-5692aeea5bcb9331e956628c3bc8fc9afcc9765d.tar.gz linux-5692aeea5bcb9331e956628c3bc8fc9afcc9765d.tar.bz2 linux-5692aeea5bcb9331e956628c3bc8fc9afcc9765d.zip |
soc: qcom: pmic: Fix resource leaks in a device_for_each_child_node() loop
The device_for_each_child_node loop should call fwnode_handle_put()
before return in the error cases, to avoid resource leaks.
Let's fix this bug in pmic_glink_altmode_probe().
Signed-off-by: Lu Hongfei <luhongfei@vivo.com>
Link: https://lore.kernel.org/r/20230612133452.47315-1-luhongfei@vivo.com
[bjorn: Rebased patch, moved fw_handle_put() from jump target into the loop]
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Diffstat (limited to 'drivers/soc/qcom')
-rw-r--r-- | drivers/soc/qcom/pmic_glink_altmode.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c index d05e0d6edf49..9569d999391d 100644 --- a/drivers/soc/qcom/pmic_glink_altmode.c +++ b/drivers/soc/qcom/pmic_glink_altmode.c @@ -444,6 +444,7 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev, ret = fwnode_property_read_u32(fwnode, "reg", &port); if (ret < 0) { dev_err(dev, "missing reg property of %pOFn\n", fwnode); + fwnode_handle_put(fwnode); return ret; } @@ -454,6 +455,7 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev, if (altmode->ports[port].altmode) { dev_err(dev, "multiple connector definition for port %u\n", port); + fwnode_handle_put(fwnode); return -EINVAL; } @@ -468,45 +470,59 @@ static int pmic_glink_altmode_probe(struct auxiliary_device *adev, alt_port->bridge.type = DRM_MODE_CONNECTOR_USB; ret = devm_drm_bridge_add(dev, &alt_port->bridge); - if (ret) + if (ret) { + fwnode_handle_put(fwnode); return ret; + } alt_port->dp_alt.svid = USB_TYPEC_DP_SID; alt_port->dp_alt.mode = USB_TYPEC_DP_MODE; alt_port->dp_alt.active = 1; alt_port->typec_mux = fwnode_typec_mux_get(fwnode); - if (IS_ERR(alt_port->typec_mux)) + if (IS_ERR(alt_port->typec_mux)) { + fwnode_handle_put(fwnode); return dev_err_probe(dev, PTR_ERR(alt_port->typec_mux), "failed to acquire mode-switch for port: %d\n", port); + } ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_mux, alt_port->typec_mux); - if (ret) + if (ret) { + fwnode_handle_put(fwnode); return ret; + } alt_port->typec_retimer = fwnode_typec_retimer_get(fwnode); - if (IS_ERR(alt_port->typec_retimer)) + if (IS_ERR(alt_port->typec_retimer)) { + fwnode_handle_put(fwnode); return dev_err_probe(dev, PTR_ERR(alt_port->typec_retimer), "failed to acquire retimer-switch for port: %d\n", port); + } ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_retimer, alt_port->typec_retimer); - if (ret) + if (ret) { + fwnode_handle_put(fwnode); return ret; + } alt_port->typec_switch = fwnode_typec_switch_get(fwnode); - if (IS_ERR(alt_port->typec_switch)) + if (IS_ERR(alt_port->typec_switch)) { + fwnode_handle_put(fwnode); return dev_err_probe(dev, PTR_ERR(alt_port->typec_switch), "failed to acquire orientation-switch for port: %d\n", port); + } ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_switch, alt_port->typec_switch); - if (ret) + if (ret) { + fwnode_handle_put(fwnode); return ret; + } } altmode->client = devm_pmic_glink_register_client(dev, |