History

Merge tag 'fbdev-v5.3' of git://github.com/bzolnier/linux

Pull fbdev updates from Bartlomiej Zolnierkiewicz: - remove fbdev notifier usage for fbcon (as prep work to clean up the fbcon locking), add locking checks in vt/console code and make assorted cleanups in fbdev and backlight code (Daniel Vetter) - add COMPILE_TEST support to atmel_lcdfb, da8xx-fb, gbefb, imxfb, pvr2fb and pxa168fb drivers (me) - fix DMA API abuse in au1200fb and jz4740_fb drivers (Christoph Hellwig) - add check for new BGRT status field rotation bits in efifb driver (Hans de Goede) - mark expected switch fall-throughs in s3c-fb driver (Gustavo A. R. Silva) - remove fbdev mxsfb driver in favour of the drm version (Fabio Estevam) - remove broken rfbi code from omap2fb driver (me) - misc fixes (Arnd Bergmann, Shobhit Kukreti, Wei Yongjun, me) - misc cleanups (Gustavo A. R. Silva, Colin Ian King, me) * tag 'fbdev-v5.3' of git://github.com/bzolnier/linux: (62 commits) video: fbdev: imxfb: fix a typo in imxfb_probe() video: fbdev: s3c-fb: Mark expected switch fall-throughs video: fbdev: s3c-fb: fix sparse warnings about using incorrect types video: fbdev: don't print error message on framebuffer_alloc() failure video: fbdev: intelfb: return -ENOMEM on framebuffer_alloc() failure video: fbdev: s3c-fb: return -ENOMEM on framebuffer_alloc() failure vga_switcheroo: Depend upon fbcon being built-in, if enabled video: fbdev: omap2: remove rfbi video: fbdev: atmel_lcdfb: remove redundant initialization to variable ret video: fbdev-MMP: Use struct_size() in devm_kzalloc() video: fbdev: controlfb: fix warnings about comparing pointer to 0 efifb: BGRT: Add check for new BGRT status field rotation bits jz4740_fb: fix DMA API abuse video: fbdev: pvr2fb: fix link error for pvr2fb_pci_exit video: fbdev: s3c-fb: add COMPILE_TEST support video: fbdev: imxfb: fix sparse warnings about using incorrect types video: fbdev: pvr2fb: fix build warning when compiling as module fbcon: Export fbcon_update_vcs backlight: simplify lcd notifier staging/olpc_dcon: Add drm conversion to TODO ...

Linus Torvalds committed 7 years ago

Commit 2d41ef52 parents ed63b9c 732146a82 files · +582 −3259Browse files

Unified · Split

82 files
  1. arch/arm/mach-pxa/am200epd.c +11 −2
  2. drivers/gpu/vga/Kconfig +1 −0
  3. drivers/gpu/vga/vga_switcheroo.c +3 −8
  4. drivers/hid/hid-picolcd_fb.c +1 −3
  5. drivers/media/pci/ivtv/ivtvfb.c +1 −5
  6. drivers/staging/fbtft/fbtft-core.c +3 −1
  7. drivers/staging/olpc_dcon/TODO +7 −0
  8. drivers/staging/olpc_dcon/olpc_dcon.c +1 −5
  9. drivers/tty/vt/vt.c +18 −0
  10. drivers/video/backlight/backlight.c +1 −1
  11. drivers/video/backlight/lcd.c +0 −12
  12. drivers/video/console/dummycon.c +6 −0
  13. drivers/video/fbdev/Kconfig +15 −19
  14. drivers/video/fbdev/Makefile +0 −1
  15. drivers/video/fbdev/amifb.c +1 −3
  16. drivers/video/fbdev/arkfb.c +1 −3
  17. drivers/video/fbdev/atafb.c +0 −21
  18. drivers/video/fbdev/atmel_lcdfb.c +4 −6
  19. drivers/video/fbdev/aty/aty128fb.c +2 −67
  20. drivers/video/fbdev/aty/atyfb_base.c +5 −8
  21. drivers/video/fbdev/aty/radeon_base.c +0 −2
  22. drivers/video/fbdev/au1200fb.c +4 −15
  23. drivers/video/fbdev/chipsfb.c +0 −1
  24. drivers/video/fbdev/cirrusfb.c +1 −4
  25. drivers/video/fbdev/controlfb.c +4 −4
  26. drivers/video/fbdev/core/fbcmap.c +1 −5
  27. drivers/video/fbdev/core/fbcon.c +134 −180
  28. drivers/video/fbdev/core/fbcon.h +3 −3
  29. drivers/video/fbdev/core/fbmem.c +145 −254
  30. drivers/video/fbdev/core/fbsysfs.c +8 −12
  31. drivers/video/fbdev/cyber2000fb.c +0 −6
  32. drivers/video/fbdev/da8xx-fb.c +0 −1
  33. drivers/video/fbdev/efifb.c +5 −1
  34. drivers/video/fbdev/gbefb.c +7 −12
  35. drivers/video/fbdev/grvga.c +1 −3
  36. drivers/video/fbdev/gxt4500.c +2 −3
  37. drivers/video/fbdev/hyperv_fb.c +1 −3
  38. drivers/video/fbdev/i740fb.c +1 −3
  39. drivers/video/fbdev/imsttfb.c +1 −4
  40. drivers/video/fbdev/imxfb.c +5 −6
  41. drivers/video/fbdev/intelfb/intelfbdrv.c +3 −4
  42. drivers/video/fbdev/jz4740_fb.c +1 −10
  43. drivers/video/fbdev/mb862xx/mb862xxfbdrv.c +1 −4
  44. drivers/video/fbdev/mbx/mbxfb.c +1 −3
  45. drivers/video/fbdev/mmp/hw/mmp_ctrl.c +4 −4
  46. drivers/video/fbdev/mxsfb.c +0 −1028
  47. drivers/video/fbdev/neofb.c +1 −8
  48. drivers/video/fbdev/omap/omapfb_main.c +0 −2
  49. drivers/video/fbdev/omap2/omapfb/dss/Kconfig +0 −12
  50. drivers/video/fbdev/omap2/omapfb/dss/Makefile +0 −1
  51. drivers/video/fbdev/omap2/omapfb/dss/core.c +0 −6
  52. drivers/video/fbdev/omap2/omapfb/dss/dss.h +0 −4
  53. drivers/video/fbdev/omap2/omapfb/dss/rfbi.c +0 −1067
  54. drivers/video/fbdev/omap2/omapfb/omapfb-main.c +1 −5
  55. drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c +7 −14
  56. drivers/video/fbdev/platinumfb.c +2 −3
  57. drivers/video/fbdev/pmag-aa-fb.c +1 −3
  58. drivers/video/fbdev/pmag-ba-fb.c +1 −3
  59. drivers/video/fbdev/pmagb-b-fb.c +1 −3
  60. drivers/video/fbdev/pvr2fb.c +87 −101
  61. drivers/video/fbdev/riva/fbdev.c +0 −1
  62. drivers/video/fbdev/s3c-fb.c +11 −13
  63. drivers/video/fbdev/s3fb.c +1 −3
  64. drivers/video/fbdev/sa1100fb.c +0 −25
  65. drivers/video/fbdev/savage/savagefb_driver.c +1 −8
  66. drivers/video/fbdev/sh_mobile_lcdcfb.c +4 −136
  67. drivers/video/fbdev/sh_mobile_lcdcfb.h +0 −5
  68. drivers/video/fbdev/sm501fb.c +1 −3
  69. drivers/video/fbdev/sm712fb.c +0 −1
  70. drivers/video/fbdev/smscufx.c +1 −3
  71. drivers/video/fbdev/ssd1307fb.c +1 −3
  72. drivers/video/fbdev/sunxvr1000.c +0 −1
  73. drivers/video/fbdev/sunxvr2500.c +0 −1
  74. drivers/video/fbdev/sunxvr500.c +0 −1
  75. drivers/video/fbdev/tgafb.c +1 −3
  76. drivers/video/fbdev/udlfb.c +1 −3
  77. drivers/video/fbdev/via/viafbdev.c +1 −5
  78. drivers/video/fbdev/vt8623fb.c +1 −3
  79. include/linux/console_struct.h +1 −4
  80. include/linux/fb.h +12 −33
  81. include/linux/fbcon.h +30 −0
  82. include/video/omapfb_dss.h +0 −32
