* [PATCH net-next v2 1/9] net: sparx5: move netdev and notifier block registration to probe
2026-02-27 14:56 [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths Daniel Machon
@ 2026-02-27 14:56 ` Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 2/9] net: sparx5: move VCAP initialization " Daniel Machon
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Daniel Machon @ 2026-02-27 14:56 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Steen Hegelund, UNGLinuxDriver, Richard Cochran,
maxime.chevallier, rmk+kernel
Cc: netdev, linux-arm-kernel, linux-kernel
Move netdev registration and notifier block registration from
sparx5_start() to probe(). This allows proper cleanup via goto-based
error labels in probe().
Also, remove the sparx5_cleanup_ports() helper as its functionality is now
split between sparx5_unregister_netdevs() and sparx5_destroy_netdevs()
called at appropriate points.
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
.../net/ethernet/microchip/sparx5/sparx5_main.c | 41 +++++++++++-----------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index 582145713cfd..0ca4001a3667 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -773,20 +773,11 @@ static int sparx5_start(struct sparx5 *sparx5)
mutex_init(&sparx5->mdb_lock);
INIT_LIST_HEAD(&sparx5->mdb_entries);
- err = sparx5_register_netdevs(sparx5);
- if (err)
- return err;
-
sparx5_board_init(sparx5);
- err = sparx5_register_notifier_blocks(sparx5);
- if (err)
- return err;
err = sparx5_vcap_init(sparx5);
- if (err) {
- sparx5_unregister_notifier_blocks(sparx5);
+ if (err)
return err;
- }
/* Start Frame DMA with fallback to register based INJ/XTR */
err = -ENXIO;
@@ -835,12 +826,6 @@ static int sparx5_start(struct sparx5 *sparx5)
return err;
}
-static void sparx5_cleanup_ports(struct sparx5 *sparx5)
-{
- sparx5_unregister_netdevs(sparx5);
- sparx5_destroy_netdevs(sparx5);
-}
-
static int mchp_sparx5_probe(struct platform_device *pdev)
{
struct initial_port_config *configs, *config;
@@ -1020,10 +1005,26 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
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_ptp;
+ }
+
+ err = sparx5_register_notifier_blocks(sparx5);
+ if (err) {
+ dev_err(sparx5->dev, "Failed to register notifier blocks\n");
+ goto cleanup_netdevs;
+ }
+
goto cleanup_config;
+cleanup_netdevs:
+ sparx5_unregister_netdevs(sparx5);
+cleanup_ptp:
+ sparx5_ptp_deinit(sparx5);
cleanup_ports:
- sparx5_cleanup_ports(sparx5);
+ sparx5_destroy_netdevs(sparx5);
if (sparx5->mact_queue)
destroy_workqueue(sparx5->mact_queue);
cleanup_config:
@@ -1047,12 +1048,12 @@ static void mchp_sparx5_remove(struct platform_device *pdev)
disable_irq(sparx5->fdma_irq);
sparx5->fdma_irq = -ENXIO;
}
+ sparx5_unregister_notifier_blocks(sparx5);
+ sparx5_unregister_netdevs(sparx5);
sparx5_ptp_deinit(sparx5);
ops->fdma_deinit(sparx5);
- sparx5_cleanup_ports(sparx5);
sparx5_vcap_destroy(sparx5);
- /* Unregister netdevs */
- sparx5_unregister_notifier_blocks(sparx5);
+ sparx5_destroy_netdevs(sparx5);
destroy_workqueue(sparx5->mact_queue);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH net-next v2 2/9] net: sparx5: move VCAP initialization to probe
2026-02-27 14:56 [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 1/9] net: sparx5: move netdev and notifier block registration to probe Daniel Machon
@ 2026-02-27 14:56 ` Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 3/9] net: sparx5: move MAC table initialization and add deinit function Daniel Machon
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Daniel Machon @ 2026-02-27 14:56 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Steen Hegelund, UNGLinuxDriver, Richard Cochran,
maxime.chevallier, rmk+kernel
Cc: netdev, linux-arm-kernel, linux-kernel
Move the VCAP initialization code from sparx5_start() to probe(). Add
proper error handling with a cleanup_vcap label and sparx5_vcap_deinit()
call.
Also, rename sparx5_vcap_destroy() to sparx5_vcap_deinit() to stay
consistent with the naming.
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 16 ++++++++++------
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 2 +-
drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c | 2 +-
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index 0ca4001a3667..fbd75423f2a7 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -775,10 +775,6 @@ static int sparx5_start(struct sparx5 *sparx5)
sparx5_board_init(sparx5);
- err = sparx5_vcap_init(sparx5);
- if (err)
- return err;
-
/* Start Frame DMA with fallback to register based INJ/XTR */
err = -ENXIO;
if (sparx5->fdma_irq >= 0) {
@@ -1003,12 +999,18 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
goto cleanup_ports;
}
+ err = sparx5_vcap_init(sparx5);
+ if (err) {
+ dev_err(sparx5->dev, "Failed to initialize VCAP\n");
+ goto cleanup_ptp;
+ }
+
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_ptp;
+ goto cleanup_vcap;
}
err = sparx5_register_notifier_blocks(sparx5);
@@ -1021,6 +1023,8 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
cleanup_netdevs:
sparx5_unregister_netdevs(sparx5);
+cleanup_vcap:
+ sparx5_vcap_deinit(sparx5);
cleanup_ptp:
sparx5_ptp_deinit(sparx5);
cleanup_ports:
@@ -1050,9 +1054,9 @@ static void mchp_sparx5_remove(struct platform_device *pdev)
}
sparx5_unregister_notifier_blocks(sparx5);
sparx5_unregister_netdevs(sparx5);
+ sparx5_vcap_deinit(sparx5);
sparx5_ptp_deinit(sparx5);
ops->fdma_deinit(sparx5);
- sparx5_vcap_destroy(sparx5);
sparx5_destroy_netdevs(sparx5);
destroy_workqueue(sparx5->mact_queue);
}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index fe7d8bcc0cd9..6a069434fca6 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -563,7 +563,7 @@ void sparx5_get_hwtimestamp(struct sparx5 *sparx5,
/* sparx5_vcap_impl.c */
int sparx5_vcap_init(struct sparx5 *sparx5);
-void sparx5_vcap_destroy(struct sparx5 *sparx5);
+void sparx5_vcap_deinit(struct sparx5 *sparx5);
/* sparx5_pgid.c */
enum sparx5_pgid_type {
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
index 25066ddb8d4d..9b4ea3e22ef8 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c
@@ -2083,7 +2083,7 @@ int sparx5_vcap_init(struct sparx5 *sparx5)
return err;
}
-void sparx5_vcap_destroy(struct sparx5 *sparx5)
+void sparx5_vcap_deinit(struct sparx5 *sparx5)
{
struct vcap_control *ctrl = sparx5->vcap_ctrl;
struct vcap_admin *admin, *admin_next;
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH net-next v2 3/9] net: sparx5: move MAC table initialization and add deinit function
2026-02-27 14:56 [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 1/9] net: sparx5: move netdev and notifier block registration to probe Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 2/9] net: sparx5: move VCAP initialization " Daniel Machon
@ 2026-02-27 14:56 ` Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 4/9] net: sparx5: move stats " Daniel Machon
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Daniel Machon @ 2026-02-27 14:56 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Steen Hegelund, UNGLinuxDriver, Richard Cochran,
maxime.chevallier, rmk+kernel
Cc: netdev, linux-arm-kernel, linux-kernel
Consolidate all MAC table initialization from sparx5_start() into
sparx5_mact_init(), move it to probe(), and add a deinit function for
proper teardown.
Also, make sparx5_mact_pull_work() static since it is only used within
sparx5_mactable.c.
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
.../ethernet/microchip/sparx5/sparx5_mactable.c | 34 +++++++++++++++++--
.../net/ethernet/microchip/sparx5/sparx5_main.c | 39 ++++++----------------
.../net/ethernet/microchip/sparx5/sparx5_main.h | 4 +--
3 files changed, 44 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
index f5584244612c..2bf9c5f64151 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_mactable.c
@@ -419,7 +419,7 @@ static void sparx5_mact_handle_entry(struct sparx5 *sparx5,
true);
}
-void sparx5_mact_pull_work(struct work_struct *work)
+static void sparx5_mact_pull_work(struct work_struct *work)
{
struct delayed_work *del_work = to_delayed_work(work);
struct sparx5 *sparx5 = container_of(del_work, struct sparx5,
@@ -489,8 +489,10 @@ void sparx5_set_ageing(struct sparx5 *sparx5, int msecs)
LRN_AUTOAGE_CFG(0));
}
-void sparx5_mact_init(struct sparx5 *sparx5)
+int sparx5_mact_init(struct sparx5 *sparx5)
{
+ char queue_name[32];
+
mutex_init(&sparx5->lock);
/* Flush MAC table */
@@ -502,4 +504,32 @@ void sparx5_mact_init(struct sparx5 *sparx5)
dev_warn(sparx5->dev, "MAC flush error\n");
sparx5_set_ageing(sparx5, BR_DEFAULT_AGEING_TIME / HZ * 1000);
+
+ /* Add host mode BC address (points only to CPU) */
+ sparx5_mact_learn(sparx5, sparx5_get_pgid(sparx5, PGID_CPU),
+ (unsigned char[]){0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+ NULL_VID);
+
+ mutex_init(&sparx5->mdb_lock);
+ INIT_LIST_HEAD(&sparx5->mdb_entries);
+ mutex_init(&sparx5->mact_lock);
+ INIT_LIST_HEAD(&sparx5->mact_entries);
+ snprintf(queue_name, sizeof(queue_name), "%s-mact",
+ dev_name(sparx5->dev));
+ sparx5->mact_queue = create_singlethread_workqueue(queue_name);
+ if (!sparx5->mact_queue)
+ return -ENOMEM;
+
+ INIT_DELAYED_WORK(&sparx5->mact_work, sparx5_mact_pull_work);
+ queue_delayed_work(sparx5->mact_queue, &sparx5->mact_work,
+ SPX5_MACT_PULL_DELAY);
+
+ return 0;
+}
+
+void sparx5_mact_deinit(struct sparx5 *sparx5)
+{
+ cancel_delayed_work_sync(&sparx5->mact_work);
+ destroy_workqueue(sparx5->mact_queue);
+ mutex_destroy(&sparx5->mact_lock);
}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index fbd75423f2a7..4271f4a29cad 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -685,10 +685,8 @@ static void sparx5_board_init(struct sparx5 *sparx5)
static int sparx5_start(struct sparx5 *sparx5)
{
- u8 broadcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const struct sparx5_consts *consts = sparx5->data->consts;
const struct sparx5_ops *ops = sparx5->data->ops;
- char queue_name[32];
u32 idx;
int err;
@@ -728,19 +726,12 @@ static int sparx5_start(struct sparx5 *sparx5)
ANA_CL_FILTER_CTRL_FORCE_FCS_UPDATE_ENA,
sparx5, ANA_CL_FILTER_CTRL(idx));
- /* Init MAC table, ageing */
- sparx5_mact_init(sparx5);
-
/* Init PGID table arbitrator */
sparx5_pgid_init(sparx5);
/* Setup VLANs */
sparx5_vlan_init(sparx5);
- /* Add host mode BC address (points only to CPU) */
- sparx5_mact_learn(sparx5, sparx5_get_pgid(sparx5, PGID_CPU), broadcast,
- NULL_VID);
-
/* Enable queue limitation watermarks */
sparx5_qlim_set(sparx5);
@@ -757,22 +748,6 @@ static int sparx5_start(struct sparx5 *sparx5)
if (err)
return err;
- /* Init mact_sw struct */
- mutex_init(&sparx5->mact_lock);
- INIT_LIST_HEAD(&sparx5->mact_entries);
- snprintf(queue_name, sizeof(queue_name), "%s-mact",
- dev_name(sparx5->dev));
- sparx5->mact_queue = create_singlethread_workqueue(queue_name);
- if (!sparx5->mact_queue)
- return -ENOMEM;
-
- INIT_DELAYED_WORK(&sparx5->mact_work, sparx5_mact_pull_work);
- queue_delayed_work(sparx5->mact_queue, &sparx5->mact_work,
- SPX5_MACT_PULL_DELAY);
-
- mutex_init(&sparx5->mdb_lock);
- INIT_LIST_HEAD(&sparx5->mdb_entries);
-
sparx5_board_init(sparx5);
/* Start Frame DMA with fallback to register based INJ/XTR */
@@ -1005,12 +980,18 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
goto cleanup_ptp;
}
+ err = sparx5_mact_init(sparx5);
+ if (err) {
+ dev_err(sparx5->dev, "Failed to initialize MAC table\n");
+ goto cleanup_vcap;
+ }
+
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_vcap;
+ goto cleanup_mact;
}
err = sparx5_register_notifier_blocks(sparx5);
@@ -1023,14 +1004,14 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
cleanup_netdevs:
sparx5_unregister_netdevs(sparx5);
+cleanup_mact:
+ sparx5_mact_deinit(sparx5);
cleanup_vcap:
sparx5_vcap_deinit(sparx5);
cleanup_ptp:
sparx5_ptp_deinit(sparx5);
cleanup_ports:
sparx5_destroy_netdevs(sparx5);
- if (sparx5->mact_queue)
- destroy_workqueue(sparx5->mact_queue);
cleanup_config:
kfree(configs);
cleanup_pnode:
@@ -1054,11 +1035,11 @@ static void mchp_sparx5_remove(struct platform_device *pdev)
}
sparx5_unregister_notifier_blocks(sparx5);
sparx5_unregister_netdevs(sparx5);
+ sparx5_mact_deinit(sparx5);
sparx5_vcap_deinit(sparx5);
sparx5_ptp_deinit(sparx5);
ops->fdma_deinit(sparx5);
sparx5_destroy_netdevs(sparx5);
- destroy_workqueue(sparx5->mact_queue);
}
static const struct sparx5_regs sparx5_regs = {
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index 6a069434fca6..e4c39cca7b26 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -470,7 +470,6 @@ void sparx5_fdma_reload(struct sparx5 *sparx5, struct fdma *fdma);
void sparx5_fdma_injection_mode(struct sparx5 *sparx5);
/* sparx5_mactable.c */
-void sparx5_mact_pull_work(struct work_struct *work);
int sparx5_mact_learn(struct sparx5 *sparx5, int port,
const unsigned char mac[ETH_ALEN], u16 vid);
bool sparx5_mact_getnext(struct sparx5 *sparx5,
@@ -489,7 +488,8 @@ int sparx5_del_mact_entry(struct sparx5 *sparx5,
int sparx5_mc_sync(struct net_device *dev, const unsigned char *addr);
int sparx5_mc_unsync(struct net_device *dev, const unsigned char *addr);
void sparx5_set_ageing(struct sparx5 *sparx5, int msecs);
-void sparx5_mact_init(struct sparx5 *sparx5);
+int sparx5_mact_init(struct sparx5 *sparx5);
+void sparx5_mact_deinit(struct sparx5 *sparx5);
/* sparx5_vlan.c */
void sparx5_pgid_update_mask(struct sparx5_port *port, int pgid, bool enable);
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH net-next v2 4/9] net: sparx5: move stats initialization and add deinit function
2026-02-27 14:56 [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths Daniel Machon
` (2 preceding siblings ...)
2026-02-27 14:56 ` [PATCH net-next v2 3/9] net: sparx5: move MAC table initialization and add deinit function Daniel Machon
@ 2026-02-27 14:56 ` Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 5/9] net: sparx5: move calendar initialization to probe Daniel Machon
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Daniel Machon @ 2026-02-27 14:56 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Steen Hegelund, UNGLinuxDriver, Richard Cochran,
maxime.chevallier, rmk+kernel
Cc: netdev, linux-arm-kernel, linux-kernel
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 <daniel.machon@microchip.com>
---
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 4271f4a29cad..bcc7b895fad6 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -743,11 +743,6 @@ static int sparx5_start(struct sparx5 *sparx5)
if (err)
return err;
- /* Init stats */
- err = sparx_stats_init(sparx5);
- if (err)
- return err;
-
sparx5_board_init(sparx5);
/* Start Frame DMA with fallback to register based INJ/XTR */
@@ -986,12 +981,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);
@@ -1004,6 +1005,8 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
cleanup_netdevs:
sparx5_unregister_netdevs(sparx5);
+cleanup_stats:
+ sparx5_stats_deinit(sparx5);
cleanup_mact:
sparx5_mact_deinit(sparx5);
cleanup_vcap:
@@ -1035,6 +1038,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
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH net-next v2 5/9] net: sparx5: move calendar initialization to probe
2026-02-27 14:56 [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths Daniel Machon
` (3 preceding siblings ...)
2026-02-27 14:56 ` [PATCH net-next v2 4/9] net: sparx5: move stats " Daniel Machon
@ 2026-02-27 14:56 ` Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 6/9] net: sparx5: move remaining init functions from start() to probe() Daniel Machon
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Daniel Machon @ 2026-02-27 14:56 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Steen Hegelund, UNGLinuxDriver, Richard Cochran,
maxime.chevallier, rmk+kernel
Cc: netdev, linux-arm-kernel, linux-kernel
Move the calendar initialization from sparx5_start() to probe() by
creating a new sparx5_calendar_init() wrapper function that calls both
sparx5_config_auto_calendar() and sparx5_config_dsm_calendar().
Calendar initialization does not require cleanup.
Also, make the individual calendar config functions static since they
are now only called from within sparx5_calendar.c.
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c | 15 +++++++++++++--
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 14 ++++++--------
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 3 +--
3 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
index 5c46d81de530..4ec95590a3c6 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
@@ -151,7 +151,7 @@ enum sparx5_cal_bw sparx5_get_port_cal_speed(struct sparx5 *sparx5, u32 portno)
}
/* Auto configure the QSYS calendar based on port configuration */
-int sparx5_config_auto_calendar(struct sparx5 *sparx5)
+static int sparx5_config_auto_calendar(struct sparx5 *sparx5)
{
const struct sparx5_consts *consts = sparx5->data->consts;
u32 cal[7], value, idx, portno;
@@ -578,7 +578,7 @@ static int sparx5_dsm_calendar_update(struct sparx5 *sparx5, u32 taxi,
}
/* Configure the DSM calendar based on port configuration */
-int sparx5_config_dsm_calendar(struct sparx5 *sparx5)
+static int sparx5_config_dsm_calendar(struct sparx5 *sparx5)
{
const struct sparx5_ops *ops = sparx5->data->ops;
int taxi;
@@ -610,3 +610,14 @@ int sparx5_config_dsm_calendar(struct sparx5 *sparx5)
kfree(data);
return err;
}
+
+int sparx5_calendar_init(struct sparx5 *sparx5)
+{
+ int err;
+
+ err = sparx5_config_auto_calendar(sparx5);
+ if (err)
+ return err;
+
+ return sparx5_config_dsm_calendar(sparx5);
+}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index bcc7b895fad6..a58c79a6e873 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -735,14 +735,6 @@ static int sparx5_start(struct sparx5 *sparx5)
/* Enable queue limitation watermarks */
sparx5_qlim_set(sparx5);
- err = sparx5_config_auto_calendar(sparx5);
- if (err)
- return err;
-
- err = sparx5_config_dsm_calendar(sparx5);
- if (err)
- return err;
-
sparx5_board_init(sparx5);
/* Start Frame DMA with fallback to register based INJ/XTR */
@@ -957,6 +949,12 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
goto cleanup_ports;
}
+ err = sparx5_calendar_init(sparx5);
+ if (err) {
+ dev_err(sparx5->dev, "Failed to initialize calendar\n");
+ goto cleanup_ports;
+ }
+
err = sparx5_qos_init(sparx5);
if (err) {
dev_err(sparx5->dev, "Failed to initialize QoS\n");
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index 97d53e229ad6..6a745bb71b5c 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -504,8 +504,7 @@ int sparx5_vlan_vid_del(struct sparx5_port *port, u16 vid);
void sparx5_vlan_port_apply(struct sparx5 *sparx5, struct sparx5_port *port);
/* sparx5_calendar.c */
-int sparx5_config_auto_calendar(struct sparx5 *sparx5);
-int sparx5_config_dsm_calendar(struct sparx5 *sparx5);
+int sparx5_calendar_init(struct sparx5 *sparx5);
int sparx5_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
struct sparx5_calendar_data *data);
u32 sparx5_cal_speed_to_value(enum sparx5_cal_bw speed);
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH net-next v2 6/9] net: sparx5: move remaining init functions from start() to probe()
2026-02-27 14:56 [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths Daniel Machon
` (4 preceding siblings ...)
2026-02-27 14:56 ` [PATCH net-next v2 5/9] net: sparx5: move calendar initialization to probe Daniel Machon
@ 2026-02-27 14:56 ` Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 7/9] net: sparx5: move PTP IRQ handling out of sparx5_start() Daniel Machon
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Daniel Machon @ 2026-02-27 14:56 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Steen Hegelund, UNGLinuxDriver, Richard Cochran,
maxime.chevallier, rmk+kernel
Cc: netdev, linux-arm-kernel, linux-kernel
Move sparx5_pgid_init(), sparx5_vlan_init(), and sparx5_board_init()
from sparx5_start() to probe(). These functions do not require cleanup.
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index a58c79a6e873..d37f34197e84 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -726,17 +726,9 @@ static int sparx5_start(struct sparx5 *sparx5)
ANA_CL_FILTER_CTRL_FORCE_FCS_UPDATE_ENA,
sparx5, ANA_CL_FILTER_CTRL(idx));
- /* Init PGID table arbitrator */
- sparx5_pgid_init(sparx5);
-
- /* Setup VLANs */
- sparx5_vlan_init(sparx5);
-
/* Enable queue limitation watermarks */
sparx5_qlim_set(sparx5);
- sparx5_board_init(sparx5);
-
/* Start Frame DMA with fallback to register based INJ/XTR */
err = -ENXIO;
if (sparx5->fdma_irq >= 0) {
@@ -943,6 +935,10 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
}
}
+ sparx5_pgid_init(sparx5);
+ sparx5_vlan_init(sparx5);
+ sparx5_board_init(sparx5);
+
err = sparx5_start(sparx5);
if (err) {
dev_err(sparx5->dev, "Start failed\n");
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH net-next v2 7/9] net: sparx5: move PTP IRQ handling out of sparx5_start()
2026-02-27 14:56 [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths Daniel Machon
` (5 preceding siblings ...)
2026-02-27 14:56 ` [PATCH net-next v2 6/9] net: sparx5: move remaining init functions from start() to probe() Daniel Machon
@ 2026-02-27 14:56 ` Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 8/9] net: sparx5: move FDMA/XTR initialization " Daniel Machon
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Daniel Machon @ 2026-02-27 14:56 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Steen Hegelund, UNGLinuxDriver, Richard Cochran,
maxime.chevallier, rmk+kernel
Cc: netdev, linux-arm-kernel, linux-kernel
Move the PTP IRQ request into sparx5_ptp_init() so all PTP setup is
done in one place.
Also move the sparx5_ptp_init() call to right before
sparx5_register_netdevs() and add a cleanup_ptp label. Update remove()
to disable the PTP IRQ and reorder ptp_deinit accordingly.
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
.../net/ethernet/microchip/sparx5/sparx5_main.c | 34 +++++++---------------
drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c | 18 ++++++++++++
2 files changed, 29 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index d37f34197e84..f359008d2205 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -761,18 +761,6 @@ static int sparx5_start(struct sparx5 *sparx5)
sparx5->xtr_irq = -ENXIO;
}
- if (sparx5->ptp_irq >= 0 &&
- sparx5_has_feature(sparx5, SPX5_FEATURE_PTP)) {
- err = devm_request_threaded_irq(sparx5->dev, sparx5->ptp_irq,
- NULL, ops->ptp_irq_handler,
- IRQF_ONESHOT, "sparx5-ptp",
- sparx5);
- if (err)
- sparx5->ptp_irq = -ENXIO;
-
- sparx5->ptp = 1;
- }
-
return err;
}
@@ -957,16 +945,10 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
goto cleanup_ports;
}
- err = sparx5_ptp_init(sparx5);
- if (err) {
- dev_err(sparx5->dev, "PTP failed\n");
- goto cleanup_ports;
- }
-
err = sparx5_vcap_init(sparx5);
if (err) {
dev_err(sparx5->dev, "Failed to initialize VCAP\n");
- goto cleanup_ptp;
+ goto cleanup_ports;
}
err = sparx5_mact_init(sparx5);
@@ -983,10 +965,16 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&sparx5->mall_entries);
+ err = sparx5_ptp_init(sparx5);
+ if (err) {
+ dev_err(sparx5->dev, "Failed to initialize PTP\n");
+ goto cleanup_stats;
+ }
+
err = sparx5_register_netdevs(sparx5);
if (err) {
dev_err(sparx5->dev, "Failed to register net devices\n");
- goto cleanup_stats;
+ goto cleanup_ptp;
}
err = sparx5_register_notifier_blocks(sparx5);
@@ -999,14 +987,14 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
cleanup_netdevs:
sparx5_unregister_netdevs(sparx5);
+cleanup_ptp:
+ sparx5_ptp_deinit(sparx5);
cleanup_stats:
sparx5_stats_deinit(sparx5);
cleanup_mact:
sparx5_mact_deinit(sparx5);
cleanup_vcap:
sparx5_vcap_deinit(sparx5);
-cleanup_ptp:
- sparx5_ptp_deinit(sparx5);
cleanup_ports:
sparx5_destroy_netdevs(sparx5);
cleanup_config:
@@ -1032,10 +1020,10 @@ static void mchp_sparx5_remove(struct platform_device *pdev)
}
sparx5_unregister_notifier_blocks(sparx5);
sparx5_unregister_netdevs(sparx5);
+ sparx5_ptp_deinit(sparx5);
sparx5_stats_deinit(sparx5);
sparx5_mact_deinit(sparx5);
sparx5_vcap_deinit(sparx5);
- sparx5_ptp_deinit(sparx5);
ops->fdma_deinit(sparx5);
sparx5_destroy_netdevs(sparx5);
}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
index 8b2e07821a95..a16ec8136d6d 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
@@ -606,9 +606,22 @@ static int sparx5_ptp_phc_init(struct sparx5 *sparx5,
int sparx5_ptp_init(struct sparx5 *sparx5)
{
u64 tod_adj = sparx5_ptp_get_nominal_value(sparx5);
+ const struct sparx5_ops *ops = sparx5->data->ops;
struct sparx5_port *port;
int err, i;
+ if (sparx5->ptp_irq >= 0 &&
+ sparx5_has_feature(sparx5, SPX5_FEATURE_PTP)) {
+ err = devm_request_threaded_irq(sparx5->dev, sparx5->ptp_irq,
+ NULL, ops->ptp_irq_handler,
+ IRQF_ONESHOT, "sparx5-ptp",
+ sparx5);
+ if (err)
+ sparx5->ptp_irq = -ENXIO;
+
+ sparx5->ptp = 1;
+ }
+
if (!sparx5->ptp)
return 0;
@@ -660,6 +673,11 @@ void sparx5_ptp_deinit(struct sparx5 *sparx5)
struct sparx5_port *port;
int i;
+ if (sparx5->ptp_irq >= 0) {
+ disable_irq(sparx5->ptp_irq);
+ sparx5->ptp_irq = -ENXIO;
+ }
+
for (i = 0; i < sparx5->data->consts->n_ports; i++) {
port = sparx5->ports[i];
if (!port)
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH net-next v2 8/9] net: sparx5: move FDMA/XTR initialization out of sparx5_start()
2026-02-27 14:56 [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths Daniel Machon
` (6 preceding siblings ...)
2026-02-27 14:56 ` [PATCH net-next v2 7/9] net: sparx5: move PTP IRQ handling out of sparx5_start() Daniel Machon
@ 2026-02-27 14:56 ` Daniel Machon
2026-02-27 14:56 ` [PATCH net-next v2 9/9] net: sparx5: replace sparx5_start() with sparx5_forwarding_init() Daniel Machon
2026-03-03 4:46 ` [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths patchwork-bot+netdevbpf
9 siblings, 0 replies; 11+ messages in thread
From: Daniel Machon @ 2026-02-27 14:56 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Steen Hegelund, UNGLinuxDriver, Richard Cochran,
maxime.chevallier, rmk+kernel
Cc: netdev, linux-arm-kernel, linux-kernel
Move the Frame DMA and register-based extraction initialization out of
sparx5_start() and into a new sparx5_frame_io_init() function, called
from probe().
Also, add sparx5_frame_io_deinit() for the cleanup path.
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
.../net/ethernet/microchip/sparx5/sparx5_main.c | 109 ++++++++++++---------
1 file changed, 63 insertions(+), 46 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index f359008d2205..e4a448fd2b30 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -658,6 +658,58 @@ static int sparx5_qlim_set(struct sparx5 *sparx5)
return 0;
}
+static int sparx5_frame_io_init(struct sparx5 *sparx5)
+{
+ const struct sparx5_ops *ops = sparx5->data->ops;
+ int err = -ENXIO;
+
+ /* Start Frame DMA with fallback to register based INJ/XTR */
+ if (sparx5->fdma_irq >= 0) {
+ if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0 ||
+ !is_sparx5(sparx5))
+ err = devm_request_irq(sparx5->dev,
+ sparx5->fdma_irq,
+ sparx5_fdma_handler,
+ 0,
+ "sparx5-fdma", sparx5);
+ if (!err) {
+ err = ops->fdma_init(sparx5);
+ if (!err)
+ sparx5_fdma_start(sparx5);
+ }
+ if (err)
+ sparx5->fdma_irq = -ENXIO;
+ } else {
+ sparx5->fdma_irq = -ENXIO;
+ }
+ if (err && sparx5->xtr_irq >= 0) {
+ err = devm_request_irq(sparx5->dev, sparx5->xtr_irq,
+ sparx5_xtr_handler, IRQF_SHARED,
+ "sparx5-xtr", sparx5);
+ if (!err)
+ err = sparx5_manual_injection_mode(sparx5);
+ if (err)
+ sparx5->xtr_irq = -ENXIO;
+ } else {
+ sparx5->xtr_irq = -ENXIO;
+ }
+
+ return err;
+}
+
+static void sparx5_frame_io_deinit(struct sparx5 *sparx5)
+{
+ if (sparx5->xtr_irq >= 0) {
+ disable_irq(sparx5->xtr_irq);
+ sparx5->xtr_irq = -ENXIO;
+ }
+ if (sparx5->fdma_irq >= 0) {
+ disable_irq(sparx5->fdma_irq);
+ sparx5->data->ops->fdma_deinit(sparx5);
+ sparx5->fdma_irq = -ENXIO;
+ }
+}
+
/* Some boards needs to map the SGPIO for signal detect explicitly to the
* port module
*/
@@ -686,9 +738,7 @@ static void sparx5_board_init(struct sparx5 *sparx5)
static int sparx5_start(struct sparx5 *sparx5)
{
const struct sparx5_consts *consts = sparx5->data->consts;
- const struct sparx5_ops *ops = sparx5->data->ops;
u32 idx;
- int err;
/* Setup own UPSIDs */
for (idx = 0; idx < consts->n_own_upsids; idx++) {
@@ -729,39 +779,7 @@ static int sparx5_start(struct sparx5 *sparx5)
/* Enable queue limitation watermarks */
sparx5_qlim_set(sparx5);
- /* Start Frame DMA with fallback to register based INJ/XTR */
- err = -ENXIO;
- if (sparx5->fdma_irq >= 0) {
- if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0 ||
- !is_sparx5(sparx5))
- err = devm_request_irq(sparx5->dev,
- sparx5->fdma_irq,
- sparx5_fdma_handler,
- 0,
- "sparx5-fdma", sparx5);
- if (!err) {
- err = ops->fdma_init(sparx5);
- if (!err)
- sparx5_fdma_start(sparx5);
- }
- if (err)
- sparx5->fdma_irq = -ENXIO;
- } else {
- sparx5->fdma_irq = -ENXIO;
- }
- if (err && sparx5->xtr_irq >= 0) {
- err = devm_request_irq(sparx5->dev, sparx5->xtr_irq,
- sparx5_xtr_handler, IRQF_SHARED,
- "sparx5-xtr", sparx5);
- if (!err)
- err = sparx5_manual_injection_mode(sparx5);
- if (err)
- sparx5->xtr_irq = -ENXIO;
- } else {
- sparx5->xtr_irq = -ENXIO;
- }
-
- return err;
+ return 0;
}
static int mchp_sparx5_probe(struct platform_device *pdev)
@@ -965,10 +983,16 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&sparx5->mall_entries);
+ err = sparx5_frame_io_init(sparx5);
+ if (err) {
+ dev_err(sparx5->dev, "Failed to initialize frame I/O\n");
+ goto cleanup_stats;
+ }
+
err = sparx5_ptp_init(sparx5);
if (err) {
dev_err(sparx5->dev, "Failed to initialize PTP\n");
- goto cleanup_stats;
+ goto cleanup_frame_io;
}
err = sparx5_register_netdevs(sparx5);
@@ -989,6 +1013,8 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
sparx5_unregister_netdevs(sparx5);
cleanup_ptp:
sparx5_ptp_deinit(sparx5);
+cleanup_frame_io:
+ sparx5_frame_io_deinit(sparx5);
cleanup_stats:
sparx5_stats_deinit(sparx5);
cleanup_mact:
@@ -1007,24 +1033,15 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
static void mchp_sparx5_remove(struct platform_device *pdev)
{
struct sparx5 *sparx5 = platform_get_drvdata(pdev);
- const struct sparx5_ops *ops = sparx5->data->ops;
debugfs_remove_recursive(sparx5->debugfs_root);
- if (sparx5->xtr_irq) {
- disable_irq(sparx5->xtr_irq);
- sparx5->xtr_irq = -ENXIO;
- }
- if (sparx5->fdma_irq) {
- disable_irq(sparx5->fdma_irq);
- sparx5->fdma_irq = -ENXIO;
- }
sparx5_unregister_notifier_blocks(sparx5);
sparx5_unregister_netdevs(sparx5);
sparx5_ptp_deinit(sparx5);
+ sparx5_frame_io_deinit(sparx5);
sparx5_stats_deinit(sparx5);
sparx5_mact_deinit(sparx5);
sparx5_vcap_deinit(sparx5);
- ops->fdma_deinit(sparx5);
sparx5_destroy_netdevs(sparx5);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH net-next v2 9/9] net: sparx5: replace sparx5_start() with sparx5_forwarding_init()
2026-02-27 14:56 [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths Daniel Machon
` (7 preceding siblings ...)
2026-02-27 14:56 ` [PATCH net-next v2 8/9] net: sparx5: move FDMA/XTR initialization " Daniel Machon
@ 2026-02-27 14:56 ` Daniel Machon
2026-03-03 4:46 ` [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths patchwork-bot+netdevbpf
9 siblings, 0 replies; 11+ messages in thread
From: Daniel Machon @ 2026-02-27 14:56 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Steen Hegelund, UNGLinuxDriver, Richard Cochran,
maxime.chevallier, rmk+kernel
Cc: netdev, linux-arm-kernel, linux-kernel
With all subsystem initializations moved out, sparx5_start() only sets
up forwarding (UPSIDs, CPU ports, masks, PGIDs, FCS, watermarks).
Rename it to sparx5_forwarding_init() and make it void since it cannot
fail. This removes sparx5_start() entirely.
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index e4a448fd2b30..cab5daf265c2 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -735,7 +735,7 @@ static void sparx5_board_init(struct sparx5 *sparx5)
GCB_HW_SGPIO_TO_SD_MAP_CFG(idx));
}
-static int sparx5_start(struct sparx5 *sparx5)
+static void sparx5_forwarding_init(struct sparx5 *sparx5)
{
const struct sparx5_consts *consts = sparx5->data->consts;
u32 idx;
@@ -779,7 +779,6 @@ static int sparx5_start(struct sparx5 *sparx5)
/* Enable queue limitation watermarks */
sparx5_qlim_set(sparx5);
- return 0;
}
static int mchp_sparx5_probe(struct platform_device *pdev)
@@ -944,12 +943,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
sparx5_pgid_init(sparx5);
sparx5_vlan_init(sparx5);
sparx5_board_init(sparx5);
-
- err = sparx5_start(sparx5);
- if (err) {
- dev_err(sparx5->dev, "Start failed\n");
- goto cleanup_ports;
- }
+ sparx5_forwarding_init(sparx5);
err = sparx5_calendar_init(sparx5);
if (err) {
--
2.34.1
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths
2026-02-27 14:56 [PATCH net-next v2 0/9] net: sparx5: clean up probe/remove init and deinit paths Daniel Machon
` (8 preceding siblings ...)
2026-02-27 14:56 ` [PATCH net-next v2 9/9] net: sparx5: replace sparx5_start() with sparx5_forwarding_init() Daniel Machon
@ 2026-03-03 4:46 ` patchwork-bot+netdevbpf
9 siblings, 0 replies; 11+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-03-03 4:46 UTC (permalink / raw)
To: Daniel Machon
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, Steen.Hegelund,
UNGLinuxDriver, richardcochran, maxime.chevallier, rmk+kernel,
netdev, linux-arm-kernel, linux-kernel
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Fri, 27 Feb 2026 15:56:38 +0100 you wrote:
> This series refactors the sparx5 init and deinit code out of
> sparx5_start() and into probe(), adding proper per-subsystem cleanup
> labels and deinit functions.
>
> Currently, the sparx5 driver initializes most subsystems inside
> sparx5_start(), which is called from probe(). This includes registering
> netdevs, starting worker threads for stats and MAC table polling,
> requesting PTP IRQs, and initializing VCAP. The function has grown to
> handle many unrelated subsystems, and has no granular error handling —
> it either succeeds entirely or returns an error, leaving cleanup to a
> single catch-all label in probe().
>
> [...]
Here is the summary with links:
- [net-next,v2,1/9] net: sparx5: move netdev and notifier block registration to probe
https://git.kernel.org/netdev/net-next/c/b8909aad5b8d
- [net-next,v2,2/9] net: sparx5: move VCAP initialization to probe
https://git.kernel.org/netdev/net-next/c/3a95973e7c79
- [net-next,v2,3/9] net: sparx5: move MAC table initialization and add deinit function
https://git.kernel.org/netdev/net-next/c/13cb1b68842b
- [net-next,v2,4/9] net: sparx5: move stats initialization and add deinit function
https://git.kernel.org/netdev/net-next/c/e180067a03ca
- [net-next,v2,5/9] net: sparx5: move calendar initialization to probe
https://git.kernel.org/netdev/net-next/c/274182ff34fd
- [net-next,v2,6/9] net: sparx5: move remaining init functions from start() to probe()
https://git.kernel.org/netdev/net-next/c/cdc374359fe8
- [net-next,v2,7/9] net: sparx5: move PTP IRQ handling out of sparx5_start()
https://git.kernel.org/netdev/net-next/c/0432c60112b4
- [net-next,v2,8/9] net: sparx5: move FDMA/XTR initialization out of sparx5_start()
https://git.kernel.org/netdev/net-next/c/8b1e4a6747b8
- [net-next,v2,9/9] net: sparx5: replace sparx5_start() with sparx5_forwarding_init()
https://git.kernel.org/netdev/net-next/c/1e540c4d8f32
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 11+ messages in thread