diff options
-rw-r--r-- | drivers/char/hw_random/amd-rng.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c index 4a99ac756f08..9959c762da2f 100644 --- a/drivers/char/hw_random/amd-rng.c +++ b/drivers/char/hw_random/amd-rng.c | |||
@@ -55,6 +55,7 @@ MODULE_DEVICE_TABLE(pci, pci_tbl); | |||
55 | struct amd768_priv { | 55 | struct amd768_priv { |
56 | void __iomem *iobase; | 56 | void __iomem *iobase; |
57 | struct pci_dev *pcidev; | 57 | struct pci_dev *pcidev; |
58 | u32 pmbase; | ||
58 | }; | 59 | }; |
59 | 60 | ||
60 | static int amd_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) | 61 | static int amd_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) |
@@ -148,33 +149,58 @@ found: | |||
148 | if (pmbase == 0) | 149 | if (pmbase == 0) |
149 | return -EIO; | 150 | return -EIO; |
150 | 151 | ||
151 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 152 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
152 | if (!priv) | 153 | if (!priv) |
153 | return -ENOMEM; | 154 | return -ENOMEM; |
154 | 155 | ||
155 | if (!devm_request_region(&pdev->dev, pmbase + PMBASE_OFFSET, | 156 | if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) { |
156 | PMBASE_SIZE, DRV_NAME)) { | ||
157 | dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n", | 157 | dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n", |
158 | pmbase + 0xF0); | 158 | pmbase + 0xF0); |
159 | return -EBUSY; | 159 | err = -EBUSY; |
160 | goto out; | ||
160 | } | 161 | } |
161 | 162 | ||
162 | priv->iobase = devm_ioport_map(&pdev->dev, pmbase + PMBASE_OFFSET, | 163 | priv->iobase = ioport_map(pmbase + PMBASE_OFFSET, PMBASE_SIZE); |
163 | PMBASE_SIZE); | ||
164 | if (!priv->iobase) { | 164 | if (!priv->iobase) { |
165 | pr_err(DRV_NAME "Cannot map ioport\n"); | 165 | pr_err(DRV_NAME "Cannot map ioport\n"); |
166 | return -ENOMEM; | 166 | err = -EINVAL; |
167 | goto err_iomap; | ||
167 | } | 168 | } |
168 | 169 | ||
169 | amd_rng.priv = (unsigned long)priv; | 170 | amd_rng.priv = (unsigned long)priv; |
171 | priv->pmbase = pmbase; | ||
170 | priv->pcidev = pdev; | 172 | priv->pcidev = pdev; |
171 | 173 | ||
172 | pr_info(DRV_NAME " detected\n"); | 174 | pr_info(DRV_NAME " detected\n"); |
173 | return devm_hwrng_register(&pdev->dev, &amd_rng); | 175 | err = hwrng_register(&amd_rng); |
176 | if (err) { | ||
177 | pr_err(DRV_NAME " registering failed (%d)\n", err); | ||
178 | goto err_hwrng; | ||
179 | } | ||
180 | return 0; | ||
181 | |||
182 | err_hwrng: | ||
183 | ioport_unmap(priv->iobase); | ||
184 | err_iomap: | ||
185 | release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
186 | out: | ||
187 | kfree(priv); | ||
188 | return err; | ||
174 | } | 189 | } |
175 | 190 | ||
176 | static void __exit mod_exit(void) | 191 | static void __exit mod_exit(void) |
177 | { | 192 | { |
193 | struct amd768_priv *priv; | ||
194 | |||
195 | priv = (struct amd768_priv *)amd_rng.priv; | ||
196 | |||
197 | hwrng_unregister(&amd_rng); | ||
198 | |||
199 | ioport_unmap(priv->iobase); | ||
200 | |||
201 | release_region(priv->pmbase + PMBASE_OFFSET, PMBASE_SIZE); | ||
202 | |||
203 | kfree(priv); | ||
178 | } | 204 | } |
179 | 205 | ||
180 | module_init(mod_init); | 206 | module_init(mod_init); |