summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-09 12:55:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-09 12:55:45 -0400
commit2d41ef5432b76ae90dc0db93026f1d981f874ec4 (patch)
treedc97253d9328e8652614bfe8026748dd53c6561a
parented63b9c873601ca113da5c7b1745e3946493e9f3 (diff)
parent732146a3f1dc78ebb0d3c4b1f4dc6ea33cc2c58f (diff)
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 ...
-rw-r--r--arch/arm/mach-pxa/am200epd.c13
-rw-r--r--drivers/gpu/vga/Kconfig1
-rw-r--r--drivers/gpu/vga/vga_switcheroo.c11
-rw-r--r--drivers/hid/hid-picolcd_fb.c4
-rw-r--r--drivers/media/pci/ivtv/ivtvfb.c6
-rw-r--r--drivers/staging/fbtft/fbtft-core.c4
-rw-r--r--drivers/staging/olpc_dcon/TODO7
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon.c6
-rw-r--r--drivers/tty/vt/vt.c18
-rw-r--r--drivers/video/backlight/backlight.c2
-rw-r--r--drivers/video/backlight/lcd.c12
-rw-r--r--drivers/video/console/dummycon.c6
-rw-r--r--drivers/video/fbdev/Kconfig34
-rw-r--r--drivers/video/fbdev/Makefile1
-rw-r--r--drivers/video/fbdev/amifb.c4
-rw-r--r--drivers/video/fbdev/arkfb.c4
-rw-r--r--drivers/video/fbdev/atafb.c21
-rw-r--r--drivers/video/fbdev/atmel_lcdfb.c10
-rw-r--r--drivers/video/fbdev/aty/aty128fb.c69
-rw-r--r--drivers/video/fbdev/aty/atyfb_base.c13
-rw-r--r--drivers/video/fbdev/aty/radeon_base.c2
-rw-r--r--drivers/video/fbdev/au1200fb.c19
-rw-r--r--drivers/video/fbdev/chipsfb.c1
-rw-r--r--drivers/video/fbdev/cirrusfb.c5
-rw-r--r--drivers/video/fbdev/controlfb.c8
-rw-r--r--drivers/video/fbdev/core/fbcmap.c6
-rw-r--r--drivers/video/fbdev/core/fbcon.c314
-rw-r--r--drivers/video/fbdev/core/fbcon.h6
-rw-r--r--drivers/video/fbdev/core/fbmem.c399
-rw-r--r--drivers/video/fbdev/core/fbsysfs.c20
-rw-r--r--drivers/video/fbdev/cyber2000fb.c6
-rw-r--r--drivers/video/fbdev/da8xx-fb.c1
-rw-r--r--drivers/video/fbdev/efifb.c6
-rw-r--r--drivers/video/fbdev/gbefb.c19
-rw-r--r--drivers/video/fbdev/grvga.c4
-rw-r--r--drivers/video/fbdev/gxt4500.c5
-rw-r--r--drivers/video/fbdev/hyperv_fb.c4
-rw-r--r--drivers/video/fbdev/i740fb.c4
-rw-r--r--drivers/video/fbdev/imsttfb.c5
-rw-r--r--drivers/video/fbdev/imxfb.c11
-rw-r--r--drivers/video/fbdev/intelfb/intelfbdrv.c7
-rw-r--r--drivers/video/fbdev/jz4740_fb.c11
-rw-r--r--drivers/video/fbdev/mb862xx/mb862xxfbdrv.c5
-rw-r--r--drivers/video/fbdev/mbx/mbxfb.c4
-rw-r--r--drivers/video/fbdev/mmp/hw/mmp_ctrl.c8
-rw-r--r--drivers/video/fbdev/mxsfb.c1028
-rw-r--r--drivers/video/fbdev/neofb.c9
-rw-r--r--drivers/video/fbdev/omap/omapfb_main.c2
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/Kconfig12
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/Makefile1
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/core.c6
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/dss.h4
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/rfbi.c1067
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb-main.c6
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c21
-rw-r--r--drivers/video/fbdev/platinumfb.c5
-rw-r--r--drivers/video/fbdev/pmag-aa-fb.c4
-rw-r--r--drivers/video/fbdev/pmag-ba-fb.c4
-rw-r--r--drivers/video/fbdev/pmagb-b-fb.c4
-rw-r--r--drivers/video/fbdev/pvr2fb.c188
-rw-r--r--drivers/video/fbdev/riva/fbdev.c1
-rw-r--r--drivers/video/fbdev/s3c-fb.c24
-rw-r--r--drivers/video/fbdev/s3fb.c4
-rw-r--r--drivers/video/fbdev/sa1100fb.c25
-rw-r--r--drivers/video/fbdev/savage/savagefb_driver.c9
-rw-r--r--drivers/video/fbdev/sh_mobile_lcdcfb.c140
-rw-r--r--drivers/video/fbdev/sh_mobile_lcdcfb.h5
-rw-r--r--drivers/video/fbdev/sm501fb.c4
-rw-r--r--drivers/video/fbdev/sm712fb.c1
-rw-r--r--drivers/video/fbdev/smscufx.c4
-rw-r--r--drivers/video/fbdev/ssd1307fb.c4
-rw-r--r--drivers/video/fbdev/sunxvr1000.c1
-rw-r--r--drivers/video/fbdev/sunxvr2500.c1
-rw-r--r--drivers/video/fbdev/sunxvr500.c1
-rw-r--r--drivers/video/fbdev/tgafb.c4
-rw-r--r--drivers/video/fbdev/udlfb.c4
-rw-r--r--drivers/video/fbdev/via/viafbdev.c6
-rw-r--r--drivers/video/fbdev/vt8623fb.c4
-rw-r--r--include/linux/console_struct.h5
-rw-r--r--include/linux/fb.h45
-rw-r--r--include/linux/fbcon.h30
-rw-r--r--include/video/omapfb_dss.h32
82 files changed, 582 insertions, 3259 deletions
diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c
index 50e18ed37fa6..cac0bb09db14 100644
--- a/arch/arm/mach-pxa/am200epd.c
+++ b/arch/arm/mach-pxa/am200epd.c
@@ -347,8 +347,17 @@ int __init am200_init(void)
347{ 347{
348 int ret; 348 int ret;
349 349
350 /* before anything else, we request notification for any fb 350 /*
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));
diff --git a/drivers/gpu/vga/Kconfig b/drivers/gpu/vga/Kconfig
index 84ab482d0db6..c8c770b05ed9 100644
--- a/drivers/gpu/vga/Kconfig
+++ b/drivers/gpu/vga/Kconfig
@@ -23,6 +23,7 @@ config VGA_SWITCHEROO
23 depends on X86 23 depends on X86
24 depends on ACPI 24 depends on ACPI
25 depends on PCI 25 depends on PCI
26 depends on (FRAMEBUFFER_CONSOLE=n || FB=y)
26 select VGA_ARB 27 select VGA_ARB
27 help 28 help
28 Many laptops released in 2008/9/10 have two GPUs with a multiplexer 29 Many laptops released in 2008/9/10 have two GPUs with a multiplexer
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c
index a132c37d7334..65d7541c413a 100644
--- a/drivers/gpu/vga/vga_switcheroo.c
+++ b/drivers/gpu/vga/vga_switcheroo.c
@@ -35,6 +35,7 @@
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)
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);
diff --git a/drivers/hid/hid-picolcd_fb.c b/drivers/hid/hid-picolcd_fb.c
index 6897e14e7cb7..e162a668fb7e 100644
--- a/drivers/hid/hid-picolcd_fb.c
+++ b/drivers/hid/hid-picolcd_fb.c
@@ -512,10 +512,8 @@ int picolcd_init_framebuffer(struct picolcd_data *data)
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;
diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c
index 800b3654cac5..95a56cce9b65 100644
--- a/drivers/media/pci/ivtv/ivtvfb.c
+++ b/drivers/media/pci/ivtv/ivtvfb.c
@@ -1256,11 +1256,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p)
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);
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
index 9b07badf4c6c..7cbc1bdd2d8a 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -891,7 +891,9 @@ int fbtft_unregister_framebuffer(struct fb_info *fb_info)
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
diff --git a/drivers/staging/olpc_dcon/TODO b/drivers/staging/olpc_dcon/TODO
index 665a0b061719..fe09efbc7f77 100644
--- a/drivers/staging/olpc_dcon/TODO
+++ b/drivers/staging/olpc_dcon/TODO
@@ -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 can 9 - see if vx855 gpio API can be made similar enough to cs5535 so we can
3 share more code 10 share more code
4 - convert all uses of the old GPIO API from <linux/gpio.h> to the 11 - convert all uses of the old GPIO API from <linux/gpio.h> to the
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c
index 6b714f740ac3..a254238be181 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon.c
@@ -250,11 +250,7 @@ static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank)
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,
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 5c0ca1c24b6f..ec92f36ab5c4 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3822,6 +3822,8 @@ int con_is_bound(const struct consw *csw)
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;
@@ -3834,6 +3836,20 @@ int con_is_bound(const struct consw *csw)
3834EXPORT_SYMBOL(con_is_bound); 3836EXPORT_SYMBOL(con_is_bound);
3835 3837
3836/** 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
3852/**
3837 * con_debug_enter - prepare the console for the kernel debugger 3853 * con_debug_enter - prepare the console for the kernel debugger
3838 * @sw: console driver 3854 * @sw: console driver
3839 * 3855 *
@@ -4166,6 +4182,8 @@ void do_blank_screen(int entering_gfx)
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) {
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 1ef8b6fd62ac..5dc07106a59e 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -47,7 +47,7 @@ static int fb_notifier_callback(struct notifier_block *self,
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);
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 151b18776add..d6b653aa4ee9 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -30,18 +30,6 @@ static int fb_notifier_callback(struct notifier_block *self,
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;
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
index ff886e99104b..2a0d0bda7faa 100644
--- a/drivers/video/console/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -34,6 +34,8 @@ static bool dummycon_putc_called;
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)
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}
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 1b2f5f31fb6f..b174af914e7a 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -332,7 +332,8 @@ config FB_SA1100
332 332
333config FB_IMX 333config 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_MXC 335 depends on FB && HAVE_CLK && HAS_IOMEM
336 depends on ARCH_MXC || COMPILE_TEST
336 select LCD_CLASS_DEVICE 337 select LCD_CLASS_DEVICE
337 select FB_CFB_FILLRECT 338 select FB_CFB_FILLRECT
338 select FB_CFB_COPYAREA 339 select FB_CFB_COPYAREA
@@ -670,7 +671,8 @@ config FB_HGA
670 671
671config FB_GBE 672config FB_GBE
672 bool "SGI Graphics Backend frame buffer support" 673 bool "SGI Graphics Backend frame buffer support"
673 depends on (FB = y) && SGI_IP32 674 depends on (FB = y) && HAS_IOMEM
675 depends on SGI_IP32 || COMPILE_TEST
674 select FB_CFB_FILLRECT 676 select FB_CFB_FILLRECT
675 select FB_CFB_COPYAREA 677 select FB_CFB_COPYAREA
676 select FB_CFB_IMAGEBLIT 678 select FB_CFB_IMAGEBLIT
@@ -808,7 +810,8 @@ config FB_XVR1000
808 810
809config FB_PVR2 811config FB_PVR2
810 tristate "NEC PowerVR 2 display support" 812 tristate "NEC PowerVR 2 display support"
811 depends on FB && SH_DREAMCAST 813 depends on FB && HAS_IOMEM
814 depends on SH_DREAMCAST || COMPILE_TEST
812 select FB_CFB_FILLRECT 815 select FB_CFB_FILLRECT
813 select FB_CFB_COPYAREA 816 select FB_CFB_COPYAREA
814 select FB_CFB_IMAGEBLIT 817 select FB_CFB_IMAGEBLIT
@@ -856,7 +859,8 @@ config FB_S1D13XXX
856 859
857config FB_ATMEL 860config FB_ATMEL
858 tristate "AT91 LCD Controller support" 861 tristate "AT91 LCD Controller support"
859 depends on FB && OF && HAVE_FB_ATMEL 862 depends on FB && OF && HAVE_CLK && HAS_IOMEM
863 depends on HAVE_FB_ATMEL || COMPILE_TEST
860 select FB_BACKLIGHT 864 select FB_BACKLIGHT
861 select FB_CFB_FILLRECT 865 select FB_CFB_FILLRECT
862 select FB_CFB_COPYAREA 866 select FB_CFB_COPYAREA
@@ -1729,7 +1733,8 @@ config FB_68328
1729 1733
1730config FB_PXA168 1734config 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_FILLRECT 1738 select FB_CFB_FILLRECT
1734 select FB_CFB_COPYAREA 1739 select FB_CFB_COPYAREA
1735 select FB_CFB_IMAGEBLIT 1740 select FB_CFB_IMAGEBLIT
@@ -1873,7 +1878,8 @@ config FB_TMIO_ACCELL
1873 1878
1874config FB_S3C 1879config 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_FILLRECT 1883 select FB_CFB_FILLRECT
1878 select FB_CFB_COPYAREA 1884 select FB_CFB_COPYAREA
1879 select FB_CFB_IMAGEBLIT 1885 select FB_CFB_IMAGEBLIT
@@ -2055,7 +2061,8 @@ config FB_SH7760
2055 2061
2056config FB_DA8XX 2062config 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_FILLRECT 2066 select FB_CFB_FILLRECT
2060 select FB_CFB_COPYAREA 2067 select FB_CFB_COPYAREA
2061 select FB_CFB_IMAGEBLIT 2068 select FB_CFB_IMAGEBLIT
@@ -2172,7 +2179,7 @@ config FB_EP93XX
2172 2179
2173config FB_PRE_INIT_FB 2180config 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 by 2184 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
2213 help 2220 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_UNIGFX 2223config FB_PUV3_UNIGFX
2228 tristate "PKUnity v3 Unigfx framebuffer support" 2224 tristate "PKUnity v3 Unigfx framebuffer support"
2229 depends on FB && UNICORE32 && ARCH_PUV3 2225 depends on FB && UNICORE32 && ARCH_PUV3
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 655f2537cac1..7dc4861a93e6 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -131,7 +131,6 @@ obj-$(CONFIG_FB_VGA16) += vga16fb.o
131obj-$(CONFIG_FB_OF) += offb.o 131obj-$(CONFIG_FB_OF) += offb.o
132obj-$(CONFIG_FB_MX3) += mx3fb.o 132obj-$(CONFIG_FB_MX3) += mx3fb.o
133obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o 133obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
134obj-$(CONFIG_FB_MXS) += mxsfb.o
135obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o 134obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o
136obj-$(CONFIG_FB_SIMPLE) += simplefb.o 135obj-$(CONFIG_FB_SIMPLE) += simplefb.o
137 136
diff --git a/drivers/video/fbdev/amifb.c b/drivers/video/fbdev/amifb.c
index 758457026694..91ddc9602014 100644
--- a/drivers/video/fbdev/amifb.c
+++ b/drivers/video/fbdev/amifb.c
@@ -3554,10 +3554,8 @@ static int __init amifb_probe(struct platform_device *pdev)
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;
diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
index 13ba371e70aa..f940e8b66b85 100644
--- a/drivers/video/fbdev/arkfb.c
+++ b/drivers/video/fbdev/arkfb.c
@@ -954,10 +954,8 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
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);
diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c
index b986af2a8042..fc9dfb0a95af 100644
--- a/drivers/video/fbdev/atafb.c
+++ b/drivers/video/fbdev/atafb.c
@@ -77,29 +77,8 @@
77#define SWITCH_SND7 0x80 77#define SWITCH_SND7 0x80
78#define SWITCH_NONE 0x00 78#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
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index e67dfd94bf1d..5ff8e0320d95 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -673,7 +673,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
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)
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)
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)
1291 * We don't want to handle interrupts while the clock is 1289 * 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);
diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c
index 794434891291..8504e19437ff 100644
--- a/drivers/video/fbdev/aty/aty128fb.c
+++ b/drivers/video/fbdev/aty/aty128fb.c
@@ -2103,10 +2103,9 @@ static int aty128_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
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)
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;
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index b6fe103df145..72bcfbe42e49 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -3550,10 +3550,9 @@ static int atyfb_pci_probe(struct pci_dev *pdev,
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)
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,
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
diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
index e8594bbaea60..6f891d82eebe 100644
--- a/drivers/video/fbdev/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
@@ -2294,8 +2294,6 @@ static int radeonfb_pci_register(struct pci_dev *pdev,
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 }
diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c
index 3872ccef4cb2..26caffb02b7e 100644
--- a/drivers/video/fbdev/au1200fb.c
+++ b/drivers/video/fbdev/au1200fb.c
@@ -147,6 +147,7 @@ struct au1200_lcd_iodata_t {
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)
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)
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)
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)
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
diff --git a/drivers/video/fbdev/chipsfb.c b/drivers/video/fbdev/chipsfb.c
index ca549e1532e6..f4dc320dcafe 100644
--- a/drivers/video/fbdev/chipsfb.c
+++ b/drivers/video/fbdev/chipsfb.c
@@ -366,7 +366,6 @@ static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
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 }
diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c
index b3be06dd2908..e4ce5667b125 100644
--- a/drivers/video/fbdev/cirrusfb.c
+++ b/drivers/video/fbdev/cirrusfb.c
@@ -2093,7 +2093,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev,
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,
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;
diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c
index 7af8db28bb80..9a680ef3ffc3 100644
--- a/drivers/video/fbdev/controlfb.c
+++ b/drivers/video/fbdev/controlfb.c
@@ -182,7 +182,7 @@ int init_module(void)
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)
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)
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 */
diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c
index 2811c4afde01..e5ae33c1a8e8 100644
--- a/drivers/video/fbdev/core/fbcmap.c
+++ b/drivers/video/fbdev/core/fbcmap.c
@@ -285,11 +285,7 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
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:
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index a9c69ae30878..c9235a2f42f8 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -76,6 +76,7 @@
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 @@
87# define DPRINTK(fmt, args...) 88# define DPRINTK(fmt, args...)
88#endif 89#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;
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);
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)
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)
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)
900 * Low Level Operations 919 * 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,
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,
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)
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)
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);
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,
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,
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;
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)
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)
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)
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)
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)
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)
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)
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,
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,
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,
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,
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,
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,
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
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,
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)
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)
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,
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)
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,
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,
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)
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)
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)
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)
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)
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)
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,
3045} 3066}
3046 3067
3047#ifdef CONFIG_VT_HW_CONSOLE_BINDING 3068#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)
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#else 3079#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)
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)
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)
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_PRIMARY 3198#ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
@@ -3213,7 +3226,7 @@ static inline void fbcon_select_primary(struct fb_info *info)
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)
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)
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)
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,
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 console 3384 * The console `switch' structure for the frame buffer based console
3405 */ 3385 */
@@ -3431,10 +3411,6 @@ static const struct consw fb_con = {
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,
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,
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,
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,
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,
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)
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_TAKEOVER 3632#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)
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)
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)
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)
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();
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 21912a3ba32f..20dea853765f 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -25,7 +25,7 @@
25 * low-level frame buffer device 25 * 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 {
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);
225#define FBCON_ATTRIBUTE_REVERSE 2 225#define FBCON_ATTRIBUTE_REVERSE 2
226#define FBCON_ATTRIBUTE_BOLD 4 226#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
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index d1949c92be98..64dd732021d8 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -80,17 +80,6 @@ static void put_fb_info(struct fb_info *fb_info)
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 * Helpers 84 * Helpers
96 */ 85 */
@@ -943,16 +932,13 @@ EXPORT_SYMBOL(fb_pan_display);
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)
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)
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 and 984 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,
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,
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,
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,
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,
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,
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,
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)
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)
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)
1499 fb_deferred_io_open(info, inode, file); 1429 fb_deferred_io_open(info, inode, file);
1500#endif 1430#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)
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,
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 0xA0000 1556#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,
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,
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)
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 else 1659 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 else 1667 else
@@ -1744,44 +1669,44 @@ unlock_console:
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)
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 framebuffers 1733 * remove_conflicting_framebuffers - remove firmware-configured framebuffers
1834 * @a: memory range, users of which are to be removed 1734 * @a: memory range, users of which are to be removed
@@ -1842,7 +1742,6 @@ EXPORT_SYMBOL(unlink_framebuffer);
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,
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);
1959 * that the driver implements fb_open() and fb_release() to 1858 * 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 */
1962int 1861void
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);
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);
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)
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");
diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c
index 954ed99e80da..d54c88f88991 100644
--- a/drivers/video/fbdev/core/fbsysfs.c
+++ b/drivers/video/fbdev/core/fbsysfs.c
@@ -14,6 +14,7 @@
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,
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,
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,
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
diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c
index 0de12be823c0..3a2d9ff0aa42 100644
--- a/drivers/video/fbdev/cyber2000fb.c
+++ b/drivers/video/fbdev/cyber2000fb.c
@@ -58,7 +58,6 @@
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;
@@ -1639,10 +1638,6 @@ static void cyberpro_common_resume(struct cfb_info *cfb)
1639} 1638}
1640 1639
1641/* 1640/*
1642 * PCI specific support.
1643 */
1644#ifdef CONFIG_PCI
1645/*
1646 * We need to wake up the CyberPro, and make sure its in linear memory 1641 * 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 that 1642 * mode. Unfortunately, this is specific to the platform and card that
1648 * we are running on. 1643 * we are running on.
@@ -1858,7 +1853,6 @@ static struct pci_driver cyberpro_driver = {
1858 .resume = cyberpro_pci_resume, 1853 .resume = cyberpro_pci_resume,
1859 .id_table = cyberpro_pci_table 1854 .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 because 1858 * I don't think we can use the "module_init" stuff here because
diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
index 9ea817ac1d81..b1cf248f3291 100644
--- a/drivers/video/fbdev/da8xx-fb.c
+++ b/drivers/video/fbdev/da8xx-fb.c
@@ -1387,7 +1387,6 @@ static int fb_probe(struct platform_device *device)
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 }
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index 9f39f0c360e0..04a22663b4fb 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -169,6 +169,11 @@ static void efifb_show_boot_graphics(struct fb_info *info)
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)
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 }
diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c
index 3fcb33232ba3..b9f6a82a0495 100644
--- a/drivers/video/fbdev/gbefb.c
+++ b/drivers/video/fbdev/gbefb.c
@@ -39,9 +39,7 @@ struct gbefb_par {
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_MIPS 45#ifdef CONFIG_MIPS
@@ -51,10 +49,6 @@ struct gbefb_par {
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#endif 50#endif
53#endif 51#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 screen 54 * RAM we reserve for the frame buffer. This defines the maximum screen
@@ -279,7 +273,7 @@ static void gbe_turn_off(void)
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)
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)
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)
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)
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,
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 */
diff --git a/drivers/video/fbdev/grvga.c b/drivers/video/fbdev/grvga.c
index df5d546e57e9..d22e8b0c906d 100644
--- a/drivers/video/fbdev/grvga.c
+++ b/drivers/video/fbdev/grvga.c
@@ -336,10 +336,8 @@ static int grvga_probe(struct platform_device *dev)
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 *
diff --git a/drivers/video/fbdev/gxt4500.c b/drivers/video/fbdev/gxt4500.c
index 37527a10b954..c7502fd8f447 100644
--- a/drivers/video/fbdev/gxt4500.c
+++ b/drivers/video/fbdev/gxt4500.c
@@ -643,10 +643,9 @@ static int gxt4500_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
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;
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index 00f5bdcc6c6f..2dcb7c58b31e 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -762,10 +762,8 @@ static int hvfb_probe(struct hv_device *hdev,
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;
diff --git a/drivers/video/fbdev/i740fb.c b/drivers/video/fbdev/i740fb.c
index 24d3280a5b5f..347cf8babc3e 100644
--- a/drivers/video/fbdev/i740fb.c
+++ b/drivers/video/fbdev/i740fb.c
@@ -1006,10 +1006,8 @@ static int i740fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)
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);
diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c
index 35bba3c2036d..58b01c7d9056 100644
--- a/drivers/video/fbdev/imsttfb.c
+++ b/drivers/video/fbdev/imsttfb.c
@@ -1477,11 +1477,8 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
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
diff --git a/drivers/video/fbdev/imxfb.c b/drivers/video/fbdev/imxfb.c
index c4eb8661f751..b3286d1fa543 100644
--- a/drivers/video/fbdev/imxfb.c
+++ b/drivers/video/fbdev/imxfb.c
@@ -974,10 +974,9 @@ static int imxfb_probe(struct platform_device *pdev)
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:
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)
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));
diff --git a/drivers/video/fbdev/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c
index d7463a2a5d83..a76c61512c60 100644
--- a/drivers/video/fbdev/intelfb/intelfbdrv.c
+++ b/drivers/video/fbdev/intelfb/intelfbdrv.c
@@ -491,10 +491,9 @@ static int intelfb_pci_register(struct pci_dev *pdev,
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;
diff --git a/drivers/video/fbdev/jz4740_fb.c b/drivers/video/fbdev/jz4740_fb.c
index 145095655cc2..0b6fa25f6924 100644
--- a/drivers/video/fbdev/jz4740_fb.c
+++ b/drivers/video/fbdev/jz4740_fb.c
@@ -457,7 +457,6 @@ static int jzfb_alloc_devmem(struct jzfb *jzfb)
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)
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)
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;
diff --git a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
index c0c2600c2167..962c0171d271 100644
--- a/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
+++ b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
@@ -680,10 +680,8 @@ static int of_platform_mb862xx_probe(struct platform_device *ofdev)
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,
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 }
diff --git a/drivers/video/fbdev/mbx/mbxfb.c b/drivers/video/fbdev/mbx/mbxfb.c
index 6ded480a69b4..50935252b50b 100644
--- a/drivers/video/fbdev/mbx/mbxfb.c
+++ b/drivers/video/fbdev/mbx/mbxfb.c
@@ -899,10 +899,8 @@ static int mbxfb_probe(struct platform_device *dev)
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;
diff --git a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
index 87d943f15a12..17174cd7a5bb 100644
--- a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
+++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
@@ -433,7 +433,7 @@ static int mmphw_probe(struct platform_device *pdev)
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)
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;
diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c
deleted file mode 100644
index d8bebe35b410..000000000000
--- a/drivers/video/fbdev/mxsfb.c
+++ /dev/null
@@ -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");
diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c
index 5d3a444083f7..b770946a0920 100644
--- a/drivers/video/fbdev/neofb.c
+++ b/drivers/video/fbdev/neofb.c
@@ -2122,14 +2122,7 @@ static void neofb_remove(struct pci_dev *dev)
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);
diff --git a/drivers/video/fbdev/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c
index 406f972d2e42..90eca64e3144 100644
--- a/drivers/video/fbdev/omap/omapfb_main.c
+++ b/drivers/video/fbdev/omap/omapfb_main.c
@@ -1502,8 +1502,6 @@ static int planes_init(struct omapfb_device *fbdev)
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 }
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/Kconfig b/drivers/video/fbdev/omap2/omapfb/dss/Kconfig
index a34820e8ab97..36b97fee2d57 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/Kconfig
+++ b/drivers/video/fbdev/omap2/omapfb/dss/Kconfig
@@ -39,18 +39,6 @@ config FB_OMAP2_DSS_DPI
39 help 39 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_VENC 42config FB_OMAP2_DSS_VENC
55 bool "VENC support" 43 bool "VENC support"
56 default y 44 default y
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/Makefile b/drivers/video/fbdev/omap2/omapfb/dss/Makefile
index 7318d5260e8d..eb3689ae8d87 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/Makefile
+++ b/drivers/video/fbdev/omap2/omapfb/dss/Makefile
@@ -8,7 +8,6 @@ omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
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.o 9 dispc-compat.o display-sysfs.o
10omapdss-$(CONFIG_FB_OMAP2_DSS_DPI) += dpi.o 10omapdss-$(CONFIG_FB_OMAP2_DSS_DPI) += dpi.o
11omapdss-$(CONFIG_FB_OMAP2_DSS_RFBI) += rfbi.o
12omapdss-$(CONFIG_FB_OMAP2_DSS_VENC) += venc.o 11omapdss-$(CONFIG_FB_OMAP2_DSS_VENC) += venc.o
13omapdss-$(CONFIG_FB_OMAP2_DSS_SDI) += sdi.o 12omapdss-$(CONFIG_FB_OMAP2_DSS_SDI) += sdi.o
14omapdss-$(CONFIG_FB_OMAP2_DSS_DSI) += dsi.o 13omapdss-$(CONFIG_FB_OMAP2_DSS_DSI) += dsi.o
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/core.c b/drivers/video/fbdev/omap2/omapfb/dss/core.c
index f3ac5103b44a..37858be8be83 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/core.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/core.c
@@ -207,9 +207,6 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
207#ifdef CONFIG_FB_OMAP2_DSS_SDI 207#ifdef CONFIG_FB_OMAP2_DSS_SDI
208 sdi_init_platform_driver, 208 sdi_init_platform_driver,
209#endif 209#endif
210#ifdef CONFIG_FB_OMAP2_DSS_RFBI
211 rfbi_init_platform_driver,
212#endif
213#ifdef CONFIG_FB_OMAP2_DSS_VENC 210#ifdef CONFIG_FB_OMAP2_DSS_VENC
214 venc_init_platform_driver, 211 venc_init_platform_driver,
215#endif 212#endif
@@ -231,9 +228,6 @@ static void (*dss_output_drv_unreg_funcs[])(void) = {
231#ifdef CONFIG_FB_OMAP2_DSS_VENC 228#ifdef CONFIG_FB_OMAP2_DSS_VENC
232 venc_uninit_platform_driver, 229 venc_uninit_platform_driver,
233#endif 230#endif
234#ifdef CONFIG_FB_OMAP2_DSS_RFBI
235 rfbi_uninit_platform_driver,
236#endif
237#ifdef CONFIG_FB_OMAP2_DSS_SDI 231#ifdef CONFIG_FB_OMAP2_DSS_SDI
238 sdi_uninit_platform_driver, 232 sdi_uninit_platform_driver,
239#endif 233#endif
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss.h b/drivers/video/fbdev/omap2/omapfb/dss/dss.h
index 99bebc1983dc..a2269008590f 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dss.h
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dss.h
@@ -461,10 +461,6 @@ void hdmi4_uninit_platform_driver(void);
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_STATS 465#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)
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/rfbi.c b/drivers/video/fbdev/omap2/omapfb/dss/rfbi.c
deleted file mode 100644
index c6813b9b8a8d..000000000000
--- a/drivers/video/fbdev/omap2/omapfb/dss/rfbi.c
+++ /dev/null
@@ -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}
diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
index c7d936f9d383..858c2c011d19 100644
--- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
@@ -1881,12 +1881,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
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
diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c
index e1f8b5ae75b8..4a5db170ef59 100644
--- a/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c
@@ -49,8 +49,7 @@ static ssize_t store_rotate_type(struct device *dev,
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,
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,
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,
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,
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,
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,
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);
diff --git a/drivers/video/fbdev/platinumfb.c b/drivers/video/fbdev/platinumfb.c
index 76f299375a00..632b246ca35f 100644
--- a/drivers/video/fbdev/platinumfb.c
+++ b/drivers/video/fbdev/platinumfb.c
@@ -538,10 +538,9 @@ static int platinumfb_probe(struct platform_device* odev)
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) ||
diff --git a/drivers/video/fbdev/pmag-aa-fb.c b/drivers/video/fbdev/pmag-aa-fb.c
index ca7e9390d1e7..d1e78ce3a9c2 100644
--- a/drivers/video/fbdev/pmag-aa-fb.c
+++ b/drivers/video/fbdev/pmag-aa-fb.c
@@ -165,10 +165,8 @@ static int pmagaafb_probe(struct device *dev)
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);
diff --git a/drivers/video/fbdev/pmag-ba-fb.c b/drivers/video/fbdev/pmag-ba-fb.c
index 3b9249449ea6..56b912bb28de 100644
--- a/drivers/video/fbdev/pmag-ba-fb.c
+++ b/drivers/video/fbdev/pmag-ba-fb.c
@@ -150,10 +150,8 @@ static int pmagbafb_probe(struct device *dev)
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);
diff --git a/drivers/video/fbdev/pmagb-b-fb.c b/drivers/video/fbdev/pmagb-b-fb.c
index e58df36233c4..2822b2225924 100644
--- a/drivers/video/fbdev/pmagb-b-fb.c
+++ b/drivers/video/fbdev/pmagb-b-fb.c
@@ -257,10 +257,8 @@ static int pmagbbfb_probe(struct device *dev)
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);
diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c
index 73d92d8a85cc..7ff4b6b84282 100644
--- a/drivers/video/fbdev/pvr2fb.c
+++ b/drivers/video/fbdev/pvr2fb.c
@@ -140,7 +140,7 @@ static struct pvr2fb_par {
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;
194static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS; 194static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS;
195#endif 195#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 with 199 * Broadcast video modes (PAL and NTSC). I'm unfamiliar with
@@ -354,6 +321,36 @@ static int pvr2fb_setcolreg(unsigned int regno, unsigned int red,
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)
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)
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_DMA 642#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:
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_init 753 * pvr2fb_common_init
747 * 754 *
@@ -760,7 +767,7 @@ out_unmap:
760 * in for flexibility anyways. Who knows, maybe someone has tv-out on a 767 * 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)
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)
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_QUEUES 835#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:
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)
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)
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)
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 maps 1003 * inverse Use inverse color maps
@@ -1047,9 +1037,9 @@ static int __init pvr2fb_setup(char *options)
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)
1082#endif 1072#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
diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c
index cc242ba057d3..ca593a3e41d7 100644
--- a/drivers/video/fbdev/riva/fbdev.c
+++ b/drivers/video/fbdev/riva/fbdev.c
@@ -1902,7 +1902,6 @@ static int rivafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
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 }
diff --git a/drivers/video/fbdev/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c
index 288300035164..ba04d7a67829 100644
--- a/drivers/video/fbdev/s3c-fb.c
+++ b/drivers/video/fbdev/s3c-fb.c
@@ -284,7 +284,7 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
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,
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)
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)
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)
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,
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;
diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c
index d63f23e26f7d..be16c349c10f 100644
--- a/drivers/video/fbdev/s3fb.c
+++ b/drivers/video/fbdev/s3fb.c
@@ -1128,10 +1128,8 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
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);
diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c
index 15ae50063296..f7f8dee044b1 100644
--- a/drivers/video/fbdev/sa1100fb.c
+++ b/drivers/video/fbdev/sa1100fb.c
@@ -974,35 +974,10 @@ static void sa1100fb_task(struct work_struct *w)
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/*
diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c
index 47b78f0138c3..512789f5f884 100644
--- a/drivers/video/fbdev/savage/savagefb_driver.c
+++ b/drivers/video/fbdev/savage/savagefb_driver.c
@@ -2333,14 +2333,7 @@ static void savagefb_remove(struct pci_dev *dev)
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_I2C 2338#ifdef CONFIG_FB_SAVAGE_I2C
2346 savagefb_delete_i2c_busses(info); 2339 savagefb_delete_i2c_busses(info);
diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c
index dc46be38c970..ac0bcac9a865 100644
--- a/drivers/video/fbdev/sh_mobile_lcdcfb.c
+++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c
@@ -15,6 +15,7 @@
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 {
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)
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 helpers 541 * Format helpers
622 */ 542 */
@@ -1644,10 +1564,8 @@ sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl)
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)
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)
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,
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 = {
2319 * Framebuffer notifier 2226 * 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/exit 2230 * Probe/remove and driver init/exit
2355 */ 2231 */
@@ -2377,8 +2253,6 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
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)
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)
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);
diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.h b/drivers/video/fbdev/sh_mobile_lcdcfb.h
index b8e47a8bd8ab..589400372098 100644
--- a/drivers/video/fbdev/sh_mobile_lcdcfb.h
+++ b/drivers/video/fbdev/sh_mobile_lcdcfb.h
@@ -87,11 +87,6 @@ struct sh_mobile_lcdc_chan {
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;
diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c
index 5a326163847b..6edb4492e675 100644
--- a/drivers/video/fbdev/sm501fb.c
+++ b/drivers/video/fbdev/sm501fb.c
@@ -1865,10 +1865,8 @@ static int sm501fb_probe_one(struct sm501fb_info *info,
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;
diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index f1dcc6766d1e..7b1b0d8d27a7 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1538,7 +1538,6 @@ static int smtcfb_pci_probe(struct pci_dev *pdev,
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 }
diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index 8cd7892a0b0d..0e0f5bbfc5ef 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1650,10 +1650,8 @@ static int ufx_usb_probe(struct usb_interface *interface,
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;
diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index 021b727e8b5c..b674948e3bb8 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -555,10 +555,8 @@ static int ssd1307fb_probe(struct i2c_client *client,
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;
diff --git a/drivers/video/fbdev/sunxvr1000.c b/drivers/video/fbdev/sunxvr1000.c
index 8fe37c0ef2f5..784c9bd5d502 100644
--- a/drivers/video/fbdev/sunxvr1000.c
+++ b/drivers/video/fbdev/sunxvr1000.c
@@ -121,7 +121,6 @@ static int gfb_probe(struct platform_device *op)
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 }
diff --git a/drivers/video/fbdev/sunxvr2500.c b/drivers/video/fbdev/sunxvr2500.c
index 544465ba1dc0..31683e5a8b79 100644
--- a/drivers/video/fbdev/sunxvr2500.c
+++ b/drivers/video/fbdev/sunxvr2500.c
@@ -132,7 +132,6 @@ static int s3d_pci_register(struct pci_dev *pdev,
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 }
diff --git a/drivers/video/fbdev/sunxvr500.c b/drivers/video/fbdev/sunxvr500.c
index bc595937df08..d392976126a6 100644
--- a/drivers/video/fbdev/sunxvr500.c
+++ b/drivers/video/fbdev/sunxvr500.c
@@ -272,7 +272,6 @@ static int e3d_pci_register(struct pci_dev *pdev,
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 }
diff --git a/drivers/video/fbdev/tgafb.c b/drivers/video/fbdev/tgafb.c
index 65ba9921506e..286b2371c7dd 100644
--- a/drivers/video/fbdev/tgafb.c
+++ b/drivers/video/fbdev/tgafb.c
@@ -1416,10 +1416,8 @@ static int tgafb_register(struct device *dev)
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);
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
index 00b99363e528..c328e8265cb1 100644
--- a/drivers/video/fbdev/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
@@ -1686,10 +1686,8 @@ static int dlfb_usb_probe(struct usb_interface *intf,
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;
diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c
index 8db5de13e2b7..f815f98190bc 100644
--- a/drivers/video/fbdev/via/viafbdev.c
+++ b/drivers/video/fbdev/via/viafbdev.c
@@ -1742,10 +1742,8 @@ int via_fb_pci_probe(struct viafb_dev *vdev)
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)
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 }
diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
index 5cac871db3ee..c339a8fbad81 100644
--- a/drivers/video/fbdev/vt8623fb.c
+++ b/drivers/video/fbdev/vt8623fb.c
@@ -669,10 +669,8 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
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);
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index ed798e114663..24d4c16e3ae0 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -168,9 +168,6 @@ extern void vc_SAK(struct work_struct *work);
168 168
169#define CUR_DEFAULT CUR_UNDERLINE 169#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 */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index f52ef0ad6781..303771264644 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -126,39 +126,15 @@ struct fb_cursor_user {
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 0x01 128#define FB_EVENT_MODE_CHANGE 0x01
129/* The display on this fb_info is being suspended, no access to the 129
130 * framebuffer is allowed any more after that call returns 130#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 0x05 132#define FB_EVENT_FB_REGISTERED 0x05
141/* A driver unregistered itself */
142#define FB_EVENT_FB_UNREGISTERED 0x06 133#define FB_EVENT_FB_UNREGISTERED 0x06
143/* CONSOLE-SPECIFIC: get console to framebuffer mapping */ 134#endif
144#define FB_EVENT_GET_CONSOLE_MAP 0x07 135
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 0x09 137#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 0x10 139#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,
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;
660 for (i = 0; i < FB_MAX; i++) \ 636 for (i = 0; i < FB_MAX; i++) \
661 if (!registered_fb[i]) {} else 637 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{
diff --git a/include/linux/fbcon.h b/include/linux/fbcon.h
index f68a7db14165..ff5596dd30f8 100644
--- a/include/linux/fbcon.h
+++ b/include/linux/fbcon.h
@@ -4,9 +4,39 @@
4#ifdef CONFIG_FRAMEBUFFER_CONSOLE 4#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#else 22#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#endif 40#endif
11 41
12#endif /* _LINUX_FBCON_H */ 42#endif /* _LINUX_FBCON_H */
diff --git a/include/video/omapfb_dss.h b/include/video/omapfb_dss.h
index a167b839eccb..e8eaac2cb7b8 100644
--- a/include/video/omapfb_dss.h
+++ b/include/video/omapfb_dss.h
@@ -114,11 +114,6 @@ enum omap_dss_trans_key_type {
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 {
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 {
@@ -641,11 +615,6 @@ struct omap_dss_device {
641 } dpi; 615 } dpi;
642 616
643 struct { 617 struct {
644 u8 channel;
645 u8 data_lines;
646 } rfbi;
647
648 struct {
649 u8 datapairs; 618 u8 datapairs;
650 } sdi; 619 } sdi;
651 620
@@ -668,7 +637,6 @@ struct omap_dss_device {
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;