mms: rng: Add bus bandwidth support to PRNG
PRNG has to use pnoc clock, but pnoc is a bus clock & clients cannot
directly call pnoc apis, so prng calls bus bandwidth api to get the
clock cycles.
Change-Id: Ib3cd075097b4b70f82ec6325535e6e39808c6408
Signed-off-by: Hariprasad Dhalinarasimha <hnamgund@codeaurora.org>
diff --git a/drivers/char/hw_random/msm_rng.c b/drivers/char/hw_random/msm_rng.c
index 261af7d..369477f 100644
--- a/drivers/char/hw_random/msm_rng.c
+++ b/drivers/char/hw_random/msm_rng.c
@@ -24,6 +24,7 @@
#include <linux/types.h>
#include <mach/msm_iomap.h>
#include <mach/socinfo.h>
+#include <mach/msm_bus.h>
#define DRIVER_NAME "msm_rng"
@@ -47,6 +48,7 @@
struct platform_device *pdev;
void __iomem *base;
struct clk *prng_clk;
+ uint32_t qrng_perf_client;
};
static int msm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
@@ -77,7 +79,12 @@
dev_err(&pdev->dev, "failed to enable clock in callback\n");
return 0;
}
-
+ if (msm_rng_dev->qrng_perf_client) {
+ ret = msm_bus_scale_client_update_request(
+ msm_rng_dev->qrng_perf_client, 1);
+ if (ret)
+ pr_err("bus_scale_client_update_req failed!\n");
+ }
/* read random data from h/w */
do {
/* check status bit if data is available */
@@ -97,7 +104,9 @@
if ((maxsize - currsize) < 4)
break;
} while (currsize < maxsize);
-
+ if (msm_rng_dev->qrng_perf_client)
+ ret = msm_bus_scale_client_update_request(
+ msm_rng_dev->qrng_perf_client, 0);
/* vote to turn off clock */
clk_disable_unprepare(msm_rng_dev->prng_clk);
@@ -115,6 +124,12 @@
unsigned long reg_val = 0;
int ret = 0;
+ if (msm_rng_dev->qrng_perf_client) {
+ ret = msm_bus_scale_client_update_request(
+ msm_rng_dev->qrng_perf_client, 1);
+ if (ret)
+ pr_err("bus_scale_client_update_req failed!\n");
+ }
/* Enable the PRNG CLK */
ret = clk_prepare_enable(msm_rng_dev->prng_clk);
if (ret) {
@@ -145,8 +160,10 @@
*/
mb();
}
-
clk_disable_unprepare(msm_rng_dev->prng_clk);
+ if (msm_rng_dev->qrng_perf_client)
+ ret = msm_bus_scale_client_update_request(
+ msm_rng_dev->qrng_perf_client, 0);
return 0;
}
@@ -157,6 +174,7 @@
struct msm_rng_device *msm_rng_dev = NULL;
void __iomem *base = NULL;
int error = 0;
+ struct msm_bus_scale_pdata *qrng_platform_support = NULL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
@@ -197,6 +215,15 @@
msm_rng_dev->pdev = pdev;
platform_set_drvdata(pdev, msm_rng_dev);
+ if (pdev->dev.of_node) {
+ /* Register bus client */
+ qrng_platform_support = msm_bus_cl_get_pdata(pdev);
+ msm_rng_dev->qrng_perf_client = msm_bus_scale_register_client(
+ qrng_platform_support);
+ if (!msm_rng_dev->qrng_perf_client)
+ pr_err("Unable to register bus client\n");
+ }
+
/* Enable rng h/w */
error = msm_rng_enable_hw(msm_rng_dev);
@@ -232,6 +259,8 @@
clk_put(msm_rng_dev->prng_clk);
iounmap(msm_rng_dev->base);
platform_set_drvdata(pdev, NULL);
+ if (msm_rng_dev->qrng_perf_client)
+ msm_bus_scale_unregister_client(msm_rng_dev->qrng_perf_client);
kfree(msm_rng_dev);
return 0;
}