diff options
author | Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com> | 2016-05-27 06:10:39 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-05-31 05:52:23 -0400 |
commit | 422a7491459b4d989259cd94fd21f4fbde382930 (patch) | |
tree | 573a5550f2e29eff66b489e50e20d63de0da2a0b /drivers/char | |
parent | f8e4f9a0a85d3589d20c4c9f20e576cc8d3c99b6 (diff) |
hwrng: bcm2835 - Support Broadcom NSP SoC rng
This supports the random number generator available in NSP SoC.
Masks the rng interrupt for NSP.
Signed-off-by: Yendapally Reddy Dhananjaya Reddy <yendapally.reddy@broadcom.com>
Acked-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/hw_random/Kconfig | 2 | ||||
-rw-r--r-- | drivers/char/hw_random/bcm2835-rng.c | 34 |
2 files changed, 31 insertions, 5 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index ac51149e9777..43d527ea9014 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -90,7 +90,7 @@ config HW_RANDOM_BCM63XX | |||
90 | 90 | ||
91 | config HW_RANDOM_BCM2835 | 91 | config HW_RANDOM_BCM2835 |
92 | tristate "Broadcom BCM2835 Random Number Generator support" | 92 | tristate "Broadcom BCM2835 Random Number Generator support" |
93 | depends on ARCH_BCM2835 | 93 | depends on ARCH_BCM2835 || ARCH_BCM_NSP |
94 | default HW_RANDOM | 94 | default HW_RANDOM |
95 | ---help--- | 95 | ---help--- |
96 | This driver provides kernel-side support for the Random Number | 96 | This driver provides kernel-side support for the Random Number |
diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c index 7192ec25f667..b1e8b7847e9a 100644 --- a/drivers/char/hw_random/bcm2835-rng.c +++ b/drivers/char/hw_random/bcm2835-rng.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #define RNG_CTRL 0x0 | 19 | #define RNG_CTRL 0x0 |
20 | #define RNG_STATUS 0x4 | 20 | #define RNG_STATUS 0x4 |
21 | #define RNG_DATA 0x8 | 21 | #define RNG_DATA 0x8 |
22 | #define RNG_INT_MASK 0x10 | ||
22 | 23 | ||
23 | /* enable rng */ | 24 | /* enable rng */ |
24 | #define RNG_RBGEN 0x1 | 25 | #define RNG_RBGEN 0x1 |
@@ -26,6 +27,18 @@ | |||
26 | /* the initial numbers generated are "less random" so will be discarded */ | 27 | /* the initial numbers generated are "less random" so will be discarded */ |
27 | #define RNG_WARMUP_COUNT 0x40000 | 28 | #define RNG_WARMUP_COUNT 0x40000 |
28 | 29 | ||
30 | #define RNG_INT_OFF 0x1 | ||
31 | |||
32 | static void __init nsp_rng_init(void __iomem *base) | ||
33 | { | ||
34 | u32 val; | ||
35 | |||
36 | /* mask the interrupt */ | ||
37 | val = readl(base + RNG_INT_MASK); | ||
38 | val |= RNG_INT_OFF; | ||
39 | writel(val, base + RNG_INT_MASK); | ||
40 | } | ||
41 | |||
29 | static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max, | 42 | static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max, |
30 | bool wait) | 43 | bool wait) |
31 | { | 44 | { |
@@ -46,10 +59,18 @@ static struct hwrng bcm2835_rng_ops = { | |||
46 | .read = bcm2835_rng_read, | 59 | .read = bcm2835_rng_read, |
47 | }; | 60 | }; |
48 | 61 | ||
62 | static const struct of_device_id bcm2835_rng_of_match[] = { | ||
63 | { .compatible = "brcm,bcm2835-rng"}, | ||
64 | { .compatible = "brcm,bcm-nsp-rng", .data = nsp_rng_init}, | ||
65 | {}, | ||
66 | }; | ||
67 | |||
49 | static int bcm2835_rng_probe(struct platform_device *pdev) | 68 | static int bcm2835_rng_probe(struct platform_device *pdev) |
50 | { | 69 | { |
51 | struct device *dev = &pdev->dev; | 70 | struct device *dev = &pdev->dev; |
52 | struct device_node *np = dev->of_node; | 71 | struct device_node *np = dev->of_node; |
72 | void (*rng_setup)(void __iomem *base); | ||
73 | const struct of_device_id *rng_id; | ||
53 | void __iomem *rng_base; | 74 | void __iomem *rng_base; |
54 | int err; | 75 | int err; |
55 | 76 | ||
@@ -61,6 +82,15 @@ static int bcm2835_rng_probe(struct platform_device *pdev) | |||
61 | } | 82 | } |
62 | bcm2835_rng_ops.priv = (unsigned long)rng_base; | 83 | bcm2835_rng_ops.priv = (unsigned long)rng_base; |
63 | 84 | ||
85 | rng_id = of_match_node(bcm2835_rng_of_match, np); | ||
86 | if (!rng_id) | ||
87 | return -EINVAL; | ||
88 | |||
89 | /* Check for rng init function, execute it */ | ||
90 | rng_setup = rng_id->data; | ||
91 | if (rng_setup) | ||
92 | rng_setup(rng_base); | ||
93 | |||
64 | /* set warm-up count & enable */ | 94 | /* set warm-up count & enable */ |
65 | __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS); | 95 | __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS); |
66 | __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL); | 96 | __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL); |
@@ -90,10 +120,6 @@ static int bcm2835_rng_remove(struct platform_device *pdev) | |||
90 | return 0; | 120 | return 0; |
91 | } | 121 | } |
92 | 122 | ||
93 | static const struct of_device_id bcm2835_rng_of_match[] = { | ||
94 | { .compatible = "brcm,bcm2835-rng", }, | ||
95 | {}, | ||
96 | }; | ||
97 | MODULE_DEVICE_TABLE(of, bcm2835_rng_of_match); | 123 | MODULE_DEVICE_TABLE(of, bcm2835_rng_of_match); |
98 | 124 | ||
99 | static struct platform_driver bcm2835_rng_driver = { | 125 | static struct platform_driver bcm2835_rng_driver = { |