summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Gu <ustc.gu@gmail.com>2026-04-28 21:18:21 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-05-21 16:40:54 +0200
commitca927fc45e4906bdab42426da044fba4d3584f34 (patch)
treee2d28981ea7e2fefb37ec2e71308bffcb4261d05
parentc1a0ecbf32c4b397353204e2ec94c5bb9f3300ed (diff)
usb: typec: fusb302: Fix resource leak when devm_drm_dp_hpd_bridge_add() fails
If devm_drm_dp_hpd_bridge_add() fails during fusb302_probe(), the original code returned directly without cleaning up the resources. Move bridge registration before the IRQ is requested and route bridge registration failures through the existing TCPM unregister and fwnode cleanup path. Fixes: 5d79c525405d ("usb: typec: fusb302: add DRM DP HPD bridge support") Signed-off-by: Felix Gu <ustc.gu@gmail.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com> Link: https://patch.msgid.link/20260428-fusb-v2-1-aa3b5942cabb@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/typec/tcpm/fusb302.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/usb/typec/tcpm/fusb302.c b/drivers/usb/typec/tcpm/fusb302.c
index 889c4c29c1b8..9ab1277b7ed1 100644
--- a/drivers/usb/typec/tcpm/fusb302.c
+++ b/drivers/usb/typec/tcpm/fusb302.c
@@ -1751,19 +1751,22 @@ static int fusb302_probe(struct i2c_client *client)
bridge_dev = devm_drm_dp_hpd_bridge_alloc(chip->dev, to_of_node(chip->tcpc_dev.fwnode));
if (IS_ERR(bridge_dev)) {
- ret = PTR_ERR(bridge_dev);
- dev_err_probe(chip->dev, ret, "failed to alloc bridge\n");
- goto destroy_workqueue;
+ ret = dev_err_probe(chip->dev, PTR_ERR(bridge_dev),
+ "failed to alloc bridge\n");
+ goto fwnode_put;
}
chip->tcpm_port = tcpm_register_port(&client->dev, &chip->tcpc_dev);
if (IS_ERR(chip->tcpm_port)) {
- fwnode_handle_put(chip->tcpc_dev.fwnode);
ret = dev_err_probe(dev, PTR_ERR(chip->tcpm_port),
"cannot register tcpm port\n");
- goto destroy_workqueue;
+ goto fwnode_put;
}
+ ret = devm_drm_dp_hpd_bridge_add(chip->dev, bridge_dev);
+ if (ret)
+ goto tcpm_unregister_port;
+
ret = request_threaded_irq(chip->gpio_int_n_irq, NULL, fusb302_irq_intn,
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
"fsc_interrupt_int_n", chip);
@@ -1774,14 +1777,11 @@ static int fusb302_probe(struct i2c_client *client)
enable_irq_wake(chip->gpio_int_n_irq);
i2c_set_clientdata(client, chip);
- ret = devm_drm_dp_hpd_bridge_add(chip->dev, bridge_dev);
- if (ret)
- return ret;
-
- return ret;
+ return 0;
tcpm_unregister_port:
tcpm_unregister_port(chip->tcpm_port);
+fwnode_put:
fwnode_handle_put(chip->tcpc_dev.fwnode);
destroy_workqueue:
fusb302_debugfs_exit(chip);