diff options
author | Alexander Clouter <alex@digriz.org.uk> | 2009-06-03 05:28:03 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2009-06-03 05:28:03 -0400 |
commit | 08ced854fc4a979d9e59ba01000bf96e7057cfbc (patch) | |
tree | f290c5ebb2f7627fb67196fcc5738d44ef243443 | |
parent | aa07a6990f4b6a8ef9fc538dea55bac6f92255f2 (diff) |
hwrng: timeriomem - Fix potential oops (request_mem_region/__devinit)
Fixed oops when calling device_unregister followed by device_register
(changing __init to __devinit) and removed request_mem_region() as
platform_device_register already does this which can result in EBUSY
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | drivers/char/hw_random/timeriomem-rng.c | 26 |
1 files changed, 6 insertions, 20 deletions
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c index dcd352ad0e7f..a94e930575f2 100644 --- a/drivers/char/hw_random/timeriomem-rng.c +++ b/drivers/char/hw_random/timeriomem-rng.c | |||
@@ -88,9 +88,9 @@ static struct hwrng timeriomem_rng_ops = { | |||
88 | .priv = 0, | 88 | .priv = 0, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | static int __init timeriomem_rng_probe(struct platform_device *pdev) | 91 | static int __devinit timeriomem_rng_probe(struct platform_device *pdev) |
92 | { | 92 | { |
93 | struct resource *res, *mem; | 93 | struct resource *res; |
94 | int ret; | 94 | int ret; |
95 | 95 | ||
96 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 96 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -98,21 +98,12 @@ static int __init timeriomem_rng_probe(struct platform_device *pdev) | |||
98 | if (!res) | 98 | if (!res) |
99 | return -ENOENT; | 99 | return -ENOENT; |
100 | 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 | |||
108 | timeriomem_rng_data = pdev->dev.platform_data; | 101 | timeriomem_rng_data = pdev->dev.platform_data; |
109 | 102 | ||
110 | timeriomem_rng_data->address = ioremap(res->start, | 103 | timeriomem_rng_data->address = ioremap(res->start, |
111 | res->end - res->start + 1); | 104 | res->end - res->start + 1); |
112 | if (!timeriomem_rng_data->address) { | 105 | if (!timeriomem_rng_data->address) |
113 | ret = -ENOMEM; | 106 | return -EIO; |
114 | goto err_ioremap; | ||
115 | } | ||
116 | 107 | ||
117 | if (timeriomem_rng_data->period != 0 | 108 | if (timeriomem_rng_data->period != 0 |
118 | && usecs_to_jiffies(timeriomem_rng_data->period) > 0) { | 109 | && usecs_to_jiffies(timeriomem_rng_data->period) > 0) { |
@@ -125,7 +116,7 @@ static int __init timeriomem_rng_probe(struct platform_device *pdev) | |||
125 | 116 | ||
126 | ret = hwrng_register(&timeriomem_rng_ops); | 117 | ret = hwrng_register(&timeriomem_rng_ops); |
127 | if (ret) | 118 | if (ret) |
128 | goto err_register; | 119 | goto failed; |
129 | 120 | ||
130 | dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n", | 121 | dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n", |
131 | timeriomem_rng_data->address, | 122 | timeriomem_rng_data->address, |
@@ -133,24 +124,19 @@ static int __init timeriomem_rng_probe(struct platform_device *pdev) | |||
133 | 124 | ||
134 | return 0; | 125 | return 0; |
135 | 126 | ||
136 | err_register: | 127 | failed: |
137 | dev_err(&pdev->dev, "problem registering\n"); | 128 | dev_err(&pdev->dev, "problem registering\n"); |
138 | iounmap(timeriomem_rng_data->address); | 129 | iounmap(timeriomem_rng_data->address); |
139 | err_ioremap: | ||
140 | release_resource(mem); | ||
141 | 130 | ||
142 | return ret; | 131 | return ret; |
143 | } | 132 | } |
144 | 133 | ||
145 | static int __devexit timeriomem_rng_remove(struct platform_device *pdev) | 134 | static int __devexit timeriomem_rng_remove(struct platform_device *pdev) |
146 | { | 135 | { |
147 | struct resource *mem = dev_get_drvdata(&pdev->dev); | ||
148 | |||
149 | del_timer_sync(&timeriomem_rng_timer); | 136 | del_timer_sync(&timeriomem_rng_timer); |
150 | hwrng_unregister(&timeriomem_rng_ops); | 137 | hwrng_unregister(&timeriomem_rng_ops); |
151 | 138 | ||
152 | iounmap(timeriomem_rng_data->address); | 139 | iounmap(timeriomem_rng_data->address); |
153 | release_resource(mem); | ||
154 | 140 | ||
155 | return 0; | 141 | return 0; |
156 | } | 142 | } |