The sparx5_stats_init() function starts a worker thread which needs to be cleaned up. Move the initialization code to probe() and add a deinit() function for proper teardown. Also, rename sparx_stats_init() to sparx5_stats_init() to match the driver naming convention. Signed-off-by: Daniel Machon --- drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c | 9 ++++++++- drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 16 ++++++++++------ drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 3 ++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c index 049541eeaae0..d42c57bead89 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ethtool.c @@ -1244,7 +1244,7 @@ const struct ethtool_ops sparx5_ethtool_ops = { .set_pauseparam = sparx5_set_pauseparam, }; -int sparx_stats_init(struct sparx5 *sparx5) +int sparx5_stats_init(struct sparx5 *sparx5) { const struct sparx5_consts *consts = sparx5->data->consts; char queue_name[32]; @@ -1278,3 +1278,10 @@ int sparx_stats_init(struct sparx5 *sparx5) return 0; } + +void sparx5_stats_deinit(struct sparx5 *sparx5) +{ + cancel_delayed_work_sync(&sparx5->stats_work); + destroy_workqueue(sparx5->stats_queue); + mutex_destroy(&sparx5->queue_stats_lock); +} diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c index 97dd3cea0554..17748854ca48 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c @@ -748,11 +748,6 @@ static int sparx5_start(struct sparx5 *sparx5) if (err) return err; - /* Init stats */ - err = sparx_stats_init(sparx5); - if (err) - return err; - mutex_init(&sparx5->mdb_lock); INIT_LIST_HEAD(&sparx5->mdb_entries); @@ -976,12 +971,18 @@ static int mchp_sparx5_probe(struct platform_device *pdev) goto cleanup_vcap; } + err = sparx5_stats_init(sparx5); + if (err) { + dev_err(sparx5->dev, "Failed to initialize stats\n"); + goto cleanup_mact; + } + INIT_LIST_HEAD(&sparx5->mall_entries); err = sparx5_register_netdevs(sparx5); if (err) { dev_err(sparx5->dev, "Failed to register net devices\n"); - goto cleanup_mact; + goto cleanup_stats; } err = sparx5_register_notifier_blocks(sparx5); @@ -1005,6 +1006,8 @@ static int mchp_sparx5_probe(struct platform_device *pdev) sparx5_unregister_notifier_blocks(sparx5); cleanup_netdevs: sparx5_unregister_netdevs(sparx5); +cleanup_stats: + sparx5_stats_deinit(sparx5); cleanup_mact: sparx5_mact_deinit(sparx5); cleanup_vcap: @@ -1040,6 +1043,7 @@ static void mchp_sparx5_remove(struct platform_device *pdev) } sparx5_unregister_notifier_blocks(sparx5); sparx5_unregister_netdevs(sparx5); + sparx5_stats_deinit(sparx5); sparx5_mact_deinit(sparx5); sparx5_vcap_deinit(sparx5); sparx5_ptp_deinit(sparx5); diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h index e4c39cca7b26..97d53e229ad6 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h @@ -514,7 +514,8 @@ enum sparx5_cal_bw sparx5_get_port_cal_speed(struct sparx5 *sparx5, u32 portno); /* sparx5_ethtool.c */ void sparx5_get_stats64(struct net_device *ndev, struct rtnl_link_stats64 *stats); -int sparx_stats_init(struct sparx5 *sparx5); +int sparx5_stats_init(struct sparx5 *sparx5); +void sparx5_stats_deinit(struct sparx5 *sparx5); /* sparx5_dcb.c */ #ifdef CONFIG_SPARX5_DCB -- 2.34.1