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/video/au1200fb.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/video/au1200fb.c')
-rw-r--r-- | drivers/video/au1200fb.c | 25 |
1 files changed, 14 insertions, 11 deletions
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 | ||
1625 | static int au1200fb_drv_probe(struct device *dev) | 1625 | static 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 | ||
1718 | static int au1200fb_drv_remove(struct device *dev) | 1718 | static 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 |
1750 | static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level) | 1751 | static 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 | ||
1756 | static int au1200fb_drv_resume(struct device *dev, u32 level) | 1757 | static 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 | ||
1763 | static struct device_driver au1200fb_driver = { | 1764 | static 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 | ||
1912 | static void __exit au1200fb_cleanup(void) | 1915 | static void __exit au1200fb_cleanup(void) |
1913 | { | 1916 | { |
1914 | driver_unregister(&au1200fb_driver); | 1917 | platform_driver_unregister(&au1200fb_driver); |
1915 | } | 1918 | } |
1916 | 1919 | ||
1917 | module_init(au1200fb_init); | 1920 | module_init(au1200fb_init); |