[PATCH v2] usb: typec: fusb302: Fix resource leak when devm_drm_dp_hpd_bridge_add() fails

Felix Gu posted 1 patch 1 month, 2 weeks ago
drivers/usb/typec/tcpm/fusb302.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
[PATCH v2] usb: typec: fusb302: Fix resource leak when devm_drm_dp_hpd_bridge_add() fails
Posted by Felix Gu 1 month, 2 weeks ago
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>
---
Changes in v2:
- Fix Heikki's comment.
- Link to v1: https://lore.kernel.org/r/20260421-fusb-v1-1-0a9dd64e785b@gmail.com
---
 drivers/usb/typec/tcpm/fusb302.c | 20 ++++++++++----------
 1 file 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);

---
base-commit: 97e797263a5e963da3d1e66e743fd518567dfe37
change-id: 20260421-fusb-0e7085ce431a

Best regards,
-- 
Felix Gu <ustc.gu@gmail.com>
Re: [PATCH v2] usb: typec: fusb302: Fix resource leak when devm_drm_dp_hpd_bridge_add() fails
Posted by Sebastian Reichel 1 month, 2 weeks ago
Hi,

On Tue, Apr 28, 2026 at 09:18:21PM +0800, Felix Gu wrote:
> 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>
> ---
> Changes in v2:
> - Fix Heikki's comment.
> - Link to v1: https://lore.kernel.org/r/20260421-fusb-v1-1-0a9dd64e785b@gmail.com
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

-- Sebastian

>  drivers/usb/typec/tcpm/fusb302.c | 20 ++++++++++----------
>  1 file 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);
> 
> ---
> base-commit: 97e797263a5e963da3d1e66e743fd518567dfe37
> change-id: 20260421-fusb-0e7085ce431a
> 
> Best regards,
> -- 
> Felix Gu <ustc.gu@gmail.com>
> 
Re: [PATCH v2] usb: typec: fusb302: Fix resource leak when devm_drm_dp_hpd_bridge_add() fails
Posted by Heikki Krogerus 1 month, 2 weeks ago
On Tue, Apr 28, 2026 at 09:18:21PM +0800, Felix Gu wrote:
> 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>

> ---
> Changes in v2:
> - Fix Heikki's comment.
> - Link to v1: https://lore.kernel.org/r/20260421-fusb-v1-1-0a9dd64e785b@gmail.com
> ---
>  drivers/usb/typec/tcpm/fusb302.c | 20 ++++++++++----------
>  1 file 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);
> 
> ---
> base-commit: 97e797263a5e963da3d1e66e743fd518567dfe37
> change-id: 20260421-fusb-0e7085ce431a
> 
> Best regards,
> -- 
> Felix Gu <ustc.gu@gmail.com>

-- 
heikki