Commit cc2180a5 authored by David S. Miller's avatar David S. Miller

Merge branch 'mvpp2-fixes'

Maxime Chevallier says:

====================
net: mvpp2: Fix hangs when starting some interfaces on 7k/8k

Armada 7K / 8K clock management has recently been reworked, see :

commit c7e92def ("clk: mvebu: cp110: Fix clock tree representation")

I have been experiencing overall system hangs on MacchiatoBin when starting
the eth1 interface since then. It turns out some clocks dependencies were
missing in the PPv2 and xmdio driver, the clock rework made this visible.

This is the V2 series, that adds support for the missing 'MG Core clock' in
mvpp2, and fixes an issue with the error path for the axi_clk.

Thanks to Gregory Clement for finding the root cause of this bug.

V2 : Remove all DT patches from this series, they will be merged through
     the mvebu tree.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c55ca688 9af771ce
...@@ -942,6 +942,7 @@ struct mvpp2 { ...@@ -942,6 +942,7 @@ struct mvpp2 {
struct clk *pp_clk; struct clk *pp_clk;
struct clk *gop_clk; struct clk *gop_clk;
struct clk *mg_clk; struct clk *mg_clk;
struct clk *mg_core_clk;
struct clk *axi_clk; struct clk *axi_clk;
/* List of pointers to port structures */ /* List of pointers to port structures */
...@@ -8768,18 +8769,27 @@ static int mvpp2_probe(struct platform_device *pdev) ...@@ -8768,18 +8769,27 @@ static int mvpp2_probe(struct platform_device *pdev)
err = clk_prepare_enable(priv->mg_clk); err = clk_prepare_enable(priv->mg_clk);
if (err < 0) if (err < 0)
goto err_gop_clk; goto err_gop_clk;
priv->mg_core_clk = devm_clk_get(&pdev->dev, "mg_core_clk");
if (IS_ERR(priv->mg_core_clk)) {
priv->mg_core_clk = NULL;
} else {
err = clk_prepare_enable(priv->mg_core_clk);
if (err < 0)
goto err_mg_clk;
}
} }
priv->axi_clk = devm_clk_get(&pdev->dev, "axi_clk"); priv->axi_clk = devm_clk_get(&pdev->dev, "axi_clk");
if (IS_ERR(priv->axi_clk)) { if (IS_ERR(priv->axi_clk)) {
err = PTR_ERR(priv->axi_clk); err = PTR_ERR(priv->axi_clk);
if (err == -EPROBE_DEFER) if (err == -EPROBE_DEFER)
goto err_gop_clk; goto err_mg_core_clk;
priv->axi_clk = NULL; priv->axi_clk = NULL;
} else { } else {
err = clk_prepare_enable(priv->axi_clk); err = clk_prepare_enable(priv->axi_clk);
if (err < 0) if (err < 0)
goto err_gop_clk; goto err_mg_core_clk;
} }
/* Get system's tclk rate */ /* Get system's tclk rate */
...@@ -8793,7 +8803,7 @@ static int mvpp2_probe(struct platform_device *pdev) ...@@ -8793,7 +8803,7 @@ static int mvpp2_probe(struct platform_device *pdev)
if (priv->hw_version == MVPP22) { if (priv->hw_version == MVPP22) {
err = dma_set_mask(&pdev->dev, MVPP2_DESC_DMA_MASK); err = dma_set_mask(&pdev->dev, MVPP2_DESC_DMA_MASK);
if (err) if (err)
goto err_mg_clk; goto err_axi_clk;
/* Sadly, the BM pools all share the same register to /* Sadly, the BM pools all share the same register to
* store the high 32 bits of their address. So they * store the high 32 bits of their address. So they
* must all have the same high 32 bits, which forces * must all have the same high 32 bits, which forces
...@@ -8801,14 +8811,14 @@ static int mvpp2_probe(struct platform_device *pdev) ...@@ -8801,14 +8811,14 @@ static int mvpp2_probe(struct platform_device *pdev)
*/ */
err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (err) if (err)
goto err_mg_clk; goto err_axi_clk;
} }
/* Initialize network controller */ /* Initialize network controller */
err = mvpp2_init(pdev, priv); err = mvpp2_init(pdev, priv);
if (err < 0) { if (err < 0) {
dev_err(&pdev->dev, "failed to initialize controller\n"); dev_err(&pdev->dev, "failed to initialize controller\n");
goto err_mg_clk; goto err_axi_clk;
} }
/* Initialize ports */ /* Initialize ports */
...@@ -8821,7 +8831,7 @@ static int mvpp2_probe(struct platform_device *pdev) ...@@ -8821,7 +8831,7 @@ static int mvpp2_probe(struct platform_device *pdev)
if (priv->port_count == 0) { if (priv->port_count == 0) {
dev_err(&pdev->dev, "no ports enabled\n"); dev_err(&pdev->dev, "no ports enabled\n");
err = -ENODEV; err = -ENODEV;
goto err_mg_clk; goto err_axi_clk;
} }
/* Statistics must be gathered regularly because some of them (like /* Statistics must be gathered regularly because some of them (like
...@@ -8849,8 +8859,13 @@ static int mvpp2_probe(struct platform_device *pdev) ...@@ -8849,8 +8859,13 @@ static int mvpp2_probe(struct platform_device *pdev)
mvpp2_port_remove(priv->port_list[i]); mvpp2_port_remove(priv->port_list[i]);
i++; i++;
} }
err_mg_clk: err_axi_clk:
clk_disable_unprepare(priv->axi_clk); clk_disable_unprepare(priv->axi_clk);
err_mg_core_clk:
if (priv->hw_version == MVPP22)
clk_disable_unprepare(priv->mg_core_clk);
err_mg_clk:
if (priv->hw_version == MVPP22) if (priv->hw_version == MVPP22)
clk_disable_unprepare(priv->mg_clk); clk_disable_unprepare(priv->mg_clk);
err_gop_clk: err_gop_clk:
...@@ -8897,6 +8912,7 @@ static int mvpp2_remove(struct platform_device *pdev) ...@@ -8897,6 +8912,7 @@ static int mvpp2_remove(struct platform_device *pdev)
return 0; return 0;
clk_disable_unprepare(priv->axi_clk); clk_disable_unprepare(priv->axi_clk);
clk_disable_unprepare(priv->mg_core_clk);
clk_disable_unprepare(priv->mg_clk); clk_disable_unprepare(priv->mg_clk);
clk_disable_unprepare(priv->pp_clk); clk_disable_unprepare(priv->pp_clk);
clk_disable_unprepare(priv->gop_clk); clk_disable_unprepare(priv->gop_clk);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment