Commit 92ae112e authored by Gregory CLEMENT's avatar Gregory CLEMENT Committed by Mark Brown

spi: orion: Fix clock resource by adding an optional bus clock

On Armada 7K/8K we need to explicitly enable the bus clock. The bus clock
is optional because not all the SoCs need them but at least for Armada
7K/8K it is actually mandatory.

The binding documentation is updating accordingly as well as mentioning
the mandatory clock which was also missing.
Signed-off-by: default avatarGregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4fbd8d19
...@@ -18,8 +18,17 @@ Required properties: ...@@ -18,8 +18,17 @@ Required properties:
The eight register sets following the control registers refer to The eight register sets following the control registers refer to
chip-select lines 0 through 7 respectively. chip-select lines 0 through 7 respectively.
- cell-index : Which of multiple SPI controllers is this. - cell-index : Which of multiple SPI controllers is this.
- clocks : pointers to the reference clocks for this device, the first
one is the one used for the clock on the spi bus, the
second one is optional and is the clock used for the
functional part of the controller
Optional properties: Optional properties:
- interrupts : Is currently not used. - interrupts : Is currently not used.
- clock-names : names of used clocks, mandatory if the second clock is
used, the name must be "core", and "axi" (the latter
is only for Armada 7K/8K).
Example: Example:
spi@10600 { spi@10600 {
......
...@@ -94,6 +94,7 @@ struct orion_spi { ...@@ -94,6 +94,7 @@ struct orion_spi {
struct spi_master *master; struct spi_master *master;
void __iomem *base; void __iomem *base;
struct clk *clk; struct clk *clk;
struct clk *axi_clk;
const struct orion_spi_dev *devdata; const struct orion_spi_dev *devdata;
struct orion_direct_acc direct_access[ORION_NUM_CHIPSELECTS]; struct orion_direct_acc direct_access[ORION_NUM_CHIPSELECTS];
...@@ -634,6 +635,14 @@ static int orion_spi_probe(struct platform_device *pdev) ...@@ -634,6 +635,14 @@ static int orion_spi_probe(struct platform_device *pdev)
if (status) if (status)
goto out; goto out;
/* The following clock is only used by some SoCs */
spi->axi_clk = devm_clk_get(&pdev->dev, "axi");
if (IS_ERR(spi->axi_clk) &&
PTR_ERR(spi->axi_clk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (!IS_ERR(spi->axi_clk))
clk_prepare_enable(spi->axi_clk);
tclk_hz = clk_get_rate(spi->clk); tclk_hz = clk_get_rate(spi->clk);
/* /*
...@@ -725,6 +734,7 @@ static int orion_spi_probe(struct platform_device *pdev) ...@@ -725,6 +734,7 @@ static int orion_spi_probe(struct platform_device *pdev)
out_rel_pm: out_rel_pm:
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
out_rel_clk: out_rel_clk:
clk_disable_unprepare(spi->axi_clk);
clk_disable_unprepare(spi->clk); clk_disable_unprepare(spi->clk);
out: out:
spi_master_put(master); spi_master_put(master);
...@@ -738,6 +748,7 @@ static int orion_spi_remove(struct platform_device *pdev) ...@@ -738,6 +748,7 @@ static int orion_spi_remove(struct platform_device *pdev)
struct orion_spi *spi = spi_master_get_devdata(master); struct orion_spi *spi = spi_master_get_devdata(master);
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
clk_disable_unprepare(spi->axi_clk);
clk_disable_unprepare(spi->clk); clk_disable_unprepare(spi->clk);
spi_unregister_master(master); spi_unregister_master(master);
...@@ -754,6 +765,7 @@ static int orion_spi_runtime_suspend(struct device *dev) ...@@ -754,6 +765,7 @@ static int orion_spi_runtime_suspend(struct device *dev)
struct spi_master *master = dev_get_drvdata(dev); struct spi_master *master = dev_get_drvdata(dev);
struct orion_spi *spi = spi_master_get_devdata(master); struct orion_spi *spi = spi_master_get_devdata(master);
clk_disable_unprepare(spi->axi_clk);
clk_disable_unprepare(spi->clk); clk_disable_unprepare(spi->clk);
return 0; return 0;
} }
...@@ -763,6 +775,8 @@ static int orion_spi_runtime_resume(struct device *dev) ...@@ -763,6 +775,8 @@ static int orion_spi_runtime_resume(struct device *dev)
struct spi_master *master = dev_get_drvdata(dev); struct spi_master *master = dev_get_drvdata(dev);
struct orion_spi *spi = spi_master_get_devdata(master); struct orion_spi *spi = spi_master_get_devdata(master);
if (!IS_ERR(spi->axi_clk))
clk_prepare_enable(spi->axi_clk);
return clk_prepare_enable(spi->clk); return clk_prepare_enable(spi->clk);
} }
#endif #endif
......
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