]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/char/omap-rng.c
ARM: OMAP: Replace clock.h with clk.h
[linux-2.6-omap-h63xx.git] / drivers / char / omap-rng.c
1 /*
2  * drivers/char/omap-rng.c
3  *
4  * Copyright (C) 2005 Nokia Corporation
5  * Author: Juha Yrjölä <juha.yrjola@nokia.com>
6  *
7  * OMAP16xx and OMAP24xx Random Number Generator driver
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  *
13  */
14
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/random.h>
18 #include <linux/err.h>
19 #include <linux/clk.h>
20
21 #include <asm/io.h>
22
23 #if defined (CONFIG_ARCH_OMAP16XX)
24 #define RNG_BASE                0xfffe5000
25 #endif
26 #if defined (CONFIG_ARCH_OMAP24XX)
27 #define RNG_BASE                0x480A0000
28 #endif
29
30 #define RNG_OUT_REG             0x00            /* Output register */
31 #define RNG_STAT_REG            0x04            /* Status register
32                                                         [0] = STAT_BUSY */
33 #define RNG_ALARM_REG           0x24            /* Alarm register
34                                                         [7:0] = ALARM_COUNTER */
35 #define RNG_CONFIG_REG          0x28            /* Configuration register
36                                                         [11:6] = RESET_COUNT
37                                                         [5:3]  = RING2_DELAY 
38                                                         [2:0]  = RING1_DELAY */
39 #define RNG_REV_REG             0x3c            /* Revision register
40                                                         [7:0] = REV_NB */
41 #define RNG_MASK_REG            0x40            /* Mask and reset register
42                                                         [2] = IT_EN
43                                                         [1] = SOFTRESET
44                                                         [0] = AUTOIDLE */
45 #define RNG_SYSSTATUS           0x44            /* System status
46                                                         [0] = RESETDONE */
47
48 #define ENTROPY_WORD_COUNT      128
49
50 static u32 rng_base = io_p2v(RNG_BASE);
51
52 static struct clk *rng_ick = NULL;
53
54 static u32 rng_read_reg(int reg)
55 {
56         return __raw_readl(rng_base + reg);
57 }
58
59 static void rng_write_reg(int reg, u32 val)
60 {
61         __raw_writel(val, rng_base + reg);
62 }
63
64 static void rng_feed_entropy(int count)
65 {
66         u32 l;
67
68         while (count--) {
69                 while (rng_read_reg(RNG_STAT_REG));
70                 l = rng_read_reg(RNG_OUT_REG);
71                 add_input_randomness(0, 0, l);
72         }
73 }
74
75 static int __init rng_init(void)
76 {
77         if (!cpu_is_omap16xx() && !cpu_is_omap24xx())
78                 return -ENODEV;
79
80         if (cpu_is_omap24xx()) {
81                 rng_ick = clk_get(NULL, "rng_ick");
82                 if (IS_ERR(rng_ick)) {
83                         printk(KERN_ERR "omap-rng.c: Could not get rng_ick\n");
84                         return PTR_ERR(rng_ick);
85                 }
86                 clk_enable(rng_ick);
87         }
88
89         printk("OMAP Random Number Generator ver. %02x\n",
90         rng_read_reg(RNG_REV_REG));
91         rng_write_reg(RNG_MASK_REG, 0x00000001);
92         rng_feed_entropy(ENTROPY_WORD_COUNT);
93         rng_write_reg(RNG_MASK_REG, 0x00000000);
94         printk("%d words of entropy generated\n", ENTROPY_WORD_COUNT);
95
96         return 0;
97 }
98 late_initcall(rng_init);