diff options
author | Aaro Koskinen <aaro.koskinen@iki.fi> | 2015-11-18 14:59:01 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-11-23 07:55:54 -0500 |
commit | 4c13ac1cf0e40c1fea8993354e54822ef643425e (patch) | |
tree | 546ba7ff47448880ca37ab54a0aa3185ff46aefa /drivers/char | |
parent | 56b85c9d7a45a90bf7cb8b5e8c2693f8064b2c09 (diff) |
hwrng: omap3-rom - convert timer to delayed work
We cannot put the HW RNG to idle using a timer because we cannot disable
clocks from atomic context. Use a delayed work instead.
Fixes a warning with CONFIG_DEBUG_MUTEXES on Nokia N900 during boot.
Reported-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/hw_random/omap3-rom-rng.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c index a405cdcd8dd2..8da14f1a1f56 100644 --- a/drivers/char/hw_random/omap3-rom-rng.c +++ b/drivers/char/hw_random/omap3-rom-rng.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/random.h> | 18 | #include <linux/random.h> |
19 | #include <linux/hw_random.h> | 19 | #include <linux/hw_random.h> |
20 | #include <linux/timer.h> | 20 | #include <linux/workqueue.h> |
21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
@@ -29,11 +29,11 @@ | |||
29 | /* param1: ptr, param2: count, param3: flag */ | 29 | /* param1: ptr, param2: count, param3: flag */ |
30 | static u32 (*omap3_rom_rng_call)(u32, u32, u32); | 30 | static u32 (*omap3_rom_rng_call)(u32, u32, u32); |
31 | 31 | ||
32 | static struct timer_list idle_timer; | 32 | static struct delayed_work idle_work; |
33 | static int rng_idle; | 33 | static int rng_idle; |
34 | static struct clk *rng_clk; | 34 | static struct clk *rng_clk; |
35 | 35 | ||
36 | static void omap3_rom_rng_idle(unsigned long data) | 36 | static void omap3_rom_rng_idle(struct work_struct *work) |
37 | { | 37 | { |
38 | int r; | 38 | int r; |
39 | 39 | ||
@@ -51,7 +51,7 @@ static int omap3_rom_rng_get_random(void *buf, unsigned int count) | |||
51 | u32 r; | 51 | u32 r; |
52 | u32 ptr; | 52 | u32 ptr; |
53 | 53 | ||
54 | del_timer_sync(&idle_timer); | 54 | cancel_delayed_work_sync(&idle_work); |
55 | if (rng_idle) { | 55 | if (rng_idle) { |
56 | clk_prepare_enable(rng_clk); | 56 | clk_prepare_enable(rng_clk); |
57 | r = omap3_rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT); | 57 | r = omap3_rom_rng_call(0, 0, RNG_GEN_PRNG_HW_INIT); |
@@ -65,7 +65,7 @@ static int omap3_rom_rng_get_random(void *buf, unsigned int count) | |||
65 | 65 | ||
66 | ptr = virt_to_phys(buf); | 66 | ptr = virt_to_phys(buf); |
67 | r = omap3_rom_rng_call(ptr, count, RNG_GEN_HW); | 67 | r = omap3_rom_rng_call(ptr, count, RNG_GEN_HW); |
68 | mod_timer(&idle_timer, jiffies + msecs_to_jiffies(500)); | 68 | schedule_delayed_work(&idle_work, msecs_to_jiffies(500)); |
69 | if (r != 0) | 69 | if (r != 0) |
70 | return -EINVAL; | 70 | return -EINVAL; |
71 | return 0; | 71 | return 0; |
@@ -102,7 +102,7 @@ static int omap3_rom_rng_probe(struct platform_device *pdev) | |||
102 | return -EINVAL; | 102 | return -EINVAL; |
103 | } | 103 | } |
104 | 104 | ||
105 | setup_timer(&idle_timer, omap3_rom_rng_idle, 0); | 105 | INIT_DELAYED_WORK(&idle_work, omap3_rom_rng_idle); |
106 | rng_clk = devm_clk_get(&pdev->dev, "ick"); | 106 | rng_clk = devm_clk_get(&pdev->dev, "ick"); |
107 | if (IS_ERR(rng_clk)) { | 107 | if (IS_ERR(rng_clk)) { |
108 | pr_err("unable to get RNG clock\n"); | 108 | pr_err("unable to get RNG clock\n"); |
@@ -118,6 +118,7 @@ static int omap3_rom_rng_probe(struct platform_device *pdev) | |||
118 | 118 | ||
119 | static int omap3_rom_rng_remove(struct platform_device *pdev) | 119 | static int omap3_rom_rng_remove(struct platform_device *pdev) |
120 | { | 120 | { |
121 | cancel_delayed_work_sync(&idle_work); | ||
121 | hwrng_unregister(&omap3_rom_rng_ops); | 122 | hwrng_unregister(&omap3_rom_rng_ops); |
122 | clk_disable_unprepare(rng_clk); | 123 | clk_disable_unprepare(rng_clk); |
123 | return 0; | 124 | return 0; |