aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
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
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')
-rw-r--r--drivers/video/au1100fb.c31
-rw-r--r--drivers/video/au1200fb.c25
2 files changed, 30 insertions, 26 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}
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 03e57ef88378..0d96f1d2d4c5 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1622,7 +1622,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
1622 1622
1623/* AU1200 LCD controller device driver */ 1623/* AU1200 LCD controller device driver */
1624 1624
1625static int au1200fb_drv_probe(struct device *dev) 1625static int au1200fb_drv_probe(struct platform_device *dev)
1626{ 1626{
1627 struct au1200fb_device *fbdev; 1627 struct au1200fb_device *fbdev;
1628 unsigned long page; 1628 unsigned long page;
@@ -1645,7 +1645,7 @@ static int au1200fb_drv_probe(struct device *dev)
1645 /* Allocate the framebuffer to the maximum screen size */ 1645 /* Allocate the framebuffer to the maximum screen size */
1646 fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; 1646 fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
1647 1647
1648 fbdev->fb_mem = dma_alloc_noncoherent(dev, 1648 fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev,
1649 PAGE_ALIGN(fbdev->fb_len), 1649 PAGE_ALIGN(fbdev->fb_len),
1650 &fbdev->fb_phys, GFP_KERNEL); 1650 &fbdev->fb_phys, GFP_KERNEL);
1651 if (!fbdev->fb_mem) { 1651 if (!fbdev->fb_mem) {
@@ -1715,7 +1715,7 @@ failed:
1715 return ret; 1715 return ret;
1716} 1716}
1717 1717
1718static int au1200fb_drv_remove(struct device *dev) 1718static int au1200fb_drv_remove(struct platform_device *dev)
1719{ 1719{
1720 struct au1200fb_device *fbdev; 1720 struct au1200fb_device *fbdev;
1721 int plane; 1721 int plane;
@@ -1733,7 +1733,8 @@ static int au1200fb_drv_remove(struct device *dev)
1733 /* Clean up all probe data */ 1733 /* Clean up all probe data */
1734 unregister_framebuffer(&fbdev->fb_info); 1734 unregister_framebuffer(&fbdev->fb_info);
1735 if (fbdev->fb_mem) 1735 if (fbdev->fb_mem)
1736 dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len), 1736 dma_free_noncoherent(&dev->dev,
1737 PAGE_ALIGN(fbdev->fb_len),
1737 fbdev->fb_mem, fbdev->fb_phys); 1738 fbdev->fb_mem, fbdev->fb_phys);
1738 if (fbdev->fb_info.cmap.len != 0) 1739 if (fbdev->fb_info.cmap.len != 0)
1739 fb_dealloc_cmap(&fbdev->fb_info.cmap); 1740 fb_dealloc_cmap(&fbdev->fb_info.cmap);
@@ -1747,22 +1748,24 @@ static int au1200fb_drv_remove(struct device *dev)
1747} 1748}
1748 1749
1749#ifdef CONFIG_PM 1750#ifdef CONFIG_PM
1750static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level) 1751static int au1200fb_drv_suspend(struct platform_device *dev, u32 state)
1751{ 1752{
1752 /* TODO */ 1753 /* TODO */
1753 return 0; 1754 return 0;
1754} 1755}
1755 1756
1756static int au1200fb_drv_resume(struct device *dev, u32 level) 1757static int au1200fb_drv_resume(struct platform_device *dev)
1757{ 1758{
1758 /* TODO */ 1759 /* TODO */
1759 return 0; 1760 return 0;
1760} 1761}
1761#endif /* CONFIG_PM */ 1762#endif /* CONFIG_PM */
1762 1763
1763static struct device_driver au1200fb_driver = { 1764static struct platform_driver au1200fb_driver = {
1764 .name = "au1200-lcd", 1765 .driver = {
1765 .bus = &platform_bus_type, 1766 .name = "au1200-lcd",
1767 .owner = THIS_MODULE,
1768 },
1766 .probe = au1200fb_drv_probe, 1769 .probe = au1200fb_drv_probe,
1767 .remove = au1200fb_drv_remove, 1770 .remove = au1200fb_drv_remove,
1768#ifdef CONFIG_PM 1771#ifdef CONFIG_PM
@@ -1906,12 +1909,12 @@ static int __init au1200fb_init(void)
1906 printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n"); 1909 printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
1907 #endif 1910 #endif
1908 1911
1909 return driver_register(&au1200fb_driver); 1912 return platform_driver_register(&au1200fb_driver);
1910} 1913}
1911 1914
1912static void __exit au1200fb_cleanup(void) 1915static void __exit au1200fb_cleanup(void)
1913{ 1916{
1914 driver_unregister(&au1200fb_driver); 1917 platform_driver_unregister(&au1200fb_driver);
1915} 1918}
1916 1919
1917module_init(au1200fb_init); 1920module_init(au1200fb_init);