diff options
author | Ming Lei <tom.leiming@gmail.com> | 2009-02-06 10:40:12 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-03-24 19:38:25 -0400 |
commit | 7a192ec334cab9fafe3a8665a65af398b0e24730 (patch) | |
tree | eea572863500f94d446cfded69835e188dba3447 /drivers/net | |
parent | 6da2d377bba06c29d0bc41c8dee014164dec82a7 (diff) |
platform driver: fix incorrect use of 'platform_bus_type' with 'struct device_driver'
This patch fixes the bug reported in
http://bugzilla.kernel.org/show_bug.cgi?id=11681.
"Lots of device drivers register a 'struct device_driver' with
the '.bus' member set to '&platform_bus_type'. This is wrong,
since the platform_bus functions expect the 'struct device_driver'
to be wrapped up in a 'struct platform_driver' which provides
some additional callbacks (like suspend_late, resume_early).
The effect may be that platform_suspend_late() uses bogus data
outside the device_driver struct as a pointer pointer to the
device driver's suspend_late() function or other hard to
reproduce failures."(Lothar Wassmann)
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Acked-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/mipsnet.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c index 4e7a5faf0351..664835b822fb 100644 --- a/drivers/net/mipsnet.c +++ b/drivers/net/mipsnet.c | |||
@@ -237,7 +237,7 @@ static void mipsnet_set_mclist(struct net_device *dev) | |||
237 | { | 237 | { |
238 | } | 238 | } |
239 | 239 | ||
240 | static int __init mipsnet_probe(struct device *dev) | 240 | static int __init mipsnet_probe(struct platform_device *dev) |
241 | { | 241 | { |
242 | struct net_device *netdev; | 242 | struct net_device *netdev; |
243 | int err; | 243 | int err; |
@@ -248,7 +248,7 @@ static int __init mipsnet_probe(struct device *dev) | |||
248 | goto out; | 248 | goto out; |
249 | } | 249 | } |
250 | 250 | ||
251 | dev_set_drvdata(dev, netdev); | 251 | platform_set_drvdata(dev, netdev); |
252 | 252 | ||
253 | netdev->open = mipsnet_open; | 253 | netdev->open = mipsnet_open; |
254 | netdev->stop = mipsnet_close; | 254 | netdev->stop = mipsnet_close; |
@@ -293,23 +293,25 @@ out: | |||
293 | return err; | 293 | return err; |
294 | } | 294 | } |
295 | 295 | ||
296 | static int __devexit mipsnet_device_remove(struct device *device) | 296 | static int __devexit mipsnet_device_remove(struct platform_device *device) |
297 | { | 297 | { |
298 | struct net_device *dev = dev_get_drvdata(device); | 298 | struct net_device *dev = platform_get_drvdata(device); |
299 | 299 | ||
300 | unregister_netdev(dev); | 300 | unregister_netdev(dev); |
301 | release_region(dev->base_addr, sizeof(struct mipsnet_regs)); | 301 | release_region(dev->base_addr, sizeof(struct mipsnet_regs)); |
302 | free_netdev(dev); | 302 | free_netdev(dev); |
303 | dev_set_drvdata(device, NULL); | 303 | platform_set_drvdata(device, NULL); |
304 | 304 | ||
305 | return 0; | 305 | return 0; |
306 | } | 306 | } |
307 | 307 | ||
308 | static struct device_driver mipsnet_driver = { | 308 | static struct platform_driver mipsnet_driver = { |
309 | .name = mipsnet_string, | 309 | .driver = { |
310 | .bus = &platform_bus_type, | 310 | .name = mipsnet_string, |
311 | .probe = mipsnet_probe, | 311 | .owner = THIS_MODULE, |
312 | .remove = __devexit_p(mipsnet_device_remove), | 312 | }, |
313 | .probe = mipsnet_probe, | ||
314 | .remove = __devexit_p(mipsnet_device_remove), | ||
313 | }; | 315 | }; |
314 | 316 | ||
315 | static int __init mipsnet_init_module(void) | 317 | static int __init mipsnet_init_module(void) |
@@ -319,7 +321,7 @@ static int __init mipsnet_init_module(void) | |||
319 | printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. " | 321 | printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. " |
320 | "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION); | 322 | "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION); |
321 | 323 | ||
322 | err = driver_register(&mipsnet_driver); | 324 | err = platform_driver_register(&mipsnet_driver); |
323 | if (err) | 325 | if (err) |
324 | printk(KERN_ERR "Driver registration failed\n"); | 326 | printk(KERN_ERR "Driver registration failed\n"); |
325 | 327 | ||
@@ -328,7 +330,7 @@ static int __init mipsnet_init_module(void) | |||
328 | 330 | ||
329 | static void __exit mipsnet_exit_module(void) | 331 | static void __exit mipsnet_exit_module(void) |
330 | { | 332 | { |
331 | driver_unregister(&mipsnet_driver); | 333 | platform_driver_unregister(&mipsnet_driver); |
332 | } | 334 | } |
333 | 335 | ||
334 | module_init(mipsnet_init_module); | 336 | module_init(mipsnet_init_module); |