diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/hw_random/timeriomem-rng.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c index 10ad41be5897..dcd352ad0e7f 100644 --- a/drivers/char/hw_random/timeriomem-rng.c +++ b/drivers/char/hw_random/timeriomem-rng.c | |||
@@ -90,10 +90,30 @@ static struct hwrng timeriomem_rng_ops = { | |||
90 | 90 | ||
91 | static int __init timeriomem_rng_probe(struct platform_device *pdev) | 91 | static int __init timeriomem_rng_probe(struct platform_device *pdev) |
92 | { | 92 | { |
93 | struct resource *res, *mem; | ||
93 | int ret; | 94 | int ret; |
94 | 95 | ||
96 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
97 | |||
98 | if (!res) | ||
99 | return -ENOENT; | ||
100 | |||
101 | mem = request_mem_region(res->start, res->end - res->start + 1, | ||
102 | pdev->name); | ||
103 | if (mem == NULL) | ||
104 | return -EBUSY; | ||
105 | |||
106 | dev_set_drvdata(&pdev->dev, mem); | ||
107 | |||
95 | timeriomem_rng_data = pdev->dev.platform_data; | 108 | timeriomem_rng_data = pdev->dev.platform_data; |
96 | 109 | ||
110 | timeriomem_rng_data->address = ioremap(res->start, | ||
111 | res->end - res->start + 1); | ||
112 | if (!timeriomem_rng_data->address) { | ||
113 | ret = -ENOMEM; | ||
114 | goto err_ioremap; | ||
115 | } | ||
116 | |||
97 | if (timeriomem_rng_data->period != 0 | 117 | if (timeriomem_rng_data->period != 0 |
98 | && usecs_to_jiffies(timeriomem_rng_data->period) > 0) { | 118 | && usecs_to_jiffies(timeriomem_rng_data->period) > 0) { |
99 | timeriomem_rng_timer.expires = jiffies; | 119 | timeriomem_rng_timer.expires = jiffies; |
@@ -104,23 +124,34 @@ static int __init timeriomem_rng_probe(struct platform_device *pdev) | |||
104 | timeriomem_rng_data->present = 1; | 124 | timeriomem_rng_data->present = 1; |
105 | 125 | ||
106 | ret = hwrng_register(&timeriomem_rng_ops); | 126 | ret = hwrng_register(&timeriomem_rng_ops); |
107 | if (ret) { | 127 | if (ret) |
108 | dev_err(&pdev->dev, "problem registering\n"); | 128 | goto err_register; |
109 | return ret; | ||
110 | } | ||
111 | 129 | ||
112 | dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n", | 130 | dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n", |
113 | timeriomem_rng_data->address, | 131 | timeriomem_rng_data->address, |
114 | timeriomem_rng_data->period); | 132 | timeriomem_rng_data->period); |
115 | 133 | ||
116 | return 0; | 134 | return 0; |
135 | |||
136 | err_register: | ||
137 | dev_err(&pdev->dev, "problem registering\n"); | ||
138 | iounmap(timeriomem_rng_data->address); | ||
139 | err_ioremap: | ||
140 | release_resource(mem); | ||
141 | |||
142 | return ret; | ||
117 | } | 143 | } |
118 | 144 | ||
119 | static int __devexit timeriomem_rng_remove(struct platform_device *pdev) | 145 | static int __devexit timeriomem_rng_remove(struct platform_device *pdev) |
120 | { | 146 | { |
147 | struct resource *mem = dev_get_drvdata(&pdev->dev); | ||
148 | |||
121 | del_timer_sync(&timeriomem_rng_timer); | 149 | del_timer_sync(&timeriomem_rng_timer); |
122 | hwrng_unregister(&timeriomem_rng_ops); | 150 | hwrng_unregister(&timeriomem_rng_ops); |
123 | 151 | ||
152 | iounmap(timeriomem_rng_data->address); | ||
153 | release_resource(mem); | ||
154 | |||
124 | return 0; | 155 | return 0; |
125 | } | 156 | } |
126 | 157 | ||