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/pcmcia/m32r_pcc.c | |
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/pcmcia/m32r_pcc.c')
-rw-r--r-- | drivers/pcmcia/m32r_pcc.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 2f108c23dbd9..12034b41d196 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c | |||
@@ -672,13 +672,25 @@ static struct pccard_operations pcc_operations = { | |||
672 | .set_mem_map = pcc_set_mem_map, | 672 | .set_mem_map = pcc_set_mem_map, |
673 | }; | 673 | }; |
674 | 674 | ||
675 | static int pcc_drv_pcmcia_suspend(struct platform_device *dev, | ||
676 | pm_message_t state) | ||
677 | { | ||
678 | return pcmcia_socket_dev_suspend(&dev->dev, state); | ||
679 | } | ||
680 | |||
681 | static int pcc_drv_pcmcia_resume(struct platform_device *dev) | ||
682 | { | ||
683 | return pcmcia_socket_dev_resume(&dev->dev); | ||
684 | } | ||
675 | /*====================================================================*/ | 685 | /*====================================================================*/ |
676 | 686 | ||
677 | static struct device_driver pcc_driver = { | 687 | static struct platform_driver pcc_driver = { |
678 | .name = "pcc", | 688 | .driver = { |
679 | .bus = &platform_bus_type, | 689 | .name = "pcc", |
680 | .suspend = pcmcia_socket_dev_suspend, | 690 | .owner = THIS_MODULE, |
681 | .resume = pcmcia_socket_dev_resume, | 691 | }, |
692 | .suspend = pcc_drv_pcmcia_suspend, | ||
693 | .resume = pcc_drv_pcmcia_resume, | ||
682 | }; | 694 | }; |
683 | 695 | ||
684 | static struct platform_device pcc_device = { | 696 | static struct platform_device pcc_device = { |
@@ -692,13 +704,13 @@ static int __init init_m32r_pcc(void) | |||
692 | { | 704 | { |
693 | int i, ret; | 705 | int i, ret; |
694 | 706 | ||
695 | ret = driver_register(&pcc_driver); | 707 | ret = platform_driver_register(&pcc_driver); |
696 | if (ret) | 708 | if (ret) |
697 | return ret; | 709 | return ret; |
698 | 710 | ||
699 | ret = platform_device_register(&pcc_device); | 711 | ret = platform_device_register(&pcc_device); |
700 | if (ret){ | 712 | if (ret){ |
701 | driver_unregister(&pcc_driver); | 713 | platform_driver_unregister(&pcc_driver); |
702 | return ret; | 714 | return ret; |
703 | } | 715 | } |
704 | 716 | ||
@@ -715,7 +727,7 @@ static int __init init_m32r_pcc(void) | |||
715 | if (pcc_sockets == 0) { | 727 | if (pcc_sockets == 0) { |
716 | printk("socket is not found.\n"); | 728 | printk("socket is not found.\n"); |
717 | platform_device_unregister(&pcc_device); | 729 | platform_device_unregister(&pcc_device); |
718 | driver_unregister(&pcc_driver); | 730 | platform_driver_unregister(&pcc_driver); |
719 | return -ENODEV; | 731 | return -ENODEV; |
720 | } | 732 | } |
721 | 733 | ||
@@ -763,7 +775,7 @@ static void __exit exit_m32r_pcc(void) | |||
763 | if (poll_interval != 0) | 775 | if (poll_interval != 0) |
764 | del_timer_sync(&poll_timer); | 776 | del_timer_sync(&poll_timer); |
765 | 777 | ||
766 | driver_unregister(&pcc_driver); | 778 | platform_driver_unregister(&pcc_driver); |
767 | } /* exit_m32r_pcc */ | 779 | } /* exit_m32r_pcc */ |
768 | 780 | ||
769 | module_init(init_m32r_pcc); | 781 | module_init(init_m32r_pcc); |