aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/hw_random/bcm2835-rng.c
diff options
context:
space:
mode:
authorMatt Porter <mporter@linaro.org>2014-04-10 15:22:10 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2014-04-11 11:31:13 +0800
commiteb4a5346e777784f1b5ae9fd0c29b96344bdc3ae (patch)
tree9803168c7b40fd074d3140436547a58c6c0365dd /drivers/char/hw_random/bcm2835-rng.c
parentMerge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 (diff)
downloadlinux-dev-eb4a5346e777784f1b5ae9fd0c29b96344bdc3ae.tar.xz
linux-dev-eb4a5346e777784f1b5ae9fd0c29b96344bdc3ae.zip
hwrng: bcm2835 - fix oops when rng h/w is accessed during registration
Commit "d9e7972 hwrng: add randomness to system from rng sources" exposed a bug in the bcm2835-rng driver resulting in boot failure on Raspberry Pi due to the following oops: [ 28.261523] BUG: soft lockup - CPU#0 stuck for 23s! [swapper:1] [ 28.271058] [ 28.275958] CPU: 0 PID: 1 Comm: swapper Not tainted 3.14.0+ #11 [ 28.285374] task: db480000 ti: db484000 task.ti: db484000 [ 28.294279] PC is at bcm2835_rng_read+0x28/0x48 [ 28.302276] LR is at hwrng_register+0x1a8/0x238 . . . The RNG h/w is not completely initialized and enabled before hwrng_register() is called and so the bcm2835_rng_read() fails. Fix this by making the warmup/enable writes before registering the RNG source with the hwrng core. Signed-off-by: Matt Porter <mporter@linaro.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/char/hw_random/bcm2835-rng.c')
-rw-r--r--drivers/char/hw_random/bcm2835-rng.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c
index 8c3b255e629a..e900961cdd2e 100644
--- a/drivers/char/hw_random/bcm2835-rng.c
+++ b/drivers/char/hw_random/bcm2835-rng.c
@@ -61,18 +61,18 @@ static int bcm2835_rng_probe(struct platform_device *pdev)
}
bcm2835_rng_ops.priv = (unsigned long)rng_base;
+ /* set warm-up count & enable */
+ __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
+ __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
+
/* register driver */
err = hwrng_register(&bcm2835_rng_ops);
if (err) {
dev_err(dev, "hwrng registration failed\n");
iounmap(rng_base);
- } else {
+ } else
dev_info(dev, "hwrng registered\n");
- /* set warm-up count & enable */
- __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
- __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
- }
return err;
}