Commit 0488e272 authored by David S. Miller's avatar David S. Miller

Merge branch 'Armada-8040-SoC-in-orion-mdio-hang'

Josua Mayer says:

====================
Fix hang of Armada 8040 SoC in orion-mdio

With a modular kernel as configured by Debian a hang was observed with
the Armada 8040 SoC in the Clearfog GT and Macchiatobin boards.

The 8040 SoC actually requires four clocks to be enabled for the mdio
interface to function. All 4 clocks are already specified in
armada-cp110.dtsi. It has however been missed that the orion-mdio driver
only supports enabling up to three clocks.

This patch-set allows the orion-mdio driver to handle four clocks and
adds a warning when more clocks are specified to prevent this particular
oversight in the future.

Changes since v1:
- fixed condition for priting the warning (Andrew Lunn)
- rephrased commit description for deferred probing (Andrew Lunn)
- fixed compiler warnings (kbuild test robot)
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7715ff16 433a06d7
...@@ -16,7 +16,7 @@ Required properties: ...@@ -16,7 +16,7 @@ Required properties:
Optional properties: Optional properties:
- interrupts: interrupt line number for the SMI error/done interrupt - interrupts: interrupt line number for the SMI error/done interrupt
- clocks: phandle for up to three required clocks for the MDIO instance - clocks: phandle for up to four required clocks for the MDIO instance
The child nodes of the MDIO driver are the individual PHY devices The child nodes of the MDIO driver are the individual PHY devices
connected to this MDIO bus. They must have a "reg" property given the connected to this MDIO bus. They must have a "reg" property given the
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
struct orion_mdio_dev { struct orion_mdio_dev {
void __iomem *regs; void __iomem *regs;
struct clk *clk[3]; struct clk *clk[4];
/* /*
* If we have access to the error interrupt pin (which is * If we have access to the error interrupt pin (which is
* somewhat misnamed as it not only reflects internal errors * somewhat misnamed as it not only reflects internal errors
...@@ -321,11 +321,19 @@ static int orion_mdio_probe(struct platform_device *pdev) ...@@ -321,11 +321,19 @@ static int orion_mdio_probe(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
dev->clk[i] = of_clk_get(pdev->dev.of_node, i); dev->clk[i] = of_clk_get(pdev->dev.of_node, i);
if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
goto out_clk;
}
if (IS_ERR(dev->clk[i])) if (IS_ERR(dev->clk[i]))
break; break;
clk_prepare_enable(dev->clk[i]); clk_prepare_enable(dev->clk[i]);
} }
if (!IS_ERR(of_clk_get(pdev->dev.of_node, ARRAY_SIZE(dev->clk))))
dev_warn(&pdev->dev, "unsupported number of clocks, limiting to the first "
__stringify(ARRAY_SIZE(dev->clk)) "\n");
dev->err_interrupt = platform_get_irq(pdev, 0); dev->err_interrupt = platform_get_irq(pdev, 0);
if (dev->err_interrupt > 0 && if (dev->err_interrupt > 0 &&
resource_size(r) < MVMDIO_ERR_INT_MASK + 4) { resource_size(r) < MVMDIO_ERR_INT_MASK + 4) {
...@@ -362,6 +370,7 @@ static int orion_mdio_probe(struct platform_device *pdev) ...@@ -362,6 +370,7 @@ static int orion_mdio_probe(struct platform_device *pdev)
if (dev->err_interrupt > 0) if (dev->err_interrupt > 0)
writel(0, dev->regs + MVMDIO_ERR_INT_MASK); writel(0, dev->regs + MVMDIO_ERR_INT_MASK);
out_clk:
for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { for (i = 0; i < ARRAY_SIZE(dev->clk); i++) {
if (IS_ERR(dev->clk[i])) if (IS_ERR(dev->clk[i]))
break; break;
......
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