diff mbox series

spi/bcm63xx-hsspi: keep pll clk enabled

Message ID 20180828114411.6346-1-jonas.gorski@gmail.com (mailing list archive)
State Accepted
Commit 0fd85869c2a9c8723a98bc1f56a876e8383649f4
Headers show
Series spi/bcm63xx-hsspi: keep pll clk enabled | expand

Commit Message

Jonas Gorski Aug. 28, 2018, 11:44 a.m. UTC
If the pll clock needs to be enabled to get its rate, it will also need
to be enabled to provide it. So ensure it is kept enabled through the
lifetime of the device.

Fixes: 0d7412ed1f5dc ("spi/bcm63xx-hspi: Enable the clock before calling clk_get_rate().")
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
 drivers/spi/spi-bcm63xx-hsspi.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

Comments

Mark Brown Aug. 28, 2018, 6:48 p.m. UTC | #1
On Tue, Aug 28, 2018 at 01:44:11PM +0200, Jonas Gorski wrote:
> If the pll clock needs to be enabled to get its rate, it will also need
> to be enabled to provide it. So ensure it is kept enabled through the
> lifetime of the device.

Why not only when the device is in use, saving some power?
Jonas Gorski Sept. 18, 2018, 1 p.m. UTC | #2
Sorry for the late reply, Gmail considered your email spam, and I just
found it there :-(

On 28 August 2018 at 20:48, Mark Brown <broonie@kernel.org> wrote:
> On Tue, Aug 28, 2018 at 01:44:11PM +0200, Jonas Gorski wrote:
>> If the pll clock needs to be enabled to get its rate, it will also need
>> to be enabled to provide it. So ensure it is kept enabled through the
>> lifetime of the device.
>
> Why not only when the device is in use, saving some power?

It isn't a gated clock, there is no power to save. So far it's a (more
or less) virtual fixed clock to pass the platform spezific Hz value to
the driver without having to rely on platform data. The actual gated
clock ("hsspi") is already disabled while not in use.


Regards
Jonas
diff mbox series

Patch

diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c
index c23849f7aa7b..9a06ffdb73b8 100644
--- a/drivers/spi/spi-bcm63xx-hsspi.c
+++ b/drivers/spi/spi-bcm63xx-hsspi.c
@@ -101,6 +101,7 @@  struct bcm63xx_hsspi {
 
 	struct platform_device *pdev;
 	struct clk *clk;
+	struct clk *pll_clk;
 	void __iomem *regs;
 	u8 __iomem *fifo;
 
@@ -332,7 +333,7 @@  static int bcm63xx_hsspi_probe(struct platform_device *pdev)
 	struct resource *res_mem;
 	void __iomem *regs;
 	struct device *dev = &pdev->dev;
-	struct clk *clk;
+	struct clk *clk, *pll_clk = NULL;
 	int irq, ret;
 	u32 reg, rate, num_cs = HSSPI_SPI_MAX_CS;
 
@@ -358,7 +359,7 @@  static int bcm63xx_hsspi_probe(struct platform_device *pdev)
 
 	rate = clk_get_rate(clk);
 	if (!rate) {
-		struct clk *pll_clk = devm_clk_get(dev, "pll");
+		pll_clk = devm_clk_get(dev, "pll");
 
 		if (IS_ERR(pll_clk)) {
 			ret = PTR_ERR(pll_clk);
@@ -373,19 +374,20 @@  static int bcm63xx_hsspi_probe(struct platform_device *pdev)
 		clk_disable_unprepare(pll_clk);
 		if (!rate) {
 			ret = -EINVAL;
-			goto out_disable_clk;
+			goto out_disable_pll_clk;
 		}
 	}
 
 	master = spi_alloc_master(&pdev->dev, sizeof(*bs));
 	if (!master) {
 		ret = -ENOMEM;
-		goto out_disable_clk;
+		goto out_disable_pll_clk;
 	}
 
 	bs = spi_master_get_devdata(master);
 	bs->pdev = pdev;
 	bs->clk = clk;
+	bs->pll_clk = pll_clk;
 	bs->regs = regs;
 	bs->speed_hz = rate;
 	bs->fifo = (u8 __iomem *)(bs->regs + HSSPI_FIFO_REG(0));
@@ -440,6 +442,8 @@  static int bcm63xx_hsspi_probe(struct platform_device *pdev)
 
 out_put_master:
 	spi_master_put(master);
+out_disable_pll_clk:
+	clk_disable_unprepare(pll_clk);
 out_disable_clk:
 	clk_disable_unprepare(clk);
 	return ret;
@@ -453,6 +457,7 @@  static int bcm63xx_hsspi_remove(struct platform_device *pdev)
 
 	/* reset the hardware and block queue progress */
 	__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
+	clk_disable_unprepare(bs->pll_clk);
 	clk_disable_unprepare(bs->clk);
 
 	return 0;
@@ -465,6 +470,7 @@  static int bcm63xx_hsspi_suspend(struct device *dev)
 	struct bcm63xx_hsspi *bs = spi_master_get_devdata(master);
 
 	spi_master_suspend(master);
+	clk_disable_unprepare(bs->pll_clk);
 	clk_disable_unprepare(bs->clk);
 
 	return 0;
@@ -480,6 +486,12 @@  static int bcm63xx_hsspi_resume(struct device *dev)
 	if (ret)
 		return ret;
 
+	if (bs->pll_clk) {
+		ret = clk_prepare_enable(bs->pll_clk);
+		if (ret)
+			return ret;
+	}
+
 	spi_master_resume(master);
 
 	return 0;