Commit 9468613b2bb0a386af563953b613efc6c77bd8c1
Committed by
Russell King
1 parent
84b5abe69f
Exists in
master
and in
7 other branches
[ARM] Fix suspend oops caused by PXA2xx PCMCIA driver
The PXA2xx PCMCIA driver was registering a device_driver with the platform_bus_type. Unfortunately, this causes data outside the device_driver structure to be dereferenced as if it were a platform_driver structure, causing an oops. Convert the PXA2xx core driver to use the proper platform_driver structure. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Showing 3 changed files with 31 additions and 14 deletions Side-by-side Diff
drivers/pcmcia/pxa2xx_base.c
... | ... | @@ -166,7 +166,7 @@ |
166 | 166 | } |
167 | 167 | #endif |
168 | 168 | |
169 | -int pxa2xx_drv_pcmcia_probe(struct device *dev) | |
169 | +int __pxa2xx_drv_pcmcia_probe(struct device *dev) | |
170 | 170 | { |
171 | 171 | int ret; |
172 | 172 | struct pcmcia_low_level *ops; |
173 | 173 | |
174 | 174 | |
175 | 175 | |
176 | 176 | |
177 | 177 | |
178 | 178 | |
179 | 179 | |
180 | 180 | |
... | ... | @@ -203,35 +203,52 @@ |
203 | 203 | |
204 | 204 | return ret; |
205 | 205 | } |
206 | -EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe); | |
206 | +EXPORT_SYMBOL(__pxa2xx_drv_pcmcia_probe); | |
207 | 207 | |
208 | -static int pxa2xx_drv_pcmcia_resume(struct device *dev) | |
208 | + | |
209 | +static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | |
209 | 210 | { |
210 | - struct pcmcia_low_level *ops = dev->platform_data; | |
211 | + return __pxa2xx_drv_pcmcia_probe(&dev->dev); | |
212 | +} | |
213 | + | |
214 | +static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev) | |
215 | +{ | |
216 | + return soc_common_drv_pcmcia_remove(&dev->dev); | |
217 | +} | |
218 | + | |
219 | +static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t state) | |
220 | +{ | |
221 | + return pcmcia_socket_dev_suspend(&dev->dev, state); | |
222 | +} | |
223 | + | |
224 | +static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev) | |
225 | +{ | |
226 | + struct pcmcia_low_level *ops = dev->dev.platform_data; | |
211 | 227 | int nr = ops ? ops->nr : 0; |
212 | 228 | |
213 | 229 | MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0); |
214 | 230 | |
215 | - return pcmcia_socket_dev_resume(dev); | |
231 | + return pcmcia_socket_dev_resume(&dev->dev); | |
216 | 232 | } |
217 | 233 | |
218 | -static struct device_driver pxa2xx_pcmcia_driver = { | |
234 | +static struct platform_driver pxa2xx_pcmcia_driver = { | |
219 | 235 | .probe = pxa2xx_drv_pcmcia_probe, |
220 | - .remove = soc_common_drv_pcmcia_remove, | |
221 | - .suspend = pcmcia_socket_dev_suspend, | |
236 | + .remove = pxa2xx_drv_pcmcia_remove, | |
237 | + .suspend = pxa2xx_drv_pcmcia_suspend, | |
222 | 238 | .resume = pxa2xx_drv_pcmcia_resume, |
223 | - .name = "pxa2xx-pcmcia", | |
224 | - .bus = &platform_bus_type, | |
239 | + .driver = { | |
240 | + .name = "pxa2xx-pcmcia", | |
241 | + }, | |
225 | 242 | }; |
226 | 243 | |
227 | 244 | static int __init pxa2xx_pcmcia_init(void) |
228 | 245 | { |
229 | - return driver_register(&pxa2xx_pcmcia_driver); | |
246 | + return platform_driver_register(&pxa2xx_pcmcia_driver); | |
230 | 247 | } |
231 | 248 | |
232 | 249 | static void __exit pxa2xx_pcmcia_exit(void) |
233 | 250 | { |
234 | - driver_unregister(&pxa2xx_pcmcia_driver); | |
251 | + platform_driver_unregister(&pxa2xx_pcmcia_driver); | |
235 | 252 | } |
236 | 253 | |
237 | 254 | fs_initcall(pxa2xx_pcmcia_init); |
drivers/pcmcia/pxa2xx_base.h
drivers/pcmcia/pxa2xx_lubbock.c