diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2011-06-10 11:23:01 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-06-15 02:48:54 -0400 |
commit | c329f606a23e13fe952768cb9c32ea929ed91480 (patch) | |
tree | 92d73105d173e8ec67e45666dd023ad2f940813f /drivers/video/au1200fb.c | |
parent | fc90ec86294202b306b7b124f2f6d5035c94fa13 (diff) |
au1200fb: use framebuffer_alloc()
Convert to use framebuffer_alloc() instead of using fb_info embedded
into device context (which broke the driver in the past due to un-
initialized elements).
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video/au1200fb.c')
-rw-r--r-- | drivers/video/au1200fb.c | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 5dff32ac804..442d005e452 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c | |||
@@ -150,7 +150,7 @@ struct au1200_lcd_iodata_t { | |||
150 | 150 | ||
151 | /* Private, per-framebuffer management information (independent of the panel itself) */ | 151 | /* Private, per-framebuffer management information (independent of the panel itself) */ |
152 | struct au1200fb_device { | 152 | struct au1200fb_device { |
153 | struct fb_info fb_info; /* FB driver info record */ | 153 | struct fb_info *fb_info; /* FB driver info record */ |
154 | 154 | ||
155 | int plane; | 155 | int plane; |
156 | unsigned char* fb_mem; /* FrameBuffer memory map */ | 156 | unsigned char* fb_mem; /* FrameBuffer memory map */ |
@@ -158,7 +158,7 @@ struct au1200fb_device { | |||
158 | dma_addr_t fb_phys; | 158 | dma_addr_t fb_phys; |
159 | }; | 159 | }; |
160 | 160 | ||
161 | static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS]; | 161 | static struct fb_info *_au1200fb_infos[CONFIG_FB_AU1200_DEVS]; |
162 | /********************************************************************/ | 162 | /********************************************************************/ |
163 | 163 | ||
164 | /* LCD controller restrictions */ | 164 | /* LCD controller restrictions */ |
@@ -713,7 +713,7 @@ static int fbinfo2index (struct fb_info *fb_info) | |||
713 | int i; | 713 | int i; |
714 | 714 | ||
715 | for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) { | 715 | for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) { |
716 | if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info)) | 716 | if (fb_info == _au1200fb_infos[i]) |
717 | return i; | 717 | return i; |
718 | } | 718 | } |
719 | printk("au1200fb: ERROR: fbinfo2index failed!\n"); | 719 | printk("au1200fb: ERROR: fbinfo2index failed!\n"); |
@@ -962,7 +962,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev) | |||
962 | lcd->window[plane].winctrl2 = ( 0 | 962 | lcd->window[plane].winctrl2 = ( 0 |
963 | | LCD_WINCTRL2_CKMODE_00 | 963 | | LCD_WINCTRL2_CKMODE_00 |
964 | | LCD_WINCTRL2_DBM | 964 | | LCD_WINCTRL2_DBM |
965 | | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length) | 965 | | LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length) |
966 | | LCD_WINCTRL2_SCX_1 | 966 | | LCD_WINCTRL2_SCX_1 |
967 | | LCD_WINCTRL2_SCY_1 | 967 | | LCD_WINCTRL2_SCY_1 |
968 | ) ; | 968 | ) ; |
@@ -1050,7 +1050,7 @@ static void au1200fb_update_fbinfo(struct fb_info *fbi) | |||
1050 | static int au1200fb_fb_check_var(struct fb_var_screeninfo *var, | 1050 | static int au1200fb_fb_check_var(struct fb_var_screeninfo *var, |
1051 | struct fb_info *fbi) | 1051 | struct fb_info *fbi) |
1052 | { | 1052 | { |
1053 | struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi; | 1053 | struct au1200fb_device *fbdev = fbi->par; |
1054 | u32 pixclock; | 1054 | u32 pixclock; |
1055 | int screen_size, plane; | 1055 | int screen_size, plane; |
1056 | 1056 | ||
@@ -1142,7 +1142,7 @@ static int au1200fb_fb_check_var(struct fb_var_screeninfo *var, | |||
1142 | */ | 1142 | */ |
1143 | static int au1200fb_fb_set_par(struct fb_info *fbi) | 1143 | static int au1200fb_fb_set_par(struct fb_info *fbi) |
1144 | { | 1144 | { |
1145 | struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi; | 1145 | struct au1200fb_device *fbdev = fbi->par; |
1146 | 1146 | ||
1147 | au1200fb_update_fbinfo(fbi); | 1147 | au1200fb_update_fbinfo(fbi); |
1148 | au1200_setmode(fbdev); | 1148 | au1200_setmode(fbdev); |
@@ -1246,7 +1246,7 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) | |||
1246 | { | 1246 | { |
1247 | unsigned int len; | 1247 | unsigned int len; |
1248 | unsigned long start=0, off; | 1248 | unsigned long start=0, off; |
1249 | struct au1200fb_device *fbdev = (struct au1200fb_device *) info; | 1249 | struct au1200fb_device *fbdev = info->par; |
1250 | 1250 | ||
1251 | #ifdef CONFIG_PM | 1251 | #ifdef CONFIG_PM |
1252 | au1xxx_pm_access(LCD_pm_dev); | 1252 | au1xxx_pm_access(LCD_pm_dev); |
@@ -1561,10 +1561,9 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id) | |||
1561 | 1561 | ||
1562 | static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) | 1562 | static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) |
1563 | { | 1563 | { |
1564 | struct fb_info *fbi = &fbdev->fb_info; | 1564 | struct fb_info *fbi = fbdev->fb_info; |
1565 | int bpp; | 1565 | int bpp; |
1566 | 1566 | ||
1567 | memset(fbi, 0, sizeof(struct fb_info)); | ||
1568 | fbi->fbops = &au1200fb_fb_ops; | 1567 | fbi->fbops = &au1200fb_fb_ops; |
1569 | 1568 | ||
1570 | bpp = winbpp(win->w[fbdev->plane].mode_winctrl1); | 1569 | bpp = winbpp(win->w[fbdev->plane].mode_winctrl1); |
@@ -1626,11 +1625,13 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) | |||
1626 | static int au1200fb_drv_probe(struct platform_device *dev) | 1625 | static int au1200fb_drv_probe(struct platform_device *dev) |
1627 | { | 1626 | { |
1628 | struct au1200fb_device *fbdev; | 1627 | struct au1200fb_device *fbdev; |
1628 | struct fb_info *fbi = NULL; | ||
1629 | unsigned long page; | 1629 | unsigned long page; |
1630 | int bpp, plane, ret; | 1630 | int bpp, plane, ret; |
1631 | 1631 | ||
1632 | if (!dev) | 1632 | /* shut gcc up */ |
1633 | return -EINVAL; | 1633 | ret = 0; |
1634 | fbdev = NULL; | ||
1634 | 1635 | ||
1635 | for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) { | 1636 | for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) { |
1636 | bpp = winbpp(win->w[plane].mode_winctrl1); | 1637 | bpp = winbpp(win->w[plane].mode_winctrl1); |
@@ -1639,8 +1640,15 @@ static int au1200fb_drv_probe(struct platform_device *dev) | |||
1639 | if (win->w[plane].yres == 0) | 1640 | if (win->w[plane].yres == 0) |
1640 | win->w[plane].yres = panel->Yres; | 1641 | win->w[plane].yres = panel->Yres; |
1641 | 1642 | ||
1642 | fbdev = &_au1200fb_devices[plane]; | 1643 | fbi = framebuffer_alloc(sizeof(struct au1200fb_device), |
1643 | memset(fbdev, 0, sizeof(struct au1200fb_device)); | 1644 | &dev->dev); |
1645 | if (!fbi) | ||
1646 | goto failed; | ||
1647 | |||
1648 | _au1200fb_infos[plane] = fbi; | ||
1649 | fbdev = fbi->par; | ||
1650 | fbdev->fb_info = fbi; | ||
1651 | |||
1644 | fbdev->plane = plane; | 1652 | fbdev->plane = plane; |
1645 | 1653 | ||
1646 | /* Allocate the framebuffer to the maximum screen size */ | 1654 | /* Allocate the framebuffer to the maximum screen size */ |
@@ -1673,21 +1681,20 @@ static int au1200fb_drv_probe(struct platform_device *dev) | |||
1673 | goto failed; | 1681 | goto failed; |
1674 | 1682 | ||
1675 | /* Register new framebuffer */ | 1683 | /* Register new framebuffer */ |
1676 | if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) { | 1684 | ret = register_framebuffer(fbi); |
1685 | if (ret < 0) { | ||
1677 | print_err("cannot register new framebuffer"); | 1686 | print_err("cannot register new framebuffer"); |
1678 | goto failed; | 1687 | goto failed; |
1679 | } | 1688 | } |
1680 | 1689 | ||
1681 | au1200fb_fb_set_par(&fbdev->fb_info); | 1690 | au1200fb_fb_set_par(fbi); |
1682 | 1691 | ||
1683 | #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) | 1692 | #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) |
1684 | if (plane == 0) | 1693 | if (plane == 0) |
1685 | if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) { | 1694 | if (fb_prepare_logo(fbi, FB_ROTATE_UR)) { |
1686 | /* Start display and show logo on boot */ | 1695 | /* Start display and show logo on boot */ |
1687 | fb_set_cmap(&fbdev->fb_info.cmap, | 1696 | fb_set_cmap(&fbi->cmap, fbi); |
1688 | &fbdev->fb_info); | 1697 | fb_show_logo(fbi, FB_ROTATE_UR); |
1689 | |||
1690 | fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR); | ||
1691 | } | 1698 | } |
1692 | #endif | 1699 | #endif |
1693 | } | 1700 | } |
@@ -1705,12 +1712,13 @@ static int au1200fb_drv_probe(struct platform_device *dev) | |||
1705 | failed: | 1712 | failed: |
1706 | /* NOTE: This only does the current plane/window that failed; others are still active */ | 1713 | /* NOTE: This only does the current plane/window that failed; others are still active */ |
1707 | if (fbdev->fb_mem) | 1714 | if (fbdev->fb_mem) |
1708 | dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len), | 1715 | dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), |
1709 | fbdev->fb_mem, fbdev->fb_phys); | 1716 | fbdev->fb_mem, fbdev->fb_phys); |
1710 | if (fbdev->fb_info.cmap.len != 0) | 1717 | if (fbi) { |
1711 | fb_dealloc_cmap(&fbdev->fb_info.cmap); | 1718 | if (fbi->cmap.len != 0) |
1712 | if (fbdev->fb_info.pseudo_palette) | 1719 | fb_dealloc_cmap(&fbi->cmap); |
1713 | kfree(fbdev->fb_info.pseudo_palette); | 1720 | kfree(fbi->pseudo_palette); |
1721 | } | ||
1714 | if (plane == 0) | 1722 | if (plane == 0) |
1715 | free_irq(AU1200_LCD_INT, (void*)dev); | 1723 | free_irq(AU1200_LCD_INT, (void*)dev); |
1716 | return ret; | 1724 | return ret; |
@@ -1719,6 +1727,7 @@ failed: | |||
1719 | static int au1200fb_drv_remove(struct platform_device *dev) | 1727 | static int au1200fb_drv_remove(struct platform_device *dev) |
1720 | { | 1728 | { |
1721 | struct au1200fb_device *fbdev; | 1729 | struct au1200fb_device *fbdev; |
1730 | struct fb_info *fbi; | ||
1722 | int plane; | 1731 | int plane; |
1723 | 1732 | ||
1724 | if (!dev) | 1733 | if (!dev) |
@@ -1727,20 +1736,22 @@ static int au1200fb_drv_remove(struct platform_device *dev) | |||
1727 | /* Turn off the panel */ | 1736 | /* Turn off the panel */ |
1728 | au1200_setpanel(NULL); | 1737 | au1200_setpanel(NULL); |
1729 | 1738 | ||
1730 | for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) | 1739 | for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) { |
1731 | { | 1740 | fbi = _au1200fb_infos[plane]; |
1732 | fbdev = &_au1200fb_devices[plane]; | 1741 | fbdev = fbi->par; |
1733 | 1742 | ||
1734 | /* Clean up all probe data */ | 1743 | /* Clean up all probe data */ |
1735 | unregister_framebuffer(&fbdev->fb_info); | 1744 | unregister_framebuffer(fbi); |
1736 | if (fbdev->fb_mem) | 1745 | if (fbdev->fb_mem) |
1737 | dma_free_noncoherent(&dev->dev, | 1746 | dma_free_noncoherent(&dev->dev, |
1738 | PAGE_ALIGN(fbdev->fb_len), | 1747 | PAGE_ALIGN(fbdev->fb_len), |
1739 | fbdev->fb_mem, fbdev->fb_phys); | 1748 | fbdev->fb_mem, fbdev->fb_phys); |
1740 | if (fbdev->fb_info.cmap.len != 0) | 1749 | if (fbi->cmap.len != 0) |
1741 | fb_dealloc_cmap(&fbdev->fb_info.cmap); | 1750 | fb_dealloc_cmap(&fbi->cmap); |
1742 | if (fbdev->fb_info.pseudo_palette) | 1751 | kfree(fbi->pseudo_palette); |
1743 | kfree(fbdev->fb_info.pseudo_palette); | 1752 | |
1753 | framebuffer_release(fbi); | ||
1754 | _au1200fb_infos[plane] = NULL; | ||
1744 | } | 1755 | } |
1745 | 1756 | ||
1746 | free_irq(AU1200_LCD_INT, (void *)dev); | 1757 | free_irq(AU1200_LCD_INT, (void *)dev); |
@@ -1749,7 +1760,8 @@ static int au1200fb_drv_remove(struct platform_device *dev) | |||
1749 | } | 1760 | } |
1750 | 1761 | ||
1751 | #ifdef CONFIG_PM | 1762 | #ifdef CONFIG_PM |
1752 | static int au1200fb_drv_suspend(struct platform_device *dev, u32 state) | 1763 | static int au1200fb_drv_suspend(struct platform_device *dev, |
1764 | pm_message_t state) | ||
1753 | { | 1765 | { |
1754 | /* TODO */ | 1766 | /* TODO */ |
1755 | return 0; | 1767 | return 0; |