On Wed, Apr 19, 2023 at 04:27:35PM +0800, Jiawen Wu wrote: > + ret = txgbe_sfp_register(txgbe); > + if (ret) { > + wx_err(txgbe->wx, "failed to register sfp\n"); > + goto err; > + } The usual error handling pattern is to jump to specific labels within the error unwind code path (which duplicates the normal teardown path except for the first operation), rather than calling the single cleanup function - here txgbe_remove_phy() - and filling that with "if" conditions. Normally (at least in the networking layer except for Qdiscs, that's all I know), one would expect that if txgbe_init_phy() fails, txgbe_remove_phy() is never called. So, given that expectation, txgbe->sfp_dev would never be NULL. > + > return 0; > > err: > @@ -131,6 +156,8 @@ int txgbe_init_phy(struct txgbe *txgbe) > > void txgbe_remove_phy(struct txgbe *txgbe) > { > + if (txgbe->sfp_dev) > + platform_device_unregister(txgbe->sfp_dev); > if (txgbe->i2c_dev) > platform_device_unregister(txgbe->i2c_dev); > > diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h > index 771aefbc7c80..aa94c4fce311 100644 > --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h > +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h > @@ -149,6 +149,7 @@ struct txgbe_nodes { > struct txgbe { > struct wx *wx; > struct txgbe_nodes nodes; > + struct platform_device *sfp_dev; > struct platform_device *i2c_dev; > }; > > -- > 2.27.0 >