diff options
Diffstat (limited to 'drivers/spi/spi-orion.c')
-rw-r--r-- | drivers/spi/spi-orion.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 8974bb340b3a..deca63e82ff6 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -94,6 +94,7 @@ struct orion_spi { struct spi_master *master; void __iomem *base; struct clk *clk; + struct clk *axi_clk; const struct orion_spi_dev *devdata; struct orion_direct_acc direct_access[ORION_NUM_CHIPSELECTS]; @@ -634,6 +635,16 @@ static int orion_spi_probe(struct platform_device *pdev) if (status) 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) { + status = -EPROBE_DEFER; + goto out_rel_clk; + } + if (!IS_ERR(spi->axi_clk)) + clk_prepare_enable(spi->axi_clk); + tclk_hz = clk_get_rate(spi->clk); /* @@ -658,7 +669,7 @@ static int orion_spi_probe(struct platform_device *pdev) spi->base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(spi->base)) { status = PTR_ERR(spi->base); - goto out_rel_clk; + goto out_rel_axi_clk; } /* Scan all SPI devices of this controller for direct mapped devices */ @@ -696,7 +707,7 @@ static int orion_spi_probe(struct platform_device *pdev) PAGE_SIZE); if (!spi->direct_access[cs].vaddr) { status = -ENOMEM; - goto out_rel_clk; + goto out_rel_axi_clk; } spi->direct_access[cs].size = PAGE_SIZE; @@ -724,6 +735,8 @@ static int orion_spi_probe(struct platform_device *pdev) out_rel_pm: pm_runtime_disable(&pdev->dev); +out_rel_axi_clk: + clk_disable_unprepare(spi->axi_clk); out_rel_clk: clk_disable_unprepare(spi->clk); out: @@ -738,6 +751,7 @@ static int orion_spi_remove(struct platform_device *pdev) struct orion_spi *spi = spi_master_get_devdata(master); pm_runtime_get_sync(&pdev->dev); + clk_disable_unprepare(spi->axi_clk); clk_disable_unprepare(spi->clk); spi_unregister_master(master); @@ -754,6 +768,7 @@ static int orion_spi_runtime_suspend(struct device *dev) struct spi_master *master = dev_get_drvdata(dev); struct orion_spi *spi = spi_master_get_devdata(master); + clk_disable_unprepare(spi->axi_clk); clk_disable_unprepare(spi->clk); return 0; } @@ -763,6 +778,8 @@ static int orion_spi_runtime_resume(struct device *dev) struct spi_master *master = dev_get_drvdata(dev); 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); } #endif |