diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-09 12:55:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-09 12:55:45 -0400 |
commit | 2d41ef5432b76ae90dc0db93026f1d981f874ec4 (patch) | |
tree | dc97253d9328e8652614bfe8026748dd53c6561a | |
parent | ed63b9c873601ca113da5c7b1745e3946493e9f3 (diff) | |
parent | 732146a3f1dc78ebb0d3c4b1f4dc6ea33cc2c58f (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
...
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 | } |
896 | EXPORT_SYMBOL(fbtft_unregister_framebuffer); | 898 | EXPORT_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 @@ | |||
1 | TODO: | 1 | TODO: |
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) | |||
3834 | EXPORT_SYMBOL(con_is_bound); | 3836 | EXPORT_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 | */ | ||
3844 | bool con_is_visible(const struct vc_data *vc) | ||
3845 | { | ||
3846 | WARN_CONSOLE_UNLOCKED(); | ||
3847 | |||
3848 | return *vc->vc_display_fg == vc; | ||
3849 | } | ||
3850 | EXPORT_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 | ||
35 | void dummycon_register_output_notifier(struct notifier_block *nb) | 35 | void 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 | ||
43 | void dummycon_unregister_output_notifier(struct notifier_block *nb) | 45 | void 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 | ||
48 | static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) | 52 | static 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 | ||
333 | config FB_IMX | 333 | config 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 | ||
671 | config FB_GBE | 672 | config 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 | ||
809 | config FB_PVR2 | 811 | config 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 | ||
857 | config FB_ATMEL | 860 | config 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 | ||
1730 | config FB_PXA168 | 1734 | config 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 | ||
1874 | config FB_S3C | 1879 | config 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 | ||
2056 | config FB_DA8XX | 2062 | config 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 | ||
2173 | config FB_PRE_INIT_FB | 2180 | config 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 | ||
2216 | config 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 | |||
2227 | config FB_PUV3_UNIGFX | 2223 | config 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 | |||
131 | obj-$(CONFIG_FB_OF) += offb.o | 131 | obj-$(CONFIG_FB_OF) += offb.o |
132 | obj-$(CONFIG_FB_MX3) += mx3fb.o | 132 | obj-$(CONFIG_FB_MX3) += mx3fb.o |
133 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o | 133 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o |
134 | obj-$(CONFIG_FB_MXS) += mxsfb.o | ||
135 | obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o | 134 | obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o |
136 | obj-$(CONFIG_FB_SIMPLE) += simplefb.o | 135 | obj-$(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 | |||
87 | static int atafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); | ||
88 | static int atafb_set_par(struct fb_info *info); | ||
89 | static int atafb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, | ||
90 | unsigned int blue, unsigned int transp, | ||
91 | struct fb_info *info); | ||
92 | static int atafb_blank(int blank, struct fb_info *info); | ||
93 | static int atafb_pan_display(struct fb_var_screeninfo *var, | ||
94 | struct fb_info *info); | ||
95 | static void atafb_fillrect(struct fb_info *info, | ||
96 | const struct fb_fillrect *rect); | ||
97 | static void atafb_copyarea(struct fb_info *info, | ||
98 | const struct fb_copyarea *region); | ||
99 | static void atafb_imageblit(struct fb_info *info, const struct fb_image *image); | ||
100 | static int atafb_ioctl(struct fb_info *info, unsigned int cmd, | ||
101 | unsigned long arg); | ||
102 | |||
103 | 82 | ||
104 | static int default_par; /* default resolution (0=none) */ | 83 | static 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 | |||
2358 | static 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 | |||
2402 | static 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 | |||
2417 | static void aty128_set_suspend(struct aty128fb_par *par, int suspend) | 2352 | static 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 { | |||
147 | struct au1200fb_device { | 147 | struct 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 | ||
1241 | static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) | 1240 | static 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); |
295 | out: | 291 | out: |
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 | |||
90 | enum { | 110 | enum { |
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 | ||
96 | static struct display fb_display[MAX_NR_CONSOLES]; | 116 | static struct fbcon_display fb_display[MAX_NR_CONSOLES]; |
97 | 117 | ||
98 | static signed char con2fb_map[MAX_NR_CONSOLES]; | 118 | static signed char con2fb_map[MAX_NR_CONSOLES]; |
99 | static signed char con2fb_map_boot[MAX_NR_CONSOLES]; | 119 | static signed char con2fb_map_boot[MAX_NR_CONSOLES]; |
@@ -112,7 +132,6 @@ static int softback_lines; | |||
112 | static int first_fb_vc; | 132 | static int first_fb_vc; |
113 | static int last_fb_vc = MAX_NR_CONSOLES - 1; | 133 | static int last_fb_vc = MAX_NR_CONSOLES - 1; |
114 | static int fbcon_is_default = 1; | 134 | static int fbcon_is_default = 1; |
115 | static int fbcon_has_exited; | ||
116 | static int primary_device = -1; | 135 | static int primary_device = -1; |
117 | static int fbcon_has_console_bind; | 136 | static int fbcon_has_console_bind; |
118 | 137 | ||
@@ -185,11 +204,11 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count); | |||
185 | static __inline__ void ywrap_down(struct vc_data *vc, int count); | 204 | static __inline__ void ywrap_down(struct vc_data *vc, int count); |
186 | static __inline__ void ypan_up(struct vc_data *vc, int count); | 205 | static __inline__ void ypan_up(struct vc_data *vc, int count); |
187 | static __inline__ void ypan_down(struct vc_data *vc, int count); | 206 | static __inline__ void ypan_down(struct vc_data *vc, int count); |
188 | static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, | 207 | static 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); |
190 | static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, | 209 | static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, |
191 | int unit); | 210 | int unit); |
192 | static void fbcon_redraw_move(struct vc_data *vc, struct display *p, | 211 | static 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); |
194 | static void fbcon_modechanged(struct fb_info *info); | 213 | static void fbcon_modechanged(struct fb_info *info); |
195 | static void fbcon_set_all_vcs(struct fb_info *info); | 214 | static 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 */ |
903 | static int var_to_display(struct display *disp, | 922 | static 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 | ||
927 | static void display_to_var(struct fb_var_screeninfo *var, | 946 | static 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, | |||
946 | static const char *fbcon_startup(void) | 965 | static 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 | ||
1057 | static void fbcon_init(struct vc_data *vc, int init) | 1075 | static 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 | ||
1206 | static void fbcon_free_font(struct display *p, bool freefont) | 1228 | static 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 | ||
1216 | static void fbcon_deinit(struct vc_data *vc) | 1238 | static 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; | |||
1388 | static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, | 1410 | static 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) | |||
1494 | static __inline__ void ypan_up(struct vc_data *vc, int count) | 1516 | static __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) | |||
1542 | static __inline__ void ypan_down(struct vc_data *vc, int count) | 1564 | static __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 | ||
1590 | static void fbcon_redraw_softback(struct vc_data *vc, struct display *p, | 1612 | static 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 | ||
1683 | static void fbcon_redraw_move(struct vc_data *vc, struct display *p, | 1705 | static 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 | ||
1717 | static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info, | 1739 | static 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 | ||
1767 | static void fbcon_redraw(struct vc_data *vc, struct display *p, | 1789 | static 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 | ||
2074 | static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, | 2096 | static 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 | ||
2116 | static void updatescrollmode(struct display *p, | 2138 | static 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) | |||
2348 | static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, | 2370 | static 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 = ␣ | ||
2369 | fb_notifier_call_chain(FB_EVENT_CONBLANK, &event); | ||
2370 | unlock_fb_info(info); | ||
2371 | } | 2383 | } |
2372 | 2384 | ||
2373 | static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) | 2385 | static 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 | ||
2602 | static int fbcon_copy_font(struct vc_data *vc, int con) | 2613 | static 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 | ||
2921 | static void fbcon_suspended(struct fb_info *info) | 2932 | void 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 | ||
2934 | static void fbcon_resumed(struct fb_info *info) | 2945 | void 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 | ||
3021 | static int fbcon_mode_deleted(struct fb_info *info, | 3032 | |
3022 | struct fb_videomode *mode) | 3033 | void 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 | } | ||
3040 | EXPORT_SYMBOL(fbcon_update_vcs); | ||
3041 | |||
3042 | int 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 |
3048 | static int fbcon_unbind(void) | 3069 | static 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 |
3061 | static inline int fbcon_unbind(void) | 3080 | static 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 */ |
3068 | static int fbcon_fb_unbind(int idx) | 3084 | void 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 */ |
3120 | static int fbcon_fb_unregistered(struct fb_info *info) | 3135 | void 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 */ | 3173 | void fbcon_remap_all(struct fb_info *info) |
3161 | static 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 */ |
3216 | static int fbcon_fb_registered(struct fb_info *info) | 3229 | int 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 | ||
3250 | static void fbcon_fb_blanked(struct fb_info *info, int blank) | 3263 | void 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 | ||
3272 | static void fbcon_new_modelist(struct fb_info *info) | 3285 | void 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 | ||
3293 | static void fbcon_get_requirement(struct fb_info *info, | 3306 | void 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 | ||
3329 | static int fbcon_event_notify(struct notifier_block *self, | 3342 | int 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 | } |
3399 | done: | 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 | ||
3367 | int 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 | ||
3434 | static struct notifier_block fbcon_event_notifier = { | ||
3435 | .notifier_call = fbcon_event_notify, | ||
3436 | }; | ||
3437 | |||
3438 | static ssize_t store_rotate(struct device *device, | 3414 | static 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 | ||
3725 | void __init fb_console_init(void) | 3681 | void __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) | |||
3763 | void __exit fb_console_exit(void) | 3718 | void __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 | ||
28 | struct display { | 28 | struct 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 | ||
228 | static inline int real_y(struct display *p, int ypos) | 228 | static 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 | ||
83 | int 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 | } | ||
92 | EXPORT_SYMBOL(lock_fb_info); | ||
93 | |||
94 | /* | 83 | /* |
95 | * Helpers | 84 | * Helpers |
96 | */ | 85 | */ |
@@ -943,16 +932,13 @@ EXPORT_SYMBOL(fb_pan_display); | |||
943 | static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, | 932 | static 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 = ∩︀ | ||
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 | } |
1075 | EXPORT_SYMBOL(fb_set_var); | 1055 | EXPORT_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 |
1501 | out: | 1431 | out: |
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 | ||
1624 | static int do_unregister_framebuffer(struct fb_info *fb_info); | 1554 | static void do_unregister_framebuffer(struct fb_info *fb_info); |
1625 | 1555 | ||
1626 | #define VGA_FB_PHYS 0xA0000 | 1556 | #define VGA_FB_PHYS 0xA0000 |
1627 | static int do_remove_conflicting_framebuffers(struct apertures_struct *a, | 1557 | static 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 | ||
1655 | static bool lockless_register_fb; | 1581 | static bool lockless_register_fb; |
@@ -1660,17 +1586,14 @@ MODULE_PARM_DESC(lockless_register_fb, | |||
1660 | static int do_register_framebuffer(struct fb_info *fb_info) | 1586 | static 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); |
1739 | unlock_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 | ||
1747 | static int unbind_console(struct fb_info *fb_info) | 1672 | static 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 | ||
1770 | static int __unlink_framebuffer(struct fb_info *fb_info); | 1686 | void unlink_framebuffer(struct fb_info *fb_info) |
1771 | |||
1772 | static 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 | } | ||
1705 | EXPORT_SYMBOL(unlink_framebuffer); | ||
1706 | |||
1707 | static 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 | ||
1802 | static 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 | |||
1818 | int 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 | } | ||
1830 | EXPORT_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); | |||
1842 | int remove_conflicting_framebuffers(struct apertures_struct *a, | 1742 | int 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(®istration_lock); | 1757 | mutex_lock(®istration_lock); |
1859 | ret = do_remove_conflicting_framebuffers(a, name, primary); | 1758 | do_remove_conflicting_framebuffers(a, name, primary); |
1860 | mutex_unlock(®istration_lock); | 1759 | mutex_unlock(®istration_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 | } |
1867 | EXPORT_SYMBOL(remove_conflicting_framebuffers); | 1766 | EXPORT_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 | */ |
1962 | int | 1861 | void |
1963 | unregister_framebuffer(struct fb_info *fb_info) | 1862 | unregister_framebuffer(struct fb_info *fb_info) |
1964 | { | 1863 | { |
1965 | int ret; | ||
1966 | |||
1967 | mutex_lock(®istration_lock); | 1864 | mutex_lock(®istration_lock); |
1968 | ret = do_unregister_framebuffer(fb_info); | 1865 | do_unregister_framebuffer(fb_info); |
1969 | mutex_unlock(®istration_lock); | 1866 | mutex_unlock(®istration_lock); |
1970 | |||
1971 | return ret; | ||
1972 | } | 1867 | } |
1973 | EXPORT_SYMBOL(unregister_framebuffer); | 1868 | EXPORT_SYMBOL(unregister_framebuffer); |
1974 | 1869 | ||
@@ -1983,15 +1878,14 @@ EXPORT_SYMBOL(unregister_framebuffer); | |||
1983 | */ | 1878 | */ |
1984 | void fb_set_suspend(struct fb_info *info, int state) | 1879 | void 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 | } |
1997 | EXPORT_SYMBOL(fb_set_suspend); | 1891 | EXPORT_SYMBOL(fb_set_suspend); |
@@ -2059,7 +1953,6 @@ subsys_initcall(fbmem_init); | |||
2059 | 1953 | ||
2060 | int fb_new_modelist(struct fb_info *info) | 1954 | int 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 | ||
2092 | MODULE_LICENSE("GPL"); | 1983 | MODULE_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 @@ | |||
58 | struct cfb_info { | 58 | struct 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); |
1048 | failed_platform_init: | 1047 | failed_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); |
1051 | failed_map: | 1050 | failed_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 | |||
147 | enum mxsfb_devtype { | ||
148 | MXSFB_V3, | ||
149 | MXSFB_V4, | ||
150 | }; | ||
151 | |||
152 | /* CPU dependent register offsets */ | ||
153 | struct 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 | |||
163 | struct 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 | |||
182 | static 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 */ | ||
204 | static 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 | |||
210 | static 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 | |||
216 | static 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 | |||
234 | static 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 | |||
252 | static 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 | |||
259 | static 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 | |||
309 | static 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 | |||
315 | static 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 | |||
321 | static 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 | |||
358 | static 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 | |||
400 | static 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 | |||
526 | static 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 | |||
566 | static 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 | |||
587 | static 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 | |||
609 | static 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 | |||
621 | static 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 | |||
716 | err: | ||
717 | if (ret) | ||
718 | mxsfb_disable_axi_clk(host); | ||
719 | |||
720 | return ret; | ||
721 | } | ||
722 | |||
723 | static 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 | |||
797 | put_display_node: | ||
798 | of_node_put(display_np); | ||
799 | return ret; | ||
800 | } | ||
801 | |||
802 | static 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 | |||
846 | static 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 | |||
855 | static 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 | }; | ||
866 | MODULE_DEVICE_TABLE(platform, mxsfb_devtype); | ||
867 | |||
868 | static 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 | }; | ||
873 | MODULE_DEVICE_TABLE(of, mxsfb_dt_ids); | ||
874 | |||
875 | static 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 | |||
972 | fb_destroy: | ||
973 | if (host->enabled) | ||
974 | clk_disable_unprepare(host->clk); | ||
975 | fb_release: | ||
976 | framebuffer_release(fb_info); | ||
977 | |||
978 | return ret; | ||
979 | } | ||
980 | |||
981 | static 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 | |||
997 | static 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 | |||
1013 | static 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 | |||
1024 | module_platform_driver(mxsfb_driver); | ||
1025 | |||
1026 | MODULE_DESCRIPTION("Freescale mxs framebuffer driver"); | ||
1027 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | ||
1028 | MODULE_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 | ||
42 | config 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 | |||
54 | config FB_OMAP2_DSS_VENC | 42 | config 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 \ | |||
8 | omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \ | 8 | omapdss-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 |
10 | omapdss-$(CONFIG_FB_OMAP2_DSS_DPI) += dpi.o | 10 | omapdss-$(CONFIG_FB_OMAP2_DSS_DPI) += dpi.o |
11 | omapdss-$(CONFIG_FB_OMAP2_DSS_RFBI) += rfbi.o | ||
12 | omapdss-$(CONFIG_FB_OMAP2_DSS_VENC) += venc.o | 11 | omapdss-$(CONFIG_FB_OMAP2_DSS_VENC) += venc.o |
13 | omapdss-$(CONFIG_FB_OMAP2_DSS_SDI) += sdi.o | 12 | omapdss-$(CONFIG_FB_OMAP2_DSS_SDI) += sdi.o |
14 | omapdss-$(CONFIG_FB_OMAP2_DSS_DSI) += dsi.o | 13 | omapdss-$(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); | |||
461 | int hdmi5_init_platform_driver(void) __init; | 461 | int hdmi5_init_platform_driver(void) __init; |
462 | void hdmi5_uninit_platform_driver(void); | 462 | void hdmi5_uninit_platform_driver(void); |
463 | 463 | ||
464 | /* RFBI */ | ||
465 | int rfbi_init_platform_driver(void) __init; | ||
466 | void 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 |
470 | static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr) | 466 | static 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 | |||
33 | struct 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 | |||
62 | enum 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 | |||
69 | enum 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 | |||
76 | enum 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 | |||
83 | static int rfbi_convert_timings(struct rfbi_timings *t); | ||
84 | static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); | ||
85 | |||
86 | static 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 | |||
113 | static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) | ||
114 | { | ||
115 | __raw_writel(val, rfbi.base + idx.idx); | ||
116 | } | ||
117 | |||
118 | static inline u32 rfbi_read_reg(const struct rfbi_reg idx) | ||
119 | { | ||
120 | return __raw_readl(rfbi.base + idx.idx); | ||
121 | } | ||
122 | |||
123 | static 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 | |||
134 | static 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 | |||
144 | static void rfbi_bus_lock(void) | ||
145 | { | ||
146 | down(&rfbi.bus_lock); | ||
147 | } | ||
148 | |||
149 | static void rfbi_bus_unlock(void) | ||
150 | { | ||
151 | up(&rfbi.bus_lock); | ||
152 | } | ||
153 | |||
154 | static 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 | |||
181 | static 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 | |||
212 | static 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 | |||
240 | static 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 | |||
294 | static 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 | |||
329 | static 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 */ | ||
345 | static 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 | ||
369 | static void rfbi_print_timings(void) {} | ||
370 | #endif | ||
371 | |||
372 | |||
373 | |||
374 | |||
375 | static u32 extif_clk_period; | ||
376 | |||
377 | static 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 | |||
383 | static 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 | |||
412 | static 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 | |||
431 | static 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 | |||
453 | static 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 | |||
466 | static 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 | |||
472 | static 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 */ | ||
561 | static 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 */ | ||
602 | static 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 | |||
623 | static 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 | |||
755 | static 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 | |||
761 | static 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 | |||
767 | static 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 | |||
773 | static void rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size) | ||
774 | { | ||
775 | rfbi.pixel_size = pixel_size; | ||
776 | } | ||
777 | |||
778 | static void rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) | ||
779 | { | ||
780 | rfbi.data_lines = data_lines; | ||
781 | } | ||
782 | |||
783 | static void rfbi_set_interface_timings(struct omap_dss_device *dssdev, | ||
784 | struct rfbi_timings *timings) | ||
785 | { | ||
786 | rfbi.intf_timings = *timings; | ||
787 | } | ||
788 | |||
789 | static 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 | |||
829 | static 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 | |||
867 | static 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; | ||
896 | err1: | ||
897 | rfbi_runtime_put(); | ||
898 | return r; | ||
899 | } | ||
900 | |||
901 | static 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 | |||
911 | static int rfbi_init_display(struct omap_dss_device *dssdev) | ||
912 | { | ||
913 | rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev; | ||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | static 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 | |||
931 | static 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 */ | ||
939 | static 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 | |||
994 | err_runtime_get: | ||
995 | pm_runtime_disable(&pdev->dev); | ||
996 | return r; | ||
997 | } | ||
998 | |||
999 | static 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 | |||
1010 | static const struct component_ops rfbi_component_ops = { | ||
1011 | .bind = rfbi_bind, | ||
1012 | .unbind = rfbi_unbind, | ||
1013 | }; | ||
1014 | |||
1015 | static int rfbi_probe(struct platform_device *pdev) | ||
1016 | { | ||
1017 | return component_add(&pdev->dev, &rfbi_component_ops); | ||
1018 | } | ||
1019 | |||
1020 | static int rfbi_remove(struct platform_device *pdev) | ||
1021 | { | ||
1022 | component_del(&pdev->dev, &rfbi_component_ops); | ||
1023 | return 0; | ||
1024 | } | ||
1025 | |||
1026 | static int rfbi_runtime_suspend(struct device *dev) | ||
1027 | { | ||
1028 | dispc_runtime_put(); | ||
1029 | |||
1030 | return 0; | ||
1031 | } | ||
1032 | |||
1033 | static 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 | |||
1044 | static const struct dev_pm_ops rfbi_pm_ops = { | ||
1045 | .runtime_suspend = rfbi_runtime_suspend, | ||
1046 | .runtime_resume = rfbi_runtime_resume, | ||
1047 | }; | ||
1048 | |||
1049 | static 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 | |||
1059 | int __init rfbi_init_platform_driver(void) | ||
1060 | { | ||
1061 | return platform_driver_register(&omap_rfbihw_driver); | ||
1062 | } | ||
1063 | |||
1064 | void 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; | |||
194 | static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS; | 194 | static unsigned int pvr2dma = ONCHIP_NR_DMA_CHANNELS; |
195 | #endif | 195 | #endif |
196 | 196 | ||
197 | static int pvr2fb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, unsigned int blue, | ||
198 | unsigned int transp, struct fb_info *info); | ||
199 | static int pvr2fb_blank(int blank, struct fb_info *info); | ||
200 | static unsigned long get_line_length(int xres_virtual, int bpp); | ||
201 | static void set_color_bitfields(struct fb_var_screeninfo *var); | ||
202 | static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); | ||
203 | static int pvr2fb_set_par(struct fb_info *info); | ||
204 | static void pvr2_update_display(struct fb_info *info); | ||
205 | static void pvr2_init_display(struct fb_info *info); | ||
206 | static void pvr2_do_blank(void); | ||
207 | static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id); | ||
208 | static int pvr2_init_cable(void); | ||
209 | static int pvr2_get_param(const struct pvr2_params *p, const char *s, | ||
210 | int val, int size); | ||
211 | #ifdef CONFIG_PVR2_DMA | ||
212 | static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, | ||
213 | size_t count, loff_t *ppos); | ||
214 | #endif | ||
215 | |||
216 | static 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 | |||
230 | static struct fb_videomode pvr2_modedb[] = { | 197 | static 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 | |||
333 | static 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 | |||
357 | static int pvr2fb_set_par(struct fb_info *info) | 354 | static 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 | ||
626 | static irqreturn_t pvr2fb_interrupt(int irq, void *dev_id) | 623 | static 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 | |||
654 | static 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 |
676 | static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, | 643 | static 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 | ||
712 | static 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 | ||
727 | static 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 | |||
740 | static 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 | */ |
763 | static int pvr2fb_common_init(void) | 770 | static 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 | ||
904 | static void __exit pvr2fb_dc_exit(void) | 911 | static 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 | ||
988 | static void __exit pvr2fb_pci_exit(void) | 995 | static 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 | ||
994 | static 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 | */ |
975 | static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi) | 975 | static 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 | ||
537 | static bool | ||
538 | sh_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 | |||
556 | static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var, | 537 | static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var, |
557 | struct fb_info *info); | 538 | struct fb_info *info); |
558 | 539 | ||
559 | static 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 */ | ||
2323 | static 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; |
2778 | err1: | 2646 | err1: |
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 | ||
171 | static inline bool con_is_visible(const struct vc_data *vc) | 171 | bool 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 */ |
635 | extern int register_framebuffer(struct fb_info *fb_info); | 611 | extern int register_framebuffer(struct fb_info *fb_info); |
636 | extern int unregister_framebuffer(struct fb_info *fb_info); | 612 | extern void unregister_framebuffer(struct fb_info *fb_info); |
637 | extern int unlink_framebuffer(struct fb_info *fb_info); | 613 | extern void unlink_framebuffer(struct fb_info *fb_info); |
638 | extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, int res_id, | 614 | extern int remove_conflicting_pci_framebuffers(struct pci_dev *pdev, int res_id, |
639 | const char *name); | 615 | const char *name); |
640 | extern int remove_conflicting_framebuffers(struct apertures_struct *a, | 616 | extern 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 | ||
663 | extern int lock_fb_info(struct fb_info *info); | 639 | static inline void lock_fb_info(struct fb_info *info) |
640 | { | ||
641 | mutex_lock(&info->lock); | ||
642 | } | ||
664 | 643 | ||
665 | static inline void unlock_fb_info(struct fb_info *info) | 644 | static 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 |
5 | void __init fb_console_init(void); | 5 | void __init fb_console_init(void); |
6 | void __exit fb_console_exit(void); | 6 | void __exit fb_console_exit(void); |
7 | int fbcon_fb_registered(struct fb_info *info); | ||
8 | void fbcon_fb_unregistered(struct fb_info *info); | ||
9 | void fbcon_fb_unbind(struct fb_info *info); | ||
10 | void fbcon_suspended(struct fb_info *info); | ||
11 | void fbcon_resumed(struct fb_info *info); | ||
12 | int fbcon_mode_deleted(struct fb_info *info, | ||
13 | struct fb_videomode *mode); | ||
14 | void fbcon_new_modelist(struct fb_info *info); | ||
15 | void fbcon_get_requirement(struct fb_info *info, | ||
16 | struct fb_blit_caps *caps); | ||
17 | void fbcon_fb_blanked(struct fb_info *info, int blank); | ||
18 | void fbcon_update_vcs(struct fb_info *info, bool all); | ||
19 | void fbcon_remap_all(struct fb_info *info); | ||
20 | int fbcon_set_con2fb_map_ioctl(void __user *argp); | ||
21 | int fbcon_get_con2fb_map_ioctl(void __user *argp); | ||
7 | #else | 22 | #else |
8 | static inline void fb_console_init(void) {} | 23 | static inline void fb_console_init(void) {} |
9 | static inline void fb_console_exit(void) {} | 24 | static inline void fb_console_exit(void) {} |
25 | static inline int fbcon_fb_registered(struct fb_info *info) { return 0; } | ||
26 | static inline void fbcon_fb_unregistered(struct fb_info *info) {} | ||
27 | static inline void fbcon_fb_unbind(struct fb_info *info) {} | ||
28 | static inline void fbcon_suspended(struct fb_info *info) {} | ||
29 | static inline void fbcon_resumed(struct fb_info *info) {} | ||
30 | static inline int fbcon_mode_deleted(struct fb_info *info, | ||
31 | struct fb_videomode *mode) { return 0; } | ||
32 | static inline void fbcon_new_modelist(struct fb_info *info) {} | ||
33 | static inline void fbcon_get_requirement(struct fb_info *info, | ||
34 | struct fb_blit_caps *caps) {} | ||
35 | static inline void fbcon_fb_blanked(struct fb_info *info, int blank) {} | ||
36 | static inline void fbcon_update_vcs(struct fb_info *info, bool all) {} | ||
37 | static inline void fbcon_remap_all(struct fb_info *info) {} | ||
38 | static inline int fbcon_set_con2fb_map_ioctl(void __user *argp) { return 0; } | ||
39 | static 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 | ||
117 | enum omap_rfbi_te_mode { | ||
118 | OMAP_DSS_RFBI_TE_MODE_1 = 1, | ||
119 | OMAP_DSS_RFBI_TE_MODE_2 = 2, | ||
120 | }; | ||
121 | |||
122 | enum omap_dss_signal_level { | 117 | enum 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 | |||
194 | struct 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 | ||
215 | enum omap_dss_dsi_trans_mode { | 189 | enum 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; |