Message ID | 20230908165120.730867-10-gatien.chevallier@foss.st.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Herbert Xu |
Headers | show |
Series | hwrng: stm32: support STM32MP13x platforms | expand |
Hi Gatien, kernel test robot noticed the following build warnings: [auto build test WARNING on atorgue-stm32/stm32-next] [also build test WARNING on robh/for-next herbert-crypto-2.6/master herbert-cryptodev-2.6/master linus/master v6.5 next-20230908] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Gatien-Chevallier/dt-bindings-rng-introduce-new-compatible-for-STM32MP13x/20230909-005611 base: https://git.kernel.org/pub/scm/linux/kernel/git/atorgue/stm32.git stm32-next patch link: https://lore.kernel.org/r/20230908165120.730867-10-gatien.chevallier%40foss.st.com patch subject: [PATCH 09/10] hwrng: stm32 - rework power management sequences config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230909/202309090255.4Ttcm8zy-lkp@intel.com/config) compiler: m68k-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230909/202309090255.4Ttcm8zy-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202309090255.4Ttcm8zy-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/char/hw_random/stm32-rng.c:403:12: warning: 'stm32_rng_runtime_resume' defined but not used [-Wunused-function] 403 | static int stm32_rng_runtime_resume(struct device *dev) | ^~~~~~~~~~~~~~~~~~~~~~~~ >> drivers/char/hw_random/stm32-rng.c:371:12: warning: 'stm32_rng_runtime_suspend' defined but not used [-Wunused-function] 371 | static int stm32_rng_runtime_suspend(struct device *dev) | ^~~~~~~~~~~~~~~~~~~~~~~~~ vim +/stm32_rng_runtime_resume +403 drivers/char/hw_random/stm32-rng.c af0d4442dd6813 Lionel Debieve 2019-04-01 370 c6a97c42e399ad Daniel Thompson 2015-10-12 @371 static int stm32_rng_runtime_suspend(struct device *dev) c6a97c42e399ad Daniel Thompson 2015-10-12 372 { d6ba06b8b9a947 Daniel Thompson 2015-10-14 373 struct stm32_rng_private *priv = dev_get_drvdata(dev); f81a08733f43ae Gatien Chevallier 2023-09-08 374 u32 reg; c6a97c42e399ad Daniel Thompson 2015-10-12 375 d9494cfe524b05 Gatien Chevallier 2023-09-08 376 reg = readl_relaxed(priv->base + RNG_CR); d9494cfe524b05 Gatien Chevallier 2023-09-08 377 reg &= ~RNG_CR_RNGEN; d9494cfe524b05 Gatien Chevallier 2023-09-08 378 writel_relaxed(reg, priv->base + RNG_CR); d9494cfe524b05 Gatien Chevallier 2023-09-08 379 clk_disable_unprepare(priv->clk); c6a97c42e399ad Daniel Thompson 2015-10-12 380 c6a97c42e399ad Daniel Thompson 2015-10-12 381 return 0; c6a97c42e399ad Daniel Thompson 2015-10-12 382 } c6a97c42e399ad Daniel Thompson 2015-10-12 383 f81a08733f43ae Gatien Chevallier 2023-09-08 384 static int __maybe_unused stm32_rng_suspend(struct device *dev) f81a08733f43ae Gatien Chevallier 2023-09-08 385 { f81a08733f43ae Gatien Chevallier 2023-09-08 386 struct stm32_rng_private *priv = dev_get_drvdata(dev); f81a08733f43ae Gatien Chevallier 2023-09-08 387 f81a08733f43ae Gatien Chevallier 2023-09-08 388 if (priv->data->has_cond_reset) { f81a08733f43ae Gatien Chevallier 2023-09-08 389 priv->pm_conf.nscr = readl_relaxed(priv->base + RNG_NSCR); f81a08733f43ae Gatien Chevallier 2023-09-08 390 priv->pm_conf.htcr = readl_relaxed(priv->base + RNG_HTCR); f81a08733f43ae Gatien Chevallier 2023-09-08 391 } f81a08733f43ae Gatien Chevallier 2023-09-08 392 f81a08733f43ae Gatien Chevallier 2023-09-08 393 /* Do not save that RNG is enabled as it will be handled at resume */ f81a08733f43ae Gatien Chevallier 2023-09-08 394 priv->pm_conf.cr = readl_relaxed(priv->base + RNG_CR) & ~RNG_CR_RNGEN; f81a08733f43ae Gatien Chevallier 2023-09-08 395 f81a08733f43ae Gatien Chevallier 2023-09-08 396 writel_relaxed(priv->pm_conf.cr, priv->base + RNG_CR); f81a08733f43ae Gatien Chevallier 2023-09-08 397 f81a08733f43ae Gatien Chevallier 2023-09-08 398 clk_disable_unprepare(priv->clk); f81a08733f43ae Gatien Chevallier 2023-09-08 399 f81a08733f43ae Gatien Chevallier 2023-09-08 400 return 0; f81a08733f43ae Gatien Chevallier 2023-09-08 401 } f81a08733f43ae Gatien Chevallier 2023-09-08 402 c6a97c42e399ad Daniel Thompson 2015-10-12 @403 static int stm32_rng_runtime_resume(struct device *dev) c6a97c42e399ad Daniel Thompson 2015-10-12 404 { f81a08733f43ae Gatien Chevallier 2023-09-08 405 struct stm32_rng_private *priv = dev_get_drvdata(dev); f81a08733f43ae Gatien Chevallier 2023-09-08 406 int err; d9494cfe524b05 Gatien Chevallier 2023-09-08 407 u32 reg; f81a08733f43ae Gatien Chevallier 2023-09-08 408 f81a08733f43ae Gatien Chevallier 2023-09-08 409 err = clk_prepare_enable(priv->clk); f81a08733f43ae Gatien Chevallier 2023-09-08 410 if (err) f81a08733f43ae Gatien Chevallier 2023-09-08 411 return err; f81a08733f43ae Gatien Chevallier 2023-09-08 412 f81a08733f43ae Gatien Chevallier 2023-09-08 413 /* Clean error indications */ f81a08733f43ae Gatien Chevallier 2023-09-08 414 writel_relaxed(0, priv->base + RNG_SR); f81a08733f43ae Gatien Chevallier 2023-09-08 415 f81a08733f43ae Gatien Chevallier 2023-09-08 416 reg = readl_relaxed(priv->base + RNG_CR); f81a08733f43ae Gatien Chevallier 2023-09-08 417 reg |= RNG_CR_RNGEN; f81a08733f43ae Gatien Chevallier 2023-09-08 418 writel_relaxed(reg, priv->base + RNG_CR); f81a08733f43ae Gatien Chevallier 2023-09-08 419 f81a08733f43ae Gatien Chevallier 2023-09-08 420 return 0; f81a08733f43ae Gatien Chevallier 2023-09-08 421 } f81a08733f43ae Gatien Chevallier 2023-09-08 422
diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c index 0243b889ac54..3ac6712324c7 100644 --- a/drivers/char/hw_random/stm32-rng.c +++ b/drivers/char/hw_random/stm32-rng.c @@ -55,11 +55,25 @@ struct stm32_rng_data { bool has_cond_reset; }; +/** + * struct stm32_rng_config - RNG configuration data + * + * @cr: RNG configuration. 0 means default hardware RNG configuration + * @nscr: Noise sources control configuration. + * @htcr: Health tests configuration. + */ +struct stm32_rng_config { + u32 cr; + u32 nscr; + u32 htcr; +}; + struct stm32_rng_private { struct hwrng rng; void __iomem *base; struct clk *clk; struct reset_control *rst; + struct stm32_rng_config pm_conf; const struct stm32_rng_data *data; bool ced; bool lock_conf; @@ -355,11 +369,10 @@ static int stm32_rng_remove(struct platform_device *ofdev) return 0; } -#ifdef CONFIG_PM static int stm32_rng_runtime_suspend(struct device *dev) { - u32 reg; struct stm32_rng_private *priv = dev_get_drvdata(dev); + u32 reg; reg = readl_relaxed(priv->base + RNG_CR); reg &= ~RNG_CR_RNGEN; @@ -369,25 +382,98 @@ static int stm32_rng_runtime_suspend(struct device *dev) return 0; } +static int __maybe_unused stm32_rng_suspend(struct device *dev) +{ + struct stm32_rng_private *priv = dev_get_drvdata(dev); + + if (priv->data->has_cond_reset) { + priv->pm_conf.nscr = readl_relaxed(priv->base + RNG_NSCR); + priv->pm_conf.htcr = readl_relaxed(priv->base + RNG_HTCR); + } + + /* Do not save that RNG is enabled as it will be handled at resume */ + priv->pm_conf.cr = readl_relaxed(priv->base + RNG_CR) & ~RNG_CR_RNGEN; + + writel_relaxed(priv->pm_conf.cr, priv->base + RNG_CR); + + clk_disable_unprepare(priv->clk); + + return 0; +} + static int stm32_rng_runtime_resume(struct device *dev) { - u32 reg; struct stm32_rng_private *priv = dev_get_drvdata(dev); + int err; + u32 reg; + + err = clk_prepare_enable(priv->clk); + if (err) + return err; + + /* Clean error indications */ + writel_relaxed(0, priv->base + RNG_SR); - clk_prepare_enable(priv->clk); reg = readl_relaxed(priv->base + RNG_CR); reg |= RNG_CR_RNGEN; writel_relaxed(reg, priv->base + RNG_CR); return 0; } -#endif + +static int __maybe_unused stm32_rng_resume(struct device *dev) +{ + struct stm32_rng_private *priv = dev_get_drvdata(dev); + int err; + u32 reg; + + err = clk_prepare_enable(priv->clk); + if (err) + return err; + + /* Clean error indications */ + writel_relaxed(0, priv->base + RNG_SR); + + if (priv->data->has_cond_reset) { + /* + * Correct configuration in bits [29:4] must be set in the same + * access that set RNG_CR_CONDRST bit. Else config setting is + * not taken into account. CONFIGLOCK bit must also be unset but + * it is not handled at the moment. + */ + writel_relaxed(priv->pm_conf.cr | RNG_CR_CONDRST, priv->base + RNG_CR); + + writel_relaxed(priv->pm_conf.nscr, priv->base + RNG_NSCR); + writel_relaxed(priv->pm_conf.htcr, priv->base + RNG_HTCR); + + reg = readl_relaxed(priv->base + RNG_CR); + reg |= RNG_CR_RNGEN; + reg &= ~RNG_CR_CONDRST; + writel_relaxed(reg, priv->base + RNG_CR); + + err = readl_relaxed_poll_timeout_atomic(priv->base + RNG_CR, reg, + reg & ~RNG_CR_CONDRST, 10, 100000); + + if (err) { + clk_disable_unprepare(priv->clk); + dev_err((struct device *)priv->rng.priv, + "%s: timeout:%x CR: %x!\n", __func__, err, reg); + return -EINVAL; + } + } else { + reg = priv->pm_conf.cr; + reg |= RNG_CR_RNGEN; + writel_relaxed(reg, priv->base + RNG_CR); + } + + return 0; +} static const struct dev_pm_ops stm32_rng_pm_ops = { SET_RUNTIME_PM_OPS(stm32_rng_runtime_suspend, stm32_rng_runtime_resume, NULL) - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) + SET_SYSTEM_SLEEP_PM_OPS(stm32_rng_suspend, + stm32_rng_resume) }; static const struct stm32_rng_data stm32mp13_rng_data = {
Implement stm32_rng_suspend()/stm32_rng_resume() low-power APIs called when the hardware block context will be lost. There is no need to save the RNG_CR register in stm32_rng_runtime_suspend() as the context is not lost. Therefore, only enable/disable the RNG in the runtime sequences. Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com> --- drivers/char/hw_random/stm32-rng.c | 100 +++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 7 deletions(-)