aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Clouter <alex@digriz.org.uk>2009-06-03 05:28:03 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2009-06-03 05:28:03 -0400
commit08ced854fc4a979d9e59ba01000bf96e7057cfbc (patch)
treef290c5ebb2f7627fb67196fcc5738d44ef243443
parentaa07a6990f4b6a8ef9fc538dea55bac6f92255f2 (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.c26
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
91static int __init timeriomem_rng_probe(struct platform_device *pdev) 91static 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
136err_register: 127failed:
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);
139err_ioremap:
140 release_resource(mem);
141 130
142 return ret; 131 return ret;
143} 132}
144 133
145static int __devexit timeriomem_rng_remove(struct platform_device *pdev) 134static 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}