aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/au1100fb.c
diff options
context:
space:
mode:
authorMing Lei <tom.leiming@gmail.com>2009-02-06 10:40:12 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 19:38:25 -0400
commit7a192ec334cab9fafe3a8665a65af398b0e24730 (patch)
treeeea572863500f94d446cfded69835e188dba3447 /drivers/video/au1100fb.c
parent6da2d377bba06c29d0bc41c8dee014164dec82a7 (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/video/au1100fb.c')
-rw-r--r--drivers/video/au1100fb.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 62bd4441b5e0..378f27745a1d 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -457,7 +457,7 @@ static struct fb_ops au1100fb_ops =
457 457
458/* AU1100 LCD controller device driver */ 458/* AU1100 LCD controller device driver */
459 459
460static int __init au1100fb_drv_probe(struct device *dev) 460static int __init au1100fb_drv_probe(struct platform_device *dev)
461{ 461{
462 struct au1100fb_device *fbdev = NULL; 462 struct au1100fb_device *fbdev = NULL;
463 struct resource *regs_res; 463 struct resource *regs_res;
@@ -475,7 +475,7 @@ static int __init au1100fb_drv_probe(struct device *dev)
475 475
476 fbdev->panel = &known_lcd_panels[drv_info.panel_idx]; 476 fbdev->panel = &known_lcd_panels[drv_info.panel_idx];
477 477
478 dev_set_drvdata(dev, (void*)fbdev); 478 platform_set_drvdata(dev, (void *)fbdev);
479 479
480 /* Allocate region for our registers and map them */ 480 /* Allocate region for our registers and map them */
481 if (!(regs_res = platform_get_resource(to_platform_device(dev), 481 if (!(regs_res = platform_get_resource(to_platform_device(dev),
@@ -583,19 +583,19 @@ failed:
583 fb_dealloc_cmap(&fbdev->info.cmap); 583 fb_dealloc_cmap(&fbdev->info.cmap);
584 } 584 }
585 kfree(fbdev); 585 kfree(fbdev);
586 dev_set_drvdata(dev, NULL); 586 platform_set_drvdata(dev, NULL);
587 587
588 return 0; 588 return 0;
589} 589}
590 590
591int au1100fb_drv_remove(struct device *dev) 591int au1100fb_drv_remove(struct platform_device *dev)
592{ 592{
593 struct au1100fb_device *fbdev = NULL; 593 struct au1100fb_device *fbdev = NULL;
594 594
595 if (!dev) 595 if (!dev)
596 return -ENODEV; 596 return -ENODEV;
597 597
598 fbdev = (struct au1100fb_device*) dev_get_drvdata(dev); 598 fbdev = (struct au1100fb_device *) platform_get_drvdata(dev);
599 599
600#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) 600#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
601 au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); 601 au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
@@ -620,9 +620,9 @@ int au1100fb_drv_remove(struct device *dev)
620static u32 sys_clksrc; 620static u32 sys_clksrc;
621static struct au1100fb_regs fbregs; 621static struct au1100fb_regs fbregs;
622 622
623int au1100fb_drv_suspend(struct device *dev, pm_message_t state) 623int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state)
624{ 624{
625 struct au1100fb_device *fbdev = dev_get_drvdata(dev); 625 struct au1100fb_device *fbdev = platform_get_drvdata(dev);
626 626
627 if (!fbdev) 627 if (!fbdev)
628 return 0; 628 return 0;
@@ -641,9 +641,9 @@ int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
641 return 0; 641 return 0;
642} 642}
643 643
644int au1100fb_drv_resume(struct device *dev) 644int au1100fb_drv_resume(struct platform_device *dev)
645{ 645{
646 struct au1100fb_device *fbdev = dev_get_drvdata(dev); 646 struct au1100fb_device *fbdev = platform_get_drvdata(dev);
647 647
648 if (!fbdev) 648 if (!fbdev)
649 return 0; 649 return 0;
@@ -663,10 +663,11 @@ int au1100fb_drv_resume(struct device *dev)
663#define au1100fb_drv_resume NULL 663#define au1100fb_drv_resume NULL
664#endif 664#endif
665 665
666static struct device_driver au1100fb_driver = { 666static struct platform_driver au1100fb_driver = {
667 .name = "au1100-lcd", 667 .driver = {
668 .bus = &platform_bus_type, 668 .name = "au1100-lcd",
669 669 .owner = THIS_MODULE,
670 },
670 .probe = au1100fb_drv_probe, 671 .probe = au1100fb_drv_probe,
671 .remove = au1100fb_drv_remove, 672 .remove = au1100fb_drv_remove,
672 .suspend = au1100fb_drv_suspend, 673 .suspend = au1100fb_drv_suspend,
@@ -753,12 +754,12 @@ int __init au1100fb_init(void)
753 return ret; 754 return ret;
754 } 755 }
755 756
756 return driver_register(&au1100fb_driver); 757 return platform_driver_register(&au1100fb_driver);
757} 758}
758 759
759void __exit au1100fb_cleanup(void) 760void __exit au1100fb_cleanup(void)
760{ 761{
761 driver_unregister(&au1100fb_driver); 762 platform_driver_unregister(&au1100fb_driver);
762 763
763 kfree(drv_info.opt_mode); 764 kfree(drv_info.opt_mode);
764} 765}