arch/arm/mach-pxa/am200epd.c+11−2
@@ -347,8 +347,17 @@ int __init am200_init(void) · 346 unmodified lines
347{347{
348 int ret;348 int ret;
349 349
350 /* before anything else, we request notification for any fb350 /*
351 * creation events */351 * Before anything else, we request notification for any fb
352 * creation events.
353 *
354 * FIXME: This is terrible and needs to be nuked. The notifier is used
355 * to get at the fb base address from the boot splash fb driver, which
356 * is then passed to metronomefb. Instaed of metronomfb or this board
357 * support file here figuring this out on their own.
358 *
359 * See also the #ifdef in fbmem.c.
360 */
352 fb_register_client(&am200_fb_notif);361 fb_register_client(&am200_fb_notif);
353 362
354 pxa2xx_mfp_config(ARRAY_AND_SIZE(am200_pin_config));363 pxa2xx_mfp_config(ARRAY_AND_SIZE(am200_pin_config));
drivers/gpu/vga/Kconfig+1−0
@@ -23,6 +23,7 @@ config VGA_SWITCHEROO · 22 unmodified lines
23 depends on X8623 depends on X86
24 depends on ACPI24 depends on ACPI
25 depends on PCI25 depends on PCI
26 depends on (FRAMEBUFFER_CONSOLE=n || FB=y)
26 select VGA_ARB27 select VGA_ARB
27 help28 help
28 Many laptops released in 2008/9/10 have two GPUs with a multiplexer29 Many laptops released in 2008/9/10 have two GPUs with a multiplexer
drivers/gpu/vga/vga_switcheroo.c+3−8
@@ -35,6 +35,7 @@ · 34 unmodified lines
35#include <linux/debugfs.h>35#include <linux/debugfs.h>
36#include <linux/fb.h>36#include <linux/fb.h>
37#include <linux/fs.h>37#include <linux/fs.h>
38#include <linux/fbcon.h>
38#include <linux/module.h>39#include <linux/module.h>
39#include <linux/pci.h>40#include <linux/pci.h>
40#include <linux/pm_domain.h>41#include <linux/pm_domain.h>
@@ -736,14 +737,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) · 695 unmodified lines
736 if (!active->driver_power_control)737 if (!active->driver_power_control)
737 set_audio_state(active->id, VGA_SWITCHEROO_OFF);738 set_audio_state(active->id, VGA_SWITCHEROO_OFF);
738 739
739 if (new_client->fb_info) {740 if (new_client->fb_info)
740 struct fb_event event;741 fbcon_remap_all(new_client->fb_info);
741
742 console_lock();
743 event.info = new_client->fb_info;
744 fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
745 console_unlock();
746 }
747 742
748 mutex_lock(&vgasr_priv.mux_hw_lock);743 mutex_lock(&vgasr_priv.mux_hw_lock);
749 ret = vgasr_priv.handler->switchto(new_client->id);744 ret = vgasr_priv.handler->switchto(new_client->id);
drivers/hid/hid-picolcd_fb.c+1−3
@@ -512,10 +512,8 @@ int picolcd_init_framebuffer(struct picolcd_data *data) · 511 unmodified lines
512 sizeof(struct fb_deferred_io) +512 sizeof(struct fb_deferred_io) +
513 sizeof(struct picolcd_fb_data) +513 sizeof(struct picolcd_fb_data) +
514 PICOLCDFB_SIZE, dev);514 PICOLCDFB_SIZE, dev);
515 if (info == NULL) {515 if (!info)
516 dev_err(dev, "failed to allocate a framebuffer\n");
517 goto err_nomem;516 goto err_nomem;
518 }
519 517
520 info->fbdefio = info->par;518 info->fbdefio = info->par;
521 *info->fbdefio = picolcd_fb_defio;519 *info->fbdefio = picolcd_fb_defio;
drivers/media/pci/ivtv/ivtvfb.c+1−5
@@ -1256,11 +1256,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p) · 1255 unmodified lines
1256 itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps &=1256 itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps &=
1257 ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;1257 ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
1258 itv->v4l2_cap &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;1258 itv->v4l2_cap &= ~V4L2_CAP_VIDEO_OUTPUT_OVERLAY;
1259 if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {1259 unregister_framebuffer(&itv->osd_info->ivtvfb_info);
1260 IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n",
1261 itv->instance);
1262 return 0;
1263 }
1264 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);1260 IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
1265 itv->ivtvfb_restore = NULL;1261 itv->ivtvfb_restore = NULL;
1266 ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);1262 ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
drivers/staging/fbtft/fbtft-core.c+3−1
@@ -891,7 +891,9 @@ int fbtft_unregister_framebuffer(struct fb_info *fb_info) · 890 unmodified lines
891 if (par->fbtftops.unregister_backlight)891 if (par->fbtftops.unregister_backlight)
892 par->fbtftops.unregister_backlight(par);892 par->fbtftops.unregister_backlight(par);
893 fbtft_sysfs_exit(par);893 fbtft_sysfs_exit(par);
894 return unregister_framebuffer(fb_info);894 unregister_framebuffer(fb_info);
895
896 return 0;
895}897}
896EXPORT_SYMBOL(fbtft_unregister_framebuffer);898EXPORT_SYMBOL(fbtft_unregister_framebuffer);
897 899
drivers/staging/olpc_dcon/TODO+7−0
@@ -1,4 +1,11 @@
1TODO:1TODO:
2 - complete rewrite:
3 1. The underlying fbdev drivers need to be converted into drm kernel
4 modesetting drivers.
5 2. The dcon low-power display mode can then be integrated using the
6 drm damage tracking and self-refresh helpers.
7 This bolted-on self-refresh support that digs around in fbdev
8 internals, but isn't properly integrated, is not the correct solution.
2 - see if vx855 gpio API can be made similar enough to cs5535 so we can9 - see if vx855 gpio API can be made similar enough to cs5535 so we can
3 share more code10 share more code
4 - convert all uses of the old GPIO API from <linux/gpio.h> to the11 - convert all uses of the old GPIO API from <linux/gpio.h> to the
drivers/staging/olpc_dcon/olpc_dcon.c+1−5
@@ -250,11 +250,7 @@ static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank) · 249 unmodified lines
250 int err;250 int err;
251 251
252 console_lock();252 console_lock();
253 if (!lock_fb_info(dcon->fbinfo)) {253 lock_fb_info(dcon->fbinfo);
254 console_unlock();
255 dev_err(&dcon->client->dev, "unable to lock framebuffer\n");
256 return false;
257 }
258 254
259 dcon->ignore_fb_events = true;255 dcon->ignore_fb_events = true;
260 err = fb_blank(dcon->fbinfo,256 err = fb_blank(dcon->fbinfo,
drivers/tty/vt/vt.c+18−0
@@ -3822,6 +3822,8 @@ int con_is_bound(const struct consw *csw) · 3821 unmodified lines
3822{3822{
3823 int i, bound = 0;3823 int i, bound = 0;
3824 3824
3825 WARN_CONSOLE_UNLOCKED();
3826
3825 for (i = 0; i < MAX_NR_CONSOLES; i++) {3827 for (i = 0; i < MAX_NR_CONSOLES; i++) {
3826 if (con_driver_map[i] == csw) {3828 if (con_driver_map[i] == csw) {
3827 bound = 1;3829 bound = 1;
@@ -3833,6 +3835,20 @@ int con_is_bound(const struct consw *csw) · 5 unmodified lines
3833}3835}
3834EXPORT_SYMBOL(con_is_bound);3836EXPORT_SYMBOL(con_is_bound);
3835 3837
3838/**
3839 * con_is_visible - checks whether the current console is visible
3840 * @vc: virtual console
3841 *
3842 * RETURNS: zero if not visible, nonzero if visible
3843 */
3844bool con_is_visible(const struct vc_data *vc)
3845{
3846 WARN_CONSOLE_UNLOCKED();
3847
3848 return *vc->vc_display_fg == vc;
3849}
3850EXPORT_SYMBOL(con_is_visible);
3851
3836/**3852/**
3837 * con_debug_enter - prepare the console for the kernel debugger3853 * con_debug_enter - prepare the console for the kernel debugger
3838 * @sw: console driver3854 * @sw: console driver
@@ -4166,6 +4182,8 @@ void do_blank_screen(int entering_gfx) · 327 unmodified lines
4166 struct vc_data *vc = vc_cons[fg_console].d;4182 struct vc_data *vc = vc_cons[fg_console].d;
4167 int i;4183 int i;
4168 4184
4185 might_sleep();
4186
4169 WARN_CONSOLE_UNLOCKED();4187 WARN_CONSOLE_UNLOCKED();
4170 4188
4171 if (console_blanked) {4189 if (console_blanked) {
drivers/video/backlight/backlight.c+1−1
@@ -47,7 +47,7 @@ static int fb_notifier_callback(struct notifier_block *self, · 46 unmodified lines
47 int fb_blank = 0;47 int fb_blank = 0;
48 48
49 /* If we aren't interested in this event, skip it immediately ... */49 /* If we aren't interested in this event, skip it immediately ... */
50 if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)50 if (event != FB_EVENT_BLANK)
51 return 0;51 return 0;
52 52
53 bd = container_of(self, struct backlight_device, fb_notif);53 bd = container_of(self, struct backlight_device, fb_notif);
drivers/video/backlight/lcd.c+0−12
@@ -30,18 +30,6 @@ static int fb_notifier_callback(struct notifier_block *self, · 29 unmodified lines
30 struct lcd_device *ld;30 struct lcd_device *ld;
31 struct fb_event *evdata = data;31 struct fb_event *evdata = data;
32 32
33 /* If we aren't interested in this event, skip it immediately ... */
34 switch (event) {
35 case FB_EVENT_BLANK:
36 case FB_EVENT_MODE_CHANGE:
37 case FB_EVENT_MODE_CHANGE_ALL:
38 case FB_EARLY_EVENT_BLANK:
39 case FB_R_EARLY_EVENT_BLANK:
40 break;
41 default:
42 return 0;
43 }
44
45 ld = container_of(self, struct lcd_device, fb_notif);33 ld = container_of(self, struct lcd_device, fb_notif);
46 if (!ld->ops)34 if (!ld->ops)
47 return 0;35 return 0;
drivers/video/console/dummycon.c+6−0
@@ -34,6 +34,8 @@ static bool dummycon_putc_called; · 33 unmodified lines
34 34
35void dummycon_register_output_notifier(struct notifier_block *nb)35void dummycon_register_output_notifier(struct notifier_block *nb)
36{36{
37 WARN_CONSOLE_UNLOCKED();
38
37 raw_notifier_chain_register(&dummycon_output_nh, nb);39 raw_notifier_chain_register(&dummycon_output_nh, nb);
38 40
39 if (dummycon_putc_called)41 if (dummycon_putc_called)
@@ -42,11 +44,15 @@ void dummycon_register_output_notifier(struct notifier_block *nb) · 2 unmodified lines
42 44
43void dummycon_unregister_output_notifier(struct notifier_block *nb)45void dummycon_unregister_output_notifier(struct notifier_block *nb)
44{46{
47 WARN_CONSOLE_UNLOCKED();
48
45 raw_notifier_chain_unregister(&dummycon_output_nh, nb);49 raw_notifier_chain_unregister(&dummycon_output_nh, nb);
46}50}
47 51
48static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos)52static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos)
49{53{
54 WARN_CONSOLE_UNLOCKED();
55
50 dummycon_putc_called = true;56 dummycon_putc_called = true;
51 raw_notifier_call_chain(&dummycon_output_nh, 0, NULL);57 raw_notifier_call_chain(&dummycon_output_nh, 0, NULL);
52}58}
drivers/video/fbdev/Kconfig+15−19
@@ -332,7 +332,8 @@ config FB_SA1100 · 331 unmodified lines
332 332
333config FB_IMX333config FB_IMX
334 tristate "Freescale i.MX1/21/25/27 LCD support"334 tristate "Freescale i.MX1/21/25/27 LCD support"
335 depends on FB && ARCH_MXC335 depends on FB && HAVE_CLK && HAS_IOMEM
336 depends on ARCH_MXC || COMPILE_TEST
336 select LCD_CLASS_DEVICE337 select LCD_CLASS_DEVICE
337 select FB_CFB_FILLRECT338 select FB_CFB_FILLRECT
338 select FB_CFB_COPYAREA339 select FB_CFB_COPYAREA
@@ -670,7 +671,8 @@ config FB_HGA · 331 unmodified lines
670 671
671config FB_GBE672config FB_GBE
672 bool "SGI Graphics Backend frame buffer support"673 bool "SGI Graphics Backend frame buffer support"
673 depends on (FB = y) && SGI_IP32674 depends on (FB = y) && HAS_IOMEM
675 depends on SGI_IP32 || COMPILE_TEST
674 select FB_CFB_FILLRECT676 select FB_CFB_FILLRECT
675 select FB_CFB_COPYAREA677 select FB_CFB_COPYAREA
676 select FB_CFB_IMAGEBLIT678 select FB_CFB_IMAGEBLIT
@@ -808,7 +810,8 @@ config FB_XVR1000 · 131 unmodified lines
808 810
809config FB_PVR2811config FB_PVR2
810 tristate "NEC PowerVR 2 display support"812 tristate "NEC PowerVR 2 display support"
811 depends on FB && SH_DREAMCAST813 depends on FB && HAS_IOMEM
814 depends on SH_DREAMCAST || COMPILE_TEST
812 select FB_CFB_FILLRECT815 select FB_CFB_FILLRECT
813 select FB_CFB_COPYAREA816 select FB_CFB_COPYAREA
814 select FB_CFB_IMAGEBLIT817 select FB_CFB_IMAGEBLIT
@@ -856,7 +859,8 @@ config FB_S1D13XXX · 41 unmodified lines
856 859
857config FB_ATMEL860config FB_ATMEL
858 tristate "AT91 LCD Controller support"861 tristate "AT91 LCD Controller support"
859 depends on FB && OF && HAVE_FB_ATMEL862 depends on FB && OF && HAVE_CLK && HAS_IOMEM
863 depends on HAVE_FB_ATMEL || COMPILE_TEST
860 select FB_BACKLIGHT864 select FB_BACKLIGHT
861 select FB_CFB_FILLRECT865 select FB_CFB_FILLRECT
862 select FB_CFB_COPYAREA866 select FB_CFB_COPYAREA
@@ -1729,7 +1733,8 @@ config FB_68328 · 866 unmodified lines
1729 1733
1730config FB_PXA1681734config FB_PXA168
1731 tristate "PXA168/910 LCD framebuffer support"1735 tristate "PXA168/910 LCD framebuffer support"
1732 depends on FB && (CPU_PXA168 || CPU_PXA910)1736 depends on FB && HAVE_CLK && HAS_IOMEM
1737 depends on CPU_PXA168 || CPU_PXA910 || COMPILE_TEST
1733 select FB_CFB_FILLRECT1738 select FB_CFB_FILLRECT
1734 select FB_CFB_COPYAREA1739 select FB_CFB_COPYAREA
1735 select FB_CFB_IMAGEBLIT1740 select FB_CFB_IMAGEBLIT
@@ -1873,7 +1878,8 @@ config FB_TMIO_ACCELL · 137 unmodified lines
1873 1878
1874config FB_S3C1879config FB_S3C
1875 tristate "Samsung S3C framebuffer support"1880 tristate "Samsung S3C framebuffer support"
1876 depends on FB && (CPU_S3C2416 || ARCH_S3C64XX)1881 depends on FB && HAVE_CLK && HAS_IOMEM
1882 depends on (CPU_S3C2416 || ARCH_S3C64XX) || COMPILE_TEST
1877 select FB_CFB_FILLRECT1883 select FB_CFB_FILLRECT
1878 select FB_CFB_COPYAREA1884 select FB_CFB_COPYAREA
1879 select FB_CFB_IMAGEBLIT1885 select FB_CFB_IMAGEBLIT
@@ -2055,7 +2061,8 @@ config FB_SH7760 · 175 unmodified lines
2055 2061
2056config FB_DA8XX2062config FB_DA8XX
2057 tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support"2063 tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support"
2058 depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX)2064 depends on FB && HAVE_CLK && HAS_IOMEM
2065 depends on ARCH_DAVINCI_DA8XX || SOC_AM33XX || COMPILE_TEST
2059 select FB_CFB_FILLRECT2066 select FB_CFB_FILLRECT
2060 select FB_CFB_COPYAREA2067 select FB_CFB_COPYAREA
2061 select FB_CFB_IMAGEBLIT2068 select FB_CFB_IMAGEBLIT
@@ -2172,7 +2179,7 @@ config FB_EP93XX · 110 unmodified lines
2172 2179
2173config FB_PRE_INIT_FB2180config FB_PRE_INIT_FB
2174 bool "Don't reinitialize, use bootloader's GDC/Display configuration"2181 bool "Don't reinitialize, use bootloader's GDC/Display configuration"
2175 depends on FB && (FB_MB862XX_LIME || FB_MXS)2182 depends on FB && FB_MB862XX_LIME
2176 ---help---2183 ---help---
2177 Select this option if display contents should be inherited as set by2184 Select this option if display contents should be inherited as set by
2178 the bootloader.2185 the bootloader.
@@ -2213,17 +2220,6 @@ config FB_JZ4740 · 34 unmodified lines
2213 help2220 help
2214 Framebuffer support for the JZ4740 SoC.2221 Framebuffer support for the JZ4740 SoC.
2215 2222
2216config FB_MXS
2217 tristate "MXS LCD framebuffer support"
2218 depends on FB && (ARCH_MXS || ARCH_MXC)
2219 select FB_CFB_FILLRECT
2220 select FB_CFB_COPYAREA
2221 select FB_CFB_IMAGEBLIT
2222 select FB_MODE_HELPERS
2223 select VIDEOMODE_HELPERS
2224 help
2225 Framebuffer support for the MXS SoC.
2226
2227config FB_PUV3_UNIGFX2223config FB_PUV3_UNIGFX
2228 tristate "PKUnity v3 Unigfx framebuffer support"2224 tristate "PKUnity v3 Unigfx framebuffer support"
2229 depends on FB && UNICORE32 && ARCH_PUV32225 depends on FB && UNICORE32 && ARCH_PUV3
drivers/video/fbdev/Makefile+0−1
@@ -131,7 +131,6 @@ obj-$(CONFIG_FB_VGA16) += vga16fb.o · 130 unmodified lines
131obj-$(CONFIG_FB_OF) += offb.o131obj-$(CONFIG_FB_OF) += offb.o
132obj-$(CONFIG_FB_MX3) += mx3fb.o132obj-$(CONFIG_FB_MX3) += mx3fb.o
133obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o133obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
134obj-$(CONFIG_FB_MXS) += mxsfb.o
135obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o134obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o
136obj-$(CONFIG_FB_SIMPLE) += simplefb.o135obj-$(CONFIG_FB_SIMPLE) += simplefb.o
137 136
drivers/video/fbdev/amifb.c+1−3
@@ -3554,10 +3554,8 @@ static int __init amifb_probe(struct platform_device *pdev) · 3553 unmodified lines
3554 custom.dmacon = DMAF_ALL | DMAF_MASTER;3554 custom.dmacon = DMAF_ALL | DMAF_MASTER;
3555 3555
3556 info = framebuffer_alloc(sizeof(struct amifb_par), &pdev->dev);3556 info = framebuffer_alloc(sizeof(struct amifb_par), &pdev->dev);
3557 if (!info) {3557 if (!info)
3558 dev_err(&pdev->dev, "framebuffer_alloc failed\n");
3559 return -ENOMEM;3558 return -ENOMEM;
3560 }
3561 3559
3562 strcpy(info->fix.id, "Amiga ");3560 strcpy(info->fix.id, "Amiga ");
3563 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;3561 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
drivers/video/fbdev/arkfb.c+1−3
@@ -954,10 +954,8 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) · 953 unmodified lines
954 954
955 /* Allocate and fill driver data structure */955 /* Allocate and fill driver data structure */
956 info = framebuffer_alloc(sizeof(struct arkfb_info), &(dev->dev));956 info = framebuffer_alloc(sizeof(struct arkfb_info), &(dev->dev));
957 if (! info) {957 if (!info)
958 dev_err(&(dev->dev), "cannot allocate memory\n");
959 return -ENOMEM;958 return -ENOMEM;
960 }
961 959
962 par = info->par;960 par = info->par;
963 mutex_init(&par->open_lock);961 mutex_init(&par->open_lock);
drivers/video/fbdev/atafb.c+0−21
@@ -77,29 +77,8 @@ · 76 unmodified lines
77#define SWITCH_SND7 0x8077#define SWITCH_SND7 0x80
78#define SWITCH_NONE 0x0078#define SWITCH_NONE 0x00
79 79
80
81#define up(x, r) (((x) + (r) - 1) & ~((r)-1))80#define up(x, r) (((x) + (r) - 1) & ~((r)-1))
82 81
83 /*
84 * Interface to the world
85 */
86
87static int atafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
88static int atafb_set_par(struct fb_info *info);
89static int atafb_setcolreg(unsigned int regno, unsigned int red, unsigned int green,
90 unsigned int blue, unsigned int transp,
91 struct fb_info *info);
92static int atafb_blank(int blank, struct fb_info *info);
93static int atafb_pan_display(struct fb_var_screeninfo *var,
94 struct fb_info *info);
95static void atafb_fillrect(struct fb_info *info,
96 const struct fb_fillrect *rect);
97static void atafb_copyarea(struct fb_info *info,
98 const struct fb_copyarea *region);
99static void atafb_imageblit(struct fb_info *info, const struct fb_image *image);
100static int atafb_ioctl(struct fb_info *info, unsigned int cmd,
101 unsigned long arg);
102
103 82
104static int default_par; /* default resolution (0=none) */83static int default_par; /* default resolution (0=none) */
105 84
drivers/video/fbdev/atmel_lcdfb.c+4−6
@@ -673,7 +673,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) · 672 unmodified lines
673 lcdc_writel(sinfo, ATMEL_LCDC_MVAL, 0);673 lcdc_writel(sinfo, ATMEL_LCDC_MVAL, 0);
674 674
675 /* Disable all interrupts */675 /* Disable all interrupts */
676 lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);676 lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0U);
677 /* Enable FIFO & DMA errors */677 /* Enable FIFO & DMA errors */
678 lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);678 lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);
679 679
@@ -950,7 +950,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) · 270 unmodified lines
950 struct fb_videomode fb_vm;950 struct fb_videomode fb_vm;
951 struct gpio_desc *gpiod;951 struct gpio_desc *gpiod;
952 struct videomode vm;952 struct videomode vm;
953 int ret = -ENOENT;953 int ret;
954 int i;954 int i;
955 955
956 sinfo->config = (struct atmel_lcdfb_config*)956 sinfo->config = (struct atmel_lcdfb_config*)
@@ -1053,10 +1053,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) · 96 unmodified lines
1053 1053
1054 ret = -ENOMEM;1054 ret = -ENOMEM;
1055 info = framebuffer_alloc(sizeof(struct atmel_lcdfb_info), dev);1055 info = framebuffer_alloc(sizeof(struct atmel_lcdfb_info), dev);
1056 if (!info) {1056 if (!info)
1057 dev_err(dev, "cannot allocate memory\n");
1058 goto out;1057 goto out;
1059 }
1060 1058
1061 sinfo = info->par;1059 sinfo = info->par;
1062 sinfo->pdev = pdev;1060 sinfo->pdev = pdev;
@@ -1291,7 +1289,7 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg) · 228 unmodified lines
1291 * We don't want to handle interrupts while the clock is1289 * We don't want to handle interrupts while the clock is
1292 * stopped. It may take forever.1290 * stopped. It may take forever.
1293 */1291 */
1294 lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);1292 lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0U);
1295 1293
1296 sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_CTR);1294 sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_CTR);
1297 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);1295 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
drivers/video/fbdev/aty/aty128fb.c+2−67
@@ -2103,10 +2103,9 @@ static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 2102 unmodified lines
2103 2103
2104 /* We have the resources. Now virtualize them */2104 /* We have the resources. Now virtualize them */
2105 info = framebuffer_alloc(sizeof(struct aty128fb_par), &pdev->dev);2105 info = framebuffer_alloc(sizeof(struct aty128fb_par), &pdev->dev);
2106 if (info == NULL) {2106 if (!info)
2107 printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
2108 goto err_free_mmio;2107 goto err_free_mmio;
2109 }2108
2110 par = info->par;2109 par = info->par;
2111 2110
2112 info->pseudo_palette = par->pseudo_palette;2111 info->pseudo_palette = par->pseudo_palette;
@@ -2350,70 +2349,6 @@ static int aty128fb_ioctl(struct fb_info *info, u_int cmd, u_long arg) · 237 unmodified lines
2350 return -EINVAL;2349 return -EINVAL;
2351}2350}
2352 2351
2353#if 0
2354 /*
2355 * Accelerated functions
2356 */
2357
2358static inline void aty128_rectcopy(int srcx, int srcy, int dstx, int dsty,
2359 u_int width, u_int height,
2360 struct fb_info_aty128 *par)
2361{
2362 u32 save_dp_datatype, save_dp_cntl, dstval;
2363
2364 if (!width || !height)
2365 return;
2366
2367 dstval = depth_to_dst(par->current_par.crtc.depth);
2368 if (dstval == DST_24BPP) {
2369 srcx *= 3;
2370 dstx *= 3;
2371 width *= 3;
2372 } else if (dstval == -EINVAL) {
2373 printk("aty128fb: invalid depth or RGBA\n");
2374 return;
2375 }
2376
2377 wait_for_fifo(2, par);
2378 save_dp_datatype = aty_ld_le32(DP_DATATYPE);
2379 save_dp_cntl = aty_ld_le32(DP_CNTL);
2380
2381 wait_for_fifo(6, par);
2382 aty_st_le32(SRC_Y_X, (srcy << 16) | srcx);
2383 aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT);
2384 aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
2385 aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR);
2386
2387 aty_st_le32(DST_Y_X, (dsty << 16) | dstx);
2388 aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width);
2389
2390 par->blitter_may_be_busy = 1;
2391
2392 wait_for_fifo(2, par);
2393 aty_st_le32(DP_DATATYPE, save_dp_datatype);
2394 aty_st_le32(DP_CNTL, save_dp_cntl);
2395}
2396
2397
2398 /*
2399 * Text mode accelerated functions
2400 */
2401
2402static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy,
2403 int dx, int height, int width)
2404{
2405 sx *= fontwidth(p);
2406 sy *= fontheight(p);
2407 dx *= fontwidth(p);
2408 dy *= fontheight(p);
2409 width *= fontwidth(p);
2410 height *= fontheight(p);
2411
2412 aty128_rectcopy(sx, sy, dx, dy, width, height,
2413 (struct fb_info_aty128 *)p->fb_info);
2414}
2415#endif /* 0 */
2416
2417static void aty128_set_suspend(struct aty128fb_par *par, int suspend)2352static void aty128_set_suspend(struct aty128fb_par *par, int suspend)
2418{2353{
2419 u32 pmgt;2354 u32 pmgt;
drivers/video/fbdev/aty/atyfb_base.c+5−8
@@ -3550,10 +3550,9 @@ static int atyfb_pci_probe(struct pci_dev *pdev, · 3549 unmodified lines
3550 3550
3551 /* Allocate framebuffer */3551 /* Allocate framebuffer */
3552 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);3552 info = framebuffer_alloc(sizeof(struct atyfb_par), &pdev->dev);
3553 if (!info) {3553 if (!info)
3554 PRINTKE("atyfb_pci_probe() can't alloc fb_info\n");
3555 return -ENOMEM;3554 return -ENOMEM;
3556 }3555
3557 par = info->par;3556 par = info->par;
3558 par->bus_type = PCI;3557 par->bus_type = PCI;
3559 info->fix = atyfb_fix;3558 info->fix = atyfb_fix;
@@ -3643,10 +3642,9 @@ static int __init atyfb_atari_probe(void) · 83 unmodified lines
3643 }3642 }
3644 3643
3645 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL);3644 info = framebuffer_alloc(sizeof(struct atyfb_par), NULL);
3646 if (!info) {3645 if (!info)
3647 PRINTKE("atyfb_atari_probe() can't alloc fb_info\n");
3648 return -ENOMEM;3646 return -ENOMEM;
3649 }3647
3650 par = info->par;3648 par = info->par;
3651 3649
3652 info->fix = atyfb_fix;3650 info->fix = atyfb_fix;
@@ -3916,8 +3914,7 @@ static int atyfb_reboot_notify(struct notifier_block *nb, · 263 unmodified lines
3916 if (!reboot_info)3914 if (!reboot_info)
3917 goto out;3915 goto out;
3918 3916
3919 if (!lock_fb_info(reboot_info))3917 lock_fb_info(reboot_info);
3920 goto out;
3921 3918
3922 par = reboot_info->par;3919 par = reboot_info->par;
3923 3920
drivers/video/fbdev/aty/radeon_base.c+0−2
@@ -2294,8 +2294,6 @@ static int radeonfb_pci_register(struct pci_dev *pdev, · 2293 unmodified lines
2294 2294
2295 info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev);2295 info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev);
2296 if (!info) {2296 if (!info) {
2297 printk (KERN_ERR "radeonfb (%s): could not allocate memory\n",
2298 pci_name(pdev));
2299 ret = -ENOMEM;2297 ret = -ENOMEM;
2300 goto err_disable;2298 goto err_disable;
2301 }2299 }
drivers/video/fbdev/au1200fb.c+4−15
@@ -147,6 +147,7 @@ struct au1200_lcd_iodata_t { · 146 unmodified lines
147struct au1200fb_device {147struct au1200fb_device {
148 struct fb_info *fb_info; /* FB driver info record */148 struct fb_info *fb_info; /* FB driver info record */
149 struct au1200fb_platdata *pd;149 struct au1200fb_platdata *pd;
150 struct device *dev;
150 151
151 int plane;152 int plane;
152 unsigned char* fb_mem; /* FrameBuffer memory map */153 unsigned char* fb_mem; /* FrameBuffer memory map */
@@ -1232,10 +1233,8 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) · 1079 unmodified lines
1232{1233{
1233 struct au1200fb_device *fbdev = info->par;1234 struct au1200fb_device *fbdev = info->par;
1234 1235
1235 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);1236 return dma_mmap_attrs(fbdev->dev, vma, fbdev->fb_mem, fbdev->fb_phys,
1236 pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */1237 fbdev->fb_len, DMA_ATTR_NON_CONSISTENT);
1237
1238 return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);
1239}1238}
1240 1239
1241static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)1240static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
@@ -1647,7 +1646,6 @@ static int au1200fb_drv_probe(struct platform_device *dev) · 405 unmodified lines
1647 struct au1200fb_device *fbdev;1646 struct au1200fb_device *fbdev;
1648 struct au1200fb_platdata *pd;1647 struct au1200fb_platdata *pd;
1649 struct fb_info *fbi = NULL;1648 struct fb_info *fbi = NULL;
1650 unsigned long page;
1651 int bpp, plane, ret, irq;1649 int bpp, plane, ret, irq;
1652 1650
1653 print_info("" DRIVER_DESC "");1651 print_info("" DRIVER_DESC "");
@@ -1685,6 +1683,7 @@ static int au1200fb_drv_probe(struct platform_device *dev) · 31 unmodified lines
1685 fbdev = fbi->par;1683 fbdev = fbi->par;
1686 fbdev->fb_info = fbi;1684 fbdev->fb_info = fbi;
1687 fbdev->pd = pd;1685 fbdev->pd = pd;
1686 fbdev->dev = &dev->dev;
1688 1687
1689 fbdev->plane = plane;1688 fbdev->plane = plane;
1690 1689
@@ -1702,16 +1701,6 @@ static int au1200fb_drv_probe(struct platform_device *dev) · 11 unmodified lines
1702 goto failed;1701 goto failed;
1703 }1702 }
1704 1703
1705 /*
1706 * Set page reserved so that mmap will work. This is necessary
1707 * since we'll be remapping normal memory.
1708 */
1709 for (page = (unsigned long)fbdev->fb_phys;
1710 page < PAGE_ALIGN((unsigned long)fbdev->fb_phys +
1711 fbdev->fb_len);
1712 page += PAGE_SIZE) {
1713 SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */
1714 }
1715 print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);1704 print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
1716 print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);1705 print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
1717 1706
drivers/video/fbdev/chipsfb.c+0−1
@@ -366,7 +366,6 @@ static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) · 365 unmodified lines
366 366
367 p = framebuffer_alloc(0, &dp->dev);367 p = framebuffer_alloc(0, &dp->dev);
368 if (p == NULL) {368 if (p == NULL) {
369 dev_err(&dp->dev, "Cannot allocate framebuffer structure\n");
370 rc = -ENOMEM;369 rc = -ENOMEM;
371 goto err_disable;370 goto err_disable;
372 }371 }
drivers/video/fbdev/cirrusfb.c+1−4
@@ -2093,7 +2093,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev, · 2092 unmodified lines
2093 2093
2094 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);2094 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2095 if (!info) {2095 if (!info) {
2096 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2097 ret = -ENOMEM;2096 ret = -ENOMEM;
2098 goto err_out;2097 goto err_out;
2099 }2098 }
@@ -2206,10 +2205,8 @@ static int cirrusfb_zorro_register(struct zorro_dev *z, · 106 unmodified lines
2206 struct cirrusfb_info *cinfo;2205 struct cirrusfb_info *cinfo;
2207 2206
2208 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);2207 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2209 if (!info) {2208 if (!info)
2210 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2211 return -ENOMEM;2209 return -ENOMEM;
2212 }
2213 2210
2214 zcl = (const struct zorrocl *)ent->driver_data;2211 zcl = (const struct zorrocl *)ent->driver_data;
2215 btype = zcl->type;2212 btype = zcl->type;
drivers/video/fbdev/controlfb.c+4−4
@@ -182,7 +182,7 @@ int init_module(void) · 181 unmodified lines
182 int ret = -ENXIO;182 int ret = -ENXIO;
183 183
184 dp = of_find_node_by_name(NULL, "control");184 dp = of_find_node_by_name(NULL, "control");
185 if (dp != 0 && !control_of_init(dp))185 if (dp && !control_of_init(dp))
186 ret = 0;186 ret = 0;
187 of_node_put(dp);187 of_node_put(dp);
188 188
@@ -580,7 +580,7 @@ static int __init control_init(void) · 391 unmodified lines
580 control_setup(option);580 control_setup(option);
581 581
582 dp = of_find_node_by_name(NULL, "control");582 dp = of_find_node_by_name(NULL, "control");
583 if (dp != 0 && !control_of_init(dp))583 if (dp && !control_of_init(dp))
584 ret = 0;584 ret = 0;
585 of_node_put(dp);585 of_node_put(dp);
586 586
@@ -683,8 +683,8 @@ static int __init control_of_init(struct device_node *dp) · 96 unmodified lines
683 return -ENXIO;683 return -ENXIO;
684 }684 }
685 p = kzalloc(sizeof(*p), GFP_KERNEL);685 p = kzalloc(sizeof(*p), GFP_KERNEL);
686 if (p == 0)686 if (!p)
687 return -ENXIO;687 return -ENOMEM;
688 control_fb = p; /* save it for cleanups */688 control_fb = p; /* save it for cleanups */
689 689
690 /* Map in frame buffer and registers */690 /* Map in frame buffer and registers */
drivers/video/fbdev/core/fbcmap.c+1−5
@@ -285,11 +285,7 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) · 284 unmodified lines
285 goto out;285 goto out;
286 }286 }
287 umap.start = cmap->start;287 umap.start = cmap->start;
288 if (!lock_fb_info(info)) {288 lock_fb_info(info);
289 rc = -ENODEV;
290 goto out;
291 }
292
293 rc = fb_set_cmap(&umap, info);289 rc = fb_set_cmap(&umap, info);
294 unlock_fb_info(info);290 unlock_fb_info(info);
295out:291out:
drivers/video/fbdev/core/fbcon.c+134−180
@@ -76,6 +76,7 @@ · 75 unmodified lines
76#include <linux/init.h>76#include <linux/init.h>
77#include <linux/interrupt.h>77#include <linux/interrupt.h>
78#include <linux/crc32.h> /* For counting font checksums */78#include <linux/crc32.h> /* For counting font checksums */
79#include <linux/uaccess.h>
79#include <asm/fb.h>80#include <asm/fb.h>
80#include <asm/irq.h>81#include <asm/irq.h>
81 82
@@ -87,13 +88,32 @@ · 5 unmodified lines
87# define DPRINTK(fmt, args...)88# define DPRINTK(fmt, args...)
88#endif89#endif
89 90
91/*
92 * FIXME: Locking
93 *
94 * - fbcon state itself is protected by the console_lock, and the code does a
95 * pretty good job at making sure that lock is held everywhere it's needed.
96 *
97 * - access to the registered_fb array is entirely unprotected. This should use
98 * proper object lifetime handling, i.e. get/put_fb_info. This also means
99 * switching from indices to proper pointers for fb_info everywhere.
100 *
101 * - fbcon doesn't bother with fb_lock/unlock at all. This is buggy, since it
102 * means concurrent access to the same fbdev from both fbcon and userspace
103 * will blow up. To fix this all fbcon calls from fbmem.c need to be moved out
104 * of fb_lock/unlock protected sections, since otherwise we'll recurse and
105 * deadlock eventually. Aside: Due to these deadlock issues the fbdev code in
106 * fbmem.c cannot use locking asserts, and there's lots of callers which get
107 * the rules wrong, e.g. fbsysfs.c entirely missed fb_lock/unlock calls too.
108 */
109
90enum {110enum {
91 FBCON_LOGO_CANSHOW = -1, /* the logo can be shown */111 FBCON_LOGO_CANSHOW = -1, /* the logo can be shown */
92 FBCON_LOGO_DRAW = -2, /* draw the logo to a console */112 FBCON_LOGO_DRAW = -2, /* draw the logo to a console */
93 FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */113 FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */
94};114};
95 115
96static struct display fb_display[MAX_NR_CONSOLES];116static struct fbcon_display fb_display[MAX_NR_CONSOLES];
97 117
98static signed char con2fb_map[MAX_NR_CONSOLES];118static signed char con2fb_map[MAX_NR_CONSOLES];
99static signed char con2fb_map_boot[MAX_NR_CONSOLES];119static signed char con2fb_map_boot[MAX_NR_CONSOLES];
@@ -112,7 +132,6 @@ static int softback_lines; · 12 unmodified lines
112static int first_fb_vc;132static int first_fb_vc;
113static int last_fb_vc = MAX_NR_CONSOLES - 1;133static int last_fb_vc = MAX_NR_CONSOLES - 1;
114static int fbcon_is_default = 1; 134static int fbcon_is_default = 1;
115static int fbcon_has_exited;
116static int primary_device = -1;135static int primary_device = -1;
117static int fbcon_has_console_bind;136static int fbcon_has_console_bind;
118 137
@@ -185,11 +204,11 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count); · 66 unmodified lines
185static __inline__ void ywrap_down(struct vc_data *vc, int count);204static __inline__ void ywrap_down(struct vc_data *vc, int count);
186static __inline__ void ypan_up(struct vc_data *vc, int count);205static __inline__ void ypan_up(struct vc_data *vc, int count);
187static __inline__ void ypan_down(struct vc_data *vc, int count);206static __inline__ void ypan_down(struct vc_data *vc, int count);
188static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx,207static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx,
189 int dy, int dx, int height, int width, u_int y_break);208 int dy, int dx, int height, int width, u_int y_break);
190static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,209static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
191 int unit);210 int unit);
192static void fbcon_redraw_move(struct vc_data *vc, struct display *p,211static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
193 int line, int count, int dy);212 int line, int count, int dy);
194static void fbcon_modechanged(struct fb_info *info);213static void fbcon_modechanged(struct fb_info *info);
195static void fbcon_set_all_vcs(struct fb_info *info);214static void fbcon_set_all_vcs(struct fb_info *info);
@@ -220,7 +239,7 @@ static void fbcon_rotate(struct fb_info *info, u32 rotate) · 24 unmodified lines
220 fb_info = registered_fb[con2fb_map[ops->currcon]];239 fb_info = registered_fb[con2fb_map[ops->currcon]];
221 240
222 if (info == fb_info) {241 if (info == fb_info) {
223 struct display *p = &fb_display[ops->currcon];242 struct fbcon_display *p = &fb_display[ops->currcon];
224 243
225 if (rotate < 4)244 if (rotate < 4)
226 p->con_rotate = rotate;245 p->con_rotate = rotate;
@@ -235,7 +254,7 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate) · 8 unmodified lines
235{254{
236 struct fbcon_ops *ops = info->fbcon_par;255 struct fbcon_ops *ops = info->fbcon_par;
237 struct vc_data *vc;256 struct vc_data *vc;
238 struct display *p;257 struct fbcon_display *p;
239 int i;258 int i;
240 259
241 if (!ops || ops->currcon < 0 || rotate > 3)260 if (!ops || ops->currcon < 0 || rotate > 3)
@@ -900,7 +919,7 @@ static int set_con2fb_map(int unit, int newidx, int user) · 658 unmodified lines
900 * Low Level Operations919 * Low Level Operations
901 */920 */
902/* NOTE: fbcon cannot be __init: it may be called from do_take_over_console later */921/* NOTE: fbcon cannot be __init: it may be called from do_take_over_console later */
903static int var_to_display(struct display *disp,922static int var_to_display(struct fbcon_display *disp,
904 struct fb_var_screeninfo *var,923 struct fb_var_screeninfo *var,
905 struct fb_info *info)924 struct fb_info *info)
906{925{
@@ -925,7 +944,7 @@ static int var_to_display(struct display *disp, · 18 unmodified lines
925}944}
926 945
927static void display_to_var(struct fb_var_screeninfo *var,946static void display_to_var(struct fb_var_screeninfo *var,
928 struct display *disp)947 struct fbcon_display *disp)
929{948{
930 fb_videomode_to_var(var, disp->mode);949 fb_videomode_to_var(var, disp->mode);
931 var->xres_virtual = disp->xres_virtual;950 var->xres_virtual = disp->xres_virtual;
@@ -946,7 +965,7 @@ static void display_to_var(struct fb_var_screeninfo *var, · 14 unmodified lines
946static const char *fbcon_startup(void)965static const char *fbcon_startup(void)
947{966{
948 const char *display_desc = "frame buffer device";967 const char *display_desc = "frame buffer device";
949 struct display *p = &fb_display[fg_console];968 struct fbcon_display *p = &fb_display[fg_console];
950 struct vc_data *vc = vc_cons[fg_console].d;969 struct vc_data *vc = vc_cons[fg_console].d;
951 const struct font_desc *font = NULL;970 const struct font_desc *font = NULL;
952 struct module *owner;971 struct module *owner;
@@ -1050,23 +1069,26 @@ static const char *fbcon_startup(void) · 97 unmodified lines
1050 info->var.bits_per_pixel);1069 info->var.bits_per_pixel);
1051 1070
1052 fbcon_add_cursor_timer(info);1071 fbcon_add_cursor_timer(info);
1053 fbcon_has_exited = 0;
1054 return display_desc;1072 return display_desc;
1055}1073}
1056 1074
1057static void fbcon_init(struct vc_data *vc, int init)1075static void fbcon_init(struct vc_data *vc, int init)
1058{1076{
1059 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];1077 struct fb_info *info;
1060 struct fbcon_ops *ops;1078 struct fbcon_ops *ops;
1061 struct vc_data **default_mode = vc->vc_display_fg;1079 struct vc_data **default_mode = vc->vc_display_fg;
1062 struct vc_data *svc = *default_mode;1080 struct vc_data *svc = *default_mode;
1063 struct display *t, *p = &fb_display[vc->vc_num];1081 struct fbcon_display *t, *p = &fb_display[vc->vc_num];
1064 int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256;1082 int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256;
1065 int cap, ret;1083 int cap, ret;
1066 1084
1067 if (info_idx == -1 || info == NULL)1085 if (WARN_ON(info_idx == -1))
1068 return;1086 return;
1069 1087
1088 if (con2fb_map[vc->vc_num] == -1)
1089 con2fb_map[vc->vc_num] = info_idx;
1090
1091 info = registered_fb[con2fb_map[vc->vc_num]];
1070 cap = info->flags;1092 cap = info->flags;
1071 1093
1072 if (logo_shown < 0 && console_loglevel <= CONSOLE_LOGLEVEL_QUIET)1094 if (logo_shown < 0 && console_loglevel <= CONSOLE_LOGLEVEL_QUIET)
@@ -1203,7 +1225,7 @@ static void fbcon_init(struct vc_data *vc, int init) · 130 unmodified lines
1203 ops->p = &fb_display[fg_console];1225 ops->p = &fb_display[fg_console];
1204}1226}
1205 1227
1206static void fbcon_free_font(struct display *p, bool freefont)1228static void fbcon_free_font(struct fbcon_display *p, bool freefont)
1207{1229{
1208 if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))1230 if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
1209 kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));1231 kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
@@ -1215,7 +1237,7 @@ static void set_vc_hi_font(struct vc_data *vc, bool set); · 5 unmodified lines
1215 1237
1216static void fbcon_deinit(struct vc_data *vc)1238static void fbcon_deinit(struct vc_data *vc)
1217{1239{
1218 struct display *p = &fb_display[vc->vc_num];1240 struct fbcon_display *p = &fb_display[vc->vc_num];
1219 struct fb_info *info;1241 struct fb_info *info;
1220 struct fbcon_ops *ops;1242 struct fbcon_ops *ops;
1221 int idx;1243 int idx;
@@ -1288,7 +1310,7 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, · 66 unmodified lines
1288 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];1310 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1289 struct fbcon_ops *ops = info->fbcon_par;1311 struct fbcon_ops *ops = info->fbcon_par;
1290 1312
1291 struct display *p = &fb_display[vc->vc_num];1313 struct fbcon_display *p = &fb_display[vc->vc_num];
1292 u_int y_break;1314 u_int y_break;
1293 1315
1294 if (fbcon_is_inactive(vc, info))1316 if (fbcon_is_inactive(vc, info))
@@ -1324,7 +1346,7 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, · 29 unmodified lines
1324 int count, int ypos, int xpos)1346 int count, int ypos, int xpos)
1325{1347{
1326 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];1348 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1327 struct display *p = &fb_display[vc->vc_num];1349 struct fbcon_display *p = &fb_display[vc->vc_num];
1328 struct fbcon_ops *ops = info->fbcon_par;1350 struct fbcon_ops *ops = info->fbcon_par;
1329 1351
1330 if (!fbcon_is_inactive(vc, info))1352 if (!fbcon_is_inactive(vc, info))
@@ -1388,7 +1410,7 @@ static int scrollback_current = 0; · 57 unmodified lines
1388static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,1410static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1389 int unit)1411 int unit)
1390{1412{
1391 struct display *p, *t;1413 struct fbcon_display *p, *t;
1392 struct vc_data **default_mode, *vc;1414 struct vc_data **default_mode, *vc;
1393 struct vc_data *svc;1415 struct vc_data *svc;
1394 struct fbcon_ops *ops = info->fbcon_par;1416 struct fbcon_ops *ops = info->fbcon_par;
@@ -1457,7 +1479,7 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count) · 62 unmodified lines
1457{1479{
1458 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];1480 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1459 struct fbcon_ops *ops = info->fbcon_par;1481 struct fbcon_ops *ops = info->fbcon_par;
1460 struct display *p = &fb_display[vc->vc_num];1482 struct fbcon_display *p = &fb_display[vc->vc_num];
1461 1483
1462 p->yscroll += count;1484 p->yscroll += count;
1463 if (p->yscroll >= p->vrows) /* Deal with wrap */1485 if (p->yscroll >= p->vrows) /* Deal with wrap */
@@ -1476,7 +1498,7 @@ static __inline__ void ywrap_down(struct vc_data *vc, int count) · 12 unmodified lines
1476{1498{
1477 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];1499 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1478 struct fbcon_ops *ops = info->fbcon_par;1500 struct fbcon_ops *ops = info->fbcon_par;
1479 struct display *p = &fb_display[vc->vc_num];1501 struct fbcon_display *p = &fb_display[vc->vc_num];
1480 1502
1481 p->yscroll -= count;1503 p->yscroll -= count;
1482 if (p->yscroll < 0) /* Deal with wrap */1504 if (p->yscroll < 0) /* Deal with wrap */
@@ -1494,7 +1516,7 @@ static __inline__ void ywrap_down(struct vc_data *vc, int count) · 11 unmodified lines
1494static __inline__ void ypan_up(struct vc_data *vc, int count)1516static __inline__ void ypan_up(struct vc_data *vc, int count)
1495{1517{
1496 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];1518 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1497 struct display *p = &fb_display[vc->vc_num];1519 struct fbcon_display *p = &fb_display[vc->vc_num];
1498 struct fbcon_ops *ops = info->fbcon_par;1520 struct fbcon_ops *ops = info->fbcon_par;
1499 1521
1500 p->yscroll += count;1522 p->yscroll += count;
@@ -1519,7 +1541,7 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) · 18 unmodified lines
1519{1541{
1520 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];1542 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1521 struct fbcon_ops *ops = info->fbcon_par;1543 struct fbcon_ops *ops = info->fbcon_par;
1522 struct display *p = &fb_display[vc->vc_num];1544 struct fbcon_display *p = &fb_display[vc->vc_num];
1523 1545
1524 p->yscroll += count;1546 p->yscroll += count;
1525 1547
@@ -1542,7 +1564,7 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) · 16 unmodified lines
1542static __inline__ void ypan_down(struct vc_data *vc, int count)1564static __inline__ void ypan_down(struct vc_data *vc, int count)
1543{1565{
1544 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];1566 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1545 struct display *p = &fb_display[vc->vc_num];1567 struct fbcon_display *p = &fb_display[vc->vc_num];
1546 struct fbcon_ops *ops = info->fbcon_par;1568 struct fbcon_ops *ops = info->fbcon_par;
1547 1569
1548 p->yscroll -= count;1570 p->yscroll -= count;
@@ -1567,7 +1589,7 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) · 18 unmodified lines
1567{1589{
1568 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];1590 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1569 struct fbcon_ops *ops = info->fbcon_par;1591 struct fbcon_ops *ops = info->fbcon_par;
1570 struct display *p = &fb_display[vc->vc_num];1592 struct fbcon_display *p = &fb_display[vc->vc_num];
1571 1593
1572 p->yscroll -= count;1594 p->yscroll -= count;
1573 1595
@@ -1587,7 +1609,7 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) · 13 unmodified lines
1587 scrollback_current = 0;1609 scrollback_current = 0;
1588}1610}
1589 1611
1590static void fbcon_redraw_softback(struct vc_data *vc, struct display *p,1612static void fbcon_redraw_softback(struct vc_data *vc, struct fbcon_display *p,
1591 long delta)1613 long delta)
1592{1614{
1593 int count = vc->vc_rows;1615 int count = vc->vc_rows;
@@ -1680,7 +1702,7 @@ static void fbcon_redraw_softback(struct vc_data *vc, struct display *p, · 86 unmodified lines
1680 }1702 }
1681}1703}
1682 1704
1683static void fbcon_redraw_move(struct vc_data *vc, struct display *p,1705static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
1684 int line, int count, int dy)1706 int line, int count, int dy)
1685{1707{
1686 unsigned short *s = (unsigned short *)1708 unsigned short *s = (unsigned short *)
@@ -1715,7 +1737,7 @@ static void fbcon_redraw_move(struct vc_data *vc, struct display *p, · 28 unmodified lines
1715}1737}
1716 1738
1717static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,1739static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info,
1718 struct display *p, int line, int count, int ycount)1740 struct fbcon_display *p, int line, int count, int ycount)
1719{1741{
1720 int offset = ycount * vc->vc_cols;1742 int offset = ycount * vc->vc_cols;
1721 unsigned short *d = (unsigned short *)1743 unsigned short *d = (unsigned short *)
@@ -1764,7 +1786,7 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info, · 42 unmodified lines
1764 }1786 }
1765}1787}
1766 1788
1767static void fbcon_redraw(struct vc_data *vc, struct display *p,1789static void fbcon_redraw(struct vc_data *vc, struct fbcon_display *p,
1768 int line, int count, int offset)1790 int line, int count, int offset)
1769{1791{
1770 unsigned short *d = (unsigned short *)1792 unsigned short *d = (unsigned short *)
@@ -1848,7 +1870,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, · 77 unmodified lines
1848 enum con_scroll dir, unsigned int count)1870 enum con_scroll dir, unsigned int count)
1849{1871{
1850 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];1872 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1851 struct display *p = &fb_display[vc->vc_num];1873 struct fbcon_display *p = &fb_display[vc->vc_num];
1852 int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;1874 int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK;
1853 1875
1854 if (fbcon_is_inactive(vc, info))1876 if (fbcon_is_inactive(vc, info))
@@ -2052,7 +2074,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, · 197 unmodified lines
2052 int height, int width)2074 int height, int width)
2053{2075{
2054 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];2076 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2055 struct display *p = &fb_display[vc->vc_num];2077 struct fbcon_display *p = &fb_display[vc->vc_num];
2056 2078
2057 if (fbcon_is_inactive(vc, info))2079 if (fbcon_is_inactive(vc, info))
2058 return;2080 return;
@@ -2071,7 +2093,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, · 12 unmodified lines
2071 p->vrows - p->yscroll);2093 p->vrows - p->yscroll);
2072}2094}
2073 2095
2074static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, 2096static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx,
2075 int dy, int dx, int height, int width, u_int y_break)2097 int dy, int dx, int height, int width, u_int y_break)
2076{2098{
2077 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];2099 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
@@ -2113,7 +2135,7 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s · 35 unmodified lines
2113 height, width);2135 height, width);
2114}2136}
2115 2137
2116static void updatescrollmode(struct display *p,2138static void updatescrollmode(struct fbcon_display *p,
2117 struct fb_info *info,2139 struct fb_info *info,
2118 struct vc_data *vc)2140 struct vc_data *vc)
2119{2141{
@@ -2165,7 +2187,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, · 45 unmodified lines
2165{2187{
2166 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];2188 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2167 struct fbcon_ops *ops = info->fbcon_par;2189 struct fbcon_ops *ops = info->fbcon_par;
2168 struct display *p = &fb_display[vc->vc_num];2190 struct fbcon_display *p = &fb_display[vc->vc_num];
2169 struct fb_var_screeninfo var = info->var;2191 struct fb_var_screeninfo var = info->var;
2170 int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;2192 int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
2171 2193
@@ -2210,7 +2232,7 @@ static int fbcon_switch(struct vc_data *vc) · 38 unmodified lines
2210{2232{
2211 struct fb_info *info, *old_info = NULL;2233 struct fb_info *info, *old_info = NULL;
2212 struct fbcon_ops *ops;2234 struct fbcon_ops *ops;
2213 struct display *p = &fb_display[vc->vc_num];2235 struct fbcon_display *p = &fb_display[vc->vc_num];
2214 struct fb_var_screeninfo var;2236 struct fb_var_screeninfo var;
2215 int i, ret, prev_console, charcnt = 256;2237 int i, ret, prev_console, charcnt = 256;
2216 2238
@@ -2348,8 +2370,6 @@ static int fbcon_switch(struct vc_data *vc) · 131 unmodified lines
2348static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,2370static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
2349 int blank)2371 int blank)
2350{2372{
2351 struct fb_event event;
2352
2353 if (blank) {2373 if (blank) {
2354 unsigned short charmask = vc->vc_hi_font_mask ?2374 unsigned short charmask = vc->vc_hi_font_mask ?
2355 0x1ff : 0xff;2375 0x1ff : 0xff;
@@ -2360,14 +2380,6 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, · 4 unmodified lines
2360 fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);2380 fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
2361 vc->vc_video_erase_char = oldc;2381 vc->vc_video_erase_char = oldc;
2362 }2382 }
2363
2364
2365 if (!lock_fb_info(info))
2366 return;
2367 event.info = info;
2368 event.data = &blank;
2369 fb_notifier_call_chain(FB_EVENT_CONBLANK, &event);
2370 unlock_fb_info(info);
2371}2383}
2372 2384
2373static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)2385static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
@@ -2394,9 +2406,8 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) · 20 unmodified lines
2394 fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);2406 fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
2395 ops->cursor_flash = (!blank);2407 ops->cursor_flash = (!blank);
2396 2408
2397 if (!(info->flags & FBINFO_MISC_USEREVENT))2409 if (fb_blank(info, blank))
2398 if (fb_blank(info, blank))2410 fbcon_generic_blank(vc, info, blank);
2399 fbcon_generic_blank(vc, info, blank);
2400 }2411 }
2401 2412
2402 if (!blank)2413 if (!blank)
@@ -2553,7 +2564,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, · 150 unmodified lines
2553{2564{
2554 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];2565 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2555 struct fbcon_ops *ops = info->fbcon_par;2566 struct fbcon_ops *ops = info->fbcon_par;
2556 struct display *p = &fb_display[vc->vc_num];2567 struct fbcon_display *p = &fb_display[vc->vc_num];
2557 int resize;2568 int resize;
2558 int cnt;2569 int cnt;
2559 char *old_data = NULL;2570 char *old_data = NULL;
@@ -2601,7 +2612,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, · 41 unmodified lines
2601 2612
2602static int fbcon_copy_font(struct vc_data *vc, int con)2613static int fbcon_copy_font(struct vc_data *vc, int con)
2603{2614{
2604 struct display *od = &fb_display[con];2615 struct fbcon_display *od = &fb_display[con];
2605 struct console_font *f = &vc->vc_font;2616 struct console_font *f = &vc->vc_font;
2606 2617
2607 if (od->fontdata == f->data)2618 if (od->fontdata == f->data)
@@ -2826,7 +2837,7 @@ static void fbcon_scrolldelta(struct vc_data *vc, int lines) · 218 unmodified lines
2826{2837{
2827 struct fb_info *info = registered_fb[con2fb_map[fg_console]];2838 struct fb_info *info = registered_fb[con2fb_map[fg_console]];
2828 struct fbcon_ops *ops = info->fbcon_par;2839 struct fbcon_ops *ops = info->fbcon_par;
2829 struct display *disp = &fb_display[fg_console];2840 struct fbcon_display *disp = &fb_display[fg_console];
2830 int offset, limit, scrollback_old;2841 int offset, limit, scrollback_old;
2831 2842
2832 if (softback_top) {2843 if (softback_top) {
@@ -2918,7 +2929,7 @@ static int fbcon_set_origin(struct vc_data *vc) · 85 unmodified lines
2918 return 0;2929 return 0;
2919}2930}
2920 2931
2921static void fbcon_suspended(struct fb_info *info)2932void fbcon_suspended(struct fb_info *info)
2922{2933{
2923 struct vc_data *vc = NULL;2934 struct vc_data *vc = NULL;
2924 struct fbcon_ops *ops = info->fbcon_par;2935 struct fbcon_ops *ops = info->fbcon_par;
@@ -2931,7 +2942,7 @@ static void fbcon_suspended(struct fb_info *info) · 6 unmodified lines
2931 fbcon_cursor(vc, CM_ERASE);2942 fbcon_cursor(vc, CM_ERASE);
2932}2943}
2933 2944
2934static void fbcon_resumed(struct fb_info *info)2945void fbcon_resumed(struct fb_info *info)
2935{2946{
2936 struct vc_data *vc;2947 struct vc_data *vc;
2937 struct fbcon_ops *ops = info->fbcon_par;2948 struct fbcon_ops *ops = info->fbcon_par;
@@ -2947,7 +2958,7 @@ static void fbcon_modechanged(struct fb_info *info) · 9 unmodified lines
2947{2958{
2948 struct fbcon_ops *ops = info->fbcon_par;2959 struct fbcon_ops *ops = info->fbcon_par;
2949 struct vc_data *vc;2960 struct vc_data *vc;
2950 struct display *p;2961 struct fbcon_display *p;
2951 int rows, cols;2962 int rows, cols;
2952 2963
2953 if (!ops || ops->currcon < 0)2964 if (!ops || ops->currcon < 0)
@@ -2987,7 +2998,7 @@ static void fbcon_set_all_vcs(struct fb_info *info) · 33 unmodified lines
2987{2998{
2988 struct fbcon_ops *ops = info->fbcon_par;2999 struct fbcon_ops *ops = info->fbcon_par;
2989 struct vc_data *vc;3000 struct vc_data *vc;
2990 struct display *p;3001 struct fbcon_display *p;
2991 int i, rows, cols, fg = -1;3002 int i, rows, cols, fg = -1;
2992 3003
2993 if (!ops || ops->currcon < 0)3004 if (!ops || ops->currcon < 0)
@@ -3018,11 +3029,21 @@ static void fbcon_set_all_vcs(struct fb_info *info) · 24 unmodified lines
3018 fbcon_modechanged(info);3029 fbcon_modechanged(info);
3019}3030}
3020 3031
3021static int fbcon_mode_deleted(struct fb_info *info,3032
3022 struct fb_videomode *mode)3033void fbcon_update_vcs(struct fb_info *info, bool all)
3034{
3035 if (all)
3036 fbcon_set_all_vcs(info);
3037 else
3038 fbcon_modechanged(info);
3039}
3040EXPORT_SYMBOL(fbcon_update_vcs);
3041
3042int fbcon_mode_deleted(struct fb_info *info,
3043 struct fb_videomode *mode)
3023{3044{
3024 struct fb_info *fb_info;3045 struct fb_info *fb_info;
3025 struct display *p;3046 struct fbcon_display *p;
3026 int i, j, found = 0;3047 int i, j, found = 0;
3027 3048
3028 /* before deletion, ensure that mode is not in use */3049 /* before deletion, ensure that mode is not in use */
@@ -3045,7 +3066,7 @@ static int fbcon_mode_deleted(struct fb_info *info, · 16 unmodified lines
3045}3066}
3046 3067
3047#ifdef CONFIG_VT_HW_CONSOLE_BINDING3068#ifdef CONFIG_VT_HW_CONSOLE_BINDING
3048static int fbcon_unbind(void)3069static void fbcon_unbind(void)
3049{3070{
3050 int ret;3071 int ret;
3051 3072
@@ -3054,25 +3075,21 @@ static int fbcon_unbind(void) · 2 unmodified lines
3054 3075
3055 if (!ret)3076 if (!ret)
3056 fbcon_has_console_bind = 0;3077 fbcon_has_console_bind = 0;
3057
3058 return ret;
3059}3078}
3060#else3079#else
3061static inline int fbcon_unbind(void)3080static inline void fbcon_unbind(void) {}
3062{
3063 return -EINVAL;
3064}
3065#endif /* CONFIG_VT_HW_CONSOLE_BINDING */3081#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
3066 3082
3067/* called with console_lock held */3083/* called with console_lock held */
3068static int fbcon_fb_unbind(int idx)3084void fbcon_fb_unbind(struct fb_info *info)
3069{3085{
3070 int i, new_idx = -1, ret = 0;3086 int i, new_idx = -1, ret = 0;
3087 int idx = info->node;
3071 3088
3072 WARN_CONSOLE_UNLOCKED();3089 WARN_CONSOLE_UNLOCKED();
3073 3090
3074 if (!fbcon_has_console_bind)3091 if (!fbcon_has_console_bind)
3075 return 0;3092 return;
3076 3093
3077 for (i = first_fb_vc; i <= last_fb_vc; i++) {3094 for (i = first_fb_vc; i <= last_fb_vc; i++) {
3078 if (con2fb_map[i] != idx &&3095 if (con2fb_map[i] != idx &&
@@ -3105,26 +3122,24 @@ static int fbcon_fb_unbind(int idx) · 26 unmodified lines
3105 idx, 0);3122 idx, 0);
3106 if (ret) {3123 if (ret) {
3107 con2fb_map[i] = idx;3124 con2fb_map[i] = idx;
3108 return ret;3125 return;
3109 }3126 }
3110 }3127 }
3111 }3128 }
3112 }3129 }
3113 ret = fbcon_unbind();3130 fbcon_unbind();
3114 }3131 }
3115
3116 return ret;
3117}3132}
3118 3133
3119/* called with console_lock held */3134/* called with console_lock held */
3120static int fbcon_fb_unregistered(struct fb_info *info)3135void fbcon_fb_unregistered(struct fb_info *info)
3121{3136{
3122 int i, idx;3137 int i, idx;
3123 3138
3124 WARN_CONSOLE_UNLOCKED();3139 WARN_CONSOLE_UNLOCKED();
3125 3140
3126 if (deferred_takeover)3141 if (deferred_takeover)
3127 return 0;3142 return;
3128 3143
3129 idx = info->node;3144 idx = info->node;
3130 for (i = first_fb_vc; i <= last_fb_vc; i++) {3145 for (i = first_fb_vc; i <= last_fb_vc; i++) {
@@ -3153,21 +3168,18 @@ static int fbcon_fb_unregistered(struct fb_info *info) · 22 unmodified lines
3153 3168
3154 if (!num_registered_fb)3169 if (!num_registered_fb)
3155 do_unregister_con_driver(&fb_con);3170 do_unregister_con_driver(&fb_con);
3156
3157 return 0;
3158}3171}
3159 3172
3160/* called with console_lock held */3173void fbcon_remap_all(struct fb_info *info)
3161static void fbcon_remap_all(int idx)
3162{3174{
3163 int i;3175 int i, idx = info->node;
3164
3165 WARN_CONSOLE_UNLOCKED();
3166 3176
3177 console_lock();
3167 if (deferred_takeover) {3178 if (deferred_takeover) {
3168 for (i = first_fb_vc; i <= last_fb_vc; i++)3179 for (i = first_fb_vc; i <= last_fb_vc; i++)
3169 con2fb_map_boot[i] = idx;3180 con2fb_map_boot[i] = idx;
3170 fbcon_map_override();3181 fbcon_map_override();
3182 console_unlock();
3171 return;3183 return;
3172 }3184 }
3173 3185
@@ -3180,6 +3192,7 @@ static void fbcon_remap_all(int idx) · 6 unmodified lines
3180 first_fb_vc + 1, last_fb_vc + 1);3192 first_fb_vc + 1, last_fb_vc + 1);
3181 info_idx = idx;3193 info_idx = idx;
3182 }3194 }
3195 console_unlock();
3183}3196}
3184 3197
3185#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY3198#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
@@ -3213,7 +3226,7 @@ static inline void fbcon_select_primary(struct fb_info *info) · 27 unmodified lines
3213#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */3226#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */
3214 3227
3215/* called with console_lock held */3228/* called with console_lock held */
3216static int fbcon_fb_registered(struct fb_info *info)3229int fbcon_fb_registered(struct fb_info *info)
3217{3230{
3218 int ret = 0, i, idx;3231 int ret = 0, i, idx;
3219 3232
@@ -3247,7 +3260,7 @@ static int fbcon_fb_registered(struct fb_info *info) · 27 unmodified lines
3247 return ret;3260 return ret;
3248}3261}
3249 3262
3250static void fbcon_fb_blanked(struct fb_info *info, int blank)3263void fbcon_fb_blanked(struct fb_info *info, int blank)
3251{3264{
3252 struct fbcon_ops *ops = info->fbcon_par;3265 struct fbcon_ops *ops = info->fbcon_par;
3253 struct vc_data *vc;3266 struct vc_data *vc;
@@ -3269,7 +3282,7 @@ static void fbcon_fb_blanked(struct fb_info *info, int blank) · 15 unmodified lines
3269 ops->blank_state = blank;3282 ops->blank_state = blank;
3270}3283}
3271 3284
3272static void fbcon_new_modelist(struct fb_info *info)3285void fbcon_new_modelist(struct fb_info *info)
3273{3286{
3274 int i;3287 int i;
3275 struct vc_data *vc;3288 struct vc_data *vc;
@@ -3290,11 +3303,11 @@ static void fbcon_new_modelist(struct fb_info *info) · 14 unmodified lines
3290 }3303 }
3291}3304}
3292 3305
3293static void fbcon_get_requirement(struct fb_info *info,3306void fbcon_get_requirement(struct fb_info *info,
3294 struct fb_blit_caps *caps)3307 struct fb_blit_caps *caps)
3295{3308{
3296 struct vc_data *vc;3309 struct vc_data *vc;
3297 struct display *p;3310 struct fbcon_display *p;
3298 3311
3299 if (caps->flags) {3312 if (caps->flags) {
3300 int i, charcnt;3313 int i, charcnt;
@@ -3326,80 +3339,47 @@ static void fbcon_get_requirement(struct fb_info *info, · 25 unmodified lines
3326 }3339 }
3327}3340}
3328 3341
3329static int fbcon_event_notify(struct notifier_block *self,3342int fbcon_set_con2fb_map_ioctl(void __user *argp)
3330 unsigned long action, void *data)
3331{3343{
3332 struct fb_event *event = data;3344 struct fb_con2fbmap con2fb;
3333 struct fb_info *info = event->info;3345 int ret;
3334 struct fb_videomode *mode;
3335 struct fb_con2fbmap *con2fb;
3336 struct fb_blit_caps *caps;
3337 int idx, ret = 0;
3338
3339 /*
3340 * ignore all events except driver registration and deregistration
3341 * if fbcon is not active
3342 */
3343 if (fbcon_has_exited && !(action == FB_EVENT_FB_REGISTERED ||
3344 action == FB_EVENT_FB_UNREGISTERED))
3345 goto done;
3346 3346
3347 switch(action) {3347 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
3348 case FB_EVENT_SUSPEND:3348 return -EFAULT;
3349 fbcon_suspended(info);3349 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
3350 break;3350 return -EINVAL;
3351 case FB_EVENT_RESUME:3351 if (con2fb.framebuffer >= FB_MAX)
3352 fbcon_resumed(info);3352 return -EINVAL;
3353 break;3353 if (!registered_fb[con2fb.framebuffer])
3354 case FB_EVENT_MODE_CHANGE:3354 request_module("fb%d", con2fb.framebuffer);
3355 fbcon_modechanged(info);3355 if (!registered_fb[con2fb.framebuffer]) {
3356 break;3356 return -EINVAL;
3357 case FB_EVENT_MODE_CHANGE_ALL:
3358 fbcon_set_all_vcs(info);
3359 break;
3360 case FB_EVENT_MODE_DELETE:
3361 mode = event->data;
3362 ret = fbcon_mode_deleted(info, mode);
3363 break;
3364 case FB_EVENT_FB_UNBIND:
3365 idx = info->node;
3366 ret = fbcon_fb_unbind(idx);
3367 break;
3368 case FB_EVENT_FB_REGISTERED:
3369 ret = fbcon_fb_registered(info);
3370 break;
3371 case FB_EVENT_FB_UNREGISTERED:
3372 ret = fbcon_fb_unregistered(info);
3373 break;
3374 case FB_EVENT_SET_CONSOLE_MAP:
3375 /* called with console lock held */
3376 con2fb = event->data;
3377 ret = set_con2fb_map(con2fb->console - 1,
3378 con2fb->framebuffer, 1);
3379 break;
3380 case FB_EVENT_GET_CONSOLE_MAP:
3381 con2fb = event->data;
3382 con2fb->framebuffer = con2fb_map[con2fb->console - 1];
3383 break;
3384 case FB_EVENT_BLANK:
3385 fbcon_fb_blanked(info, *(int *)event->data);
3386 break;
3387 case FB_EVENT_NEW_MODELIST:
3388 fbcon_new_modelist(info);
3389 break;
3390 case FB_EVENT_GET_REQ:
3391 caps = event->data;
3392 fbcon_get_requirement(info, caps);
3393 break;
3394 case FB_EVENT_REMAP_ALL_CONSOLE:
3395 idx = info->node;
3396 fbcon_remap_all(idx);
3397 break;
3398 }3357 }
3399done:3358
3359 console_lock();
3360 ret = set_con2fb_map(con2fb.console - 1,
3361 con2fb.framebuffer, 1);
3362 console_unlock();
3363
3400 return ret;3364 return ret;
3401}3365}
3402 3366
3367int fbcon_get_con2fb_map_ioctl(void __user *argp)
3368{
3369 struct fb_con2fbmap con2fb;
3370
3371 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
3372 return -EFAULT;
3373 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
3374 return -EINVAL;
3375
3376 console_lock();
3377 con2fb.framebuffer = con2fb_map[con2fb.console - 1];
3378 console_unlock();
3379
3380 return copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
3381}
3382
3403/*3383/*
3404 * The console `switch' structure for the frame buffer based console3384 * The console `switch' structure for the frame buffer based console
3405 */3385 */
@@ -3431,10 +3411,6 @@ static const struct consw fb_con = { · 25 unmodified lines
3431 .con_debug_leave = fbcon_debug_leave,3411 .con_debug_leave = fbcon_debug_leave,
3432};3412};
3433 3413
3434static struct notifier_block fbcon_event_notifier = {
3435 .notifier_call = fbcon_event_notify,
3436};
3437
3438static ssize_t store_rotate(struct device *device,3414static ssize_t store_rotate(struct device *device,
3439 struct device_attribute *attr, const char *buf,3415 struct device_attribute *attr, const char *buf,
3440 size_t count)3416 size_t count)
@@ -3443,9 +3419,6 @@ static ssize_t store_rotate(struct device *device, · 2 unmodified lines
3443 int rotate, idx;3419 int rotate, idx;
3444 char **last = NULL;3420 char **last = NULL;
3445 3421
3446 if (fbcon_has_exited)
3447 return count;
3448
3449 console_lock();3422 console_lock();
3450 idx = con2fb_map[fg_console];3423 idx = con2fb_map[fg_console];
3451 3424
@@ -3468,9 +3441,6 @@ static ssize_t store_rotate_all(struct device *device, · 16 unmodified lines
3468 int rotate, idx;3441 int rotate, idx;
3469 char **last = NULL;3442 char **last = NULL;
3470 3443
3471 if (fbcon_has_exited)
3472 return count;
3473
3474 console_lock();3444 console_lock();
3475 idx = con2fb_map[fg_console];3445 idx = con2fb_map[fg_console];
3476 3446
@@ -3491,9 +3461,6 @@ static ssize_t show_rotate(struct device *device, · 14 unmodified lines
3491 struct fb_info *info;3461 struct fb_info *info;
3492 int rotate = 0, idx;3462 int rotate = 0, idx;
3493 3463
3494 if (fbcon_has_exited)
3495 return 0;
3496
3497 console_lock();3464 console_lock();
3498 idx = con2fb_map[fg_console];3465 idx = con2fb_map[fg_console];
3499 3466
@@ -3514,9 +3481,6 @@ static ssize_t show_cursor_blink(struct device *device, · 14 unmodified lines
3514 struct fbcon_ops *ops;3481 struct fbcon_ops *ops;
3515 int idx, blink = -1;3482 int idx, blink = -1;
3516 3483
3517 if (fbcon_has_exited)
3518 return 0;
3519
3520 console_lock();3484 console_lock();
3521 idx = con2fb_map[fg_console];3485 idx = con2fb_map[fg_console];
3522 3486
@@ -3543,9 +3507,6 @@ static ssize_t store_cursor_blink(struct device *device, · 20 unmodified lines
3543 int blink, idx;3507 int blink, idx;
3544 char **last = NULL;3508 char **last = NULL;
3545 3509
3546 if (fbcon_has_exited)
3547 return count;
3548
3549 console_lock();3510 console_lock();
3550 idx = con2fb_map[fg_console];3511 idx = con2fb_map[fg_console];
3551 3512
@@ -3668,9 +3629,6 @@ static void fbcon_exit(void) · 116 unmodified lines
3668 struct fb_info *info;3629 struct fb_info *info;
3669 int i, j, mapped;3630 int i, j, mapped;
3670 3631
3671 if (fbcon_has_exited)
3672 return;
3673
3674#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER3632#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
3675 if (deferred_takeover) {3633 if (deferred_takeover) {
3676 dummycon_unregister_output_notifier(&fbcon_output_nb);3634 dummycon_unregister_output_notifier(&fbcon_output_nb);
@@ -3695,7 +3653,7 @@ static void fbcon_exit(void) · 18 unmodified lines
3695 for (j = first_fb_vc; j <= last_fb_vc; j++) {3653 for (j = first_fb_vc; j <= last_fb_vc; j++) {
3696 if (con2fb_map[j] == i) {3654 if (con2fb_map[j] == i) {
3697 mapped = 1;3655 mapped = 1;
3698 break;3656 con2fb_map[j] = -1;
3699 }3657 }
3700 }3658 }
3701 3659
@@ -3718,8 +3676,6 @@ static void fbcon_exit(void) · 16 unmodified lines
3718 info->queue.func = NULL;3676 info->queue.func = NULL;
3719 }3677 }
3720 }3678 }
3721
3722 fbcon_has_exited = 1;
3723}3679}
3724 3680
3725void __init fb_console_init(void)3681void __init fb_console_init(void)
@@ -3727,7 +3683,6 @@ void __init fb_console_init(void) · 1 unmodified line
3727 int i;3683 int i;
3728 3684
3729 console_lock();3685 console_lock();
3730 fb_register_client(&fbcon_event_notifier);
3731 fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,3686 fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,
3732 "fbcon");3687 "fbcon");
3733 3688
@@ -3763,7 +3718,6 @@ static void __exit fbcon_deinit_device(void) · 29 unmodified lines
3763void __exit fb_console_exit(void)3718void __exit fb_console_exit(void)
3764{3719{
3765 console_lock();3720 console_lock();
3766 fb_unregister_client(&fbcon_event_notifier);
3767 fbcon_deinit_device();3721 fbcon_deinit_device();
3768 device_destroy(fb_class, MKDEV(0, 0));3722 device_destroy(fb_class, MKDEV(0, 0));
3769 fbcon_exit();3723 fbcon_exit();
drivers/video/fbdev/core/fbcon.h+3−3
@@ -25,7 +25,7 @@ · 24 unmodified lines
25 * low-level frame buffer device25 * low-level frame buffer device
26 */26 */
27 27
28struct display {28struct fbcon_display {
29 /* Filled in by the low-level console driver */29 /* Filled in by the low-level console driver */
30 const u_char *fontdata;30 const u_char *fontdata;
31 int userfont; /* != 0 if fontdata kmalloc()ed */31 int userfont; /* != 0 if fontdata kmalloc()ed */
@@ -68,7 +68,7 @@ struct fbcon_ops { · 36 unmodified lines
68 struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */68 struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
69 struct timer_list cursor_timer; /* Cursor timer */69 struct timer_list cursor_timer; /* Cursor timer */
70 struct fb_cursor cursor_state;70 struct fb_cursor cursor_state;
71 struct display *p;71 struct fbcon_display *p;
72 struct fb_info *info;72 struct fb_info *info;
73 int currcon; /* Current VC. */73 int currcon; /* Current VC. */
74 int cur_blink_jiffies;74 int cur_blink_jiffies;
@@ -225,7 +225,7 @@ extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); · 150 unmodified lines
225#define FBCON_ATTRIBUTE_REVERSE 2225#define FBCON_ATTRIBUTE_REVERSE 2
226#define FBCON_ATTRIBUTE_BOLD 4226#define FBCON_ATTRIBUTE_BOLD 4
227 227
228static inline int real_y(struct display *p, int ypos)228static inline int real_y(struct fbcon_display *p, int ypos)
229{229{
230 int rows = p->vrows;230 int rows = p->vrows;
231 231
drivers/video/fbdev/core/fbmem.c+145−254
@@ -80,17 +80,6 @@ static void put_fb_info(struct fb_info *fb_info) · 79 unmodified lines
80 fb_info->fbops->fb_destroy(fb_info);80 fb_info->fbops->fb_destroy(fb_info);
81}81}
82 82
83int lock_fb_info(struct fb_info *info)
84{
85 mutex_lock(&info->lock);
86 if (!info->fbops) {
87 mutex_unlock(&info->lock);
88 return 0;
89 }
90 return 1;
91}
92EXPORT_SYMBOL(lock_fb_info);
93
94/*83/*
95 * Helpers84 * Helpers
96 */85 */
@@ -943,16 +932,13 @@ EXPORT_SYMBOL(fb_pan_display); · 846 unmodified lines
943static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var,932static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var,
944 u32 activate)933 u32 activate)
945{934{
946 struct fb_event event;
947 struct fb_blit_caps caps, fbcaps;935 struct fb_blit_caps caps, fbcaps;
948 int err = 0;936 int err = 0;
949 937
950 memset(&caps, 0, sizeof(caps));938 memset(&caps, 0, sizeof(caps));
951 memset(&fbcaps, 0, sizeof(fbcaps));939 memset(&fbcaps, 0, sizeof(fbcaps));
952 caps.flags = (activate & FB_ACTIVATE_ALL) ? 1 : 0;940 caps.flags = (activate & FB_ACTIVATE_ALL) ? 1 : 0;
953 event.info = info;941 fbcon_get_requirement(info, &caps);
954 event.data = &caps;
955 fb_notifier_call_chain(FB_EVENT_GET_REQ, &event);
956 info->fbops->fb_get_caps(info, &fbcaps, var);942 info->fbops->fb_get_caps(info, &fbcaps, var);
957 943
958 if (((fbcaps.x ^ caps.x) & caps.x) ||944 if (((fbcaps.x ^ caps.x) & caps.x) ||
@@ -968,6 +954,10 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) · 9 unmodified lines
968{954{
969 int flags = info->flags;955 int flags = info->flags;
970 int ret = 0;956 int ret = 0;
957 u32 activate;
958 struct fb_var_screeninfo old_var;
959 struct fb_videomode mode;
960 struct fb_event event;
971 961
972 if (var->activate & FB_ACTIVATE_INV_MODE) {962 if (var->activate & FB_ACTIVATE_INV_MODE) {
973 struct fb_videomode mode1, mode2;963 struct fb_videomode mode1, mode2;
@@ -977,100 +967,90 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) · 3 unmodified lines
977 /* make sure we don't delete the videomode of current var */967 /* make sure we don't delete the videomode of current var */
978 ret = fb_mode_is_equal(&mode1, &mode2);968 ret = fb_mode_is_equal(&mode1, &mode2);
979 969
980 if (!ret) {970 if (!ret)
981 struct fb_event event;971 fbcon_mode_deleted(info, &mode1);
982
983 event.info = info;
984 event.data = &mode1;
985 ret = fb_notifier_call_chain(FB_EVENT_MODE_DELETE, &event);
986 }
987 972
988 if (!ret)973 if (!ret)
989 fb_delete_videomode(&mode1, &info->modelist);974 fb_delete_videomode(&mode1, &info->modelist);
990 975
991 976
992 ret = (ret) ? -EINVAL : 0;977 return ret ? -EINVAL : 0;
993 goto done;
994 }978 }
995 979
996 if ((var->activate & FB_ACTIVATE_FORCE) ||980 if (!(var->activate & FB_ACTIVATE_FORCE) &&
997 memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) {981 !memcmp(&info->var, var, sizeof(struct fb_var_screeninfo)))
998 u32 activate = var->activate;982 return 0;
999 983
1000 /* When using FOURCC mode, make sure the red, green, blue and984 activate = var->activate;
1001 * transp fields are set to 0.
1002 */
1003 if ((info->fix.capabilities & FB_CAP_FOURCC) &&
1004 var->grayscale > 1) {
1005 if (var->red.offset || var->green.offset ||
1006 var->blue.offset || var->transp.offset ||
1007 var->red.length || var->green.length ||
1008 var->blue.length || var->transp.length ||
1009 var->red.msb_right || var->green.msb_right ||
1010 var->blue.msb_right || var->transp.msb_right)
1011 return -EINVAL;
1012 }
1013 985
1014 if (!info->fbops->fb_check_var) {986 /* When using FOURCC mode, make sure the red, green, blue and
1015 *var = info->var;987 * transp fields are set to 0.
1016 goto done;988 */
1017 }989 if ((info->fix.capabilities & FB_CAP_FOURCC) &&
990 var->grayscale > 1) {
991 if (var->red.offset || var->green.offset ||
992 var->blue.offset || var->transp.offset ||
993 var->red.length || var->green.length ||
994 var->blue.length || var->transp.length ||
995 var->red.msb_right || var->green.msb_right ||
996 var->blue.msb_right || var->transp.msb_right)
997 return -EINVAL;
998 }
1018 999
1019 ret = info->fbops->fb_check_var(var, info);1000 if (!info->fbops->fb_check_var) {
1001 *var = info->var;
1002 return 0;
1003 }
1020 1004
1021 if (ret)1005 ret = info->fbops->fb_check_var(var, info);
1022 goto done;
1023 1006
1024 if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {1007 if (ret)
1025 struct fb_var_screeninfo old_var;1008 return ret;
1026 struct fb_videomode mode;
1027 1009
1028 if (info->fbops->fb_get_caps) {1010 if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
1029 ret = fb_check_caps(info, var, activate);1011 return 0;
1030 1012
1031 if (ret)1013 if (info->fbops->fb_get_caps) {
1032 goto done;1014 ret = fb_check_caps(info, var, activate);
1033 }
1034 1015
1035 old_var = info->var;1016 if (ret)
1036 info->var = *var;1017 return ret;
1018 }
1037 1019
1038 if (info->fbops->fb_set_par) {1020 old_var = info->var;
1039 ret = info->fbops->fb_set_par(info);1021 info->var = *var;
1040 1022
1041 if (ret) {1023 if (info->fbops->fb_set_par) {
1042 info->var = old_var;1024 ret = info->fbops->fb_set_par(info);
1043 printk(KERN_WARNING "detected "
1044 "fb_set_par error, "
1045 "error code: %d\n", ret);
1046 goto done;
1047 }
1048 }
1049 1025
1050 fb_pan_display(info, &info->var);1026 if (ret) {
1051 fb_set_cmap(&info->cmap, info);1027 info->var = old_var;
1052 fb_var_to_videomode(&mode, &info->var);1028 printk(KERN_WARNING "detected "
1029 "fb_set_par error, "
1030 "error code: %d\n", ret);
1031 return ret;
1032 }
1033 }
1053 1034
1054 if (info->modelist.prev && info->modelist.next &&1035 fb_pan_display(info, &info->var);
1055 !list_empty(&info->modelist))1036 fb_set_cmap(&info->cmap, info);
1056 ret = fb_add_videomode(&mode, &info->modelist);1037 fb_var_to_videomode(&mode, &info->var);
1057 1038
1058 if (!ret && (flags & FBINFO_MISC_USEREVENT)) {1039 if (info->modelist.prev && info->modelist.next &&
1059 struct fb_event event;1040 !list_empty(&info->modelist))
1060 int evnt = (activate & FB_ACTIVATE_ALL) ?1041 ret = fb_add_videomode(&mode, &info->modelist);
1061 FB_EVENT_MODE_CHANGE_ALL :
1062 FB_EVENT_MODE_CHANGE;
1063 1042
1064 info->flags &= ~FBINFO_MISC_USEREVENT;1043 if (ret)
1065 event.info = info;1044 return ret;
1066 event.data = &mode;
1067 fb_notifier_call_chain(evnt, &event);
1068 }
1069 }
1070 }
1071 1045
1072 done:1046 event.info = info;
1073 return ret;1047 event.data = &mode;
1048 fb_notifier_call_chain(FB_EVENT_MODE_CHANGE, &event);
1049
1050 if (flags & FBINFO_MISC_USEREVENT)
1051 fbcon_update_vcs(info, activate & FB_ACTIVATE_ALL);
1052
1053 return 0;
1074}1054}
1075EXPORT_SYMBOL(fb_set_var);1055EXPORT_SYMBOL(fb_set_var);
1076 1056
@@ -1112,17 +1092,14 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 35 unmodified lines
1112 struct fb_ops *fb;1092 struct fb_ops *fb;
1113 struct fb_var_screeninfo var;1093 struct fb_var_screeninfo var;
1114 struct fb_fix_screeninfo fix;1094 struct fb_fix_screeninfo fix;
1115 struct fb_con2fbmap con2fb;
1116 struct fb_cmap cmap_from;1095 struct fb_cmap cmap_from;
1117 struct fb_cmap_user cmap;1096 struct fb_cmap_user cmap;
1118 struct fb_event event;
1119 void __user *argp = (void __user *)arg;1097 void __user *argp = (void __user *)arg;
1120 long ret = 0;1098 long ret = 0;
1121 1099
1122 switch (cmd) {1100 switch (cmd) {
1123 case FBIOGET_VSCREENINFO:1101 case FBIOGET_VSCREENINFO:
1124 if (!lock_fb_info(info))1102 lock_fb_info(info);
1125 return -ENODEV;
1126 var = info->var;1103 var = info->var;
1127 unlock_fb_info(info);1104 unlock_fb_info(info);
1128 1105
@@ -1132,10 +1109,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 3 unmodified lines
1132 if (copy_from_user(&var, argp, sizeof(var)))1109 if (copy_from_user(&var, argp, sizeof(var)))
1133 return -EFAULT;1110 return -EFAULT;
1134 console_lock();1111 console_lock();
1135 if (!lock_fb_info(info)) {1112 lock_fb_info(info);
1136 console_unlock();
1137 return -ENODEV;
1138 }
1139 info->flags |= FBINFO_MISC_USEREVENT;1113 info->flags |= FBINFO_MISC_USEREVENT;
1140 ret = fb_set_var(info, &var);1114 ret = fb_set_var(info, &var);
1141 info->flags &= ~FBINFO_MISC_USEREVENT;1115 info->flags &= ~FBINFO_MISC_USEREVENT;
@@ -1145,8 +1119,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 3 unmodified lines
1145 ret = -EFAULT;1119 ret = -EFAULT;
1146 break;1120 break;
1147 case FBIOGET_FSCREENINFO:1121 case FBIOGET_FSCREENINFO:
1148 if (!lock_fb_info(info))1122 lock_fb_info(info);
1149 return -ENODEV;
1150 fix = info->fix;1123 fix = info->fix;
1151 if (info->flags & FBINFO_HIDE_SMEM_START)1124 if (info->flags & FBINFO_HIDE_SMEM_START)
1152 fix.smem_start = 0;1125 fix.smem_start = 0;
@@ -1162,8 +1135,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 9 unmodified lines
1162 case FBIOGETCMAP:1135 case FBIOGETCMAP:
1163 if (copy_from_user(&cmap, argp, sizeof(cmap)))1136 if (copy_from_user(&cmap, argp, sizeof(cmap)))
1164 return -EFAULT;1137 return -EFAULT;
1165 if (!lock_fb_info(info))1138 lock_fb_info(info);
1166 return -ENODEV;
1167 cmap_from = info->cmap;1139 cmap_from = info->cmap;
1168 unlock_fb_info(info);1140 unlock_fb_info(info);
1169 ret = fb_cmap_to_user(&cmap_from, &cmap);1141 ret = fb_cmap_to_user(&cmap_from, &cmap);
@@ -1172,10 +1144,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 2 unmodified lines
1172 if (copy_from_user(&var, argp, sizeof(var)))1144 if (copy_from_user(&var, argp, sizeof(var)))
1173 return -EFAULT;1145 return -EFAULT;
1174 console_lock();1146 console_lock();
1175 if (!lock_fb_info(info)) {1147 lock_fb_info(info);
1176 console_unlock();
1177 return -ENODEV;
1178 }
1179 ret = fb_pan_display(info, &var);1148 ret = fb_pan_display(info, &var);
1180 unlock_fb_info(info);1149 unlock_fb_info(info);
1181 console_unlock();1150 console_unlock();
@@ -1186,58 +1155,22 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 4 unmodified lines
1186 ret = -EINVAL;1155 ret = -EINVAL;
1187 break;1156 break;
1188 case FBIOGET_CON2FBMAP:1157 case FBIOGET_CON2FBMAP:
1189 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))1158 ret = fbcon_get_con2fb_map_ioctl(argp);
1190 return -EFAULT;
1191 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
1192 return -EINVAL;
1193 con2fb.framebuffer = -1;
1194 event.data = &con2fb;
1195 if (!lock_fb_info(info))
1196 return -ENODEV;
1197 event.info = info;
1198 fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
1199 unlock_fb_info(info);
1200 ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
1201 break;1159 break;
1202 case FBIOPUT_CON2FBMAP:1160 case FBIOPUT_CON2FBMAP:
1203 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))1161 ret = fbcon_set_con2fb_map_ioctl(argp);
1204 return -EFAULT;
1205 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
1206 return -EINVAL;
1207 if (con2fb.framebuffer >= FB_MAX)
1208 return -EINVAL;
1209 if (!registered_fb[con2fb.framebuffer])
1210 request_module("fb%d", con2fb.framebuffer);
1211 if (!registered_fb[con2fb.framebuffer]) {
1212 ret = -EINVAL;
1213 break;
1214 }
1215 event.data = &con2fb;
1216 console_lock();
1217 if (!lock_fb_info(info)) {
1218 console_unlock();
1219 return -ENODEV;
1220 }
1221 event.info = info;
1222 ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
1223 unlock_fb_info(info);
1224 console_unlock();
1225 break;1162 break;
1226 case FBIOBLANK:1163 case FBIOBLANK:
1227 console_lock();1164 console_lock();
1228 if (!lock_fb_info(info)) {1165 lock_fb_info(info);
1229 console_unlock();
1230 return -ENODEV;
1231 }
1232 info->flags |= FBINFO_MISC_USEREVENT;
1233 ret = fb_blank(info, arg);1166 ret = fb_blank(info, arg);
1234 info->flags &= ~FBINFO_MISC_USEREVENT;1167 /* might again call into fb_blank */
1168 fbcon_fb_blanked(info, arg);
1235 unlock_fb_info(info);1169 unlock_fb_info(info);
1236 console_unlock();1170 console_unlock();
1237 break;1171 break;
1238 default:1172 default:
1239 if (!lock_fb_info(info))1173 lock_fb_info(info);
1240 return -ENODEV;
1241 fb = info->fbops;1174 fb = info->fbops;
1242 if (fb->fb_ioctl)1175 if (fb->fb_ioctl)
1243 ret = fb->fb_ioctl(info, cmd, arg);1176 ret = fb->fb_ioctl(info, cmd, arg);
@@ -1357,8 +1290,7 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, · 113 unmodified lines
1357{1290{
1358 struct fb_fix_screeninfo fix;1291 struct fb_fix_screeninfo fix;
1359 1292
1360 if (!lock_fb_info(info))1293 lock_fb_info(info);
1361 return -ENODEV;
1362 fix = info->fix;1294 fix = info->fix;
1363 if (info->flags & FBINFO_HIDE_SMEM_START)1295 if (info->flags & FBINFO_HIDE_SMEM_START)
1364 fix.smem_start = 0;1296 fix.smem_start = 0;
@@ -1418,8 +1350,6 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) · 53 unmodified lines
1418 if (!info)1350 if (!info)
1419 return -ENODEV;1351 return -ENODEV;
1420 fb = info->fbops;1352 fb = info->fbops;
1421 if (!fb)
1422 return -ENODEV;
1423 mutex_lock(&info->mm_lock);1353 mutex_lock(&info->mm_lock);
1424 if (fb->fb_mmap) {1354 if (fb->fb_mmap) {
1425 int res;1355 int res;
@@ -1483,7 +1413,7 @@ __releases(&info->lock) · 57 unmodified lines
1483 if (IS_ERR(info))1413 if (IS_ERR(info))
1484 return PTR_ERR(info);1414 return PTR_ERR(info);
1485 1415
1486 mutex_lock(&info->lock);1416 lock_fb_info(info);
1487 if (!try_module_get(info->fbops->owner)) {1417 if (!try_module_get(info->fbops->owner)) {
1488 res = -ENODEV;1418 res = -ENODEV;
1489 goto out;1419 goto out;
@@ -1499,7 +1429,7 @@ __releases(&info->lock) · 9 unmodified lines
1499 fb_deferred_io_open(info, inode, file);1429 fb_deferred_io_open(info, inode, file);
1500#endif1430#endif
1501out:1431out:
1502 mutex_unlock(&info->lock);1432 unlock_fb_info(info);
1503 if (res)1433 if (res)
1504 put_fb_info(info);1434 put_fb_info(info);
1505 return res;1435 return res;
@@ -1512,11 +1442,11 @@ __releases(&info->lock) · 6 unmodified lines
1512{1442{
1513 struct fb_info * const info = file->private_data;1443 struct fb_info * const info = file->private_data;
1514 1444
1515 mutex_lock(&info->lock);1445 lock_fb_info(info);
1516 if (info->fbops->fb_release)1446 if (info->fbops->fb_release)
1517 info->fbops->fb_release(info,1);1447 info->fbops->fb_release(info,1);
1518 module_put(info->fbops->owner);1448 module_put(info->fbops->owner);
1519 mutex_unlock(&info->lock);1449 unlock_fb_info(info);
1520 put_fb_info(info);1450 put_fb_info(info);
1521 return 0;1451 return 0;
1522}1452}
@@ -1621,13 +1551,13 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena, · 98 unmodified lines
1621 return false;1551 return false;
1622}1552}
1623 1553
1624static int do_unregister_framebuffer(struct fb_info *fb_info);1554static void do_unregister_framebuffer(struct fb_info *fb_info);
1625 1555
1626#define VGA_FB_PHYS 0xA00001556#define VGA_FB_PHYS 0xA0000
1627static int do_remove_conflicting_framebuffers(struct apertures_struct *a,1557static void do_remove_conflicting_framebuffers(struct apertures_struct *a,
1628 const char *name, bool primary)1558 const char *name, bool primary)
1629{1559{
1630 int i, ret;1560 int i;
1631 1561
1632 /* check all firmware fbs and kick off if the base addr overlaps */1562 /* check all firmware fbs and kick off if the base addr overlaps */
1633 for_each_registered_fb(i) {1563 for_each_registered_fb(i) {
@@ -1643,13 +1573,9 @@ static int do_remove_conflicting_framebuffers(struct apertures_struct *a, · 9 unmodified lines
1643 1573
1644 printk(KERN_INFO "fb%d: switching to %s from %s\n",1574 printk(KERN_INFO "fb%d: switching to %s from %s\n",
1645 i, name, registered_fb[i]->fix.id);1575 i, name, registered_fb[i]->fix.id);
1646 ret = do_unregister_framebuffer(registered_fb[i]);1576 do_unregister_framebuffer(registered_fb[i]);
1647 if (ret)
1648 return ret;
1649 }1577 }
1650 }1578 }
1651
1652 return 0;
1653}1579}
1654 1580
1655static bool lockless_register_fb;1581static bool lockless_register_fb;
@@ -1660,17 +1586,14 @@ MODULE_PARM_DESC(lockless_register_fb, · 4 unmodified lines
1660static int do_register_framebuffer(struct fb_info *fb_info)1586static int do_register_framebuffer(struct fb_info *fb_info)
1661{1587{
1662 int i, ret;1588 int i, ret;
1663 struct fb_event event;
1664 struct fb_videomode mode;1589 struct fb_videomode mode;
1665 1590
1666 if (fb_check_foreignness(fb_info))1591 if (fb_check_foreignness(fb_info))
1667 return -ENOSYS;1592 return -ENOSYS;
1668 1593
1669 ret = do_remove_conflicting_framebuffers(fb_info->apertures,1594 do_remove_conflicting_framebuffers(fb_info->apertures,
1670 fb_info->fix.id,1595 fb_info->fix.id,
1671 fb_is_primary_device(fb_info));1596 fb_is_primary_device(fb_info));
1672 if (ret)
1673 return ret;
1674 1597
1675 if (num_registered_fb == FB_MAX)1598 if (num_registered_fb == FB_MAX)
1676 return -ENXIO;1599 return -ENXIO;
@@ -1723,20 +1646,22 @@ static int do_register_framebuffer(struct fb_info *fb_info) · 46 unmodified lines
1723 fb_add_videomode(&mode, &fb_info->modelist);1646 fb_add_videomode(&mode, &fb_info->modelist);
1724 registered_fb[i] = fb_info;1647 registered_fb[i] = fb_info;
1725 1648
1726 event.info = fb_info;1649#ifdef CONFIG_GUMSTIX_AM200EPD
1650 {
1651 struct fb_event event;
1652 event.info = fb_info;
1653 fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
1654 }
1655#endif
1656
1727 if (!lockless_register_fb)1657 if (!lockless_register_fb)
1728 console_lock();1658 console_lock();
1729 else1659 else
1730 atomic_inc(&ignore_console_lock_warning);1660 atomic_inc(&ignore_console_lock_warning);
1731 if (!lock_fb_info(fb_info)) {1661 lock_fb_info(fb_info);
1732 ret = -ENODEV;1662 ret = fbcon_fb_registered(fb_info);
1733 goto unlock_console;
1734 }
1735 ret = 0;
1736
1737 fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
1738 unlock_fb_info(fb_info);1663 unlock_fb_info(fb_info);
1739unlock_console:1664
1740 if (!lockless_register_fb)1665 if (!lockless_register_fb)
1741 console_unlock();1666 console_unlock();
1742 else1667 else
@@ -1744,44 +1669,44 @@ unlock_console: · 1 unmodified line
1744 return ret;1669 return ret;
1745}1670}
1746 1671
1747static int unbind_console(struct fb_info *fb_info)1672static void unbind_console(struct fb_info *fb_info)
1748{1673{
1749 struct fb_event event;
1750 int ret;
1751 int i = fb_info->node;1674 int i = fb_info->node;
1752 1675
1753 if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)1676 if (WARN_ON(i < 0 || i >= FB_MAX || registered_fb[i] != fb_info))
1754 return -EINVAL;1677 return;
1755 1678
1756 console_lock();1679 console_lock();
1757 if (!lock_fb_info(fb_info)) {1680 lock_fb_info(fb_info);
1758 console_unlock();1681 fbcon_fb_unbind(fb_info);
1759 return -ENODEV;
1760 }
1761
1762 event.info = fb_info;
1763 ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
1764 unlock_fb_info(fb_info);1682 unlock_fb_info(fb_info);
1765 console_unlock();1683 console_unlock();
1766
1767 return ret;
1768}1684}
1769 1685
1770static int __unlink_framebuffer(struct fb_info *fb_info);1686void unlink_framebuffer(struct fb_info *fb_info)
1771
1772static int do_unregister_framebuffer(struct fb_info *fb_info)
1773{1687{
1774 struct fb_event event;1688 int i;
1775 int ret;1689
1690 i = fb_info->node;
1691 if (WARN_ON(i < 0 || i >= FB_MAX || registered_fb[i] != fb_info))
1692 return;
1776 1693
1777 ret = unbind_console(fb_info);1694 if (!fb_info->dev)
1695 return;
1778 1696
1779 if (ret)1697 device_destroy(fb_class, MKDEV(FB_MAJOR, i));
1780 return -EINVAL;
1781 1698
1782 pm_vt_switch_unregister(fb_info->dev);1699 pm_vt_switch_unregister(fb_info->dev);
1783 1700
1784 __unlink_framebuffer(fb_info);1701 unbind_console(fb_info);
1702
1703 fb_info->dev = NULL;
1704}
1705EXPORT_SYMBOL(unlink_framebuffer);
1706
1707static void do_unregister_framebuffer(struct fb_info *fb_info)
1708{
1709 unlink_framebuffer(fb_info);
1785 if (fb_info->pixmap.addr &&1710 if (fb_info->pixmap.addr &&
1786 (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))1711 (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
1787 kfree(fb_info->pixmap.addr);1712 kfree(fb_info->pixmap.addr);
@@ -1789,46 +1714,21 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) · 1 unmodified line
1789 registered_fb[fb_info->node] = NULL;1714 registered_fb[fb_info->node] = NULL;
1790 num_registered_fb--;1715 num_registered_fb--;
1791 fb_cleanup_device(fb_info);1716 fb_cleanup_device(fb_info);
1792 event.info = fb_info;1717#ifdef CONFIG_GUMSTIX_AM200EPD
1718 {
1719 struct fb_event event;
1720 event.info = fb_info;
1721 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1722 }
1723#endif
1793 console_lock();1724 console_lock();
1794 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);1725 fbcon_fb_unregistered(fb_info);
1795 console_unlock();1726 console_unlock();
1796 1727
1797 /* this may free fb info */1728 /* this may free fb info */
1798 put_fb_info(fb_info);1729 put_fb_info(fb_info);
1799 return 0;
1800}1730}
1801 1731
1802static int __unlink_framebuffer(struct fb_info *fb_info)
1803{
1804 int i;
1805
1806 i = fb_info->node;
1807 if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
1808 return -EINVAL;
1809
1810 if (fb_info->dev) {
1811 device_destroy(fb_class, MKDEV(FB_MAJOR, i));
1812 fb_info->dev = NULL;
1813 }
1814
1815 return 0;
1816}
1817
1818int unlink_framebuffer(struct fb_info *fb_info)
1819{
1820 int ret;
1821
1822 ret = __unlink_framebuffer(fb_info);
1823 if (ret)
1824 return ret;
1825
1826 unbind_console(fb_info);
1827
1828 return 0;
1829}
1830EXPORT_SYMBOL(unlink_framebuffer);
1831
1832/**1732/**
1833 * remove_conflicting_framebuffers - remove firmware-configured framebuffers1733 * remove_conflicting_framebuffers - remove firmware-configured framebuffers
1834 * @a: memory range, users of which are to be removed1734 * @a: memory range, users of which are to be removed
@@ -1842,7 +1742,6 @@ EXPORT_SYMBOL(unlink_framebuffer); · 7 unmodified lines
1842int remove_conflicting_framebuffers(struct apertures_struct *a,1742int remove_conflicting_framebuffers(struct apertures_struct *a,
1843 const char *name, bool primary)1743 const char *name, bool primary)
1844{1744{
1845 int ret;
1846 bool do_free = false;1745 bool do_free = false;
1847 1746
1848 if (!a) {1747 if (!a) {
@@ -1856,13 +1755,13 @@ int remove_conflicting_framebuffers(struct apertures_struct *a, · 7 unmodified lines
1856 }1755 }
1857 1756
1858 mutex_lock(&registration_lock);1757 mutex_lock(&registration_lock);
1859 ret = do_remove_conflicting_framebuffers(a, name, primary);1758 do_remove_conflicting_framebuffers(a, name, primary);
1860 mutex_unlock(&registration_lock);1759 mutex_unlock(&registration_lock);
1861 1760
1862 if (do_free)1761 if (do_free)
1863 kfree(a);1762 kfree(a);
1864 1763
1865 return ret;1764 return 0;
1866}1765}
1867EXPORT_SYMBOL(remove_conflicting_framebuffers);1766EXPORT_SYMBOL(remove_conflicting_framebuffers);
1868 1767
@@ -1959,16 +1858,12 @@ EXPORT_SYMBOL(register_framebuffer); · 90 unmodified lines
1959 * that the driver implements fb_open() and fb_release() to1858 * that the driver implements fb_open() and fb_release() to
1960 * check that no processes are using the device.1859 * check that no processes are using the device.
1961 */1860 */
1962int1861void
1963unregister_framebuffer(struct fb_info *fb_info)1862unregister_framebuffer(struct fb_info *fb_info)
1964{1863{
1965 int ret;
1966
1967 mutex_lock(&registration_lock);1864 mutex_lock(&registration_lock);
1968 ret = do_unregister_framebuffer(fb_info);1865 do_unregister_framebuffer(fb_info);
1969 mutex_unlock(&registration_lock);1866 mutex_unlock(&registration_lock);
1970
1971 return ret;
1972}1867}
1973EXPORT_SYMBOL(unregister_framebuffer);1868EXPORT_SYMBOL(unregister_framebuffer);
1974 1869
@@ -1983,15 +1878,14 @@ EXPORT_SYMBOL(unregister_framebuffer); · 8 unmodified lines
1983 */1878 */
1984void fb_set_suspend(struct fb_info *info, int state)1879void fb_set_suspend(struct fb_info *info, int state)
1985{1880{
1986 struct fb_event event;1881 WARN_CONSOLE_UNLOCKED();
1987 1882
1988 event.info = info;
1989 if (state) {1883 if (state) {
1990 fb_notifier_call_chain(FB_EVENT_SUSPEND, &event);1884 fbcon_suspended(info);
1991 info->state = FBINFO_STATE_SUSPENDED;1885 info->state = FBINFO_STATE_SUSPENDED;
1992 } else {1886 } else {
1993 info->state = FBINFO_STATE_RUNNING;1887 info->state = FBINFO_STATE_RUNNING;
1994 fb_notifier_call_chain(FB_EVENT_RESUME, &event);1888 fbcon_resumed(info);
1995 }1889 }
1996}1890}
1997EXPORT_SYMBOL(fb_set_suspend);1891EXPORT_SYMBOL(fb_set_suspend);
@@ -2059,7 +1953,6 @@ subsys_initcall(fbmem_init); · 61 unmodified lines
2059 1953
2060int fb_new_modelist(struct fb_info *info)1954int fb_new_modelist(struct fb_info *info)
2061{1955{
2062 struct fb_event event;
2063 struct fb_var_screeninfo var = info->var;1956 struct fb_var_screeninfo var = info->var;
2064 struct list_head *pos, *n;1957 struct list_head *pos, *n;
2065 struct fb_modelist *modelist;1958 struct fb_modelist *modelist;
@@ -2079,14 +1972,12 @@ int fb_new_modelist(struct fb_info *info) · 13 unmodified lines
2079 }1972 }
2080 }1973 }
2081 1974
2082 err = 1;1975 if (list_empty(&info->modelist))
1976 return 1;
2083 1977
2084 if (!list_empty(&info->modelist)) {1978 fbcon_new_modelist(info);
2085 event.info = info;
2086 err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
2087 }
2088 1979
2089 return err;1980 return 0;
2090}1981}
2091 1982
2092MODULE_LICENSE("GPL");1983MODULE_LICENSE("GPL");
drivers/video/fbdev/core/fbsysfs.c+8−12
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <linux/kernel.h>14#include <linux/kernel.h>
15#include <linux/slab.h>15#include <linux/slab.h>
16#include <linux/fb.h>16#include <linux/fb.h>
17#include <linux/fbcon.h>
17#include <linux/console.h>18#include <linux/console.h>
18#include <linux/module.h>19#include <linux/module.h>
19 20
@@ -175,10 +176,7 @@ static ssize_t store_modes(struct device *device, · 155 unmodified lines
175 return -EINVAL;176 return -EINVAL;
176 177
177 console_lock();178 console_lock();
178 if (!lock_fb_info(fb_info)) {179 lock_fb_info(fb_info);
179 console_unlock();
180 return -ENODEV;
181 }
182 180
183 list_splice(&fb_info->modelist, &old_list);181 list_splice(&fb_info->modelist, &old_list);
184 fb_videomode_to_modelist((const struct fb_videomode *)buf, i,182 fb_videomode_to_modelist((const struct fb_videomode *)buf, i,
@@ -304,12 +302,13 @@ static ssize_t store_blank(struct device *device, · 119 unmodified lines
304{302{
305 struct fb_info *fb_info = dev_get_drvdata(device);303 struct fb_info *fb_info = dev_get_drvdata(device);
306 char *last = NULL;304 char *last = NULL;
307 int err;305 int err, arg;
308 306
307 arg = simple_strtoul(buf, &last, 0);
309 console_lock();308 console_lock();
310 fb_info->flags |= FBINFO_MISC_USEREVENT;309 err = fb_blank(fb_info, arg);
311 err = fb_blank(fb_info, simple_strtoul(buf, &last, 0));310 /* might again call into fb_blank */
312 fb_info->flags &= ~FBINFO_MISC_USEREVENT;311 fbcon_fb_blanked(fb_info, arg);
313 console_unlock();312 console_unlock();
314 if (err < 0)313 if (err < 0)
315 return err;314 return err;
@@ -405,10 +404,7 @@ static ssize_t store_fbstate(struct device *device, · 89 unmodified lines
405 state = simple_strtoul(buf, &last, 0);404 state = simple_strtoul(buf, &last, 0);
406 405
407 console_lock();406 console_lock();
408 if (!lock_fb_info(fb_info)) {407 lock_fb_info(fb_info);
409 console_unlock();
410 return -ENODEV;
411 }
412 408
413 fb_set_suspend(fb_info, (int)state);409 fb_set_suspend(fb_info, (int)state);
414 410
drivers/video/fbdev/cyber2000fb.c+0−6
@@ -58,7 +58,6 @@ · 57 unmodified lines
58struct cfb_info {58struct cfb_info {
59 struct fb_info fb;59 struct fb_info fb;
60 struct display_switch *dispsw;60 struct display_switch *dispsw;
61 struct display *display;
62 unsigned char __iomem *region;61 unsigned char __iomem *region;
63 unsigned char __iomem *regs;62 unsigned char __iomem *regs;
64 u_int id;63 u_int id;
@@ -1638,10 +1637,6 @@ static void cyberpro_common_resume(struct cfb_info *cfb) · 1573 unmodified lines
1638 cyber2000fb_set_par(&cfb->fb);1637 cyber2000fb_set_par(&cfb->fb);
1639}1638}
1640 1639
1641/*
1642 * PCI specific support.
1643 */
1644#ifdef CONFIG_PCI
1645/*1640/*
1646 * We need to wake up the CyberPro, and make sure its in linear memory1641 * We need to wake up the CyberPro, and make sure its in linear memory
1647 * mode. Unfortunately, this is specific to the platform and card that1642 * mode. Unfortunately, this is specific to the platform and card that
@@ -1858,7 +1853,6 @@ static struct pci_driver cyberpro_driver = { · 210 unmodified lines
1858 .resume = cyberpro_pci_resume,1853 .resume = cyberpro_pci_resume,
1859 .id_table = cyberpro_pci_table1854 .id_table = cyberpro_pci_table
1860};1855};
1861#endif
1862 1856
1863/*1857/*
1864 * I don't think we can use the "module_init" stuff here because1858 * I don't think we can use the "module_init" stuff here because
drivers/video/fbdev/da8xx-fb.c+0−1
@@ -1387,7 +1387,6 @@ static int fb_probe(struct platform_device *device) · 1386 unmodified lines
1387 da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),1387 da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),
1388 &device->dev);1388 &device->dev);
1389 if (!da8xx_fb_info) {1389 if (!da8xx_fb_info) {
1390 dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");
1391 ret = -ENOMEM;1390 ret = -ENOMEM;
1392 goto err_pm_runtime_disable;1391 goto err_pm_runtime_disable;
1393 }1392 }
drivers/video/fbdev/efifb.c+5−1
@@ -169,6 +169,11 @@ static void efifb_show_boot_graphics(struct fb_info *info) · 168 unmodified lines
169 return;169 return;
170 }170 }
171 171
172 if (bgrt_tab.status & 0x06) {
173 pr_info("efifb: BGRT rotation bits set, not showing boot graphics\n");
174 return;
175 }
176
172 /* Avoid flashing the logo if we're going to print std probe messages */177 /* Avoid flashing the logo if we're going to print std probe messages */
173 if (console_loglevel > CONSOLE_LOGLEVEL_QUIET)178 if (console_loglevel > CONSOLE_LOGLEVEL_QUIET)
174 return;179 return;
@@ -448,7 +453,6 @@ static int efifb_probe(struct platform_device *dev) · 273 unmodified lines
448 453
449 info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);454 info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
450 if (!info) {455 if (!info) {
451 pr_err("efifb: cannot allocate framebuffer\n");
452 err = -ENOMEM;456 err = -ENOMEM;
453 goto err_release_mem;457 goto err_release_mem;
454 }458 }
drivers/video/fbdev/gbefb.c+7−12
@@ -39,9 +39,7 @@ struct gbefb_par { · 38 unmodified lines
39 int valid;39 int valid;
40};40};
41 41
42#ifdef CONFIG_SGI_IP32
43#define GBE_BASE 0x16000000 /* SGI O2 */42#define GBE_BASE 0x16000000 /* SGI O2 */
44#endif
45 43
46/* macro for fastest write-though access to the framebuffer */44/* macro for fastest write-though access to the framebuffer */
47#ifdef CONFIG_MIPS45#ifdef CONFIG_MIPS
@@ -51,10 +49,6 @@ struct gbefb_par { · 3 unmodified lines
51#define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)49#define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
52#endif50#endif
53#endif51#endif
54#ifdef CONFIG_X86
55#define pgprot_fb(_prot) (((_prot) & ~_PAGE_CACHE_MASK) | \
56 cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS))
57#endif
58 52
59/*53/*
60 * RAM we reserve for the frame buffer. This defines the maximum screen54 * RAM we reserve for the frame buffer. This defines the maximum screen
@@ -279,7 +273,7 @@ static void gbe_turn_off(void) · 218 unmodified lines
279 val = 0;273 val = 0;
280 SET_GBE_FIELD(VT_XY, FREEZE, val, 1);274 SET_GBE_FIELD(VT_XY, FREEZE, val, 1);
281 gbe->vt_xy = val;275 gbe->vt_xy = val;
282 udelay(10000);276 mdelay(10);
283 for (i = 0; i < 10000; i++) {277 for (i = 0; i < 10000; i++) {
284 val = gbe->vt_xy;278 val = gbe->vt_xy;
285 if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1)279 if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1)
@@ -294,7 +288,7 @@ static void gbe_turn_off(void) · 8 unmodified lines
294 val = gbe->dotclock;288 val = gbe->dotclock;
295 SET_GBE_FIELD(DOTCLK, RUN, val, 0);289 SET_GBE_FIELD(DOTCLK, RUN, val, 0);
296 gbe->dotclock = val;290 gbe->dotclock = val;
297 udelay(10000);291 mdelay(10);
298 for (i = 0; i < 10000; i++) {292 for (i = 0; i < 10000; i++) {
299 val = gbe->dotclock;293 val = gbe->dotclock;
300 if (GET_GBE_FIELD(DOTCLK, RUN, val))294 if (GET_GBE_FIELD(DOTCLK, RUN, val))
@@ -331,7 +325,7 @@ static void gbe_turn_on(void) · 30 unmodified lines
331 val = gbe->dotclock;325 val = gbe->dotclock;
332 SET_GBE_FIELD(DOTCLK, RUN, val, 1);326 SET_GBE_FIELD(DOTCLK, RUN, val, 1);
333 gbe->dotclock = val;327 gbe->dotclock = val;
334 udelay(10000);328 mdelay(10);
335 for (i = 0; i < 10000; i++) {329 for (i = 0; i < 10000; i++) {
336 val = gbe->dotclock;330 val = gbe->dotclock;
337 if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1)331 if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1)
@@ -346,7 +340,7 @@ static void gbe_turn_on(void) · 8 unmodified lines
346 val = 0;340 val = 0;
347 SET_GBE_FIELD(VT_XY, FREEZE, val, 0);341 SET_GBE_FIELD(VT_XY, FREEZE, val, 0);
348 gbe->vt_xy = val;342 gbe->vt_xy = val;
349 udelay(10000);343 mdelay(10);
350 for (i = 0; i < 10000; i++) {344 for (i = 0; i < 10000; i++) {
351 val = gbe->vt_xy;345 val = gbe->vt_xy;
352 if (GET_GBE_FIELD(VT_XY, FREEZE, val))346 if (GET_GBE_FIELD(VT_XY, FREEZE, val))
@@ -547,7 +541,7 @@ static void gbe_set_timing_info(struct gbe_timing_info *timing) · 194 unmodified lines
547 SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p);541 SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p);
548 SET_GBE_FIELD(DOTCLK, RUN, val, 0); /* do not start yet */542 SET_GBE_FIELD(DOTCLK, RUN, val, 0); /* do not start yet */
549 gbe->dotclock = val;543 gbe->dotclock = val;
550 udelay(10000);544 mdelay(10);
551 545
552 /* setup pixel counter */546 /* setup pixel counter */
553 val = 0;547 val = 0;
@@ -1018,9 +1012,10 @@ static int gbefb_mmap(struct fb_info *info, · 464 unmodified lines
1018 1012
1019 /* remap using the fastest write-through mode on architecture */1013 /* remap using the fastest write-through mode on architecture */
1020 /* try not polluting the cache when possible */1014 /* try not polluting the cache when possible */
1015#ifdef CONFIG_MIPS
1021 pgprot_val(vma->vm_page_prot) =1016 pgprot_val(vma->vm_page_prot) =
1022 pgprot_fb(pgprot_val(vma->vm_page_prot));1017 pgprot_fb(pgprot_val(vma->vm_page_prot));
1023 1018#endif
1024 /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */1019 /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
1025 1020
1026 /* look for the starting tile */1021 /* look for the starting tile */
drivers/video/fbdev/grvga.c+1−3
@@ -336,10 +336,8 @@ static int grvga_probe(struct platform_device *dev) · 335 unmodified lines
336 char *options = NULL, *mode_opt = NULL;336 char *options = NULL, *mode_opt = NULL;
337 337
338 info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);338 info = framebuffer_alloc(sizeof(struct grvga_par), &dev->dev);
339 if (!info) {339 if (!info)
340 dev_err(&dev->dev, "framebuffer_alloc failed\n");
341 return -ENOMEM;340 return -ENOMEM;
342 }
343 341
344 /* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>]342 /* Expecting: "grvga: modestring, [addr:<framebuffer physical address>], [size:<framebuffer size>]
345 *343 *
drivers/video/fbdev/gxt4500.c+2−3
@@ -643,10 +643,9 @@ static int gxt4500_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 642 unmodified lines
643 }643 }
644 644
645 info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev);645 info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev);
646 if (!info) {646 if (!info)
647 dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record\n");
648 goto err_free_fb;647 goto err_free_fb;
649 }648
650 par = info->par;649 par = info->par;
651 cardtype = ent->driver_data;650 cardtype = ent->driver_data;
652 par->refclk_ps = cardinfo[cardtype].refclk_ps;651 par->refclk_ps = cardinfo[cardtype].refclk_ps;
drivers/video/fbdev/hyperv_fb.c+1−3
@@ -762,10 +762,8 @@ static int hvfb_probe(struct hv_device *hdev, · 761 unmodified lines
762 int ret;762 int ret;
763 763
764 info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device);764 info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device);
765 if (!info) {765 if (!info)
766 pr_err("No memory for framebuffer info\n");
767 return -ENOMEM;766 return -ENOMEM;
768 }
769 767
770 par = info->par;768 par = info->par;
771 par->info = info;769 par->info = info;
drivers/video/fbdev/i740fb.c+1−3
@@ -1006,10 +1006,8 @@ static int i740fb_probe(struct pci_dev *dev, const struct pci_device_id *ent) · 1005 unmodified lines
1006 u8 *edid;1006 u8 *edid;
1007 1007
1008 info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev));1008 info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev));
1009 if (!info) {1009 if (!info)
1010 dev_err(&(dev->dev), "cannot allocate framebuffer\n");
1011 return -ENOMEM;1010 return -ENOMEM;
1012 }
1013 1011
1014 par = info->par;1012 par = info->par;
1015 mutex_init(&par->open_lock);1013 mutex_init(&par->open_lock);
drivers/video/fbdev/imsttfb.c+1−4
@@ -1477,11 +1477,8 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 1476 unmodified lines
1477 printk(KERN_ERR "imsttfb: no OF node for pci device\n");1477 printk(KERN_ERR "imsttfb: no OF node for pci device\n");
1478 1478
1479 info = framebuffer_alloc(sizeof(struct imstt_par), &pdev->dev);1479 info = framebuffer_alloc(sizeof(struct imstt_par), &pdev->dev);
1480 1480 if (!info)
1481 if (!info) {
1482 printk(KERN_ERR "imsttfb: Can't allocate memory\n");
1483 return -ENOMEM;1481 return -ENOMEM;
1484 }
1485 1482
1486 par = info->par;1483 par = info->par;
1487 1484
drivers/video/fbdev/imxfb.c+5−6
@@ -974,10 +974,9 @@ static int imxfb_probe(struct platform_device *pdev) · 973 unmodified lines
974 }974 }
975 975
976 fbi->map_size = PAGE_ALIGN(info->fix.smem_len);976 fbi->map_size = PAGE_ALIGN(info->fix.smem_len);
977 info->screen_base = dma_alloc_wc(&pdev->dev, fbi->map_size,977 info->screen_buffer = dma_alloc_wc(&pdev->dev, fbi->map_size,
978 &fbi->map_dma, GFP_KERNEL);978 &fbi->map_dma, GFP_KERNEL);
979 979 if (!info->screen_buffer) {
980 if (!info->screen_base) {
981 dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);980 dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
982 ret = -ENOMEM;981 ret = -ENOMEM;
983 goto failed_map;982 goto failed_map;
@@ -1046,7 +1045,7 @@ failed_cmap: · 62 unmodified lines
1046 if (pdata && pdata->exit)1045 if (pdata && pdata->exit)
1047 pdata->exit(fbi->pdev);1046 pdata->exit(fbi->pdev);
1048failed_platform_init:1047failed_platform_init:
1049 dma_free_wc(&pdev->dev, fbi->map_size, info->screen_base,1048 dma_free_wc(&pdev->dev, fbi->map_size, info->screen_buffer,
1050 fbi->map_dma);1049 fbi->map_dma);
1051failed_map:1050failed_map:
1052 iounmap(fbi->regs);1051 iounmap(fbi->regs);
@@ -1077,7 +1076,7 @@ static int imxfb_remove(struct platform_device *pdev) · 24 unmodified lines
1077 pdata = dev_get_platdata(&pdev->dev);1076 pdata = dev_get_platdata(&pdev->dev);
1078 if (pdata && pdata->exit)1077 if (pdata && pdata->exit)
1079 pdata->exit(fbi->pdev);1078 pdata->exit(fbi->pdev);
1080 dma_free_wc(&pdev->dev, fbi->map_size, info->screen_base,1079 dma_free_wc(&pdev->dev, fbi->map_size, info->screen_buffer,
1081 fbi->map_dma);1080 fbi->map_dma);
1082 iounmap(fbi->regs);1081 iounmap(fbi->regs);
1083 release_mem_region(res->start, resource_size(res));1082 release_mem_region(res->start, resource_size(res));
drivers/video/fbdev/intelfb/intelfbdrv.c+3−4
@@ -491,10 +491,9 @@ static int intelfb_pci_register(struct pci_dev *pdev, · 490 unmodified lines
491 }491 }
492 492
493 info = framebuffer_alloc(sizeof(struct intelfb_info), &pdev->dev);493 info = framebuffer_alloc(sizeof(struct intelfb_info), &pdev->dev);
494 if (!info) {494 if (!info)
495 ERR_MSG("Could not allocate memory for intelfb_info.\n");495 return -ENOMEM;
496 return -ENODEV;496
497 }
498 if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {497 if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
499 ERR_MSG("Could not allocate cmap for intelfb_info.\n");498 ERR_MSG("Could not allocate cmap for intelfb_info.\n");
500 goto err_out_cmap;499 goto err_out_cmap;
drivers/video/fbdev/jz4740_fb.c+1−10
@@ -457,7 +457,6 @@ static int jzfb_alloc_devmem(struct jzfb *jzfb) · 456 unmodified lines
457{457{
458 int max_videosize = 0;458 int max_videosize = 0;
459 struct fb_videomode *mode = jzfb->pdata->modes;459 struct fb_videomode *mode = jzfb->pdata->modes;
460 void *page;
461 int i;460 int i;
462 461
463 for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) {462 for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) {
@@ -482,12 +481,6 @@ static int jzfb_alloc_devmem(struct jzfb *jzfb) · 18 unmodified lines
482 if (!jzfb->vidmem)481 if (!jzfb->vidmem)
483 goto err_free_framedesc;482 goto err_free_framedesc;
484 483
485 for (page = jzfb->vidmem;
486 page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
487 page += PAGE_SIZE) {
488 SetPageReserved(virt_to_page(page));
489 }
490
491 jzfb->framedesc->next = jzfb->framedesc_phys;484 jzfb->framedesc->next = jzfb->framedesc_phys;
492 jzfb->framedesc->addr = jzfb->vidmem_phys;485 jzfb->framedesc->addr = jzfb->vidmem_phys;
493 jzfb->framedesc->id = 0xdeafbead;486 jzfb->framedesc->id = 0xdeafbead;
@@ -535,10 +528,8 @@ static int jzfb_probe(struct platform_device *pdev) · 41 unmodified lines
535 }528 }
536 529
537 fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);530 fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
538 if (!fb) {531 if (!fb)
539 dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
540 return -ENOMEM;532 return -ENOMEM;
541 }
542 533
543 fb->fbops = &jzfb_ops;534 fb->fbops = &jzfb_ops;
544 fb->flags = FBINFO_DEFAULT;535 fb->flags = FBINFO_DEFAULT;
drivers/video/fbdev/mb862xx/mb862xxfbdrv.c+1−4
@@ -680,10 +680,8 @@ static int of_platform_mb862xx_probe(struct platform_device *ofdev) · 679 unmodified lines
680 }680 }
681 681
682 info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev);682 info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev);
683 if (info == NULL) {683 if (!info)
684 dev_err(dev, "cannot allocate framebuffer\n");
685 return -ENOMEM;684 return -ENOMEM;
686 }
687 685
688 par = info->par;686 par = info->par;
689 par->info = info;687 par->info = info;
@@ -1005,7 +1003,6 @@ static int mb862xx_pci_probe(struct pci_dev *pdev, · 315 unmodified lines
1005 1003
1006 info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev);1004 info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev);
1007 if (!info) {1005 if (!info) {
1008 dev_err(dev, "framebuffer alloc failed\n");
1009 ret = -ENOMEM;1006 ret = -ENOMEM;
1010 goto dis_dev;1007 goto dis_dev;
1011 }1008 }
drivers/video/fbdev/mbx/mbxfb.c+1−3
@@ -899,10 +899,8 @@ static int mbxfb_probe(struct platform_device *dev) · 898 unmodified lines
899 }899 }
900 900
901 fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);901 fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);
902 if (fbi == NULL) {902 if (!fbi)
903 dev_err(&dev->dev, "framebuffer_alloc failed\n");
904 return -ENOMEM;903 return -ENOMEM;
905 }
906 904
907 mfbi = fbi->par;905 mfbi = fbi->par;
908 fbi->pseudo_palette = mfbi->pseudo_palette;906 fbi->pseudo_palette = mfbi->pseudo_palette;
drivers/video/fbdev/mmp/hw/mmp_ctrl.c+4−4
@@ -433,7 +433,7 @@ static int mmphw_probe(struct platform_device *pdev) · 432 unmodified lines
433{433{
434 struct mmp_mach_plat_info *mi;434 struct mmp_mach_plat_info *mi;
435 struct resource *res;435 struct resource *res;
436 int ret, i, size, irq;436 int ret, i, irq;
437 struct mmphw_path_plat *path_plat;437 struct mmphw_path_plat *path_plat;
438 struct mmphw_ctrl *ctrl = NULL;438 struct mmphw_ctrl *ctrl = NULL;
439 439
@@ -461,9 +461,9 @@ static int mmphw_probe(struct platform_device *pdev) · 21 unmodified lines
461 }461 }
462 462
463 /* allocate */463 /* allocate */
464 size = sizeof(struct mmphw_ctrl) + sizeof(struct mmphw_path_plat) *464 ctrl = devm_kzalloc(&pdev->dev,
465 mi->path_num;465 struct_size(ctrl, path_plats, mi->path_num),
466 ctrl = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);466 GFP_KERNEL);
467 if (!ctrl) {467 if (!ctrl) {
468 ret = -ENOMEM;468 ret = -ENOMEM;
469 goto failed;469 goto failed;
drivers/video/fbdev/mxsfb.c+0−1028
@@ -1,1028 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2010 Juergen Beisert, Pengutronix
4 *
5 * This code is based on:
6 * Author: Vitaly Wool <vital@embeddedalley.com>
7 *
8 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
9 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
10 */
11
12#define DRIVER_NAME "mxsfb"
13
14/**
15 * @file
16 * @brief LCDIF driver for i.MX23 and i.MX28
17 *
18 * The LCDIF support four modes of operation
19 * - MPU interface (to drive smart displays) -> not supported yet
20 * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet
21 * - Dotclock interface (to drive LC displays with RGB data and sync signals)
22 * - DVI (to drive ITU-R BT656) -> not supported yet
23 *
24 * This driver depends on a correct setup of the pins used for this purpose
25 * (platform specific).
26 *
27 * For the developer: Don't forget to set the data bus width to the display
28 * in the imx_fb_videomode structure. You will else end up with ugly colours.
29 * If you fight against jitter you can vary the clock delay. This is a feature
30 * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give
31 * the required value in the imx_fb_videomode structure.
32 */
33
34#include <linux/module.h>
35#include <linux/kernel.h>
36#include <linux/of_device.h>
37#include <linux/platform_device.h>
38#include <linux/clk.h>
39#include <linux/dma-mapping.h>
40#include <linux/io.h>
41#include <linux/fb.h>
42#include <linux/regulator/consumer.h>
43#include <video/of_display_timing.h>
44#include <video/of_videomode.h>
45#include <video/videomode.h>
46
47#define REG_SET 4
48#define REG_CLR 8
49
50#define LCDC_CTRL 0x00
51#define LCDC_CTRL1 0x10
52#define LCDC_V4_CTRL2 0x20
53#define LCDC_V3_TRANSFER_COUNT 0x20
54#define LCDC_V4_TRANSFER_COUNT 0x30
55#define LCDC_V4_CUR_BUF 0x40
56#define LCDC_V4_NEXT_BUF 0x50
57#define LCDC_V3_CUR_BUF 0x30
58#define LCDC_V3_NEXT_BUF 0x40
59#define LCDC_TIMING 0x60
60#define LCDC_VDCTRL0 0x70
61#define LCDC_VDCTRL1 0x80
62#define LCDC_VDCTRL2 0x90
63#define LCDC_VDCTRL3 0xa0
64#define LCDC_VDCTRL4 0xb0
65#define LCDC_DVICTRL0 0xc0
66#define LCDC_DVICTRL1 0xd0
67#define LCDC_DVICTRL2 0xe0
68#define LCDC_DVICTRL3 0xf0
69#define LCDC_DVICTRL4 0x100
70#define LCDC_V4_DATA 0x180
71#define LCDC_V3_DATA 0x1b0
72#define LCDC_V4_DEBUG0 0x1d0
73#define LCDC_V3_DEBUG0 0x1f0
74
75#define CTRL_SFTRST (1 << 31)
76#define CTRL_CLKGATE (1 << 30)
77#define CTRL_BYPASS_COUNT (1 << 19)
78#define CTRL_VSYNC_MODE (1 << 18)
79#define CTRL_DOTCLK_MODE (1 << 17)
80#define CTRL_DATA_SELECT (1 << 16)
81#define CTRL_SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
82#define CTRL_GET_BUS_WIDTH(x) (((x) >> 10) & 0x3)
83#define CTRL_SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
84#define CTRL_GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
85#define CTRL_MASTER (1 << 5)
86#define CTRL_DF16 (1 << 3)
87#define CTRL_DF18 (1 << 2)
88#define CTRL_DF24 (1 << 1)
89#define CTRL_RUN (1 << 0)
90
91#define CTRL1_FIFO_CLEAR (1 << 21)
92#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
93#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
94
95#define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16)
96#define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff)
97#define TRANSFER_COUNT_SET_HCOUNT(x) ((x) & 0xffff)
98#define TRANSFER_COUNT_GET_HCOUNT(x) ((x) & 0xffff)
99
100
101#define VDCTRL0_ENABLE_PRESENT (1 << 28)
102#define VDCTRL0_VSYNC_ACT_HIGH (1 << 27)
103#define VDCTRL0_HSYNC_ACT_HIGH (1 << 26)
104#define VDCTRL0_DOTCLK_ACT_FALLING (1 << 25)
105#define VDCTRL0_ENABLE_ACT_HIGH (1 << 24)
106#define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
107#define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
108#define VDCTRL0_HALF_LINE (1 << 19)
109#define VDCTRL0_HALF_LINE_MODE (1 << 18)
110#define VDCTRL0_SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
111#define VDCTRL0_GET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
112
113#define VDCTRL2_SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
114#define VDCTRL2_GET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
115
116#define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)
117#define VDCTRL3_VSYNC_ONLY (1 << 28)
118#define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
119#define GET_HOR_WAIT_CNT(x) (((x) >> 16) & 0xfff)
120#define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
121#define GET_VERT_WAIT_CNT(x) ((x) & 0xffff)
122
123#define VDCTRL4_SET_DOTCLK_DLY(x) (((x) & 0x7) << 29) /* v4 only */
124#define VDCTRL4_GET_DOTCLK_DLY(x) (((x) >> 29) & 0x7) /* v4 only */
125#define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)
126#define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
127
128#define DEBUG0_HSYNC (1 < 26)
129#define DEBUG0_VSYNC (1 < 25)
130
131#define MIN_XRES 120
132#define MIN_YRES 120
133
134#define RED 0
135#define GREEN 1
136#define BLUE 2
137#define TRANSP 3
138
139#define STMLCDIF_8BIT 1 /** pixel data bus to the display is of 8 bit width */
140#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
141#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
142#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
143
144#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
145#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negative edge sampling */
146
147enum mxsfb_devtype {
148 MXSFB_V3,
149 MXSFB_V4,
150};
151
152/* CPU dependent register offsets */
153struct mxsfb_devdata {
154 unsigned transfer_count;
155 unsigned cur_buf;
156 unsigned next_buf;
157 unsigned debug0;
158 unsigned hs_wdth_mask;
159 unsigned hs_wdth_shift;
160 unsigned ipversion;
161};
162
163struct mxsfb_info {
164 struct platform_device *pdev;
165 struct clk *clk;
166 struct clk *clk_axi;
167 struct clk *clk_disp_axi;
168 void __iomem *base; /* registers */
169 unsigned allocated_size;
170 int enabled;
171 unsigned ld_intf_width;
172 unsigned dotclk_delay;
173 const struct mxsfb_devdata *devdata;
174 u32 sync;
175 struct regulator *reg_lcd;
176 int pre_init;
177};
178
179#define mxsfb_is_v3(host) (host->devdata->ipversion == 3)
180#define mxsfb_is_v4(host) (host->devdata->ipversion == 4)
181
182static const struct mxsfb_devdata mxsfb_devdata[] = {
183 [MXSFB_V3] = {
184 .transfer_count = LCDC_V3_TRANSFER_COUNT,
185 .cur_buf = LCDC_V3_CUR_BUF,
186 .next_buf = LCDC_V3_NEXT_BUF,
187 .debug0 = LCDC_V3_DEBUG0,
188 .hs_wdth_mask = 0xff,
189 .hs_wdth_shift = 24,
190 .ipversion = 3,
191 },
192 [MXSFB_V4] = {
193 .transfer_count = LCDC_V4_TRANSFER_COUNT,
194 .cur_buf = LCDC_V4_CUR_BUF,
195 .next_buf = LCDC_V4_NEXT_BUF,
196 .debug0 = LCDC_V4_DEBUG0,
197 .hs_wdth_mask = 0x3fff,
198 .hs_wdth_shift = 18,
199 .ipversion = 4,
200 },
201};
202
203/* mask and shift depends on architecture */
204static inline u32 set_hsync_pulse_width(struct mxsfb_info *host, unsigned val)
205{
206 return (val & host->devdata->hs_wdth_mask) <<
207 host->devdata->hs_wdth_shift;
208}
209
210static inline u32 get_hsync_pulse_width(struct mxsfb_info *host, unsigned val)
211{
212 return (val >> host->devdata->hs_wdth_shift) &
213 host->devdata->hs_wdth_mask;
214}
215
216static const struct fb_bitfield def_rgb565[] = {
217 [RED] = {
218 .offset = 11,
219 .length = 5,
220 },
221 [GREEN] = {
222 .offset = 5,
223 .length = 6,
224 },
225 [BLUE] = {
226 .offset = 0,
227 .length = 5,
228 },
229 [TRANSP] = { /* no support for transparency */
230 .length = 0,
231 }
232};
233
234static const struct fb_bitfield def_rgb888[] = {
235 [RED] = {
236 .offset = 16,
237 .length = 8,
238 },
239 [GREEN] = {
240 .offset = 8,
241 .length = 8,
242 },
243 [BLUE] = {
244 .offset = 0,
245 .length = 8,
246 },
247 [TRANSP] = { /* no support for transparency */
248 .length = 0,
249 }
250};
251
252static inline unsigned chan_to_field(unsigned chan, struct fb_bitfield *bf)
253{
254 chan &= 0xffff;
255 chan >>= 16 - bf->length;
256 return chan << bf->offset;
257}
258
259static int mxsfb_check_var(struct fb_var_screeninfo *var,
260 struct fb_info *fb_info)
261{
262 struct mxsfb_info *host = fb_info->par;
263 const struct fb_bitfield *rgb = NULL;
264
265 if (var->xres < MIN_XRES)
266 var->xres = MIN_XRES;
267 if (var->yres < MIN_YRES)
268 var->yres = MIN_YRES;
269
270 var->xres_virtual = var->xres;
271
272 var->yres_virtual = var->yres;
273
274 switch (var->bits_per_pixel) {
275 case 16:
276 /* always expect RGB 565 */
277 rgb = def_rgb565;
278 break;
279 case 32:
280 switch (host->ld_intf_width) {
281 case STMLCDIF_8BIT:
282 pr_debug("Unsupported LCD bus width mapping\n");
283 break;
284 case STMLCDIF_16BIT:
285 case STMLCDIF_18BIT:
286 case STMLCDIF_24BIT:
287 /* real 24 bit */
288 rgb = def_rgb888;
289 break;
290 }
291 break;
292 default:
293 pr_err("Unsupported colour depth: %u\n", var->bits_per_pixel);
294 return -EINVAL;
295 }
296
297 /*
298 * Copy the RGB parameters for this display
299 * from the machine specific parameters.
300 */
301 var->red = rgb[RED];
302 var->green = rgb[GREEN];
303 var->blue = rgb[BLUE];
304 var->transp = rgb[TRANSP];
305
306 return 0;
307}
308
309static inline void mxsfb_enable_axi_clk(struct mxsfb_info *host)
310{
311 if (host->clk_axi)
312 clk_prepare_enable(host->clk_axi);
313}
314
315static inline void mxsfb_disable_axi_clk(struct mxsfb_info *host)
316{
317 if (host->clk_axi)
318 clk_disable_unprepare(host->clk_axi);
319}
320
321static void mxsfb_enable_controller(struct fb_info *fb_info)
322{
323 struct mxsfb_info *host = fb_info->par;
324 u32 reg;
325 int ret;
326
327 dev_dbg(&host->pdev->dev, "%s\n", __func__);
328
329 if (host->reg_lcd) {
330 ret = regulator_enable(host->reg_lcd);
331 if (ret) {
332 dev_err(&host->pdev->dev,
333 "lcd regulator enable failed: %d\n", ret);
334 return;
335 }
336 }
337
338 if (host->clk_disp_axi)
339 clk_prepare_enable(host->clk_disp_axi);
340 clk_prepare_enable(host->clk);
341 clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
342
343 mxsfb_enable_axi_clk(host);
344
345 /* if it was disabled, re-enable the mode again */
346 writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_SET);
347
348 /* enable the SYNC signals first, then the DMA engine */
349 reg = readl(host->base + LCDC_VDCTRL4);
350 reg |= VDCTRL4_SYNC_SIGNALS_ON;
351 writel(reg, host->base + LCDC_VDCTRL4);
352
353 writel(CTRL_RUN, host->base + LCDC_CTRL + REG_SET);
354
355 host->enabled = 1;
356}
357
358static void mxsfb_disable_controller(struct fb_info *fb_info)
359{
360 struct mxsfb_info *host = fb_info->par;
361 unsigned loop;
362 u32 reg;
363 int ret;
364
365 dev_dbg(&host->pdev->dev, "%s\n", __func__);
366
367 /*
368 * Even if we disable the controller here, it will still continue
369 * until its FIFOs are running out of data
370 */
371 writel(CTRL_DOTCLK_MODE, host->base + LCDC_CTRL + REG_CLR);
372
373 loop = 1000;
374 while (loop) {
375 reg = readl(host->base + LCDC_CTRL);
376 if (!(reg & CTRL_RUN))
377 break;
378 loop--;
379 }
380
381 reg = readl(host->base + LCDC_VDCTRL4);
382 writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
383
384 mxsfb_disable_axi_clk(host);
385
386 clk_disable_unprepare(host->clk);
387 if (host->clk_disp_axi)
388 clk_disable_unprepare(host->clk_disp_axi);
389
390 host->enabled = 0;
391
392 if (host->reg_lcd) {
393 ret = regulator_disable(host->reg_lcd);
394 if (ret)
395 dev_err(&host->pdev->dev,
396 "lcd regulator disable failed: %d\n", ret);
397 }
398}
399
400static int mxsfb_set_par(struct fb_info *fb_info)
401{
402 struct mxsfb_info *host = fb_info->par;
403 u32 ctrl, vdctrl0, vdctrl4;
404 int line_size, fb_size;
405 int reenable = 0;
406
407 line_size = fb_info->var.xres * (fb_info->var.bits_per_pixel >> 3);
408 fb_size = fb_info->var.yres_virtual * line_size;
409
410 if (fb_size > fb_info->fix.smem_len)
411 return -ENOMEM;
412
413 fb_info->fix.line_length = line_size;
414
415 if (host->pre_init) {
416 mxsfb_enable_controller(fb_info);
417 host->pre_init = 0;
418 return 0;
419 }
420
421 /*
422 * It seems, you can't re-program the controller if it is still running.
423 * This may lead into shifted pictures (FIFO issue?).
424 * So, first stop the controller and drain its FIFOs
425 */
426 if (host->enabled) {
427 reenable = 1;
428 mxsfb_disable_controller(fb_info);
429 }
430
431 mxsfb_enable_axi_clk(host);
432
433 /* clear the FIFOs */
434 writel(CTRL1_FIFO_CLEAR, host->base + LCDC_CTRL1 + REG_SET);
435
436 ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER |
437 CTRL_SET_BUS_WIDTH(host->ld_intf_width);
438
439 switch (fb_info->var.bits_per_pixel) {
440 case 16:
441 dev_dbg(&host->pdev->dev, "Setting up RGB565 mode\n");
442 ctrl |= CTRL_SET_WORD_LENGTH(0);
443 writel(CTRL1_SET_BYTE_PACKAGING(0xf), host->base + LCDC_CTRL1);
444 break;
445 case 32:
446 dev_dbg(&host->pdev->dev, "Setting up RGB888/666 mode\n");
447 ctrl |= CTRL_SET_WORD_LENGTH(3);
448 switch (host->ld_intf_width) {
449 case STMLCDIF_8BIT:
450 mxsfb_disable_axi_clk(host);
451 dev_err(&host->pdev->dev,
452 "Unsupported LCD bus width mapping\n");
453 return -EINVAL;
454 case STMLCDIF_16BIT:
455 case STMLCDIF_18BIT:
456 case STMLCDIF_24BIT:
457 /* real 24 bit */
458 break;
459 }
460 /* do not use packed pixels = one pixel per word instead */
461 writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1);
462 break;
463 default:
464 mxsfb_disable_axi_clk(host);
465 dev_err(&host->pdev->dev, "Unhandled color depth of %u\n",
466 fb_info->var.bits_per_pixel);
467 return -EINVAL;
468 }
469
470 writel(ctrl, host->base + LCDC_CTRL);
471
472 writel(TRANSFER_COUNT_SET_VCOUNT(fb_info->var.yres) |
473 TRANSFER_COUNT_SET_HCOUNT(fb_info->var.xres),
474 host->base + host->devdata->transfer_count);
475
476 vdctrl0 = VDCTRL0_ENABLE_PRESENT | /* always in DOTCLOCK mode */
477 VDCTRL0_VSYNC_PERIOD_UNIT |
478 VDCTRL0_VSYNC_PULSE_WIDTH_UNIT |
479 VDCTRL0_SET_VSYNC_PULSE_WIDTH(fb_info->var.vsync_len);
480 if (fb_info->var.sync & FB_SYNC_HOR_HIGH_ACT)
481 vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
482 if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT)
483 vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
484 if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT)
485 vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
486 if (host->sync & MXSFB_SYNC_DOTCLK_FALLING_ACT)
487 vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;
488
489 writel(vdctrl0, host->base + LCDC_VDCTRL0);
490
491 /* frame length in lines */
492 writel(fb_info->var.upper_margin + fb_info->var.vsync_len +
493 fb_info->var.lower_margin + fb_info->var.yres,
494 host->base + LCDC_VDCTRL1);
495
496 /* line length in units of clocks or pixels */
497 writel(set_hsync_pulse_width(host, fb_info->var.hsync_len) |
498 VDCTRL2_SET_HSYNC_PERIOD(fb_info->var.left_margin +
499 fb_info->var.hsync_len + fb_info->var.right_margin +
500 fb_info->var.xres),
501 host->base + LCDC_VDCTRL2);
502
503 writel(SET_HOR_WAIT_CNT(fb_info->var.left_margin +
504 fb_info->var.hsync_len) |
505 SET_VERT_WAIT_CNT(fb_info->var.upper_margin +
506 fb_info->var.vsync_len),
507 host->base + LCDC_VDCTRL3);
508
509 vdctrl4 = SET_DOTCLK_H_VALID_DATA_CNT(fb_info->var.xres);
510 if (mxsfb_is_v4(host))
511 vdctrl4 |= VDCTRL4_SET_DOTCLK_DLY(host->dotclk_delay);
512 writel(vdctrl4, host->base + LCDC_VDCTRL4);
513
514 writel(fb_info->fix.smem_start +
515 fb_info->fix.line_length * fb_info->var.yoffset,
516 host->base + host->devdata->next_buf);
517
518 mxsfb_disable_axi_clk(host);
519
520 if (reenable)
521 mxsfb_enable_controller(fb_info);
522
523 return 0;
524}
525
526static int mxsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
527 u_int transp, struct fb_info *fb_info)
528{
529 unsigned int val;
530 int ret = -EINVAL;
531
532 /*
533 * If greyscale is true, then we convert the RGB value
534 * to greyscale no matter what visual we are using.
535 */
536 if (fb_info->var.grayscale)
537 red = green = blue = (19595 * red + 38470 * green +
538 7471 * blue) >> 16;
539
540 switch (fb_info->fix.visual) {
541 case FB_VISUAL_TRUECOLOR:
542 /*
543 * 12 or 16-bit True Colour. We encode the RGB value
544 * according to the RGB bitfield information.
545 */
546 if (regno < 16) {
547 u32 *pal = fb_info->pseudo_palette;
548
549 val = chan_to_field(red, &fb_info->var.red);
550 val |= chan_to_field(green, &fb_info->var.green);
551 val |= chan_to_field(blue, &fb_info->var.blue);
552
553 pal[regno] = val;
554 ret = 0;
555 }
556 break;
557
558 case FB_VISUAL_STATIC_PSEUDOCOLOR:
559 case FB_VISUAL_PSEUDOCOLOR:
560 break;
561 }
562
563 return ret;
564}
565
566static int mxsfb_blank(int blank, struct fb_info *fb_info)
567{
568 struct mxsfb_info *host = fb_info->par;
569
570 switch (blank) {
571 case FB_BLANK_POWERDOWN:
572 case FB_BLANK_VSYNC_SUSPEND:
573 case FB_BLANK_HSYNC_SUSPEND:
574 case FB_BLANK_NORMAL:
575 if (host->enabled)
576 mxsfb_disable_controller(fb_info);
577 break;
578
579 case FB_BLANK_UNBLANK:
580 if (!host->enabled)
581 mxsfb_enable_controller(fb_info);
582 break;
583 }
584 return 0;
585}
586
587static int mxsfb_pan_display(struct fb_var_screeninfo *var,
588 struct fb_info *fb_info)
589{
590 struct mxsfb_info *host = fb_info->par;
591 unsigned offset;
592
593 if (var->xoffset != 0)
594 return -EINVAL;
595
596 offset = fb_info->fix.line_length * var->yoffset;
597
598 mxsfb_enable_axi_clk(host);
599
600 /* update on next VSYNC */
601 writel(fb_info->fix.smem_start + offset,
602 host->base + host->devdata->next_buf);
603
604 mxsfb_disable_axi_clk(host);
605
606 return 0;
607}
608
609static struct fb_ops mxsfb_ops = {
610 .owner = THIS_MODULE,
611 .fb_check_var = mxsfb_check_var,
612 .fb_set_par = mxsfb_set_par,
613 .fb_setcolreg = mxsfb_setcolreg,
614 .fb_blank = mxsfb_blank,
615 .fb_pan_display = mxsfb_pan_display,
616 .fb_fillrect = cfb_fillrect,
617 .fb_copyarea = cfb_copyarea,
618 .fb_imageblit = cfb_imageblit,
619};
620
621static int mxsfb_restore_mode(struct fb_info *fb_info,
622 struct fb_videomode *vmode)
623{
624 struct mxsfb_info *host = fb_info->par;
625 unsigned period;
626 unsigned long pa, fbsize;
627 int bits_per_pixel, ofs, ret = 0;
628 u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl;
629
630 mxsfb_enable_axi_clk(host);
631
632 /* Only restore the mode when the controller is running */
633 ctrl = readl(host->base + LCDC_CTRL);
634 if (!(ctrl & CTRL_RUN)) {
635 ret = -EINVAL;
636 goto err;
637 }
638
639 vdctrl0 = readl(host->base + LCDC_VDCTRL0);
640 vdctrl2 = readl(host->base + LCDC_VDCTRL2);
641 vdctrl3 = readl(host->base + LCDC_VDCTRL3);
642 vdctrl4 = readl(host->base + LCDC_VDCTRL4);
643
644 transfer_count = readl(host->base + host->devdata->transfer_count);
645
646 vmode->xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count);
647 vmode->yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count);
648
649 switch (CTRL_GET_WORD_LENGTH(ctrl)) {
650 case 0:
651 bits_per_pixel = 16;
652 break;
653 case 3:
654 bits_per_pixel = 32;
655 break;
656 case 1:
657 default:
658 ret = -EINVAL;
659 goto err;
660 }
661
662 fb_info->var.bits_per_pixel = bits_per_pixel;
663
664 vmode->pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U);
665 vmode->hsync_len = get_hsync_pulse_width(host, vdctrl2);
666 vmode->left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode->hsync_len;
667 vmode->right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) -
668 vmode->hsync_len - vmode->left_margin - vmode->xres;
669 vmode->vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0);
670 period = readl(host->base + LCDC_VDCTRL1);
671 vmode->upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode->vsync_len;
672 vmode->lower_margin = period - vmode->vsync_len -
673 vmode->upper_margin - vmode->yres;
674
675 vmode->vmode = FB_VMODE_NONINTERLACED;
676
677 vmode->sync = 0;
678 if (vdctrl0 & VDCTRL0_HSYNC_ACT_HIGH)
679 vmode->sync |= FB_SYNC_HOR_HIGH_ACT;
680 if (vdctrl0 & VDCTRL0_VSYNC_ACT_HIGH)
681 vmode->sync |= FB_SYNC_VERT_HIGH_ACT;
682
683 pr_debug("Reconstructed video mode:\n");
684 pr_debug("%dx%d, hsync: %u left: %u, right: %u, vsync: %u, upper: %u, lower: %u\n",
685 vmode->xres, vmode->yres, vmode->hsync_len, vmode->left_margin,
686 vmode->right_margin, vmode->vsync_len, vmode->upper_margin,
687 vmode->lower_margin);
688 pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode->pixclock));
689
690 host->ld_intf_width = CTRL_GET_BUS_WIDTH(ctrl);
691 host->dotclk_delay = VDCTRL4_GET_DOTCLK_DLY(vdctrl4);
692
693 fb_info->fix.line_length = vmode->xres * (bits_per_pixel >> 3);
694
695 pa = readl(host->base + host->devdata->cur_buf);
696 fbsize = fb_info->fix.line_length * vmode->yres;
697 if (pa < fb_info->fix.smem_start) {
698 ret = -EINVAL;
699 goto err;
700 }
701 if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) {
702 ret = -EINVAL;
703 goto err;
704 }
705 ofs = pa - fb_info->fix.smem_start;
706 if (ofs) {
707 memmove(fb_info->screen_base, fb_info->screen_base + ofs, fbsize);
708 writel(fb_info->fix.smem_start, host->base + host->devdata->next_buf);
709 }
710
711 fb_info->fix.ypanstep = 1;
712
713 clk_prepare_enable(host->clk);
714 host->enabled = 1;
715
716err:
717 if (ret)
718 mxsfb_disable_axi_clk(host);
719
720 return ret;
721}
722
723static int mxsfb_init_fbinfo_dt(struct fb_info *fb_info,
724 struct fb_videomode *vmode)
725{
726 struct mxsfb_info *host = fb_info->par;
727 struct fb_var_screeninfo *var = &fb_info->var;
728 struct device *dev = &host->pdev->dev;
729 struct device_node *np = host->pdev->dev.of_node;
730 struct device_node *display_np;
731 struct videomode vm;
732 u32 width;
733 int ret;
734
735 display_np = of_parse_phandle(np, "display", 0);
736 if (!display_np) {
737 dev_err(dev, "failed to find display phandle\n");
738 return -ENOENT;
739 }
740
741 ret = of_property_read_u32(display_np, "bus-width", &width);
742 if (ret < 0) {
743 dev_err(dev, "failed to get property bus-width\n");
744 goto put_display_node;
745 }
746
747 switch (width) {
748 case 8:
749 host->ld_intf_width = STMLCDIF_8BIT;
750 break;
751 case 16:
752 host->ld_intf_width = STMLCDIF_16BIT;
753 break;
754 case 18:
755 host->ld_intf_width = STMLCDIF_18BIT;
756 break;
757 case 24:
758 host->ld_intf_width = STMLCDIF_24BIT;
759 break;
760 default:
761 dev_err(dev, "invalid bus-width value\n");
762 ret = -EINVAL;
763 goto put_display_node;
764 }
765
766 ret = of_property_read_u32(display_np, "bits-per-pixel",
767 &var->bits_per_pixel);
768 if (ret < 0) {
769 dev_err(dev, "failed to get property bits-per-pixel\n");
770 goto put_display_node;
771 }
772
773 ret = of_get_videomode(display_np, &vm, OF_USE_NATIVE_MODE);
774 if (ret) {
775 dev_err(dev, "failed to get videomode from DT\n");
776 goto put_display_node;
777 }
778
779 ret = fb_videomode_from_videomode(&vm, vmode);
780 if (ret < 0)
781 goto put_display_node;
782
783 if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
784 host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
785
786 /*
787 * The PIXDATA flags of the display_flags enum are controller
788 * centric, e.g. NEGEDGE means drive data on negative edge.
789 * However, the drivers flag is display centric: Sample the
790 * data on negative (falling) edge. Therefore, check for the
791 * POSEDGE flag:
792 * drive on positive edge => sample on negative edge
793 */
794 if (vm.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
795 host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT;
796
797put_display_node:
798 of_node_put(display_np);
799 return ret;
800}
801
802static int mxsfb_init_fbinfo(struct fb_info *fb_info,
803 struct fb_videomode *vmode)
804{
805 int ret;
806 struct mxsfb_info *host = fb_info->par;
807 struct device *dev = &host->pdev->dev;
808 struct fb_var_screeninfo *var = &fb_info->var;
809 dma_addr_t fb_phys;
810 void *fb_virt;
811 unsigned fb_size;
812
813 fb_info->fbops = &mxsfb_ops;
814 fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
815 strlcpy(fb_info->fix.id, "mxs", sizeof(fb_info->fix.id));
816 fb_info->fix.type = FB_TYPE_PACKED_PIXELS;
817 fb_info->fix.ypanstep = 1;
818 fb_info->fix.visual = FB_VISUAL_TRUECOLOR,
819 fb_info->fix.accel = FB_ACCEL_NONE;
820
821 ret = mxsfb_init_fbinfo_dt(fb_info, vmode);
822 if (ret)
823 return ret;
824
825 var->nonstd = 0;
826 var->activate = FB_ACTIVATE_NOW;
827 var->accel_flags = 0;
828 var->vmode = FB_VMODE_NONINTERLACED;
829
830 /* Memory allocation for framebuffer */
831 fb_size = SZ_2M;
832 fb_virt = dma_alloc_wc(dev, PAGE_ALIGN(fb_size), &fb_phys, GFP_KERNEL);
833 if (!fb_virt)
834 return -ENOMEM;
835
836 fb_info->fix.smem_start = fb_phys;
837 fb_info->screen_base = fb_virt;
838 fb_info->screen_size = fb_info->fix.smem_len = fb_size;
839
840 if (mxsfb_restore_mode(fb_info, vmode))
841 memset(fb_virt, 0, fb_size);
842
843 return 0;
844}
845
846static void mxsfb_free_videomem(struct fb_info *fb_info)
847{
848 struct mxsfb_info *host = fb_info->par;
849 struct device *dev = &host->pdev->dev;
850
851 dma_free_wc(dev, fb_info->screen_size, fb_info->screen_base,
852 fb_info->fix.smem_start);
853}
854
855static const struct platform_device_id mxsfb_devtype[] = {
856 {
857 .name = "imx23-fb",
858 .driver_data = MXSFB_V3,
859 }, {
860 .name = "imx28-fb",
861 .driver_data = MXSFB_V4,
862 }, {
863 /* sentinel */
864 }
865};
866MODULE_DEVICE_TABLE(platform, mxsfb_devtype);
867
868static const struct of_device_id mxsfb_dt_ids[] = {
869 { .compatible = "fsl,imx23-lcdif", .data = &mxsfb_devtype[0], },
870 { .compatible = "fsl,imx28-lcdif", .data = &mxsfb_devtype[1], },
871 { /* sentinel */ }
872};
873MODULE_DEVICE_TABLE(of, mxsfb_dt_ids);
874
875static int mxsfb_probe(struct platform_device *pdev)
876{
877 const struct of_device_id *of_id =
878 of_match_device(mxsfb_dt_ids, &pdev->dev);
879 struct resource *res;
880 struct mxsfb_info *host;
881 struct fb_info *fb_info;
882 struct fb_videomode *mode;
883 int ret;
884
885 if (of_id)
886 pdev->id_entry = of_id->data;
887
888 fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev);
889 if (!fb_info) {
890 dev_err(&pdev->dev, "Failed to allocate fbdev\n");
891 return -ENOMEM;
892 }
893
894 mode = devm_kzalloc(&pdev->dev, sizeof(struct fb_videomode),
895 GFP_KERNEL);
896 if (mode == NULL)
897 return -ENOMEM;
898
899 host = fb_info->par;
900
901 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
902 host->base = devm_ioremap_resource(&pdev->dev, res);
903 if (IS_ERR(host->base)) {
904 ret = PTR_ERR(host->base);
905 goto fb_release;
906 }
907
908 host->pdev = pdev;
909 platform_set_drvdata(pdev, host);
910
911 host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data];
912
913 host->clk = devm_clk_get(&host->pdev->dev, NULL);
914 if (IS_ERR(host->clk)) {
915 ret = PTR_ERR(host->clk);
916 goto fb_release;
917 }
918
919 host->clk_axi = devm_clk_get(&host->pdev->dev, "axi");
920 if (IS_ERR(host->clk_axi))
921 host->clk_axi = NULL;
922
923 host->clk_disp_axi = devm_clk_get(&host->pdev->dev, "disp_axi");
924 if (IS_ERR(host->clk_disp_axi))
925 host->clk_disp_axi = NULL;
926
927 host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
928 if (IS_ERR(host->reg_lcd))
929 host->reg_lcd = NULL;
930
931#if defined(CONFIG_FB_PRE_INIT_FB)
932 host->pre_init = 1;
933#endif
934
935 fb_info->pseudo_palette = devm_kcalloc(&pdev->dev, 16, sizeof(u32),
936 GFP_KERNEL);
937 if (!fb_info->pseudo_palette) {
938 ret = -ENOMEM;
939 goto fb_release;
940 }
941
942 ret = mxsfb_init_fbinfo(fb_info, mode);
943 if (ret != 0)
944 goto fb_release;
945
946 fb_videomode_to_var(&fb_info->var, mode);
947
948 /* init the color fields */
949 mxsfb_check_var(&fb_info->var, fb_info);
950
951 platform_set_drvdata(pdev, fb_info);
952
953 ret = register_framebuffer(fb_info);
954 if (ret != 0) {
955 dev_err(&pdev->dev,"Failed to register framebuffer\n");
956 goto fb_destroy;
957 }
958
959 if (!host->enabled) {
960 mxsfb_enable_axi_clk(host);
961 writel(0, host->base + LCDC_CTRL);
962 mxsfb_disable_axi_clk(host);
963 mxsfb_set_par(fb_info);
964 mxsfb_enable_controller(fb_info);
965 }
966
967 host->pre_init = 0;
968 dev_info(&pdev->dev, "initialized\n");
969
970 return 0;
971
972fb_destroy:
973 if (host->enabled)
974 clk_disable_unprepare(host->clk);
975fb_release:
976 framebuffer_release(fb_info);
977
978 return ret;
979}
980
981static int mxsfb_remove(struct platform_device *pdev)
982{
983 struct fb_info *fb_info = platform_get_drvdata(pdev);
984 struct mxsfb_info *host = fb_info->par;
985
986 if (host->enabled)
987 mxsfb_disable_controller(fb_info);
988
989 unregister_framebuffer(fb_info);
990 mxsfb_free_videomem(fb_info);
991
992 framebuffer_release(fb_info);
993
994 return 0;
995}
996
997static void mxsfb_shutdown(struct platform_device *pdev)
998{
999 struct fb_info *fb_info = platform_get_drvdata(pdev);
1000 struct mxsfb_info *host = fb_info->par;
1001
1002 mxsfb_enable_axi_clk(host);
1003
1004 /*
1005 * Force stop the LCD controller as keeping it running during reboot
1006 * might interfere with the BootROM's boot mode pads sampling.
1007 */
1008 writel(CTRL_RUN, host->base + LCDC_CTRL + REG_CLR);
1009
1010 mxsfb_disable_axi_clk(host);
1011}
1012
1013static struct platform_driver mxsfb_driver = {
1014 .probe = mxsfb_probe,
1015 .remove = mxsfb_remove,
1016 .shutdown = mxsfb_shutdown,
1017 .id_table = mxsfb_devtype,
1018 .driver = {
1019 .name = DRIVER_NAME,
1020 .of_match_table = mxsfb_dt_ids,
1021 },
1022};
1023
1024module_platform_driver(mxsfb_driver);
1025
1026MODULE_DESCRIPTION("Freescale mxs framebuffer driver");
1027MODULE_AUTHOR("Sascha Hauer, Pengutronix");
1028MODULE_LICENSE("GPL");
drivers/video/fbdev/neofb.c+1−8
@@ -2122,14 +2122,7 @@ static void neofb_remove(struct pci_dev *dev) · 2121 unmodified lines
2122 DBG("neofb_remove");2122 DBG("neofb_remove");
2123 2123
2124 if (info) {2124 if (info) {
2125 /*2125 unregister_framebuffer(info);
2126 * If unregister_framebuffer fails, then
2127 * we will be leaving hooks that could cause
2128 * oopsen laying around.
2129 */
2130 if (unregister_framebuffer(info))
2131 printk(KERN_WARNING
2132 "neofb: danger danger! Oopsen imminent!\n");
2133 2126
2134 neo_unmap_video(info);2127 neo_unmap_video(info);
2135 fb_destroy_modedb(info->monspecs.modedb);2128 fb_destroy_modedb(info->monspecs.modedb);
drivers/video/fbdev/omap/omapfb_main.c+0−2
@@ -1502,8 +1502,6 @@ static int planes_init(struct omapfb_device *fbdev) · 1501 unmodified lines
1502 fbi = framebuffer_alloc(sizeof(struct omapfb_plane_struct),1502 fbi = framebuffer_alloc(sizeof(struct omapfb_plane_struct),
1503 fbdev->dev);1503 fbdev->dev);
1504 if (fbi == NULL) {1504 if (fbi == NULL) {
1505 dev_err(fbdev->dev,
1506 "unable to allocate memory for plane info\n");
1507 planes_cleanup(fbdev);1505 planes_cleanup(fbdev);
1508 return -ENOMEM;1506 return -ENOMEM;
1509 }1507 }
drivers/video/fbdev/omap2/omapfb/dss/Kconfig+0−12
@@ -39,18 +39,6 @@ config FB_OMAP2_DSS_DPI · 38 unmodified lines
39 help39 help
40 DPI Interface. This is the Parallel Display Interface.40 DPI Interface. This is the Parallel Display Interface.
41 41
42config FB_OMAP2_DSS_RFBI
43 bool "RFBI support"
44 depends on BROKEN
45 help
46 MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas
47 Instrument's terminology).
48
49 DBI is a bus between the host processor and a peripheral,
50 such as a display or a framebuffer chip.
51
52 See http://www.mipi.org/ for DBI specifications.
53
54config FB_OMAP2_DSS_VENC42config FB_OMAP2_DSS_VENC
55 bool "VENC support"43 bool "VENC support"
56 default y44 default y
drivers/video/fbdev/omap2/omapfb/dss/Makefile+0−1
@@ -8,7 +8,6 @@ omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ · 7 unmodified lines
8omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \8omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
9 dispc-compat.o display-sysfs.o9 dispc-compat.o display-sysfs.o
10omapdss-$(CONFIG_FB_OMAP2_DSS_DPI) += dpi.o10omapdss-$(CONFIG_FB_OMAP2_DSS_DPI) += dpi.o
11omapdss-$(CONFIG_FB_OMAP2_DSS_RFBI) += rfbi.o
12omapdss-$(CONFIG_FB_OMAP2_DSS_VENC) += venc.o11omapdss-$(CONFIG_FB_OMAP2_DSS_VENC) += venc.o
13omapdss-$(CONFIG_FB_OMAP2_DSS_SDI) += sdi.o12omapdss-$(CONFIG_FB_OMAP2_DSS_SDI) += sdi.o
14omapdss-$(CONFIG_FB_OMAP2_DSS_DSI) += dsi.o13omapdss-$(CONFIG_FB_OMAP2_DSS_DSI) += dsi.o
drivers/video/fbdev/omap2/omapfb/dss/core.c+0−6
@@ -207,9 +207,6 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { · 206 unmodified lines
207#ifdef CONFIG_FB_OMAP2_DSS_SDI207#ifdef CONFIG_FB_OMAP2_DSS_SDI
208 sdi_init_platform_driver,208 sdi_init_platform_driver,
209#endif209#endif
210#ifdef CONFIG_FB_OMAP2_DSS_RFBI
211 rfbi_init_platform_driver,
212#endif
213#ifdef CONFIG_FB_OMAP2_DSS_VENC210#ifdef CONFIG_FB_OMAP2_DSS_VENC
214 venc_init_platform_driver,211 venc_init_platform_driver,
215#endif212#endif
@@ -231,9 +228,6 @@ static void (*dss_output_drv_unreg_funcs[])(void) = { · 15 unmodified lines
231#ifdef CONFIG_FB_OMAP2_DSS_VENC228#ifdef CONFIG_FB_OMAP2_DSS_VENC
232 venc_uninit_platform_driver,229 venc_uninit_platform_driver,
233#endif230#endif
234#ifdef CONFIG_FB_OMAP2_DSS_RFBI
235 rfbi_uninit_platform_driver,
236#endif
237#ifdef CONFIG_FB_OMAP2_DSS_SDI231#ifdef CONFIG_FB_OMAP2_DSS_SDI
238 sdi_uninit_platform_driver,232 sdi_uninit_platform_driver,
239#endif233#endif
drivers/video/fbdev/omap2/omapfb/dss/dss.h+0−4
@@ -461,10 +461,6 @@ void hdmi4_uninit_platform_driver(void); · 460 unmodified lines
461int hdmi5_init_platform_driver(void) __init;461int hdmi5_init_platform_driver(void) __init;
462void hdmi5_uninit_platform_driver(void);462void hdmi5_uninit_platform_driver(void);
463 463
464/* RFBI */
465int rfbi_init_platform_driver(void) __init;
466void rfbi_uninit_platform_driver(void);
467
468 464
469#ifdef CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS465#ifdef CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS
470static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)466static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)
drivers/video/fbdev/omap2/omapfb/dss/rfbi.c+0−1067
@@ -1,1067 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * linux/drivers/video/omap2/dss/rfbi.c
4 *
5 * Copyright (C) 2009 Nokia Corporation
6 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
7 *
8 * Some code and ideas taken from drivers/video/omap/ driver
9 * by Imre Deak.
10 */
11
12#define DSS_SUBSYS_NAME "RFBI"
13
14#include <linux/kernel.h>
15#include <linux/dma-mapping.h>
16#include <linux/export.h>
17#include <linux/vmalloc.h>
18#include <linux/clk.h>
19#include <linux/io.h>
20#include <linux/delay.h>
21#include <linux/kfifo.h>
22#include <linux/ktime.h>
23#include <linux/hrtimer.h>
24#include <linux/seq_file.h>
25#include <linux/semaphore.h>
26#include <linux/platform_device.h>
27#include <linux/pm_runtime.h>
28#include <linux/component.h>
29
30#include <video/omapfb_dss.h>
31#include "dss.h"
32
33struct rfbi_reg { u16 idx; };
34
35#define RFBI_REG(idx) ((const struct rfbi_reg) { idx })
36
37#define RFBI_REVISION RFBI_REG(0x0000)
38#define RFBI_SYSCONFIG RFBI_REG(0x0010)
39#define RFBI_SYSSTATUS RFBI_REG(0x0014)
40#define RFBI_CONTROL RFBI_REG(0x0040)
41#define RFBI_PIXEL_CNT RFBI_REG(0x0044)
42#define RFBI_LINE_NUMBER RFBI_REG(0x0048)
43#define RFBI_CMD RFBI_REG(0x004c)
44#define RFBI_PARAM RFBI_REG(0x0050)
45#define RFBI_DATA RFBI_REG(0x0054)
46#define RFBI_READ RFBI_REG(0x0058)
47#define RFBI_STATUS RFBI_REG(0x005c)
48
49#define RFBI_CONFIG(n) RFBI_REG(0x0060 + (n)*0x18)
50#define RFBI_ONOFF_TIME(n) RFBI_REG(0x0064 + (n)*0x18)
51#define RFBI_CYCLE_TIME(n) RFBI_REG(0x0068 + (n)*0x18)
52#define RFBI_DATA_CYCLE1(n) RFBI_REG(0x006c + (n)*0x18)
53#define RFBI_DATA_CYCLE2(n) RFBI_REG(0x0070 + (n)*0x18)
54#define RFBI_DATA_CYCLE3(n) RFBI_REG(0x0074 + (n)*0x18)
55
56#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090)
57#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094)
58
59#define REG_FLD_MOD(idx, val, start, end) \
60 rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
61
62enum omap_rfbi_cycleformat {
63 OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0,
64 OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1,
65 OMAP_DSS_RFBI_CYCLEFORMAT_3_1 = 2,
66 OMAP_DSS_RFBI_CYCLEFORMAT_3_2 = 3,
67};
68
69enum omap_rfbi_datatype {
70 OMAP_DSS_RFBI_DATATYPE_12 = 0,
71 OMAP_DSS_RFBI_DATATYPE_16 = 1,
72 OMAP_DSS_RFBI_DATATYPE_18 = 2,
73 OMAP_DSS_RFBI_DATATYPE_24 = 3,
74};
75
76enum omap_rfbi_parallelmode {
77 OMAP_DSS_RFBI_PARALLELMODE_8 = 0,
78 OMAP_DSS_RFBI_PARALLELMODE_9 = 1,
79 OMAP_DSS_RFBI_PARALLELMODE_12 = 2,
80 OMAP_DSS_RFBI_PARALLELMODE_16 = 3,
81};
82
83static int rfbi_convert_timings(struct rfbi_timings *t);
84static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
85
86static struct {
87 struct platform_device *pdev;
88 void __iomem *base;
89
90 unsigned long l4_khz;
91
92 enum omap_rfbi_datatype datatype;
93 enum omap_rfbi_parallelmode parallelmode;
94
95 enum omap_rfbi_te_mode te_mode;
96 int te_enabled;
97
98 void (*framedone_callback)(void *data);
99 void *framedone_callback_data;
100
101 struct omap_dss_device *dssdev[2];
102
103 struct semaphore bus_lock;
104
105 struct omap_video_timings timings;
106 int pixel_size;
107 int data_lines;
108 struct rfbi_timings intf_timings;
109
110 struct omap_dss_device output;
111} rfbi;
112
113static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
114{
115 __raw_writel(val, rfbi.base + idx.idx);
116}
117
118static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
119{
120 return __raw_readl(rfbi.base + idx.idx);
121}
122
123static int rfbi_runtime_get(void)
124{
125 int r;
126
127 DSSDBG("rfbi_runtime_get\n");
128
129 r = pm_runtime_get_sync(&rfbi.pdev->dev);
130 WARN_ON(r < 0);
131 return r < 0 ? r : 0;
132}
133
134static void rfbi_runtime_put(void)
135{
136 int r;
137
138 DSSDBG("rfbi_runtime_put\n");
139
140 r = pm_runtime_put_sync(&rfbi.pdev->dev);
141 WARN_ON(r < 0 && r != -ENOSYS);
142}
143
144static void rfbi_bus_lock(void)
145{
146 down(&rfbi.bus_lock);
147}
148
149static void rfbi_bus_unlock(void)
150{
151 up(&rfbi.bus_lock);
152}
153
154static void rfbi_write_command(const void *buf, u32 len)
155{
156 switch (rfbi.parallelmode) {
157 case OMAP_DSS_RFBI_PARALLELMODE_8:
158 {
159 const u8 *b = buf;
160 for (; len; len--)
161 rfbi_write_reg(RFBI_CMD, *b++);
162 break;
163 }
164
165 case OMAP_DSS_RFBI_PARALLELMODE_16:
166 {
167 const u16 *w = buf;
168 BUG_ON(len & 1);
169 for (; len; len -= 2)
170 rfbi_write_reg(RFBI_CMD, *w++);
171 break;
172 }
173
174 case OMAP_DSS_RFBI_PARALLELMODE_9:
175 case OMAP_DSS_RFBI_PARALLELMODE_12:
176 default:
177 BUG();
178 }
179}
180
181static void rfbi_read_data(void *buf, u32 len)
182{
183 switch (rfbi.parallelmode) {
184 case OMAP_DSS_RFBI_PARALLELMODE_8:
185 {
186 u8 *b = buf;
187 for (; len; len--) {
188 rfbi_write_reg(RFBI_READ, 0);
189 *b++ = rfbi_read_reg(RFBI_READ);
190 }
191 break;
192 }
193
194 case OMAP_DSS_RFBI_PARALLELMODE_16:
195 {
196 u16 *w = buf;
197 BUG_ON(len & ~1);
198 for (; len; len -= 2) {
199 rfbi_write_reg(RFBI_READ, 0);
200 *w++ = rfbi_read_reg(RFBI_READ);
201 }
202 break;
203 }
204
205 case OMAP_DSS_RFBI_PARALLELMODE_9:
206 case OMAP_DSS_RFBI_PARALLELMODE_12:
207 default:
208 BUG();
209 }
210}
211
212static void rfbi_write_data(const void *buf, u32 len)
213{
214 switch (rfbi.parallelmode) {
215 case OMAP_DSS_RFBI_PARALLELMODE_8:
216 {
217 const u8 *b = buf;
218 for (; len; len--)
219 rfbi_write_reg(RFBI_PARAM, *b++);
220 break;
221 }
222
223 case OMAP_DSS_RFBI_PARALLELMODE_16:
224 {
225 const u16 *w = buf;
226 BUG_ON(len & 1);
227 for (; len; len -= 2)
228 rfbi_write_reg(RFBI_PARAM, *w++);
229 break;
230 }
231
232 case OMAP_DSS_RFBI_PARALLELMODE_9:
233 case OMAP_DSS_RFBI_PARALLELMODE_12:
234 default:
235 BUG();
236
237 }
238}
239
240static void rfbi_write_pixels(const void __iomem *buf, int scr_width,
241 u16 x, u16 y,
242 u16 w, u16 h)
243{
244 int start_offset = scr_width * y + x;
245 int horiz_offset = scr_width - w;
246 int i;
247
248 if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
249 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
250 const u16 __iomem *pd = buf;
251 pd += start_offset;
252
253 for (; h; --h) {
254 for (i = 0; i < w; ++i) {
255 const u8 __iomem *b = (const u8 __iomem *)pd;
256 rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
257 rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
258 ++pd;
259 }
260 pd += horiz_offset;
261 }
262 } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_24 &&
263 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
264 const u32 __iomem *pd = buf;
265 pd += start_offset;
266
267 for (; h; --h) {
268 for (i = 0; i < w; ++i) {
269 const u8 __iomem *b = (const u8 __iomem *)pd;
270 rfbi_write_reg(RFBI_PARAM, __raw_readb(b+2));
271 rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
272 rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
273 ++pd;
274 }
275 pd += horiz_offset;
276 }
277 } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
278 rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_16) {
279 const u16 __iomem *pd = buf;
280 pd += start_offset;
281
282 for (; h; --h) {
283 for (i = 0; i < w; ++i) {
284 rfbi_write_reg(RFBI_PARAM, __raw_readw(pd));
285 ++pd;
286 }
287 pd += horiz_offset;
288 }
289 } else {
290 BUG();
291 }
292}
293
294static int rfbi_transfer_area(struct omap_dss_device *dssdev,
295 void (*callback)(void *data), void *data)
296{
297 u32 l;
298 int r;
299 struct omap_overlay_manager *mgr = rfbi.output.manager;
300 u16 width = rfbi.timings.x_res;
301 u16 height = rfbi.timings.y_res;
302
303 /*BUG_ON(callback == 0);*/
304 BUG_ON(rfbi.framedone_callback != NULL);
305
306 DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
307
308 dss_mgr_set_timings(mgr, &rfbi.timings);
309
310 r = dss_mgr_enable(mgr);
311 if (r)
312 return r;
313
314 rfbi.framedone_callback = callback;
315 rfbi.framedone_callback_data = data;
316
317 rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
318
319 l = rfbi_read_reg(RFBI_CONTROL);
320 l = FLD_MOD(l, 1, 0, 0); /* enable */
321 if (!rfbi.te_enabled)
322 l = FLD_MOD(l, 1, 4, 4); /* ITE */
323
324 rfbi_write_reg(RFBI_CONTROL, l);
325
326 return 0;
327}
328
329static void framedone_callback(void *data)
330{
331 void (*callback)(void *data);
332
333 DSSDBG("FRAMEDONE\n");
334
335 REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
336
337 callback = rfbi.framedone_callback;
338 rfbi.framedone_callback = NULL;
339
340 if (callback != NULL)
341 callback(rfbi.framedone_callback_data);
342}
343
344#if 1 /* VERBOSE */
345static void rfbi_print_timings(void)
346{
347 u32 l;
348 u32 time;
349
350 l = rfbi_read_reg(RFBI_CONFIG(0));
351 time = 1000000000 / rfbi.l4_khz;
352 if (l & (1 << 4))
353 time *= 2;
354
355 DSSDBG("Tick time %u ps\n", time);
356 l = rfbi_read_reg(RFBI_ONOFF_TIME(0));
357 DSSDBG("CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
358 "REONTIME %d, REOFFTIME %d\n",
359 l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
360 (l >> 20) & 0x0f, (l >> 24) & 0x3f);
361
362 l = rfbi_read_reg(RFBI_CYCLE_TIME(0));
363 DSSDBG("WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
364 "ACCESSTIME %d\n",
365 (l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f,
366 (l >> 22) & 0x3f);
367}
368#else
369static void rfbi_print_timings(void) {}
370#endif
371
372
373
374
375static u32 extif_clk_period;
376
377static inline unsigned long round_to_extif_ticks(unsigned long ps, int div)
378{
379 int bus_tick = extif_clk_period * div;
380 return (ps + bus_tick - 1) / bus_tick * bus_tick;
381}
382
383static int calc_reg_timing(struct rfbi_timings *t, int div)
384{
385 t->clk_div = div;
386
387 t->cs_on_time = round_to_extif_ticks(t->cs_on_time, div);
388
389 t->we_on_time = round_to_extif_ticks(t->we_on_time, div);
390 t->we_off_time = round_to_extif_ticks(t->we_off_time, div);
391 t->we_cycle_time = round_to_extif_ticks(t->we_cycle_time, div);
392
393 t->re_on_time = round_to_extif_ticks(t->re_on_time, div);
394 t->re_off_time = round_to_extif_ticks(t->re_off_time, div);
395 t->re_cycle_time = round_to_extif_ticks(t->re_cycle_time, div);
396
397 t->access_time = round_to_extif_ticks(t->access_time, div);
398 t->cs_off_time = round_to_extif_ticks(t->cs_off_time, div);
399 t->cs_pulse_width = round_to_extif_ticks(t->cs_pulse_width, div);
400
401 DSSDBG("[reg]cson %d csoff %d reon %d reoff %d\n",
402 t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
403 DSSDBG("[reg]weon %d weoff %d recyc %d wecyc %d\n",
404 t->we_on_time, t->we_off_time, t->re_cycle_time,
405 t->we_cycle_time);
406 DSSDBG("[reg]rdaccess %d cspulse %d\n",
407 t->access_time, t->cs_pulse_width);
408
409 return rfbi_convert_timings(t);
410}
411
412static int calc_extif_timings(struct rfbi_timings *t)
413{
414 u32 max_clk_div;
415 int div;
416
417 rfbi_get_clk_info(&extif_clk_period, &max_clk_div);
418 for (div = 1; div <= max_clk_div; div++) {
419 if (calc_reg_timing(t, div) == 0)
420 break;
421 }
422
423 if (div <= max_clk_div)
424 return 0;
425
426 DSSERR("can't setup timings\n");
427 return -1;
428}
429
430
431static void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
432{
433 int r;
434
435 if (!t->converted) {
436 r = calc_extif_timings(t);
437 if (r < 0)
438 DSSERR("Failed to calc timings\n");
439 }
440
441 BUG_ON(!t->converted);
442
443 rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]);
444 rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]);
445
446 /* TIMEGRANULARITY */
447 REG_FLD_MOD(RFBI_CONFIG(rfbi_module),
448 (t->tim[2] ? 1 : 0), 4, 4);
449
450 rfbi_print_timings();
451}
452
453static int ps_to_rfbi_ticks(int time, int div)
454{
455 unsigned long tick_ps;
456 int ret;
457
458 /* Calculate in picosecs to yield more exact results */
459 tick_ps = 1000000000 / (rfbi.l4_khz) * div;
460
461 ret = (time + tick_ps - 1) / tick_ps;
462
463 return ret;
464}
465
466static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
467{
468 *clk_period = 1000000000 / rfbi.l4_khz;
469 *max_clk_div = 2;
470}
471
472static int rfbi_convert_timings(struct rfbi_timings *t)
473{
474 u32 l;
475 int reon, reoff, weon, weoff, cson, csoff, cs_pulse;
476 int actim, recyc, wecyc;
477 int div = t->clk_div;
478
479 if (div <= 0 || div > 2)
480 return -1;
481
482 /* Make sure that after conversion it still holds that:
483 * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
484 * csoff > cson, csoff >= max(weoff, reoff), actim > reon
485 */
486 weon = ps_to_rfbi_ticks(t->we_on_time, div);
487 weoff = ps_to_rfbi_ticks(t->we_off_time, div);
488 if (weoff <= weon)
489 weoff = weon + 1;
490 if (weon > 0x0f)
491 return -1;
492 if (weoff > 0x3f)
493 return -1;
494
495 reon = ps_to_rfbi_ticks(t->re_on_time, div);
496 reoff = ps_to_rfbi_ticks(t->re_off_time, div);
497 if (reoff <= reon)
498 reoff = reon + 1;
499 if (reon > 0x0f)
500 return -1;
501 if (reoff > 0x3f)
502 return -1;
503
504 cson = ps_to_rfbi_ticks(t->cs_on_time, div);
505 csoff = ps_to_rfbi_ticks(t->cs_off_time, div);
506 if (csoff <= cson)
507 csoff = cson + 1;
508 if (csoff < max(weoff, reoff))
509 csoff = max(weoff, reoff);
510 if (cson > 0x0f)
511 return -1;
512 if (csoff > 0x3f)
513 return -1;
514
515 l = cson;
516 l |= csoff << 4;
517 l |= weon << 10;
518 l |= weoff << 14;
519 l |= reon << 20;
520 l |= reoff << 24;
521
522 t->tim[0] = l;
523
524 actim = ps_to_rfbi_ticks(t->access_time, div);
525 if (actim <= reon)
526 actim = reon + 1;
527 if (actim > 0x3f)
528 return -1;
529
530 wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div);
531 if (wecyc < weoff)
532 wecyc = weoff;
533 if (wecyc > 0x3f)
534 return -1;
535
536 recyc = ps_to_rfbi_ticks(t->re_cycle_time, div);
537 if (recyc < reoff)
538 recyc = reoff;
539 if (recyc > 0x3f)
540 return -1;
541
542 cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div);
543 if (cs_pulse > 0x3f)
544 return -1;
545
546 l = wecyc;
547 l |= recyc << 6;
548 l |= cs_pulse << 12;
549 l |= actim << 22;
550
551 t->tim[1] = l;
552
553 t->tim[2] = div - 1;
554
555 t->converted = 1;
556
557 return 0;
558}
559
560/* xxx FIX module selection missing */
561static int rfbi_setup_te(enum omap_rfbi_te_mode mode,
562 unsigned hs_pulse_time, unsigned vs_pulse_time,
563 int hs_pol_inv, int vs_pol_inv, int extif_div)
564{
565 int hs, vs;
566 int min;
567 u32 l;
568
569 hs = ps_to_rfbi_ticks(hs_pulse_time, 1);
570 vs = ps_to_rfbi_ticks(vs_pulse_time, 1);
571 if (hs < 2)
572 return -EDOM;
573 if (mode == OMAP_DSS_RFBI_TE_MODE_2)
574 min = 2;
575 else /* OMAP_DSS_RFBI_TE_MODE_1 */
576 min = 4;
577 if (vs < min)
578 return -EDOM;
579 if (vs == hs)
580 return -EINVAL;
581 rfbi.te_mode = mode;
582 DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
583 mode, hs, vs, hs_pol_inv, vs_pol_inv);
584
585 rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
586 rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
587
588 l = rfbi_read_reg(RFBI_CONFIG(0));
589 if (hs_pol_inv)
590 l &= ~(1 << 21);
591 else
592 l |= 1 << 21;
593 if (vs_pol_inv)
594 l &= ~(1 << 20);
595 else
596 l |= 1 << 20;
597
598 return 0;
599}
600
601/* xxx FIX module selection missing */
602static int rfbi_enable_te(bool enable, unsigned line)
603{
604 u32 l;
605
606 DSSDBG("te %d line %d mode %d\n", enable, line, rfbi.te_mode);
607 if (line > (1 << 11) - 1)
608 return -EINVAL;
609
610 l = rfbi_read_reg(RFBI_CONFIG(0));
611 l &= ~(0x3 << 2);
612 if (enable) {
613 rfbi.te_enabled = 1;
614 l |= rfbi.te_mode << 2;
615 } else
616 rfbi.te_enabled = 0;
617 rfbi_write_reg(RFBI_CONFIG(0), l);
618 rfbi_write_reg(RFBI_LINE_NUMBER, line);
619
620 return 0;
621}
622
623static int rfbi_configure_bus(int rfbi_module, int bpp, int lines)
624{
625 u32 l;
626 int cycle1 = 0, cycle2 = 0, cycle3 = 0;
627 enum omap_rfbi_cycleformat cycleformat;
628 enum omap_rfbi_datatype datatype;
629 enum omap_rfbi_parallelmode parallelmode;
630
631 switch (bpp) {
632 case 12:
633 datatype = OMAP_DSS_RFBI_DATATYPE_12;
634 break;
635 case 16:
636 datatype = OMAP_DSS_RFBI_DATATYPE_16;
637 break;
638 case 18:
639 datatype = OMAP_DSS_RFBI_DATATYPE_18;
640 break;
641 case 24:
642 datatype = OMAP_DSS_RFBI_DATATYPE_24;
643 break;
644 default:
645 BUG();
646 return 1;
647 }
648 rfbi.datatype = datatype;
649
650 switch (lines) {
651 case 8:
652 parallelmode = OMAP_DSS_RFBI_PARALLELMODE_8;
653 break;
654 case 9:
655 parallelmode = OMAP_DSS_RFBI_PARALLELMODE_9;
656 break;
657 case 12:
658 parallelmode = OMAP_DSS_RFBI_PARALLELMODE_12;
659 break;
660 case 16:
661 parallelmode = OMAP_DSS_RFBI_PARALLELMODE_16;
662 break;
663 default:
664 BUG();
665 return 1;
666 }
667 rfbi.parallelmode = parallelmode;
668
669 if ((bpp % lines) == 0) {
670 switch (bpp / lines) {
671 case 1:
672 cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_1_1;
673 break;
674 case 2:
675 cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_2_1;
676 break;
677 case 3:
678 cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_1;
679 break;
680 default:
681 BUG();
682 return 1;
683 }
684 } else if ((2 * bpp % lines) == 0) {
685 if ((2 * bpp / lines) == 3)
686 cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_2;
687 else {
688 BUG();
689 return 1;
690 }
691 } else {
692 BUG();
693 return 1;
694 }
695
696 switch (cycleformat) {
697 case OMAP_DSS_RFBI_CYCLEFORMAT_1_1:
698 cycle1 = lines;
699 break;
700
701 case OMAP_DSS_RFBI_CYCLEFORMAT_2_1:
702 cycle1 = lines;
703 cycle2 = lines;
704 break;
705
706 case OMAP_DSS_RFBI_CYCLEFORMAT_3_1:
707 cycle1 = lines;
708 cycle2 = lines;
709 cycle3 = lines;
710 break;
711
712 case OMAP_DSS_RFBI_CYCLEFORMAT_3_2:
713 cycle1 = lines;
714 cycle2 = (lines / 2) | ((lines / 2) << 16);
715 cycle3 = (lines << 16);
716 break;
717 }
718
719 REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */
720
721 l = 0;
722 l |= FLD_VAL(parallelmode, 1, 0);
723 l |= FLD_VAL(0, 3, 2); /* TRIGGERMODE: ITE */
724 l |= FLD_VAL(0, 4, 4); /* TIMEGRANULARITY */
725 l |= FLD_VAL(datatype, 6, 5);
726 /* l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */
727 l |= FLD_VAL(0, 8, 7); /* L4FORMAT, 1pix/L4 */
728 l |= FLD_VAL(cycleformat, 10, 9);
729 l |= FLD_VAL(0, 12, 11); /* UNUSEDBITS */
730 l |= FLD_VAL(0, 16, 16); /* A0POLARITY */
731 l |= FLD_VAL(0, 17, 17); /* REPOLARITY */
732 l |= FLD_VAL(0, 18, 18); /* WEPOLARITY */
733 l |= FLD_VAL(0, 19, 19); /* CSPOLARITY */
734 l |= FLD_VAL(1, 20, 20); /* TE_VSYNC_POLARITY */
735 l |= FLD_VAL(1, 21, 21); /* HSYNCPOLARITY */
736 rfbi_write_reg(RFBI_CONFIG(rfbi_module), l);
737
738 rfbi_write_reg(RFBI_DATA_CYCLE1(rfbi_module), cycle1);
739 rfbi_write_reg(RFBI_DATA_CYCLE2(rfbi_module), cycle2);
740 rfbi_write_reg(RFBI_DATA_CYCLE3(rfbi_module), cycle3);
741
742
743 l = rfbi_read_reg(RFBI_CONTROL);
744 l = FLD_MOD(l, rfbi_module+1, 3, 2); /* Select CSx */
745 l = FLD_MOD(l, 0, 1, 1); /* clear bypass */
746 rfbi_write_reg(RFBI_CONTROL, l);
747
748
749 DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n",
750 bpp, lines, cycle1, cycle2, cycle3);
751
752 return 0;
753}
754
755static int rfbi_configure(struct omap_dss_device *dssdev)
756{
757 return rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size,
758 rfbi.data_lines);
759}
760
761static int rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
762 void *data)
763{
764 return rfbi_transfer_area(dssdev, callback, data);
765}
766
767static void rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
768{
769 rfbi.timings.x_res = w;
770 rfbi.timings.y_res = h;
771}
772
773static void rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size)
774{
775 rfbi.pixel_size = pixel_size;
776}
777
778static void rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
779{
780 rfbi.data_lines = data_lines;
781}
782
783static void rfbi_set_interface_timings(struct omap_dss_device *dssdev,
784 struct rfbi_timings *timings)
785{
786 rfbi.intf_timings = *timings;
787}
788
789static void rfbi_dump_regs(struct seq_file *s)
790{
791#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
792
793 if (rfbi_runtime_get())
794 return;
795
796 DUMPREG(RFBI_REVISION);
797 DUMPREG(RFBI_SYSCONFIG);
798 DUMPREG(RFBI_SYSSTATUS);
799 DUMPREG(RFBI_CONTROL);
800 DUMPREG(RFBI_PIXEL_CNT);
801 DUMPREG(RFBI_LINE_NUMBER);
802 DUMPREG(RFBI_CMD);
803 DUMPREG(RFBI_PARAM);
804 DUMPREG(RFBI_DATA);
805 DUMPREG(RFBI_READ);
806 DUMPREG(RFBI_STATUS);
807
808 DUMPREG(RFBI_CONFIG(0));
809 DUMPREG(RFBI_ONOFF_TIME(0));
810 DUMPREG(RFBI_CYCLE_TIME(0));
811 DUMPREG(RFBI_DATA_CYCLE1(0));
812 DUMPREG(RFBI_DATA_CYCLE2(0));
813 DUMPREG(RFBI_DATA_CYCLE3(0));
814
815 DUMPREG(RFBI_CONFIG(1));
816 DUMPREG(RFBI_ONOFF_TIME(1));
817 DUMPREG(RFBI_CYCLE_TIME(1));
818 DUMPREG(RFBI_DATA_CYCLE1(1));
819 DUMPREG(RFBI_DATA_CYCLE2(1));
820 DUMPREG(RFBI_DATA_CYCLE3(1));
821
822 DUMPREG(RFBI_VSYNC_WIDTH);
823 DUMPREG(RFBI_HSYNC_WIDTH);
824
825 rfbi_runtime_put();
826#undef DUMPREG
827}
828
829static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
830{
831 struct omap_overlay_manager *mgr = rfbi.output.manager;
832 struct dss_lcd_mgr_config mgr_config;
833
834 mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
835
836 mgr_config.stallmode = true;
837 /* Do we need fifohandcheck for RFBI? */
838 mgr_config.fifohandcheck = false;
839
840 mgr_config.video_port_width = rfbi.pixel_size;
841 mgr_config.lcden_sig_polarity = 0;
842
843 dss_mgr_set_lcd_config(mgr, &mgr_config);
844
845 /*
846 * Set rfbi.timings with default values, the x_res and y_res fields
847 * are expected to be already configured by the panel driver via
848 * omapdss_rfbi_set_size()
849 */
850 rfbi.timings.hsw = 1;
851 rfbi.timings.hfp = 1;
852 rfbi.timings.hbp = 1;
853 rfbi.timings.vsw = 1;
854 rfbi.timings.vfp = 0;
855 rfbi.timings.vbp = 0;
856
857 rfbi.timings.interlace = false;
858 rfbi.timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
859 rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
860 rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
861 rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
862 rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_FALLING_EDGE;
863
864 dss_mgr_set_timings(mgr, &rfbi.timings);
865}
866
867static int rfbi_display_enable(struct omap_dss_device *dssdev)
868{
869 struct omap_dss_device *out = &rfbi.output;
870 int r;
871
872 if (out->manager == NULL) {
873 DSSERR("failed to enable display: no output/manager\n");
874 return -ENODEV;
875 }
876
877 r = rfbi_runtime_get();
878 if (r)
879 return r;
880
881 r = dss_mgr_register_framedone_handler(out->manager,
882 framedone_callback, NULL);
883 if (r) {
884 DSSERR("can't get FRAMEDONE irq\n");
885 goto err1;
886 }
887
888 rfbi_config_lcd_manager(dssdev);
889
890 rfbi_configure_bus(dssdev->phy.rfbi.channel, rfbi.pixel_size,
891 rfbi.data_lines);
892
893 rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings);
894
895 return 0;
896err1:
897 rfbi_runtime_put();
898 return r;
899}
900
901static void rfbi_display_disable(struct omap_dss_device *dssdev)
902{
903 struct omap_dss_device *out = &rfbi.output;
904
905 dss_mgr_unregister_framedone_handler(out->manager,
906 framedone_callback, NULL);
907
908 rfbi_runtime_put();
909}
910
911static int rfbi_init_display(struct omap_dss_device *dssdev)
912{
913 rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
914 return 0;
915}
916
917static void rfbi_init_output(struct platform_device *pdev)
918{
919 struct omap_dss_device *out = &rfbi.output;
920
921 out->dev = &pdev->dev;
922 out->id = OMAP_DSS_OUTPUT_DBI;
923 out->output_type = OMAP_DISPLAY_TYPE_DBI;
924 out->name = "rfbi.0";
925 out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
926 out->owner = THIS_MODULE;
927
928 omapdss_register_output(out);
929}
930
931static void rfbi_uninit_output(struct platform_device *pdev)
932{
933 struct omap_dss_device *out = &rfbi.output;
934
935 omapdss_unregister_output(out);
936}
937
938/* RFBI HW IP initialisation */
939static int rfbi_bind(struct device *dev, struct device *master, void *data)
940{
941 struct platform_device *pdev = to_platform_device(dev);
942 u32 rev;
943 struct resource *rfbi_mem;
944 struct clk *clk;
945 int r;
946
947 rfbi.pdev = pdev;
948
949 sema_init(&rfbi.bus_lock, 1);
950
951 rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
952 if (!rfbi_mem) {
953 DSSERR("can't get IORESOURCE_MEM RFBI\n");
954 return -EINVAL;
955 }
956
957 rfbi.base = devm_ioremap(&pdev->dev, rfbi_mem->start,
958 resource_size(rfbi_mem));
959 if (!rfbi.base) {
960 DSSERR("can't ioremap RFBI\n");
961 return -ENOMEM;
962 }
963
964 clk = clk_get(&pdev->dev, "ick");
965 if (IS_ERR(clk)) {
966 DSSERR("can't get ick\n");
967 return PTR_ERR(clk);
968 }
969
970 rfbi.l4_khz = clk_get_rate(clk) / 1000;
971
972 clk_put(clk);
973
974 pm_runtime_enable(&pdev->dev);
975
976 r = rfbi_runtime_get();
977 if (r)
978 goto err_runtime_get;
979
980 msleep(10);
981
982 rev = rfbi_read_reg(RFBI_REVISION);
983 dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
984 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
985
986 rfbi_runtime_put();
987
988 dss_debugfs_create_file("rfbi", rfbi_dump_regs);
989
990 rfbi_init_output(pdev);
991
992 return 0;
993
994err_runtime_get:
995 pm_runtime_disable(&pdev->dev);
996 return r;
997}
998
999static void rfbi_unbind(struct device *dev, struct device *master, void *data)
1000{
1001 struct platform_device *pdev = to_platform_device(dev);
1002
1003 rfbi_uninit_output(pdev);
1004
1005 pm_runtime_disable(&pdev->dev);
1006
1007 return 0;
1008}
1009
1010static const struct component_ops rfbi_component_ops = {
1011 .bind = rfbi_bind,
1012 .unbind = rfbi_unbind,
1013};
1014
1015static int rfbi_probe(struct platform_device *pdev)
1016{
1017 return component_add(&pdev->dev, &rfbi_component_ops);
1018}
1019
1020static int rfbi_remove(struct platform_device *pdev)
1021{
1022 component_del(&pdev->dev, &rfbi_component_ops);
1023 return 0;
1024}
1025
1026static int rfbi_runtime_suspend(struct device *dev)
1027{
1028 dispc_runtime_put();
1029
1030 return 0;
1031}
1032
1033static int rfbi_runtime_resume(struct device *dev)
1034{
1035 int r;
1036
1037 r = dispc_runtime_get();
1038 if (r < 0)
1039 return r;
1040
1041 return 0;
1042}
1043
1044static const struct dev_pm_ops rfbi_pm_ops = {
1045 .runtime_suspend = rfbi_runtime_suspend,
1046 .runtime_resume = rfbi_runtime_resume,
1047};
1048
1049static struct platform_driver omap_rfbihw_driver = {
1050 .probe = rfbi_probe,
1051 .remove = rfbi_remove,
1052 .driver = {
1053 .name = "omapdss_rfbi",
1054 .pm = &rfbi_pm_ops,
1055 .suppress_bind_attrs = true,
1056 },
1057};
1058
1059int __init rfbi_init_platform_driver(void)
1060{
1061 return platform_driver_register(&omap_rfbihw_driver);
1062}
1063
1064void rfbi_uninit_platform_driver(void)
1065{
1066 platform_driver_unregister(&omap_rfbihw_driver);
1067}
drivers/video/fbdev/omap2/omapfb/omapfb-main.c+1−5
@@ -1881,12 +1881,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) · 1880 unmodified lines
1881 1881
1882 fbi = framebuffer_alloc(sizeof(struct omapfb_info),1882 fbi = framebuffer_alloc(sizeof(struct omapfb_info),
1883 fbdev->dev);1883 fbdev->dev);
1884 1884 if (!fbi)
1885 if (fbi == NULL) {
1886 dev_err(fbdev->dev,
1887 "unable to allocate memory for plane info\n");
1888 return -ENOMEM;1885 return -ENOMEM;
1889 }
1890 1886
1891 clear_fb_info(fbi);1887 clear_fb_info(fbi);
1892 1888
drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c+7−14
@@ -49,8 +49,7 @@ static ssize_t store_rotate_type(struct device *dev, · 48 unmodified lines
49 if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB)49 if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB)
50 return -EINVAL;50 return -EINVAL;
51 51
52 if (!lock_fb_info(fbi))52 lock_fb_info(fbi);
53 return -ENODEV;
54 53
55 r = 0;54 r = 0;
56 if (rot_type == ofbi->rotation_type)55 if (rot_type == ofbi->rotation_type)
@@ -101,8 +100,7 @@ static ssize_t store_mirror(struct device *dev, · 44 unmodified lines
101 if (r)100 if (r)
102 return r;101 return r;
103 102
104 if (!lock_fb_info(fbi))103 lock_fb_info(fbi);
105 return -ENODEV;
106 104
107 ofbi->mirror = mirror;105 ofbi->mirror = mirror;
108 106
@@ -138,8 +136,7 @@ static ssize_t show_overlays(struct device *dev, · 29 unmodified lines
138 ssize_t l = 0;136 ssize_t l = 0;
139 int t;137 int t;
140 138
141 if (!lock_fb_info(fbi))139 lock_fb_info(fbi);
142 return -ENODEV;
143 omapfb_lock(fbdev);140 omapfb_lock(fbdev);
144 141
145 for (t = 0; t < ofbi->num_overlays; t++) {142 for (t = 0; t < ofbi->num_overlays; t++) {
@@ -197,8 +194,7 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, · 51 unmodified lines
197 if (buf[len - 1] == '\n')194 if (buf[len - 1] == '\n')
198 len = len - 1;195 len = len - 1;
199 196
200 if (!lock_fb_info(fbi))197 lock_fb_info(fbi);
201 return -ENODEV;
202 omapfb_lock(fbdev);198 omapfb_lock(fbdev);
203 199
204 if (len > 0) {200 if (len > 0) {
@@ -329,8 +325,7 @@ static ssize_t show_overlays_rotate(struct device *dev, · 124 unmodified lines
329 ssize_t l = 0;325 ssize_t l = 0;
330 int t;326 int t;
331 327
332 if (!lock_fb_info(fbi))328 lock_fb_info(fbi);
333 return -ENODEV;
334 329
335 for (t = 0; t < ofbi->num_overlays; t++) {330 for (t = 0; t < ofbi->num_overlays; t++) {
336 l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",331 l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
@@ -358,8 +353,7 @@ static ssize_t store_overlays_rotate(struct device *dev, · 21 unmodified lines
358 if (buf[len - 1] == '\n')353 if (buf[len - 1] == '\n')
359 len = len - 1;354 len = len - 1;
360 355
361 if (!lock_fb_info(fbi))356 lock_fb_info(fbi);
362 return -ENODEV;
363 357
364 if (len > 0) {358 if (len > 0) {
365 char *p = (char *)buf;359 char *p = (char *)buf;
@@ -442,8 +436,7 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr, · 76 unmodified lines
442 436
443 size = PAGE_ALIGN(size);437 size = PAGE_ALIGN(size);
444 438
445 if (!lock_fb_info(fbi))439 lock_fb_info(fbi);
446 return -ENODEV;
447 440
448 if (display && display->driver->sync)441 if (display && display->driver->sync)
449 display->driver->sync(display);442 display->driver->sync(display);
drivers/video/fbdev/platinumfb.c+2−3
@@ -538,10 +538,9 @@ static int platinumfb_probe(struct platform_device* odev) · 537 unmodified lines
538 dev_info(&odev->dev, "Found Apple Platinum video hardware\n");538 dev_info(&odev->dev, "Found Apple Platinum video hardware\n");
539 539
540 info = framebuffer_alloc(sizeof(*pinfo), &odev->dev);540 info = framebuffer_alloc(sizeof(*pinfo), &odev->dev);
541 if (info == NULL) {541 if (!info)
542 dev_err(&odev->dev, "Failed to allocate fbdev !\n");
543 return -ENOMEM;542 return -ENOMEM;
544 }543
545 pinfo = info->par;544 pinfo = info->par;
546 545
547 if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) ||546 if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) ||
drivers/video/fbdev/pmag-aa-fb.c+1−3
@@ -165,10 +165,8 @@ static int pmagaafb_probe(struct device *dev) · 164 unmodified lines
165 int err;165 int err;
166 166
167 info = framebuffer_alloc(sizeof(struct aafb_par), dev);167 info = framebuffer_alloc(sizeof(struct aafb_par), dev);
168 if (!info) {168 if (!info)
169 printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
170 return -ENOMEM;169 return -ENOMEM;
171 }
172 170
173 par = info->par;171 par = info->par;
174 dev_set_drvdata(dev, info);172 dev_set_drvdata(dev, info);
drivers/video/fbdev/pmag-ba-fb.c+1−3
@@ -150,10 +150,8 @@ static int pmagbafb_probe(struct device *dev) · 149 unmodified lines
150 int err;150 int err;
151 151
152 info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev);152 info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev);
153 if (!info) {153 if (!info)
154 printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
155 return -ENOMEM;154 return -ENOMEM;
156 }
157 155
158 par = info->par;156 par = info->par;
159 dev_set_drvdata(dev, info);157 dev_set_drvdata(dev, info);
drivers/video/fbdev/pmagb-b-fb.c+1−3
@@ -257,10 +257,8 @@ static int pmagbbfb_probe(struct device *dev) · 256 unmodified lines
257 int err;257 int err;
258 258
259 info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev);259 info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev);
260 if (!info) {260 if (!info)
261 printk(KERN_ERR "%s: Cannot allocate memory\n", dev_name(dev));
262 return -ENOMEM;261 return -ENOMEM;
263 }
264 262
265 par = info->par;263 par = info->par;
266 dev_set_drvdata(dev, info);264 dev_set_drvdata(dev, info);
drivers/video/fbdev/pvr2fb.c+87−101
@@ -140,7 +140,7 @@ static struct pvr2fb_par { · 139 unmodified lines
140 unsigned char is_doublescan; /* Are scanlines output twice? (doublescan) */140 unsigned char is_doublescan; /* Are scanlines output twice? (doublescan) */
141 unsigned char is_lowres; /* Is horizontal pixel-doubling enabled? */141 unsigned char is_lowres; /* Is horizontal pixel-doubling enabled? */
142 142
143 unsigned long mmio_base; /* MMIO base */143 void __iomem *mmio_base; /* MMIO base */
144 u32 palette[16];144 u32 palette[16];
145} *currentpar;145} *currentpar;
146 146
@@ -194,39 +194,6 @@ static unsigned int shdma = PVR2_CASCADE_CHAN; · 47 unmodified lines
194static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS;194static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS;
195#endif195#endif
196 196
197static int pvr2fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue,
198 unsigned int transp, struct fb_info *info);
199static int pvr2fb_blank(int blank, struct fb_info *info);
200static unsigned long get_line_length(int xres_virtual, int bpp);
201static void set_color_bitfields(struct fb_var_screeninfo *var);
202static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
203static int pvr2fb_set_par(struct fb_info *info);
204static void pvr2_update_display(struct fb_info *info);
205static void pvr2_init_display(struct fb_info *info);
206static void pvr2_do_blank(void);
207static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id);
208static int pvr2_init_cable(void);
209static int pvr2_get_param(const struct pvr2_params *p, const char *s,
210 int val, int size);
211#ifdef CONFIG_PVR2_DMA
212static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
213 size_t count, loff_t *ppos);
214#endif
215
216static struct fb_ops pvr2fb_ops = {
217 .owner = THIS_MODULE,
218 .fb_setcolreg = pvr2fb_setcolreg,
219 .fb_blank = pvr2fb_blank,
220 .fb_check_var = pvr2fb_check_var,
221 .fb_set_par = pvr2fb_set_par,
222#ifdef CONFIG_PVR2_DMA
223 .fb_write = pvr2fb_write,
224#endif
225 .fb_fillrect = cfb_fillrect,
226 .fb_copyarea = cfb_copyarea,
227 .fb_imageblit = cfb_imageblit,
228};
229
230static struct fb_videomode pvr2_modedb[] = {197static struct fb_videomode pvr2_modedb[] = {
231 /*198 /*
232 * Broadcast video modes (PAL and NTSC). I'm unfamiliar with199 * Broadcast video modes (PAL and NTSC). I'm unfamiliar with
@@ -354,6 +321,36 @@ static int pvr2fb_setcolreg(unsigned int regno, unsigned int red, · 121 unmodified lines
354 return 0;321 return 0;
355}322}
356 323
324/*
325 * Determine the cable type and initialize the cable output format. Don't do
326 * anything if the cable type has been overidden (via "cable:XX").
327 */
328
329#define PCTRA ((void __iomem *)0xff80002c)
330#define PDTRA ((void __iomem *)0xff800030)
331#define VOUTC ((void __iomem *)0xa0702c00)
332
333static int pvr2_init_cable(void)
334{
335 if (cable_type < 0) {
336 fb_writel((fb_readl(PCTRA) & 0xfff0ffff) | 0x000a0000,
337 PCTRA);
338 cable_type = (fb_readw(PDTRA) >> 8) & 3;
339 }
340
341 /* Now select the output format (either composite or other) */
342 /* XXX: Save the previous val first, as this reg is also AICA
343 related */
344 if (cable_type == CT_COMPOSITE)
345 fb_writel(3 << 8, VOUTC);
346 else if (cable_type == CT_RGB)
347 fb_writel(1 << 9, VOUTC);
348 else
349 fb_writel(0, VOUTC);
350
351 return cable_type;
352}
353
357static int pvr2fb_set_par(struct fb_info *info)354static int pvr2fb_set_par(struct fb_info *info)
358{355{
359 struct pvr2fb_par *par = (struct pvr2fb_par *)info->par;356 struct pvr2fb_par *par = (struct pvr2fb_par *)info->par;
@@ -623,7 +620,7 @@ static void pvr2_do_blank(void) · 263 unmodified lines
623 is_blanked = do_blank > 0 ? do_blank : 0;620 is_blanked = do_blank > 0 ? do_blank : 0;
624}621}
625 622
626static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id)623static irqreturn_t __maybe_unused pvr2fb_interrupt(int irq, void *dev_id)
627{624{
628 struct fb_info *info = dev_id;625 struct fb_info *info = dev_id;
629 626
@@ -642,36 +639,6 @@ static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id) · 12 unmodified lines
642 return IRQ_HANDLED;639 return IRQ_HANDLED;
643}640}
644 641
645/*
646 * Determine the cable type and initialize the cable output format. Don't do
647 * anything if the cable type has been overidden (via "cable:XX").
648 */
649
650#define PCTRA 0xff80002c
651#define PDTRA 0xff800030
652#define VOUTC 0xa0702c00
653
654static int pvr2_init_cable(void)
655{
656 if (cable_type < 0) {
657 fb_writel((fb_readl(PCTRA) & 0xfff0ffff) | 0x000a0000,
658 PCTRA);
659 cable_type = (fb_readw(PDTRA) >> 8) & 3;
660 }
661
662 /* Now select the output format (either composite or other) */
663 /* XXX: Save the previous val first, as this reg is also AICA
664 related */
665 if (cable_type == CT_COMPOSITE)
666 fb_writel(3 << 8, VOUTC);
667 else if (cable_type == CT_RGB)
668 fb_writel(1 << 9, VOUTC);
669 else
670 fb_writel(0, VOUTC);
671
672 return cable_type;
673}
674
675#ifdef CONFIG_PVR2_DMA642#ifdef CONFIG_PVR2_DMA
676static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,643static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
677 size_t count, loff_t *ppos)644 size_t count, loff_t *ppos)
@@ -742,6 +709,46 @@ out_unmap: · 64 unmodified lines
742}709}
743#endif /* CONFIG_PVR2_DMA */710#endif /* CONFIG_PVR2_DMA */
744 711
712static struct fb_ops pvr2fb_ops = {
713 .owner = THIS_MODULE,
714 .fb_setcolreg = pvr2fb_setcolreg,
715 .fb_blank = pvr2fb_blank,
716 .fb_check_var = pvr2fb_check_var,
717 .fb_set_par = pvr2fb_set_par,
718#ifdef CONFIG_PVR2_DMA
719 .fb_write = pvr2fb_write,
720#endif
721 .fb_fillrect = cfb_fillrect,
722 .fb_copyarea = cfb_copyarea,
723 .fb_imageblit = cfb_imageblit,
724};
725
726#ifndef MODULE
727static int pvr2_get_param_val(const struct pvr2_params *p, const char *s,
728 int size)
729{
730 int i;
731
732 for (i = 0; i < size; i++) {
733 if (!strncasecmp(p[i].name, s, strlen(s)))
734 return p[i].val;
735 }
736 return -1;
737}
738#endif
739
740static char *pvr2_get_param_name(const struct pvr2_params *p, int val,
741 int size)
742{
743 int i;
744
745 for (i = 0; i < size; i++) {
746 if (p[i].val == val)
747 return p[i].name;
748 }
749 return NULL;
750}
751
745/**752/**
746 * pvr2fb_common_init753 * pvr2fb_common_init
747 *754 *
@@ -760,7 +767,7 @@ out_unmap: · 12 unmodified lines
760 * in for flexibility anyways. Who knows, maybe someone has tv-out on a767 * in for flexibility anyways. Who knows, maybe someone has tv-out on a
761 * PCI-based version of these things ;-)768 * PCI-based version of these things ;-)
762 */769 */
763static int pvr2fb_common_init(void)770static int __maybe_unused pvr2fb_common_init(void)
764{771{
765 struct pvr2fb_par *par = currentpar;772 struct pvr2fb_par *par = currentpar;
766 unsigned long modememused, rev;773 unsigned long modememused, rev;
@@ -773,8 +780,8 @@ static int pvr2fb_common_init(void) · 6 unmodified lines
773 goto out_err;780 goto out_err;
774 }781 }
775 782
776 par->mmio_base = (unsigned long)ioremap_nocache(pvr2_fix.mmio_start,783 par->mmio_base = ioremap_nocache(pvr2_fix.mmio_start,
777 pvr2_fix.mmio_len);784 pvr2_fix.mmio_len);
778 if (!par->mmio_base) {785 if (!par->mmio_base) {
779 printk(KERN_ERR "pvr2fb: Failed to remap mmio space\n");786 printk(KERN_ERR "pvr2fb: Failed to remap mmio space\n");
780 goto out_err;787 goto out_err;
@@ -822,8 +829,8 @@ static int pvr2fb_common_init(void) · 41 unmodified lines
822 fb_info->var.xres, fb_info->var.yres,829 fb_info->var.xres, fb_info->var.yres,
823 fb_info->var.bits_per_pixel,830 fb_info->var.bits_per_pixel,
824 get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel),831 get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel),
825 (char *)pvr2_get_param(cables, NULL, cable_type, 3),832 pvr2_get_param_name(cables, cable_type, 3),
826 (char *)pvr2_get_param(outputs, NULL, video_output, 3));833 pvr2_get_param_name(outputs, video_output, 3));
827 834
828#ifdef CONFIG_SH_STORE_QUEUES835#ifdef CONFIG_SH_STORE_QUEUES
829 fb_notice(fb_info, "registering with SQ API\n");836 fb_notice(fb_info, "registering with SQ API\n");
@@ -841,7 +848,7 @@ out_err: · 11 unmodified lines
841 if (fb_info->screen_base)848 if (fb_info->screen_base)
842 iounmap(fb_info->screen_base);849 iounmap(fb_info->screen_base);
843 if (par->mmio_base)850 if (par->mmio_base)
844 iounmap((void *)par->mmio_base);851 iounmap(par->mmio_base);
845 852
846 return -ENXIO;853 return -ENXIO;
847}854}
@@ -901,15 +908,15 @@ static int __init pvr2fb_dc_init(void) · 53 unmodified lines
901 return pvr2fb_common_init();908 return pvr2fb_common_init();
902}909}
903 910
904static void __exit pvr2fb_dc_exit(void)911static void pvr2fb_dc_exit(void)
905{912{
906 if (fb_info->screen_base) {913 if (fb_info->screen_base) {
907 iounmap(fb_info->screen_base);914 iounmap(fb_info->screen_base);
908 fb_info->screen_base = NULL;915 fb_info->screen_base = NULL;
909 }916 }
910 if (currentpar->mmio_base) {917 if (currentpar->mmio_base) {
911 iounmap((void *)currentpar->mmio_base);918 iounmap(currentpar->mmio_base);
912 currentpar->mmio_base = 0;919 currentpar->mmio_base = NULL;
913 }920 }
914 921
915 free_irq(HW_EVENT_VSYNC, fb_info);922 free_irq(HW_EVENT_VSYNC, fb_info);
@@ -958,8 +965,8 @@ static void pvr2fb_pci_remove(struct pci_dev *pdev) · 42 unmodified lines
958 fb_info->screen_base = NULL;965 fb_info->screen_base = NULL;
959 }966 }
960 if (currentpar->mmio_base) {967 if (currentpar->mmio_base) {
961 iounmap((void *)currentpar->mmio_base);968 iounmap(currentpar->mmio_base);
962 currentpar->mmio_base = 0;969 currentpar->mmio_base = NULL;
963 }970 }
964 971
965 pci_release_regions(pdev);972 pci_release_regions(pdev);
@@ -985,29 +992,12 @@ static int __init pvr2fb_pci_init(void) · 19 unmodified lines
985 return pci_register_driver(&pvr2fb_pci_driver);992 return pci_register_driver(&pvr2fb_pci_driver);
986}993}
987 994
988static void __exit pvr2fb_pci_exit(void)995static void pvr2fb_pci_exit(void)
989{996{
990 pci_unregister_driver(&pvr2fb_pci_driver);997 pci_unregister_driver(&pvr2fb_pci_driver);
991}998}
992#endif /* CONFIG_PCI */999#endif /* CONFIG_PCI */
993 1000
994static int pvr2_get_param(const struct pvr2_params *p, const char *s, int val,
995 int size)
996{
997 int i;
998
999 for (i = 0 ; i < size ; i++ ) {
1000 if (s != NULL) {
1001 if (!strncasecmp(p[i].name, s, strlen(s)))
1002 return p[i].val;
1003 } else {
1004 if (p[i].val == val)
1005 return (int)p[i].name;
1006 }
1007 }
1008 return -1;
1009}
1010
1011/*1001/*
1012 * Parse command arguments. Supported arguments are:1002 * Parse command arguments. Supported arguments are:
1013 * inverse Use inverse color maps1003 * inverse Use inverse color maps
@@ -1047,9 +1037,9 @@ static int __init pvr2fb_setup(char *options) · 33 unmodified lines
1047 }1037 }
1048 1038
1049 if (*cable_arg)1039 if (*cable_arg)
1050 cable_type = pvr2_get_param(cables, cable_arg, 0, 3);1040 cable_type = pvr2_get_param_val(cables, cable_arg, 3);
1051 if (*output_arg)1041 if (*output_arg)
1052 video_output = pvr2_get_param(outputs, output_arg, 0, 3);1042 video_output = pvr2_get_param_val(outputs, output_arg, 3);
1053 1043
1054 return 0;1044 return 0;
1055}1045}
@@ -1082,12 +1072,8 @@ static int __init pvr2fb_init(void) · 26 unmodified lines
1082#endif1072#endif
1083 1073
1084 fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL);1074 fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL);
1085 1075 if (!fb_info)
1086 if (!fb_info) {
1087 printk(KERN_ERR "Failed to allocate memory for fb_info\n");
1088 return -ENOMEM;1076 return -ENOMEM;
1089 }
1090
1091 1077
1092 currentpar = fb_info->par;1078 currentpar = fb_info->par;
1093 1079
drivers/video/fbdev/riva/fbdev.c+0−1
@@ -1902,7 +1902,6 @@ static int rivafb_probe(struct pci_dev *pd, const struct pci_device_id *ent) · 1901 unmodified lines
1902 1902
1903 info = framebuffer_alloc(sizeof(struct riva_par), &pd->dev);1903 info = framebuffer_alloc(sizeof(struct riva_par), &pd->dev);
1904 if (!info) {1904 if (!info) {
1905 printk (KERN_ERR PFX "could not allocate memory\n");
1906 ret = -ENOMEM;1905 ret = -ENOMEM;
1907 goto err_ret;1906 goto err_ret;
1908 }1907 }
drivers/video/fbdev/s3c-fb.c+11−13
@@ -284,7 +284,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, · 283 unmodified lines
284 /* 666 with one bit alpha/transparency */284 /* 666 with one bit alpha/transparency */
285 var->transp.offset = 18;285 var->transp.offset = 18;
286 var->transp.length = 1;286 var->transp.length = 1;
287 /* drop through */287 /* fall through */
288 case 18:288 case 18:
289 var->bits_per_pixel = 32;289 var->bits_per_pixel = 32;
290 290
@@ -312,7 +312,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var, · 21 unmodified lines
312 case 25:312 case 25:
313 var->transp.length = var->bits_per_pixel - 24;313 var->transp.length = var->bits_per_pixel - 24;
314 var->transp.offset = 24;314 var->transp.offset = 24;
315 /* drop through */315 /* fall through */
316 case 24:316 case 24:
317 /* our 24bpp is unpacked, so 32bpp */317 /* our 24bpp is unpacked, so 32bpp */
318 var->bits_per_pixel = 32;318 var->bits_per_pixel = 32;
@@ -809,7 +809,7 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info) · 490 unmodified lines
809 case FB_BLANK_POWERDOWN:809 case FB_BLANK_POWERDOWN:
810 wincon &= ~WINCONx_ENWIN;810 wincon &= ~WINCONx_ENWIN;
811 sfb->enabled &= ~(1 << index);811 sfb->enabled &= ~(1 << index);
812 /* fall through to FB_BLANK_NORMAL */812 /* fall through - to FB_BLANK_NORMAL */
813 813
814 case FB_BLANK_NORMAL:814 case FB_BLANK_NORMAL:
815 /* disable the DMA and display 0x0 (black) */815 /* disable the DMA and display 0x0 (black) */
@@ -1102,14 +1102,14 @@ static int s3c_fb_alloc_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) · 286 unmodified lines
1102 1102
1103 dev_dbg(sfb->dev, "want %u bytes for window\n", size);1103 dev_dbg(sfb->dev, "want %u bytes for window\n", size);
1104 1104
1105 fbi->screen_base = dma_alloc_wc(sfb->dev, size, &map_dma, GFP_KERNEL);1105 fbi->screen_buffer = dma_alloc_wc(sfb->dev, size, &map_dma, GFP_KERNEL);
1106 if (!fbi->screen_base)1106 if (!fbi->screen_buffer)
1107 return -ENOMEM;1107 return -ENOMEM;
1108 1108
1109 dev_dbg(sfb->dev, "mapped %x to %p\n",1109 dev_dbg(sfb->dev, "mapped %x to %p\n",
1110 (unsigned int)map_dma, fbi->screen_base);1110 (unsigned int)map_dma, fbi->screen_buffer);
1111 1111
1112 memset(fbi->screen_base, 0x0, size);1112 memset(fbi->screen_buffer, 0x0, size);
1113 fbi->fix.smem_start = map_dma;1113 fbi->fix.smem_start = map_dma;
1114 1114
1115 return 0;1115 return 0;
@@ -1126,9 +1126,9 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) · 10 unmodified lines
1126{1126{
1127 struct fb_info *fbi = win->fbinfo;1127 struct fb_info *fbi = win->fbinfo;
1128 1128
1129 if (fbi->screen_base)1129 if (fbi->screen_buffer)
1130 dma_free_wc(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len),1130 dma_free_wc(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len),
1131 fbi->screen_base, fbi->fix.smem_start);1131 fbi->screen_buffer, fbi->fix.smem_start);
1132}1132}
1133 1133
1134/**1134/**
@@ -1186,10 +1186,8 @@ static int s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, · 51 unmodified lines
1186 1186
1187 fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) +1187 fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) +
1188 palette_size * sizeof(u32), sfb->dev);1188 palette_size * sizeof(u32), sfb->dev);
1189 if (!fbinfo) {1189 if (!fbinfo)
1190 dev_err(sfb->dev, "failed to allocate framebuffer\n");1190 return -ENOMEM;
1191 return -ENOENT;
1192 }
1193 1191
1194 windata = sfb->pdata->win[win_no];1192 windata = sfb->pdata->win[win_no];
1195 initmode = *sfb->pdata->vtiming;1193 initmode = *sfb->pdata->vtiming;
drivers/video/fbdev/s3fb.c+1−3
@@ -1128,10 +1128,8 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) · 1127 unmodified lines
1128 1128
1129 /* Allocate and fill driver data structure */1129 /* Allocate and fill driver data structure */
1130 info = framebuffer_alloc(sizeof(struct s3fb_info), &(dev->dev));1130 info = framebuffer_alloc(sizeof(struct s3fb_info), &(dev->dev));
1131 if (!info) {1131 if (!info)
1132 dev_err(&(dev->dev), "cannot allocate memory\n");
1133 return -ENOMEM;1132 return -ENOMEM;
1134 }
1135 1133
1136 par = info->par;1134 par = info->par;
1137 mutex_init(&par->open_lock);1135 mutex_init(&par->open_lock);
drivers/video/fbdev/sa1100fb.c+0−25
@@ -974,35 +974,10 @@ static void sa1100fb_task(struct work_struct *w) · 973 unmodified lines
974 */974 */
975static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi)975static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi)
976{976{
977#if 0
978 unsigned int min_period = (unsigned int)-1;
979 int i;
980
981 for (i = 0; i < MAX_NR_CONSOLES; i++) {
982 struct display *disp = &fb_display[i];
983 unsigned int period;
984
985 /*
986 * Do we own this display?
987 */
988 if (disp->fb_info != &fbi->fb)
989 continue;
990
991 /*
992 * Ok, calculate its DMA period
993 */
994 period = sa1100fb_display_dma_period(&disp->var);
995 if (period < min_period)
996 min_period = period;
997 }
998
999 return min_period;
1000#else
1001 /*977 /*
1002 * FIXME: we need to verify _all_ consoles.978 * FIXME: we need to verify _all_ consoles.
1003 */979 */
1004 return sa1100fb_display_dma_period(&fbi->fb.var);980 return sa1100fb_display_dma_period(&fbi->fb.var);
1005#endif
1006}981}
1007 982
1008/*983/*
drivers/video/fbdev/savage/savagefb_driver.c+1−8
@@ -2333,14 +2333,7 @@ static void savagefb_remove(struct pci_dev *dev) · 2332 unmodified lines
2333 DBG("savagefb_remove");2333 DBG("savagefb_remove");
2334 2334
2335 if (info) {2335 if (info) {
2336 /*2336 unregister_framebuffer(info);
2337 * If unregister_framebuffer fails, then
2338 * we will be leaving hooks that could cause
2339 * oopsen laying around.
2340 */
2341 if (unregister_framebuffer(info))
2342 printk(KERN_WARNING "savagefb: danger danger! "
2343 "Oopsen imminent!\n");
2344 2337
2345#ifdef CONFIG_FB_SAVAGE_I2C2338#ifdef CONFIG_FB_SAVAGE_I2C
2346 savagefb_delete_i2c_busses(info);2339 savagefb_delete_i2c_busses(info);
drivers/video/fbdev/sh_mobile_lcdcfb.c+4−136
@@ -15,6 +15,7 @@ · 14 unmodified lines
15#include <linux/ctype.h>15#include <linux/ctype.h>
16#include <linux/dma-mapping.h>16#include <linux/dma-mapping.h>
17#include <linux/delay.h>17#include <linux/delay.h>
18#include <linux/fbcon.h>
18#include <linux/gpio.h>19#include <linux/gpio.h>
19#include <linux/init.h>20#include <linux/init.h>
20#include <linux/interrupt.h>21#include <linux/interrupt.h>
@@ -213,7 +214,6 @@ struct sh_mobile_lcdc_priv { · 192 unmodified lines
213 struct sh_mobile_lcdc_chan ch[2];214 struct sh_mobile_lcdc_chan ch[2];
214 struct sh_mobile_lcdc_overlay overlays[4];215 struct sh_mobile_lcdc_overlay overlays[4];
215 216
216 struct notifier_block notifier;
217 int started;217 int started;
218 int forced_fourcc; /* 2 channel LCDC must share fourcc setting */218 int forced_fourcc; /* 2 channel LCDC must share fourcc setting */
219};219};
@@ -534,89 +534,9 @@ static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch) · 314 unmodified lines
534 ch->tx_dev->ops->display_off(ch->tx_dev);534 ch->tx_dev->ops->display_off(ch->tx_dev);
535}535}
536 536
537static bool
538sh_mobile_lcdc_must_reconfigure(struct sh_mobile_lcdc_chan *ch,
539 const struct fb_videomode *new_mode)
540{
541 dev_dbg(ch->info->dev, "Old %ux%u, new %ux%u\n",
542 ch->display.mode.xres, ch->display.mode.yres,
543 new_mode->xres, new_mode->yres);
544
545 /* It can be a different monitor with an equal video-mode */
546 if (fb_mode_is_equal(&ch->display.mode, new_mode))
547 return false;
548
549 dev_dbg(ch->info->dev, "Switching %u -> %u lines\n",
550 ch->display.mode.yres, new_mode->yres);
551 ch->display.mode = *new_mode;
552
553 return true;
554}
555
556static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,537static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var,
557 struct fb_info *info);538 struct fb_info *info);
558 539
559static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,
560 enum sh_mobile_lcdc_entity_event event,
561 const struct fb_videomode *mode,
562 const struct fb_monspecs *monspec)
563{
564 struct fb_info *info = ch->info;
565 struct fb_var_screeninfo var;
566 int ret = 0;
567
568 switch (event) {
569 case SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT:
570 /* HDMI plug in */
571 console_lock();
572 if (lock_fb_info(info)) {
573
574
575 ch->display.width = monspec->max_x * 10;
576 ch->display.height = monspec->max_y * 10;
577
578 if (!sh_mobile_lcdc_must_reconfigure(ch, mode) &&
579 info->state == FBINFO_STATE_RUNNING) {
580 /* First activation with the default monitor.
581 * Just turn on, if we run a resume here, the
582 * logo disappears.
583 */
584 info->var.width = ch->display.width;
585 info->var.height = ch->display.height;
586 sh_mobile_lcdc_display_on(ch);
587 } else {
588 /* New monitor or have to wake up */
589 fb_set_suspend(info, 0);
590 }
591
592
593 unlock_fb_info(info);
594 }
595 console_unlock();
596 break;
597
598 case SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT:
599 /* HDMI disconnect */
600 console_lock();
601 if (lock_fb_info(info)) {
602 fb_set_suspend(info, 1);
603 unlock_fb_info(info);
604 }
605 console_unlock();
606 break;
607
608 case SH_MOBILE_LCDC_EVENT_DISPLAY_MODE:
609 /* Validate a proposed new mode */
610 fb_videomode_to_var(&var, mode);
611 var.bits_per_pixel = info->var.bits_per_pixel;
612 var.grayscale = info->var.grayscale;
613 ret = sh_mobile_lcdc_check_var(&var, info);
614 break;
615 }
616
617 return ret;
618}
619
620/* -----------------------------------------------------------------------------540/* -----------------------------------------------------------------------------
621 * Format helpers541 * Format helpers
622 */542 */
@@ -1644,10 +1564,8 @@ sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl) · 1021 unmodified lines
1644 1564
1645 /* Allocate and initialize the frame buffer device. */1565 /* Allocate and initialize the frame buffer device. */
1646 info = framebuffer_alloc(0, priv->dev);1566 info = framebuffer_alloc(0, priv->dev);
1647 if (info == NULL) {1567 if (!info)
1648 dev_err(priv->dev, "unable to allocate fb_info\n");
1649 return -ENOMEM;1568 return -ENOMEM;
1650 }
1651 1569
1652 ovl->info = info;1570 ovl->info = info;
1653 1571
@@ -1838,8 +1756,6 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) · 184 unmodified lines
1838 struct sh_mobile_lcdc_chan *ch = info->par;1756 struct sh_mobile_lcdc_chan *ch = info->par;
1839 struct fb_var_screeninfo var;1757 struct fb_var_screeninfo var;
1840 struct fb_videomode mode;1758 struct fb_videomode mode;
1841 struct fb_event event;
1842 int evnt = FB_EVENT_MODE_CHANGE_ALL;
1843 1759
1844 if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par))1760 if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par))
1845 /* More framebuffer users are active */1761 /* More framebuffer users are active */
@@ -1861,14 +1777,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) · 15 unmodified lines
1861 /* Couldn't reconfigure, hopefully, can continue as before */1777 /* Couldn't reconfigure, hopefully, can continue as before */
1862 return;1778 return;
1863 1779
1864 /*1780 fbcon_update_vcs(info, true);
1865 * fb_set_var() calls the notifier change internally, only if
1866 * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a
1867 * user event, we have to call the chain ourselves.
1868 */
1869 event.info = info;
1870 event.data = &ch->display.mode;
1871 fb_notifier_call_chain(evnt, &event);
1872}1781}
1873 1782
1874/*1783/*
@@ -2138,10 +2047,8 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch, · 263 unmodified lines
2138 * list and allocate the color map.2047 * list and allocate the color map.
2139 */2048 */
2140 info = framebuffer_alloc(0, priv->dev);2049 info = framebuffer_alloc(0, priv->dev);
2141 if (info == NULL) {2050 if (!info)
2142 dev_err(priv->dev, "unable to allocate fb_info\n");
2143 return -ENOMEM;2051 return -ENOMEM;
2144 }
2145 2052
2146 ch->info = info;2053 ch->info = info;
2147 2054
@@ -2319,37 +2226,6 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { · 171 unmodified lines
2319 * Framebuffer notifier2226 * Framebuffer notifier
2320 */2227 */
2321 2228
2322/* locking: called with info->lock held */
2323static int sh_mobile_lcdc_notify(struct notifier_block *nb,
2324 unsigned long action, void *data)
2325{
2326 struct fb_event *event = data;
2327 struct fb_info *info = event->info;
2328 struct sh_mobile_lcdc_chan *ch = info->par;
2329
2330 if (&ch->lcdc->notifier != nb)
2331 return NOTIFY_DONE;
2332
2333 dev_dbg(info->dev, "%s(): action = %lu, data = %p\n",
2334 __func__, action, event->data);
2335
2336 switch(action) {
2337 case FB_EVENT_SUSPEND:
2338 sh_mobile_lcdc_display_off(ch);
2339 sh_mobile_lcdc_stop(ch->lcdc);
2340 break;
2341 case FB_EVENT_RESUME:
2342 mutex_lock(&ch->open_lock);
2343 sh_mobile_fb_reconfig(info);
2344 mutex_unlock(&ch->open_lock);
2345
2346 sh_mobile_lcdc_display_on(ch);
2347 sh_mobile_lcdc_start(ch->lcdc);
2348 }
2349
2350 return NOTIFY_OK;
2351}
2352
2353/* -----------------------------------------------------------------------------2229/* -----------------------------------------------------------------------------
2354 * Probe/remove and driver init/exit2230 * Probe/remove and driver init/exit
2355 */2231 */
@@ -2377,8 +2253,6 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) · 21 unmodified lines
2377 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);2253 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
2378 unsigned int i;2254 unsigned int i;
2379 2255
2380 fb_unregister_client(&priv->notifier);
2381
2382 for (i = 0; i < ARRAY_SIZE(priv->overlays); i++)2256 for (i = 0; i < ARRAY_SIZE(priv->overlays); i++)
2383 sh_mobile_lcdc_overlay_fb_unregister(&priv->overlays[i]);2257 sh_mobile_lcdc_overlay_fb_unregister(&priv->overlays[i]);
2384 for (i = 0; i < ARRAY_SIZE(priv->ch); i++)2258 for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
@@ -2540,8 +2414,6 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch) · 155 unmodified lines
2540 unsigned int max_size;2414 unsigned int max_size;
2541 unsigned int i;2415 unsigned int i;
2542 2416
2543 ch->notify = sh_mobile_lcdc_display_notify;
2544
2545 /* Validate the format. */2417 /* Validate the format. */
2546 format = sh_mobile_format_info(cfg->fourcc);2418 format = sh_mobile_format_info(cfg->fourcc);
2547 if (format == NULL) {2419 if (format == NULL) {
@@ -2770,10 +2642,6 @@ static int sh_mobile_lcdc_probe(struct platform_device *pdev) · 222 unmodified lines
2770 goto err1;2642 goto err1;
2771 }2643 }
2772 2644
2773 /* Failure ignored */
2774 priv->notifier.notifier_call = sh_mobile_lcdc_notify;
2775 fb_register_client(&priv->notifier);
2776
2777 return 0;2645 return 0;
2778err1:2646err1:
2779 sh_mobile_lcdc_remove(pdev);2647 sh_mobile_lcdc_remove(pdev);
drivers/video/fbdev/sh_mobile_lcdcfb.h+0−5
@@ -87,11 +87,6 @@ struct sh_mobile_lcdc_chan { · 86 unmodified lines
87 unsigned long base_addr_c;87 unsigned long base_addr_c;
88 unsigned int line_size;88 unsigned int line_size;
89 89
90 int (*notify)(struct sh_mobile_lcdc_chan *ch,
91 enum sh_mobile_lcdc_entity_event event,
92 const struct fb_videomode *mode,
93 const struct fb_monspecs *monspec);
94
95 /* Backlight */90 /* Backlight */
96 struct backlight_device *bl;91 struct backlight_device *bl;
97 unsigned int bl_brightness;92 unsigned int bl_brightness;
drivers/video/fbdev/sm501fb.c+1−3
@@ -1865,10 +1865,8 @@ static int sm501fb_probe_one(struct sm501fb_info *info, · 1864 unmodified lines
1865 }1865 }
1866 1866
1867 fbi = framebuffer_alloc(sizeof(struct sm501fb_par), info->dev);1867 fbi = framebuffer_alloc(sizeof(struct sm501fb_par), info->dev);
1868 if (fbi == NULL) {1868 if (!fbi)
1869 dev_err(info->dev, "cannot allocate %s framebuffer\n", name);
1870 return -ENOMEM;1869 return -ENOMEM;
1871 }
1872 1870
1873 par = fbi->par;1871 par = fbi->par;
1874 par->info = info;1872 par->info = info;
drivers/video/fbdev/sm712fb.c+0−1
@@ -1538,7 +1538,6 @@ static int smtcfb_pci_probe(struct pci_dev *pdev, · 1537 unmodified lines
1538 1538
1539 info = framebuffer_alloc(sizeof(*sfb), &pdev->dev);1539 info = framebuffer_alloc(sizeof(*sfb), &pdev->dev);
1540 if (!info) {1540 if (!info) {
1541 dev_err(&pdev->dev, "framebuffer_alloc failed\n");
1542 err = -ENOMEM;1541 err = -ENOMEM;
1543 goto failed_free;1542 goto failed_free;
1544 }1543 }
drivers/video/fbdev/smscufx.c+1−3
@@ -1650,10 +1650,8 @@ static int ufx_usb_probe(struct usb_interface *interface, · 1649 unmodified lines
1650 1650
1651 /* allocates framebuffer driver structure, not framebuffer memory */1651 /* allocates framebuffer driver structure, not framebuffer memory */
1652 info = framebuffer_alloc(0, &usbdev->dev);1652 info = framebuffer_alloc(0, &usbdev->dev);
1653 if (!info) {1653 if (!info)
1654 dev_err(dev->gdev, "framebuffer_alloc failed\n");
1655 goto e_nomem;1654 goto e_nomem;
1656 }
1657 1655
1658 dev->info = info;1656 dev->info = info;
1659 info->par = dev;1657 info->par = dev;
drivers/video/fbdev/ssd1307fb.c+1−3
@@ -555,10 +555,8 @@ static int ssd1307fb_probe(struct i2c_client *client, · 554 unmodified lines
555 }555 }
556 556
557 info = framebuffer_alloc(sizeof(struct ssd1307fb_par), &client->dev);557 info = framebuffer_alloc(sizeof(struct ssd1307fb_par), &client->dev);
558 if (!info) {558 if (!info)
559 dev_err(&client->dev, "Couldn't allocate framebuffer.\n");
560 return -ENOMEM;559 return -ENOMEM;
561 }
562 560
563 par = info->par;561 par = info->par;
564 par->info = info;562 par->info = info;
drivers/video/fbdev/sunxvr1000.c+0−1
@@ -121,7 +121,6 @@ static int gfb_probe(struct platform_device *op) · 120 unmodified lines
121 121
122 info = framebuffer_alloc(sizeof(struct gfb_info), &op->dev);122 info = framebuffer_alloc(sizeof(struct gfb_info), &op->dev);
123 if (!info) {123 if (!info) {
124 printk(KERN_ERR "gfb: Cannot allocate fb_info\n");
125 err = -ENOMEM;124 err = -ENOMEM;
126 goto err_out;125 goto err_out;
127 }126 }
drivers/video/fbdev/sunxvr2500.c+0−1
@@ -132,7 +132,6 @@ static int s3d_pci_register(struct pci_dev *pdev, · 131 unmodified lines
132 132
133 info = framebuffer_alloc(sizeof(struct s3d_info), &pdev->dev);133 info = framebuffer_alloc(sizeof(struct s3d_info), &pdev->dev);
134 if (!info) {134 if (!info) {
135 printk(KERN_ERR "s3d: Cannot allocate fb_info\n");
136 err = -ENOMEM;135 err = -ENOMEM;
137 goto err_disable;136 goto err_disable;
138 }137 }
drivers/video/fbdev/sunxvr500.c+0−1
@@ -272,7 +272,6 @@ static int e3d_pci_register(struct pci_dev *pdev, · 271 unmodified lines
272 272
273 info = framebuffer_alloc(sizeof(struct e3d_info), &pdev->dev);273 info = framebuffer_alloc(sizeof(struct e3d_info), &pdev->dev);
274 if (!info) {274 if (!info) {
275 printk(KERN_ERR "e3d: Cannot allocate fb_info\n");
276 err = -ENOMEM;275 err = -ENOMEM;
277 goto err_disable;276 goto err_disable;
278 }277 }
drivers/video/fbdev/tgafb.c+1−3
@@ -1416,10 +1416,8 @@ static int tgafb_register(struct device *dev) · 1415 unmodified lines
1416 1416
1417 /* Allocate the fb and par structures. */1417 /* Allocate the fb and par structures. */
1418 info = framebuffer_alloc(sizeof(struct tga_par), dev);1418 info = framebuffer_alloc(sizeof(struct tga_par), dev);
1419 if (!info) {1419 if (!info)
1420 printk(KERN_ERR "tgafb: Cannot allocate memory\n");
1421 return -ENOMEM;1420 return -ENOMEM;
1422 }
1423 1421
1424 par = info->par;1422 par = info->par;
1425 dev_set_drvdata(dev, info);1423 dev_set_drvdata(dev, info);
drivers/video/fbdev/udlfb.c+1−3
@@ -1686,10 +1686,8 @@ static int dlfb_usb_probe(struct usb_interface *intf, · 1685 unmodified lines
1686 1686
1687 /* allocates framebuffer driver structure, not framebuffer memory */1687 /* allocates framebuffer driver structure, not framebuffer memory */
1688 info = framebuffer_alloc(0, &dlfb->udev->dev);1688 info = framebuffer_alloc(0, &dlfb->udev->dev);
1689 if (!info) {1689 if (!info)
1690 dev_err(&dlfb->udev->dev, "framebuffer_alloc failed\n");
1691 goto error;1690 goto error;
1692 }
1693 1691
1694 dlfb->info = info;1692 dlfb->info = info;
1695 info->par = dlfb;1693 info->par = dlfb;
drivers/video/fbdev/via/viafbdev.c+1−5
@@ -1742,10 +1742,8 @@ int via_fb_pci_probe(struct viafb_dev *vdev) · 1741 unmodified lines
1742 viafbinfo = framebuffer_alloc(viafb_par_length +1742 viafbinfo = framebuffer_alloc(viafb_par_length +
1743 ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8),1743 ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8),
1744 &vdev->pdev->dev);1744 &vdev->pdev->dev);
1745 if (!viafbinfo) {1745 if (!viafbinfo)
1746 printk(KERN_ERR"Could not allocate memory for viafb_info.\n");
1747 return -ENOMEM;1746 return -ENOMEM;
1748 }
1749 1747
1750 viaparinfo = (struct viafb_par *)viafbinfo->par;1748 viaparinfo = (struct viafb_par *)viafbinfo->par;
1751 viaparinfo->shared = viafbinfo->par + viafb_par_length;1749 viaparinfo->shared = viafbinfo->par + viafb_par_length;
@@ -1820,8 +1818,6 @@ int via_fb_pci_probe(struct viafb_dev *vdev) · 68 unmodified lines
1820 viafbinfo1 = framebuffer_alloc(viafb_par_length,1818 viafbinfo1 = framebuffer_alloc(viafb_par_length,
1821 &vdev->pdev->dev);1819 &vdev->pdev->dev);
1822 if (!viafbinfo1) {1820 if (!viafbinfo1) {
1823 printk(KERN_ERR
1824 "allocate the second framebuffer struct error\n");
1825 rc = -ENOMEM;1821 rc = -ENOMEM;
1826 goto out_fb_release;1822 goto out_fb_release;
1827 }1823 }
drivers/video/fbdev/vt8623fb.c+1−3
@@ -669,10 +669,8 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) · 668 unmodified lines
669 669
670 /* Allocate and fill driver data structure */670 /* Allocate and fill driver data structure */
671 info = framebuffer_alloc(sizeof(struct vt8623fb_info), &(dev->dev));671 info = framebuffer_alloc(sizeof(struct vt8623fb_info), &(dev->dev));
672 if (! info) {672 if (!info)
673 dev_err(&(dev->dev), "cannot allocate memory\n");
674 return -ENOMEM;673 return -ENOMEM;
675 }
676 674
677 par = info->par;675 par = info->par;
678 mutex_init(&par->open_lock);676 mutex_init(&par->open_lock);
include/linux/console_struct.h+1−4
@@ -168,9 +168,6 @@ extern void vc_SAK(struct work_struct *work); · 167 unmodified lines
168 168
169#define CUR_DEFAULT CUR_UNDERLINE169#define CUR_DEFAULT CUR_UNDERLINE
170 170
171static inline bool con_is_visible(const struct vc_data *vc)171bool con_is_visible(const struct vc_data *vc);
172{
173 return *vc->vc_display_fg == vc;
174}
175 172
176#endif /* _LINUX_CONSOLE_STRUCT_H */173#endif /* _LINUX_CONSOLE_STRUCT_H */
include/linux/fb.h+12−33
@@ -126,39 +126,15 @@ struct fb_cursor_user { · 125 unmodified lines
126 126
127/* The resolution of the passed in fb_info about to change */ 127/* The resolution of the passed in fb_info about to change */
128#define FB_EVENT_MODE_CHANGE 0x01128#define FB_EVENT_MODE_CHANGE 0x01
129/* The display on this fb_info is being suspended, no access to the129
130 * framebuffer is allowed any more after that call returns130#ifdef CONFIG_GUMSTIX_AM200EPD
131 */131/* only used by mach-pxa/am200epd.c */
132#define FB_EVENT_SUSPEND 0x02
133/* The display on this fb_info was resumed, you can restore the display
134 * if you own it
135 */
136#define FB_EVENT_RESUME 0x03
137/* An entry from the modelist was removed */
138#define FB_EVENT_MODE_DELETE 0x04
139/* A driver registered itself */
140#define FB_EVENT_FB_REGISTERED 0x05132#define FB_EVENT_FB_REGISTERED 0x05
141/* A driver unregistered itself */
142#define FB_EVENT_FB_UNREGISTERED 0x06133#define FB_EVENT_FB_UNREGISTERED 0x06
143/* CONSOLE-SPECIFIC: get console to framebuffer mapping */134#endif
144#define FB_EVENT_GET_CONSOLE_MAP 0x07135
145/* CONSOLE-SPECIFIC: set console to framebuffer mapping */136/* A display blank is requested */
146#define FB_EVENT_SET_CONSOLE_MAP 0x08
147/* A hardware display blank change occurred */
148#define FB_EVENT_BLANK 0x09137#define FB_EVENT_BLANK 0x09
149/* Private modelist is to be replaced */
150#define FB_EVENT_NEW_MODELIST 0x0A
151/* The resolution of the passed in fb_info about to change and
152 all vc's should be changed */
153#define FB_EVENT_MODE_CHANGE_ALL 0x0B
154/* A software display blank change occurred */
155#define FB_EVENT_CONBLANK 0x0C
156/* Get drawing requirements */
157#define FB_EVENT_GET_REQ 0x0D
158/* Unbind from the console if possible */
159#define FB_EVENT_FB_UNBIND 0x0E
160/* CONSOLE-SPECIFIC: remap all consoles to new fb - for vga_switcheroo */
161#define FB_EVENT_REMAP_ALL_CONSOLE 0x0F
162/* A hardware display blank early change occurred */138/* A hardware display blank early change occurred */
163#define FB_EARLY_EVENT_BLANK 0x10139#define FB_EARLY_EVENT_BLANK 0x10
164/* A hardware display blank revert early change occurred */140/* A hardware display blank revert early change occurred */
@@ -633,8 +609,8 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, · 468 unmodified lines
633 609
634/* drivers/video/fbmem.c */610/* drivers/video/fbmem.c */
635extern int register_framebuffer(struct fb_info *fb_info);611extern int register_framebuffer(struct fb_info *fb_info);
636extern int unregister_framebuffer(struct fb_info *fb_info);612extern void unregister_framebuffer(struct fb_info *fb_info);
637extern int unlink_framebuffer(struct fb_info *fb_info);613extern void unlink_framebuffer(struct fb_info *fb_info);
638extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, int res_id,614extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, int res_id,
639 const char *name);615 const char *name);
640extern int remove_conflicting_framebuffers(struct apertures_struct *a,616extern int remove_conflicting_framebuffers(struct apertures_struct *a,
@@ -660,7 +636,10 @@ extern struct class *fb_class; · 19 unmodified lines
660 for (i = 0; i < FB_MAX; i++) \636 for (i = 0; i < FB_MAX; i++) \
661 if (!registered_fb[i]) {} else637 if (!registered_fb[i]) {} else
662 638
663extern int lock_fb_info(struct fb_info *info);639static inline void lock_fb_info(struct fb_info *info)
640{
641 mutex_lock(&info->lock);
642}
664 643
665static inline void unlock_fb_info(struct fb_info *info)644static inline void unlock_fb_info(struct fb_info *info)
666{645{
include/linux/fbcon.h+30−0
@@ -4,9 +4,39 @@ · 3 unmodified lines
4#ifdef CONFIG_FRAMEBUFFER_CONSOLE4#ifdef CONFIG_FRAMEBUFFER_CONSOLE
5void __init fb_console_init(void);5void __init fb_console_init(void);
6void __exit fb_console_exit(void);6void __exit fb_console_exit(void);
7int fbcon_fb_registered(struct fb_info *info);
8void fbcon_fb_unregistered(struct fb_info *info);
9void fbcon_fb_unbind(struct fb_info *info);
10void fbcon_suspended(struct fb_info *info);
11void fbcon_resumed(struct fb_info *info);
12int fbcon_mode_deleted(struct fb_info *info,
13 struct fb_videomode *mode);
14void fbcon_new_modelist(struct fb_info *info);
15void fbcon_get_requirement(struct fb_info *info,
16 struct fb_blit_caps *caps);
17void fbcon_fb_blanked(struct fb_info *info, int blank);
18void fbcon_update_vcs(struct fb_info *info, bool all);
19void fbcon_remap_all(struct fb_info *info);
20int fbcon_set_con2fb_map_ioctl(void __user *argp);
21int fbcon_get_con2fb_map_ioctl(void __user *argp);
7#else22#else
8static inline void fb_console_init(void) {}23static inline void fb_console_init(void) {}
9static inline void fb_console_exit(void) {}24static inline void fb_console_exit(void) {}
25static inline int fbcon_fb_registered(struct fb_info *info) { return 0; }
26static inline void fbcon_fb_unregistered(struct fb_info *info) {}
27static inline void fbcon_fb_unbind(struct fb_info *info) {}
28static inline void fbcon_suspended(struct fb_info *info) {}
29static inline void fbcon_resumed(struct fb_info *info) {}
30static inline int fbcon_mode_deleted(struct fb_info *info,
31 struct fb_videomode *mode) { return 0; }
32static inline void fbcon_new_modelist(struct fb_info *info) {}
33static inline void fbcon_get_requirement(struct fb_info *info,
34 struct fb_blit_caps *caps) {}
35static inline void fbcon_fb_blanked(struct fb_info *info, int blank) {}
36static inline void fbcon_update_vcs(struct fb_info *info, bool all) {}
37static inline void fbcon_remap_all(struct fb_info *info) {}
38static inline int fbcon_set_con2fb_map_ioctl(void __user *argp) { return 0; }
39static inline int fbcon_get_con2fb_map_ioctl(void __user *argp) { return 0; }
10#endif40#endif
11 41
12#endif /* _LINUX_FBCON_H */42#endif /* _LINUX_FBCON_H */
include/video/omapfb_dss.h+0−32
@@ -114,11 +114,6 @@ enum omap_dss_trans_key_type { · 113 unmodified lines
114 OMAP_DSS_COLOR_KEY_VID_SRC = 1,114 OMAP_DSS_COLOR_KEY_VID_SRC = 1,
115};115};
116 116
117enum omap_rfbi_te_mode {
118 OMAP_DSS_RFBI_TE_MODE_1 = 1,
119 OMAP_DSS_RFBI_TE_MODE_2 = 2,
120};
121
122enum omap_dss_signal_level {117enum omap_dss_signal_level {
123 OMAPDSS_SIG_ACTIVE_LOW,118 OMAPDSS_SIG_ACTIVE_LOW,
124 OMAPDSS_SIG_ACTIVE_HIGH,119 OMAPDSS_SIG_ACTIVE_HIGH,
@@ -189,27 +184,6 @@ enum omap_dss_output_id { · 64 unmodified lines
189 OMAP_DSS_OUTPUT_HDMI = 1 << 6,184 OMAP_DSS_OUTPUT_HDMI = 1 << 6,
190};185};
191 186
192/* RFBI */
193
194struct rfbi_timings {
195 int cs_on_time;
196 int cs_off_time;
197 int we_on_time;
198 int we_off_time;
199 int re_on_time;
200 int re_off_time;
201 int we_cycle_time;
202 int re_cycle_time;
203 int cs_pulse_width;
204 int access_time;
205
206 int clk_div;
207
208 u32 tim[5]; /* set by rfbi_convert_timings() */
209
210 int converted;
211};
212
213/* DSI */187/* DSI */
214 188
215enum omap_dss_dsi_trans_mode {189enum omap_dss_dsi_trans_mode {
@@ -640,11 +614,6 @@ struct omap_dss_device { · 424 unmodified lines
640 u8 data_lines;614 u8 data_lines;
641 } dpi;615 } dpi;
642 616
643 struct {
644 u8 channel;
645 u8 data_lines;
646 } rfbi;
647
648 struct {617 struct {
649 u8 datapairs;618 u8 datapairs;
650 } sdi;619 } sdi;
@@ -668,7 +637,6 @@ struct omap_dss_device { · 17 unmodified lines
668 637
669 struct {638 struct {
670 u8 pixel_size;639 u8 pixel_size;
671 struct rfbi_timings rfbi_timings;
672 } ctrl;640 } ctrl;
673 641
674 const char *name;642 const char *name;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t