Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
char
hw_random
nomadik-rng.c
Go to the documentation of this file.
1
/*
2
* Nomadik RNG support
3
* Copyright 2009 Alessandro Rubini
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
9
*/
10
11
#include <linux/kernel.h>
12
#include <linux/module.h>
13
#include <
linux/init.h
>
14
#include <linux/device.h>
15
#include <
linux/amba/bus.h
>
16
#include <
linux/hw_random.h
>
17
#include <
linux/io.h
>
18
#include <
linux/clk.h
>
19
#include <
linux/err.h
>
20
21
static
struct
clk
*rng_clk;
22
23
static
int
nmk_rng_read(
struct
hwrng
*rng,
void
*
data
,
size_t
max
,
bool
wait
)
24
{
25
void
__iomem
*
base
= (
void
__iomem
*)rng->
priv
;
26
27
/*
28
* The register is 32 bits and gives 16 random bits (low half).
29
* A subsequent read will delay the core for 400ns, so we just read
30
* once and accept the very unlikely very small delay, even if wait==0.
31
*/
32
*(
u16
*)data =
__raw_readl
(base + 8) & 0xffff;
33
return
2;
34
}
35
36
/* we have at most one RNG per machine, granted */
37
static
struct
hwrng
nmk_rng = {
38
.name =
"nomadik"
,
39
.read = nmk_rng_read,
40
};
41
42
static
int
nmk_rng_probe(
struct
amba_device
*
dev
,
const
struct
amba_id
*
id
)
43
{
44
void
__iomem
*
base
;
45
int
ret
;
46
47
rng_clk =
clk_get
(&dev->
dev
,
NULL
);
48
if
(IS_ERR(rng_clk)) {
49
dev_err
(&dev->
dev
,
"could not get rng clock\n"
);
50
ret = PTR_ERR(rng_clk);
51
return
ret
;
52
}
53
54
clk_enable
(rng_clk);
55
56
ret =
amba_request_regions
(dev, dev->
dev
.init_name);
57
if
(ret)
58
goto
out_clk;
59
ret = -
ENOMEM
;
60
base =
ioremap
(dev->
res
.start, resource_size(&dev->
res
));
61
if
(!base)
62
goto
out_release;
63
nmk_rng.
priv
= (
unsigned
long
)base;
64
ret =
hwrng_register
(&nmk_rng);
65
if
(ret)
66
goto
out_unmap;
67
return
0;
68
69
out_unmap:
70
iounmap
(base);
71
out_release:
72
amba_release_regions
(dev);
73
out_clk:
74
clk_disable
(rng_clk);
75
clk_put
(rng_clk);
76
return
ret
;
77
}
78
79
static
int
nmk_rng_remove(
struct
amba_device
*dev)
80
{
81
void
__iomem
*base = (
void
__iomem
*)nmk_rng.
priv
;
82
hwrng_unregister
(&nmk_rng);
83
iounmap
(base);
84
amba_release_regions
(dev);
85
clk_disable
(rng_clk);
86
clk_put
(rng_clk);
87
return
0;
88
}
89
90
static
struct
amba_id
nmk_rng_ids[] = {
91
{
92
.id = 0x000805e1,
93
.mask = 0x000fffff,
/* top bits are rev and cfg: accept all */
94
},
95
{0, 0},
96
};
97
98
MODULE_DEVICE_TABLE
(amba, nmk_rng_ids);
99
100
static
struct
amba_driver
nmk_rng_driver = {
101
.drv = {
102
.owner =
THIS_MODULE
,
103
.name =
"rng"
,
104
},
105
.probe = nmk_rng_probe,
106
.remove = nmk_rng_remove,
107
.id_table = nmk_rng_ids,
108
};
109
110
module_amba_driver
(nmk_rng_driver);
111
112
MODULE_LICENSE
(
"GPL"
);
Generated on Thu Jan 10 2013 13:27:39 for Linux Kernel by
1.8.2