hwrng: omap - Fix clock resource by adding a register clock
authorGregory CLEMENT <gregory.clement@bootlin.com>
Wed, 28 Feb 2018 14:27:23 +0000 (15:27 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 9 Mar 2018 14:45:45 +0000 (22:45 +0800)
On Armada 7K/8K we need to explicitly enable the register clock. This
clock is optional because not all the SoCs using this IP need it but at
least for Armada 7K/8K it is actually mandatory.

The binding documentation is updating accordingly.

Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Documentation/devicetree/bindings/rng/omap_rng.txt
drivers/char/hw_random/omap-rng.c

index 9cf7876..ea434ce 100644 (file)
@@ -13,7 +13,12 @@ Required properties:
 - interrupts : the interrupt number for the RNG module.
                Used for "ti,omap4-rng" and "inside-secure,safexcel-eip76"
 - clocks: the trng clock source. Only mandatory for the
-  "inside-secure,safexcel-eip76" compatible.
+  "inside-secure,safexcel-eip76" compatible, the second clock is
+  needed for the Armada 7K/8K SoCs
+- clock-names: mandatory if there is a second clock, in this case the
+  name must be "core" for the first clock and "reg" for the second
+  one
+
 
 Example:
 /* AM335x */
index 159d4a1..b65ff69 100644 (file)
@@ -150,6 +150,7 @@ struct omap_rng_dev {
        const struct omap_rng_pdata     *pdata;
        struct hwrng rng;
        struct clk                      *clk;
+       struct clk                      *clk_reg;
 };
 
 static inline u32 omap_rng_read(struct omap_rng_dev *priv, u16 reg)
@@ -480,6 +481,19 @@ static int omap_rng_probe(struct platform_device *pdev)
                }
        }
 
+       priv->clk_reg = devm_clk_get(&pdev->dev, "reg");
+       if (IS_ERR(priv->clk_reg) && PTR_ERR(priv->clk_reg) == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+       if (!IS_ERR(priv->clk_reg)) {
+               ret = clk_prepare_enable(priv->clk_reg);
+               if (ret) {
+                       dev_err(&pdev->dev,
+                               "Unable to enable the register clk: %d\n",
+                               ret);
+                       goto err_register;
+               }
+       }
+
        ret = (dev->of_node) ? of_get_omap_rng_device_details(priv, pdev) :
                                get_omap_rng_device_details(priv);
        if (ret)
@@ -499,6 +513,7 @@ err_register:
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 
+       clk_disable_unprepare(priv->clk_reg);
        clk_disable_unprepare(priv->clk);
 err_ioremap:
        dev_err(dev, "initialization failed.\n");
@@ -517,6 +532,7 @@ static int omap_rng_remove(struct platform_device *pdev)
        pm_runtime_disable(&pdev->dev);
 
        clk_disable_unprepare(priv->clk);
+       clk_disable_unprepare(priv->clk_reg);
 
        return 0;
 }