mirror of
https://github.com/torvalds/linux.git
synced 2026-08-02 05:12:01 +02:00
net: airoha: Rework the code flow in airoha_remove() and in airoha_probe() error path
As suggested by Simon in [0], rework the code flow in airoha_remove() and in the airoha_probe() error path in order to rely on a more common approach un-registering configured net-devices first and destroying the hw resources at the end of the code. Introduce airoha_qdma_cleanup routine to release QDMA resources. [0] https://lore.kernel.org/netdev/20251214-airoha-fix-dev-registration-v1-1-860e027ad4c6@kernel.org/ Suggested-by: Simon Horman <horms@kernel.org> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20260321-airoha-remove-rework-v2-1-16c7bade5fe5@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
a4b908c89d
commit
b1c803d5c8
|
|
@ -1368,6 +1368,33 @@ static int airoha_qdma_init(struct platform_device *pdev,
|
|||
return airoha_qdma_hw_init(qdma);
|
||||
}
|
||||
|
||||
static void airoha_qdma_cleanup(struct airoha_qdma *qdma)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||
if (!qdma->q_rx[i].ndesc)
|
||||
continue;
|
||||
|
||||
netif_napi_del(&qdma->q_rx[i].napi);
|
||||
airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]);
|
||||
if (qdma->q_rx[i].page_pool) {
|
||||
page_pool_destroy(qdma->q_rx[i].page_pool);
|
||||
qdma->q_rx[i].page_pool = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
|
||||
netif_napi_del(&qdma->q_tx_irq[i].napi);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
||||
if (!qdma->q_tx[i].ndesc)
|
||||
continue;
|
||||
|
||||
airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int airoha_hw_init(struct platform_device *pdev,
|
||||
struct airoha_eth *eth)
|
||||
{
|
||||
|
|
@ -1395,41 +1422,30 @@ static int airoha_hw_init(struct platform_device *pdev,
|
|||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
|
||||
err = airoha_qdma_init(pdev, eth, ð->qdma[i]);
|
||||
if (err)
|
||||
return err;
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = airoha_ppe_init(eth);
|
||||
if (err)
|
||||
return err;
|
||||
goto error;
|
||||
|
||||
set_bit(DEV_STATE_INITIALIZED, ð->state);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_cleanup(ð->qdma[i]);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void airoha_hw_cleanup(struct airoha_qdma *qdma)
|
||||
static void airoha_hw_cleanup(struct airoha_eth *eth)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
|
||||
if (!qdma->q_rx[i].ndesc)
|
||||
continue;
|
||||
|
||||
netif_napi_del(&qdma->q_rx[i].napi);
|
||||
airoha_qdma_cleanup_rx_queue(&qdma->q_rx[i]);
|
||||
if (qdma->q_rx[i].page_pool)
|
||||
page_pool_destroy(qdma->q_rx[i].page_pool);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
|
||||
netif_napi_del(&qdma->q_tx_irq[i].napi);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
||||
if (!qdma->q_tx[i].ndesc)
|
||||
continue;
|
||||
|
||||
airoha_qdma_cleanup_tx_queue(&qdma->q_tx[i]);
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_cleanup(ð->qdma[i]);
|
||||
airoha_ppe_deinit(eth);
|
||||
}
|
||||
|
||||
static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
|
||||
|
|
@ -3012,7 +3028,7 @@ static int airoha_probe(struct platform_device *pdev)
|
|||
|
||||
err = airoha_hw_init(pdev, eth);
|
||||
if (err)
|
||||
goto error_hw_cleanup;
|
||||
goto error_netdev_free;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_start_napi(ð->qdma[i]);
|
||||
|
|
@ -3040,10 +3056,6 @@ static int airoha_probe(struct platform_device *pdev)
|
|||
error_napi_stop:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_stop_napi(ð->qdma[i]);
|
||||
airoha_ppe_deinit(eth);
|
||||
error_hw_cleanup:
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_hw_cleanup(ð->qdma[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
|
|
@ -3055,6 +3067,8 @@ static int airoha_probe(struct platform_device *pdev)
|
|||
unregister_netdev(port->dev);
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
airoha_hw_cleanup(eth);
|
||||
error_netdev_free:
|
||||
free_netdev(eth->napi_dev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
|
|
@ -3066,10 +3080,8 @@ static void airoha_remove(struct platform_device *pdev)
|
|||
struct airoha_eth *eth = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
|
||||
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
|
||||
airoha_qdma_stop_napi(ð->qdma[i]);
|
||||
airoha_hw_cleanup(ð->qdma[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
|
|
@ -3080,9 +3092,9 @@ static void airoha_remove(struct platform_device *pdev)
|
|||
unregister_netdev(port->dev);
|
||||
airoha_metadata_dst_free(port);
|
||||
}
|
||||
free_netdev(eth->napi_dev);
|
||||
airoha_hw_cleanup(eth);
|
||||
|
||||
airoha_ppe_deinit(eth);
|
||||
free_netdev(eth->napi_dev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user