From 6e933cd69ad9eadcc26d6db01b066e524b8894c2 Mon Sep 17 00:00:00 2001 From: Sam Day Date: Wed, 12 Feb 2025 07:01:39 +0000 Subject: rng: msm: don't enable PRNG if it's already enabled msm_rng_enable is supposed to skip writing to LFSR_CFG + CONFIG registers in the PRNG_ block if PRNG_CONFIG_HW_ENABLE is already set. The logic to test for this was inverted. Without this fix, the driver was causing SError aborts on my MSM8916 device. Stephan Gerhold suggested this was probably because TZ has marked this as a protected register, since it would also be using it for RNG. Fixes: 033ec636fcb ("rng: Add Qualcomm MSM PRNG driver") Suggested-by: Stephan Gerhold Reviewed-by: Neil Armstrong Signed-off-by: Sam Day Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20250212-msm-rng-fixes-v2-3-645cf8d3fd3c@samcday.com Signed-off-by: Caleb Connolly --- drivers/rng/msm_rng.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/rng/msm_rng.c') diff --git a/drivers/rng/msm_rng.c b/drivers/rng/msm_rng.c index f790d3b60f9..01505509103 100644 --- a/drivers/rng/msm_rng.c +++ b/drivers/rng/msm_rng.c @@ -76,7 +76,7 @@ static int msm_rng_enable(struct msm_rng_priv *priv, int enable) if (enable) { /* Enable PRNG only if it is not already enabled */ val = readl_relaxed(priv->base + PRNG_CONFIG); - if (val & PRNG_CONFIG_HW_ENABLE) { + if (!(val & PRNG_CONFIG_HW_ENABLE)) { val = readl_relaxed(priv->base + PRNG_LFSR_CFG); val &= ~PRNG_LFSR_CFG_MASK; val |= PRNG_LFSR_CFG_CLOCKS; -- cgit v1.2.3 From 2babb61428dcb55067a81f88bbc2124924807345 Mon Sep 17 00:00:00 2001 From: Sam Day Date: Wed, 12 Feb 2025 07:01:55 +0000 Subject: rng: msm: keep core clock disabled when PRNG not in use This is how the kernel does it. APQ8016E TRM also states that this clock can be turned off when no random numbers are needed. Signed-off-by: Sam Day Reviewed-by: Neil Armstrong Reviewed-by: Caleb Connolly Link: https://lore.kernel.org/r/20250212-msm-rng-fixes-v2-5-645cf8d3fd3c@samcday.com Signed-off-by: Caleb Connolly --- drivers/rng/msm_rng.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/rng/msm_rng.c') diff --git a/drivers/rng/msm_rng.c b/drivers/rng/msm_rng.c index 01505509103..aab602c5ed0 100644 --- a/drivers/rng/msm_rng.c +++ b/drivers/rng/msm_rng.c @@ -44,6 +44,11 @@ static int msm_rng_read(struct udevice *dev, void *data, size_t len) u32 *retdata = data; size_t maxsize; u32 val; + int ret; + + ret = clk_enable(&priv->clk); + if (ret < 0) + return ret; /* calculate max size bytes to transfer back to caller */ maxsize = min_t(size_t, MAX_HW_FIFO_SIZE, len); @@ -66,6 +71,8 @@ static int msm_rng_read(struct udevice *dev, void *data, size_t len) break; } while (currsize < maxsize); + clk_disable(&priv->clk); + return 0; } @@ -118,7 +125,9 @@ static int msm_rng_probe(struct udevice *dev) if (ret < 0) return ret; - return msm_rng_enable(priv, 1); + ret = msm_rng_enable(priv, 1); + clk_disable(&priv->clk); + return ret; } static int msm_rng_remove(struct udevice *dev) -- cgit v1.2.3