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/watchdog | |
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/watchdog')
-rw-r--r-- | drivers/watchdog/rm9k_wdt.c | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c index f1ae3729a19e..cce1982a1b58 100644 --- a/drivers/watchdog/rm9k_wdt.c +++ b/drivers/watchdog/rm9k_wdt.c | |||
@@ -59,8 +59,8 @@ static long wdt_gpi_ioctl(struct file *, unsigned int, unsigned long); | |||
59 | static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); | 59 | static int wdt_gpi_notify(struct notifier_block *, unsigned long, void *); |
60 | static const struct resource *wdt_gpi_get_resource(struct platform_device *, | 60 | static const struct resource *wdt_gpi_get_resource(struct platform_device *, |
61 | const char *, unsigned int); | 61 | const char *, unsigned int); |
62 | static int __init wdt_gpi_probe(struct device *); | 62 | static int __init wdt_gpi_probe(struct platform_device *); |
63 | static int __exit wdt_gpi_remove(struct device *); | 63 | static int __exit wdt_gpi_remove(struct platform_device *); |
64 | 64 | ||
65 | 65 | ||
66 | static const char wdt_gpi_name[] = "wdt_gpi"; | 66 | static const char wdt_gpi_name[] = "wdt_gpi"; |
@@ -346,10 +346,9 @@ static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv, | |||
346 | } | 346 | } |
347 | 347 | ||
348 | /* No hotplugging on the platform bus - use __init */ | 348 | /* No hotplugging on the platform bus - use __init */ |
349 | static int __init wdt_gpi_probe(struct device *dev) | 349 | static int __init wdt_gpi_probe(struct platform_device *pdv) |
350 | { | 350 | { |
351 | int res; | 351 | int res; |
352 | struct platform_device * const pdv = to_platform_device(dev); | ||
353 | const struct resource | 352 | const struct resource |
354 | * const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS, | 353 | * const rr = wdt_gpi_get_resource(pdv, WDT_RESOURCE_REGS, |
355 | IORESOURCE_MEM), | 354 | IORESOURCE_MEM), |
@@ -374,7 +373,7 @@ static int __init wdt_gpi_probe(struct device *dev) | |||
374 | return res; | 373 | return res; |
375 | } | 374 | } |
376 | 375 | ||
377 | static int __exit wdt_gpi_remove(struct device *dev) | 376 | static int __exit wdt_gpi_remove(struct platform_device *dev) |
378 | { | 377 | { |
379 | int res; | 378 | int res; |
380 | 379 | ||
@@ -387,15 +386,13 @@ static int __exit wdt_gpi_remove(struct device *dev) | |||
387 | 386 | ||
388 | 387 | ||
389 | /* Device driver init & exit */ | 388 | /* Device driver init & exit */ |
390 | static struct device_driver wdt_gpi_driver = { | 389 | static struct platform_driver wgt_gpi_driver = { |
391 | .name = (char *) wdt_gpi_name, | 390 | .driver = { |
392 | .bus = &platform_bus_type, | 391 | .name = wdt_gpi_name, |
393 | .owner = THIS_MODULE, | 392 | .owner = THIS_MODULE, |
393 | }, | ||
394 | .probe = wdt_gpi_probe, | 394 | .probe = wdt_gpi_probe, |
395 | .remove = __exit_p(wdt_gpi_remove), | 395 | .remove = __devexit_p(wdt_gpi_remove), |
396 | .shutdown = NULL, | ||
397 | .suspend = NULL, | ||
398 | .resume = NULL, | ||
399 | }; | 396 | }; |
400 | 397 | ||
401 | static int __init wdt_gpi_init_module(void) | 398 | static int __init wdt_gpi_init_module(void) |
@@ -403,12 +400,12 @@ static int __init wdt_gpi_init_module(void) | |||
403 | atomic_set(&opencnt, 1); | 400 | atomic_set(&opencnt, 1); |
404 | if (timeout > MAX_TIMEOUT_SECONDS) | 401 | if (timeout > MAX_TIMEOUT_SECONDS) |
405 | timeout = MAX_TIMEOUT_SECONDS; | 402 | timeout = MAX_TIMEOUT_SECONDS; |
406 | return driver_register(&wdt_gpi_driver); | 403 | return platform_driver_register(&wdt_gpi_driver); |
407 | } | 404 | } |
408 | 405 | ||
409 | static void __exit wdt_gpi_cleanup_module(void) | 406 | static void __exit wdt_gpi_cleanup_module(void) |
410 | { | 407 | { |
411 | driver_unregister(&wdt_gpi_driver); | 408 | platform_driver_unregister(&wdt_gpi_driver); |
412 | } | 409 | } |
413 | 410 | ||
414 | module_init(wdt_gpi_init_module); | 411 | module_init(wdt_gpi_init_module); |