aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/atmel_lcdfb.c135
-rw-r--r--drivers/video/backlight/Kconfig13
-rw-r--r--drivers/video/bf54x-lq043fb.c3
-rw-r--r--drivers/video/console/bitblit.c4
-rw-r--r--drivers/video/console/fbcon.c29
-rw-r--r--drivers/video/console/fbcon.h47
-rw-r--r--drivers/video/console/fbcon_ccw.c4
-rw-r--r--drivers/video/console/fbcon_cw.c4
-rw-r--r--drivers/video/console/fbcon_ud.c4
-rw-r--r--drivers/video/console/fonts.c4
-rw-r--r--drivers/video/console/tileblit.c4
-rw-r--r--drivers/video/console/vgacon.c2
-rw-r--r--drivers/video/fb_defio.c17
-rw-r--r--drivers/video/fb_draw.h1
-rw-r--r--drivers/video/fbmon.c118
-rw-r--r--drivers/video/geode/lxfb_core.c2
-rw-r--r--drivers/video/hpfb.c3
-rw-r--r--drivers/video/i810/i810_main.c2
-rw-r--r--drivers/video/igafb.c5
-rw-r--r--drivers/video/intelfb/intelfbhw.c2
-rw-r--r--drivers/video/neofb.c27
-rw-r--r--drivers/video/nvidia/nvidia.c22
-rw-r--r--drivers/video/pm2fb.c13
-rw-r--r--drivers/video/pm3fb.c2
-rw-r--r--drivers/video/pmag-aa-fb.c2
-rw-r--r--drivers/video/ps3fb.c451
-rw-r--r--drivers/video/s3c2410fb.c88
-rw-r--r--drivers/video/s3c2410fb.h7
-rw-r--r--drivers/video/sis/sis_main.c4
-rw-r--r--drivers/video/sm501fb.c64
-rw-r--r--drivers/video/tdfxfb.c2
-rw-r--r--drivers/video/uvesafb.c8
-rw-r--r--drivers/video/vermilion/vermilion.c5
33 files changed, 705 insertions, 393 deletions
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index f8e711147501..fc65c02306dd 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -16,6 +16,7 @@
16#include <linux/fb.h> 16#include <linux/fb.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/backlight.h>
19 20
20#include <asm/arch/board.h> 21#include <asm/arch/board.h>
21#include <asm/arch/cpu.h> 22#include <asm/arch/cpu.h>
@@ -69,6 +70,107 @@ static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo,
69} 70}
70#endif 71#endif
71 72
73static const u32 contrast_ctr = ATMEL_LCDC_PS_DIV8
74 | ATMEL_LCDC_POL_POSITIVE
75 | ATMEL_LCDC_ENA_PWMENABLE;
76
77#ifdef CONFIG_BACKLIGHT_ATMEL_LCDC
78
79/* some bl->props field just changed */
80static int atmel_bl_update_status(struct backlight_device *bl)
81{
82 struct atmel_lcdfb_info *sinfo = bl_get_data(bl);
83 int power = sinfo->bl_power;
84 int brightness = bl->props.brightness;
85
86 /* REVISIT there may be a meaningful difference between
87 * fb_blank and power ... there seem to be some cases
88 * this doesn't handle correctly.
89 */
90 if (bl->props.fb_blank != sinfo->bl_power)
91 power = bl->props.fb_blank;
92 else if (bl->props.power != sinfo->bl_power)
93 power = bl->props.power;
94
95 if (brightness < 0 && power == FB_BLANK_UNBLANK)
96 brightness = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
97 else if (power != FB_BLANK_UNBLANK)
98 brightness = 0;
99
100 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, brightness);
101 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR,
102 brightness ? contrast_ctr : 0);
103
104 bl->props.fb_blank = bl->props.power = sinfo->bl_power = power;
105
106 return 0;
107}
108
109static int atmel_bl_get_brightness(struct backlight_device *bl)
110{
111 struct atmel_lcdfb_info *sinfo = bl_get_data(bl);
112
113 return lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
114}
115
116static struct backlight_ops atmel_lcdc_bl_ops = {
117 .update_status = atmel_bl_update_status,
118 .get_brightness = atmel_bl_get_brightness,
119};
120
121static void init_backlight(struct atmel_lcdfb_info *sinfo)
122{
123 struct backlight_device *bl;
124
125 sinfo->bl_power = FB_BLANK_UNBLANK;
126
127 if (sinfo->backlight)
128 return;
129
130 bl = backlight_device_register("backlight", &sinfo->pdev->dev,
131 sinfo, &atmel_lcdc_bl_ops);
132 if (IS_ERR(sinfo->backlight)) {
133 dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n",
134 PTR_ERR(bl));
135 return;
136 }
137 sinfo->backlight = bl;
138
139 bl->props.power = FB_BLANK_UNBLANK;
140 bl->props.fb_blank = FB_BLANK_UNBLANK;
141 bl->props.max_brightness = 0xff;
142 bl->props.brightness = atmel_bl_get_brightness(bl);
143}
144
145static void exit_backlight(struct atmel_lcdfb_info *sinfo)
146{
147 if (sinfo->backlight)
148 backlight_device_unregister(sinfo->backlight);
149}
150
151#else
152
153static void init_backlight(struct atmel_lcdfb_info *sinfo)
154{
155 dev_warn(&sinfo->pdev->dev, "backlight control is not available\n");
156}
157
158static void exit_backlight(struct atmel_lcdfb_info *sinfo)
159{
160}
161
162#endif
163
164static void init_contrast(struct atmel_lcdfb_info *sinfo)
165{
166 /* have some default contrast/backlight settings */
167 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
168 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
169
170 if (sinfo->lcdcon_is_backlight)
171 init_backlight(sinfo);
172}
173
72 174
73static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = { 175static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = {
74 .type = FB_TYPE_PACKED_PIXELS, 176 .type = FB_TYPE_PACKED_PIXELS,
@@ -203,6 +305,26 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
203 var->transp.offset = var->transp.length = 0; 305 var->transp.offset = var->transp.length = 0;
204 var->xoffset = var->yoffset = 0; 306 var->xoffset = var->yoffset = 0;
205 307
308 /* Saturate vertical and horizontal timings at maximum values */
309 var->vsync_len = min_t(u32, var->vsync_len,
310 (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1);
311 var->upper_margin = min_t(u32, var->upper_margin,
312 ATMEL_LCDC_VBP >> ATMEL_LCDC_VBP_OFFSET);
313 var->lower_margin = min_t(u32, var->lower_margin,
314 ATMEL_LCDC_VFP);
315 var->right_margin = min_t(u32, var->right_margin,
316 (ATMEL_LCDC_HFP >> ATMEL_LCDC_HFP_OFFSET) + 1);
317 var->hsync_len = min_t(u32, var->hsync_len,
318 (ATMEL_LCDC_HPW >> ATMEL_LCDC_HPW_OFFSET) + 1);
319 var->left_margin = min_t(u32, var->left_margin,
320 ATMEL_LCDC_HBP + 1);
321
322 /* Some parameters can't be zero */
323 var->vsync_len = max_t(u32, var->vsync_len, 1);
324 var->right_margin = max_t(u32, var->right_margin, 1);
325 var->hsync_len = max_t(u32, var->hsync_len, 1);
326 var->left_margin = max_t(u32, var->left_margin, 1);
327
206 switch (var->bits_per_pixel) { 328 switch (var->bits_per_pixel) {
207 case 1: 329 case 1:
208 case 2: 330 case 2:
@@ -370,10 +492,6 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
370 /* Disable all interrupts */ 492 /* Disable all interrupts */
371 lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); 493 lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
372 494
373 /* Set contrast */
374 value = ATMEL_LCDC_PS_DIV8 | ATMEL_LCDC_POL_POSITIVE | ATMEL_LCDC_ENA_PWMENABLE;
375 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, value);
376 lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT);
377 /* ...wait for DMA engine to become idle... */ 495 /* ...wait for DMA engine to become idle... */
378 while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) 496 while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
379 msleep(10); 497 msleep(10);
@@ -577,6 +695,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
577 sinfo->default_monspecs = pdata_sinfo->default_monspecs; 695 sinfo->default_monspecs = pdata_sinfo->default_monspecs;
578 sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control; 696 sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control;
579 sinfo->guard_time = pdata_sinfo->guard_time; 697 sinfo->guard_time = pdata_sinfo->guard_time;
698 sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight;
580 } else { 699 } else {
581 dev_err(dev, "cannot get default configuration\n"); 700 dev_err(dev, "cannot get default configuration\n");
582 goto free_info; 701 goto free_info;
@@ -670,6 +789,9 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
670 goto release_mem; 789 goto release_mem;
671 } 790 }
672 791
792 /* Initialize PWM for contrast or backlight ("off") */
793 init_contrast(sinfo);
794
673 /* interrupt */ 795 /* interrupt */
674 ret = request_irq(sinfo->irq_base, atmel_lcdfb_interrupt, 0, pdev->name, info); 796 ret = request_irq(sinfo->irq_base, atmel_lcdfb_interrupt, 0, pdev->name, info);
675 if (ret) { 797 if (ret) {
@@ -721,6 +843,7 @@ free_cmap:
721unregister_irqs: 843unregister_irqs:
722 free_irq(sinfo->irq_base, info); 844 free_irq(sinfo->irq_base, info);
723unmap_mmio: 845unmap_mmio:
846 exit_backlight(sinfo);
724 iounmap(sinfo->mmio); 847 iounmap(sinfo->mmio);
725release_mem: 848release_mem:
726 release_mem_region(info->fix.mmio_start, info->fix.mmio_len); 849 release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
@@ -755,6 +878,7 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev)
755 if (!sinfo) 878 if (!sinfo)
756 return 0; 879 return 0;
757 880
881 exit_backlight(sinfo);
758 if (sinfo->atmel_lcdfb_power_control) 882 if (sinfo->atmel_lcdfb_power_control)
759 sinfo->atmel_lcdfb_power_control(0); 883 sinfo->atmel_lcdfb_power_control(0);
760 unregister_framebuffer(info); 884 unregister_framebuffer(info);
@@ -781,6 +905,9 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev)
781 905
782static struct platform_driver atmel_lcdfb_driver = { 906static struct platform_driver atmel_lcdfb_driver = {
783 .remove = __exit_p(atmel_lcdfb_remove), 907 .remove = __exit_p(atmel_lcdfb_remove),
908
909// FIXME need suspend, resume
910
784 .driver = { 911 .driver = {
785 .name = "atmel_lcdfb", 912 .name = "atmel_lcdfb",
786 .owner = THIS_MODULE, 913 .owner = THIS_MODULE,
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 9609a6c676be..924e2551044a 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -50,6 +50,19 @@ config BACKLIGHT_CLASS_DEVICE
50 To have support for your specific LCD panel you will have to 50 To have support for your specific LCD panel you will have to
51 select the proper drivers which depend on this option. 51 select the proper drivers which depend on this option.
52 52
53config BACKLIGHT_ATMEL_LCDC
54 bool "Atmel LCDC Contrast-as-Backlight control"
55 depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL
56 default y if MACH_SAM9261EK || MACH_SAM9263EK
57 help
58 This provides a backlight control internal to the Atmel LCDC
59 driver. If the LCD "contrast control" on your board is wired
60 so it controls the backlight brightness, select this option to
61 export this as a PWM-based backlight control.
62
63 If in doubt, it's safe to enable this option; it doesn't kick
64 in unless the board's description says it's wired that way.
65
53config BACKLIGHT_CORGI 66config BACKLIGHT_CORGI
54 tristate "Generic (aka Sharp Corgi) Backlight Driver" 67 tristate "Generic (aka Sharp Corgi) Backlight Driver"
55 depends on BACKLIGHT_CLASS_DEVICE 68 depends on BACKLIGHT_CLASS_DEVICE
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index c8e7427a0bc8..0ce791e6f79c 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -498,8 +498,7 @@ static struct lcd_device *lcd_dev;
498 498
499static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id) 499static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id)
500{ 500{
501 501 /*struct bfin_bf54xfb_info *info = dev_id;*/
502 /*struct bfin_bf54xfb_info *info = (struct bfin_bf54xfb_info *)dev_id;*/
503 502
504 u16 status = bfin_read_EPPI0_STATUS(); 503 u16 status = bfin_read_EPPI0_STATUS();
505 504
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 308850df16fe..69864b1b3f9e 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -63,7 +63,7 @@ static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy,
63 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 63 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
64 struct fb_fillrect region; 64 struct fb_fillrect region;
65 65
66 region.color = attr_bgcol_ec(bgshift, vc); 66 region.color = attr_bgcol_ec(bgshift, vc, info);
67 region.dx = sx * vc->vc_font.width; 67 region.dx = sx * vc->vc_font.width;
68 region.dy = sy * vc->vc_font.height; 68 region.dy = sy * vc->vc_font.height;
69 region.width = width * vc->vc_font.width; 69 region.width = width * vc->vc_font.width;
@@ -213,7 +213,7 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
213 unsigned int bs = info->var.yres - bh; 213 unsigned int bs = info->var.yres - bh;
214 struct fb_fillrect region; 214 struct fb_fillrect region;
215 215
216 region.color = attr_bgcol_ec(bgshift, vc); 216 region.color = attr_bgcol_ec(bgshift, vc, info);
217 region.rop = ROP_COPY; 217 region.rop = ROP_COPY;
218 218
219 if (rw && !bottom_only) { 219 if (rw && !bottom_only) {
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 0f32f4a00b2d..022282494d3f 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -84,7 +84,7 @@
84#ifdef CONFIG_MAC 84#ifdef CONFIG_MAC
85#include <asm/macints.h> 85#include <asm/macints.h>
86#endif 86#endif
87#if defined(__mc68000__) || defined(CONFIG_APUS) 87#if defined(__mc68000__)
88#include <asm/machdep.h> 88#include <asm/machdep.h>
89#include <asm/setup.h> 89#include <asm/setup.h>
90#endif 90#endif
@@ -147,7 +147,7 @@ static char fontname[40];
147static int info_idx = -1; 147static int info_idx = -1;
148 148
149/* console rotation */ 149/* console rotation */
150static int rotate; 150static int initial_rotation;
151static int fbcon_has_sysfs; 151static int fbcon_has_sysfs;
152 152
153static const struct consw fb_con; 153static const struct consw fb_con;
@@ -334,10 +334,7 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
334 switch (depth) { 334 switch (depth) {
335 case 1: 335 case 1:
336 { 336 {
337 int col = ~(0xfff << (max(info->var.green.length, 337 int col = mono_col(info);
338 max(info->var.red.length,
339 info->var.blue.length)))) & 0xff;
340
341 /* 0 or 1 */ 338 /* 0 or 1 */
342 int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0; 339 int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0;
343 int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col; 340 int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col;
@@ -537,9 +534,9 @@ static int __init fb_console_setup(char *this_opt)
537 if (!strncmp(options, "rotate:", 7)) { 534 if (!strncmp(options, "rotate:", 7)) {
538 options += 7; 535 options += 7;
539 if (*options) 536 if (*options)
540 rotate = simple_strtoul(options, &options, 0); 537 initial_rotation = simple_strtoul(options, &options, 0);
541 if (rotate > 3) 538 if (initial_rotation > 3)
542 rotate = 0; 539 initial_rotation = 0;
543 } 540 }
544 } 541 }
545 return 1; 542 return 1;
@@ -989,7 +986,7 @@ static const char *fbcon_startup(void)
989 ops->graphics = 1; 986 ops->graphics = 1;
990 ops->cur_rotate = -1; 987 ops->cur_rotate = -1;
991 info->fbcon_par = ops; 988 info->fbcon_par = ops;
992 p->con_rotate = rotate; 989 p->con_rotate = initial_rotation;
993 set_blitting_type(vc, info); 990 set_blitting_type(vc, info);
994 991
995 if (info->fix.type != FB_TYPE_TEXT) { 992 if (info->fix.type != FB_TYPE_TEXT) {
@@ -1176,7 +1173,7 @@ static void fbcon_init(struct vc_data *vc, int init)
1176 con_copy_unimap(vc, svc); 1173 con_copy_unimap(vc, svc);
1177 1174
1178 ops = info->fbcon_par; 1175 ops = info->fbcon_par;
1179 p->con_rotate = rotate; 1176 p->con_rotate = initial_rotation;
1180 set_blitting_type(vc, info); 1177 set_blitting_type(vc, info);
1181 1178
1182 cols = vc->vc_cols; 1179 cols = vc->vc_cols;
@@ -2795,7 +2792,7 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2795{ 2792{
2796 struct fb_info *info = registered_fb[con2fb_map[fg_console]]; 2793 struct fb_info *info = registered_fb[con2fb_map[fg_console]];
2797 struct fbcon_ops *ops = info->fbcon_par; 2794 struct fbcon_ops *ops = info->fbcon_par;
2798 struct display *p = &fb_display[fg_console]; 2795 struct display *disp = &fb_display[fg_console];
2799 int offset, limit, scrollback_old; 2796 int offset, limit, scrollback_old;
2800 2797
2801 if (softback_top) { 2798 if (softback_top) {
@@ -2833,7 +2830,7 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2833 logo_shown = FBCON_LOGO_CANSHOW; 2830 logo_shown = FBCON_LOGO_CANSHOW;
2834 } 2831 }
2835 fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK); 2832 fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
2836 fbcon_redraw_softback(vc, p, lines); 2833 fbcon_redraw_softback(vc, disp, lines);
2837 fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK); 2834 fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK);
2838 return 0; 2835 return 0;
2839 } 2836 }
@@ -2855,9 +2852,9 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2855 2852
2856 fbcon_cursor(vc, CM_ERASE); 2853 fbcon_cursor(vc, CM_ERASE);
2857 2854
2858 offset = p->yscroll - scrollback_current; 2855 offset = disp->yscroll - scrollback_current;
2859 limit = p->vrows; 2856 limit = disp->vrows;
2860 switch (p->scrollmode) { 2857 switch (disp->scrollmode) {
2861 case SCROLL_WRAP_MOVE: 2858 case SCROLL_WRAP_MOVE:
2862 info->var.vmode |= FB_VMODE_YWRAP; 2859 info->var.vmode |= FB_VMODE_YWRAP;
2863 break; 2860 break;
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 8e6ef4bc7a5c..3706307e70ed 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -93,10 +93,6 @@ struct fbcon_ops {
93 (((s) >> (fgshift)) & 0x0f) 93 (((s) >> (fgshift)) & 0x0f)
94#define attr_bgcol(bgshift,s) \ 94#define attr_bgcol(bgshift,s) \
95 (((s) >> (bgshift)) & 0x0f) 95 (((s) >> (bgshift)) & 0x0f)
96#define attr_bgcol_ec(bgshift,vc) \
97 ((vc) ? (((vc)->vc_video_erase_char >> (bgshift)) & 0x0f) : 0)
98#define attr_fgcol_ec(fgshift,vc) \
99 ((vc) ? (((vc)->vc_video_erase_char >> (fgshift)) & 0x0f) : 0)
100 96
101/* Monochrome */ 97/* Monochrome */
102#define attr_bold(s) \ 98#define attr_bold(s) \
@@ -108,6 +104,49 @@ struct fbcon_ops {
108#define attr_blink(s) \ 104#define attr_blink(s) \
109 ((s) & 0x8000) 105 ((s) & 0x8000)
110 106
107#define mono_col(info) \
108 (~(0xfff << (max((info)->var.green.length, \
109 max((info)->var.red.length, \
110 (info)->var.blue.length)))) & 0xff)
111
112static inline int attr_col_ec(int shift, struct vc_data *vc,
113 struct fb_info *info, int is_fg)
114{
115 int is_mono01;
116 int col;
117 int fg;
118 int bg;
119
120 if (!vc)
121 return 0;
122
123 if (vc->vc_can_do_color)
124 return is_fg ? attr_fgcol(shift,vc->vc_video_erase_char)
125 : attr_bgcol(shift,vc->vc_video_erase_char);
126
127 if (!info)
128 return 0;
129
130 col = mono_col(info);
131 is_mono01 = info->fix.visual == FB_VISUAL_MONO01;
132
133 if (attr_reverse(vc->vc_video_erase_char)) {
134 fg = is_mono01 ? col : 0;
135 bg = is_mono01 ? 0 : col;
136 }
137 else {
138 fg = is_mono01 ? 0 : col;
139 bg = is_mono01 ? col : 0;
140 }
141
142 return is_fg ? fg : bg;
143}
144
145#define attr_bgcol_ec(bgshift,vc,info) \
146 attr_col_ec(bgshift,vc,info,0);
147#define attr_fgcol_ec(fgshift,vc,info) \
148 attr_col_ec(fgshift,vc,info,1);
149
111/* Font */ 150/* Font */
112#define REFCOUNT(fd) (((int *)(fd))[-1]) 151#define REFCOUNT(fd) (((int *)(fd))[-1])
113#define FNTSIZE(fd) (((int *)(fd))[-2]) 152#define FNTSIZE(fd) (((int *)(fd))[-2])
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index 825e6d6972a7..bdf913ecf001 100644
--- a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -84,7 +84,7 @@ static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
84 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 84 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
85 u32 vyres = GETVYRES(ops->p->scrollmode, info); 85 u32 vyres = GETVYRES(ops->p->scrollmode, info);
86 86
87 region.color = attr_bgcol_ec(bgshift,vc); 87 region.color = attr_bgcol_ec(bgshift,vc,info);
88 region.dx = sy * vc->vc_font.height; 88 region.dx = sy * vc->vc_font.height;
89 region.dy = vyres - ((sx + width) * vc->vc_font.width); 89 region.dy = vyres - ((sx + width) * vc->vc_font.width);
90 region.height = width * vc->vc_font.width; 90 region.height = width * vc->vc_font.width;
@@ -198,7 +198,7 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info,
198 struct fb_fillrect region; 198 struct fb_fillrect region;
199 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 199 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
200 200
201 region.color = attr_bgcol_ec(bgshift,vc); 201 region.color = attr_bgcol_ec(bgshift,vc,info);
202 region.rop = ROP_COPY; 202 region.rop = ROP_COPY;
203 203
204 if (rw && !bottom_only) { 204 if (rw && !bottom_only) {
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index c637e6318803..a6819b9d1770 100644
--- a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -70,7 +70,7 @@ static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
70 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 70 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
71 u32 vxres = GETVXRES(ops->p->scrollmode, info); 71 u32 vxres = GETVXRES(ops->p->scrollmode, info);
72 72
73 region.color = attr_bgcol_ec(bgshift,vc); 73 region.color = attr_bgcol_ec(bgshift,vc,info);
74 region.dx = vxres - ((sy + height) * vc->vc_font.height); 74 region.dx = vxres - ((sy + height) * vc->vc_font.height);
75 region.dy = sx * vc->vc_font.width; 75 region.dy = sx * vc->vc_font.width;
76 region.height = width * vc->vc_font.width; 76 region.height = width * vc->vc_font.width;
@@ -182,7 +182,7 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info,
182 struct fb_fillrect region; 182 struct fb_fillrect region;
183 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 183 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
184 184
185 region.color = attr_bgcol_ec(bgshift,vc); 185 region.color = attr_bgcol_ec(bgshift,vc,info);
186 region.rop = ROP_COPY; 186 region.rop = ROP_COPY;
187 187
188 if (rw && !bottom_only) { 188 if (rw && !bottom_only) {
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index 1473506df5d0..d9b5d6eb68a7 100644
--- a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -71,7 +71,7 @@ static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
71 u32 vyres = GETVYRES(ops->p->scrollmode, info); 71 u32 vyres = GETVYRES(ops->p->scrollmode, info);
72 u32 vxres = GETVXRES(ops->p->scrollmode, info); 72 u32 vxres = GETVXRES(ops->p->scrollmode, info);
73 73
74 region.color = attr_bgcol_ec(bgshift,vc); 74 region.color = attr_bgcol_ec(bgshift,vc,info);
75 region.dy = vyres - ((sy + height) * vc->vc_font.height); 75 region.dy = vyres - ((sy + height) * vc->vc_font.height);
76 region.dx = vxres - ((sx + width) * vc->vc_font.width); 76 region.dx = vxres - ((sx + width) * vc->vc_font.width);
77 region.width = width * vc->vc_font.width; 77 region.width = width * vc->vc_font.width;
@@ -228,7 +228,7 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info,
228 struct fb_fillrect region; 228 struct fb_fillrect region;
229 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; 229 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
230 230
231 region.color = attr_bgcol_ec(bgshift,vc); 231 region.color = attr_bgcol_ec(bgshift,vc,info);
232 region.rop = ROP_COPY; 232 region.rop = ROP_COPY;
233 233
234 if (rw && !bottom_only) { 234 if (rw && !bottom_only) {
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index 96979c377518..d0c03fd70871 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -15,7 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#if defined(__mc68000__) || defined(CONFIG_APUS) 18#if defined(__mc68000__)
19#include <asm/setup.h> 19#include <asm/setup.h>
20#endif 20#endif
21#include <linux/font.h> 21#include <linux/font.h>
@@ -120,7 +120,7 @@ const struct font_desc *get_default_font(int xres, int yres, u32 font_w,
120 for(i=0; i<num_fonts; i++) { 120 for(i=0; i<num_fonts; i++) {
121 f = fonts[i]; 121 f = fonts[i];
122 c = f->pref; 122 c = f->pref;
123#if defined(__mc68000__) || defined(CONFIG_APUS) 123#if defined(__mc68000__)
124#ifdef CONFIG_FONT_PEARL_8x8 124#ifdef CONFIG_FONT_PEARL_8x8
125 if (MACH_IS_AMIGA && f->idx == PEARL8x8_IDX) 125 if (MACH_IS_AMIGA && f->idx == PEARL8x8_IDX)
126 c = 100; 126 c = 100;
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index d981fe4d86c6..0056a41e5c35 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -40,8 +40,8 @@ static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy,
40 40
41 rect.index = vc->vc_video_erase_char & 41 rect.index = vc->vc_video_erase_char &
42 ((vc->vc_hi_font_mask) ? 0x1ff : 0xff); 42 ((vc->vc_hi_font_mask) ? 0x1ff : 0xff);
43 rect.fg = attr_fgcol_ec(fgshift, vc); 43 rect.fg = attr_fgcol_ec(fgshift, vc, info);
44 rect.bg = attr_bgcol_ec(bgshift, vc); 44 rect.bg = attr_bgcol_ec(bgshift, vc, info);
45 rect.sx = sx; 45 rect.sx = sx;
46 rect.sy = sy; 46 rect.sy = sy;
47 rect.width = width; 47 rect.width = width;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index f65bcd314d54..6df29a62d720 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1153,8 +1153,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1153 1153
1154 /* if 512 char mode is already enabled don't re-enable it. */ 1154 /* if 512 char mode is already enabled don't re-enable it. */
1155 if ((set) && (ch512 != vga_512_chars)) { 1155 if ((set) && (ch512 != vga_512_chars)) {
1156 int i;
1157
1158 /* attribute controller */ 1156 /* attribute controller */
1159 for (i = 0; i < MAX_NR_CONSOLES; i++) { 1157 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1160 struct vc_data *c = vc_cons[i].d; 1158 struct vc_data *c = vc_cons[i].d;
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index a0c5d9d90d74..0f8cfb988c90 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -25,8 +25,8 @@
25#include <linux/pagemap.h> 25#include <linux/pagemap.h>
26 26
27/* this is to find and return the vmalloc-ed fb pages */ 27/* this is to find and return the vmalloc-ed fb pages */
28static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma, 28static int fb_deferred_io_fault(struct vm_area_struct *vma,
29 unsigned long vaddr, int *type) 29 struct vm_fault *vmf)
30{ 30{
31 unsigned long offset; 31 unsigned long offset;
32 struct page *page; 32 struct page *page;
@@ -34,18 +34,17 @@ static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma,
34 /* info->screen_base is in System RAM */ 34 /* info->screen_base is in System RAM */
35 void *screen_base = (void __force *) info->screen_base; 35 void *screen_base = (void __force *) info->screen_base;
36 36
37 offset = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); 37 offset = vmf->pgoff << PAGE_SHIFT;
38 if (offset >= info->fix.smem_len) 38 if (offset >= info->fix.smem_len)
39 return NOPAGE_SIGBUS; 39 return VM_FAULT_SIGBUS;
40 40
41 page = vmalloc_to_page(screen_base + offset); 41 page = vmalloc_to_page(screen_base + offset);
42 if (!page) 42 if (!page)
43 return NOPAGE_OOM; 43 return VM_FAULT_SIGBUS;
44 44
45 get_page(page); 45 get_page(page);
46 if (type) 46 vmf->page = page;
47 *type = VM_FAULT_MINOR; 47 return 0;
48 return page;
49} 48}
50 49
51int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync) 50int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync)
@@ -84,7 +83,7 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
84} 83}
85 84
86static struct vm_operations_struct fb_deferred_io_vm_ops = { 85static struct vm_operations_struct fb_deferred_io_vm_ops = {
87 .nopage = fb_deferred_io_nopage, 86 .fault = fb_deferred_io_fault,
88 .page_mkwrite = fb_deferred_io_mkwrite, 87 .page_mkwrite = fb_deferred_io_mkwrite,
89}; 88};
90 89
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h
index cdafbe14ef1f..a2a0618d86a5 100644
--- a/drivers/video/fb_draw.h
+++ b/drivers/video/fb_draw.h
@@ -91,6 +91,7 @@ static inline unsigned long fb_rev_pixels_in_long(unsigned long val,
91 val = comp(val >> 2, val << 2, REV_PIXELS_MASK2); 91 val = comp(val >> 2, val << 2, REV_PIXELS_MASK2);
92 if (bswapmask & 3) 92 if (bswapmask & 3)
93 val = comp(val >> 4, val << 4, REV_PIXELS_MASK4); 93 val = comp(val >> 4, val << 4, REV_PIXELS_MASK4);
94 return val;
94} 95}
95 96
96static inline u32 fb_shifted_pixels_mask_u32(u32 index, u32 bswapmask) 97static inline u32 fb_shifted_pixels_mask_u32(u32 index, u32 bswapmask)
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 4ba9c0894416..052e18058498 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -4,7 +4,7 @@
4 * Copyright (C) 2002 James Simmons <jsimmons@users.sf.net> 4 * Copyright (C) 2002 James Simmons <jsimmons@users.sf.net>
5 * 5 *
6 * Credits: 6 * Credits:
7 * 7 *
8 * The EDID Parser is a conglomeration from the following sources: 8 * The EDID Parser is a conglomeration from the following sources:
9 * 9 *
10 * 1. SciTech SNAP Graphics Architecture 10 * 1. SciTech SNAP Graphics Architecture
@@ -12,13 +12,13 @@
12 * 12 *
13 * 2. XFree86 4.3.0, interpret_edid.c 13 * 2. XFree86 4.3.0, interpret_edid.c
14 * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE> 14 * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
15 * 15 *
16 * 3. John Fremlin <vii@users.sourceforge.net> and 16 * 3. John Fremlin <vii@users.sourceforge.net> and
17 * Ani Joshi <ajoshi@unixbox.com> 17 * Ani Joshi <ajoshi@unixbox.com>
18 * 18 *
19 * Generalized Timing Formula is derived from: 19 * Generalized Timing Formula is derived from:
20 * 20 *
21 * GTF Spreadsheet by Andy Morrish (1/5/97) 21 * GTF Spreadsheet by Andy Morrish (1/5/97)
22 * available at http://www.vesa.org 22 * available at http://www.vesa.org
23 * 23 *
24 * This file is subject to the terms and conditions of the GNU General Public 24 * This file is subject to the terms and conditions of the GNU General Public
@@ -36,7 +36,7 @@
36#endif 36#endif
37#include "edid.h" 37#include "edid.h"
38 38
39/* 39/*
40 * EDID parser 40 * EDID parser
41 */ 41 */
42 42
@@ -160,8 +160,8 @@ static int check_edid(unsigned char *edid)
160 for (i = 0; i < ARRAY_SIZE(brokendb); i++) { 160 for (i = 0; i < ARRAY_SIZE(brokendb); i++) {
161 if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) && 161 if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) &&
162 brokendb[i].model == model) { 162 brokendb[i].model == model) {
163 fix = brokendb[i].fix; 163 fix = brokendb[i].fix;
164 break; 164 break;
165 } 165 }
166 } 166 }
167 167
@@ -323,7 +323,7 @@ static void get_dpms_capabilities(unsigned char flags,
323 (flags & DPMS_SUSPEND) ? "yes" : "no", 323 (flags & DPMS_SUSPEND) ? "yes" : "no",
324 (flags & DPMS_STANDBY) ? "yes" : "no"); 324 (flags & DPMS_STANDBY) ? "yes" : "no");
325} 325}
326 326
327static void get_chroma(unsigned char *block, struct fb_monspecs *specs) 327static void get_chroma(unsigned char *block, struct fb_monspecs *specs)
328{ 328{
329 int tmp; 329 int tmp;
@@ -365,7 +365,7 @@ static void get_chroma(unsigned char *block, struct fb_monspecs *specs)
365 tmp += 512; 365 tmp += 512;
366 specs->chroma.bluey = tmp/1024; 366 specs->chroma.bluey = tmp/1024;
367 DPRINTK("BlueY: 0.%03d\n", specs->chroma.bluey); 367 DPRINTK("BlueY: 0.%03d\n", specs->chroma.bluey);
368 368
369 tmp = ((block[6] & (3 << 2)) >> 2) | (block[0xd] << 2); 369 tmp = ((block[6] & (3 << 2)) >> 2) | (block[0xd] << 2);
370 tmp *= 1000; 370 tmp *= 1000;
371 tmp += 512; 371 tmp += 512;
@@ -383,7 +383,7 @@ static void calc_mode_timings(int xres, int yres, int refresh,
383 struct fb_videomode *mode) 383 struct fb_videomode *mode)
384{ 384{
385 struct fb_var_screeninfo *var; 385 struct fb_var_screeninfo *var;
386 386
387 var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); 387 var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL);
388 388
389 if (var) { 389 if (var) {
@@ -451,11 +451,11 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
451 451
452 c = block[1]; 452 c = block[1];
453 if (c&0x80) { 453 if (c&0x80) {
454 mode[num++] = vesa_modes[9]; 454 mode[num++] = vesa_modes[9];
455 DPRINTK(" 800x600@72Hz\n"); 455 DPRINTK(" 800x600@72Hz\n");
456 } 456 }
457 if (c&0x40) { 457 if (c&0x40) {
458 mode[num++] = vesa_modes[10]; 458 mode[num++] = vesa_modes[10];
459 DPRINTK(" 800x600@75Hz\n"); 459 DPRINTK(" 800x600@75Hz\n");
460 } 460 }
461 if (c&0x20) { 461 if (c&0x20) {
@@ -495,7 +495,7 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
495static int get_std_timing(unsigned char *block, struct fb_videomode *mode) 495static int get_std_timing(unsigned char *block, struct fb_videomode *mode)
496{ 496{
497 int xres, yres = 0, refresh, ratio, i; 497 int xres, yres = 0, refresh, ratio, i;
498 498
499 xres = (block[0] + 31) * 8; 499 xres = (block[0] + 31) * 8;
500 if (xres <= 256) 500 if (xres <= 256)
501 return 0; 501 return 0;
@@ -519,7 +519,7 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode)
519 519
520 DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh); 520 DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh);
521 for (i = 0; i < VESA_MODEDB_SIZE; i++) { 521 for (i = 0; i < VESA_MODEDB_SIZE; i++) {
522 if (vesa_modes[i].xres == xres && 522 if (vesa_modes[i].xres == xres &&
523 vesa_modes[i].yres == yres && 523 vesa_modes[i].yres == yres &&
524 vesa_modes[i].refresh == refresh) { 524 vesa_modes[i].refresh == refresh) {
525 *mode = vesa_modes[i]; 525 *mode = vesa_modes[i];
@@ -536,13 +536,13 @@ static int get_dst_timing(unsigned char *block,
536{ 536{
537 int j, num = 0; 537 int j, num = 0;
538 538
539 for (j = 0; j < 6; j++, block+= STD_TIMING_DESCRIPTION_SIZE) 539 for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE)
540 num += get_std_timing(block, &mode[num]); 540 num += get_std_timing(block, &mode[num]);
541 541
542 return num; 542 return num;
543} 543}
544 544
545static void get_detailed_timing(unsigned char *block, 545static void get_detailed_timing(unsigned char *block,
546 struct fb_videomode *mode) 546 struct fb_videomode *mode)
547{ 547{
548 mode->xres = H_ACTIVE; 548 mode->xres = H_ACTIVE;
@@ -553,7 +553,7 @@ static void get_detailed_timing(unsigned char *block,
553 mode->right_margin = H_SYNC_OFFSET; 553 mode->right_margin = H_SYNC_OFFSET;
554 mode->left_margin = (H_ACTIVE + H_BLANKING) - 554 mode->left_margin = (H_ACTIVE + H_BLANKING) -
555 (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); 555 (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
556 mode->upper_margin = V_BLANKING - V_SYNC_OFFSET - 556 mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
557 V_SYNC_WIDTH; 557 V_SYNC_WIDTH;
558 mode->lower_margin = V_SYNC_OFFSET; 558 mode->lower_margin = V_SYNC_OFFSET;
559 mode->hsync_len = H_SYNC_WIDTH; 559 mode->hsync_len = H_SYNC_WIDTH;
@@ -597,7 +597,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
597 if (mode == NULL) 597 if (mode == NULL)
598 return NULL; 598 return NULL;
599 599
600 if (edid == NULL || !edid_checksum(edid) || 600 if (edid == NULL || !edid_checksum(edid) ||
601 !edid_check_header(edid)) { 601 !edid_check_header(edid)) {
602 kfree(mode); 602 kfree(mode);
603 return NULL; 603 return NULL;
@@ -632,7 +632,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
632 if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa) 632 if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
633 num += get_dst_timing(block + 5, &mode[num]); 633 num += get_dst_timing(block + 5, &mode[num]);
634 } 634 }
635 635
636 /* Yikes, EDID data is totally useless */ 636 /* Yikes, EDID data is totally useless */
637 if (!num) { 637 if (!num) {
638 kfree(mode); 638 kfree(mode);
@@ -686,7 +686,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
686 /* estimate monitor limits based on modes supported */ 686 /* estimate monitor limits based on modes supported */
687 if (retval) { 687 if (retval) {
688 struct fb_videomode *modes, *mode; 688 struct fb_videomode *modes, *mode;
689 int num_modes, i, hz, hscan, pixclock; 689 int num_modes, hz, hscan, pixclock;
690 int vtotal, htotal; 690 int vtotal, htotal;
691 691
692 modes = fb_create_modedb(edid, &num_modes); 692 modes = fb_create_modedb(edid, &num_modes);
@@ -713,7 +713,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
713 hscan = (pixclock + htotal / 2) / htotal; 713 hscan = (pixclock + htotal / 2) / htotal;
714 hscan = (hscan + 500) / 1000 * 1000; 714 hscan = (hscan + 500) / 1000 * 1000;
715 hz = (hscan + vtotal / 2) / vtotal; 715 hz = (hscan + vtotal / 2) / vtotal;
716 716
717 if (specs->dclkmax == 0 || specs->dclkmax < pixclock) 717 if (specs->dclkmax == 0 || specs->dclkmax < pixclock)
718 specs->dclkmax = pixclock; 718 specs->dclkmax = pixclock;
719 719
@@ -966,8 +966,8 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
966 DPRINTK("========================================\n"); 966 DPRINTK("========================================\n");
967} 967}
968 968
969/* 969/*
970 * VESA Generalized Timing Formula (GTF) 970 * VESA Generalized Timing Formula (GTF)
971 */ 971 */
972 972
973#define FLYBACK 550 973#define FLYBACK 550
@@ -996,7 +996,7 @@ struct __fb_timings {
996 * @hfreq: horizontal freq 996 * @hfreq: horizontal freq
997 * 997 *
998 * DESCRIPTION: 998 * DESCRIPTION:
999 * vblank = right_margin + vsync_len + left_margin 999 * vblank = right_margin + vsync_len + left_margin
1000 * 1000 *
1001 * given: right_margin = 1 (V_FRONTPORCH) 1001 * given: right_margin = 1 (V_FRONTPORCH)
1002 * vsync_len = 3 1002 * vsync_len = 3
@@ -1010,12 +1010,12 @@ static u32 fb_get_vblank(u32 hfreq)
1010{ 1010{
1011 u32 vblank; 1011 u32 vblank;
1012 1012
1013 vblank = (hfreq * FLYBACK)/1000; 1013 vblank = (hfreq * FLYBACK)/1000;
1014 vblank = (vblank + 500)/1000; 1014 vblank = (vblank + 500)/1000;
1015 return (vblank + V_FRONTPORCH); 1015 return (vblank + V_FRONTPORCH);
1016} 1016}
1017 1017
1018/** 1018/**
1019 * fb_get_hblank_by_freq - get horizontal blank time given hfreq 1019 * fb_get_hblank_by_freq - get horizontal blank time given hfreq
1020 * @hfreq: horizontal freq 1020 * @hfreq: horizontal freq
1021 * @xres: horizontal resolution in pixels 1021 * @xres: horizontal resolution in pixels
@@ -1031,7 +1031,7 @@ static u32 fb_get_vblank(u32 hfreq)
1031 * 1031 *
1032 * where: C = ((offset - scale factor) * blank_scale) 1032 * where: C = ((offset - scale factor) * blank_scale)
1033 * -------------------------------------- + scale factor 1033 * -------------------------------------- + scale factor
1034 * 256 1034 * 256
1035 * M = blank_scale * gradient 1035 * M = blank_scale * gradient
1036 * 1036 *
1037 */ 1037 */
@@ -1039,7 +1039,7 @@ static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres)
1039{ 1039{
1040 u32 c_val, m_val, duty_cycle, hblank; 1040 u32 c_val, m_val, duty_cycle, hblank;
1041 1041
1042 c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 + 1042 c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 +
1043 H_SCALEFACTOR) * 1000; 1043 H_SCALEFACTOR) * 1000;
1044 m_val = (H_BLANKSCALE * H_GRADIENT)/256; 1044 m_val = (H_BLANKSCALE * H_GRADIENT)/256;
1045 m_val = (m_val * 1000000)/hfreq; 1045 m_val = (m_val * 1000000)/hfreq;
@@ -1048,7 +1048,7 @@ static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres)
1048 return (hblank); 1048 return (hblank);
1049} 1049}
1050 1050
1051/** 1051/**
1052 * fb_get_hblank_by_dclk - get horizontal blank time given pixelclock 1052 * fb_get_hblank_by_dclk - get horizontal blank time given pixelclock
1053 * @dclk: pixelclock in Hz 1053 * @dclk: pixelclock in Hz
1054 * @xres: horizontal resolution in pixels 1054 * @xres: horizontal resolution in pixels
@@ -1061,7 +1061,7 @@ static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres)
1061 * 1061 *
1062 * duty cycle = percent of htotal assigned to inactive display 1062 * duty cycle = percent of htotal assigned to inactive display
1063 * duty cycle = C - (M * h_period) 1063 * duty cycle = C - (M * h_period)
1064 * 1064 *
1065 * where: h_period = SQRT(100 - C + (0.4 * xres * M)/dclk) + C - 100 1065 * where: h_period = SQRT(100 - C + (0.4 * xres * M)/dclk) + C - 100
1066 * ----------------------------------------------- 1066 * -----------------------------------------------
1067 * 2 * M 1067 * 2 * M
@@ -1077,11 +1077,11 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres)
1077 h_period = 100 - C_VAL; 1077 h_period = 100 - C_VAL;
1078 h_period *= h_period; 1078 h_period *= h_period;
1079 h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk); 1079 h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk);
1080 h_period *=10000; 1080 h_period *= 10000;
1081 1081
1082 h_period = int_sqrt(h_period); 1082 h_period = int_sqrt(h_period);
1083 h_period -= (100 - C_VAL) * 100; 1083 h_period -= (100 - C_VAL) * 100;
1084 h_period *= 1000; 1084 h_period *= 1000;
1085 h_period /= 2 * M_VAL; 1085 h_period /= 2 * M_VAL;
1086 1086
1087 duty_cycle = C_VAL * 1000 - (M_VAL * h_period)/100; 1087 duty_cycle = C_VAL * 1000 - (M_VAL * h_period)/100;
@@ -1089,7 +1089,7 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres)
1089 hblank &= ~15; 1089 hblank &= ~15;
1090 return (hblank); 1090 return (hblank);
1091} 1091}
1092 1092
1093/** 1093/**
1094 * fb_get_hfreq - estimate hsync 1094 * fb_get_hfreq - estimate hsync
1095 * @vfreq: vertical refresh rate 1095 * @vfreq: vertical refresh rate
@@ -1100,13 +1100,13 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres)
1100 * (yres + front_port) * vfreq * 1000000 1100 * (yres + front_port) * vfreq * 1000000
1101 * hfreq = ------------------------------------- 1101 * hfreq = -------------------------------------
1102 * (1000000 - (vfreq * FLYBACK) 1102 * (1000000 - (vfreq * FLYBACK)
1103 * 1103 *
1104 */ 1104 */
1105 1105
1106static u32 fb_get_hfreq(u32 vfreq, u32 yres) 1106static u32 fb_get_hfreq(u32 vfreq, u32 yres)
1107{ 1107{
1108 u32 divisor, hfreq; 1108 u32 divisor, hfreq;
1109 1109
1110 divisor = (1000000 - (vfreq * FLYBACK))/1000; 1110 divisor = (1000000 - (vfreq * FLYBACK))/1000;
1111 hfreq = (yres + V_FRONTPORCH) * vfreq * 1000; 1111 hfreq = (yres + V_FRONTPORCH) * vfreq * 1000;
1112 return (hfreq/divisor); 1112 return (hfreq/divisor);
@@ -1117,7 +1117,7 @@ static void fb_timings_vfreq(struct __fb_timings *timings)
1117 timings->hfreq = fb_get_hfreq(timings->vfreq, timings->vactive); 1117 timings->hfreq = fb_get_hfreq(timings->vfreq, timings->vactive);
1118 timings->vblank = fb_get_vblank(timings->hfreq); 1118 timings->vblank = fb_get_vblank(timings->hfreq);
1119 timings->vtotal = timings->vactive + timings->vblank; 1119 timings->vtotal = timings->vactive + timings->vblank;
1120 timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, 1120 timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq,
1121 timings->hactive); 1121 timings->hactive);
1122 timings->htotal = timings->hactive + timings->hblank; 1122 timings->htotal = timings->hactive + timings->hblank;
1123 timings->dclk = timings->htotal * timings->hfreq; 1123 timings->dclk = timings->htotal * timings->hfreq;
@@ -1128,7 +1128,7 @@ static void fb_timings_hfreq(struct __fb_timings *timings)
1128 timings->vblank = fb_get_vblank(timings->hfreq); 1128 timings->vblank = fb_get_vblank(timings->hfreq);
1129 timings->vtotal = timings->vactive + timings->vblank; 1129 timings->vtotal = timings->vactive + timings->vblank;
1130 timings->vfreq = timings->hfreq/timings->vtotal; 1130 timings->vfreq = timings->hfreq/timings->vtotal;
1131 timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, 1131 timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq,
1132 timings->hactive); 1132 timings->hactive);
1133 timings->htotal = timings->hactive + timings->hblank; 1133 timings->htotal = timings->hactive + timings->hblank;
1134 timings->dclk = timings->htotal * timings->hfreq; 1134 timings->dclk = timings->htotal * timings->hfreq;
@@ -1136,7 +1136,7 @@ static void fb_timings_hfreq(struct __fb_timings *timings)
1136 1136
1137static void fb_timings_dclk(struct __fb_timings *timings) 1137static void fb_timings_dclk(struct __fb_timings *timings)
1138{ 1138{
1139 timings->hblank = fb_get_hblank_by_dclk(timings->dclk, 1139 timings->hblank = fb_get_hblank_by_dclk(timings->dclk,
1140 timings->hactive); 1140 timings->hactive);
1141 timings->htotal = timings->hactive + timings->hblank; 1141 timings->htotal = timings->hactive + timings->hblank;
1142 timings->hfreq = timings->dclk/timings->htotal; 1142 timings->hfreq = timings->dclk/timings->htotal;
@@ -1156,29 +1156,29 @@ static void fb_timings_dclk(struct __fb_timings *timings)
1156 * @info: pointer to fb_info 1156 * @info: pointer to fb_info
1157 * 1157 *
1158 * DESCRIPTION: 1158 * DESCRIPTION:
1159 * Calculates video mode based on monitor specs using VESA GTF. 1159 * Calculates video mode based on monitor specs using VESA GTF.
1160 * The GTF is best for VESA GTF compliant monitors but is 1160 * The GTF is best for VESA GTF compliant monitors but is
1161 * specifically formulated to work for older monitors as well. 1161 * specifically formulated to work for older monitors as well.
1162 * 1162 *
1163 * If @flag==0, the function will attempt to maximize the 1163 * If @flag==0, the function will attempt to maximize the
1164 * refresh rate. Otherwise, it will calculate timings based on 1164 * refresh rate. Otherwise, it will calculate timings based on
1165 * the flag and accompanying value. 1165 * the flag and accompanying value.
1166 * 1166 *
1167 * If FB_IGNOREMON bit is set in @flags, monitor specs will be 1167 * If FB_IGNOREMON bit is set in @flags, monitor specs will be
1168 * ignored and @var will be filled with the calculated timings. 1168 * ignored and @var will be filled with the calculated timings.
1169 * 1169 *
1170 * All calculations are based on the VESA GTF Spreadsheet 1170 * All calculations are based on the VESA GTF Spreadsheet
1171 * available at VESA's public ftp (http://www.vesa.org). 1171 * available at VESA's public ftp (http://www.vesa.org).
1172 * 1172 *
1173 * NOTES: 1173 * NOTES:
1174 * The timings generated by the GTF will be different from VESA 1174 * The timings generated by the GTF will be different from VESA
1175 * DMT. It might be a good idea to keep a table of standard 1175 * DMT. It might be a good idea to keep a table of standard
1176 * VESA modes as well. The GTF may also not work for some displays, 1176 * VESA modes as well. The GTF may also not work for some displays,
1177 * such as, and especially, analog TV. 1177 * such as, and especially, analog TV.
1178 * 1178 *
1179 * REQUIRES: 1179 * REQUIRES:
1180 * A valid info->monspecs, otherwise 'safe numbers' will be used. 1180 * A valid info->monspecs, otherwise 'safe numbers' will be used.
1181 */ 1181 */
1182int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info) 1182int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info)
1183{ 1183{
1184 struct __fb_timings *timings; 1184 struct __fb_timings *timings;
@@ -1191,7 +1191,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf
1191 if (!timings) 1191 if (!timings)
1192 return -ENOMEM; 1192 return -ENOMEM;
1193 1193
1194 /* 1194 /*
1195 * If monspecs are invalid, use values that are enough 1195 * If monspecs are invalid, use values that are enough
1196 * for 640x480@60 1196 * for 640x480@60
1197 */ 1197 */
@@ -1214,7 +1214,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf
1214 1214
1215 timings->hactive = var->xres; 1215 timings->hactive = var->xres;
1216 timings->vactive = var->yres; 1216 timings->vactive = var->yres;
1217 if (var->vmode & FB_VMODE_INTERLACED) { 1217 if (var->vmode & FB_VMODE_INTERLACED) {
1218 timings->vactive /= 2; 1218 timings->vactive /= 2;
1219 interlace = 2; 1219 interlace = 2;
1220 } 1220 }
@@ -1250,9 +1250,9 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf
1250 break; 1250 break;
1251 default: 1251 default:
1252 err = -EINVAL; 1252 err = -EINVAL;
1253 1253
1254 } 1254 }
1255 1255
1256 if (err || (!(flags & FB_IGNOREMON) && 1256 if (err || (!(flags & FB_IGNOREMON) &&
1257 (timings->vfreq < vfmin || timings->vfreq > vfmax || 1257 (timings->vfreq < vfmin || timings->vfreq > vfmax ||
1258 timings->hfreq < hfmin || timings->hfreq > hfmax || 1258 timings->hfreq < hfmin || timings->hfreq > hfmax ||
@@ -1269,7 +1269,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf
1269 var->upper_margin = (timings->vblank * interlace)/dscan - 1269 var->upper_margin = (timings->vblank * interlace)/dscan -
1270 (var->vsync_len + var->lower_margin); 1270 (var->vsync_len + var->lower_margin);
1271 } 1271 }
1272 1272
1273 kfree(timings); 1273 kfree(timings);
1274 return err; 1274 return err;
1275} 1275}
@@ -1291,7 +1291,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var,
1291 return -EINVAL; 1291 return -EINVAL;
1292} 1292}
1293#endif /* CONFIG_FB_MODE_HELPERS */ 1293#endif /* CONFIG_FB_MODE_HELPERS */
1294 1294
1295/* 1295/*
1296 * fb_validate_mode - validates var against monitor capabilities 1296 * fb_validate_mode - validates var against monitor capabilities
1297 * @var: pointer to fb_var_screeninfo 1297 * @var: pointer to fb_var_screeninfo
@@ -1309,7 +1309,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
1309 u32 hfreq, vfreq, htotal, vtotal, pixclock; 1309 u32 hfreq, vfreq, htotal, vtotal, pixclock;
1310 u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax; 1310 u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax;
1311 1311
1312 /* 1312 /*
1313 * If monspecs are invalid, use values that are enough 1313 * If monspecs are invalid, use values that are enough
1314 * for 640x480@60 1314 * for 640x480@60
1315 */ 1315 */
@@ -1333,10 +1333,10 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
1333 if (!var->pixclock) 1333 if (!var->pixclock)
1334 return -EINVAL; 1334 return -EINVAL;
1335 pixclock = PICOS2KHZ(var->pixclock) * 1000; 1335 pixclock = PICOS2KHZ(var->pixclock) * 1000;
1336 1336
1337 htotal = var->xres + var->right_margin + var->hsync_len + 1337 htotal = var->xres + var->right_margin + var->hsync_len +
1338 var->left_margin; 1338 var->left_margin;
1339 vtotal = var->yres + var->lower_margin + var->vsync_len + 1339 vtotal = var->yres + var->lower_margin + var->vsync_len +
1340 var->upper_margin; 1340 var->upper_margin;
1341 1341
1342 if (var->vmode & FB_VMODE_INTERLACED) 1342 if (var->vmode & FB_VMODE_INTERLACED)
@@ -1349,7 +1349,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
1349 1349
1350 vfreq = hfreq/vtotal; 1350 vfreq = hfreq/vtotal;
1351 1351
1352 return (vfreq < vfmin || vfreq > vfmax || 1352 return (vfreq < vfmin || vfreq > vfmax ||
1353 hfreq < hfmin || hfreq > hfmax || 1353 hfreq < hfmin || hfreq > hfmax ||
1354 pixclock < dclkmin || pixclock > dclkmax) ? 1354 pixclock < dclkmin || pixclock > dclkmax) ?
1355 -EINVAL : 0; 1355 -EINVAL : 0;
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c
index 583185fd7c94..eb6b88171538 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/geode/lxfb_core.c
@@ -34,7 +34,7 @@ static int fbsize;
34 * we try to make it something sane - 640x480-60 is sane 34 * we try to make it something sane - 640x480-60 is sane
35 */ 35 */
36 36
37const struct fb_videomode geode_modedb[] __initdata = { 37static const struct fb_videomode geode_modedb[] __initdata = {
38 /* 640x480-60 */ 38 /* 640x480-60 */
39 { NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2, 39 { NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2,
40 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 40 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index b18486ad8e17..2eb4fb159084 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -207,7 +207,8 @@ static struct fb_ops hpfb_ops = {
207#define HPFB_FBOMSB 0x5d /* Frame buffer offset */ 207#define HPFB_FBOMSB 0x5d /* Frame buffer offset */
208#define HPFB_FBOLSB 0x5f 208#define HPFB_FBOLSB 0x5f
209 209
210static int __init hpfb_init_one(unsigned long phys_base, unsigned long virt_base) 210static int __devinit hpfb_init_one(unsigned long phys_base,
211 unsigned long virt_base)
211{ 212{
212 unsigned long fboff, fb_width, fb_height, fb_start; 213 unsigned long fboff, fb_width, fb_height, fb_start;
213 214
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 1a7d7789d877..1d13dd099af8 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1476,7 +1476,7 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1476 struct i810fb_par *par = info->par; 1476 struct i810fb_par *par = info->par;
1477 u8 __iomem *mmio = par->mmio_start_virtual; 1477 u8 __iomem *mmio = par->mmio_start_virtual;
1478 1478
1479 if (!par->dev_flags & LOCKUP) 1479 if (!(par->dev_flags & LOCKUP))
1480 return -ENXIO; 1480 return -ENXIO;
1481 1481
1482 if (cursor->image.width > 64 || cursor->image.height > 64) 1482 if (cursor->image.width > 64 || cursor->image.height > 64)
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index b87ea21d3d78..3a81060137a2 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -400,6 +400,7 @@ int __init igafb_init(void)
400 info = kzalloc(size, GFP_ATOMIC); 400 info = kzalloc(size, GFP_ATOMIC);
401 if (!info) { 401 if (!info) {
402 printk("igafb_init: can't alloc fb_info\n"); 402 printk("igafb_init: can't alloc fb_info\n");
403 pci_dev_put(pdev);
403 return -ENOMEM; 404 return -ENOMEM;
404 } 405 }
405 406
@@ -409,12 +410,14 @@ int __init igafb_init(void)
409 if ((addr = pdev->resource[0].start) == 0) { 410 if ((addr = pdev->resource[0].start) == 0) {
410 printk("igafb_init: no memory start\n"); 411 printk("igafb_init: no memory start\n");
411 kfree(info); 412 kfree(info);
413 pci_dev_put(pdev);
412 return -ENXIO; 414 return -ENXIO;
413 } 415 }
414 416
415 if ((info->screen_base = ioremap(addr, 1024*1024*2)) == 0) { 417 if ((info->screen_base = ioremap(addr, 1024*1024*2)) == 0) {
416 printk("igafb_init: can't remap %lx[2M]\n", addr); 418 printk("igafb_init: can't remap %lx[2M]\n", addr);
417 kfree(info); 419 kfree(info);
420 pci_dev_put(pdev);
418 return -ENXIO; 421 return -ENXIO;
419 } 422 }
420 423
@@ -449,6 +452,7 @@ int __init igafb_init(void)
449 printk("igafb_init: can't remap %lx[4K]\n", igafb_fix.mmio_start); 452 printk("igafb_init: can't remap %lx[4K]\n", igafb_fix.mmio_start);
450 iounmap((void *)info->screen_base); 453 iounmap((void *)info->screen_base);
451 kfree(info); 454 kfree(info);
455 pci_dev_put(pdev);
452 return -ENXIO; 456 return -ENXIO;
453 } 457 }
454 458
@@ -466,6 +470,7 @@ int __init igafb_init(void)
466 iounmap((void *)par->io_base); 470 iounmap((void *)par->io_base);
467 iounmap(info->screen_base); 471 iounmap(info->screen_base);
468 kfree(info); 472 kfree(info);
473 pci_dev_put(pdev);
469 return -ENOMEM; 474 return -ENOMEM;
470 } 475 }
471 476
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 5f6fb7d2c408..fa1fff553565 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -1971,7 +1971,7 @@ void intelfbhw_cursor_reset(struct intelfb_info *dinfo)
1971static irqreturn_t intelfbhw_irq(int irq, void *dev_id) 1971static irqreturn_t intelfbhw_irq(int irq, void *dev_id)
1972{ 1972{
1973 u16 tmp; 1973 u16 tmp;
1974 struct intelfb_info *dinfo = (struct intelfb_info *)dev_id; 1974 struct intelfb_info *dinfo = dev_id;
1975 1975
1976 spin_lock(&dinfo->int_lock); 1976 spin_lock(&dinfo->int_lock);
1977 1977
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 4b6a99b5be0d..5246b0402d76 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -2066,40 +2066,49 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
2066 2066
2067 switch (info->fix.accel) { 2067 switch (info->fix.accel) {
2068 case FB_ACCEL_NEOMAGIC_NM2070: 2068 case FB_ACCEL_NEOMAGIC_NM2070:
2069 sprintf(info->fix.id, "MagicGraph 128"); 2069 snprintf(info->fix.id, sizeof(info->fix.id),
2070 "MagicGraph 128");
2070 break; 2071 break;
2071 case FB_ACCEL_NEOMAGIC_NM2090: 2072 case FB_ACCEL_NEOMAGIC_NM2090:
2072 sprintf(info->fix.id, "MagicGraph 128V"); 2073 snprintf(info->fix.id, sizeof(info->fix.id),
2074 "MagicGraph 128V");
2073 break; 2075 break;
2074 case FB_ACCEL_NEOMAGIC_NM2093: 2076 case FB_ACCEL_NEOMAGIC_NM2093:
2075 sprintf(info->fix.id, "MagicGraph 128ZV"); 2077 snprintf(info->fix.id, sizeof(info->fix.id),
2078 "MagicGraph 128ZV");
2076 break; 2079 break;
2077 case FB_ACCEL_NEOMAGIC_NM2097: 2080 case FB_ACCEL_NEOMAGIC_NM2097:
2078 sprintf(info->fix.id, "MagicGraph 128ZV+"); 2081 snprintf(info->fix.id, sizeof(info->fix.id),
2082 "MagicGraph 128ZV+");
2079 break; 2083 break;
2080 case FB_ACCEL_NEOMAGIC_NM2160: 2084 case FB_ACCEL_NEOMAGIC_NM2160:
2081 sprintf(info->fix.id, "MagicGraph 128XD"); 2085 snprintf(info->fix.id, sizeof(info->fix.id),
2086 "MagicGraph 128XD");
2082 break; 2087 break;
2083 case FB_ACCEL_NEOMAGIC_NM2200: 2088 case FB_ACCEL_NEOMAGIC_NM2200:
2084 sprintf(info->fix.id, "MagicGraph 256AV"); 2089 snprintf(info->fix.id, sizeof(info->fix.id),
2090 "MagicGraph 256AV");
2085 info->flags |= FBINFO_HWACCEL_IMAGEBLIT | 2091 info->flags |= FBINFO_HWACCEL_IMAGEBLIT |
2086 FBINFO_HWACCEL_COPYAREA | 2092 FBINFO_HWACCEL_COPYAREA |
2087 FBINFO_HWACCEL_FILLRECT; 2093 FBINFO_HWACCEL_FILLRECT;
2088 break; 2094 break;
2089 case FB_ACCEL_NEOMAGIC_NM2230: 2095 case FB_ACCEL_NEOMAGIC_NM2230:
2090 sprintf(info->fix.id, "MagicGraph 256AV+"); 2096 snprintf(info->fix.id, sizeof(info->fix.id),
2097 "MagicGraph 256AV+");
2091 info->flags |= FBINFO_HWACCEL_IMAGEBLIT | 2098 info->flags |= FBINFO_HWACCEL_IMAGEBLIT |
2092 FBINFO_HWACCEL_COPYAREA | 2099 FBINFO_HWACCEL_COPYAREA |
2093 FBINFO_HWACCEL_FILLRECT; 2100 FBINFO_HWACCEL_FILLRECT;
2094 break; 2101 break;
2095 case FB_ACCEL_NEOMAGIC_NM2360: 2102 case FB_ACCEL_NEOMAGIC_NM2360:
2096 sprintf(info->fix.id, "MagicGraph 256ZX"); 2103 snprintf(info->fix.id, sizeof(info->fix.id),
2104 "MagicGraph 256ZX");
2097 info->flags |= FBINFO_HWACCEL_IMAGEBLIT | 2105 info->flags |= FBINFO_HWACCEL_IMAGEBLIT |
2098 FBINFO_HWACCEL_COPYAREA | 2106 FBINFO_HWACCEL_COPYAREA |
2099 FBINFO_HWACCEL_FILLRECT; 2107 FBINFO_HWACCEL_FILLRECT;
2100 break; 2108 break;
2101 case FB_ACCEL_NEOMAGIC_NM2380: 2109 case FB_ACCEL_NEOMAGIC_NM2380:
2102 sprintf(info->fix.id, "MagicGraph 256XL+"); 2110 snprintf(info->fix.id, sizeof(info->fix.id),
2111 "MagicGraph 256XL+");
2103 info->flags |= FBINFO_HWACCEL_IMAGEBLIT | 2112 info->flags |= FBINFO_HWACCEL_IMAGEBLIT |
2104 FBINFO_HWACCEL_COPYAREA | 2113 FBINFO_HWACCEL_COPYAREA |
2105 FBINFO_HWACCEL_FILLRECT; 2114 FBINFO_HWACCEL_FILLRECT;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 30e14eb1f51e..74517b1b26a6 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -849,9 +849,27 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var,
849 if (!mode_valid && info->monspecs.modedb_len) 849 if (!mode_valid && info->monspecs.modedb_len)
850 return -EINVAL; 850 return -EINVAL;
851 851
852 /*
853 * If we're on a flat panel, check if the mode is outside of the
854 * panel dimensions. If so, cap it and try for the next best mode
855 * before bailing out.
856 */
852 if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres || 857 if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||
853 par->fpHeight < var->yres)) 858 par->fpHeight < var->yres)) {
854 return -EINVAL; 859 const struct fb_videomode *mode;
860
861 var->xres = par->fpWidth;
862 var->yres = par->fpHeight;
863
864 mode = fb_find_best_mode(var, &info->modelist);
865 if (!mode) {
866 printk(KERN_ERR PFX "mode out of range of flat "
867 "panel dimensions\n");
868 return -EINVAL;
869 }
870
871 fb_videomode_to_var(var, mode);
872 }
855 873
856 if (var->yres_virtual < var->yres) 874 if (var->yres_virtual < var->yres)
857 var->yres_virtual = var->yres; 875 var->yres_virtual = var->yres;
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 5591dfb22b18..30181b593829 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -1159,6 +1159,11 @@ static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image)
1159 u32 fgx, bgx; 1159 u32 fgx, bgx;
1160 const u32 *src = (const u32 *)image->data; 1160 const u32 *src = (const u32 *)image->data;
1161 u32 xres = (info->var.xres + 31) & ~31; 1161 u32 xres = (info->var.xres + 31) & ~31;
1162 int raster_mode = 1; /* invert bits */
1163
1164#ifdef __LITTLE_ENDIAN
1165 raster_mode |= 3 << 7; /* reverse byte order */
1166#endif
1162 1167
1163 if (info->state != FBINFO_STATE_RUNNING) 1168 if (info->state != FBINFO_STATE_RUNNING)
1164 return; 1169 return;
@@ -1208,9 +1213,8 @@ static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image)
1208 pm2_WR(par, PM2R_RENDER, 1213 pm2_WR(par, PM2R_RENDER,
1209 PM2F_RENDER_RECTANGLE | 1214 PM2F_RENDER_RECTANGLE |
1210 PM2F_INCREASE_X | PM2F_INCREASE_Y); 1215 PM2F_INCREASE_X | PM2F_INCREASE_Y);
1211 /* BitMapPackEachScanline & invert bits and byte order*/ 1216 /* BitMapPackEachScanline */
1212 /* force background */ 1217 pm2_WR(par, PM2R_RASTERIZER_MODE, raster_mode | (1 << 9));
1213 pm2_WR(par, PM2R_RASTERIZER_MODE, (1 << 9) | 1 | (3 << 7));
1214 pm2_WR(par, PM2R_CONSTANT_COLOR, fgx); 1218 pm2_WR(par, PM2R_CONSTANT_COLOR, fgx);
1215 pm2_WR(par, PM2R_RENDER, 1219 pm2_WR(par, PM2R_RENDER,
1216 PM2F_RENDER_RECTANGLE | 1220 PM2F_RENDER_RECTANGLE |
@@ -1224,8 +1228,7 @@ static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image)
1224 PM2F_RENDER_RECTANGLE | 1228 PM2F_RENDER_RECTANGLE |
1225 PM2F_RENDER_FASTFILL | 1229 PM2F_RENDER_FASTFILL |
1226 PM2F_INCREASE_X | PM2F_INCREASE_Y); 1230 PM2F_INCREASE_X | PM2F_INCREASE_Y);
1227 /* invert bits and byte order*/ 1231 pm2_WR(par, PM2R_RASTERIZER_MODE, raster_mode);
1228 pm2_WR(par, PM2R_RASTERIZER_MODE, 1 | (3 << 7));
1229 pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx); 1232 pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx);
1230 pm2_WR(par, PM2R_RENDER, 1233 pm2_WR(par, PM2R_RENDER,
1231 PM2F_RENDER_RECTANGLE | 1234 PM2F_RENDER_RECTANGLE |
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 070659992c18..5dba8cdd0517 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -1227,7 +1227,7 @@ static struct fb_ops pm3fb_ops = {
1227 1227
1228/* mmio register are already mapped when this function is called */ 1228/* mmio register are already mapped when this function is called */
1229/* the pm3fb_fix.smem_start is also set */ 1229/* the pm3fb_fix.smem_start is also set */
1230static unsigned long pm3fb_size_memory(struct pm3_par *par) 1230static unsigned long __devinit pm3fb_size_memory(struct pm3_par *par)
1231{ 1231{
1232 unsigned long memsize = 0; 1232 unsigned long memsize = 0;
1233 unsigned long tempBypass, i, temp1, temp2; 1233 unsigned long tempBypass, i, temp1, temp2;
diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/pmag-aa-fb.c
index a864438b6008..6515ec11c16b 100644
--- a/drivers/video/pmag-aa-fb.c
+++ b/drivers/video/pmag-aa-fb.c
@@ -150,7 +150,7 @@ static int aafbcon_set_font(struct display *disp, int width, int height)
150{ 150{
151 struct aafb_info *info = (struct aafb_info *)disp->fb_info; 151 struct aafb_info *info = (struct aafb_info *)disp->fb_info;
152 struct aafb_cursor *c = &info->cursor; 152 struct aafb_cursor *c = &info->cursor;
153 u8 fgc = ~attr_bgcol_ec(disp, disp->conp); 153 u8 fgc = ~attr_bgcol_ec(disp, disp->conp, &info->info);
154 154
155 if (width > 64 || height > 64 || width < 0 || height < 0) 155 if (width > 64 || height > 64 || width < 0 || height < 0)
156 return -EINVAL; 156 return -EINVAL;
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 044a423a72cb..dc3af1c78c56 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -57,8 +57,6 @@
57#define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64) 57#define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64)
58#define GPU_MAX_LINE_LENGTH (65536 - 64) 58#define GPU_MAX_LINE_LENGTH (65536 - 64)
59 59
60#define PS3FB_FULL_MODE_BIT 0x80
61
62#define GPU_INTR_STATUS_VSYNC_0 0 /* vsync on head A */ 60#define GPU_INTR_STATUS_VSYNC_0 0 /* vsync on head A */
63#define GPU_INTR_STATUS_VSYNC_1 1 /* vsync on head B */ 61#define GPU_INTR_STATUS_VSYNC_1 1 /* vsync on head B */
64#define GPU_INTR_STATUS_FLIP_0 3 /* flip head A */ 62#define GPU_INTR_STATUS_FLIP_0 3 /* flip head A */
@@ -118,8 +116,6 @@ struct ps3fb_priv {
118 unsigned int irq_no; 116 unsigned int irq_no;
119 117
120 u64 context_handle, memory_handle; 118 u64 context_handle, memory_handle;
121 void *xdr_ea;
122 size_t xdr_size;
123 struct gpu_driver_info *dinfo; 119 struct gpu_driver_info *dinfo;
124 120
125 u64 vblank_count; /* frame count */ 121 u64 vblank_count; /* frame count */
@@ -136,42 +132,19 @@ static struct ps3fb_priv ps3fb;
136struct ps3fb_par { 132struct ps3fb_par {
137 u32 pseudo_palette[16]; 133 u32 pseudo_palette[16];
138 int mode_id, new_mode_id; 134 int mode_id, new_mode_id;
139 int res_index;
140 unsigned int num_frames; /* num of frame buffers */ 135 unsigned int num_frames; /* num of frame buffers */
141 unsigned int width; 136 unsigned int width;
142 unsigned int height; 137 unsigned int height;
143 unsigned long full_offset; /* start of fullscreen DDR fb */ 138 unsigned int ddr_line_length;
144 unsigned long fb_offset; /* start of actual DDR fb */ 139 unsigned int ddr_frame_size;
145 unsigned long pan_offset; 140 unsigned int xdr_frame_size;
141 unsigned int full_offset; /* start of fullscreen DDR fb */
142 unsigned int fb_offset; /* start of actual DDR fb */
143 unsigned int pan_offset;
146}; 144};
147 145
148struct ps3fb_res_table { 146
149 u32 xres; 147#define FIRST_NATIVE_MODE_INDEX 10
150 u32 yres;
151 u32 xoff;
152 u32 yoff;
153 u32 type;
154};
155#define PS3FB_RES_FULL 1
156static const struct ps3fb_res_table ps3fb_res[] = {
157 /* res_x,y margin_x,y full */
158 { 720, 480, 72, 48 , 0},
159 { 720, 576, 72, 58 , 0},
160 { 1280, 720, 78, 38 , 0},
161 { 1920, 1080, 116, 58 , 0},
162 /* full mode */
163 { 720, 480, 0, 0 , PS3FB_RES_FULL},
164 { 720, 576, 0, 0 , PS3FB_RES_FULL},
165 { 1280, 720, 0, 0 , PS3FB_RES_FULL},
166 { 1920, 1080, 0, 0 , PS3FB_RES_FULL},
167 /* vesa: normally full mode */
168 { 1280, 768, 0, 0 , 0},
169 { 1280, 1024, 0, 0 , 0},
170 { 1920, 1200, 0, 0 , 0},
171 { 0, 0, 0, 0 , 0} };
172
173/* default resolution */
174#define GPU_RES_INDEX 0 /* 720 x 480 */
175 148
176static const struct fb_videomode ps3fb_modedb[] = { 149static const struct fb_videomode ps3fb_modedb[] = {
177 /* 60 Hz broadcast modes (modes "1" to "5") */ 150 /* 60 Hz broadcast modes (modes "1" to "5") */
@@ -211,7 +184,7 @@ static const struct fb_videomode ps3fb_modedb[] = {
211 "720p", 50, 1124, 644, 13468, 298, 478, 57, 44, 80, 5, 184 "720p", 50, 1124, 644, 13468, 298, 478, 57, 44, 80, 5,
212 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 185 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
213 }, { 186 }, {
214 /* 1080 */ 187 /* 1080i */
215 "1080i", 50, 1688, 964, 13468, 264, 600, 94, 62, 88, 5, 188 "1080i", 50, 1688, 964, 13468, 264, 600, 94, 62, 88, 5,
216 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED 189 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
217 }, { 190 }, {
@@ -220,24 +193,7 @@ static const struct fb_videomode ps3fb_modedb[] = {
220 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 193 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
221 }, 194 },
222 195
223 /* VESA modes (modes "11" to "13") */ 196 [FIRST_NATIVE_MODE_INDEX] =
224 {
225 /* WXGA */
226 "wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6,
227 0, FB_VMODE_NONINTERLACED,
228 FB_MODE_IS_VESA
229 }, {
230 /* SXGA */
231 "sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
232 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED,
233 FB_MODE_IS_VESA
234 }, {
235 /* WUXGA */
236 "wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6,
237 FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED,
238 FB_MODE_IS_VESA
239 },
240
241 /* 60 Hz broadcast modes (full resolution versions of modes "1" to "5") */ 197 /* 60 Hz broadcast modes (full resolution versions of modes "1" to "5") */
242 { 198 {
243 /* 480if */ 199 /* 480if */
@@ -276,12 +232,30 @@ static const struct fb_videomode ps3fb_modedb[] = {
276 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 232 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
277 }, { 233 }, {
278 /* 1080if */ 234 /* 1080if */
279 "1080f", 50, 1920, 1080, 13468, 148, 484, 36, 4, 88, 5, 235 "1080if", 50, 1920, 1080, 13468, 148, 484, 36, 4, 88, 5,
280 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED 236 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
281 }, { 237 }, {
282 /* 1080pf */ 238 /* 1080pf */
283 "1080pf", 50, 1920, 1080, 6734, 148, 484, 36, 4, 88, 5, 239 "1080pf", 50, 1920, 1080, 6734, 148, 484, 36, 4, 88, 5,
284 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 240 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
241 },
242
243 /* VESA modes (modes "11" to "13") */
244 {
245 /* WXGA */
246 "wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6,
247 0, FB_VMODE_NONINTERLACED,
248 FB_MODE_IS_VESA
249 }, {
250 /* SXGA */
251 "sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED,
253 FB_MODE_IS_VESA
254 }, {
255 /* WUXGA */
256 "wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6,
257 FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED,
258 FB_MODE_IS_VESA
285 } 259 }
286}; 260};
287 261
@@ -289,110 +263,188 @@ static const struct fb_videomode ps3fb_modedb[] = {
289#define HEAD_A 263#define HEAD_A
290#define HEAD_B 264#define HEAD_B
291 265
292#define X_OFF(i) (ps3fb_res[i].xoff) /* left/right margin (pixel) */
293#define Y_OFF(i) (ps3fb_res[i].yoff) /* top/bottom margin (pixel) */
294#define WIDTH(i) (ps3fb_res[i].xres) /* width of FB */
295#define HEIGHT(i) (ps3fb_res[i].yres) /* height of FB */
296#define BPP 4 /* number of bytes per pixel */ 266#define BPP 4 /* number of bytes per pixel */
297 267
298/* Start of the virtual frame buffer (relative to fullscreen ) */
299#define VP_OFF(i) ((WIDTH(i) * Y_OFF(i) + X_OFF(i)) * BPP)
300
301 268
302static int ps3fb_mode; 269static int ps3fb_mode;
303module_param(ps3fb_mode, int, 0); 270module_param(ps3fb_mode, int, 0);
304 271
305static char *mode_option __devinitdata; 272static char *mode_option __devinitdata;
306 273
307static int ps3fb_get_res_table(u32 xres, u32 yres, int mode) 274static int ps3fb_cmp_mode(const struct fb_videomode *vmode,
275 const struct fb_var_screeninfo *var)
308{ 276{
309 int full_mode; 277 long xres, yres, left_margin, right_margin, upper_margin, lower_margin;
310 unsigned int i; 278 long dx, dy;
311 u32 x, y, f; 279
312 280 /* maximum values */
313 full_mode = (mode & PS3FB_FULL_MODE_BIT) ? PS3FB_RES_FULL : 0; 281 if (var->xres > vmode->xres || var->yres > vmode->yres ||
314 for (i = 0;; i++) { 282 var->pixclock > vmode->pixclock ||
315 x = ps3fb_res[i].xres; 283 var->hsync_len > vmode->hsync_len ||
316 y = ps3fb_res[i].yres; 284 var->vsync_len > vmode->vsync_len)
317 f = ps3fb_res[i].type; 285 return -1;
318
319 if (!x) {
320 pr_debug("ERROR: ps3fb_get_res_table()\n");
321 return -1;
322 }
323 286
324 if (full_mode == PS3FB_RES_FULL && f != PS3FB_RES_FULL) 287 /* progressive/interlaced must match */
325 continue; 288 if ((var->vmode & FB_VMODE_MASK) != vmode->vmode)
289 return -1;
326 290
327 if (x == xres && (yres == 0 || y == yres)) 291 /* minimum resolution */
328 break; 292 xres = max(var->xres, 1U);
293 yres = max(var->yres, 1U);
294
295 /* minimum margins */
296 left_margin = max(var->left_margin, vmode->left_margin);
297 right_margin = max(var->right_margin, vmode->right_margin);
298 upper_margin = max(var->upper_margin, vmode->upper_margin);
299 lower_margin = max(var->lower_margin, vmode->lower_margin);
300
301 /* resolution + margins may not exceed native parameters */
302 dx = ((long)vmode->left_margin + (long)vmode->xres +
303 (long)vmode->right_margin) -
304 (left_margin + xres + right_margin);
305 if (dx < 0)
306 return -1;
329 307
330 x = x - 2 * ps3fb_res[i].xoff; 308 dy = ((long)vmode->upper_margin + (long)vmode->yres +
331 y = y - 2 * ps3fb_res[i].yoff; 309 (long)vmode->lower_margin) -
332 if (x == xres && (yres == 0 || y == yres)) 310 (upper_margin + yres + lower_margin);
333 break; 311 if (dy < 0)
312 return -1;
313
314 /* exact match */
315 if (!dx && !dy)
316 return 0;
317
318 /* resolution difference */
319 return (vmode->xres - xres) * (vmode->yres - yres);
320}
321
322static const struct fb_videomode *ps3fb_native_vmode(enum ps3av_mode_num id)
323{
324 return &ps3fb_modedb[FIRST_NATIVE_MODE_INDEX + id - 1];
325}
326
327static const struct fb_videomode *ps3fb_vmode(int id)
328{
329 u32 mode = id & PS3AV_MODE_MASK;
330
331 if (mode < PS3AV_MODE_480I || mode > PS3AV_MODE_WUXGA)
332 return NULL;
333
334 if (mode <= PS3AV_MODE_1080P50 && !(id & PS3AV_MODE_FULL)) {
335 /* Non-fullscreen broadcast mode */
336 return &ps3fb_modedb[mode - 1];
334 } 337 }
335 return i; 338
339 return ps3fb_native_vmode(mode);
336} 340}
337 341
338static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var, 342static unsigned int ps3fb_find_mode(struct fb_var_screeninfo *var,
339 u32 *ddr_line_length, u32 *xdr_line_length) 343 u32 *ddr_line_length, u32 *xdr_line_length)
340{ 344{
341 unsigned int i, mode; 345 unsigned int id, best_id;
342 346 int diff, best_diff;
343 for (i = 0; i < ARRAY_SIZE(ps3fb_modedb); i++) 347 const struct fb_videomode *vmode;
344 if (var->xres == ps3fb_modedb[i].xres && 348 long gap;
345 var->yres == ps3fb_modedb[i].yres && 349
346 var->pixclock == ps3fb_modedb[i].pixclock && 350 best_id = 0;
347 var->hsync_len == ps3fb_modedb[i].hsync_len && 351 best_diff = INT_MAX;
348 var->vsync_len == ps3fb_modedb[i].vsync_len && 352 pr_debug("%s: wanted %u [%u] %u x %u [%u] %u\n", __func__,
349 var->left_margin == ps3fb_modedb[i].left_margin && 353 var->left_margin, var->xres, var->right_margin,
350 var->right_margin == ps3fb_modedb[i].right_margin && 354 var->upper_margin, var->yres, var->lower_margin);
351 var->upper_margin == ps3fb_modedb[i].upper_margin && 355 for (id = PS3AV_MODE_480I; id <= PS3AV_MODE_WUXGA; id++) {
352 var->lower_margin == ps3fb_modedb[i].lower_margin && 356 vmode = ps3fb_native_vmode(id);
353 var->sync == ps3fb_modedb[i].sync && 357 diff = ps3fb_cmp_mode(vmode, var);
354 (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode) 358 pr_debug("%s: mode %u: %u [%u] %u x %u [%u] %u: diff = %d\n",
355 goto found; 359 __func__, id, vmode->left_margin, vmode->xres,
356 360 vmode->right_margin, vmode->upper_margin,
357 pr_debug("ps3fb_find_mode: mode not found\n"); 361 vmode->yres, vmode->lower_margin, diff);
358 return 0; 362 if (diff < 0)
363 continue;
364 if (diff < best_diff) {
365 best_id = id;
366 if (!diff)
367 break;
368 best_diff = diff;
369 }
370 }
359 371
360found: 372 if (!best_id) {
361 /* Cropped broadcast modes use the full line length */ 373 pr_debug("%s: no suitable mode found\n", __func__);
362 *ddr_line_length = ps3fb_modedb[i < 10 ? i + 13 : i].xres * BPP; 374 return 0;
375 }
363 376
364 if (ps3_compare_firmware_version(1, 9, 0) >= 0) { 377 id = best_id;
365 *xdr_line_length = GPU_ALIGN_UP(max(var->xres, 378 vmode = ps3fb_native_vmode(id);
366 var->xres_virtual) * BPP);
367 if (*xdr_line_length > GPU_MAX_LINE_LENGTH)
368 *xdr_line_length = GPU_MAX_LINE_LENGTH;
369 } else
370 *xdr_line_length = *ddr_line_length;
371 379
372 /* Full broadcast modes have the full mode bit set */ 380 *ddr_line_length = vmode->xres * BPP;
373 mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
374 381
375 pr_debug("ps3fb_find_mode: mode %u\n", mode); 382 /* minimum resolution */
383 if (!var->xres)
384 var->xres = 1;
385 if (!var->yres)
386 var->yres = 1;
376 387
377 return mode; 388 /* minimum virtual resolution */
378} 389 if (var->xres_virtual < var->xres)
390 var->xres_virtual = var->xres;
391 if (var->yres_virtual < var->yres)
392 var->yres_virtual = var->yres;
379 393
380static const struct fb_videomode *ps3fb_default_mode(int id) 394 /* minimum margins */
381{ 395 if (var->left_margin < vmode->left_margin)
382 u32 mode = id & PS3AV_MODE_MASK; 396 var->left_margin = vmode->left_margin;
383 u32 flags; 397 if (var->right_margin < vmode->right_margin)
398 var->right_margin = vmode->right_margin;
399 if (var->upper_margin < vmode->upper_margin)
400 var->upper_margin = vmode->upper_margin;
401 if (var->lower_margin < vmode->lower_margin)
402 var->lower_margin = vmode->lower_margin;
403
404 /* extra margins */
405 gap = ((long)vmode->left_margin + (long)vmode->xres +
406 (long)vmode->right_margin) -
407 ((long)var->left_margin + (long)var->xres +
408 (long)var->right_margin);
409 if (gap > 0) {
410 var->left_margin += gap/2;
411 var->right_margin += (gap+1)/2;
412 pr_debug("%s: rounded up H to %u [%u] %u\n", __func__,
413 var->left_margin, var->xres, var->right_margin);
414 }
384 415
385 if (mode < 1 || mode > 13) 416 gap = ((long)vmode->upper_margin + (long)vmode->yres +
386 return NULL; 417 (long)vmode->lower_margin) -
418 ((long)var->upper_margin + (long)var->yres +
419 (long)var->lower_margin);
420 if (gap > 0) {
421 var->upper_margin += gap/2;
422 var->lower_margin += (gap+1)/2;
423 pr_debug("%s: rounded up V to %u [%u] %u\n", __func__,
424 var->upper_margin, var->yres, var->lower_margin);
425 }
426
427 /* fixed fields */
428 var->pixclock = vmode->pixclock;
429 var->hsync_len = vmode->hsync_len;
430 var->vsync_len = vmode->vsync_len;
431 var->sync = vmode->sync;
387 432
388 flags = id & ~PS3AV_MODE_MASK; 433 if (ps3_compare_firmware_version(1, 9, 0) >= 0) {
434 *xdr_line_length = GPU_ALIGN_UP(var->xres_virtual * BPP);
435 if (*xdr_line_length > GPU_MAX_LINE_LENGTH)
436 *xdr_line_length = GPU_MAX_LINE_LENGTH;
437 } else
438 *xdr_line_length = *ddr_line_length;
389 439
390 if (mode <= 10 && flags & PS3FB_FULL_MODE_BIT) { 440 if (vmode->sync & FB_SYNC_BROADCAST) {
391 /* Full broadcast mode */ 441 /* Full broadcast modes have the full mode bit set */
392 return &ps3fb_modedb[mode + 12]; 442 if (vmode->xres == var->xres && vmode->yres == var->yres)
443 id |= PS3AV_MODE_FULL;
393 } 444 }
394 445
395 return &ps3fb_modedb[mode - 1]; 446 pr_debug("%s: mode %u\n", __func__, id);
447 return id;
396} 448}
397 449
398static void ps3fb_sync_image(struct device *dev, u64 frame_offset, 450static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
@@ -439,8 +491,7 @@ static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
439static int ps3fb_sync(struct fb_info *info, u32 frame) 491static int ps3fb_sync(struct fb_info *info, u32 frame)
440{ 492{
441 struct ps3fb_par *par = info->par; 493 struct ps3fb_par *par = info->par;
442 int i, error = 0; 494 int error = 0;
443 u32 ddr_line_length, xdr_line_length;
444 u64 ddr_base, xdr_base; 495 u64 ddr_base, xdr_base;
445 496
446 if (frame > par->num_frames - 1) { 497 if (frame > par->num_frames - 1) {
@@ -450,16 +501,13 @@ static int ps3fb_sync(struct fb_info *info, u32 frame)
450 goto out; 501 goto out;
451 } 502 }
452 503
453 i = par->res_index; 504 xdr_base = frame * par->xdr_frame_size;
454 xdr_line_length = info->fix.line_length; 505 ddr_base = frame * par->ddr_frame_size;
455 ddr_line_length = ps3fb_res[i].xres * BPP;
456 xdr_base = frame * info->var.yres_virtual * xdr_line_length;
457 ddr_base = frame * ps3fb_res[i].yres * ddr_line_length;
458 506
459 ps3fb_sync_image(info->device, ddr_base + par->full_offset, 507 ps3fb_sync_image(info->device, ddr_base + par->full_offset,
460 ddr_base + par->fb_offset, xdr_base + par->pan_offset, 508 ddr_base + par->fb_offset, xdr_base + par->pan_offset,
461 par->width, par->height, ddr_line_length, 509 par->width, par->height, par->ddr_line_length,
462 xdr_line_length); 510 info->fix.line_length);
463 511
464out: 512out:
465 return error; 513 return error;
@@ -498,22 +546,11 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
498 u32 xdr_line_length, ddr_line_length; 546 u32 xdr_line_length, ddr_line_length;
499 int mode; 547 int mode;
500 548
501 dev_dbg(info->device, "var->xres:%u info->var.xres:%u\n", var->xres,
502 info->var.xres);
503 dev_dbg(info->device, "var->yres:%u info->var.yres:%u\n", var->yres,
504 info->var.yres);
505
506 /* FIXME For now we do exact matches only */
507 mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length); 549 mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length);
508 if (!mode) 550 if (!mode)
509 return -EINVAL; 551 return -EINVAL;
510 552
511 /* Virtual screen */ 553 /* Virtual screen */
512 if (var->xres_virtual < var->xres)
513 var->xres_virtual = var->xres;
514 if (var->yres_virtual < var->yres)
515 var->yres_virtual = var->yres;
516
517 if (var->xres_virtual > xdr_line_length / BPP) { 554 if (var->xres_virtual > xdr_line_length / BPP) {
518 dev_dbg(info->device, 555 dev_dbg(info->device,
519 "Horizontal virtual screen size too large\n"); 556 "Horizontal virtual screen size too large\n");
@@ -559,7 +596,7 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
559 } 596 }
560 597
561 /* Memory limit */ 598 /* Memory limit */
562 if (var->yres_virtual * xdr_line_length > ps3fb.xdr_size) { 599 if (var->yres_virtual * xdr_line_length > info->fix.smem_len) {
563 dev_dbg(info->device, "Not enough memory\n"); 600 dev_dbg(info->device, "Not enough memory\n");
564 return -ENOMEM; 601 return -ENOMEM;
565 } 602 }
@@ -578,39 +615,38 @@ static int ps3fb_set_par(struct fb_info *info)
578{ 615{
579 struct ps3fb_par *par = info->par; 616 struct ps3fb_par *par = info->par;
580 unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines; 617 unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines;
581 int i; 618 unsigned int ddr_xoff, ddr_yoff, offset;
582 unsigned long offset; 619 const struct fb_videomode *vmode;
583 u64 dst; 620 u64 dst;
584 621
585 dev_dbg(info->device, "xres:%d xv:%d yres:%d yv:%d clock:%d\n",
586 info->var.xres, info->var.xres_virtual,
587 info->var.yres, info->var.yres_virtual, info->var.pixclock);
588
589 mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length); 622 mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length);
590 if (!mode) 623 if (!mode)
591 return -EINVAL; 624 return -EINVAL;
592 625
593 i = ps3fb_get_res_table(info->var.xres, info->var.yres, mode); 626 vmode = ps3fb_native_vmode(mode & PS3AV_MODE_MASK);
594 par->res_index = i;
595 627
596 info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
597 info->fix.smem_len = ps3fb.xdr_size;
598 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; 628 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
599 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; 629 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
600 info->fix.line_length = xdr_line_length; 630 info->fix.line_length = xdr_line_length;
601 631
602 info->screen_base = (char __iomem *)ps3fb.xdr_ea; 632 par->ddr_line_length = ddr_line_length;
633 par->ddr_frame_size = vmode->yres * ddr_line_length;
634 par->xdr_frame_size = info->var.yres_virtual * xdr_line_length;
603 635
604 par->num_frames = ps3fb.xdr_size / 636 par->num_frames = info->fix.smem_len /
605 max(ps3fb_res[i].yres * ddr_line_length, 637 max(par->ddr_frame_size, par->xdr_frame_size);
606 info->var.yres_virtual * xdr_line_length);
607 638
608 /* Keep the special bits we cannot set using fb_var_screeninfo */ 639 /* Keep the special bits we cannot set using fb_var_screeninfo */
609 par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode; 640 par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode;
610 641
611 par->width = info->var.xres; 642 par->width = info->var.xres;
612 par->height = info->var.yres; 643 par->height = info->var.yres;
613 offset = VP_OFF(i); 644
645 /* Start of the virtual frame buffer (relative to fullscreen) */
646 ddr_xoff = info->var.left_margin - vmode->left_margin;
647 ddr_yoff = info->var.upper_margin - vmode->upper_margin;
648 offset = ddr_yoff * ddr_line_length + ddr_xoff * BPP;
649
614 par->fb_offset = GPU_ALIGN_UP(offset); 650 par->fb_offset = GPU_ALIGN_UP(offset);
615 par->full_offset = par->fb_offset - offset; 651 par->full_offset = par->fb_offset - offset;
616 par->pan_offset = info->var.yoffset * xdr_line_length + 652 par->pan_offset = info->var.yoffset * xdr_line_length +
@@ -625,16 +661,16 @@ static int ps3fb_set_par(struct fb_info *info)
625 } 661 }
626 662
627 /* Clear XDR frame buffer memory */ 663 /* Clear XDR frame buffer memory */
628 memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size); 664 memset((void __force *)info->screen_base, 0, info->fix.smem_len);
629 665
630 /* Clear DDR frame buffer memory */ 666 /* Clear DDR frame buffer memory */
631 lines = ps3fb_res[i].yres * par->num_frames; 667 lines = vmode->yres * par->num_frames;
632 if (par->full_offset) 668 if (par->full_offset)
633 lines++; 669 lines++;
634 maxlines = ps3fb.xdr_size / ddr_line_length; 670 maxlines = info->fix.smem_len / ddr_line_length;
635 for (dst = 0; lines; dst += maxlines * ddr_line_length) { 671 for (dst = 0; lines; dst += maxlines * ddr_line_length) {
636 unsigned int l = min(lines, maxlines); 672 unsigned int l = min(lines, maxlines);
637 ps3fb_sync_image(info->device, 0, dst, 0, ps3fb_res[i].xres, l, 673 ps3fb_sync_image(info->device, 0, dst, 0, vmode->xres, l,
638 ddr_line_length, ddr_line_length); 674 ddr_line_length, ddr_line_length);
639 lines -= l; 675 lines -= l;
640 } 676 }
@@ -797,7 +833,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
797 case PS3FB_IOCTL_SETMODE: 833 case PS3FB_IOCTL_SETMODE:
798 { 834 {
799 struct ps3fb_par *par = info->par; 835 struct ps3fb_par *par = info->par;
800 const struct fb_videomode *mode; 836 const struct fb_videomode *vmode;
801 struct fb_var_screeninfo var; 837 struct fb_var_screeninfo var;
802 838
803 if (copy_from_user(&val, argp, sizeof(val))) 839 if (copy_from_user(&val, argp, sizeof(val)))
@@ -810,10 +846,10 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
810 } 846 }
811 dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val); 847 dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val);
812 retval = -EINVAL; 848 retval = -EINVAL;
813 mode = ps3fb_default_mode(val); 849 vmode = ps3fb_vmode(val);
814 if (mode) { 850 if (vmode) {
815 var = info->var; 851 var = info->var;
816 fb_videomode_to_var(&var, mode); 852 fb_videomode_to_var(&var, vmode);
817 acquire_console_sem(); 853 acquire_console_sem();
818 info->flags |= FBINFO_MISC_USEREVENT; 854 info->flags |= FBINFO_MISC_USEREVENT;
819 /* Force, in case only special bits changed */ 855 /* Force, in case only special bits changed */
@@ -975,10 +1011,9 @@ static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev)
975 __func__, status); 1011 __func__, status);
976 return -ENXIO; 1012 return -ENXIO;
977 } 1013 }
978 dev_dbg(dev, 1014 dev_dbg(dev, "video:%p ioif:%lx lpar:%lx size:%lx\n",
979 "video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n", 1015 ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
980 ps3fb_videomemory.address, ps3fb.xdr_ea, GPU_IOIF, xdr_lpar, 1016 ps3fb_videomemory.size);
981 virt_to_abs(ps3fb.xdr_ea), ps3fb_videomemory.size);
982 1017
983 status = lv1_gpu_context_attribute(ps3fb.context_handle, 1018 status = lv1_gpu_context_attribute(ps3fb.context_handle,
984 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP, 1019 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
@@ -1055,14 +1090,14 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1055 struct fb_info *info; 1090 struct fb_info *info;
1056 struct ps3fb_par *par; 1091 struct ps3fb_par *par;
1057 int retval = -ENOMEM; 1092 int retval = -ENOMEM;
1058 u32 xres, yres;
1059 u64 ddr_lpar = 0; 1093 u64 ddr_lpar = 0;
1060 u64 lpar_dma_control = 0; 1094 u64 lpar_dma_control = 0;
1061 u64 lpar_driver_info = 0; 1095 u64 lpar_driver_info = 0;
1062 u64 lpar_reports = 0; 1096 u64 lpar_reports = 0;
1063 u64 lpar_reports_size = 0; 1097 u64 lpar_reports_size = 0;
1064 u64 xdr_lpar; 1098 u64 xdr_lpar;
1065 int status, res_index; 1099 void *fb_start;
1100 int status;
1066 struct task_struct *task; 1101 struct task_struct *task;
1067 unsigned long max_ps3fb_size; 1102 unsigned long max_ps3fb_size;
1068 1103
@@ -1080,14 +1115,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1080 1115
1081 if (!ps3fb_mode) 1116 if (!ps3fb_mode)
1082 ps3fb_mode = ps3av_get_mode(); 1117 ps3fb_mode = ps3av_get_mode();
1083 dev_dbg(&dev->core, "ps3av_mode:%d\n", ps3fb_mode); 1118 dev_dbg(&dev->core, "ps3fb_mode: %d\n", ps3fb_mode);
1084
1085 if (ps3fb_mode > 0 &&
1086 !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
1087 res_index = ps3fb_get_res_table(xres, yres, ps3fb_mode);
1088 dev_dbg(&dev->core, "res_index:%d\n", res_index);
1089 } else
1090 res_index = GPU_RES_INDEX;
1091 1119
1092 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */ 1120 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
1093 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ 1121 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
@@ -1124,7 +1152,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1124 } 1152 }
1125 1153
1126 /* vsync interrupt */ 1154 /* vsync interrupt */
1127 ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024); 1155 ps3fb.dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024);
1128 if (!ps3fb.dinfo) { 1156 if (!ps3fb.dinfo) {
1129 dev_err(&dev->core, "%s: ioremap failed\n", __func__); 1157 dev_err(&dev->core, "%s: ioremap failed\n", __func__);
1130 goto err_gpu_context_free; 1158 goto err_gpu_context_free;
@@ -1134,22 +1162,10 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1134 if (retval) 1162 if (retval)
1135 goto err_iounmap_dinfo; 1163 goto err_iounmap_dinfo;
1136 1164
1137 /* XDR frame buffer */
1138 ps3fb.xdr_ea = ps3fb_videomemory.address;
1139 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea));
1140
1141 /* Clear memory to prevent kernel info leakage into userspace */ 1165 /* Clear memory to prevent kernel info leakage into userspace */
1142 memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size); 1166 memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size);
1143
1144 /*
1145 * The GPU command buffer is at the start of video memory
1146 * As we don't use the full command buffer, we can put the actual
1147 * frame buffer at offset GPU_FB_START and save some precious XDR
1148 * memory
1149 */
1150 ps3fb.xdr_ea += GPU_FB_START;
1151 ps3fb.xdr_size = ps3fb_videomemory.size - GPU_FB_START;
1152 1167
1168 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address));
1153 retval = ps3fb_xdr_settings(xdr_lpar, &dev->core); 1169 retval = ps3fb_xdr_settings(xdr_lpar, &dev->core);
1154 if (retval) 1170 if (retval)
1155 goto err_free_irq; 1171 goto err_free_irq;
@@ -1161,15 +1177,22 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1161 par = info->par; 1177 par = info->par;
1162 par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */ 1178 par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */
1163 par->new_mode_id = ps3fb_mode; 1179 par->new_mode_id = ps3fb_mode;
1164 par->res_index = res_index;
1165 par->num_frames = 1; 1180 par->num_frames = 1;
1166 1181
1167 info->screen_base = (char __iomem *)ps3fb.xdr_ea;
1168 info->fbops = &ps3fb_ops; 1182 info->fbops = &ps3fb_ops;
1169
1170 info->fix = ps3fb_fix; 1183 info->fix = ps3fb_fix;
1171 info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea); 1184
1172 info->fix.smem_len = ps3fb.xdr_size; 1185 /*
1186 * The GPU command buffer is at the start of video memory
1187 * As we don't use the full command buffer, we can put the actual
1188 * frame buffer at offset GPU_FB_START and save some precious XDR
1189 * memory
1190 */
1191 fb_start = ps3fb_videomemory.address + GPU_FB_START;
1192 info->screen_base = (char __force __iomem *)fb_start;
1193 info->fix.smem_start = virt_to_abs(fb_start);
1194 info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START;
1195
1173 info->pseudo_palette = par->pseudo_palette; 1196 info->pseudo_palette = par->pseudo_palette;
1174 info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST | 1197 info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
1175 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; 1198 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
@@ -1180,7 +1203,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1180 1203
1181 if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb, 1204 if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb,
1182 ARRAY_SIZE(ps3fb_modedb), 1205 ARRAY_SIZE(ps3fb_modedb),
1183 ps3fb_default_mode(par->new_mode_id), 32)) { 1206 ps3fb_vmode(par->new_mode_id), 32)) {
1184 retval = -EINVAL; 1207 retval = -EINVAL;
1185 goto err_fb_dealloc; 1208 goto err_fb_dealloc;
1186 } 1209 }
@@ -1194,9 +1217,9 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1194 1217
1195 dev->core.driver_data = info; 1218 dev->core.driver_data = info;
1196 1219
1197 dev_info(info->device, "%s %s, using %lu KiB of video memory\n", 1220 dev_info(info->device, "%s %s, using %u KiB of video memory\n",
1198 dev_driver_string(info->dev), info->dev->bus_id, 1221 dev_driver_string(info->dev), info->dev->bus_id,
1199 ps3fb.xdr_size >> 10); 1222 info->fix.smem_len >> 10);
1200 1223
1201 task = kthread_run(ps3fbd, info, DEVICE_NAME); 1224 task = kthread_run(ps3fbd, info, DEVICE_NAME);
1202 if (IS_ERR(task)) { 1225 if (IS_ERR(task)) {
@@ -1219,7 +1242,7 @@ err_free_irq:
1219 free_irq(ps3fb.irq_no, &dev->core); 1242 free_irq(ps3fb.irq_no, &dev->core);
1220 ps3_irq_plug_destroy(ps3fb.irq_no); 1243 ps3_irq_plug_destroy(ps3fb.irq_no);
1221err_iounmap_dinfo: 1244err_iounmap_dinfo:
1222 iounmap((u8 __iomem *)ps3fb.dinfo); 1245 iounmap((u8 __force __iomem *)ps3fb.dinfo);
1223err_gpu_context_free: 1246err_gpu_context_free:
1224 lv1_gpu_context_free(ps3fb.context_handle); 1247 lv1_gpu_context_free(ps3fb.context_handle);
1225err_gpu_memory_free: 1248err_gpu_memory_free:
@@ -1254,7 +1277,7 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1254 framebuffer_release(info); 1277 framebuffer_release(info);
1255 info = dev->core.driver_data = NULL; 1278 info = dev->core.driver_data = NULL;
1256 } 1279 }
1257 iounmap((u8 __iomem *)ps3fb.dinfo); 1280 iounmap((u8 __force __iomem *)ps3fb.dinfo);
1258 1281
1259 status = lv1_gpu_context_free(ps3fb.context_handle); 1282 status = lv1_gpu_context_free(ps3fb.context_handle);
1260 if (status) 1283 if (status)
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index b3c31d9dc591..71fa6edb5c47 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -110,6 +110,11 @@ static int debug = 0;
110 110
111/* useful functions */ 111/* useful functions */
112 112
113static int is_s3c2412(struct s3c2410fb_info *fbi)
114{
115 return (fbi->drv_type == DRV_S3C2412);
116}
117
113/* s3c2410fb_set_lcdaddr 118/* s3c2410fb_set_lcdaddr
114 * 119 *
115 * initialise lcd controller address pointers 120 * initialise lcd controller address pointers
@@ -501,7 +506,7 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
501{ 506{
502 unsigned long flags; 507 unsigned long flags;
503 unsigned long irqen; 508 unsigned long irqen;
504 void __iomem *regs = fbi->io; 509 void __iomem *irq_base = fbi->irq_base;
505 510
506 local_irq_save(flags); 511 local_irq_save(flags);
507 512
@@ -511,9 +516,9 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
511 fbi->palette_ready = 1; 516 fbi->palette_ready = 1;
512 517
513 /* enable IRQ */ 518 /* enable IRQ */
514 irqen = readl(regs + S3C2410_LCDINTMSK); 519 irqen = readl(irq_base + S3C24XX_LCDINTMSK);
515 irqen &= ~S3C2410_LCDINT_FRSYNC; 520 irqen &= ~S3C2410_LCDINT_FRSYNC;
516 writel(irqen, regs + S3C2410_LCDINTMSK); 521 writel(irqen, irq_base + S3C24XX_LCDINTMSK);
517 } 522 }
518 523
519 local_irq_restore(flags); 524 local_irq_restore(flags);
@@ -594,15 +599,17 @@ static int s3c2410fb_setcolreg(unsigned regno,
594static int s3c2410fb_blank(int blank_mode, struct fb_info *info) 599static int s3c2410fb_blank(int blank_mode, struct fb_info *info)
595{ 600{
596 struct s3c2410fb_info *fbi = info->par; 601 struct s3c2410fb_info *fbi = info->par;
597 void __iomem *regs = fbi->io; 602 void __iomem *tpal_reg = fbi->io;
598 603
599 dprintk("blank(mode=%d, info=%p)\n", blank_mode, info); 604 dprintk("blank(mode=%d, info=%p)\n", blank_mode, info);
600 605
606 tpal_reg += is_s3c2412(fbi) ? S3C2412_TPAL : S3C2410_TPAL;
607
601 if (blank_mode == FB_BLANK_UNBLANK) 608 if (blank_mode == FB_BLANK_UNBLANK)
602 writel(0x0, regs + S3C2410_TPAL); 609 writel(0x0, tpal_reg);
603 else { 610 else {
604 dprintk("setting TPAL to output 0x000000\n"); 611 dprintk("setting TPAL to output 0x000000\n");
605 writel(S3C2410_TPAL_EN, regs + S3C2410_TPAL); 612 writel(S3C2410_TPAL_EN, tpal_reg);
606 } 613 }
607 614
608 return 0; 615 return 0;
@@ -663,7 +670,7 @@ static int __init s3c2410fb_map_video_memory(struct fb_info *info)
663 dma_addr_t map_dma; 670 dma_addr_t map_dma;
664 unsigned map_size = PAGE_ALIGN(info->fix.smem_len); 671 unsigned map_size = PAGE_ALIGN(info->fix.smem_len);
665 672
666 dprintk("map_video_memory(fbi=%p)\n", fbi); 673 dprintk("map_video_memory(fbi=%p) map_size %u\n", fbi, map_size);
667 674
668 info->screen_base = dma_alloc_writecombine(fbi->dev, map_size, 675 info->screen_base = dma_alloc_writecombine(fbi->dev, map_size,
669 &map_dma, GFP_KERNEL); 676 &map_dma, GFP_KERNEL);
@@ -672,7 +679,7 @@ static int __init s3c2410fb_map_video_memory(struct fb_info *info)
672 /* prevent initial garbage on screen */ 679 /* prevent initial garbage on screen */
673 dprintk("map_video_memory: clear %p:%08x\n", 680 dprintk("map_video_memory: clear %p:%08x\n",
674 info->screen_base, map_size); 681 info->screen_base, map_size);
675 memset(info->screen_base, 0xf0, map_size); 682 memset(info->screen_base, 0x00, map_size);
676 683
677 info->fix.smem_start = map_dma; 684 info->fix.smem_start = map_dma;
678 685
@@ -709,6 +716,16 @@ static int s3c2410fb_init_registers(struct fb_info *info)
709 struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data; 716 struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
710 unsigned long flags; 717 unsigned long flags;
711 void __iomem *regs = fbi->io; 718 void __iomem *regs = fbi->io;
719 void __iomem *tpal;
720 void __iomem *lpcsel;
721
722 if (is_s3c2412(fbi)) {
723 tpal = regs + S3C2412_TPAL;
724 lpcsel = regs + S3C2412_TCONSEL;
725 } else {
726 tpal = regs + S3C2410_TPAL;
727 lpcsel = regs + S3C2410_LPCSEL;
728 }
712 729
713 /* Initialise LCD with values from haret */ 730 /* Initialise LCD with values from haret */
714 731
@@ -724,12 +741,12 @@ static int s3c2410fb_init_registers(struct fb_info *info)
724 local_irq_restore(flags); 741 local_irq_restore(flags);
725 742
726 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel); 743 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel);
727 writel(mach_info->lpcsel, regs + S3C2410_LPCSEL); 744 writel(mach_info->lpcsel, lpcsel);
728 745
729 dprintk("replacing TPAL %08x\n", readl(regs + S3C2410_TPAL)); 746 dprintk("replacing TPAL %08x\n", readl(tpal));
730 747
731 /* ensure temporary palette disabled */ 748 /* ensure temporary palette disabled */
732 writel(0x00, regs + S3C2410_TPAL); 749 writel(0x00, tpal);
733 750
734 return 0; 751 return 0;
735} 752}
@@ -763,15 +780,15 @@ static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
763static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) 780static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
764{ 781{
765 struct s3c2410fb_info *fbi = dev_id; 782 struct s3c2410fb_info *fbi = dev_id;
766 void __iomem *regs = fbi->io; 783 void __iomem *irq_base = fbi->irq_base;
767 unsigned long lcdirq = readl(regs + S3C2410_LCDINTPND); 784 unsigned long lcdirq = readl(irq_base + S3C24XX_LCDINTPND);
768 785
769 if (lcdirq & S3C2410_LCDINT_FRSYNC) { 786 if (lcdirq & S3C2410_LCDINT_FRSYNC) {
770 if (fbi->palette_ready) 787 if (fbi->palette_ready)
771 s3c2410fb_write_palette(fbi); 788 s3c2410fb_write_palette(fbi);
772 789
773 writel(S3C2410_LCDINT_FRSYNC, regs + S3C2410_LCDINTPND); 790 writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDINTPND);
774 writel(S3C2410_LCDINT_FRSYNC, regs + S3C2410_LCDSRCPND); 791 writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDSRCPND);
775 } 792 }
776 793
777 return IRQ_HANDLED; 794 return IRQ_HANDLED;
@@ -779,7 +796,8 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
779 796
780static char driver_name[] = "s3c2410fb"; 797static char driver_name[] = "s3c2410fb";
781 798
782static int __init s3c2410fb_probe(struct platform_device *pdev) 799static int __init s3c24xxfb_probe(struct platform_device *pdev,
800 enum s3c_drv_type drv_type)
783{ 801{
784 struct s3c2410fb_info *info; 802 struct s3c2410fb_info *info;
785 struct s3c2410fb_display *display; 803 struct s3c2410fb_display *display;
@@ -799,6 +817,12 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
799 return -EINVAL; 817 return -EINVAL;
800 } 818 }
801 819
820 if (mach_info->default_display >= mach_info->num_displays) {
821 dev_err(&pdev->dev, "default is %d but only %d displays\n",
822 mach_info->default_display, mach_info->num_displays);
823 return -EINVAL;
824 }
825
802 display = mach_info->displays + mach_info->default_display; 826 display = mach_info->displays + mach_info->default_display;
803 827
804 irq = platform_get_irq(pdev, 0); 828 irq = platform_get_irq(pdev, 0);
@@ -815,6 +839,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
815 839
816 info = fbinfo->par; 840 info = fbinfo->par;
817 info->dev = &pdev->dev; 841 info->dev = &pdev->dev;
842 info->drv_type = drv_type;
818 843
819 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 844 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
820 if (res == NULL) { 845 if (res == NULL) {
@@ -838,6 +863,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
838 goto release_mem; 863 goto release_mem;
839 } 864 }
840 865
866 info->irq_base = info->io + ((drv_type == DRV_S3C2412) ? S3C2412_LCDINTBASE : S3C2410_LCDINTBASE);
867
841 dprintk("devinit\n"); 868 dprintk("devinit\n");
842 869
843 strcpy(fbinfo->fix.id, driver_name); 870 strcpy(fbinfo->fix.id, driver_name);
@@ -946,6 +973,16 @@ dealloc_fb:
946 return ret; 973 return ret;
947} 974}
948 975
976static int __init s3c2410fb_probe(struct platform_device *pdev)
977{
978 return s3c24xxfb_probe(pdev, DRV_S3C2410);
979}
980
981static int __init s3c2412fb_probe(struct platform_device *pdev)
982{
983 return s3c24xxfb_probe(pdev, DRV_S3C2412);
984}
985
949/* s3c2410fb_stop_lcd 986/* s3c2410fb_stop_lcd
950 * 987 *
951 * shutdown the lcd controller 988 * shutdown the lcd controller
@@ -1047,14 +1084,31 @@ static struct platform_driver s3c2410fb_driver = {
1047 }, 1084 },
1048}; 1085};
1049 1086
1087static struct platform_driver s3c2412fb_driver = {
1088 .probe = s3c2412fb_probe,
1089 .remove = s3c2410fb_remove,
1090 .suspend = s3c2410fb_suspend,
1091 .resume = s3c2410fb_resume,
1092 .driver = {
1093 .name = "s3c2412-lcd",
1094 .owner = THIS_MODULE,
1095 },
1096};
1097
1050int __init s3c2410fb_init(void) 1098int __init s3c2410fb_init(void)
1051{ 1099{
1052 return platform_driver_register(&s3c2410fb_driver); 1100 int ret = platform_driver_register(&s3c2410fb_driver);
1101
1102 if (ret == 0)
1103 ret = platform_driver_register(&s3c2412fb_driver);;
1104
1105 return ret;
1053} 1106}
1054 1107
1055static void __exit s3c2410fb_cleanup(void) 1108static void __exit s3c2410fb_cleanup(void)
1056{ 1109{
1057 platform_driver_unregister(&s3c2410fb_driver); 1110 platform_driver_unregister(&s3c2410fb_driver);
1111 platform_driver_unregister(&s3c2412fb_driver);
1058} 1112}
1059 1113
1060module_init(s3c2410fb_init); 1114module_init(s3c2410fb_init);
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h
index 6ce5dc26c5f7..dbb73b95e2ef 100644
--- a/drivers/video/s3c2410fb.h
+++ b/drivers/video/s3c2410fb.h
@@ -25,13 +25,20 @@
25#ifndef __S3C2410FB_H 25#ifndef __S3C2410FB_H
26#define __S3C2410FB_H 26#define __S3C2410FB_H
27 27
28enum s3c_drv_type {
29 DRV_S3C2410,
30 DRV_S3C2412,
31};
32
28struct s3c2410fb_info { 33struct s3c2410fb_info {
29 struct device *dev; 34 struct device *dev;
30 struct clk *clk; 35 struct clk *clk;
31 36
32 struct resource *mem; 37 struct resource *mem;
33 void __iomem *io; 38 void __iomem *io;
39 void __iomem *irq_base;
34 40
41 enum s3c_drv_type drv_type;
35 struct s3c2410fb_hw regs; 42 struct s3c2410fb_hw regs;
36 43
37 unsigned int palette_ready; 44 unsigned int palette_ready;
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 93ae747440cb..73803624c131 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -427,7 +427,7 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
427 427
428 monitor->feature = buffer[0x18]; 428 monitor->feature = buffer[0x18];
429 429
430 if(!buffer[0x14] & 0x80) { 430 if(!(buffer[0x14] & 0x80)) {
431 if(!(buffer[0x14] & 0x08)) { 431 if(!(buffer[0x14] & 0x08)) {
432 printk(KERN_INFO 432 printk(KERN_INFO
433 "sisfb: WARNING: Monitor does not support separate syncs\n"); 433 "sisfb: WARNING: Monitor does not support separate syncs\n");
@@ -4621,9 +4621,9 @@ sisfb_find_host_bridge(struct sis_video_info *ivideo, struct pci_dev *mypdev,
4621 4621
4622 while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) { 4622 while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) {
4623 temp = pdev->vendor; 4623 temp = pdev->vendor;
4624 pci_dev_put(pdev);
4625 if(temp == pcivendor) { 4624 if(temp == pcivendor) {
4626 ret = 1; 4625 ret = 1;
4626 pci_dev_put(pdev);
4627 break; 4627 break;
4628 } 4628 }
4629 } 4629 }
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 58f200c69be3..e83dfba7e636 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -641,6 +641,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
641{ 641{
642 unsigned long control; 642 unsigned long control;
643 void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL; 643 void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL;
644 struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl;
644 645
645 control = readl(ctrl_reg); 646 control = readl(ctrl_reg);
646 647
@@ -657,26 +658,34 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
657 sm501fb_sync_regs(fbi); 658 sm501fb_sync_regs(fbi);
658 mdelay(10); 659 mdelay(10);
659 660
660 control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */ 661 if (pd->flags & SM501FB_FLAG_PANEL_USE_VBIASEN) {
661 writel(control, ctrl_reg); 662 control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */
662 sm501fb_sync_regs(fbi); 663 writel(control, ctrl_reg);
663 mdelay(10); 664 sm501fb_sync_regs(fbi);
664 665 mdelay(10);
665 control |= SM501_DC_PANEL_CONTROL_FPEN; 666 }
666 writel(control, ctrl_reg);
667 667
668 if (pd->flags & SM501FB_FLAG_PANEL_USE_FPEN) {
669 control |= SM501_DC_PANEL_CONTROL_FPEN;
670 writel(control, ctrl_reg);
671 sm501fb_sync_regs(fbi);
672 mdelay(10);
673 }
668 } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) { 674 } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) {
669 /* disable panel power */ 675 /* disable panel power */
676 if (pd->flags & SM501FB_FLAG_PANEL_USE_FPEN) {
677 control &= ~SM501_DC_PANEL_CONTROL_FPEN;
678 writel(control, ctrl_reg);
679 sm501fb_sync_regs(fbi);
680 mdelay(10);
681 }
670 682
671 control &= ~SM501_DC_PANEL_CONTROL_FPEN; 683 if (pd->flags & SM501FB_FLAG_PANEL_USE_VBIASEN) {
672 writel(control, ctrl_reg); 684 control &= ~SM501_DC_PANEL_CONTROL_BIAS;
673 sm501fb_sync_regs(fbi); 685 writel(control, ctrl_reg);
674 mdelay(10); 686 sm501fb_sync_regs(fbi);
675 687 mdelay(10);
676 control &= ~SM501_DC_PANEL_CONTROL_BIAS; 688 }
677 writel(control, ctrl_reg);
678 sm501fb_sync_regs(fbi);
679 mdelay(10);
680 689
681 control &= ~SM501_DC_PANEL_CONTROL_DATA; 690 control &= ~SM501_DC_PANEL_CONTROL_DATA;
682 writel(control, ctrl_reg); 691 writel(control, ctrl_reg);
@@ -1267,6 +1276,7 @@ static int sm501fb_start(struct sm501fb_info *info,
1267{ 1276{
1268 struct resource *res; 1277 struct resource *res;
1269 struct device *dev; 1278 struct device *dev;
1279 int k;
1270 int ret; 1280 int ret;
1271 1281
1272 info->dev = dev = &pdev->dev; 1282 info->dev = dev = &pdev->dev;
@@ -1328,6 +1338,13 @@ static int sm501fb_start(struct sm501fb_info *info,
1328 1338
1329 info->fbmem_len = (res->end - res->start)+1; 1339 info->fbmem_len = (res->end - res->start)+1;
1330 1340
1341 /* clear framebuffer memory - avoids garbage data on unused fb */
1342 memset(info->fbmem, 0, info->fbmem_len);
1343
1344 /* clear palette ram - undefined at power on */
1345 for (k = 0; k < (256 * 3); k++)
1346 writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4));
1347
1331 /* enable display controller */ 1348 /* enable display controller */
1332 sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); 1349 sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1);
1333 1350
@@ -1681,6 +1698,15 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info,
1681 if (par->screen.size == 0) 1698 if (par->screen.size == 0)
1682 return 0; 1699 return 0;
1683 1700
1701 /* blank the relevant interface to ensure unit power minimised */
1702 (par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi);
1703
1704 /* tell console/fb driver we are suspending */
1705
1706 acquire_console_sem();
1707 fb_set_suspend(fbi, 1);
1708 release_console_sem();
1709
1684 /* backup copies in case chip is powered down over suspend */ 1710 /* backup copies in case chip is powered down over suspend */
1685 1711
1686 par->store_fb = vmalloc(par->screen.size); 1712 par->store_fb = vmalloc(par->screen.size);
@@ -1700,12 +1726,6 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info,
1700 1726
1701 memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size); 1727 memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size);
1702 memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size); 1728 memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size);
1703 /* blank the relevant interface to ensure unit power minimised */
1704 (par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi);
1705
1706 acquire_console_sem();
1707 fb_set_suspend(fbi, 1);
1708 release_console_sem();
1709 1729
1710 return 0; 1730 return 0;
1711 1731
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 057bdd593800..71e179ea5f95 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1342,7 +1342,7 @@ out_err:
1342} 1342}
1343 1343
1344#ifndef MODULE 1344#ifndef MODULE
1345static void tdfxfb_setup(char *options) 1345static void __init tdfxfb_setup(char *options)
1346{ 1346{
1347 char *this_opt; 1347 char *this_opt;
1348 1348
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index a14ef894d571..be27b9c1ed72 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -2003,12 +2003,12 @@ static void __devexit uvesafb_exit(void)
2003 2003
2004module_exit(uvesafb_exit); 2004module_exit(uvesafb_exit);
2005 2005
2006static inline int param_get_scroll(char *buffer, struct kernel_param *kp) 2006static int param_get_scroll(char *buffer, struct kernel_param *kp)
2007{ 2007{
2008 return 0; 2008 return 0;
2009} 2009}
2010 2010
2011static inline int param_set_scroll(const char *val, struct kernel_param *kp) 2011static int param_set_scroll(const char *val, struct kernel_param *kp)
2012{ 2012{
2013 ypan = 0; 2013 ypan = 0;
2014 2014
@@ -2022,11 +2022,11 @@ static inline int param_set_scroll(const char *val, struct kernel_param *kp)
2022 return 0; 2022 return 0;
2023} 2023}
2024 2024
2025#define param_check_scroll(name, p) __param_check(name, p, void); 2025#define param_check_scroll(name, p) __param_check(name, p, void)
2026 2026
2027module_param_named(scroll, ypan, scroll, 0); 2027module_param_named(scroll, ypan, scroll, 0);
2028MODULE_PARM_DESC(scroll, 2028MODULE_PARM_DESC(scroll,
2029 "Scrolling mode, set to 'redraw', ''ypan' or 'ywrap'"); 2029 "Scrolling mode, set to 'redraw', 'ypan', or 'ywrap'");
2030module_param_named(vgapal, pmi_setpal, invbool, 0); 2030module_param_named(vgapal, pmi_setpal, invbool, 0);
2031MODULE_PARM_DESC(vgapal, "Set palette using VGA registers"); 2031MODULE_PARM_DESC(vgapal, "Set palette using VGA registers");
2032module_param_named(pmipal, pmi_setpal, bool, 0); 2032module_param_named(pmipal, pmi_setpal, bool, 0);
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 1c656667b937..2aa71eb67c2b 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -651,7 +651,7 @@ static int vmlfb_check_var_locked(struct fb_var_screeninfo *var,
651 return -EINVAL; 651 return -EINVAL;
652 } 652 }
653 653
654 pitch = __ALIGN_MASK((var->xres * var->bits_per_pixel) >> 3, 0x3F); 654 pitch = ALIGN((var->xres * var->bits_per_pixel) >> 3, 0x40);
655 mem = pitch * var->yres_virtual; 655 mem = pitch * var->yres_virtual;
656 if (mem > vinfo->vram_contig_size) { 656 if (mem > vinfo->vram_contig_size) {
657 return -ENOMEM; 657 return -ENOMEM;
@@ -785,8 +785,7 @@ static int vmlfb_set_par_locked(struct vml_info *vinfo)
785 int clock; 785 int clock;
786 786
787 vinfo->bytes_per_pixel = var->bits_per_pixel >> 3; 787 vinfo->bytes_per_pixel = var->bits_per_pixel >> 3;
788 vinfo->stride = 788 vinfo->stride = ALIGN(var->xres_virtual * vinfo->bytes_per_pixel, 0x40);
789 __ALIGN_MASK(var->xres_virtual * vinfo->bytes_per_pixel, 0x3F);
790 info->fix.line_length = vinfo->stride; 789 info->fix.line_length = vinfo->stride;
791 790
792 if (!subsys) 791 if (!subsys)