diff options
author | Gregory CLEMENT <gregory.clement@free-electrons.com> | 2018-01-12 05:42:33 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-01-12 15:17:36 -0500 |
commit | 92ae112e477ac412decc3fdd5c1eeb6c90c266b4 (patch) | |
tree | cd73da8d3272cd557b049f162e756c21209cffe4 | |
parent | 4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323 (diff) |
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: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | Documentation/devicetree/bindings/spi/spi-orion.txt | 9 | ||||
-rw-r--r-- | drivers/spi/spi-orion.c | 14 |
2 files changed, 23 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi-orion.txt b/Documentation/devicetree/bindings/spi/spi-orion.txt index df8ec31f2f07..8434a65fc12a 100644 --- a/Documentation/devicetree/bindings/spi/spi-orion.txt +++ b/Documentation/devicetree/bindings/spi/spi-orion.txt | |||
@@ -18,8 +18,17 @@ Required properties: | |||
18 | The eight register sets following the control registers refer to | 18 | The eight register sets following the control registers refer to |
19 | chip-select lines 0 through 7 respectively. | 19 | chip-select lines 0 through 7 respectively. |
20 | - cell-index : Which of multiple SPI controllers is this. | 20 | - cell-index : Which of multiple SPI controllers is this. |
21 | - clocks : pointers to the reference clocks for this device, the first | ||
22 | one is the one used for the clock on the spi bus, the | ||
23 | second one is optional and is the clock used for the | ||
24 | functional part of the controller | ||
25 | |||
21 | Optional properties: | 26 | Optional properties: |
22 | - interrupts : Is currently not used. | 27 | - interrupts : Is currently not used. |
28 | - clock-names : names of used clocks, mandatory if the second clock is | ||
29 | used, the name must be "core", and "axi" (the latter | ||
30 | is only for Armada 7K/8K). | ||
31 | |||
23 | 32 | ||
24 | Example: | 33 | Example: |
25 | spi@10600 { | 34 | spi@10600 { |
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 8974bb340b3a..482a0cf3b7aa 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c | |||
@@ -94,6 +94,7 @@ struct orion_spi { | |||
94 | struct spi_master *master; | 94 | struct spi_master *master; |
95 | void __iomem *base; | 95 | void __iomem *base; |
96 | struct clk *clk; | 96 | struct clk *clk; |
97 | struct clk *axi_clk; | ||
97 | const struct orion_spi_dev *devdata; | 98 | const struct orion_spi_dev *devdata; |
98 | 99 | ||
99 | struct orion_direct_acc direct_access[ORION_NUM_CHIPSELECTS]; | 100 | struct orion_direct_acc direct_access[ORION_NUM_CHIPSELECTS]; |
@@ -634,6 +635,14 @@ static int orion_spi_probe(struct platform_device *pdev) | |||
634 | if (status) | 635 | if (status) |
635 | goto out; | 636 | goto out; |
636 | 637 | ||
638 | /* The following clock is only used by some SoCs */ | ||
639 | spi->axi_clk = devm_clk_get(&pdev->dev, "axi"); | ||
640 | if (IS_ERR(spi->axi_clk) && | ||
641 | PTR_ERR(spi->axi_clk) == -EPROBE_DEFER) | ||
642 | return -EPROBE_DEFER; | ||
643 | if (!IS_ERR(spi->axi_clk)) | ||
644 | clk_prepare_enable(spi->axi_clk); | ||
645 | |||
637 | tclk_hz = clk_get_rate(spi->clk); | 646 | tclk_hz = clk_get_rate(spi->clk); |
638 | 647 | ||
639 | /* | 648 | /* |
@@ -725,6 +734,7 @@ static int orion_spi_probe(struct platform_device *pdev) | |||
725 | out_rel_pm: | 734 | out_rel_pm: |
726 | pm_runtime_disable(&pdev->dev); | 735 | pm_runtime_disable(&pdev->dev); |
727 | out_rel_clk: | 736 | out_rel_clk: |
737 | clk_disable_unprepare(spi->axi_clk); | ||
728 | clk_disable_unprepare(spi->clk); | 738 | clk_disable_unprepare(spi->clk); |
729 | out: | 739 | out: |
730 | spi_master_put(master); | 740 | spi_master_put(master); |
@@ -738,6 +748,7 @@ static int orion_spi_remove(struct platform_device *pdev) | |||
738 | struct orion_spi *spi = spi_master_get_devdata(master); | 748 | struct orion_spi *spi = spi_master_get_devdata(master); |
739 | 749 | ||
740 | pm_runtime_get_sync(&pdev->dev); | 750 | pm_runtime_get_sync(&pdev->dev); |
751 | clk_disable_unprepare(spi->axi_clk); | ||
741 | clk_disable_unprepare(spi->clk); | 752 | clk_disable_unprepare(spi->clk); |
742 | 753 | ||
743 | spi_unregister_master(master); | 754 | spi_unregister_master(master); |
@@ -754,6 +765,7 @@ static int orion_spi_runtime_suspend(struct device *dev) | |||
754 | struct spi_master *master = dev_get_drvdata(dev); | 765 | struct spi_master *master = dev_get_drvdata(dev); |
755 | struct orion_spi *spi = spi_master_get_devdata(master); | 766 | struct orion_spi *spi = spi_master_get_devdata(master); |
756 | 767 | ||
768 | clk_disable_unprepare(spi->axi_clk); | ||
757 | clk_disable_unprepare(spi->clk); | 769 | clk_disable_unprepare(spi->clk); |
758 | return 0; | 770 | return 0; |
759 | } | 771 | } |
@@ -763,6 +775,8 @@ static int orion_spi_runtime_resume(struct device *dev) | |||
763 | struct spi_master *master = dev_get_drvdata(dev); | 775 | struct spi_master *master = dev_get_drvdata(dev); |
764 | struct orion_spi *spi = spi_master_get_devdata(master); | 776 | struct orion_spi *spi = spi_master_get_devdata(master); |
765 | 777 | ||
778 | if (!IS_ERR(spi->axi_clk)) | ||
779 | clk_prepare_enable(spi->axi_clk); | ||
766 | return clk_prepare_enable(spi->clk); | 780 | return clk_prepare_enable(spi->clk); |
767 | } | 781 | } |
768 | #endif | 782 | #endif |