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: 5d79c52540 ("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>
This commit is contained in:
Felix Gu 2026-04-28 21:18:21 +08:00 committed by Greg Kroah-Hartman
parent c1a0ecbf32
commit ca927fc45e

View File

@ -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);