aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig14
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/S3triofb.c7
-rw-r--r--drivers/video/amba-clcd.c2
-rw-r--r--drivers/video/amifb.c16
-rw-r--r--drivers/video/arcfb.c2
-rw-r--r--drivers/video/atafb.c13
-rw-r--r--drivers/video/aty/aty128fb.c5
-rw-r--r--drivers/video/aty/atyfb.h9
-rw-r--r--drivers/video/aty/atyfb_base.c199
-rw-r--r--drivers/video/aty/mach64_ct.c47
-rw-r--r--drivers/video/aty/radeon_i2c.c16
-rw-r--r--drivers/video/aty/radeon_monitor.c3
-rw-r--r--drivers/video/au1100fb.h2
-rw-r--r--drivers/video/backlight/backlight.c95
-rw-r--r--drivers/video/backlight/corgi_bl.c8
-rw-r--r--drivers/video/backlight/hp680_bl.c6
-rw-r--r--drivers/video/backlight/lcd.c80
-rw-r--r--drivers/video/backlight/locomolcd.c4
-rw-r--r--drivers/video/cfbimgblt.c8
-rw-r--r--drivers/video/cirrusfb.c15
-rw-r--r--drivers/video/console/fbcon.c6
-rw-r--r--drivers/video/console/softcursor.c26
-rw-r--r--drivers/video/console/sticon.c2
-rw-r--r--drivers/video/console/vgacon.c30
-rw-r--r--drivers/video/cyberfb.c4
-rw-r--r--drivers/video/epson1355fb.c4
-rw-r--r--drivers/video/fb_ddc.c6
-rw-r--r--drivers/video/fbcmap.c55
-rw-r--r--drivers/video/fbcvt.c2
-rw-r--r--drivers/video/fbmem.c38
-rw-r--r--drivers/video/fbmon.c2
-rw-r--r--drivers/video/fbsysfs.c163
-rw-r--r--drivers/video/ffb.c4
-rw-r--r--drivers/video/fm2fb.c1
-rw-r--r--drivers/video/geode/Kconfig20
-rw-r--r--drivers/video/geode/display_gx.c23
-rw-r--r--drivers/video/geode/display_gx.h7
-rw-r--r--drivers/video/geode/gxfb_core.c55
-rw-r--r--drivers/video/geode/video_gx.c107
-rw-r--r--drivers/video/geode/video_gx.h25
-rw-r--r--drivers/video/gxt4500.c741
-rw-r--r--drivers/video/hitfb.c1
-rw-r--r--drivers/video/hpfb.c2
-rw-r--r--drivers/video/i810/i810-i2c.c10
-rw-r--r--drivers/video/igafb.c6
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c4
-rw-r--r--drivers/video/intelfb/intelfbdrv.c3
-rw-r--r--drivers/video/intelfb/intelfbhw.c6
-rw-r--r--drivers/video/macfb.c20
-rw-r--r--drivers/video/matrox/i2c-matroxfb.c4
-rw-r--r--drivers/video/matrox/matroxfb_base.c2
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c2
-rw-r--r--drivers/video/mbx/mbxdebugfs.c188
-rw-r--r--drivers/video/mbx/mbxfb.c359
-rw-r--r--drivers/video/mbx/reg_bits.h114
-rw-r--r--drivers/video/mbx/regs.h2
-rw-r--r--drivers/video/modedb.c6
-rw-r--r--drivers/video/neofb.c2
-rw-r--r--drivers/video/nvidia/nv_accel.c35
-rw-r--r--drivers/video/nvidia/nv_hw.c12
-rw-r--r--drivers/video/nvidia/nv_i2c.c13
-rw-r--r--drivers/video/nvidia/nv_local.h11
-rw-r--r--drivers/video/nvidia/nv_of.c3
-rw-r--r--drivers/video/nvidia/nv_proto.h1
-rw-r--r--drivers/video/nvidia/nv_setup.c20
-rw-r--r--drivers/video/nvidia/nv_type.h1
-rw-r--r--drivers/video/nvidia/nvidia.c24
-rw-r--r--drivers/video/offb.c39
-rw-r--r--drivers/video/platinumfb.c8
-rw-r--r--drivers/video/pmagb-b-fb.c2
-rw-r--r--drivers/video/pnx4008/pnxrgbfb.c5
-rw-r--r--drivers/video/pnx4008/sdum.c2
-rw-r--r--drivers/video/pvr2fb.c18
-rw-r--r--drivers/video/pxafb.c7
-rw-r--r--drivers/video/retz3fb.c4
-rw-r--r--drivers/video/riva/fbdev.c66
-rw-r--r--drivers/video/riva/riva_hw.c10
-rw-r--r--drivers/video/riva/riva_hw.h17
-rw-r--r--drivers/video/riva/rivafb-i2c.c6
-rw-r--r--drivers/video/s3c2410fb.c213
-rw-r--r--drivers/video/savage/savagefb-i2c.c9
-rw-r--r--drivers/video/sis/init301.c7
-rw-r--r--drivers/video/sstfb.c335
-rw-r--r--drivers/video/stifb.c3
-rw-r--r--drivers/video/tgafb.c58
-rw-r--r--drivers/video/tridentfb.c22
-rw-r--r--drivers/video/vesafb.c24
-rw-r--r--drivers/video/vga16fb.c28
-rw-r--r--drivers/video/virgefb.c17
90 files changed, 2543 insertions, 1081 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7a43020fa583..4e83f01e894e 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -541,6 +541,7 @@ config FB_TGA
541 select FB_CFB_FILLRECT 541 select FB_CFB_FILLRECT
542 select FB_CFB_COPYAREA 542 select FB_CFB_COPYAREA
543 select FB_CFB_IMAGEBLIT 543 select FB_CFB_IMAGEBLIT
544 select BITREVERSE
544 help 545 help
545 This is the frame buffer device driver for generic TGA graphic 546 This is the frame buffer device driver for generic TGA graphic
546 cards. Say Y if you have one of those. 547 cards. Say Y if you have one of those.
@@ -551,6 +552,7 @@ config FB_VESA
551 select FB_CFB_FILLRECT 552 select FB_CFB_FILLRECT
552 select FB_CFB_COPYAREA 553 select FB_CFB_COPYAREA
553 select FB_CFB_IMAGEBLIT 554 select FB_CFB_IMAGEBLIT
555 select VIDEO_SELECT
554 help 556 help
555 This is the frame buffer device driver for generic VESA 2.0 557 This is the frame buffer device driver for generic VESA 2.0
556 compliant graphic cards. The older VESA 1.2 cards are not supported. 558 compliant graphic cards. The older VESA 1.2 cards are not supported.
@@ -705,6 +707,7 @@ config FB_NVIDIA
705 select FB_CFB_FILLRECT 707 select FB_CFB_FILLRECT
706 select FB_CFB_COPYAREA 708 select FB_CFB_COPYAREA
707 select FB_CFB_IMAGEBLIT 709 select FB_CFB_IMAGEBLIT
710 select BITREVERSE
708 help 711 help
709 This driver supports graphics boards with the nVidia chips, TNT 712 This driver supports graphics boards with the nVidia chips, TNT
710 and newer. For very old chipsets, such as the RIVA128, then use 713 and newer. For very old chipsets, such as the RIVA128, then use
@@ -744,6 +747,7 @@ config FB_RIVA
744 select FB_CFB_FILLRECT 747 select FB_CFB_FILLRECT
745 select FB_CFB_COPYAREA 748 select FB_CFB_COPYAREA
746 select FB_CFB_IMAGEBLIT 749 select FB_CFB_IMAGEBLIT
750 select BITREVERSE
747 help 751 help
748 This driver supports graphics boards with the nVidia Riva/Geforce 752 This driver supports graphics boards with the nVidia Riva/Geforce
749 chips. 753 chips.
@@ -1611,6 +1615,16 @@ config FB_PNX4008_DUM_RGB
1611 ---help--- 1615 ---help---
1612 Say Y here to enable support for PNX4008 RGB Framebuffer 1616 Say Y here to enable support for PNX4008 RGB Framebuffer
1613 1617
1618config FB_IBM_GXT4500
1619 tristate "Framebuffer support for IBM GXT4500P adaptor"
1620 depends on PPC
1621 select FB_CFB_FILLRECT
1622 select FB_CFB_COPYAREA
1623 select FB_CFB_IMAGEBLIT
1624 ---help---
1625 Say Y here to enable support for the IBM GXT4500P display
1626 adaptor, found on some IBM System P (pSeries) machines.
1627
1614config FB_VIRTUAL 1628config FB_VIRTUAL
1615 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 1629 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
1616 depends on FB 1630 depends on FB
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index a6980e9a2481..309a26dd164a 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -99,6 +99,7 @@ obj-$(CONFIG_FB_IMX) += imxfb.o
99obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o 99obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
100obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/ 100obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/
101obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/ 101obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/
102obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
102 103
103# Platform or fallback drivers go here 104# Platform or fallback drivers go here
104obj-$(CONFIG_FB_VESA) += vesafb.o 105obj-$(CONFIG_FB_VESA) += vesafb.o
diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
index 397005eb392d..b3717c8f1bc2 100644
--- a/drivers/video/S3triofb.c
+++ b/drivers/video/S3triofb.c
@@ -535,8 +535,11 @@ static void __init s3triofb_of_init(struct device_node *dp)
535#endif 535#endif
536 536
537 fb_info.flags = FBINFO_FLAG_DEFAULT; 537 fb_info.flags = FBINFO_FLAG_DEFAULT;
538 if (register_framebuffer(&fb_info) < 0) 538 if (register_framebuffer(&fb_info) < 0) {
539 return; 539 iounmap(fb_info.screen_base);
540 fb_info.screen_base = NULL;
541 return;
542 }
540 543
541 printk("fb%d: S3 Trio frame buffer device on %s\n", 544 printk("fb%d: S3 Trio frame buffer device on %s\n",
542 fb_info.node, dp->full_name); 545 fb_info.node, dp->full_name);
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 6761b68c35e9..6c9dc2e69c82 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -447,7 +447,7 @@ static int clcdfb_probe(struct amba_device *dev, void *id)
447 goto out; 447 goto out;
448 } 448 }
449 449
450 fb = (struct clcd_fb *) kmalloc(sizeof(struct clcd_fb), GFP_KERNEL); 450 fb = kmalloc(sizeof(struct clcd_fb), GFP_KERNEL);
451 if (!fb) { 451 if (!fb) {
452 printk(KERN_INFO "CLCD: could not allocate new clcd_fb struct\n"); 452 printk(KERN_INFO "CLCD: could not allocate new clcd_fb struct\n");
453 ret = -ENOMEM; 453 ret = -ENOMEM;
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index a4e3fca05891..1a849b870bcc 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2407,10 +2407,10 @@ default_chipset:
2407 fb_info.fix.smem_len); 2407 fb_info.fix.smem_len);
2408 if (!videomemory) { 2408 if (!videomemory) {
2409 printk("amifb: WARNING! unable to map videomem cached writethrough\n"); 2409 printk("amifb: WARNING! unable to map videomem cached writethrough\n");
2410 videomemory = ZTWO_VADDR(fb_info.fix.smem_start); 2410 fb_info.screen_base = (char *)ZTWO_VADDR(fb_info.fix.smem_start);
2411 } 2411 } else
2412 fb_info.screen_base = (char *)videomemory;
2412 2413
2413 fb_info.screen_base = (char *)videomemory;
2414 memset(dummysprite, 0, DUMMYSPRITEMEMSIZE); 2414 memset(dummysprite, 0, DUMMYSPRITEMEMSIZE);
2415 2415
2416 /* 2416 /*
@@ -2453,6 +2453,8 @@ static void amifb_deinit(void)
2453{ 2453{
2454 fb_dealloc_cmap(&fb_info.cmap); 2454 fb_dealloc_cmap(&fb_info.cmap);
2455 chipfree(); 2455 chipfree();
2456 if (videomemory)
2457 iounmap((void*)videomemory);
2456 release_mem_region(CUSTOM_PHYSADDR+0xe0, 0x120); 2458 release_mem_region(CUSTOM_PHYSADDR+0xe0, 0x120);
2457 custom.dmacon = DMAF_ALL | DMAF_MASTER; 2459 custom.dmacon = DMAF_ALL | DMAF_MASTER;
2458} 2460}
@@ -2904,14 +2906,6 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
2904 par->crsr.spot_x = par->crsr.spot_y = 0; 2906 par->crsr.spot_x = par->crsr.spot_y = 0;
2905 par->crsr.height = par->crsr.width = 0; 2907 par->crsr.height = par->crsr.width = 0;
2906 2908
2907#if 0 /* fbmon not done. uncomment for 2.5.x -brad */
2908 if (!fbmon_valid_timings(pixclock[clk_shift], htotal, vtotal,
2909 &fb_info)) {
2910 DPRINTK("mode doesn't fit for monitor\n");
2911 return -EINVAL;
2912 }
2913#endif
2914
2915 return 0; 2909 return 0;
2916} 2910}
2917 2911
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index ab34b96acc31..30a8369757e7 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -454,7 +454,7 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou
454 unsigned int xres; 454 unsigned int xres;
455 455
456 p = *ppos; 456 p = *ppos;
457 inode = file->f_dentry->d_inode; 457 inode = file->f_path.dentry->d_inode;
458 fbidx = iminor(inode); 458 fbidx = iminor(inode);
459 info = registered_fb[fbidx]; 459 info = registered_fb[fbidx];
460 460
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 02c41a626fa2..602db660bc73 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -2804,8 +2804,19 @@ int __init atafb_init(void)
2804 atafb_set_disp(-1, &fb_info); 2804 atafb_set_disp(-1, &fb_info);
2805 do_install_cmap(0, &fb_info); 2805 do_install_cmap(0, &fb_info);
2806 2806
2807 if (register_framebuffer(&fb_info) < 0) 2807 if (register_framebuffer(&fb_info) < 0) {
2808#ifdef ATAFB_EXT
2809 if (external_addr) {
2810 iounmap(external_addr);
2811 external_addr = NULL;
2812 }
2813 if (external_vgaiobase) {
2814 iounmap((void*)external_vgaiobase);
2815 external_vgaiobase = 0;
2816 }
2817#endif
2808 return -EINVAL; 2818 return -EINVAL;
2819 }
2809 2820
2810 printk("Determined %dx%d, depth %d\n", 2821 printk("Determined %dx%d, depth %d\n",
2811 disp.var.xres, disp.var.yres, disp.var.bits_per_pixel); 2822 disp.var.xres, disp.var.yres, disp.var.bits_per_pixel);
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 5341462b6b48..2e976ffcde0f 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1333,6 +1333,8 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
1333 if (vclk * 12 < c.ppll_min) 1333 if (vclk * 12 < c.ppll_min)
1334 vclk = c.ppll_min/12; 1334 vclk = c.ppll_min/12;
1335 1335
1336 pll->post_divider = -1;
1337
1336 /* now, find an acceptable divider */ 1338 /* now, find an acceptable divider */
1337 for (i = 0; i < sizeof(post_dividers); i++) { 1339 for (i = 0; i < sizeof(post_dividers); i++) {
1338 output_freq = post_dividers[i] * vclk; 1340 output_freq = post_dividers[i] * vclk;
@@ -1342,6 +1344,9 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
1342 } 1344 }
1343 } 1345 }
1344 1346
1347 if (pll->post_divider < 0)
1348 return -EINVAL;
1349
1345 /* calculate feedback divider */ 1350 /* calculate feedback divider */
1346 n = c.ref_divider * output_freq; 1351 n = c.ref_divider * output_freq;
1347 d = c.ref_clk; 1352 d = c.ref_clk;
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
index b04f49fb976a..f72faff33c0c 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/aty/atyfb.h
@@ -126,7 +126,6 @@ union aty_pll {
126 */ 126 */
127 127
128struct atyfb_par { 128struct atyfb_par {
129 struct aty_cmap_regs __iomem *aty_cmap_regs;
130 struct { u8 red, green, blue; } palette[256]; 129 struct { u8 red, green, blue; } palette[256];
131 const struct aty_dac_ops *dac_ops; 130 const struct aty_dac_ops *dac_ops;
132 const struct aty_pll_ops *pll_ops; 131 const struct aty_pll_ops *pll_ops;
@@ -186,6 +185,7 @@ struct atyfb_par {
186 int mtrr_aper; 185 int mtrr_aper;
187 int mtrr_reg; 186 int mtrr_reg;
188#endif 187#endif
188 u32 mem_cntl;
189}; 189};
190 190
191 /* 191 /*
@@ -227,7 +227,7 @@ static inline u32 aty_ld_le32(int regindex, const struct atyfb_par *par)
227 regindex -= 0x800; 227 regindex -= 0x800;
228 228
229#ifdef CONFIG_ATARI 229#ifdef CONFIG_ATARI
230 return in_le32((volatile u32 *)(par->ati_regbase + regindex)); 230 return in_le32(par->ati_regbase + regindex);
231#else 231#else
232 return readl(par->ati_regbase + regindex); 232 return readl(par->ati_regbase + regindex);
233#endif 233#endif
@@ -240,7 +240,7 @@ static inline void aty_st_le32(int regindex, u32 val, const struct atyfb_par *pa
240 regindex -= 0x800; 240 regindex -= 0x800;
241 241
242#ifdef CONFIG_ATARI 242#ifdef CONFIG_ATARI
243 out_le32((volatile u32 *)(par->ati_regbase + regindex), val); 243 out_le32(par->ati_regbase + regindex, val);
244#else 244#else
245 writel(val, par->ati_regbase + regindex); 245 writel(val, par->ati_regbase + regindex);
246#endif 246#endif
@@ -253,7 +253,7 @@ static inline void aty_st_le16(int regindex, u16 val,
253 if (regindex >= 0x400) 253 if (regindex >= 0x400)
254 regindex -= 0x800; 254 regindex -= 0x800;
255#ifdef CONFIG_ATARI 255#ifdef CONFIG_ATARI
256 out_le16((volatile u16 *)(par->ati_regbase + regindex), val); 256 out_le16(par->ati_regbase + regindex, val);
257#else 257#else
258 writel(val, par->ati_regbase + regindex); 258 writel(val, par->ati_regbase + regindex);
259#endif 259#endif
@@ -315,6 +315,7 @@ struct aty_pll_ops {
315 void (*set_pll) (const struct fb_info * info, const union aty_pll * pll); 315 void (*set_pll) (const struct fb_info * info, const union aty_pll * pll);
316 void (*get_pll) (const struct fb_info *info, union aty_pll * pll); 316 void (*get_pll) (const struct fb_info *info, union aty_pll * pll);
317 int (*init_pll) (const struct fb_info * info, union aty_pll * pll); 317 int (*init_pll) (const struct fb_info * info, union aty_pll * pll);
318 void (*resume_pll)(const struct fb_info *info, union aty_pll *pll);
318}; 319};
319 320
320extern const struct aty_pll_ops aty_pll_ati18818_1; /* ATI 18818 */ 321extern const struct aty_pll_ops aty_pll_ati18818_1; /* ATI 18818 */
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index cc4bd8089fe2..f2ebdd880085 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -203,14 +203,6 @@ static void ATIReduceRatio(int *Numerator, int *Denominator)
203 * The Hardware parameters for each card 203 * The Hardware parameters for each card
204 */ 204 */
205 205
206struct aty_cmap_regs {
207 u8 windex;
208 u8 lut;
209 u8 mask;
210 u8 rindex;
211 u8 cntl;
212};
213
214struct pci_mmap_map { 206struct pci_mmap_map {
215 unsigned long voff; 207 unsigned long voff;
216 unsigned long poff; 208 unsigned long poff;
@@ -249,7 +241,8 @@ static int atyfb_sync(struct fb_info *info);
249 * Internal routines 241 * Internal routines
250 */ 242 */
251 243
252static int aty_init(struct fb_info *info, const char *name); 244static int aty_init(struct fb_info *info);
245static void aty_resume_chip(struct fb_info *info);
253#ifdef CONFIG_ATARI 246#ifdef CONFIG_ATARI
254static int store_video_par(char *videopar, unsigned char m64_num); 247static int store_video_par(char *videopar, unsigned char m64_num);
255#endif 248#endif
@@ -406,7 +399,7 @@ static struct {
406 { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO }, 399 { PCI_CHIP_MACH64LB, "3D RAGE LT PRO (Mach64 LB, AGP)", 236, 75, 100, 135, ATI_CHIP_264LTPRO },
407 { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, 400 { PCI_CHIP_MACH64LD, "3D RAGE LT PRO (Mach64 LD, AGP)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
408 { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 }, 401 { PCI_CHIP_MACH64LI, "3D RAGE LT PRO (Mach64 LI, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1_1 | M64F_G3_PB_1024x768 },
409 { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, 402 { PCI_CHIP_MACH64LP, "3D RAGE LT PRO (Mach64 LP, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO | M64F_G3_PB_1024x768 },
410 { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO }, 403 { PCI_CHIP_MACH64LQ, "3D RAGE LT PRO (Mach64 LQ, PCI)", 230, 100, 100, 135, ATI_CHIP_264LTPRO },
411 404
412 { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL }, 405 { PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP 2x)", 230, 83, 63, 135, ATI_CHIP_264XL },
@@ -1495,10 +1488,6 @@ static int atyfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1495 else 1488 else
1496 info->var.accel_flags = 0; 1489 info->var.accel_flags = 0;
1497 1490
1498#if 0 /* fbmon is not done. uncomment for 2.5.x -brad */
1499 if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
1500 return -EINVAL;
1501#endif
1502 aty_crtc_to_var(&crtc, var); 1491 aty_crtc_to_var(&crtc, var);
1503 var->pixclock = par->pll_ops->pll_to_var(info, &pll); 1492 var->pixclock = par->pll_ops->pll_to_var(info, &pll);
1504 return 0; 1493 return 0;
@@ -1937,17 +1926,14 @@ static void atyfb_save_palette(struct atyfb_par *par, int enter)
1937 aty_st_8(DAC_CNTL, tmp, par); 1926 aty_st_8(DAC_CNTL, tmp, par);
1938 aty_st_8(DAC_MASK, 0xff, par); 1927 aty_st_8(DAC_MASK, 0xff, par);
1939 1928
1940 writeb(i, &par->aty_cmap_regs->rindex); 1929 aty_st_8(DAC_R_INDEX, i, par);
1941 atyfb_save.r[enter][i] = readb(&par->aty_cmap_regs->lut); 1930 atyfb_save.r[enter][i] = aty_ld_8(DAC_DATA, par);
1942 atyfb_save.g[enter][i] = readb(&par->aty_cmap_regs->lut); 1931 atyfb_save.g[enter][i] = aty_ld_8(DAC_DATA, par);
1943 atyfb_save.b[enter][i] = readb(&par->aty_cmap_regs->lut); 1932 atyfb_save.b[enter][i] = aty_ld_8(DAC_DATA, par);
1944 writeb(i, &par->aty_cmap_regs->windex); 1933 aty_st_8(DAC_W_INDEX, i, par);
1945 writeb(atyfb_save.r[1 - enter][i], 1934 aty_st_8(DAC_DATA, atyfb_save.r[1 - enter][i], par);
1946 &par->aty_cmap_regs->lut); 1935 aty_st_8(DAC_DATA, atyfb_save.g[1 - enter][i], par);
1947 writeb(atyfb_save.g[1 - enter][i], 1936 aty_st_8(DAC_DATA, atyfb_save.b[1 - enter][i], par);
1948 &par->aty_cmap_regs->lut);
1949 writeb(atyfb_save.b[1 - enter][i],
1950 &par->aty_cmap_regs->lut);
1951 } 1937 }
1952} 1938}
1953 1939
@@ -1982,6 +1968,7 @@ static void atyfb_palette(int enter)
1982 1968
1983#if defined(CONFIG_PM) && defined(CONFIG_PCI) 1969#if defined(CONFIG_PM) && defined(CONFIG_PCI)
1984 1970
1971#ifdef CONFIG_PPC_PMAC
1985/* Power management routines. Those are used for PowerBook sleep. 1972/* Power management routines. Those are used for PowerBook sleep.
1986 */ 1973 */
1987static int aty_power_mgmt(int sleep, struct atyfb_par *par) 1974static int aty_power_mgmt(int sleep, struct atyfb_par *par)
@@ -2038,21 +2025,13 @@ static int aty_power_mgmt(int sleep, struct atyfb_par *par)
2038 2025
2039 return timeout ? 0 : -EIO; 2026 return timeout ? 0 : -EIO;
2040} 2027}
2028#endif
2041 2029
2042static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state) 2030static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2043{ 2031{
2044 struct fb_info *info = pci_get_drvdata(pdev); 2032 struct fb_info *info = pci_get_drvdata(pdev);
2045 struct atyfb_par *par = (struct atyfb_par *) info->par; 2033 struct atyfb_par *par = (struct atyfb_par *) info->par;
2046 2034
2047#ifndef CONFIG_PPC_PMAC
2048 /* HACK ALERT ! Once I find a proper way to say to each driver
2049 * individually what will happen with it's PCI slot, I'll change
2050 * that. On laptops, the AGP slot is just unclocked, so D2 is
2051 * expected, while on desktops, the card is powered off
2052 */
2053 return 0;
2054#endif /* CONFIG_PPC_PMAC */
2055
2056 if (state.event == pdev->dev.power.power_state.event) 2035 if (state.event == pdev->dev.power.power_state.event)
2057 return 0; 2036 return 0;
2058 2037
@@ -2070,6 +2049,7 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2070 par->asleep = 1; 2049 par->asleep = 1;
2071 par->lock_blank = 1; 2050 par->lock_blank = 1;
2072 2051
2052#ifdef CONFIG_PPC_PMAC
2073 /* Set chip to "suspend" mode */ 2053 /* Set chip to "suspend" mode */
2074 if (aty_power_mgmt(1, par)) { 2054 if (aty_power_mgmt(1, par)) {
2075 par->asleep = 0; 2055 par->asleep = 0;
@@ -2079,6 +2059,9 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2079 release_console_sem(); 2059 release_console_sem();
2080 return -EIO; 2060 return -EIO;
2081 } 2061 }
2062#else
2063 pci_set_power_state(pdev, pci_choose_state(pdev, state));
2064#endif
2082 2065
2083 release_console_sem(); 2066 release_console_sem();
2084 2067
@@ -2097,8 +2080,15 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
2097 2080
2098 acquire_console_sem(); 2081 acquire_console_sem();
2099 2082
2083#ifdef CONFIG_PPC_PMAC
2100 if (pdev->dev.power.power_state.event == 2) 2084 if (pdev->dev.power.power_state.event == 2)
2101 aty_power_mgmt(0, par); 2085 aty_power_mgmt(0, par);
2086#else
2087 pci_set_power_state(pdev, PCI_D0);
2088#endif
2089
2090 aty_resume_chip(info);
2091
2102 par->asleep = 0; 2092 par->asleep = 0;
2103 2093
2104 /* Restore display */ 2094 /* Restore display */
@@ -2344,24 +2334,16 @@ static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
2344} 2334}
2345#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */ 2335#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
2346 2336
2347static int __devinit aty_init(struct fb_info *info, const char *name) 2337static int __devinit aty_init(struct fb_info *info)
2348{ 2338{
2349 struct atyfb_par *par = (struct atyfb_par *) info->par; 2339 struct atyfb_par *par = (struct atyfb_par *) info->par;
2350 const char *ramname = NULL, *xtal; 2340 const char *ramname = NULL, *xtal;
2351 int gtb_memsize, has_var = 0; 2341 int gtb_memsize, has_var = 0;
2352 struct fb_var_screeninfo var; 2342 struct fb_var_screeninfo var;
2353 u8 pll_ref_div;
2354 u32 i;
2355#if defined(CONFIG_PPC)
2356 int sense;
2357#endif
2358 2343
2359 init_waitqueue_head(&par->vblank.wait); 2344 init_waitqueue_head(&par->vblank.wait);
2360 spin_lock_init(&par->int_lock); 2345 spin_lock_init(&par->int_lock);
2361 2346
2362 par->aty_cmap_regs =
2363 (struct aty_cmap_regs __iomem *) (par->ati_regbase + 0xc0);
2364
2365#ifdef CONFIG_PPC_PMAC 2347#ifdef CONFIG_PPC_PMAC
2366 /* The Apple iBook1 uses non-standard memory frequencies. We detect it 2348 /* The Apple iBook1 uses non-standard memory frequencies. We detect it
2367 * and set the frequency manually. */ 2349 * and set the frequency manually. */
@@ -2464,18 +2446,21 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
2464 par->pll_limits.mclk = 63; 2446 par->pll_limits.mclk = 63;
2465 } 2447 }
2466 2448
2467 if (M64_HAS(GTB_DSP) 2449 if (M64_HAS(GTB_DSP)) {
2468 && (pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par))) { 2450 u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
2469 int diff1, diff2; 2451
2470 diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max; 2452 if (pll_ref_div) {
2471 diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max; 2453 int diff1, diff2;
2472 if (diff1 < 0) 2454 diff1 = 510 * 14 / pll_ref_div - par->pll_limits.pll_max;
2473 diff1 = -diff1; 2455 diff2 = 510 * 29 / pll_ref_div - par->pll_limits.pll_max;
2474 if (diff2 < 0) 2456 if (diff1 < 0)
2475 diff2 = -diff2; 2457 diff1 = -diff1;
2476 if (diff2 < diff1) { 2458 if (diff2 < 0)
2477 par->ref_clk_per = 1000000000000ULL / 29498928; 2459 diff2 = -diff2;
2478 xtal = "29.498928"; 2460 if (diff2 < diff1) {
2461 par->ref_clk_per = 1000000000000ULL / 29498928;
2462 xtal = "29.498928";
2463 }
2479 } 2464 }
2480 } 2465 }
2481#endif /* CONFIG_FB_ATY_CT */ 2466#endif /* CONFIG_FB_ATY_CT */
@@ -2485,10 +2470,10 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
2485 if(par->pll_ops->get_pll) 2470 if(par->pll_ops->get_pll)
2486 par->pll_ops->get_pll(info, &saved_pll); 2471 par->pll_ops->get_pll(info, &saved_pll);
2487 2472
2488 i = aty_ld_le32(MEM_CNTL, par); 2473 par->mem_cntl = aty_ld_le32(MEM_CNTL, par);
2489 gtb_memsize = M64_HAS(GTB_DSP); 2474 gtb_memsize = M64_HAS(GTB_DSP);
2490 if (gtb_memsize) 2475 if (gtb_memsize)
2491 switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */ 2476 switch (par->mem_cntl & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
2492 case MEM_SIZE_512K: 2477 case MEM_SIZE_512K:
2493 info->fix.smem_len = 0x80000; 2478 info->fix.smem_len = 0x80000;
2494 break; 2479 break;
@@ -2510,7 +2495,7 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
2510 default: 2495 default:
2511 info->fix.smem_len = 0x80000; 2496 info->fix.smem_len = 0x80000;
2512 } else 2497 } else
2513 switch (i & MEM_SIZE_ALIAS) { 2498 switch (par->mem_cntl & MEM_SIZE_ALIAS) {
2514 case MEM_SIZE_512K: 2499 case MEM_SIZE_512K:
2515 info->fix.smem_len = 0x80000; 2500 info->fix.smem_len = 0x80000;
2516 break; 2501 break;
@@ -2540,20 +2525,20 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
2540 2525
2541 if (vram) { 2526 if (vram) {
2542 info->fix.smem_len = vram * 1024; 2527 info->fix.smem_len = vram * 1024;
2543 i = i & ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS); 2528 par->mem_cntl &= ~(gtb_memsize ? 0xF : MEM_SIZE_ALIAS);
2544 if (info->fix.smem_len <= 0x80000) 2529 if (info->fix.smem_len <= 0x80000)
2545 i |= MEM_SIZE_512K; 2530 par->mem_cntl |= MEM_SIZE_512K;
2546 else if (info->fix.smem_len <= 0x100000) 2531 else if (info->fix.smem_len <= 0x100000)
2547 i |= MEM_SIZE_1M; 2532 par->mem_cntl |= MEM_SIZE_1M;
2548 else if (info->fix.smem_len <= 0x200000) 2533 else if (info->fix.smem_len <= 0x200000)
2549 i |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M; 2534 par->mem_cntl |= gtb_memsize ? MEM_SIZE_2M_GTB : MEM_SIZE_2M;
2550 else if (info->fix.smem_len <= 0x400000) 2535 else if (info->fix.smem_len <= 0x400000)
2551 i |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M; 2536 par->mem_cntl |= gtb_memsize ? MEM_SIZE_4M_GTB : MEM_SIZE_4M;
2552 else if (info->fix.smem_len <= 0x600000) 2537 else if (info->fix.smem_len <= 0x600000)
2553 i |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M; 2538 par->mem_cntl |= gtb_memsize ? MEM_SIZE_6M_GTB : MEM_SIZE_6M;
2554 else 2539 else
2555 i |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M; 2540 par->mem_cntl |= gtb_memsize ? MEM_SIZE_8M_GTB : MEM_SIZE_8M;
2556 aty_st_le32(MEM_CNTL, i, par); 2541 aty_st_le32(MEM_CNTL, par->mem_cntl, par);
2557 } 2542 }
2558 2543
2559 /* 2544 /*
@@ -2599,11 +2584,12 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
2599#endif 2584#endif
2600 if(par->pll_ops->init_pll) 2585 if(par->pll_ops->init_pll)
2601 par->pll_ops->init_pll(info, &par->pll); 2586 par->pll_ops->init_pll(info, &par->pll);
2587 if (par->pll_ops->resume_pll)
2588 par->pll_ops->resume_pll(info, &par->pll);
2602 2589
2603 /* 2590 /*
2604 * Last page of 8 MB (4 MB on ISA) aperture is MMIO 2591 * Last page of 8 MB (4 MB on ISA) aperture is MMIO,
2605 * FIXME: we should use the auxiliary aperture instead so we can access 2592 * unless the auxiliary register aperture is used.
2606 * the full 8 MB of video RAM on 8 MB boards
2607 */ 2593 */
2608 2594
2609 if (!par->aux_start && 2595 if (!par->aux_start &&
@@ -2669,6 +2655,7 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
2669 has_var = 1; 2655 has_var = 1;
2670 } else { 2656 } else {
2671 if (default_vmode == VMODE_CHOOSE) { 2657 if (default_vmode == VMODE_CHOOSE) {
2658 int sense;
2672 if (M64_HAS(G3_PB_1024x768)) 2659 if (M64_HAS(G3_PB_1024x768))
2673 /* G3 PowerBook with 1024x768 LCD */ 2660 /* G3 PowerBook with 1024x768 LCD */
2674 default_vmode = VMODE_1024_768_60; 2661 default_vmode = VMODE_1024_768_60;
@@ -2749,7 +2736,7 @@ static int __devinit aty_init(struct fb_info *info, const char *name)
2749 fb_list = info; 2736 fb_list = info;
2750 2737
2751 PRINTKI("fb%d: %s frame buffer device on %s\n", 2738 PRINTKI("fb%d: %s frame buffer device on %s\n",
2752 info->node, info->fix.id, name); 2739 info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI");
2753 return 0; 2740 return 0;
2754 2741
2755aty_init_exit: 2742aty_init_exit:
@@ -2770,6 +2757,19 @@ aty_init_exit:
2770 return -1; 2757 return -1;
2771} 2758}
2772 2759
2760static void aty_resume_chip(struct fb_info *info)
2761{
2762 struct atyfb_par *par = info->par;
2763
2764 aty_st_le32(MEM_CNTL, par->mem_cntl, par);
2765
2766 if (par->pll_ops->resume_pll)
2767 par->pll_ops->resume_pll(info, &par->pll);
2768
2769 if (par->aux_start)
2770 aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_APER_REG_DIS, par);
2771}
2772
2773#ifdef CONFIG_ATARI 2773#ifdef CONFIG_ATARI
2774static int __devinit store_video_par(char *video_str, unsigned char m64_num) 2774static int __devinit store_video_par(char *video_str, unsigned char m64_num)
2775{ 2775{
@@ -2826,9 +2826,9 @@ static int atyfb_blank(int blank, struct fb_info *info)
2826#endif 2826#endif
2827 2827
2828 gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par); 2828 gen_cntl = aty_ld_le32(CRTC_GEN_CNTL, par);
2829 gen_cntl &= ~0x400004c;
2829 switch (blank) { 2830 switch (blank) {
2830 case FB_BLANK_UNBLANK: 2831 case FB_BLANK_UNBLANK:
2831 gen_cntl &= ~0x400004c;
2832 break; 2832 break;
2833 case FB_BLANK_NORMAL: 2833 case FB_BLANK_NORMAL:
2834 gen_cntl |= 0x4000040; 2834 gen_cntl |= 0x4000040;
@@ -2863,17 +2863,10 @@ static int atyfb_blank(int blank, struct fb_info *info)
2863static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue, 2863static void aty_st_pal(u_int regno, u_int red, u_int green, u_int blue,
2864 const struct atyfb_par *par) 2864 const struct atyfb_par *par)
2865{ 2865{
2866#ifdef CONFIG_ATARI 2866 aty_st_8(DAC_W_INDEX, regno, par);
2867 out_8(&par->aty_cmap_regs->windex, regno); 2867 aty_st_8(DAC_DATA, red, par);
2868 out_8(&par->aty_cmap_regs->lut, red); 2868 aty_st_8(DAC_DATA, green, par);
2869 out_8(&par->aty_cmap_regs->lut, green); 2869 aty_st_8(DAC_DATA, blue, par);
2870 out_8(&par->aty_cmap_regs->lut, blue);
2871#else
2872 writeb(regno, &par->aty_cmap_regs->windex);
2873 writeb(red, &par->aty_cmap_regs->lut);
2874 writeb(green, &par->aty_cmap_regs->lut);
2875 writeb(blue, &par->aty_cmap_regs->lut);
2876#endif
2877} 2870}
2878 2871
2879 /* 2872 /*
@@ -3182,7 +3175,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
3182 3175
3183#ifdef __i386__ 3176#ifdef __i386__
3184#ifdef CONFIG_FB_ATY_GENERIC_LCD 3177#ifdef CONFIG_FB_ATY_GENERIC_LCD
3185static void aty_init_lcd(struct atyfb_par *par, u32 bios_base) 3178static void __devinit aty_init_lcd(struct atyfb_par *par, u32 bios_base)
3186{ 3179{
3187 u32 driv_inf_tab, sig; 3180 u32 driv_inf_tab, sig;
3188 u16 lcd_ofs; 3181 u16 lcd_ofs;
@@ -3527,6 +3520,10 @@ static int __devinit atyfb_setup_generic(struct pci_dev *pdev, struct fb_info *i
3527atyfb_setup_generic_fail: 3520atyfb_setup_generic_fail:
3528 iounmap(par->ati_regbase); 3521 iounmap(par->ati_regbase);
3529 par->ati_regbase = NULL; 3522 par->ati_regbase = NULL;
3523 if (info->screen_base) {
3524 iounmap(info->screen_base);
3525 info->screen_base = NULL;
3526 }
3530 return ret; 3527 return ret;
3531} 3528}
3532 3529
@@ -3594,7 +3591,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
3594 pci_set_drvdata(pdev, info); 3591 pci_set_drvdata(pdev, info);
3595 3592
3596 /* Init chip & register framebuffer */ 3593 /* Init chip & register framebuffer */
3597 if (aty_init(info, "PCI")) 3594 if (aty_init(info))
3598 goto err_release_io; 3595 goto err_release_io;
3599 3596
3600#ifdef __sparc__ 3597#ifdef __sparc__
@@ -3641,12 +3638,13 @@ err_release_mem:
3641 3638
3642#ifdef CONFIG_ATARI 3639#ifdef CONFIG_ATARI
3643 3640
3644static int __devinit atyfb_atari_probe(void) 3641static int __init atyfb_atari_probe(void)
3645{ 3642{
3646 struct atyfb_par *par; 3643 struct atyfb_par *par;
3647 struct fb_info *info; 3644 struct fb_info *info;
3648 int m64_num; 3645 int m64_num;
3649 u32 clock_r; 3646 u32 clock_r;
3647 int num_found = 0;
3650 3648
3651 for (m64_num = 0; m64_num < mach64_count; m64_num++) { 3649 for (m64_num = 0; m64_num < mach64_count; m64_num++) {
3652 if (!phys_vmembase[m64_num] || !phys_size[m64_num] || 3650 if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
@@ -3694,16 +3692,34 @@ static int __devinit atyfb_atari_probe(void)
3694 break; 3692 break;
3695 } 3693 }
3696 3694
3697 if (aty_init(info, "ISA bus")) { 3695 /* Fake pci_id for correct_chipset() */
3696 switch (aty_ld_le32(CONFIG_CHIP_ID, par) & CFG_CHIP_TYPE) {
3697 case 0x00d7:
3698 par->pci_id = PCI_CHIP_MACH64GX;
3699 break;
3700 case 0x0057:
3701 par->pci_id = PCI_CHIP_MACH64CX;
3702 break;
3703 default:
3704 break;
3705 }
3706
3707 if (correct_chipset(par) || aty_init(info)) {
3708 iounmap(info->screen_base);
3709 iounmap(par->ati_regbase);
3698 framebuffer_release(info); 3710 framebuffer_release(info);
3699 /* This is insufficient! kernel_map has added two large chunks!! */ 3711 } else {
3700 return -ENXIO; 3712 num_found++;
3701 } 3713 }
3702 } 3714 }
3715
3716 return num_found ? 0 : -ENXIO;
3703} 3717}
3704 3718
3705#endif /* CONFIG_ATARI */ 3719#endif /* CONFIG_ATARI */
3706 3720
3721#ifdef CONFIG_PCI
3722
3707static void __devexit atyfb_remove(struct fb_info *info) 3723static void __devexit atyfb_remove(struct fb_info *info)
3708{ 3724{
3709 struct atyfb_par *par = (struct atyfb_par *) info->par; 3725 struct atyfb_par *par = (struct atyfb_par *) info->par;
@@ -3751,7 +3767,6 @@ static void __devexit atyfb_remove(struct fb_info *info)
3751 framebuffer_release(info); 3767 framebuffer_release(info);
3752} 3768}
3753 3769
3754#ifdef CONFIG_PCI
3755 3770
3756static void __devexit atyfb_pci_remove(struct pci_dev *pdev) 3771static void __devexit atyfb_pci_remove(struct pci_dev *pdev)
3757{ 3772{
@@ -3786,7 +3801,7 @@ static struct pci_driver atyfb_driver = {
3786#endif /* CONFIG_PCI */ 3801#endif /* CONFIG_PCI */
3787 3802
3788#ifndef MODULE 3803#ifndef MODULE
3789static int __devinit atyfb_setup(char *options) 3804static int __init atyfb_setup(char *options)
3790{ 3805{
3791 char *this_opt; 3806 char *this_opt;
3792 3807
@@ -3858,7 +3873,7 @@ static int __devinit atyfb_setup(char *options)
3858} 3873}
3859#endif /* MODULE */ 3874#endif /* MODULE */
3860 3875
3861static int __devinit atyfb_init(void) 3876static int __init atyfb_init(void)
3862{ 3877{
3863 int err1 = 1, err2 = 1; 3878 int err1 = 1, err2 = 1;
3864#ifndef MODULE 3879#ifndef MODULE
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index 5080816be653..f3b487b8710b 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -370,8 +370,8 @@ void aty_set_pll_ct(const struct fb_info *info, const union aty_pll *pll)
370#endif 370#endif
371} 371}
372 372
373static void __init aty_get_pll_ct(const struct fb_info *info, 373static void __devinit aty_get_pll_ct(const struct fb_info *info,
374 union aty_pll *pll) 374 union aty_pll *pll)
375{ 375{
376 struct atyfb_par *par = (struct atyfb_par *) info->par; 376 struct atyfb_par *par = (struct atyfb_par *) info->par;
377 u8 tmp, clock; 377 u8 tmp, clock;
@@ -394,12 +394,12 @@ static void __init aty_get_pll_ct(const struct fb_info *info,
394 } 394 }
395} 395}
396 396
397static int __init aty_init_pll_ct(const struct fb_info *info, 397static int __devinit aty_init_pll_ct(const struct fb_info *info,
398 union aty_pll *pll) 398 union aty_pll *pll)
399{ 399{
400 struct atyfb_par *par = (struct atyfb_par *) info->par; 400 struct atyfb_par *par = (struct atyfb_par *) info->par;
401 u8 mpost_div, xpost_div, sclk_post_div_real, sclk_fb_div, spll_cntl2; 401 u8 mpost_div, xpost_div, sclk_post_div_real;
402 u32 q, i, memcntl, trp; 402 u32 q, memcntl, trp;
403 u32 dsp_config, dsp_on_off, vga_dsp_config, vga_dsp_on_off; 403 u32 dsp_config, dsp_on_off, vga_dsp_config, vga_dsp_on_off;
404#ifdef DEBUG 404#ifdef DEBUG
405 int pllmclk, pllsclk; 405 int pllmclk, pllsclk;
@@ -575,14 +575,30 @@ static int __init aty_init_pll_ct(const struct fb_info *info,
575 mpost_div += (q < 32*8); 575 mpost_div += (q < 32*8);
576 } 576 }
577 sclk_post_div_real = postdividers[mpost_div]; 577 sclk_post_div_real = postdividers[mpost_div];
578 sclk_fb_div = q * sclk_post_div_real / 8; 578 pll->ct.sclk_fb_div = q * sclk_post_div_real / 8;
579 spll_cntl2 = mpost_div << 4; 579 pll->ct.spll_cntl2 = mpost_div << 4;
580#ifdef DEBUG 580#ifdef DEBUG
581 pllsclk = (1000000 * 2 * sclk_fb_div) / 581 pllsclk = (1000000 * 2 * pll->ct.sclk_fb_div) /
582 (par->ref_clk_per * pll->ct.pll_ref_div); 582 (par->ref_clk_per * pll->ct.pll_ref_div);
583 printk("atyfb(%s): use sclk, pllsclk=%d MHz, sclk=mclk=%d MHz\n", 583 printk("atyfb(%s): use sclk, pllsclk=%d MHz, sclk=mclk=%d MHz\n",
584 __FUNCTION__, pllsclk, pllsclk / sclk_post_div_real); 584 __FUNCTION__, pllsclk, pllsclk / sclk_post_div_real);
585#endif 585#endif
586 }
587
588 /* Disable the extra precision pixel clock controls since we do not use them. */
589 pll->ct.ext_vpll_cntl = aty_ld_pll_ct(EXT_VPLL_CNTL, par);
590 pll->ct.ext_vpll_cntl &= ~(EXT_VPLL_EN | EXT_VPLL_VGA_EN | EXT_VPLL_INSYNC);
591
592 return 0;
593}
594
595static void aty_resume_pll_ct(const struct fb_info *info,
596 union aty_pll *pll)
597{
598 struct atyfb_par *par = info->par;
599
600 if (par->mclk_per != par->xclk_per) {
601 int i;
586 /* 602 /*
587 * This disables the sclk, crashes the computer as reported: 603 * This disables the sclk, crashes the computer as reported:
588 * aty_st_pll_ct(SPLL_CNTL2, 3, info); 604 * aty_st_pll_ct(SPLL_CNTL2, 3, info);
@@ -590,8 +606,8 @@ static int __init aty_init_pll_ct(const struct fb_info *info,
590 * So it seems the sclk must be enabled before it is used; 606 * So it seems the sclk must be enabled before it is used;
591 * so PLL_GEN_CNTL must be programmed *after* the sclk. 607 * so PLL_GEN_CNTL must be programmed *after* the sclk.
592 */ 608 */
593 aty_st_pll_ct(SCLK_FB_DIV, sclk_fb_div, par); 609 aty_st_pll_ct(SCLK_FB_DIV, pll->ct.sclk_fb_div, par);
594 aty_st_pll_ct(SPLL_CNTL2, spll_cntl2, par); 610 aty_st_pll_ct(SPLL_CNTL2, pll->ct.spll_cntl2, par);
595 /* 611 /*
596 * The sclk has been started. However, I believe the first clock 612 * The sclk has been started. However, I believe the first clock
597 * ticks it generates are not very stable. Hope this primitive loop 613 * ticks it generates are not very stable. Hope this primitive loop
@@ -605,11 +621,7 @@ static int __init aty_init_pll_ct(const struct fb_info *info,
605 aty_st_pll_ct(PLL_GEN_CNTL, pll->ct.pll_gen_cntl, par); 621 aty_st_pll_ct(PLL_GEN_CNTL, pll->ct.pll_gen_cntl, par);
606 aty_st_pll_ct(MCLK_FB_DIV, pll->ct.mclk_fb_div, par); 622 aty_st_pll_ct(MCLK_FB_DIV, pll->ct.mclk_fb_div, par);
607 aty_st_pll_ct(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, par); 623 aty_st_pll_ct(PLL_EXT_CNTL, pll->ct.pll_ext_cntl, par);
608 /* Disable the extra precision pixel clock controls since we do not use them. */ 624 aty_st_pll_ct(EXT_VPLL_CNTL, pll->ct.ext_vpll_cntl, par);
609 aty_st_pll_ct(EXT_VPLL_CNTL, aty_ld_pll_ct(EXT_VPLL_CNTL, par) &
610 ~(EXT_VPLL_EN | EXT_VPLL_VGA_EN | EXT_VPLL_INSYNC), par);
611
612 return 0;
613} 625}
614 626
615static int dummy(void) 627static int dummy(void)
@@ -626,5 +638,6 @@ const struct aty_pll_ops aty_pll_ct = {
626 .pll_to_var = aty_pll_to_var_ct, 638 .pll_to_var = aty_pll_to_var_ct,
627 .set_pll = aty_set_pll_ct, 639 .set_pll = aty_set_pll_ct,
628 .get_pll = aty_get_pll_ct, 640 .get_pll = aty_get_pll_ct,
629 .init_pll = aty_init_pll_ct 641 .init_pll = aty_init_pll_ct,
642 .resume_pll = aty_resume_pll_ct,
630}; 643};
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 676754520099..e7c5b219ad1b 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -120,26 +120,32 @@ void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
120void radeon_delete_i2c_busses(struct radeonfb_info *rinfo) 120void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
121{ 121{
122 if (rinfo->i2c[0].rinfo) 122 if (rinfo->i2c[0].rinfo)
123 i2c_bit_del_bus(&rinfo->i2c[0].adapter); 123 i2c_del_adapter(&rinfo->i2c[0].adapter);
124 rinfo->i2c[0].rinfo = NULL; 124 rinfo->i2c[0].rinfo = NULL;
125 125
126 if (rinfo->i2c[1].rinfo) 126 if (rinfo->i2c[1].rinfo)
127 i2c_bit_del_bus(&rinfo->i2c[1].adapter); 127 i2c_del_adapter(&rinfo->i2c[1].adapter);
128 rinfo->i2c[1].rinfo = NULL; 128 rinfo->i2c[1].rinfo = NULL;
129 129
130 if (rinfo->i2c[2].rinfo) 130 if (rinfo->i2c[2].rinfo)
131 i2c_bit_del_bus(&rinfo->i2c[2].adapter); 131 i2c_del_adapter(&rinfo->i2c[2].adapter);
132 rinfo->i2c[2].rinfo = NULL; 132 rinfo->i2c[2].rinfo = NULL;
133 133
134 if (rinfo->i2c[3].rinfo) 134 if (rinfo->i2c[3].rinfo)
135 i2c_bit_del_bus(&rinfo->i2c[3].adapter); 135 i2c_del_adapter(&rinfo->i2c[3].adapter);
136 rinfo->i2c[3].rinfo = NULL; 136 rinfo->i2c[3].rinfo = NULL;
137} 137}
138 138
139int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, 139int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
140 u8 **out_edid) 140 u8 **out_edid)
141{ 141{
142 u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter); 142 u32 reg = rinfo->i2c[conn-1].ddc_reg;
143 u8 *edid;
144
145 OUTREG(reg, INREG(reg) &
146 ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
147
148 edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
143 149
144 if (out_edid) 150 if (out_edid)
145 *out_edid = edid; 151 *out_edid = edid;
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/aty/radeon_monitor.c
index ea531a6f45d1..38c7dbf8c151 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/aty/radeon_monitor.c
@@ -104,10 +104,9 @@ static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_
104 if (pedid == NULL) 104 if (pedid == NULL)
105 return mt; 105 return mt;
106 106
107 tmp = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL); 107 tmp = kmemdup(pedid, EDID_LENGTH, GFP_KERNEL);
108 if (!tmp) 108 if (!tmp)
109 return mt; 109 return mt;
110 memcpy(tmp, pedid, EDID_LENGTH);
111 *out_EDID = tmp; 110 *out_EDID = tmp;
112 return mt; 111 return mt;
113} 112}
diff --git a/drivers/video/au1100fb.h b/drivers/video/au1100fb.h
index 2855534dc235..164fe2f231ec 100644
--- a/drivers/video/au1100fb.h
+++ b/drivers/video/au1100fb.h
@@ -274,7 +274,7 @@ static struct au1100fb_panel known_lcd_panels[] =
274 .bpp = 16, 274 .bpp = 16,
275 .control_base = 0x0004886A | 275 .control_base = 0x0004886A |
276 LCD_CONTROL_DEFAULT_PO | LCD_CONTROL_DEFAULT_SBPPF | 276 LCD_CONTROL_DEFAULT_PO | LCD_CONTROL_DEFAULT_SBPPF |
277 LCD_CONTROL_BPP_16, 277 LCD_CONTROL_BPP_16 | LCD_CONTROL_SBB_4,
278 .clkcontrol_base = 0x00020000, 278 .clkcontrol_base = 0x00020000,
279 .horztiming = 0x005aff1f, 279 .horztiming = 0x005aff1f,
280 .verttiming = 0x16000e57, 280 .verttiming = 0x16000e57,
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 1d97cdf6f382..9601bfe309ac 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -14,6 +14,59 @@
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/fb.h> 15#include <linux/fb.h>
16 16
17
18#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
19 defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
20/* This callback gets called when something important happens inside a
21 * framebuffer driver. We're looking if that important event is blanking,
22 * and if it is, we're switching backlight power as well ...
23 */
24static int fb_notifier_callback(struct notifier_block *self,
25 unsigned long event, void *data)
26{
27 struct backlight_device *bd;
28 struct fb_event *evdata = data;
29
30 /* If we aren't interested in this event, skip it immediately ... */
31 if (event != FB_EVENT_BLANK)
32 return 0;
33
34 bd = container_of(self, struct backlight_device, fb_notif);
35 down(&bd->sem);
36 if (bd->props)
37 if (!bd->props->check_fb ||
38 bd->props->check_fb(evdata->info)) {
39 bd->props->fb_blank = *(int *)evdata->data;
40 if (likely(bd->props && bd->props->update_status))
41 bd->props->update_status(bd);
42 }
43 up(&bd->sem);
44 return 0;
45}
46
47static int backlight_register_fb(struct backlight_device *bd)
48{
49 memset(&bd->fb_notif, 0, sizeof(bd->fb_notif));
50 bd->fb_notif.notifier_call = fb_notifier_callback;
51
52 return fb_register_client(&bd->fb_notif);
53}
54
55static void backlight_unregister_fb(struct backlight_device *bd)
56{
57 fb_unregister_client(&bd->fb_notif);
58}
59#else
60static inline int backlight_register_fb(struct backlight_device *bd)
61{
62 return 0;
63}
64
65static inline void backlight_unregister_fb(struct backlight_device *bd)
66{
67}
68#endif /* CONFIG_FB */
69
17static ssize_t backlight_show_power(struct class_device *cdev, char *buf) 70static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
18{ 71{
19 int rc = -ENXIO; 72 int rc = -ENXIO;
@@ -142,7 +195,7 @@ static struct class backlight_class = {
142 .store = _store, \ 195 .store = _store, \
143} 196}
144 197
145static struct class_device_attribute bl_class_device_attributes[] = { 198static const struct class_device_attribute bl_class_device_attributes[] = {
146 DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power), 199 DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power),
147 DECLARE_ATTR(brightness, 0644, backlight_show_brightness, 200 DECLARE_ATTR(brightness, 0644, backlight_show_brightness,
148 backlight_store_brightness), 201 backlight_store_brightness),
@@ -151,33 +204,6 @@ static struct class_device_attribute bl_class_device_attributes[] = {
151 DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), 204 DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
152}; 205};
153 206
154/* This callback gets called when something important happens inside a
155 * framebuffer driver. We're looking if that important event is blanking,
156 * and if it is, we're switching backlight power as well ...
157 */
158static int fb_notifier_callback(struct notifier_block *self,
159 unsigned long event, void *data)
160{
161 struct backlight_device *bd;
162 struct fb_event *evdata =(struct fb_event *)data;
163
164 /* If we aren't interested in this event, skip it immediately ... */
165 if (event != FB_EVENT_BLANK)
166 return 0;
167
168 bd = container_of(self, struct backlight_device, fb_notif);
169 down(&bd->sem);
170 if (bd->props)
171 if (!bd->props->check_fb ||
172 bd->props->check_fb(evdata->info)) {
173 bd->props->fb_blank = *(int *)evdata->data;
174 if (likely(bd->props && bd->props->update_status))
175 bd->props->update_status(bd);
176 }
177 up(&bd->sem);
178 return 0;
179}
180
181/** 207/**
182 * backlight_device_register - create and register a new object of 208 * backlight_device_register - create and register a new object of
183 * backlight_device class. 209 * backlight_device class.
@@ -218,10 +244,7 @@ error: kfree(new_bd);
218 return ERR_PTR(rc); 244 return ERR_PTR(rc);
219 } 245 }
220 246
221 memset(&new_bd->fb_notif, 0, sizeof(new_bd->fb_notif)); 247 rc = backlight_register_fb(new_bd);
222 new_bd->fb_notif.notifier_call = fb_notifier_callback;
223
224 rc = fb_register_client(&new_bd->fb_notif);
225 if (unlikely(rc)) 248 if (unlikely(rc))
226 goto error; 249 goto error;
227 250
@@ -262,16 +285,10 @@ void backlight_device_unregister(struct backlight_device *bd)
262 &bl_class_device_attributes[i]); 285 &bl_class_device_attributes[i]);
263 286
264 down(&bd->sem); 287 down(&bd->sem);
265 if (likely(bd->props && bd->props->update_status)) {
266 bd->props->brightness = 0;
267 bd->props->power = 0;
268 bd->props->update_status(bd);
269 }
270
271 bd->props = NULL; 288 bd->props = NULL;
272 up(&bd->sem); 289 up(&bd->sem);
273 290
274 fb_unregister_client(&bd->fb_notif); 291 backlight_unregister_fb(bd);
275 292
276 class_device_unregister(&bd->class_dev); 293 class_device_unregister(&bd->class_dev);
277} 294}
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index 2ebbfd95145f..61587ca2cdbb 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -111,7 +111,7 @@ static struct backlight_properties corgibl_data = {
111 .update_status = corgibl_set_intensity, 111 .update_status = corgibl_set_intensity,
112}; 112};
113 113
114static int __init corgibl_probe(struct platform_device *pdev) 114static int corgibl_probe(struct platform_device *pdev)
115{ 115{
116 struct corgibl_machinfo *machinfo = pdev->dev.platform_data; 116 struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
117 117
@@ -135,6 +135,10 @@ static int __init corgibl_probe(struct platform_device *pdev)
135 135
136static int corgibl_remove(struct platform_device *dev) 136static int corgibl_remove(struct platform_device *dev)
137{ 137{
138 corgibl_data.power = 0;
139 corgibl_data.brightness = 0;
140 corgibl_send_intensity(corgi_backlight_device);
141
138 backlight_device_unregister(corgi_backlight_device); 142 backlight_device_unregister(corgi_backlight_device);
139 143
140 printk("Corgi Backlight Driver Unloaded\n"); 144 printk("Corgi Backlight Driver Unloaded\n");
@@ -166,4 +170,4 @@ module_exit(corgibl_exit);
166 170
167MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); 171MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
168MODULE_DESCRIPTION("Corgi Backlight Driver"); 172MODULE_DESCRIPTION("Corgi Backlight Driver");
169MODULE_LICENSE("GPLv2"); 173MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index fe1488374f62..1c569fb543ae 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -19,7 +19,7 @@
19#include <linux/backlight.h> 19#include <linux/backlight.h>
20 20
21#include <asm/cpu/dac.h> 21#include <asm/cpu/dac.h>
22#include <asm/hp6xx/hp6xx.h> 22#include <asm/hp6xx.h>
23#include <asm/hd64461.h> 23#include <asm/hd64461.h>
24 24
25#define HP680_MAX_INTENSITY 255 25#define HP680_MAX_INTENSITY 255
@@ -117,6 +117,10 @@ static int __init hp680bl_probe(struct platform_device *dev)
117 117
118static int hp680bl_remove(struct platform_device *dev) 118static int hp680bl_remove(struct platform_device *dev)
119{ 119{
120 hp680bl_data.brightness = 0;
121 hp680bl_data.power = 0;
122 hp680bl_send_intensity(hp680_backlight_device);
123
120 backlight_device_unregister(hp680_backlight_device); 124 backlight_device_unregister(hp680_backlight_device);
121 125
122 return 0; 126 return 0;
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index bc8ab005a3fb..f6e041627edb 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -14,6 +14,53 @@
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/fb.h> 15#include <linux/fb.h>
16 16
17#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
18 defined(CONFIG_LCD_CLASS_DEVICE_MODULE))
19/* This callback gets called when something important happens inside a
20 * framebuffer driver. We're looking if that important event is blanking,
21 * and if it is, we're switching lcd power as well ...
22 */
23static int fb_notifier_callback(struct notifier_block *self,
24 unsigned long event, void *data)
25{
26 struct lcd_device *ld;
27 struct fb_event *evdata = data;
28
29 /* If we aren't interested in this event, skip it immediately ... */
30 if (event != FB_EVENT_BLANK)
31 return 0;
32
33 ld = container_of(self, struct lcd_device, fb_notif);
34 down(&ld->sem);
35 if (ld->props)
36 if (!ld->props->check_fb || ld->props->check_fb(evdata->info))
37 ld->props->set_power(ld, *(int *)evdata->data);
38 up(&ld->sem);
39 return 0;
40}
41
42static int lcd_register_fb(struct lcd_device *ld)
43{
44 memset(&ld->fb_notif, 0, sizeof(&ld->fb_notif));
45 ld->fb_notif.notifier_call = fb_notifier_callback;
46 return fb_register_client(&ld->fb_notif);
47}
48
49static void lcd_unregister_fb(struct lcd_device *ld)
50{
51 fb_unregister_client(&ld->fb_notif);
52}
53#else
54static int lcd_register_fb(struct lcd_device *ld)
55{
56 return 0;
57}
58
59static inline void lcd_unregister_fb(struct lcd_device *ld)
60{
61}
62#endif /* CONFIG_FB */
63
17static ssize_t lcd_show_power(struct class_device *cdev, char *buf) 64static ssize_t lcd_show_power(struct class_device *cdev, char *buf)
18{ 65{
19 int rc; 66 int rc;
@@ -121,35 +168,12 @@ static struct class lcd_class = {
121 .store = _store, \ 168 .store = _store, \
122} 169}
123 170
124static struct class_device_attribute lcd_class_device_attributes[] = { 171static const struct class_device_attribute lcd_class_device_attributes[] = {
125 DECLARE_ATTR(power, 0644, lcd_show_power, lcd_store_power), 172 DECLARE_ATTR(power, 0644, lcd_show_power, lcd_store_power),
126 DECLARE_ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast), 173 DECLARE_ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast),
127 DECLARE_ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL), 174 DECLARE_ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL),
128}; 175};
129 176
130/* This callback gets called when something important happens inside a
131 * framebuffer driver. We're looking if that important event is blanking,
132 * and if it is, we're switching lcd power as well ...
133 */
134static int fb_notifier_callback(struct notifier_block *self,
135 unsigned long event, void *data)
136{
137 struct lcd_device *ld;
138 struct fb_event *evdata =(struct fb_event *)data;
139
140 /* If we aren't interested in this event, skip it immediately ... */
141 if (event != FB_EVENT_BLANK)
142 return 0;
143
144 ld = container_of(self, struct lcd_device, fb_notif);
145 down(&ld->sem);
146 if (ld->props)
147 if (!ld->props->check_fb || ld->props->check_fb(evdata->info))
148 ld->props->set_power(ld, *(int *)evdata->data);
149 up(&ld->sem);
150 return 0;
151}
152
153/** 177/**
154 * lcd_device_register - register a new object of lcd_device class. 178 * lcd_device_register - register a new object of lcd_device class.
155 * @name: the name of the new object(must be the same as the name of the 179 * @name: the name of the new object(must be the same as the name of the
@@ -186,10 +210,8 @@ error: kfree(new_ld);
186 return ERR_PTR(rc); 210 return ERR_PTR(rc);
187 } 211 }
188 212
189 memset(&new_ld->fb_notif, 0, sizeof(new_ld->fb_notif)); 213 rc = lcd_register_fb(new_ld);
190 new_ld->fb_notif.notifier_call = fb_notifier_callback;
191 214
192 rc = fb_register_client(&new_ld->fb_notif);
193 if (unlikely(rc)) 215 if (unlikely(rc))
194 goto error; 216 goto error;
195 217
@@ -232,9 +254,7 @@ void lcd_device_unregister(struct lcd_device *ld)
232 down(&ld->sem); 254 down(&ld->sem);
233 ld->props = NULL; 255 ld->props = NULL;
234 up(&ld->sem); 256 up(&ld->sem);
235 257 lcd_unregister_fb(ld);
236 fb_unregister_client(&ld->fb_notif);
237
238 class_device_unregister(&ld->class_dev); 258 class_device_unregister(&ld->class_dev);
239} 259}
240EXPORT_SYMBOL(lcd_device_unregister); 260EXPORT_SYMBOL(lcd_device_unregister);
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
index 628571c63bac..2d7905410b2a 100644
--- a/drivers/video/backlight/locomolcd.c
+++ b/drivers/video/backlight/locomolcd.c
@@ -200,6 +200,10 @@ static int locomolcd_remove(struct locomo_dev *dev)
200{ 200{
201 unsigned long flags; 201 unsigned long flags;
202 202
203 locomobl_data.brightness = 0;
204 locomobl_data.power = 0;
205 locomolcd_set_intensity(locomolcd_bl_device);
206
203 backlight_device_unregister(locomolcd_bl_device); 207 backlight_device_unregister(locomolcd_bl_device);
204 local_irq_save(flags); 208 local_irq_save(flags);
205 locomolcd_dev = NULL; 209 locomolcd_dev = NULL;
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 51d35386a945..261004473c8e 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -42,7 +42,7 @@
42#define DPRINTK(fmt, args...) 42#define DPRINTK(fmt, args...)
43#endif 43#endif
44 44
45static u32 cfb_tab8[] = { 45static const u32 cfb_tab8[] = {
46#if defined(__BIG_ENDIAN) 46#if defined(__BIG_ENDIAN)
47 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, 47 0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
48 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, 48 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
@@ -58,7 +58,7 @@ static u32 cfb_tab8[] = {
58#endif 58#endif
59}; 59};
60 60
61static u32 cfb_tab16[] = { 61static const u32 cfb_tab16[] = {
62#if defined(__BIG_ENDIAN) 62#if defined(__BIG_ENDIAN)
63 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff 63 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
64#elif defined(__LITTLE_ENDIAN) 64#elif defined(__LITTLE_ENDIAN)
@@ -68,7 +68,7 @@ static u32 cfb_tab16[] = {
68#endif 68#endif
69}; 69};
70 70
71static u32 cfb_tab32[] = { 71static const u32 cfb_tab32[] = {
72 0x00000000, 0xffffffff 72 0x00000000, 0xffffffff
73}; 73};
74 74
@@ -218,7 +218,7 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *
218 u32 bit_mask, end_mask, eorx, shift; 218 u32 bit_mask, end_mask, eorx, shift;
219 const char *s = image->data, *src; 219 const char *s = image->data, *src;
220 u32 __iomem *dst; 220 u32 __iomem *dst;
221 u32 *tab = NULL; 221 const u32 *tab = NULL;
222 int i, j, k; 222 int i, j, k;
223 223
224 switch (bpp) { 224 switch (bpp) {
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index daf43f535a0b..2c4bc6205738 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -2442,7 +2442,10 @@ static int cirrusfb_pci_register (struct pci_dev *pdev,
2442 printk ("Cirrus Logic chipset on PCI bus\n"); 2442 printk ("Cirrus Logic chipset on PCI bus\n");
2443 pci_set_drvdata(pdev, info); 2443 pci_set_drvdata(pdev, info);
2444 2444
2445 return cirrusfb_register(cinfo); 2445 ret = cirrusfb_register(cinfo);
2446 if (ret)
2447 iounmap(cinfo->fbmem);
2448 return ret;
2446 2449
2447err_release_legacy: 2450err_release_legacy:
2448 if (release_io_ports) 2451 if (release_io_ports)
@@ -2574,7 +2577,15 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
2574 printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n"); 2577 printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
2575 zorro_set_drvdata(z, info); 2578 zorro_set_drvdata(z, info);
2576 2579
2577 return cirrusfb_register(cinfo); 2580 ret = cirrusfb_register(cinfo);
2581 if (ret) {
2582 if (btype == BT_PICASSO4) {
2583 iounmap(cinfo->fbmem);
2584 iounmap(cinfo->regbase - 0x600000);
2585 } else if (board_addr > 0x01000000)
2586 iounmap(cinfo->fbmem);
2587 }
2588 return ret;
2578 2589
2579err_unmap_regbase: 2590err_unmap_regbase:
2580 /* Parental advisory: explicit hack */ 2591 /* Parental advisory: explicit hack */
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 302174b8e477..31f476a64790 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -383,9 +383,9 @@ static void fbcon_update_softback(struct vc_data *vc)
383 softback_top = 0; 383 softback_top = 0;
384} 384}
385 385
386static void fb_flashcursor(void *private) 386static void fb_flashcursor(struct work_struct *work)
387{ 387{
388 struct fb_info *info = private; 388 struct fb_info *info = container_of(work, struct fb_info, queue);
389 struct fbcon_ops *ops = info->fbcon_par; 389 struct fbcon_ops *ops = info->fbcon_par;
390 struct display *p; 390 struct display *p;
391 struct vc_data *vc = NULL; 391 struct vc_data *vc = NULL;
@@ -442,7 +442,7 @@ static void fbcon_add_cursor_timer(struct fb_info *info)
442 if ((!info->queue.func || info->queue.func == fb_flashcursor) && 442 if ((!info->queue.func || info->queue.func == fb_flashcursor) &&
443 !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) { 443 !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) {
444 if (!info->queue.func) 444 if (!info->queue.func)
445 INIT_WORK(&info->queue, fb_flashcursor, info); 445 INIT_WORK(&info->queue, fb_flashcursor);
446 446
447 init_timer(&ops->cursor_timer); 447 init_timer(&ops->cursor_timer);
448 ops->cursor_timer.function = cursor_timer_handler; 448 ops->cursor_timer.function = cursor_timer_handler;
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 7d07d8383569..f577bd80e020 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -1,11 +1,13 @@
1/* 1/*
2 * linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices 2 * linux/drivers/video/softcursor.c
3 *
4 * Generic software cursor for frame buffer devices
3 * 5 *
4 * Created 14 Nov 2002 by James Simmons 6 * Created 14 Nov 2002 by James Simmons
5 * 7 *
6 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General
7 * License. See the file COPYING in the main directory of this archive 9 * Public License. See the file COPYING in the main directory of this
8 * for more details. 10 * archive for more details.
9 */ 11 */
10 12
11#include <linux/module.h> 13#include <linux/module.h>
@@ -25,7 +27,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
25 unsigned int buf_align = info->pixmap.buf_align - 1; 27 unsigned int buf_align = info->pixmap.buf_align - 1;
26 unsigned int i, size, dsize, s_pitch, d_pitch; 28 unsigned int i, size, dsize, s_pitch, d_pitch;
27 struct fb_image *image; 29 struct fb_image *image;
28 u8 *dst; 30 u8 *src, *dst;
29 31
30 if (info->state != FBINFO_STATE_RUNNING) 32 if (info->state != FBINFO_STATE_RUNNING)
31 return 0; 33 return 0;
@@ -45,7 +47,8 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
45 } 47 }
46 } 48 }
47 49
48 image = (struct fb_image *) (ops->cursor_src + dsize); 50 src = ops->cursor_src + sizeof(struct fb_image);
51 image = (struct fb_image *)ops->cursor_src;
49 *image = cursor->image; 52 *image = cursor->image;
50 d_pitch = (s_pitch + scan_align) & ~scan_align; 53 d_pitch = (s_pitch + scan_align) & ~scan_align;
51 54
@@ -57,21 +60,18 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
57 switch (cursor->rop) { 60 switch (cursor->rop) {
58 case ROP_XOR: 61 case ROP_XOR:
59 for (i = 0; i < dsize; i++) 62 for (i = 0; i < dsize; i++)
60 ops->cursor_src[i] = image->data[i] ^ 63 src[i] = image->data[i] ^ cursor->mask[i];
61 cursor->mask[i];
62 break; 64 break;
63 case ROP_COPY: 65 case ROP_COPY:
64 default: 66 default:
65 for (i = 0; i < dsize; i++) 67 for (i = 0; i < dsize; i++)
66 ops->cursor_src[i] = image->data[i] & 68 src[i] = image->data[i] & cursor->mask[i];
67 cursor->mask[i];
68 break; 69 break;
69 } 70 }
70 } else 71 } else
71 memcpy(ops->cursor_src, image->data, dsize); 72 memcpy(src, image->data, dsize);
72 73
73 fb_pad_aligned_buffer(dst, d_pitch, ops->cursor_src, s_pitch, 74 fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
74 image->height);
75 image->data = dst; 75 image->data = dst;
76 info->fbops->fb_imageblit(info, image); 76 info->fbops->fb_imageblit(info, image);
77 return 0; 77 return 0;
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 45586aaabd1e..57b21e533036 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -345,7 +345,7 @@ static void sticon_save_screen(struct vc_data *conp)
345{ 345{
346} 346}
347 347
348static struct consw sti_con = { 348static const struct consw sti_con = {
349 .owner = THIS_MODULE, 349 .owner = THIS_MODULE,
350 .con_startup = sticon_startup, 350 .con_startup = sticon_startup,
351 .con_init = sticon_init, 351 .con_init = sticon_init,
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 0a2c10a1abf8..4a9bde2c839b 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -93,27 +93,27 @@ static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
93static unsigned long vgacon_uni_pagedir[2]; 93static unsigned long vgacon_uni_pagedir[2];
94 94
95/* Description of the hardware situation */ 95/* Description of the hardware situation */
96static unsigned long vga_vram_base; /* Base of video memory */ 96static int vga_init_done __read_mostly;
97static unsigned long vga_vram_end; /* End of video memory */ 97static unsigned long vga_vram_base __read_mostly; /* Base of video memory */
98static int vga_vram_size; /* Size of video memory */ 98static unsigned long vga_vram_end __read_mostly; /* End of video memory */
99static u16 vga_video_port_reg; /* Video register select port */ 99static unsigned int vga_vram_size __read_mostly; /* Size of video memory */
100static u16 vga_video_port_val; /* Video register value port */ 100static u16 vga_video_port_reg __read_mostly; /* Video register select port */
101static unsigned int vga_video_num_columns; /* Number of text columns */ 101static u16 vga_video_port_val __read_mostly; /* Video register value port */
102static unsigned int vga_video_num_lines; /* Number of text lines */ 102static unsigned int vga_video_num_columns; /* Number of text columns */
103static int vga_can_do_color = 0; /* Do we support colors? */ 103static unsigned int vga_video_num_lines; /* Number of text lines */
104static unsigned int vga_default_font_height;/* Height of default screen font */ 104static int vga_can_do_color __read_mostly; /* Do we support colors? */
105static unsigned char vga_video_type; /* Card type */ 105static unsigned int vga_default_font_height __read_mostly; /* Height of default screen font */
106static unsigned char vga_hardscroll_enabled; 106static unsigned char vga_video_type __read_mostly; /* Card type */
107static unsigned char vga_hardscroll_user_enable = 1; 107static unsigned char vga_hardscroll_enabled __read_mostly;
108static unsigned char vga_hardscroll_user_enable __read_mostly = 1;
108static unsigned char vga_font_is_default = 1; 109static unsigned char vga_font_is_default = 1;
109static int vga_vesa_blanked; 110static int vga_vesa_blanked;
110static int vga_palette_blanked; 111static int vga_palette_blanked;
111static int vga_is_gfx; 112static int vga_is_gfx;
112static int vga_512_chars; 113static int vga_512_chars;
113static int vga_video_font_height; 114static int vga_video_font_height;
114static int vga_scan_lines; 115static int vga_scan_lines __read_mostly;
115static unsigned int vga_rolled_over = 0; 116static unsigned int vga_rolled_over;
116static int vga_init_done;
117 117
118static int __init no_scroll(char *str) 118static int __init no_scroll(char *str)
119{ 119{
diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c
index c40e72dafb0e..0b8d5b121152 100644
--- a/drivers/video/cyberfb.c
+++ b/drivers/video/cyberfb.c
@@ -109,8 +109,6 @@ static void cv64_dump(void);
109#define wb_64(regs,reg,dat) (*(((volatile unsigned char *)regs) + reg) = dat) 109#define wb_64(regs,reg,dat) (*(((volatile unsigned char *)regs) + reg) = dat)
110#define rb_64(regs, reg) (*(((volatile unsigned char *)regs) + reg)) 110#define rb_64(regs, reg) (*(((volatile unsigned char *)regs) + reg))
111 111
112#define ww_64(regs,reg,dat) (*((volatile unsigned short *)(regs + reg) = dat)
113
114struct cyberfb_par { 112struct cyberfb_par {
115 struct fb_var_screeninfo var; 113 struct fb_var_screeninfo var;
116 __u32 type; 114 __u32 type;
@@ -1055,6 +1053,8 @@ int __init cyberfb_init(void)
1055 1053
1056 if (register_framebuffer(&fb_info) < 0) { 1054 if (register_framebuffer(&fb_info) < 0) {
1057 DPRINTK("EXIT - register_framebuffer failed\n"); 1055 DPRINTK("EXIT - register_framebuffer failed\n");
1056 if (CyberBase)
1057 iounmap(CyberBase);
1058 release_mem_region(CyberMem_phys, 0x400000); 1058 release_mem_region(CyberMem_phys, 0x400000);
1059 release_mem_region(CyberRegs_phys, 0x10000); 1059 release_mem_region(CyberRegs_phys, 0x10000);
1060 return -EINVAL; 1060 return -EINVAL;
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 737257d278f0..29e07c109887 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -405,7 +405,7 @@ static inline unsigned long copy_to_user16(void *to, const void *from,
405static ssize_t 405static ssize_t
406epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos) 406epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos)
407{ 407{
408 struct inode *inode = file->f_dentry->d_inode; 408 struct inode *inode = file->f_path.dentry->d_inode;
409 int fbidx = iminor(inode); 409 int fbidx = iminor(inode);
410 struct fb_info *info = registered_fb[fbidx]; 410 struct fb_info *info = registered_fb[fbidx];
411 unsigned long p = *ppos; 411 unsigned long p = *ppos;
@@ -437,7 +437,7 @@ static ssize_t
437epson1355fb_write(struct file *file, const char *buf, 437epson1355fb_write(struct file *file, const char *buf,
438 size_t count, loff_t * ppos) 438 size_t count, loff_t * ppos)
439{ 439{
440 struct inode *inode = file->f_dentry->d_inode; 440 struct inode *inode = file->f_path.dentry->d_inode;
441 int fbidx = iminor(inode); 441 int fbidx = iminor(inode);
442 struct fb_info *info = registered_fb[fbidx]; 442 struct fb_info *info = registered_fb[fbidx];
443 unsigned long p = *ppos; 443 unsigned long p = *ppos;
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fb_ddc.c
index 3aa6ebf68f17..f836137a0eda 100644
--- a/drivers/video/fb_ddc.c
+++ b/drivers/video/fb_ddc.c
@@ -20,26 +20,26 @@
20static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter) 20static unsigned char *fb_do_probe_ddc_edid(struct i2c_adapter *adapter)
21{ 21{
22 unsigned char start = 0x0; 22 unsigned char start = 0x0;
23 unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
23 struct i2c_msg msgs[] = { 24 struct i2c_msg msgs[] = {
24 { 25 {
25 .addr = DDC_ADDR, 26 .addr = DDC_ADDR,
27 .flags = 0,
26 .len = 1, 28 .len = 1,
27 .buf = &start, 29 .buf = &start,
28 }, { 30 }, {
29 .addr = DDC_ADDR, 31 .addr = DDC_ADDR,
30 .flags = I2C_M_RD, 32 .flags = I2C_M_RD,
31 .len = EDID_LENGTH, 33 .len = EDID_LENGTH,
34 .buf = buf,
32 } 35 }
33 }; 36 };
34 unsigned char *buf;
35 37
36 buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
37 if (!buf) { 38 if (!buf) {
38 dev_warn(&adapter->dev, "unable to allocate memory for EDID " 39 dev_warn(&adapter->dev, "unable to allocate memory for EDID "
39 "block.\n"); 40 "block.\n");
40 return NULL; 41 return NULL;
41 } 42 }
42 msgs[1].buf = buf;
43 43
44 if (i2c_transfer(adapter, msgs, 2) == 2) 44 if (i2c_transfer(adapter, msgs, 2) == 2)
45 return buf; 45 return buf;
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index e8b135f3d80d..148108afdd51 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -18,63 +18,64 @@
18 18
19#include <asm/uaccess.h> 19#include <asm/uaccess.h>
20 20
21static u16 red2[] = { 21static u16 red2[] __read_mostly = {
22 0x0000, 0xaaaa 22 0x0000, 0xaaaa
23}; 23};
24static u16 green2[] = { 24static u16 green2[] __read_mostly = {
25 0x0000, 0xaaaa 25 0x0000, 0xaaaa
26}; 26};
27static u16 blue2[] = { 27static u16 blue2[] __read_mostly = {
28 0x0000, 0xaaaa 28 0x0000, 0xaaaa
29}; 29};
30 30
31static u16 red4[] = { 31static u16 red4[] __read_mostly = {
32 0x0000, 0xaaaa, 0x5555, 0xffff 32 0x0000, 0xaaaa, 0x5555, 0xffff
33}; 33};
34static u16 green4[] = { 34static u16 green4[] __read_mostly = {
35 0x0000, 0xaaaa, 0x5555, 0xffff 35 0x0000, 0xaaaa, 0x5555, 0xffff
36}; 36};
37static u16 blue4[] = { 37static u16 blue4[] __read_mostly = {
38 0x0000, 0xaaaa, 0x5555, 0xffff 38 0x0000, 0xaaaa, 0x5555, 0xffff
39}; 39};
40 40
41static u16 red8[] = { 41static u16 red8[] __read_mostly = {
42 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa 42 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa
43}; 43};
44static u16 green8[] = { 44static u16 green8[] __read_mostly = {
45 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa 45 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa
46}; 46};
47static u16 blue8[] = { 47static u16 blue8[] __read_mostly = {
48 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa 48 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa
49}; 49};
50 50
51static u16 red16[] = { 51static u16 red16[] __read_mostly = {
52 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 52 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
53 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff 53 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
54}; 54};
55static u16 green16[] = { 55static u16 green16[] __read_mostly = {
56 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa, 56 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
57 0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff 57 0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
58}; 58};
59static u16 blue16[] = { 59static u16 blue16[] __read_mostly = {
60 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 60 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa,
61 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff 61 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff
62}; 62};
63 63
64static struct fb_cmap default_2_colors = { 64static const struct fb_cmap default_2_colors = {
65 0, 2, red2, green2, blue2, NULL 65 .len=2, .red=red2, .green=green2, .blue=blue2
66}; 66};
67static struct fb_cmap default_8_colors = { 67static const struct fb_cmap default_8_colors = {
68 0, 8, red8, green8, blue8, NULL 68 .len=8, .red=red8, .green=green8, .blue=blue8
69}; 69};
70static struct fb_cmap default_4_colors = { 70static const struct fb_cmap default_4_colors = {
71 0, 4, red4, green4, blue4, NULL 71 .len=4, .red=red4, .green=green4, .blue=blue4
72}; 72};
73static struct fb_cmap default_16_colors = { 73static const struct fb_cmap default_16_colors = {
74 0, 16, red16, green16, blue16, NULL 74 .len=16, .red=red16, .green=green16, .blue=blue16
75}; 75};
76 76
77 77
78
78/** 79/**
79 * fb_alloc_cmap - allocate a colormap 80 * fb_alloc_cmap - allocate a colormap
80 * @cmap: frame buffer colormap structure 81 * @cmap: frame buffer colormap structure
@@ -146,7 +147,7 @@ void fb_dealloc_cmap(struct fb_cmap *cmap)
146 * Copy contents of colormap from @from to @to. 147 * Copy contents of colormap from @from to @to.
147 */ 148 */
148 149
149int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to) 150int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to)
150{ 151{
151 int tooff = 0, fromoff = 0; 152 int tooff = 0, fromoff = 0;
152 int size; 153 int size;
@@ -170,7 +171,7 @@ int fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to)
170 return 0; 171 return 0;
171} 172}
172 173
173int fb_cmap_to_user(struct fb_cmap *from, struct fb_cmap_user *to) 174int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to)
174{ 175{
175 int tooff = 0, fromoff = 0; 176 int tooff = 0, fromoff = 0;
176 int size; 177 int size;
@@ -282,7 +283,7 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
282 * 283 *
283 */ 284 */
284 285
285struct fb_cmap *fb_default_cmap(int len) 286const struct fb_cmap *fb_default_cmap(int len)
286{ 287{
287 if (len <= 2) 288 if (len <= 2)
288 return &default_2_colors; 289 return &default_2_colors;
@@ -305,22 +306,22 @@ void fb_invert_cmaps(void)
305{ 306{
306 u_int i; 307 u_int i;
307 308
308 for (i = 0; i < 2; i++) { 309 for (i = 0; i < ARRAY_SIZE(red2); i++) {
309 red2[i] = ~red2[i]; 310 red2[i] = ~red2[i];
310 green2[i] = ~green2[i]; 311 green2[i] = ~green2[i];
311 blue2[i] = ~blue2[i]; 312 blue2[i] = ~blue2[i];
312 } 313 }
313 for (i = 0; i < 4; i++) { 314 for (i = 0; i < ARRAY_SIZE(red4); i++) {
314 red4[i] = ~red4[i]; 315 red4[i] = ~red4[i];
315 green4[i] = ~green4[i]; 316 green4[i] = ~green4[i];
316 blue4[i] = ~blue4[i]; 317 blue4[i] = ~blue4[i];
317 } 318 }
318 for (i = 0; i < 8; i++) { 319 for (i = 0; i < ARRAY_SIZE(red8); i++) {
319 red8[i] = ~red8[i]; 320 red8[i] = ~red8[i];
320 green8[i] = ~green8[i]; 321 green8[i] = ~green8[i];
321 blue8[i] = ~blue8[i]; 322 blue8[i] = ~blue8[i];
322 } 323 }
323 for (i = 0; i < 16; i++) { 324 for (i = 0; i < ARRAY_SIZE(red16); i++) {
324 red16[i] = ~red16[i]; 325 red16[i] = ~red16[i];
325 green16[i] = ~green16[i]; 326 green16[i] = ~green16[i];
326 blue16[i] = ~blue16[i]; 327 blue16[i] = ~blue16[i];
diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c
index b5498999c4ec..0847c5e72cbd 100644
--- a/drivers/video/fbcvt.c
+++ b/drivers/video/fbcvt.c
@@ -57,7 +57,7 @@ struct fb_cvt_data {
57 u32 status; 57 u32 status;
58}; 58};
59 59
60static int fb_cvt_vbi_tab[] = { 60static const unsigned char fb_cvt_vbi_tab[] = {
61 4, /* 4:3 */ 61 4, /* 4:3 */
62 5, /* 16:9 */ 62 5, /* 16:9 */
63 6, /* 16:10 */ 63 6, /* 16:10 */
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 93ffcdd95f50..3cfea315a48f 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -52,8 +52,8 @@
52 52
53#define FBPIXMAPSIZE (1024 * 8) 53#define FBPIXMAPSIZE (1024 * 8)
54 54
55struct fb_info *registered_fb[FB_MAX]; 55struct fb_info *registered_fb[FB_MAX] __read_mostly;
56int num_registered_fb; 56int num_registered_fb __read_mostly;
57 57
58/* 58/*
59 * Helpers 59 * Helpers
@@ -202,7 +202,7 @@ static void fb_set_logo_truepalette(struct fb_info *info,
202 const struct linux_logo *logo, 202 const struct linux_logo *logo,
203 u32 *palette) 203 u32 *palette)
204{ 204{
205 unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff }; 205 static const unsigned char mask[] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
206 unsigned char redmask, greenmask, bluemask; 206 unsigned char redmask, greenmask, bluemask;
207 int redshift, greenshift, blueshift; 207 int redshift, greenshift, blueshift;
208 int i; 208 int i;
@@ -317,7 +317,7 @@ static struct logo_data {
317 int needs_truepalette; 317 int needs_truepalette;
318 int needs_cmapreset; 318 int needs_cmapreset;
319 const struct linux_logo *logo; 319 const struct linux_logo *logo;
320} fb_logo; 320} fb_logo __read_mostly;
321 321
322static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height) 322static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
323{ 323{
@@ -572,7 +572,7 @@ static ssize_t
572fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 572fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
573{ 573{
574 unsigned long p = *ppos; 574 unsigned long p = *ppos;
575 struct inode *inode = file->f_dentry->d_inode; 575 struct inode *inode = file->f_path.dentry->d_inode;
576 int fbidx = iminor(inode); 576 int fbidx = iminor(inode);
577 struct fb_info *info = registered_fb[fbidx]; 577 struct fb_info *info = registered_fb[fbidx];
578 u32 *buffer, *dst; 578 u32 *buffer, *dst;
@@ -647,7 +647,7 @@ static ssize_t
647fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 647fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
648{ 648{
649 unsigned long p = *ppos; 649 unsigned long p = *ppos;
650 struct inode *inode = file->f_dentry->d_inode; 650 struct inode *inode = file->f_path.dentry->d_inode;
651 int fbidx = iminor(inode); 651 int fbidx = iminor(inode);
652 struct fb_info *info = registered_fb[fbidx]; 652 struct fb_info *info = registered_fb[fbidx];
653 u32 *buffer, *src; 653 u32 *buffer, *src;
@@ -1081,7 +1081,7 @@ static int fb_get_fscreeninfo(struct inode *inode, struct file *file,
1081static long 1081static long
1082fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1082fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1083{ 1083{
1084 struct inode *inode = file->f_dentry->d_inode; 1084 struct inode *inode = file->f_path.dentry->d_inode;
1085 int fbidx = iminor(inode); 1085 int fbidx = iminor(inode);
1086 struct fb_info *info = registered_fb[fbidx]; 1086 struct fb_info *info = registered_fb[fbidx];
1087 struct fb_ops *fb = info->fbops; 1087 struct fb_ops *fb = info->fbops;
@@ -1121,7 +1121,7 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1121static int 1121static int
1122fb_mmap(struct file *file, struct vm_area_struct * vma) 1122fb_mmap(struct file *file, struct vm_area_struct * vma)
1123{ 1123{
1124 int fbidx = iminor(file->f_dentry->d_inode); 1124 int fbidx = iminor(file->f_path.dentry->d_inode);
1125 struct fb_info *info = registered_fb[fbidx]; 1125 struct fb_info *info = registered_fb[fbidx];
1126 struct fb_ops *fb = info->fbops; 1126 struct fb_ops *fb = info->fbops;
1127 unsigned long off; 1127 unsigned long off;
@@ -1253,7 +1253,7 @@ fb_release(struct inode *inode, struct file *file)
1253 return 0; 1253 return 0;
1254} 1254}
1255 1255
1256static struct file_operations fb_fops = { 1256static const struct file_operations fb_fops = {
1257 .owner = THIS_MODULE, 1257 .owner = THIS_MODULE,
1258 .read = fb_read, 1258 .read = fb_read,
1259 .write = fb_write, 1259 .write = fb_write,
@@ -1296,14 +1296,14 @@ register_framebuffer(struct fb_info *fb_info)
1296 break; 1296 break;
1297 fb_info->node = i; 1297 fb_info->node = i;
1298 1298
1299 fb_info->class_device = class_device_create(fb_class, NULL, MKDEV(FB_MAJOR, i), 1299 fb_info->dev = device_create(fb_class, fb_info->device,
1300 fb_info->device, "fb%d", i); 1300 MKDEV(FB_MAJOR, i), "fb%d", i);
1301 if (IS_ERR(fb_info->class_device)) { 1301 if (IS_ERR(fb_info->dev)) {
1302 /* Not fatal */ 1302 /* Not fatal */
1303 printk(KERN_WARNING "Unable to create class_device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->class_device)); 1303 printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev));
1304 fb_info->class_device = NULL; 1304 fb_info->dev = NULL;
1305 } else 1305 } else
1306 fb_init_class_device(fb_info); 1306 fb_init_device(fb_info);
1307 1307
1308 if (fb_info->pixmap.addr == NULL) { 1308 if (fb_info->pixmap.addr == NULL) {
1309 fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL); 1309 fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
@@ -1356,8 +1356,8 @@ unregister_framebuffer(struct fb_info *fb_info)
1356 fb_destroy_modelist(&fb_info->modelist); 1356 fb_destroy_modelist(&fb_info->modelist);
1357 registered_fb[i]=NULL; 1357 registered_fb[i]=NULL;
1358 num_registered_fb--; 1358 num_registered_fb--;
1359 fb_cleanup_class_device(fb_info); 1359 fb_cleanup_device(fb_info);
1360 class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); 1360 device_destroy(fb_class, MKDEV(FB_MAJOR, i));
1361 event.info = fb_info; 1361 event.info = fb_info;
1362 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); 1362 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1363 return 0; 1363 return 0;
@@ -1459,8 +1459,8 @@ int fb_new_modelist(struct fb_info *info)
1459 return err; 1459 return err;
1460} 1460}
1461 1461
1462static char *video_options[FB_MAX]; 1462static char *video_options[FB_MAX] __read_mostly;
1463static int ofonly; 1463static int ofonly __read_mostly;
1464 1464
1465extern const char *global_mode_option; 1465extern const char *global_mode_option;
1466 1466
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index de93139ccbb5..6b385c39b8b5 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -58,7 +58,7 @@ struct broken_edid {
58 u32 fix; 58 u32 fix;
59}; 59};
60 60
61static struct broken_edid brokendb[] = { 61static const struct broken_edid brokendb[] = {
62 /* DEC FR-PCXAV-YZ */ 62 /* DEC FR-PCXAV-YZ */
63 { 63 {
64 .manufacturer = "DEC", 64 .manufacturer = "DEC",
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index d3a50417ed9a..323bdf6fc7d5 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -73,7 +73,7 @@ EXPORT_SYMBOL(framebuffer_alloc);
73 * 73 *
74 * @info: frame buffer info structure 74 * @info: frame buffer info structure
75 * 75 *
76 * Drop the reference count of the class_device embedded in the 76 * Drop the reference count of the device embedded in the
77 * framebuffer info structure. 77 * framebuffer info structure.
78 * 78 *
79 */ 79 */
@@ -120,10 +120,10 @@ static int mode_string(char *buf, unsigned int offset,
120 m, mode->xres, mode->yres, v, mode->refresh); 120 m, mode->xres, mode->yres, v, mode->refresh);
121} 121}
122 122
123static ssize_t store_mode(struct class_device *class_device, const char * buf, 123static ssize_t store_mode(struct device *device, struct device_attribute *attr,
124 size_t count) 124 const char *buf, size_t count)
125{ 125{
126 struct fb_info *fb_info = class_get_devdata(class_device); 126 struct fb_info *fb_info = dev_get_drvdata(device);
127 char mstr[100]; 127 char mstr[100];
128 struct fb_var_screeninfo var; 128 struct fb_var_screeninfo var;
129 struct fb_modelist *modelist; 129 struct fb_modelist *modelist;
@@ -151,9 +151,10 @@ static ssize_t store_mode(struct class_device *class_device, const char * buf,
151 return -EINVAL; 151 return -EINVAL;
152} 152}
153 153
154static ssize_t show_mode(struct class_device *class_device, char *buf) 154static ssize_t show_mode(struct device *device, struct device_attribute *attr,
155 char *buf)
155{ 156{
156 struct fb_info *fb_info = class_get_devdata(class_device); 157 struct fb_info *fb_info = dev_get_drvdata(device);
157 158
158 if (!fb_info->mode) 159 if (!fb_info->mode)
159 return 0; 160 return 0;
@@ -161,10 +162,11 @@ static ssize_t show_mode(struct class_device *class_device, char *buf)
161 return mode_string(buf, 0, fb_info->mode); 162 return mode_string(buf, 0, fb_info->mode);
162} 163}
163 164
164static ssize_t store_modes(struct class_device *class_device, const char * buf, 165static ssize_t store_modes(struct device *device,
165 size_t count) 166 struct device_attribute *attr,
167 const char *buf, size_t count)
166{ 168{
167 struct fb_info *fb_info = class_get_devdata(class_device); 169 struct fb_info *fb_info = dev_get_drvdata(device);
168 LIST_HEAD(old_list); 170 LIST_HEAD(old_list);
169 int i = count / sizeof(struct fb_videomode); 171 int i = count / sizeof(struct fb_videomode);
170 172
@@ -186,9 +188,10 @@ static ssize_t store_modes(struct class_device *class_device, const char * buf,
186 return 0; 188 return 0;
187} 189}
188 190
189static ssize_t show_modes(struct class_device *class_device, char *buf) 191static ssize_t show_modes(struct device *device, struct device_attribute *attr,
192 char *buf)
190{ 193{
191 struct fb_info *fb_info = class_get_devdata(class_device); 194 struct fb_info *fb_info = dev_get_drvdata(device);
192 unsigned int i; 195 unsigned int i;
193 struct list_head *pos; 196 struct list_head *pos;
194 struct fb_modelist *modelist; 197 struct fb_modelist *modelist;
@@ -203,10 +206,10 @@ static ssize_t show_modes(struct class_device *class_device, char *buf)
203 return i; 206 return i;
204} 207}
205 208
206static ssize_t store_bpp(struct class_device *class_device, const char * buf, 209static ssize_t store_bpp(struct device *device, struct device_attribute *attr,
207 size_t count) 210 const char *buf, size_t count)
208{ 211{
209 struct fb_info *fb_info = class_get_devdata(class_device); 212 struct fb_info *fb_info = dev_get_drvdata(device);
210 struct fb_var_screeninfo var; 213 struct fb_var_screeninfo var;
211 char ** last = NULL; 214 char ** last = NULL;
212 int err; 215 int err;
@@ -218,16 +221,18 @@ static ssize_t store_bpp(struct class_device *class_device, const char * buf,
218 return count; 221 return count;
219} 222}
220 223
221static ssize_t show_bpp(struct class_device *class_device, char *buf) 224static ssize_t show_bpp(struct device *device, struct device_attribute *attr,
225 char *buf)
222{ 226{
223 struct fb_info *fb_info = class_get_devdata(class_device); 227 struct fb_info *fb_info = dev_get_drvdata(device);
224 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); 228 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel);
225} 229}
226 230
227static ssize_t store_rotate(struct class_device *class_device, const char *buf, 231static ssize_t store_rotate(struct device *device,
228 size_t count) 232 struct device_attribute *attr,
233 const char *buf, size_t count)
229{ 234{
230 struct fb_info *fb_info = class_get_devdata(class_device); 235 struct fb_info *fb_info = dev_get_drvdata(device);
231 struct fb_var_screeninfo var; 236 struct fb_var_screeninfo var;
232 char **last = NULL; 237 char **last = NULL;
233 int err; 238 int err;
@@ -242,17 +247,19 @@ static ssize_t store_rotate(struct class_device *class_device, const char *buf,
242} 247}
243 248
244 249
245static ssize_t show_rotate(struct class_device *class_device, char *buf) 250static ssize_t show_rotate(struct device *device,
251 struct device_attribute *attr, char *buf)
246{ 252{
247 struct fb_info *fb_info = class_get_devdata(class_device); 253 struct fb_info *fb_info = dev_get_drvdata(device);
248 254
249 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate); 255 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate);
250} 256}
251 257
252static ssize_t store_virtual(struct class_device *class_device, 258static ssize_t store_virtual(struct device *device,
253 const char * buf, size_t count) 259 struct device_attribute *attr,
260 const char *buf, size_t count)
254{ 261{
255 struct fb_info *fb_info = class_get_devdata(class_device); 262 struct fb_info *fb_info = dev_get_drvdata(device);
256 struct fb_var_screeninfo var; 263 struct fb_var_screeninfo var;
257 char *last = NULL; 264 char *last = NULL;
258 int err; 265 int err;
@@ -269,23 +276,26 @@ static ssize_t store_virtual(struct class_device *class_device,
269 return count; 276 return count;
270} 277}
271 278
272static ssize_t show_virtual(struct class_device *class_device, char *buf) 279static ssize_t show_virtual(struct device *device,
280 struct device_attribute *attr, char *buf)
273{ 281{
274 struct fb_info *fb_info = class_get_devdata(class_device); 282 struct fb_info *fb_info = dev_get_drvdata(device);
275 return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual, 283 return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual,
276 fb_info->var.yres_virtual); 284 fb_info->var.yres_virtual);
277} 285}
278 286
279static ssize_t show_stride(struct class_device *class_device, char *buf) 287static ssize_t show_stride(struct device *device,
288 struct device_attribute *attr, char *buf)
280{ 289{
281 struct fb_info *fb_info = class_get_devdata(class_device); 290 struct fb_info *fb_info = dev_get_drvdata(device);
282 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length); 291 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length);
283} 292}
284 293
285static ssize_t store_blank(struct class_device *class_device, const char * buf, 294static ssize_t store_blank(struct device *device,
286 size_t count) 295 struct device_attribute *attr,
296 const char *buf, size_t count)
287{ 297{
288 struct fb_info *fb_info = class_get_devdata(class_device); 298 struct fb_info *fb_info = dev_get_drvdata(device);
289 char *last = NULL; 299 char *last = NULL;
290 int err; 300 int err;
291 301
@@ -299,42 +309,48 @@ static ssize_t store_blank(struct class_device *class_device, const char * buf,
299 return count; 309 return count;
300} 310}
301 311
302static ssize_t show_blank(struct class_device *class_device, char *buf) 312static ssize_t show_blank(struct device *device,
313 struct device_attribute *attr, char *buf)
303{ 314{
304// struct fb_info *fb_info = class_get_devdata(class_device); 315// struct fb_info *fb_info = dev_get_drvdata(device);
305 return 0; 316 return 0;
306} 317}
307 318
308static ssize_t store_console(struct class_device *class_device, 319static ssize_t store_console(struct device *device,
309 const char * buf, size_t count) 320 struct device_attribute *attr,
321 const char *buf, size_t count)
310{ 322{
311// struct fb_info *fb_info = class_get_devdata(class_device); 323// struct fb_info *fb_info = dev_get_drvdata(device);
312 return 0; 324 return 0;
313} 325}
314 326
315static ssize_t show_console(struct class_device *class_device, char *buf) 327static ssize_t show_console(struct device *device,
328 struct device_attribute *attr, char *buf)
316{ 329{
317// struct fb_info *fb_info = class_get_devdata(class_device); 330// struct fb_info *fb_info = dev_get_drvdata(device);
318 return 0; 331 return 0;
319} 332}
320 333
321static ssize_t store_cursor(struct class_device *class_device, 334static ssize_t store_cursor(struct device *device,
322 const char * buf, size_t count) 335 struct device_attribute *attr,
336 const char *buf, size_t count)
323{ 337{
324// struct fb_info *fb_info = class_get_devdata(class_device); 338// struct fb_info *fb_info = dev_get_drvdata(device);
325 return 0; 339 return 0;
326} 340}
327 341
328static ssize_t show_cursor(struct class_device *class_device, char *buf) 342static ssize_t show_cursor(struct device *device,
343 struct device_attribute *attr, char *buf)
329{ 344{
330// struct fb_info *fb_info = class_get_devdata(class_device); 345// struct fb_info *fb_info = dev_get_drvdata(device);
331 return 0; 346 return 0;
332} 347}
333 348
334static ssize_t store_pan(struct class_device *class_device, const char * buf, 349static ssize_t store_pan(struct device *device,
335 size_t count) 350 struct device_attribute *attr,
351 const char *buf, size_t count)
336{ 352{
337 struct fb_info *fb_info = class_get_devdata(class_device); 353 struct fb_info *fb_info = dev_get_drvdata(device);
338 struct fb_var_screeninfo var; 354 struct fb_var_screeninfo var;
339 char *last = NULL; 355 char *last = NULL;
340 int err; 356 int err;
@@ -355,24 +371,27 @@ static ssize_t store_pan(struct class_device *class_device, const char * buf,
355 return count; 371 return count;
356} 372}
357 373
358static ssize_t show_pan(struct class_device *class_device, char *buf) 374static ssize_t show_pan(struct device *device,
375 struct device_attribute *attr, char *buf)
359{ 376{
360 struct fb_info *fb_info = class_get_devdata(class_device); 377 struct fb_info *fb_info = dev_get_drvdata(device);
361 return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, 378 return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset,
362 fb_info->var.xoffset); 379 fb_info->var.xoffset);
363} 380}
364 381
365static ssize_t show_name(struct class_device *class_device, char *buf) 382static ssize_t show_name(struct device *device,
383 struct device_attribute *attr, char *buf)
366{ 384{
367 struct fb_info *fb_info = class_get_devdata(class_device); 385 struct fb_info *fb_info = dev_get_drvdata(device);
368 386
369 return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id); 387 return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id);
370} 388}
371 389
372static ssize_t store_fbstate(struct class_device *class_device, 390static ssize_t store_fbstate(struct device *device,
373 const char *buf, size_t count) 391 struct device_attribute *attr,
392 const char *buf, size_t count)
374{ 393{
375 struct fb_info *fb_info = class_get_devdata(class_device); 394 struct fb_info *fb_info = dev_get_drvdata(device);
376 u32 state; 395 u32 state;
377 char *last = NULL; 396 char *last = NULL;
378 397
@@ -385,17 +404,19 @@ static ssize_t store_fbstate(struct class_device *class_device,
385 return count; 404 return count;
386} 405}
387 406
388static ssize_t show_fbstate(struct class_device *class_device, char *buf) 407static ssize_t show_fbstate(struct device *device,
408 struct device_attribute *attr, char *buf)
389{ 409{
390 struct fb_info *fb_info = class_get_devdata(class_device); 410 struct fb_info *fb_info = dev_get_drvdata(device);
391 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state); 411 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state);
392} 412}
393 413
394#ifdef CONFIG_FB_BACKLIGHT 414#ifdef CONFIG_FB_BACKLIGHT
395static ssize_t store_bl_curve(struct class_device *class_device, 415static ssize_t store_bl_curve(struct device *device,
396 const char *buf, size_t count) 416 struct device_attribute *attr,
417 const char *buf, size_t count)
397{ 418{
398 struct fb_info *fb_info = class_get_devdata(class_device); 419 struct fb_info *fb_info = dev_get_drvdata(device);
399 u8 tmp_curve[FB_BACKLIGHT_LEVELS]; 420 u8 tmp_curve[FB_BACKLIGHT_LEVELS];
400 unsigned int i; 421 unsigned int i;
401 422
@@ -432,9 +453,10 @@ static ssize_t store_bl_curve(struct class_device *class_device,
432 return count; 453 return count;
433} 454}
434 455
435static ssize_t show_bl_curve(struct class_device *class_device, char *buf) 456static ssize_t show_bl_curve(struct device *device,
457 struct device_attribute *attr, char *buf)
436{ 458{
437 struct fb_info *fb_info = class_get_devdata(class_device); 459 struct fb_info *fb_info = dev_get_drvdata(device);
438 ssize_t len = 0; 460 ssize_t len = 0;
439 unsigned int i; 461 unsigned int i;
440 462
@@ -465,7 +487,7 @@ static ssize_t show_bl_curve(struct class_device *class_device, char *buf)
465/* When cmap is added back in it should be a binary attribute 487/* When cmap is added back in it should be a binary attribute
466 * not a text one. Consideration should also be given to converting 488 * not a text one. Consideration should also be given to converting
467 * fbdev to use configfs instead of sysfs */ 489 * fbdev to use configfs instead of sysfs */
468static struct class_device_attribute class_device_attrs[] = { 490static struct device_attribute device_attrs[] = {
469 __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), 491 __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
470 __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), 492 __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
471 __ATTR(console, S_IRUGO|S_IWUSR, show_console, store_console), 493 __ATTR(console, S_IRUGO|S_IWUSR, show_console, store_console),
@@ -483,17 +505,16 @@ static struct class_device_attribute class_device_attrs[] = {
483#endif 505#endif
484}; 506};
485 507
486int fb_init_class_device(struct fb_info *fb_info) 508int fb_init_device(struct fb_info *fb_info)
487{ 509{
488 int i, error = 0; 510 int i, error = 0;
489 511
490 class_set_devdata(fb_info->class_device, fb_info); 512 dev_set_drvdata(fb_info->dev, fb_info);
491 513
492 fb_info->class_flag |= FB_SYSFS_FLAG_ATTR; 514 fb_info->class_flag |= FB_SYSFS_FLAG_ATTR;
493 515
494 for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { 516 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
495 error = class_device_create_file(fb_info->class_device, 517 error = device_create_file(fb_info->dev, &device_attrs[i]);
496 &class_device_attrs[i]);
497 518
498 if (error) 519 if (error)
499 break; 520 break;
@@ -501,22 +522,20 @@ int fb_init_class_device(struct fb_info *fb_info)
501 522
502 if (error) { 523 if (error) {
503 while (--i >= 0) 524 while (--i >= 0)
504 class_device_remove_file(fb_info->class_device, 525 device_remove_file(fb_info->dev, &device_attrs[i]);
505 &class_device_attrs[i]);
506 fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; 526 fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR;
507 } 527 }
508 528
509 return 0; 529 return 0;
510} 530}
511 531
512void fb_cleanup_class_device(struct fb_info *fb_info) 532void fb_cleanup_device(struct fb_info *fb_info)
513{ 533{
514 unsigned int i; 534 unsigned int i;
515 535
516 if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) { 536 if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) {
517 for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) 537 for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
518 class_device_remove_file(fb_info->class_device, 538 device_remove_file(fb_info->dev, &device_attrs[i]);
519 &class_device_attrs[i]);
520 539
521 fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; 540 fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR;
522 } 541 }
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 2a0e8210d398..949141bd44d4 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -968,6 +968,8 @@ static int ffb_init_one(struct of_device *op)
968 968
969 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { 969 if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
970 printk(KERN_ERR "ffb: Could not allocate color map.\n"); 970 printk(KERN_ERR "ffb: Could not allocate color map.\n");
971 of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
972 of_iounmap(all->par.dac, sizeof(struct ffb_dac));
971 kfree(all); 973 kfree(all);
972 return -ENOMEM; 974 return -ENOMEM;
973 } 975 }
@@ -978,6 +980,8 @@ static int ffb_init_one(struct of_device *op)
978 if (err < 0) { 980 if (err < 0) {
979 printk(KERN_ERR "ffb: Could not register framebuffer.\n"); 981 printk(KERN_ERR "ffb: Could not register framebuffer.\n");
980 fb_dealloc_cmap(&all->info.cmap); 982 fb_dealloc_cmap(&all->info.cmap);
983 of_iounmap(all->par.fbc, sizeof(struct ffb_fbc));
984 of_iounmap(all->par.dac, sizeof(struct ffb_dac));
981 kfree(all); 985 kfree(all);
982 return err; 986 return err;
983 } 987 }
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
index 998374cfae6d..70ff55b14596 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fm2fb.c
@@ -283,6 +283,7 @@ static int __devinit fm2fb_probe(struct zorro_dev *z,
283 283
284 if (register_framebuffer(info) < 0) { 284 if (register_framebuffer(info) < 0) {
285 fb_dealloc_cmap(&info->cmap); 285 fb_dealloc_cmap(&info->cmap);
286 iounmap(info->screen_base);
286 framebuffer_release(info); 287 framebuffer_release(info);
287 zorro_release_device(z); 288 zorro_release_device(z);
288 return -EINVAL; 289 return -EINVAL;
diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig
index 4e173ef20a7d..a814b6c2605c 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/geode/Kconfig
@@ -23,6 +23,26 @@ config FB_GEODE_GX
23 23
24 If unsure, say N. 24 If unsure, say N.
25 25
26config FB_GEODE_GX_SET_FBSIZE
27 bool "Manually specify the Geode GX framebuffer size"
28 depends on FB_GEODE_GX
29 default n
30 ---help---
31 If you want to manually specify the size of your GX framebuffer,
32 say Y here, otherwise say N to dynamically probe it.
33
34 Say N unless you know what you are doing.
35
36config FB_GEODE_GX_FBSIZE
37 hex "Size of the GX framebuffer, in bytes"
38 depends on FB_GEODE_GX_SET_FBSIZE
39 default "0x1600000"
40 ---help---
41 Specify the size of the GX framebuffer. Normally, you will
42 want this to be MB aligned. Common values are 0x80000 (8MB)
43 and 0x1600000 (16MB). Don't change this unless you know what
44 you are doing
45
26config FB_GEODE_GX1 46config FB_GEODE_GX1
27 tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)" 47 tristate "AMD Geode GX1 framebuffer support (EXPERIMENTAL)"
28 depends on FB && FB_GEODE && EXPERIMENTAL 48 depends on FB && FB_GEODE && EXPERIMENTAL
diff --git a/drivers/video/geode/display_gx.c b/drivers/video/geode/display_gx.c
index 825c3405f5c2..0f16e4bffc6c 100644
--- a/drivers/video/geode/display_gx.c
+++ b/drivers/video/geode/display_gx.c
@@ -21,11 +21,27 @@
21#include "geodefb.h" 21#include "geodefb.h"
22#include "display_gx.h" 22#include "display_gx.h"
23 23
24int gx_frame_buffer_size(void) 24#ifdef CONFIG_FB_GEODE_GX_SET_FBSIZE
25unsigned int gx_frame_buffer_size(void)
25{ 26{
26 /* Assuming 16 MiB. */ 27 return CONFIG_FB_GEODE_GX_FBSIZE;
27 return 16*1024*1024;
28} 28}
29#else
30unsigned int gx_frame_buffer_size(void)
31{
32 unsigned int val;
33
34 /* FB size is reported by a virtual register */
35 /* Virtual register class = 0x02 */
36 /* VG_MEM_SIZE(512Kb units) = 0x00 */
37
38 outw(0xFC53, 0xAC1C);
39 outw(0x0200, 0xAC1C);
40
41 val = (unsigned int)(inw(0xAC1E)) & 0xFFl;
42 return (val << 19);
43}
44#endif
29 45
30int gx_line_delta(int xres, int bpp) 46int gx_line_delta(int xres, int bpp)
31{ 47{
@@ -81,6 +97,7 @@ static void gx_set_mode(struct fb_info *info)
81 writel(((info->var.xres * info->var.bits_per_pixel/8) >> 3) + 2, 97 writel(((info->var.xres * info->var.bits_per_pixel/8) >> 3) + 2,
82 par->dc_regs + DC_LINE_SIZE); 98 par->dc_regs + DC_LINE_SIZE);
83 99
100
84 /* Enable graphics and video data and unmask address lines. */ 101 /* Enable graphics and video data and unmask address lines. */
85 dcfg |= DC_DCFG_GDEN | DC_DCFG_VDEN | DC_DCFG_A20M | DC_DCFG_A18M; 102 dcfg |= DC_DCFG_GDEN | DC_DCFG_VDEN | DC_DCFG_A20M | DC_DCFG_A18M;
86 103
diff --git a/drivers/video/geode/display_gx.h b/drivers/video/geode/display_gx.h
index 86c623361305..0af33f329e88 100644
--- a/drivers/video/geode/display_gx.h
+++ b/drivers/video/geode/display_gx.h
@@ -11,11 +11,15 @@
11#ifndef __DISPLAY_GX_H__ 11#ifndef __DISPLAY_GX_H__
12#define __DISPLAY_GX_H__ 12#define __DISPLAY_GX_H__
13 13
14int gx_frame_buffer_size(void); 14unsigned int gx_frame_buffer_size(void);
15int gx_line_delta(int xres, int bpp); 15int gx_line_delta(int xres, int bpp);
16 16
17extern struct geode_dc_ops gx_dc_ops; 17extern struct geode_dc_ops gx_dc_ops;
18 18
19/* MSR that tells us if a TFT or CRT is attached */
20#define GLD_MSR_CONFIG 0xC0002001
21#define GLD_MSR_CONFIG_DM_FP 0x40
22
19/* Display controller registers */ 23/* Display controller registers */
20 24
21#define DC_UNLOCK 0x00 25#define DC_UNLOCK 0x00
@@ -93,4 +97,5 @@ extern struct geode_dc_ops gx_dc_ops;
93#define DC_PAL_ADDRESS 0x70 97#define DC_PAL_ADDRESS 0x70
94#define DC_PAL_DATA 0x74 98#define DC_PAL_DATA 0x74
95 99
100#define DC_GLIU0_MEM_OFFSET 0x84
96#endif /* !__DISPLAY_GX1_H__ */ 101#endif /* !__DISPLAY_GX1_H__ */
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c
index 0d3643fc6293..cf841efa229a 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/geode/gxfb_core.c
@@ -35,10 +35,10 @@
35#include "display_gx.h" 35#include "display_gx.h"
36#include "video_gx.h" 36#include "video_gx.h"
37 37
38static char mode_option[32] = "640x480-16@60"; 38static char *mode_option;
39 39
40/* Modes relevant to the GX (taken from modedb.c) */ 40/* Modes relevant to the GX (taken from modedb.c) */
41static const struct fb_videomode __initdata gx_modedb[] = { 41static const struct fb_videomode gx_modedb[] __initdata = {
42 /* 640x480-60 VESA */ 42 /* 640x480-60 VESA */
43 { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, 43 { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
44 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 44 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
@@ -240,6 +240,12 @@ static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *de
240 if (!info->screen_base) 240 if (!info->screen_base)
241 return -ENOMEM; 241 return -ENOMEM;
242 242
243 /* Set the 16MB aligned base address of the graphics memory region
244 * in the display controller */
245
246 writel(info->fix.smem_start & 0xFF000000,
247 par->dc_regs + DC_GLIU0_MEM_OFFSET);
248
243 dev_info(&dev->dev, "%d Kibyte of video memory at 0x%lx\n", 249 dev_info(&dev->dev, "%d Kibyte of video memory at 0x%lx\n",
244 info->fix.smem_len / 1024, info->fix.smem_start); 250 info->fix.smem_len / 1024, info->fix.smem_start);
245 251
@@ -302,6 +308,7 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
302 struct geodefb_par *par; 308 struct geodefb_par *par;
303 struct fb_info *info; 309 struct fb_info *info;
304 int ret; 310 int ret;
311 unsigned long val;
305 312
306 info = gxfb_init_fbinfo(&pdev->dev); 313 info = gxfb_init_fbinfo(&pdev->dev);
307 if (!info) 314 if (!info)
@@ -317,6 +324,15 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
317 goto err; 324 goto err;
318 } 325 }
319 326
327 /* Figure out if this is a TFT or CRT part */
328
329 rdmsrl(GLD_MSR_CONFIG, val);
330
331 if ((val & GLD_MSR_CONFIG_DM_FP) == GLD_MSR_CONFIG_DM_FP)
332 par->enable_crt = 0;
333 else
334 par->enable_crt = 1;
335
320 ret = fb_find_mode(&info->var, info, mode_option, 336 ret = fb_find_mode(&info->var, info, mode_option,
321 gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16); 337 gx_modedb, ARRAY_SIZE(gx_modedb), NULL, 16);
322 if (ret == 0 || ret == 4) { 338 if (ret == 0 || ret == 4) {
@@ -325,7 +341,8 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i
325 goto err; 341 goto err;
326 } 342 }
327 343
328 /* Clear the frame buffer of garbage. */ 344
345 /* Clear the frame buffer of garbage. */
329 memset_io(info->screen_base, 0, info->fix.smem_len); 346 memset_io(info->screen_base, 0, info->fix.smem_len);
330 347
331 gxfb_check_var(&info->var, info); 348 gxfb_check_var(&info->var, info);
@@ -380,7 +397,7 @@ static void gxfb_remove(struct pci_dev *pdev)
380} 397}
381 398
382static struct pci_device_id gxfb_id_table[] = { 399static struct pci_device_id gxfb_id_table[] = {
383 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_VIDEO, 400 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_GX_VIDEO,
384 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, 401 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
385 0xff0000, 0 }, 402 0xff0000, 0 },
386 { 0, } 403 { 0, }
@@ -395,11 +412,35 @@ static struct pci_driver gxfb_driver = {
395 .remove = gxfb_remove, 412 .remove = gxfb_remove,
396}; 413};
397 414
415#ifndef MODULE
416static int __init gxfb_setup(char *options)
417{
418
419 char *opt;
420
421 if (!options || !*options)
422 return 0;
423
424 while ((opt = strsep(&options, ",")) != NULL) {
425 if (!*opt)
426 continue;
427
428 mode_option = opt;
429 }
430
431 return 0;
432}
433#endif
434
398static int __init gxfb_init(void) 435static int __init gxfb_init(void)
399{ 436{
400#ifndef MODULE 437#ifndef MODULE
401 if (fb_get_options("gxfb", NULL)) 438 char *option = NULL;
439
440 if (fb_get_options("gxfb", &option))
402 return -ENODEV; 441 return -ENODEV;
442
443 gxfb_setup(option);
403#endif 444#endif
404 return pci_register_driver(&gxfb_driver); 445 return pci_register_driver(&gxfb_driver);
405} 446}
@@ -412,8 +453,8 @@ static void __exit gxfb_cleanup(void)
412module_init(gxfb_init); 453module_init(gxfb_init);
413module_exit(gxfb_cleanup); 454module_exit(gxfb_cleanup);
414 455
415module_param_string(mode, mode_option, sizeof(mode_option), 0444); 456module_param(mode_option, charp, 0);
416MODULE_PARM_DESC(mode, "video mode (<x>x<y>[-<bpp>][@<refr>])"); 457MODULE_PARM_DESC(mode_option, "video mode (<x>x<y>[-<bpp>][@<refr>])");
417 458
418MODULE_DESCRIPTION("Framebuffer driver for the AMD Geode GX"); 459MODULE_DESCRIPTION("Framebuffer driver for the AMD Geode GX");
419MODULE_LICENSE("GPL"); 460MODULE_LICENSE("GPL");
diff --git a/drivers/video/geode/video_gx.c b/drivers/video/geode/video_gx.c
index 2b2a7880ea75..7f3f18d06718 100644
--- a/drivers/video/geode/video_gx.c
+++ b/drivers/video/geode/video_gx.c
@@ -175,13 +175,88 @@ static void gx_set_dclk_frequency(struct fb_info *info)
175 } while (timeout-- && !(dotpll & MSR_GLCP_DOTPLL_LOCK)); 175 } while (timeout-- && !(dotpll & MSR_GLCP_DOTPLL_LOCK));
176} 176}
177 177
178static void
179gx_configure_tft(struct fb_info *info)
180{
181 struct geodefb_par *par = info->par;
182 unsigned long val;
183 unsigned long fp;
184
185 /* Set up the DF pad select MSR */
186
187 rdmsrl(GX_VP_MSR_PAD_SELECT, val);
188 val &= ~GX_VP_PAD_SELECT_MASK;
189 val |= GX_VP_PAD_SELECT_TFT;
190 wrmsrl(GX_VP_MSR_PAD_SELECT, val);
191
192 /* Turn off the panel */
193
194 fp = readl(par->vid_regs + GX_FP_PM);
195 fp &= ~GX_FP_PM_P;
196 writel(fp, par->vid_regs + GX_FP_PM);
197
198 /* Set timing 1 */
199
200 fp = readl(par->vid_regs + GX_FP_PT1);
201 fp &= GX_FP_PT1_VSIZE_MASK;
202 fp |= info->var.yres << GX_FP_PT1_VSIZE_SHIFT;
203 writel(fp, par->vid_regs + GX_FP_PT1);
204
205 /* Timing 2 */
206 /* Set bits that are always on for TFT */
207
208 fp = 0x0F100000;
209
210 /* Add sync polarity */
211
212 if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
213 fp |= GX_FP_PT2_VSP;
214
215 if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
216 fp |= GX_FP_PT2_HSP;
217
218 writel(fp, par->vid_regs + GX_FP_PT2);
219
220 /* Set the dither control */
221 writel(0x70, par->vid_regs + GX_FP_DFC);
222
223 /* Enable the FP data and power (in case the BIOS didn't) */
224
225 fp = readl(par->vid_regs + GX_DCFG);
226 fp |= GX_DCFG_FP_PWR_EN | GX_DCFG_FP_DATA_EN;
227 writel(fp, par->vid_regs + GX_DCFG);
228
229 /* Unblank the panel */
230
231 fp = readl(par->vid_regs + GX_FP_PM);
232 fp |= GX_FP_PM_P;
233 writel(fp, par->vid_regs + GX_FP_PM);
234}
235
178static void gx_configure_display(struct fb_info *info) 236static void gx_configure_display(struct fb_info *info)
179{ 237{
180 struct geodefb_par *par = info->par; 238 struct geodefb_par *par = info->par;
181 u32 dcfg, fp_pm; 239 u32 dcfg, misc;
240
241 /* Set up the MISC register */
242
243 misc = readl(par->vid_regs + GX_MISC);
244
245 /* Power up the DAC */
246 misc &= ~(GX_MISC_A_PWRDN | GX_MISC_DAC_PWRDN);
247
248 /* Disable gamma correction */
249 misc |= GX_MISC_GAM_EN;
250
251 writel(misc, par->vid_regs + GX_MISC);
182 252
253 /* Write the display configuration */
183 dcfg = readl(par->vid_regs + GX_DCFG); 254 dcfg = readl(par->vid_regs + GX_DCFG);
184 255
256 /* Disable hsync and vsync */
257 dcfg &= ~(GX_DCFG_VSYNC_EN | GX_DCFG_HSYNC_EN);
258 writel(dcfg, par->vid_regs + GX_DCFG);
259
185 /* Clear bits from existing mode. */ 260 /* Clear bits from existing mode. */
186 dcfg &= ~(GX_DCFG_CRT_SYNC_SKW_MASK 261 dcfg &= ~(GX_DCFG_CRT_SYNC_SKW_MASK
187 | GX_DCFG_CRT_HSYNC_POL | GX_DCFG_CRT_VSYNC_POL 262 | GX_DCFG_CRT_HSYNC_POL | GX_DCFG_CRT_VSYNC_POL
@@ -199,12 +274,19 @@ static void gx_configure_display(struct fb_info *info)
199 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) 274 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
200 dcfg |= GX_DCFG_CRT_VSYNC_POL; 275 dcfg |= GX_DCFG_CRT_VSYNC_POL;
201 276
277 /* Enable the display logic */
278 /* Set up the DACS to blank normally */
279
280 dcfg |= GX_DCFG_CRT_EN | GX_DCFG_DAC_BL_EN;
281
282 /* Enable the external DAC VREF? */
283
202 writel(dcfg, par->vid_regs + GX_DCFG); 284 writel(dcfg, par->vid_regs + GX_DCFG);
203 285
204 /* Power on flat panel. */ 286 /* Set up the flat panel (if it is enabled) */
205 fp_pm = readl(par->vid_regs + GX_FP_PM); 287
206 fp_pm |= GX_FP_PM_P; 288 if (par->enable_crt == 0)
207 writel(fp_pm, par->vid_regs + GX_FP_PM); 289 gx_configure_tft(info);
208} 290}
209 291
210static int gx_blank_display(struct fb_info *info, int blank_mode) 292static int gx_blank_display(struct fb_info *info, int blank_mode)
@@ -245,12 +327,15 @@ static int gx_blank_display(struct fb_info *info, int blank_mode)
245 writel(dcfg, par->vid_regs + GX_DCFG); 327 writel(dcfg, par->vid_regs + GX_DCFG);
246 328
247 /* Power on/off flat panel. */ 329 /* Power on/off flat panel. */
248 fp_pm = readl(par->vid_regs + GX_FP_PM); 330
249 if (blank_mode == FB_BLANK_POWERDOWN) 331 if (par->enable_crt == 0) {
250 fp_pm &= ~GX_FP_PM_P; 332 fp_pm = readl(par->vid_regs + GX_FP_PM);
251 else 333 if (blank_mode == FB_BLANK_POWERDOWN)
252 fp_pm |= GX_FP_PM_P; 334 fp_pm &= ~GX_FP_PM_P;
253 writel(fp_pm, par->vid_regs + GX_FP_PM); 335 else
336 fp_pm |= GX_FP_PM_P;
337 writel(fp_pm, par->vid_regs + GX_FP_PM);
338 }
254 339
255 return 0; 340 return 0;
256} 341}
diff --git a/drivers/video/geode/video_gx.h b/drivers/video/geode/video_gx.h
index 2d9211f3ed84..ce28d8f382dc 100644
--- a/drivers/video/geode/video_gx.h
+++ b/drivers/video/geode/video_gx.h
@@ -13,6 +13,11 @@
13 13
14extern struct geode_vid_ops gx_vid_ops; 14extern struct geode_vid_ops gx_vid_ops;
15 15
16/* GX Flatpanel control MSR */
17#define GX_VP_MSR_PAD_SELECT 0xC0002011
18#define GX_VP_PAD_SELECT_MASK 0x3FFFFFFF
19#define GX_VP_PAD_SELECT_TFT 0x1FFFFFFF
20
16/* Geode GX video processor registers */ 21/* Geode GX video processor registers */
17 22
18#define GX_DCFG 0x0008 23#define GX_DCFG 0x0008
@@ -20,6 +25,8 @@ extern struct geode_vid_ops gx_vid_ops;
20# define GX_DCFG_HSYNC_EN 0x00000002 25# define GX_DCFG_HSYNC_EN 0x00000002
21# define GX_DCFG_VSYNC_EN 0x00000004 26# define GX_DCFG_VSYNC_EN 0x00000004
22# define GX_DCFG_DAC_BL_EN 0x00000008 27# define GX_DCFG_DAC_BL_EN 0x00000008
28# define GX_DCFG_FP_PWR_EN 0x00000040
29# define GX_DCFG_FP_DATA_EN 0x00000080
23# define GX_DCFG_CRT_HSYNC_POL 0x00000100 30# define GX_DCFG_CRT_HSYNC_POL 0x00000100
24# define GX_DCFG_CRT_VSYNC_POL 0x00000200 31# define GX_DCFG_CRT_VSYNC_POL 0x00000200
25# define GX_DCFG_CRT_SYNC_SKW_MASK 0x0001C000 32# define GX_DCFG_CRT_SYNC_SKW_MASK 0x0001C000
@@ -28,10 +35,28 @@ extern struct geode_vid_ops gx_vid_ops;
28# define GX_DCFG_GV_GAM 0x00200000 35# define GX_DCFG_GV_GAM 0x00200000
29# define GX_DCFG_DAC_VREF 0x04000000 36# define GX_DCFG_DAC_VREF 0x04000000
30 37
38/* Geode GX MISC video configuration */
39
40#define GX_MISC 0x50
41#define GX_MISC_GAM_EN 0x00000001
42#define GX_MISC_DAC_PWRDN 0x00000400
43#define GX_MISC_A_PWRDN 0x00000800
44
31/* Geode GX flat panel display control registers */ 45/* Geode GX flat panel display control registers */
46
47#define GX_FP_PT1 0x0400
48#define GX_FP_PT1_VSIZE_MASK 0x7FF0000
49#define GX_FP_PT1_VSIZE_SHIFT 16
50
51#define GX_FP_PT2 0x408
52#define GX_FP_PT2_VSP (1 << 23)
53#define GX_FP_PT2_HSP (1 << 22)
54
32#define GX_FP_PM 0x410 55#define GX_FP_PM 0x410
33# define GX_FP_PM_P 0x01000000 56# define GX_FP_PM_P 0x01000000
34 57
58#define GX_FP_DFC 0x418
59
35/* Geode GX clock control MSRs */ 60/* Geode GX clock control MSRs */
36 61
37#define MSR_GLCP_SYS_RSTPLL 0x4c000014 62#define MSR_GLCP_SYS_RSTPLL 0x4c000014
diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c
new file mode 100644
index 000000000000..3adf6ab0768f
--- /dev/null
+++ b/drivers/video/gxt4500.c
@@ -0,0 +1,741 @@
1/*
2 * Frame buffer device for IBM GXT4500P display adaptor
3 *
4 * Copyright (C) 2006 Paul Mackerras, IBM Corp. <paulus@samba.org>
5 */
6
7#include <linux/kernel.h>
8#include <linux/module.h>
9#include <linux/fb.h>
10#include <linux/console.h>
11#include <linux/pci.h>
12#include <linux/pci_ids.h>
13#include <linux/delay.h>
14
15#define PCI_DEVICE_ID_IBM_GXT4500P 0x21c
16
17/* GXT4500P registers */
18
19/* Registers in PCI config space */
20#define CFG_ENDIAN0 0x40
21
22/* Misc control/status registers */
23#define STATUS 0x1000
24#define CTRL_REG0 0x1004
25#define CR0_HALT_DMA 0x4
26#define CR0_RASTER_RESET 0x8
27#define CR0_GEOM_RESET 0x10
28#define CR0_MEM_CTRLER_RESET 0x20
29
30/* Framebuffer control registers */
31#define FB_AB_CTRL 0x1100
32#define FB_CD_CTRL 0x1104
33#define FB_WID_CTRL 0x1108
34#define FB_Z_CTRL 0x110c
35#define FB_VGA_CTRL 0x1110
36#define REFRESH_AB_CTRL 0x1114
37#define REFRESH_CD_CTRL 0x1118
38#define FB_OVL_CTRL 0x111c
39#define FB_CTRL_TYPE 0x80000000
40#define FB_CTRL_WIDTH_MASK 0x007f0000
41#define FB_CTRL_WIDTH_SHIFT 16
42#define FB_CTRL_START_SEG_MASK 0x00003fff
43
44#define REFRESH_START 0x1098
45#define REFRESH_SIZE 0x109c
46
47/* "Direct" framebuffer access registers */
48#define DFA_FB_A 0x11e0
49#define DFA_FB_B 0x11e4
50#define DFA_FB_C 0x11e8
51#define DFA_FB_D 0x11ec
52#define DFA_FB_ENABLE 0x80000000
53#define DFA_FB_BASE_MASK 0x03f00000
54#define DFA_FB_STRIDE_1k 0x00000000
55#define DFA_FB_STRIDE_2k 0x00000010
56#define DFA_FB_STRIDE_4k 0x00000020
57#define DFA_PIX_8BIT 0x00000000
58#define DFA_PIX_16BIT_565 0x00000001
59#define DFA_PIX_16BIT_1555 0x00000002
60#define DFA_PIX_24BIT 0x00000004
61#define DFA_PIX_32BIT 0x00000005
62
63/* maps DFA_PIX_* to pixel size in bytes */
64static const unsigned char pixsize[] = {
65 1, 2, 2, 2, 4, 4
66};
67
68/* Display timing generator registers */
69#define DTG_CONTROL 0x1900
70#define DTG_CTL_SCREEN_REFRESH 2
71#define DTG_CTL_ENABLE 1
72#define DTG_HORIZ_EXTENT 0x1904
73#define DTG_HORIZ_DISPLAY 0x1908
74#define DTG_HSYNC_START 0x190c
75#define DTG_HSYNC_END 0x1910
76#define DTG_HSYNC_END_COMP 0x1914
77#define DTG_VERT_EXTENT 0x1918
78#define DTG_VERT_DISPLAY 0x191c
79#define DTG_VSYNC_START 0x1920
80#define DTG_VSYNC_END 0x1924
81#define DTG_VERT_SHORT 0x1928
82
83/* PLL/RAMDAC registers */
84#define DISP_CTL 0x402c
85#define DISP_CTL_OFF 2
86#define SYNC_CTL 0x4034
87#define SYNC_CTL_SYNC_ON_RGB 1
88#define SYNC_CTL_SYNC_OFF 2
89#define SYNC_CTL_HSYNC_INV 8
90#define SYNC_CTL_VSYNC_INV 0x10
91#define SYNC_CTL_HSYNC_OFF 0x20
92#define SYNC_CTL_VSYNC_OFF 0x40
93
94#define PLL_M 0x4040
95#define PLL_N 0x4044
96#define PLL_POSTDIV 0x4048
97
98/* Hardware cursor */
99#define CURSOR_X 0x4078
100#define CURSOR_Y 0x407c
101#define CURSOR_HOTSPOT 0x4080
102#define CURSOR_MODE 0x4084
103#define CURSOR_MODE_OFF 0
104#define CURSOR_MODE_4BPP 1
105#define CURSOR_PIXMAP 0x5000
106#define CURSOR_CMAP 0x7400
107
108/* Window attribute table */
109#define WAT_FMT 0x4100
110#define WAT_FMT_24BIT 0
111#define WAT_FMT_16BIT_565 1
112#define WAT_FMT_16BIT_1555 2
113#define WAT_FMT_32BIT 3 /* 0 vs. 3 is a guess */
114#define WAT_FMT_8BIT_332 9
115#define WAT_FMT_8BIT 0xa
116#define WAT_FMT_NO_CMAP 4 /* ORd in to other values */
117#define WAT_CMAP_OFFSET 0x4104 /* 4-bit value gets << 6 */
118#define WAT_CTRL 0x4108
119#define WAT_CTRL_SEL_B 1 /* select B buffer if 1 */
120#define WAT_CTRL_NO_INC 2
121#define WAT_GAMMA_CTRL 0x410c
122#define WAT_GAMMA_DISABLE 1 /* disables gamma cmap */
123#define WAT_OVL_CTRL 0x430c /* controls overlay */
124
125/* Indexed by DFA_PIX_* values */
126static const unsigned char watfmt[] = {
127 WAT_FMT_8BIT, WAT_FMT_16BIT_565, WAT_FMT_16BIT_1555, 0,
128 WAT_FMT_24BIT, WAT_FMT_32BIT
129};
130
131/* Colormap array; 1k entries of 4 bytes each */
132#define CMAP 0x6000
133
134#define readreg(par, reg) readl((par)->regs + (reg))
135#define writereg(par, reg, val) writel((val), (par)->regs + (reg))
136
137struct gxt4500_par {
138 void __iomem *regs;
139
140 int pixfmt; /* pixel format, see DFA_PIX_* values */
141
142 /* PLL parameters */
143 int pll_m; /* ref clock divisor */
144 int pll_n; /* VCO divisor */
145 int pll_pd1; /* first post-divisor */
146 int pll_pd2; /* second post-divisor */
147
148 u32 pseudo_palette[16]; /* used in color blits */
149};
150
151/* mode requested by user */
152static char *mode_option;
153
154/* default mode: 1280x1024 @ 60 Hz, 8 bpp */
155static const struct fb_videomode defaultmode __devinitdata = {
156 .refresh = 60,
157 .xres = 1280,
158 .yres = 1024,
159 .pixclock = 9295,
160 .left_margin = 248,
161 .right_margin = 48,
162 .upper_margin = 38,
163 .lower_margin = 1,
164 .hsync_len = 112,
165 .vsync_len = 3,
166 .vmode = FB_VMODE_NONINTERLACED
167};
168
169/*
170 * The refclk and VCO dividers appear to use a linear feedback shift
171 * register, which gets reloaded when it reaches a terminal value, at
172 * which point the divider output is toggled. Thus one can obtain
173 * whatever divisor is required by putting the appropriate value into
174 * the reload register. For a divisor of N, one puts the value from
175 * the LFSR sequence that comes N-1 places before the terminal value
176 * into the reload register.
177 */
178
179static const unsigned char mdivtab[] = {
180/* 1 */ 0x3f, 0x00, 0x20, 0x10, 0x28, 0x14, 0x2a, 0x15, 0x0a,
181/* 10 */ 0x25, 0x32, 0x19, 0x0c, 0x26, 0x13, 0x09, 0x04, 0x22, 0x11,
182/* 20 */ 0x08, 0x24, 0x12, 0x29, 0x34, 0x1a, 0x2d, 0x36, 0x1b, 0x0d,
183/* 30 */ 0x06, 0x23, 0x31, 0x38, 0x1c, 0x2e, 0x17, 0x0b, 0x05, 0x02,
184/* 40 */ 0x21, 0x30, 0x18, 0x2c, 0x16, 0x2b, 0x35, 0x3a, 0x1d, 0x0e,
185/* 50 */ 0x27, 0x33, 0x39, 0x3c, 0x1e, 0x2f, 0x37, 0x3b, 0x3d, 0x3e,
186/* 60 */ 0x1f, 0x0f, 0x07, 0x03, 0x01,
187};
188
189static const unsigned char ndivtab[] = {
190/* 2 */ 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0x78, 0xbc, 0x5e,
191/* 10 */ 0x2f, 0x17, 0x0b, 0x85, 0xc2, 0xe1, 0x70, 0x38, 0x9c, 0x4e,
192/* 20 */ 0xa7, 0xd3, 0xe9, 0xf4, 0xfa, 0xfd, 0xfe, 0x7f, 0xbf, 0xdf,
193/* 30 */ 0xef, 0x77, 0x3b, 0x1d, 0x8e, 0xc7, 0xe3, 0x71, 0xb8, 0xdc,
194/* 40 */ 0x6e, 0xb7, 0x5b, 0x2d, 0x16, 0x8b, 0xc5, 0xe2, 0xf1, 0xf8,
195/* 50 */ 0xfc, 0x7e, 0x3f, 0x9f, 0xcf, 0x67, 0xb3, 0xd9, 0x6c, 0xb6,
196/* 60 */ 0xdb, 0x6d, 0x36, 0x9b, 0x4d, 0x26, 0x13, 0x89, 0xc4, 0x62,
197/* 70 */ 0xb1, 0xd8, 0xec, 0xf6, 0xfb, 0x7d, 0xbe, 0x5f, 0xaf, 0x57,
198/* 80 */ 0x2b, 0x95, 0x4a, 0x25, 0x92, 0x49, 0xa4, 0x52, 0x29, 0x94,
199/* 90 */ 0xca, 0x65, 0xb2, 0x59, 0x2c, 0x96, 0xcb, 0xe5, 0xf2, 0x79,
200/* 100 */ 0x3c, 0x1e, 0x0f, 0x07, 0x83, 0x41, 0x20, 0x90, 0x48, 0x24,
201/* 110 */ 0x12, 0x09, 0x84, 0x42, 0xa1, 0x50, 0x28, 0x14, 0x8a, 0x45,
202/* 120 */ 0xa2, 0xd1, 0xe8, 0x74, 0xba, 0xdd, 0xee, 0xf7, 0x7b, 0x3d,
203/* 130 */ 0x9e, 0x4f, 0x27, 0x93, 0xc9, 0xe4, 0x72, 0x39, 0x1c, 0x0e,
204/* 140 */ 0x87, 0xc3, 0x61, 0x30, 0x18, 0x8c, 0xc6, 0x63, 0x31, 0x98,
205/* 150 */ 0xcc, 0xe6, 0x73, 0xb9, 0x5c, 0x2e, 0x97, 0x4b, 0xa5, 0xd2,
206/* 160 */ 0x69, 0xb4, 0xda, 0xed, 0x76, 0xbb, 0x5d, 0xae, 0xd7, 0x6b,
207/* 170 */ 0xb5, 0x5a, 0xad, 0x56, 0xab, 0xd5, 0x6a, 0x35, 0x1a, 0x8d,
208/* 180 */ 0x46, 0x23, 0x11, 0x88, 0x44, 0x22, 0x91, 0xc8, 0x64, 0x32,
209/* 190 */ 0x19, 0x0c, 0x86, 0x43, 0x21, 0x10, 0x08, 0x04, 0x02, 0x81,
210/* 200 */ 0x40, 0xa0, 0xd0, 0x68, 0x34, 0x9a, 0xcd, 0x66, 0x33, 0x99,
211/* 210 */ 0x4c, 0xa6, 0x53, 0xa9, 0xd4, 0xea, 0x75, 0x3a, 0x9d, 0xce,
212/* 220 */ 0xe7, 0xf3, 0xf9, 0x7c, 0x3e, 0x1f, 0x8f, 0x47, 0xa3, 0x51,
213/* 230 */ 0xa8, 0x54, 0xaa, 0x55, 0x2a, 0x15, 0x0a, 0x05, 0x82, 0xc1,
214/* 240 */ 0x60, 0xb0, 0x58, 0xac, 0xd6, 0xeb, 0xf5, 0x7a, 0xbd, 0xde,
215/* 250 */ 0x6f, 0x37, 0x1b, 0x0d, 0x06, 0x03, 0x01,
216};
217
218#define REF_PERIOD_PS 9259 /* period of reference clock in ps */
219
220static int calc_pll(int period_ps, struct gxt4500_par *par)
221{
222 int m, n, pdiv1, pdiv2, postdiv;
223 int pll_period, best_error, t;
224
225 /* only deal with range 1MHz - 400MHz */
226 if (period_ps < 2500 || period_ps > 1000000)
227 return -1;
228
229 best_error = 1000000;
230 for (pdiv1 = 1; pdiv1 <= 8; ++pdiv1) {
231 for (pdiv2 = 1; pdiv2 <= pdiv1; ++pdiv2) {
232 postdiv = pdiv1 * pdiv2;
233 pll_period = (period_ps + postdiv - 1) / postdiv;
234 /* keep pll in range 500..1250 MHz */
235 if (pll_period < 800 || pll_period > 2000)
236 continue;
237 for (m = 3; m <= 40; ++m) {
238 n = REF_PERIOD_PS * m * postdiv / period_ps;
239 if (n < 5 || n > 256)
240 continue;
241 t = REF_PERIOD_PS * m * postdiv / n;
242 t -= period_ps;
243 if (t >= 0 && t < best_error) {
244 par->pll_m = m;
245 par->pll_n = n;
246 par->pll_pd1 = pdiv1;
247 par->pll_pd2 = pdiv2;
248 best_error = t;
249 }
250 }
251 }
252 }
253 if (best_error == 1000000)
254 return -1;
255 return 0;
256}
257
258static int calc_pixclock(struct gxt4500_par *par)
259{
260 return REF_PERIOD_PS * par->pll_m * par->pll_pd1 * par->pll_pd2
261 / par->pll_n;
262}
263
264static int gxt4500_var_to_par(struct fb_var_screeninfo *var,
265 struct gxt4500_par *par)
266{
267 if (var->xres + var->xoffset > var->xres_virtual ||
268 var->yres + var->yoffset > var->yres_virtual ||
269 var->xres_virtual > 4096)
270 return -EINVAL;
271 if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
272 return -EINVAL;
273
274 if (calc_pll(var->pixclock, par) < 0)
275 return -EINVAL;
276
277 switch (var->bits_per_pixel) {
278 case 32:
279 if (var->transp.length)
280 par->pixfmt = DFA_PIX_32BIT;
281 else
282 par->pixfmt = DFA_PIX_24BIT;
283 break;
284 case 24:
285 par->pixfmt = DFA_PIX_24BIT;
286 break;
287 case 16:
288 if (var->green.length == 5)
289 par->pixfmt = DFA_PIX_16BIT_1555;
290 else
291 par->pixfmt = DFA_PIX_16BIT_565;
292 break;
293 case 8:
294 par->pixfmt = DFA_PIX_8BIT;
295 break;
296 default:
297 return -EINVAL;
298 }
299
300 return 0;
301}
302
303static const struct fb_bitfield eightbits = {0, 8};
304static const struct fb_bitfield nobits = {0, 0};
305
306static void gxt4500_unpack_pixfmt(struct fb_var_screeninfo *var,
307 int pixfmt)
308{
309 var->bits_per_pixel = pixsize[pixfmt] * 8;
310 var->red = eightbits;
311 var->green = eightbits;
312 var->blue = eightbits;
313 var->transp = nobits;
314
315 switch (pixfmt) {
316 case DFA_PIX_16BIT_565:
317 var->red.length = 5;
318 var->green.length = 6;
319 var->blue.length = 5;
320 break;
321 case DFA_PIX_16BIT_1555:
322 var->red.length = 5;
323 var->green.length = 5;
324 var->blue.length = 5;
325 var->transp.length = 1;
326 break;
327 case DFA_PIX_32BIT:
328 var->transp.length = 8;
329 break;
330 }
331 if (pixfmt != DFA_PIX_8BIT) {
332 var->green.offset = var->red.length;
333 var->blue.offset = var->green.offset + var->green.length;
334 if (var->transp.length)
335 var->transp.offset =
336 var->blue.offset + var->blue.length;
337 }
338}
339
340static int gxt4500_check_var(struct fb_var_screeninfo *var,
341 struct fb_info *info)
342{
343 struct gxt4500_par par;
344 int err;
345
346 par = *(struct gxt4500_par *)info->par;
347 err = gxt4500_var_to_par(var, &par);
348 if (!err) {
349 var->pixclock = calc_pixclock(&par);
350 gxt4500_unpack_pixfmt(var, par.pixfmt);
351 }
352 return err;
353}
354
355static int gxt4500_set_par(struct fb_info *info)
356{
357 struct gxt4500_par *par = info->par;
358 struct fb_var_screeninfo *var = &info->var;
359 int err;
360 u32 ctrlreg;
361 unsigned int dfa_ctl, pixfmt, stride;
362 unsigned int wid_tiles, i;
363 unsigned int prefetch_pix, htot;
364 struct gxt4500_par save_par;
365
366 save_par = *par;
367 err = gxt4500_var_to_par(var, par);
368 if (err) {
369 *par = save_par;
370 return err;
371 }
372
373 /* turn off DTG for now */
374 ctrlreg = readreg(par, DTG_CONTROL);
375 ctrlreg &= ~(DTG_CTL_ENABLE | DTG_CTL_SCREEN_REFRESH);
376 writereg(par, DTG_CONTROL, ctrlreg);
377
378 /* set PLL registers */
379 writereg(par, PLL_M, mdivtab[par->pll_m - 1]);
380 writereg(par, PLL_N, ndivtab[par->pll_n - 2]);
381 writereg(par, PLL_POSTDIV,
382 ((8 - par->pll_pd1) << 3) | (8 - par->pll_pd2));
383 msleep(20);
384
385 /* turn off hardware cursor */
386 writereg(par, CURSOR_MODE, CURSOR_MODE_OFF);
387
388 /* reset raster engine */
389 writereg(par, CTRL_REG0, CR0_RASTER_RESET | (CR0_RASTER_RESET << 16));
390 udelay(10);
391 writereg(par, CTRL_REG0, CR0_RASTER_RESET << 16);
392
393 /* set display timing generator registers */
394 htot = var->xres + var->left_margin + var->right_margin +
395 var->hsync_len;
396 writereg(par, DTG_HORIZ_EXTENT, htot - 1);
397 writereg(par, DTG_HORIZ_DISPLAY, var->xres - 1);
398 writereg(par, DTG_HSYNC_START, var->xres + var->right_margin - 1);
399 writereg(par, DTG_HSYNC_END,
400 var->xres + var->right_margin + var->hsync_len - 1);
401 writereg(par, DTG_HSYNC_END_COMP,
402 var->xres + var->right_margin + var->hsync_len - 1);
403 writereg(par, DTG_VERT_EXTENT,
404 var->yres + var->upper_margin + var->lower_margin +
405 var->vsync_len - 1);
406 writereg(par, DTG_VERT_DISPLAY, var->yres - 1);
407 writereg(par, DTG_VSYNC_START, var->yres + var->lower_margin - 1);
408 writereg(par, DTG_VSYNC_END,
409 var->yres + var->lower_margin + var->vsync_len - 1);
410 prefetch_pix = 3300000 / var->pixclock;
411 if (prefetch_pix >= htot)
412 prefetch_pix = htot - 1;
413 writereg(par, DTG_VERT_SHORT, htot - prefetch_pix - 1);
414 ctrlreg |= DTG_CTL_ENABLE | DTG_CTL_SCREEN_REFRESH;
415 writereg(par, DTG_CONTROL, ctrlreg);
416
417 /* calculate stride in DFA aperture */
418 if (var->xres_virtual > 2048) {
419 stride = 4096;
420 dfa_ctl = DFA_FB_STRIDE_4k;
421 } else if (var->xres_virtual > 1024) {
422 stride = 2048;
423 dfa_ctl = DFA_FB_STRIDE_2k;
424 } else {
425 stride = 1024;
426 dfa_ctl = DFA_FB_STRIDE_1k;
427 }
428
429 /* Set up framebuffer definition */
430 wid_tiles = (var->xres_virtual + 63) >> 6;
431
432 /* XXX add proper FB allocation here someday */
433 writereg(par, FB_AB_CTRL, FB_CTRL_TYPE | (wid_tiles << 16) | 0);
434 writereg(par, REFRESH_AB_CTRL, FB_CTRL_TYPE | (wid_tiles << 16) | 0);
435 writereg(par, FB_CD_CTRL, FB_CTRL_TYPE | (wid_tiles << 16) | 0);
436 writereg(par, REFRESH_CD_CTRL, FB_CTRL_TYPE | (wid_tiles << 16) | 0);
437 writereg(par, REFRESH_START, (var->xoffset << 16) | var->yoffset);
438 writereg(par, REFRESH_SIZE, (var->xres << 16) | var->yres);
439
440 /* Set up framebuffer access by CPU */
441
442 pixfmt = par->pixfmt;
443 dfa_ctl |= DFA_FB_ENABLE | pixfmt;
444 writereg(par, DFA_FB_A, dfa_ctl);
445
446 /*
447 * Set up window attribute table.
448 * We set all WAT entries the same so it doesn't matter what the
449 * window ID (WID) plane contains.
450 */
451 for (i = 0; i < 32; ++i) {
452 writereg(par, WAT_FMT + (i << 4), watfmt[pixfmt]);
453 writereg(par, WAT_CMAP_OFFSET + (i << 4), 0);
454 writereg(par, WAT_CTRL + (i << 4), 0);
455 writereg(par, WAT_GAMMA_CTRL + (i << 4), WAT_GAMMA_DISABLE);
456 }
457
458 /* Set sync polarity etc. */
459 ctrlreg = readreg(par, SYNC_CTL) &
460 ~(SYNC_CTL_SYNC_ON_RGB | SYNC_CTL_HSYNC_INV |
461 SYNC_CTL_VSYNC_INV);
462 if (var->sync & FB_SYNC_ON_GREEN)
463 ctrlreg |= SYNC_CTL_SYNC_ON_RGB;
464 if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))
465 ctrlreg |= SYNC_CTL_HSYNC_INV;
466 if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))
467 ctrlreg |= SYNC_CTL_VSYNC_INV;
468 writereg(par, SYNC_CTL, ctrlreg);
469
470 info->fix.line_length = stride * pixsize[pixfmt];
471 info->fix.visual = (pixfmt == DFA_PIX_8BIT)? FB_VISUAL_PSEUDOCOLOR:
472 FB_VISUAL_DIRECTCOLOR;
473
474 return 0;
475}
476
477static int gxt4500_setcolreg(unsigned int reg, unsigned int red,
478 unsigned int green, unsigned int blue,
479 unsigned int transp, struct fb_info *info)
480{
481 u32 cmap_entry;
482 struct gxt4500_par *par = info->par;
483
484 if (reg > 1023)
485 return 1;
486 cmap_entry = ((transp & 0xff00) << 16) | ((blue & 0xff00) << 8) |
487 (green & 0xff00) | (red >> 8);
488 writereg(par, CMAP + reg * 4, cmap_entry);
489
490 if (reg < 16 && par->pixfmt != DFA_PIX_8BIT) {
491 u32 *pal = info->pseudo_palette;
492 u32 val = reg;
493 switch (par->pixfmt) {
494 case DFA_PIX_16BIT_565:
495 val |= (reg << 11) | (reg << 6);
496 break;
497 case DFA_PIX_16BIT_1555:
498 val |= (reg << 10) | (reg << 5);
499 break;
500 case DFA_PIX_32BIT:
501 val |= (reg << 24);
502 /* fall through */
503 case DFA_PIX_24BIT:
504 val |= (reg << 16) | (reg << 8);
505 break;
506 }
507 pal[reg] = val;
508 }
509
510 return 0;
511}
512
513static int gxt4500_pan_display(struct fb_var_screeninfo *var,
514 struct fb_info *info)
515{
516 struct gxt4500_par *par = info->par;
517
518 if (var->xoffset & 7)
519 return -EINVAL;
520 if (var->xoffset + var->xres > var->xres_virtual ||
521 var->yoffset + var->yres > var->yres_virtual)
522 return -EINVAL;
523
524 writereg(par, REFRESH_START, (var->xoffset << 16) | var->yoffset);
525 return 0;
526}
527
528static int gxt4500_blank(int blank, struct fb_info *info)
529{
530 struct gxt4500_par *par = info->par;
531 int ctrl, dctl;
532
533 ctrl = readreg(par, SYNC_CTL);
534 ctrl &= ~(SYNC_CTL_SYNC_OFF | SYNC_CTL_HSYNC_OFF | SYNC_CTL_VSYNC_OFF);
535 dctl = readreg(par, DISP_CTL);
536 dctl |= DISP_CTL_OFF;
537 switch (blank) {
538 case FB_BLANK_UNBLANK:
539 dctl &= ~DISP_CTL_OFF;
540 break;
541 case FB_BLANK_POWERDOWN:
542 ctrl |= SYNC_CTL_SYNC_OFF;
543 break;
544 case FB_BLANK_HSYNC_SUSPEND:
545 ctrl |= SYNC_CTL_HSYNC_OFF;
546 break;
547 case FB_BLANK_VSYNC_SUSPEND:
548 ctrl |= SYNC_CTL_VSYNC_OFF;
549 break;
550 default: ;
551 }
552 writereg(par, SYNC_CTL, ctrl);
553 writereg(par, DISP_CTL, dctl);
554
555 return 0;
556}
557
558static const struct fb_fix_screeninfo gxt4500_fix __devinitdata = {
559 .id = "IBM GXT4500P",
560 .type = FB_TYPE_PACKED_PIXELS,
561 .visual = FB_VISUAL_PSEUDOCOLOR,
562 .xpanstep = 8,
563 .ypanstep = 1,
564 .mmio_len = 0x20000,
565};
566
567static struct fb_ops gxt4500_ops = {
568 .owner = THIS_MODULE,
569 .fb_check_var = gxt4500_check_var,
570 .fb_set_par = gxt4500_set_par,
571 .fb_setcolreg = gxt4500_setcolreg,
572 .fb_pan_display = gxt4500_pan_display,
573 .fb_blank = gxt4500_blank,
574 .fb_fillrect = cfb_fillrect,
575 .fb_copyarea = cfb_copyarea,
576 .fb_imageblit = cfb_imageblit,
577};
578
579/* PCI functions */
580static int __devinit gxt4500_probe(struct pci_dev *pdev,
581 const struct pci_device_id *ent)
582{
583 int err;
584 unsigned long reg_phys, fb_phys;
585 struct gxt4500_par *par;
586 struct fb_info *info;
587 struct fb_var_screeninfo var;
588
589 err = pci_enable_device(pdev);
590 if (err) {
591 dev_err(&pdev->dev, "gxt4500: cannot enable PCI device: %d\n",
592 err);
593 return err;
594 }
595
596 reg_phys = pci_resource_start(pdev, 0);
597 if (!request_mem_region(reg_phys, pci_resource_len(pdev, 0),
598 "gxt4500 regs")) {
599 dev_err(&pdev->dev, "gxt4500: cannot get registers\n");
600 goto err_nodev;
601 }
602
603 fb_phys = pci_resource_start(pdev, 1);
604 if (!request_mem_region(fb_phys, pci_resource_len(pdev, 1),
605 "gxt4500 FB")) {
606 dev_err(&pdev->dev, "gxt4500: cannot get framebuffer\n");
607 goto err_free_regs;
608 }
609
610 info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev);
611 if (!info) {
612 dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record");
613 goto err_free_fb;
614 }
615 par = info->par;
616 info->fix = gxt4500_fix;
617 info->pseudo_palette = par->pseudo_palette;
618
619 info->fix.mmio_start = reg_phys;
620 par->regs = ioremap(reg_phys, pci_resource_len(pdev, 0));
621 if (!par->regs) {
622 dev_err(&pdev->dev, "gxt4500: cannot map registers\n");
623 goto err_free_all;
624 }
625
626 info->fix.smem_start = fb_phys;
627 info->fix.smem_len = pci_resource_len(pdev, 1);
628 info->screen_base = ioremap(fb_phys, pci_resource_len(pdev, 1));
629 if (!info->screen_base) {
630 dev_err(&pdev->dev, "gxt4500: cannot map framebuffer\n");
631 goto err_unmap_regs;
632 }
633
634 pci_set_drvdata(pdev, info);
635
636 /* Set byte-swapping for DFA aperture for all pixel sizes */
637 pci_write_config_dword(pdev, CFG_ENDIAN0, 0x333300);
638
639 info->fbops = &gxt4500_ops;
640 info->flags = FBINFO_FLAG_DEFAULT;
641
642 err = fb_alloc_cmap(&info->cmap, 256, 0);
643 if (err) {
644 dev_err(&pdev->dev, "gxt4500: cannot allocate cmap\n");
645 goto err_unmap_all;
646 }
647
648 gxt4500_blank(FB_BLANK_UNBLANK, info);
649
650 if (!fb_find_mode(&var, info, mode_option, NULL, 0, &defaultmode, 8)) {
651 dev_err(&pdev->dev, "gxt4500: cannot find valid video mode\n");
652 goto err_free_cmap;
653 }
654 info->var = var;
655 if (gxt4500_set_par(info)) {
656 printk(KERN_ERR "gxt4500: cannot set video mode\n");
657 goto err_free_cmap;
658 }
659
660 if (register_framebuffer(info) < 0) {
661 dev_err(&pdev->dev, "gxt4500: cannot register framebuffer\n");
662 goto err_free_cmap;
663 }
664 printk(KERN_INFO "fb%d: %s frame buffer device\n",
665 info->node, info->fix.id);
666
667 return 0;
668
669 err_free_cmap:
670 fb_dealloc_cmap(&info->cmap);
671 err_unmap_all:
672 iounmap(info->screen_base);
673 err_unmap_regs:
674 iounmap(par->regs);
675 err_free_all:
676 framebuffer_release(info);
677 err_free_fb:
678 release_mem_region(fb_phys, pci_resource_len(pdev, 1));
679 err_free_regs:
680 release_mem_region(reg_phys, pci_resource_len(pdev, 0));
681 err_nodev:
682 return -ENODEV;
683}
684
685static void __devexit gxt4500_remove(struct pci_dev *pdev)
686{
687 struct fb_info *info = pci_get_drvdata(pdev);
688 struct gxt4500_par *par;
689
690 if (!info)
691 return;
692 par = info->par;
693 unregister_framebuffer(info);
694 fb_dealloc_cmap(&info->cmap);
695 iounmap(par->regs);
696 iounmap(info->screen_base);
697 release_mem_region(pci_resource_start(pdev, 0),
698 pci_resource_len(pdev, 0));
699 release_mem_region(pci_resource_start(pdev, 1),
700 pci_resource_len(pdev, 1));
701 framebuffer_release(info);
702}
703
704/* supported chipsets */
705static const struct pci_device_id gxt4500_pci_tbl[] = {
706 { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_GXT4500P,
707 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
708 { 0 }
709};
710
711MODULE_DEVICE_TABLE(pci, gxt4500_pci_tbl);
712
713static struct pci_driver gxt4500_driver = {
714 .name = "gxt4500",
715 .id_table = gxt4500_pci_tbl,
716 .probe = gxt4500_probe,
717 .remove = __devexit_p(gxt4500_remove),
718};
719
720static int __devinit gxt4500_init(void)
721{
722#ifndef MODULE
723 if (fb_get_options("gxt4500", &mode_option))
724 return -ENODEV;
725#endif
726
727 return pci_register_driver(&gxt4500_driver);
728}
729module_init(gxt4500_init);
730
731static void __exit gxt4500_exit(void)
732{
733 pci_unregister_driver(&gxt4500_driver);
734}
735module_exit(gxt4500_exit);
736
737MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
738MODULE_DESCRIPTION("FBDev driver for IBM GXT4500P");
739MODULE_LICENSE("GPL");
740module_param(mode_option, charp, 0);
741MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index 3afb472763c0..3dc49424dc75 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -29,7 +29,6 @@
29#include <asm/io.h> 29#include <asm/io.h>
30#include <asm/hd64461.h> 30#include <asm/hd64461.h>
31#include <asm/cpu/dac.h> 31#include <asm/cpu/dac.h>
32#include <asm/hp6xx/hp6xx.h>
33 32
34#define WIDTH 640 33#define WIDTH 640
35 34
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index 91cf3b577d15..9ab9b839a0f5 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -295,6 +295,8 @@ static int __init hpfb_init_one(unsigned long phys_base, unsigned long virt_base
295 295
296 if (register_framebuffer(&fb_info) < 0) { 296 if (register_framebuffer(&fb_info) < 0) {
297 fb_dealloc_cmap(&fb_info.cmap); 297 fb_dealloc_cmap(&fb_info.cmap);
298 iounmap(fb_info.screen_base);
299 fb_info.screen_base = NULL;
298 return 1; 300 return 1;
299 } 301 }
300 302
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index b38d805db313..961f4d404467 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -137,15 +137,15 @@ void i810_create_i2c_busses(struct i810fb_par *par)
137void i810_delete_i2c_busses(struct i810fb_par *par) 137void i810_delete_i2c_busses(struct i810fb_par *par)
138{ 138{
139 if (par->chan[0].par) 139 if (par->chan[0].par)
140 i2c_bit_del_bus(&par->chan[0].adapter); 140 i2c_del_adapter(&par->chan[0].adapter);
141 par->chan[0].par = NULL; 141 par->chan[0].par = NULL;
142 142
143 if (par->chan[1].par) 143 if (par->chan[1].par)
144 i2c_bit_del_bus(&par->chan[1].adapter); 144 i2c_del_adapter(&par->chan[1].adapter);
145 par->chan[1].par = NULL; 145 par->chan[1].par = NULL;
146 146
147 if (par->chan[2].par) 147 if (par->chan[2].par)
148 i2c_bit_del_bus(&par->chan[2].adapter); 148 i2c_del_adapter(&par->chan[2].adapter);
149 par->chan[2].par = NULL; 149 par->chan[2].par = NULL;
150} 150}
151 151
@@ -162,9 +162,7 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
162 162
163 if (e != NULL) { 163 if (e != NULL) {
164 DPRINTK("i810-i2c: Getting EDID from BIOS\n"); 164 DPRINTK("i810-i2c: Getting EDID from BIOS\n");
165 edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 165 edid = kmemdup(e, EDID_LENGTH, GFP_KERNEL);
166 if (edid)
167 memcpy(edid, e, EDID_LENGTH);
168 } 166 }
169 } 167 }
170 168
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index e6df492c22a5..655ae0fa99ca 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -384,19 +384,21 @@ int __init igafb_init(void)
384 if (!con_is_present()) 384 if (!con_is_present())
385 return -ENXIO; 385 return -ENXIO;
386 386
387 pdev = pci_find_device(PCI_VENDOR_ID_INTERG, 387 pdev = pci_get_device(PCI_VENDOR_ID_INTERG,
388 PCI_DEVICE_ID_INTERG_1682, 0); 388 PCI_DEVICE_ID_INTERG_1682, 0);
389 if (pdev == NULL) { 389 if (pdev == NULL) {
390 /* 390 /*
391 * XXX We tried to use cyber2000fb.c for IGS 2000. 391 * XXX We tried to use cyber2000fb.c for IGS 2000.
392 * But it does not initialize the chip in JavaStation-E, alas. 392 * But it does not initialize the chip in JavaStation-E, alas.
393 */ 393 */
394 pdev = pci_find_device(PCI_VENDOR_ID_INTERG, 0x2000, 0); 394 pdev = pci_get_device(PCI_VENDOR_ID_INTERG, 0x2000, 0);
395 if(pdev == NULL) { 395 if(pdev == NULL) {
396 return -ENXIO; 396 return -ENXIO;
397 } 397 }
398 iga2000 = 1; 398 iga2000 = 1;
399 } 399 }
400 /* We leak a reference here but as it cannot be unloaded this is
401 fine. If you write unload code remember to free it in unload */
400 402
401 size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16; 403 size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16;
402 404
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
index 5686e2164e39..33bc41f50540 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -188,11 +188,11 @@ void intelfb_delete_i2c_busses(struct intelfb_info *dinfo)
188 188
189 for (i = 0; i < MAX_OUTPUTS; i++) { 189 for (i = 0; i < MAX_OUTPUTS; i++) {
190 if (dinfo->output[i].i2c_bus.dinfo) { 190 if (dinfo->output[i].i2c_bus.dinfo) {
191 i2c_bit_del_bus(&dinfo->output[i].i2c_bus.adapter); 191 i2c_del_adapter(&dinfo->output[i].i2c_bus.adapter);
192 dinfo->output[i].i2c_bus.dinfo = NULL; 192 dinfo->output[i].i2c_bus.dinfo = NULL;
193 } 193 }
194 if (dinfo->output[i].ddc_bus.dinfo) { 194 if (dinfo->output[i].ddc_bus.dinfo) {
195 i2c_bit_del_bus(&dinfo->output[i].ddc_bus.adapter); 195 i2c_del_adapter(&dinfo->output[i].ddc_bus.adapter);
196 dinfo->output[i].ddc_bus.dinfo = NULL; 196 dinfo->output[i].ddc_bus.dinfo = NULL;
197 } 197 }
198 } 198 }
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 6f9de04193d2..664fc5cf962a 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -1058,10 +1058,9 @@ intelfb_init_var(struct intelfb_info *dinfo)
1058 u8 *edid_d = NULL; 1058 u8 *edid_d = NULL;
1059 1059
1060 if (edid_s) { 1060 if (edid_s) {
1061 edid_d = kmalloc(EDID_LENGTH, GFP_KERNEL); 1061 edid_d = kmemdup(edid_s, EDID_LENGTH, GFP_KERNEL);
1062 1062
1063 if (edid_d) { 1063 if (edid_d) {
1064 memcpy(edid_d, edid_s, EDID_LENGTH);
1065 fb_edid_to_monspecs(edid_d, 1064 fb_edid_to_monspecs(edid_d,
1066 &dinfo->info->monspecs); 1065 &dinfo->info->monspecs);
1067 kfree(edid_d); 1066 kfree(edid_d);
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index eeeeff9a09eb..a95836839e1e 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -161,7 +161,7 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
161 return 1; 161 return 1;
162 162
163 /* Find the bridge device. It is always 0:0.0 */ 163 /* Find the bridge device. It is always 0:0.0 */
164 if (!(bridge_dev = pci_find_slot(0, PCI_DEVFN(0, 0)))) { 164 if (!(bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)))) {
165 ERR_MSG("cannot find bridge device\n"); 165 ERR_MSG("cannot find bridge device\n");
166 return 1; 166 return 1;
167 } 167 }
@@ -169,6 +169,8 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
169 /* Get the fb aperture size and "stolen" memory amount. */ 169 /* Get the fb aperture size and "stolen" memory amount. */
170 tmp = 0; 170 tmp = 0;
171 pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); 171 pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
172 pci_dev_put(bridge_dev);
173
172 switch (pdev->device) { 174 switch (pdev->device) {
173 case PCI_DEVICE_ID_INTEL_915G: 175 case PCI_DEVICE_ID_INTEL_915G:
174 case PCI_DEVICE_ID_INTEL_915GM: 176 case PCI_DEVICE_ID_INTEL_915GM:
@@ -662,7 +664,7 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
662 int index = dinfo->pll_index; 664 int index = dinfo->pll_index;
663 DBG_MSG("intelfbhw_print_hw_state\n"); 665 DBG_MSG("intelfbhw_print_hw_state\n");
664 666
665 if (!hw || !dinfo) 667 if (!hw)
666 return; 668 return;
667 /* Read in as much of the HW state as possible. */ 669 /* Read in as much of the HW state as possible. */
668 printk("hw state dump start\n"); 670 printk("hw state dump start\n");
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index 80a043807161..180d94c2b4d2 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -608,6 +608,22 @@ void __init macfb_setup(char *options)
608 } 608 }
609} 609}
610 610
611static void __init iounmap_macfb(void)
612{
613 if (valkyrie_cmap_regs)
614 iounmap(valkyrie_cmap_regs);
615 if (dafb_cmap_regs)
616 iounmap(dafb_cmap_regs);
617 if (v8_brazil_cmap_regs)
618 iounmap(v8_brazil_cmap_regs);
619 if (rbv_cmap_regs)
620 iounmap(rbv_cmap_regs);
621 if (civic_cmap_regs)
622 iounmap(civic_cmap_regs);
623 if (csc_cmap_regs)
624 iounmap(csc_cmap_regs);
625}
626
611static int __init macfb_init(void) 627static int __init macfb_init(void)
612{ 628{
613 int video_cmap_len, video_is_nubus = 0; 629 int video_cmap_len, video_is_nubus = 0;
@@ -962,6 +978,10 @@ static int __init macfb_init(void)
962 if (!err) 978 if (!err)
963 printk("fb%d: %s frame buffer device\n", 979 printk("fb%d: %s frame buffer device\n",
964 fb_info.node, fb_info.fix.id); 980 fb_info.node, fb_info.fix.id);
981 else {
982 iounmap(fb_info.screen_base);
983 iounmap_macfb();
984 }
965 return err; 985 return err;
966} 986}
967 987
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
index 795c1a99a680..fe28848e7b52 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/matrox/i2c-matroxfb.c
@@ -124,7 +124,7 @@ static int i2c_bus_reg(struct i2c_bit_adapter* b, struct matrox_fb_info* minfo,
124 124
125static void i2c_bit_bus_del(struct i2c_bit_adapter* b) { 125static void i2c_bit_bus_del(struct i2c_bit_adapter* b) {
126 if (b->initialized) { 126 if (b->initialized) {
127 i2c_bit_del_bus(&b->adapter); 127 i2c_del_adapter(&b->adapter);
128 b->initialized = 0; 128 b->initialized = 0;
129 } 129 }
130} 130}
@@ -146,7 +146,7 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
146 unsigned long flags; 146 unsigned long flags;
147 struct matroxfb_dh_maven_info* m2info; 147 struct matroxfb_dh_maven_info* m2info;
148 148
149 m2info = (struct matroxfb_dh_maven_info*)kmalloc(sizeof(*m2info), GFP_KERNEL); 149 m2info = kmalloc(sizeof(*m2info), GFP_KERNEL);
150 if (!m2info) 150 if (!m2info)
151 return NULL; 151 return NULL;
152 152
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index e9b4115fcad0..cb2aa402ddfd 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -2028,7 +2028,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
2028 } 2028 }
2029 2029
2030#ifdef CONFIG_FB_MATROX_MULTIHEAD 2030#ifdef CONFIG_FB_MATROX_MULTIHEAD
2031 minfo = (struct matrox_fb_info*)kmalloc(sizeof(*minfo), GFP_KERNEL); 2031 minfo = kmalloc(sizeof(*minfo), GFP_KERNEL);
2032 if (!minfo) 2032 if (!minfo)
2033 return -1; 2033 return -1;
2034#else 2034#else
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 27eb4bb4f89f..2c9801090fae 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -694,7 +694,7 @@ static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) {
694 /* hardware is CRTC2 incapable... */ 694 /* hardware is CRTC2 incapable... */
695 if (!ACCESS_FBINFO(devflags.crtc2)) 695 if (!ACCESS_FBINFO(devflags.crtc2))
696 return NULL; 696 return NULL;
697 m2info = (struct matroxfb_dh_fb_info*)kmalloc(sizeof(*m2info), GFP_KERNEL); 697 m2info = kmalloc(sizeof(*m2info), GFP_KERNEL);
698 if (!m2info) { 698 if (!m2info) {
699 printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n"); 699 printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n");
700 return NULL; 700 return NULL;
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/mbx/mbxdebugfs.c
index 84aab3ad024e..472a3ca3d92d 100644
--- a/drivers/video/mbx/mbxdebugfs.c
+++ b/drivers/video/mbx/mbxdebugfs.c
@@ -10,6 +10,8 @@ struct mbxfb_debugfs_data {
10 struct dentry *clock; 10 struct dentry *clock;
11 struct dentry *display; 11 struct dentry *display;
12 struct dentry *gsctl; 12 struct dentry *gsctl;
13 struct dentry *sdram;
14 struct dentry *misc;
13}; 15};
14 16
15static int open_file_generic(struct inode *inode, struct file *file) 17static int open_file_generic(struct inode *inode, struct file *file)
@@ -29,11 +31,11 @@ static ssize_t sysconf_read_file(struct file *file, char __user *userbuf,
29{ 31{
30 char * s = big_buffer; 32 char * s = big_buffer;
31 33
32 s += sprintf(s, "SYSCFG = %08lx\n", SYSCFG); 34 s += sprintf(s, "SYSCFG = %08x\n", readl(SYSCFG));
33 s += sprintf(s, "PFBASE = %08lx\n", PFBASE); 35 s += sprintf(s, "PFBASE = %08x\n", readl(PFBASE));
34 s += sprintf(s, "PFCEIL = %08lx\n", PFCEIL); 36 s += sprintf(s, "PFCEIL = %08x\n", readl(PFCEIL));
35 s += sprintf(s, "POLLFLAG = %08lx\n", POLLFLAG); 37 s += sprintf(s, "POLLFLAG = %08x\n", readl(POLLFLAG));
36 s += sprintf(s, "SYSRST = %08lx\n", SYSRST); 38 s += sprintf(s, "SYSRST = %08x\n", readl(SYSRST));
37 39
38 return simple_read_from_buffer(userbuf, count, ppos, 40 return simple_read_from_buffer(userbuf, count, ppos,
39 big_buffer, s-big_buffer); 41 big_buffer, s-big_buffer);
@@ -45,24 +47,24 @@ static ssize_t gsctl_read_file(struct file *file, char __user *userbuf,
45{ 47{
46 char * s = big_buffer; 48 char * s = big_buffer;
47 49
48 s += sprintf(s, "GSCTRL = %08lx\n", GSCTRL); 50 s += sprintf(s, "GSCTRL = %08x\n", readl(GSCTRL));
49 s += sprintf(s, "VSCTRL = %08lx\n", VSCTRL); 51 s += sprintf(s, "VSCTRL = %08x\n", readl(VSCTRL));
50 s += sprintf(s, "GBBASE = %08lx\n", GBBASE); 52 s += sprintf(s, "GBBASE = %08x\n", readl(GBBASE));
51 s += sprintf(s, "VBBASE = %08lx\n", VBBASE); 53 s += sprintf(s, "VBBASE = %08x\n", readl(VBBASE));
52 s += sprintf(s, "GDRCTRL = %08lx\n", GDRCTRL); 54 s += sprintf(s, "GDRCTRL = %08x\n", readl(GDRCTRL));
53 s += sprintf(s, "VCMSK = %08lx\n", VCMSK); 55 s += sprintf(s, "VCMSK = %08x\n", readl(VCMSK));
54 s += sprintf(s, "GSCADR = %08lx\n", GSCADR); 56 s += sprintf(s, "GSCADR = %08x\n", readl(GSCADR));
55 s += sprintf(s, "VSCADR = %08lx\n", VSCADR); 57 s += sprintf(s, "VSCADR = %08x\n", readl(VSCADR));
56 s += sprintf(s, "VUBASE = %08lx\n", VUBASE); 58 s += sprintf(s, "VUBASE = %08x\n", readl(VUBASE));
57 s += sprintf(s, "VVBASE = %08lx\n", VVBASE); 59 s += sprintf(s, "VVBASE = %08x\n", readl(VVBASE));
58 s += sprintf(s, "GSADR = %08lx\n", GSADR); 60 s += sprintf(s, "GSADR = %08x\n", readl(GSADR));
59 s += sprintf(s, "VSADR = %08lx\n", VSADR); 61 s += sprintf(s, "VSADR = %08x\n", readl(VSADR));
60 s += sprintf(s, "HCCTRL = %08lx\n", HCCTRL); 62 s += sprintf(s, "HCCTRL = %08x\n", readl(HCCTRL));
61 s += sprintf(s, "HCSIZE = %08lx\n", HCSIZE); 63 s += sprintf(s, "HCSIZE = %08x\n", readl(HCSIZE));
62 s += sprintf(s, "HCPOS = %08lx\n", HCPOS); 64 s += sprintf(s, "HCPOS = %08x\n", readl(HCPOS));
63 s += sprintf(s, "HCBADR = %08lx\n", HCBADR); 65 s += sprintf(s, "HCBADR = %08x\n", readl(HCBADR));
64 s += sprintf(s, "HCCKMSK = %08lx\n", HCCKMSK); 66 s += sprintf(s, "HCCKMSK = %08x\n", readl(HCCKMSK));
65 s += sprintf(s, "GPLUT = %08lx\n", GPLUT); 67 s += sprintf(s, "GPLUT = %08x\n", readl(GPLUT));
66 68
67 return simple_read_from_buffer(userbuf, count, ppos, 69 return simple_read_from_buffer(userbuf, count, ppos,
68 big_buffer, s-big_buffer); 70 big_buffer, s-big_buffer);
@@ -73,36 +75,36 @@ static ssize_t display_read_file(struct file *file, char __user *userbuf,
73{ 75{
74 char * s = big_buffer; 76 char * s = big_buffer;
75 77
76 s += sprintf(s, "DSCTRL = %08lx\n", DSCTRL); 78 s += sprintf(s, "DSCTRL = %08x\n", readl(DSCTRL));
77 s += sprintf(s, "DHT01 = %08lx\n", DHT01); 79 s += sprintf(s, "DHT01 = %08x\n", readl(DHT01));
78 s += sprintf(s, "DHT02 = %08lx\n", DHT02); 80 s += sprintf(s, "DHT02 = %08x\n", readl(DHT02));
79 s += sprintf(s, "DHT03 = %08lx\n", DHT03); 81 s += sprintf(s, "DHT03 = %08x\n", readl(DHT03));
80 s += sprintf(s, "DVT01 = %08lx\n", DVT01); 82 s += sprintf(s, "DVT01 = %08x\n", readl(DVT01));
81 s += sprintf(s, "DVT02 = %08lx\n", DVT02); 83 s += sprintf(s, "DVT02 = %08x\n", readl(DVT02));
82 s += sprintf(s, "DVT03 = %08lx\n", DVT03); 84 s += sprintf(s, "DVT03 = %08x\n", readl(DVT03));
83 s += sprintf(s, "DBCOL = %08lx\n", DBCOL); 85 s += sprintf(s, "DBCOL = %08x\n", readl(DBCOL));
84 s += sprintf(s, "BGCOLOR = %08lx\n", BGCOLOR); 86 s += sprintf(s, "BGCOLOR = %08x\n", readl(BGCOLOR));
85 s += sprintf(s, "DINTRS = %08lx\n", DINTRS); 87 s += sprintf(s, "DINTRS = %08x\n", readl(DINTRS));
86 s += sprintf(s, "DINTRE = %08lx\n", DINTRE); 88 s += sprintf(s, "DINTRE = %08x\n", readl(DINTRE));
87 s += sprintf(s, "DINTRCNT = %08lx\n", DINTRCNT); 89 s += sprintf(s, "DINTRCNT = %08x\n", readl(DINTRCNT));
88 s += sprintf(s, "DSIG = %08lx\n", DSIG); 90 s += sprintf(s, "DSIG = %08x\n", readl(DSIG));
89 s += sprintf(s, "DMCTRL = %08lx\n", DMCTRL); 91 s += sprintf(s, "DMCTRL = %08x\n", readl(DMCTRL));
90 s += sprintf(s, "CLIPCTRL = %08lx\n", CLIPCTRL); 92 s += sprintf(s, "CLIPCTRL = %08x\n", readl(CLIPCTRL));
91 s += sprintf(s, "SPOCTRL = %08lx\n", SPOCTRL); 93 s += sprintf(s, "SPOCTRL = %08x\n", readl(SPOCTRL));
92 s += sprintf(s, "SVCTRL = %08lx\n", SVCTRL); 94 s += sprintf(s, "SVCTRL = %08x\n", readl(SVCTRL));
93 s += sprintf(s, "DLSTS = %08lx\n", DLSTS); 95 s += sprintf(s, "DLSTS = %08x\n", readl(DLSTS));
94 s += sprintf(s, "DLLCTRL = %08lx\n", DLLCTRL); 96 s += sprintf(s, "DLLCTRL = %08x\n", readl(DLLCTRL));
95 s += sprintf(s, "DVLNUM = %08lx\n", DVLNUM); 97 s += sprintf(s, "DVLNUM = %08x\n", readl(DVLNUM));
96 s += sprintf(s, "DUCTRL = %08lx\n", DUCTRL); 98 s += sprintf(s, "DUCTRL = %08x\n", readl(DUCTRL));
97 s += sprintf(s, "DVECTRL = %08lx\n", DVECTRL); 99 s += sprintf(s, "DVECTRL = %08x\n", readl(DVECTRL));
98 s += sprintf(s, "DHDET = %08lx\n", DHDET); 100 s += sprintf(s, "DHDET = %08x\n", readl(DHDET));
99 s += sprintf(s, "DVDET = %08lx\n", DVDET); 101 s += sprintf(s, "DVDET = %08x\n", readl(DVDET));
100 s += sprintf(s, "DODMSK = %08lx\n", DODMSK); 102 s += sprintf(s, "DODMSK = %08x\n", readl(DODMSK));
101 s += sprintf(s, "CSC01 = %08lx\n", CSC01); 103 s += sprintf(s, "CSC01 = %08x\n", readl(CSC01));
102 s += sprintf(s, "CSC02 = %08lx\n", CSC02); 104 s += sprintf(s, "CSC02 = %08x\n", readl(CSC02));
103 s += sprintf(s, "CSC03 = %08lx\n", CSC03); 105 s += sprintf(s, "CSC03 = %08x\n", readl(CSC03));
104 s += sprintf(s, "CSC04 = %08lx\n", CSC04); 106 s += sprintf(s, "CSC04 = %08x\n", readl(CSC04));
105 s += sprintf(s, "CSC05 = %08lx\n", CSC05); 107 s += sprintf(s, "CSC05 = %08x\n", readl(CSC05));
106 108
107 return simple_read_from_buffer(userbuf, count, ppos, 109 return simple_read_from_buffer(userbuf, count, ppos,
108 big_buffer, s-big_buffer); 110 big_buffer, s-big_buffer);
@@ -113,24 +115,61 @@ static ssize_t clock_read_file(struct file *file, char __user *userbuf,
113{ 115{
114 char * s = big_buffer; 116 char * s = big_buffer;
115 117
116 s += sprintf(s, "SYSCLKSRC = %08lx\n", SYSCLKSRC); 118 s += sprintf(s, "SYSCLKSRC = %08x\n", readl(SYSCLKSRC));
117 s += sprintf(s, "PIXCLKSRC = %08lx\n", PIXCLKSRC); 119 s += sprintf(s, "PIXCLKSRC = %08x\n", readl(PIXCLKSRC));
118 s += sprintf(s, "CLKSLEEP = %08lx\n", CLKSLEEP); 120 s += sprintf(s, "CLKSLEEP = %08x\n", readl(CLKSLEEP));
119 s += sprintf(s, "COREPLL = %08lx\n", COREPLL); 121 s += sprintf(s, "COREPLL = %08x\n", readl(COREPLL));
120 s += sprintf(s, "DISPPLL = %08lx\n", DISPPLL); 122 s += sprintf(s, "DISPPLL = %08x\n", readl(DISPPLL));
121 s += sprintf(s, "PLLSTAT = %08lx\n", PLLSTAT); 123 s += sprintf(s, "PLLSTAT = %08x\n", readl(PLLSTAT));
122 s += sprintf(s, "VOVRCLK = %08lx\n", VOVRCLK); 124 s += sprintf(s, "VOVRCLK = %08x\n", readl(VOVRCLK));
123 s += sprintf(s, "PIXCLK = %08lx\n", PIXCLK); 125 s += sprintf(s, "PIXCLK = %08x\n", readl(PIXCLK));
124 s += sprintf(s, "MEMCLK = %08lx\n", MEMCLK); 126 s += sprintf(s, "MEMCLK = %08x\n", readl(MEMCLK));
125 s += sprintf(s, "M24CLK = %08lx\n", M24CLK); 127 s += sprintf(s, "M24CLK = %08x\n", readl(M24CLK));
126 s += sprintf(s, "MBXCLK = %08lx\n", MBXCLK); 128 s += sprintf(s, "MBXCLK = %08x\n", readl(MBXCLK));
127 s += sprintf(s, "SDCLK = %08lx\n", SDCLK); 129 s += sprintf(s, "SDCLK = %08x\n", readl(SDCLK));
128 s += sprintf(s, "PIXCLKDIV = %08lx\n", PIXCLKDIV); 130 s += sprintf(s, "PIXCLKDIV = %08x\n", readl(PIXCLKDIV));
129 131
130 return simple_read_from_buffer(userbuf, count, ppos, 132 return simple_read_from_buffer(userbuf, count, ppos,
131 big_buffer, s-big_buffer); 133 big_buffer, s-big_buffer);
132} 134}
133 135
136static ssize_t sdram_read_file(struct file *file, char __user *userbuf,
137 size_t count, loff_t *ppos)
138{
139 char * s = big_buffer;
140
141 s += sprintf(s, "LMRST = %08x\n", readl(LMRST));
142 s += sprintf(s, "LMCFG = %08x\n", readl(LMCFG));
143 s += sprintf(s, "LMPWR = %08x\n", readl(LMPWR));
144 s += sprintf(s, "LMPWRSTAT = %08x\n", readl(LMPWRSTAT));
145 s += sprintf(s, "LMCEMR = %08x\n", readl(LMCEMR));
146 s += sprintf(s, "LMTYPE = %08x\n", readl(LMTYPE));
147 s += sprintf(s, "LMTIM = %08x\n", readl(LMTIM));
148 s += sprintf(s, "LMREFRESH = %08x\n", readl(LMREFRESH));
149 s += sprintf(s, "LMPROTMIN = %08x\n", readl(LMPROTMIN));
150 s += sprintf(s, "LMPROTMAX = %08x\n", readl(LMPROTMAX));
151 s += sprintf(s, "LMPROTCFG = %08x\n", readl(LMPROTCFG));
152 s += sprintf(s, "LMPROTERR = %08x\n", readl(LMPROTERR));
153
154 return simple_read_from_buffer(userbuf, count, ppos,
155 big_buffer, s-big_buffer);
156}
157
158static ssize_t misc_read_file(struct file *file, char __user *userbuf,
159 size_t count, loff_t *ppos)
160{
161 char * s = big_buffer;
162
163 s += sprintf(s, "LCD_CONFIG = %08x\n", readl(LCD_CONFIG));
164 s += sprintf(s, "ODFBPWR = %08x\n", readl(ODFBPWR));
165 s += sprintf(s, "ODFBSTAT = %08x\n", readl(ODFBSTAT));
166 s += sprintf(s, "ID = %08x\n", readl(ID));
167
168 return simple_read_from_buffer(userbuf, count, ppos,
169 big_buffer, s-big_buffer);
170}
171
172
134static struct file_operations sysconf_fops = { 173static struct file_operations sysconf_fops = {
135 .read = sysconf_read_file, 174 .read = sysconf_read_file,
136 .write = write_file_dummy, 175 .write = write_file_dummy,
@@ -155,6 +194,17 @@ static struct file_operations gsctl_fops = {
155 .open = open_file_generic, 194 .open = open_file_generic,
156}; 195};
157 196
197static struct file_operations sdram_fops = {
198 .read = sdram_read_file,
199 .write = write_file_dummy,
200 .open = open_file_generic,
201};
202
203static struct file_operations misc_fops = {
204 .read = misc_read_file,
205 .write = write_file_dummy,
206 .open = open_file_generic,
207};
158 208
159static void __devinit mbxfb_debugfs_init(struct fb_info *fbi) 209static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
160{ 210{
@@ -173,6 +223,10 @@ static void __devinit mbxfb_debugfs_init(struct fb_info *fbi)
173 fbi, &display_fops); 223 fbi, &display_fops);
174 dbg->gsctl = debugfs_create_file("gsctl", 0444, dbg->dir, 224 dbg->gsctl = debugfs_create_file("gsctl", 0444, dbg->dir,
175 fbi, &gsctl_fops); 225 fbi, &gsctl_fops);
226 dbg->sdram = debugfs_create_file("sdram", 0444, dbg->dir,
227 fbi, &sdram_fops);
228 dbg->misc = debugfs_create_file("misc", 0444, dbg->dir,
229 fbi, &misc_fops);
176} 230}
177 231
178static void __devexit mbxfb_debugfs_remove(struct fb_info *fbi) 232static void __devexit mbxfb_debugfs_remove(struct fb_info *fbi)
@@ -180,6 +234,8 @@ static void __devexit mbxfb_debugfs_remove(struct fb_info *fbi)
180 struct mbxfb_info *mfbi = fbi->par; 234 struct mbxfb_info *mfbi = fbi->par;
181 struct mbxfb_debugfs_data *dbg = mfbi->debugfs_data; 235 struct mbxfb_debugfs_data *dbg = mfbi->debugfs_data;
182 236
237 debugfs_remove(dbg->misc);
238 debugfs_remove(dbg->sdram);
183 debugfs_remove(dbg->gsctl); 239 debugfs_remove(dbg->gsctl);
184 debugfs_remove(dbg->display); 240 debugfs_remove(dbg->display);
185 debugfs_remove(dbg->clock); 241 debugfs_remove(dbg->clock);
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index a32d1af79e07..980d5f623902 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -1,8 +1,14 @@
1/* 1/*
2 * linux/drivers/video/mbx/mbxfb.c 2 * linux/drivers/video/mbx/mbxfb.c
3 * 3 *
4 * Copyright (C) 2006 8D Technologies inc
5 * Raphael Assenat <raph@8d.com>
6 * - Added video overlay support
7 * - Various improvements
8 *
4 * Copyright (C) 2006 Compulab, Ltd. 9 * Copyright (C) 2006 Compulab, Ltd.
5 * Mike Rapoport <mike@compulab.co.il> 10 * Mike Rapoport <mike@compulab.co.il>
11 * - Creation of driver
6 * 12 *
7 * Based on pxafb.c 13 * Based on pxafb.c
8 * 14 *
@@ -19,6 +25,7 @@
19#include <linux/init.h> 25#include <linux/init.h>
20#include <linux/module.h> 26#include <linux/module.h>
21#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/uaccess.h>
22 29
23#include <asm/io.h> 30#include <asm/io.h>
24 31
@@ -29,6 +36,14 @@
29 36
30static unsigned long virt_base_2700; 37static unsigned long virt_base_2700;
31 38
39#define write_reg(val, reg) do { writel((val), (reg)); } while(0)
40
41/* Without this delay, the graphics appears somehow scaled and
42 * there is a lot of jitter in scanlines. This delay is probably
43 * needed only after setting some specific register(s) somewhere,
44 * not all over the place... */
45#define write_reg_dly(val, reg) do { writel((val), reg); udelay(1000); } while(0)
46
32#define MIN_XRES 16 47#define MIN_XRES 16
33#define MIN_YRES 16 48#define MIN_YRES 16
34#define MAX_XRES 2048 49#define MAX_XRES 2048
@@ -257,19 +272,17 @@ static int mbxfb_set_par(struct fb_info *info)
257 gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT)); 272 gsctrl &= ~(FMsk(GSCTRL_GSWIDTH) | FMsk(GSCTRL_GSHEIGHT));
258 gsctrl |= Gsctrl_Width(info->var.xres) | 273 gsctrl |= Gsctrl_Width(info->var.xres) |
259 Gsctrl_Height(info->var.yres); 274 Gsctrl_Height(info->var.yres);
260 writel(gsctrl, GSCTRL); 275 write_reg_dly(gsctrl, GSCTRL);
261 udelay(1000);
262 276
263 gsadr &= ~(FMsk(GSADR_SRCSTRIDE)); 277 gsadr &= ~(FMsk(GSADR_SRCSTRIDE));
264 gsadr |= Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel / 278 gsadr |= Gsadr_Srcstride(info->var.xres * info->var.bits_per_pixel /
265 (8 * 16) - 1); 279 (8 * 16) - 1);
266 writel(gsadr, GSADR); 280 write_reg_dly(gsadr, GSADR);
267 udelay(1000);
268 281
269 /* setup timings */ 282 /* setup timings */
270 var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div); 283 var->pixclock = mbxfb_get_pixclock(info->var.pixclock, &div);
271 284
272 writel((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) | 285 write_reg_dly((Disp_Pll_M(div.m) | Disp_Pll_N(div.n) |
273 Disp_Pll_P(div.p) | DISP_PLL_EN), DISPPLL); 286 Disp_Pll_P(div.p) | DISP_PLL_EN), DISPPLL);
274 287
275 hbps = var->hsync_len; 288 hbps = var->hsync_len;
@@ -282,18 +295,20 @@ static int mbxfb_set_par(struct fb_info *info)
282 vfps = vas + var->yres; 295 vfps = vas + var->yres;
283 vt = vfps + var->lower_margin; 296 vt = vfps + var->lower_margin;
284 297
285 writel((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01); 298 write_reg_dly((Dht01_Hbps(hbps) | Dht01_Ht(ht)), DHT01);
286 writel((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02); 299 write_reg_dly((Dht02_Hlbs(has) | Dht02_Has(has)), DHT02);
287 writel((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03); 300 write_reg_dly((Dht03_Hfps(hfps) | Dht03_Hrbs(hfps)), DHT03);
288 writel((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET); 301 write_reg_dly((Dhdet_Hdes(has) | Dhdet_Hdef(hfps)), DHDET);
289 302
290 writel((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01); 303 write_reg_dly((Dvt01_Vbps(vbps) | Dvt01_Vt(vt)), DVT01);
291 writel((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02); 304 write_reg_dly((Dvt02_Vtbs(vas) | Dvt02_Vas(vas)), DVT02);
292 writel((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03); 305 write_reg_dly((Dvt03_Vfps(vfps) | Dvt03_Vbbs(vfps)), DVT03);
293 writel((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET); 306 write_reg_dly((Dvdet_Vdes(vas) | Dvdet_Vdef(vfps)), DVDET);
294 writel((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL); 307 write_reg_dly((Dvectrl_Vevent(vfps) | Dvectrl_Vfetch(vbps)), DVECTRL);
295 308
296 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 309 write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
310
311 write_reg_dly(DINTRE_VEVENT0_EN, DINTRE);
297 312
298 return 0; 313 return 0;
299} 314}
@@ -305,23 +320,203 @@ static int mbxfb_blank(int blank, struct fb_info *info)
305 case FB_BLANK_VSYNC_SUSPEND: 320 case FB_BLANK_VSYNC_SUSPEND:
306 case FB_BLANK_HSYNC_SUSPEND: 321 case FB_BLANK_HSYNC_SUSPEND:
307 case FB_BLANK_NORMAL: 322 case FB_BLANK_NORMAL:
308 writel((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL); 323 write_reg_dly((readl(DSCTRL) & ~DSCTRL_SYNCGEN_EN), DSCTRL);
309 udelay(1000); 324 write_reg_dly((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK);
310 writel((readl(PIXCLK) & ~PIXCLK_EN), PIXCLK); 325 write_reg_dly((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK);
311 udelay(1000);
312 writel((readl(VOVRCLK) & ~VOVRCLK_EN), VOVRCLK);
313 udelay(1000);
314 break; 326 break;
315 case FB_BLANK_UNBLANK: 327 case FB_BLANK_UNBLANK:
316 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 328 write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
317 udelay(1000); 329 write_reg_dly((readl(PIXCLK) | PIXCLK_EN), PIXCLK);
318 writel((readl(PIXCLK) | PIXCLK_EN), PIXCLK);
319 udelay(1000);
320 break; 330 break;
321 } 331 }
322 return 0; 332 return 0;
323} 333}
324 334
335static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
336{
337 u32 vsctrl, vbbase, vscadr, vsadr;
338 u32 sssize, spoctrl, svctrl, shctrl;
339 u32 vubase, vvbase;
340 u32 vovrclk;
341
342 if (set->scaled_width==0 || set->scaled_height==0)
343 return -EINVAL;
344
345 /* read registers which have reserved bits
346 * so we can write them back as-is. */
347 vovrclk = readl(VOVRCLK);
348 vsctrl = readl(VSCTRL);
349 vscadr = readl(VSCADR);
350 vubase = readl(VUBASE);
351 vvbase = readl(VVBASE);
352
353 spoctrl = readl(SPOCTRL);
354 sssize = readl(SSSIZE);
355
356
357 vbbase = Vbbase_Glalpha(set->alpha);
358
359 vsctrl &= ~( FMsk(VSCTRL_VSWIDTH) |
360 FMsk(VSCTRL_VSHEIGHT) |
361 FMsk(VSCTRL_VPIXFMT) |
362 VSCTRL_GAMMA_EN | VSCTRL_CSC_EN |
363 VSCTRL_COSITED );
364 vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) |
365 VSCTRL_CSC_EN;
366
367 vscadr &= ~(VSCADR_STR_EN | VSCADR_COLKEY_EN | VSCADR_COLKEYSRC |
368 FMsk(VSCADR_BLEND_M) | FMsk(VSCADR_BLEND_POS) |
369 FMsk(VSCADR_VBASE_ADR) );
370 vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR));
371 vvbase &= ~(FMsk(VVBASE_VBASE_ADR));
372
373 switch (set->fmt)
374 {
375 case MBXFB_FMT_YUV12:
376 vsctrl |= VSCTRL_VPIXFMT_YUV12;
377
378 set->Y_stride = ((set->width) + 0xf ) & ~0xf;
379
380 break;
381 case MBXFB_FMT_UY0VY1:
382 vsctrl |= VSCTRL_VPIXFMT_UY0VY1;
383 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
384 break;
385 case MBXFB_FMT_VY0UY1:
386 vsctrl |= VSCTRL_VPIXFMT_VY0UY1;
387 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
388 break;
389 case MBXFB_FMT_Y0UY1V:
390 vsctrl |= VSCTRL_VPIXFMT_Y0UY1V;
391 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
392 break;
393 case MBXFB_FMT_Y0VY1U:
394 vsctrl |= VSCTRL_VPIXFMT_Y0VY1U;
395 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
396 break;
397 default:
398 return -EINVAL;
399 }
400
401 /* VSCTRL has the bits which sets the Video Pixel Format.
402 * When passing from a packed to planar format,
403 * if we write VSCTRL first, VVBASE and VUBASE would
404 * be zero if we would not set them here. (And then,
405 * the chips hangs and only a reset seems to fix it).
406 *
407 * If course, the values calculated here have no meaning
408 * for packed formats.
409 */
410 set->UV_stride = ((set->width/2) + 0x7 ) & ~0x7;
411 set->U_offset = set->height * set->Y_stride;
412 set->V_offset = set->U_offset +
413 set->height * set->UV_stride;
414 vubase |= Vubase_Ubase_Adr(
415 (0x60000 + set->mem_offset + set->U_offset)>>3);
416 vvbase |= Vvbase_Vbase_Adr(
417 (0x60000 + set->mem_offset + set->V_offset)>>3);
418
419
420 vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_GLOB |
421 Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4);
422
423 if (set->enable)
424 vscadr |= VSCADR_STR_EN;
425
426
427 vsadr = Vsadr_Srcstride((set->Y_stride)/16-1) |
428 Vsadr_Xstart(set->x) | Vsadr_Ystart(set->y);
429
430 sssize &= ~(FMsk(SSSIZE_SC_WIDTH) | FMsk(SSSIZE_SC_HEIGHT));
431 sssize = Sssize_Sc_Width(set->scaled_width-1) |
432 Sssize_Sc_Height(set->scaled_height-1);
433
434 spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP |
435 SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C |
436 FMsk(SPOCTRL_VORDER) | FMsk(SPOCTRL_VPITCH));
437 spoctrl = Spoctrl_Vpitch((set->height<<11)/set->scaled_height)
438 | SPOCTRL_VORDER_2TAP;
439
440 /* Bypass horiz/vert scaler when same size */
441 if (set->scaled_width == set->width)
442 spoctrl |= SPOCTRL_H_SC_BP;
443 if (set->scaled_height == set->height)
444 spoctrl |= SPOCTRL_V_SC_BP;
445
446 svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10);
447
448 shctrl = Shctrl_Hinitial(4<<11)
449 | Shctrl_Hpitch((set->width<<11)/set->scaled_width);
450
451 /* Video plane registers */
452 write_reg(vsctrl, VSCTRL);
453 write_reg(vbbase, VBBASE);
454 write_reg(vscadr, VSCADR);
455 write_reg(vubase, VUBASE);
456 write_reg(vvbase, VVBASE);
457 write_reg(vsadr, VSADR);
458
459 /* Video scaler registers */
460 write_reg(sssize, SSSIZE);
461 write_reg(spoctrl, SPOCTRL);
462 write_reg(svctrl, SVCTRL);
463 write_reg(shctrl, SHCTRL);
464
465 /* RAPH: Using those coefficients, the scaled
466 * image is quite blurry. I dont know how
467 * to improve them ; The chip documentation
468 * was not helpful.. */
469 write_reg(0x21212121, VSCOEFF0);
470 write_reg(0x21212121, VSCOEFF1);
471 write_reg(0x21212121, VSCOEFF2);
472 write_reg(0x21212121, VSCOEFF3);
473 write_reg(0x21212121, VSCOEFF4);
474 write_reg(0x00000000, HSCOEFF0);
475 write_reg(0x00000000, HSCOEFF1);
476 write_reg(0x00000000, HSCOEFF2);
477 write_reg(0x03020201, HSCOEFF3);
478 write_reg(0x09070604, HSCOEFF4);
479 write_reg(0x0f0e0c0a, HSCOEFF5);
480 write_reg(0x15141211, HSCOEFF6);
481 write_reg(0x19181716, HSCOEFF7);
482 write_reg(0x00000019, HSCOEFF8);
483
484 /* Clock */
485 if (set->enable)
486 vovrclk |= 1;
487 else
488 vovrclk &= ~1;
489
490 write_reg(vovrclk, VOVRCLK);
491
492 return 0;
493}
494
495static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,
496 unsigned long arg)
497{
498 struct mbxfb_overlaySetup setup;
499 int res;
500
501 if (cmd == MBXFB_IOCX_OVERLAY)
502 {
503 if (copy_from_user(&setup, (void __user*)arg,
504 sizeof(struct mbxfb_overlaySetup)))
505 return -EFAULT;
506
507 res = mbxfb_setupOverlay(&setup);
508 if (res)
509 return res;
510
511 if (copy_to_user((void __user*)arg, &setup,
512 sizeof(struct mbxfb_overlaySetup)))
513 return -EFAULT;
514
515 return 0;
516 }
517 return -EINVAL;
518}
519
325static struct fb_ops mbxfb_ops = { 520static struct fb_ops mbxfb_ops = {
326 .owner = THIS_MODULE, 521 .owner = THIS_MODULE,
327 .fb_check_var = mbxfb_check_var, 522 .fb_check_var = mbxfb_check_var,
@@ -331,6 +526,7 @@ static struct fb_ops mbxfb_ops = {
331 .fb_copyarea = cfb_copyarea, 526 .fb_copyarea = cfb_copyarea,
332 .fb_imageblit = cfb_imageblit, 527 .fb_imageblit = cfb_imageblit,
333 .fb_blank = mbxfb_blank, 528 .fb_blank = mbxfb_blank,
529 .fb_ioctl = mbxfb_ioctl,
334}; 530};
335 531
336/* 532/*
@@ -339,36 +535,29 @@ static struct fb_ops mbxfb_ops = {
339*/ 535*/
340static void __devinit setup_memc(struct fb_info *fbi) 536static void __devinit setup_memc(struct fb_info *fbi)
341{ 537{
342 struct mbxfb_info *mfbi = fbi->par;
343 unsigned long tmp; 538 unsigned long tmp;
344 int i; 539 int i;
345 540
346 /* FIXME: use platfrom specific parameters */ 541 /* FIXME: use platfrom specific parameters */
347 /* setup SDRAM controller */ 542 /* setup SDRAM controller */
348 writel((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS | 543 write_reg_dly((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |
349 LMCFG_LMA_TS), 544 LMCFG_LMA_TS),
350 LMCFG); 545 LMCFG);
351 udelay(1000);
352 546
353 writel(LMPWR_MC_PWR_ACT, LMPWR); 547 write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);
354 udelay(1000);
355 548
356 /* setup SDRAM timings */ 549 /* setup SDRAM timings */
357 writel((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) | 550 write_reg_dly((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) |
358 Lmtim_Trc(9) | Lmtim_Tdpl(2)), 551 Lmtim_Trc(9) | Lmtim_Tdpl(2)),
359 LMTIM); 552 LMTIM);
360 udelay(1000);
361 /* setup SDRAM refresh rate */ 553 /* setup SDRAM refresh rate */
362 writel(0xc2b, LMREFRESH); 554 write_reg_dly(0xc2b, LMREFRESH);
363 udelay(1000);
364 /* setup SDRAM type parameters */ 555 /* setup SDRAM type parameters */
365 writel((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 | 556 write_reg_dly((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 |
366 LMTYPE_COLSZ_8), 557 LMTYPE_COLSZ_8),
367 LMTYPE); 558 LMTYPE);
368 udelay(1000);
369 /* enable memory controller */ 559 /* enable memory controller */
370 writel(LMPWR_MC_PWR_ACT, LMPWR); 560 write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);
371 udelay(1000);
372 561
373 /* perform dummy reads */ 562 /* perform dummy reads */
374 for ( i = 0; i < 16; i++ ) { 563 for ( i = 0; i < 16; i++ ) {
@@ -379,34 +568,30 @@ static void __devinit setup_memc(struct fb_info *fbi)
379static void enable_clocks(struct fb_info *fbi) 568static void enable_clocks(struct fb_info *fbi)
380{ 569{
381 /* enable clocks */ 570 /* enable clocks */
382 writel(SYSCLKSRC_PLL_2, SYSCLKSRC); 571 write_reg_dly(SYSCLKSRC_PLL_2, SYSCLKSRC);
383 udelay(1000); 572 write_reg_dly(PIXCLKSRC_PLL_1, PIXCLKSRC);
384 writel(PIXCLKSRC_PLL_1, PIXCLKSRC); 573 write_reg_dly(0x00000000, CLKSLEEP);
385 udelay(1000); 574
386 writel(0x00000000, CLKSLEEP); 575 /* PLL output = (Frefclk * M) / (N * 2^P )
387 udelay(1000); 576 *
388 writel((Core_Pll_M(0x17) | Core_Pll_N(0x3) | Core_Pll_P(0x0) | 577 * M: 0x17, N: 0x3, P: 0x0 == 100 Mhz!
578 * M: 0xb, N: 0x1, P: 0x1 == 71 Mhz
579 * */
580 write_reg_dly((Core_Pll_M(0xb) | Core_Pll_N(0x1) | Core_Pll_P(0x1) |
389 CORE_PLL_EN), 581 CORE_PLL_EN),
390 COREPLL); 582 COREPLL);
391 udelay(1000); 583
392 writel((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) | 584 write_reg_dly((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) |
393 DISP_PLL_EN), 585 DISP_PLL_EN),
394 DISPPLL); 586 DISPPLL);
395 587
396 writel(0x00000000, VOVRCLK); 588 write_reg_dly(0x00000000, VOVRCLK);
397 udelay(1000); 589 write_reg_dly(PIXCLK_EN, PIXCLK);
398 writel(PIXCLK_EN, PIXCLK); 590 write_reg_dly(MEMCLK_EN, MEMCLK);
399 udelay(1000); 591 write_reg_dly(0x00000006, M24CLK);
400 writel(MEMCLK_EN, MEMCLK); 592 write_reg_dly(0x00000006, MBXCLK);
401 udelay(1000); 593 write_reg_dly(SDCLK_EN, SDCLK);
402 writel(0x00000006, M24CLK); 594 write_reg_dly(0x00000001, PIXCLKDIV);
403 udelay(1000);
404 writel(0x00000006, MBXCLK);
405 udelay(1000);
406 writel(SDCLK_EN, SDCLK);
407 udelay(1000);
408 writel(0x00000001, PIXCLKDIV);
409 udelay(1000);
410} 595}
411 596
412static void __devinit setup_graphics(struct fb_info *fbi) 597static void __devinit setup_graphics(struct fb_info *fbi)
@@ -430,16 +615,11 @@ static void __devinit setup_graphics(struct fb_info *fbi)
430 break; 615 break;
431 } 616 }
432 617
433 writel(gsctrl, GSCTRL); 618 write_reg_dly(gsctrl, GSCTRL);
434 udelay(1000); 619 write_reg_dly(0x00000000, GBBASE);
435 writel(0x00000000, GBBASE); 620 write_reg_dly(0x00ffffff, GDRCTRL);
436 udelay(1000); 621 write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
437 writel(0x00ffffff, GDRCTRL); 622 write_reg_dly(0x00000000, GPLUT);
438 udelay(1000);
439 writel((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
440 udelay(1000);
441 writel(0x00000000, GPLUT);
442 udelay(1000);
443} 623}
444 624
445static void __devinit setup_display(struct fb_info *fbi) 625static void __devinit setup_display(struct fb_info *fbi)
@@ -451,17 +631,14 @@ static void __devinit setup_display(struct fb_info *fbi)
451 dsctrl |= DSCTRL_HS_POL; 631 dsctrl |= DSCTRL_HS_POL;
452 if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) 632 if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
453 dsctrl |= DSCTRL_VS_POL; 633 dsctrl |= DSCTRL_VS_POL;
454 writel(dsctrl, DSCTRL); 634 write_reg_dly(dsctrl, DSCTRL);
455 udelay(1000); 635 write_reg_dly(0xd0303010, DMCTRL);
456 writel(0xd0303010, DMCTRL); 636 write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
457 udelay(1000);
458 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
459} 637}
460 638
461static void __devinit enable_controller(struct fb_info *fbi) 639static void __devinit enable_controller(struct fb_info *fbi)
462{ 640{
463 writel(SYSRST_RST, SYSRST); 641 write_reg_dly(SYSRST_RST, SYSRST);
464 udelay(1000);
465 642
466 643
467 enable_clocks(fbi); 644 enable_clocks(fbi);
@@ -478,12 +655,12 @@ static void __devinit enable_controller(struct fb_info *fbi)
478static int mbxfb_suspend(struct platform_device *dev, pm_message_t state) 655static int mbxfb_suspend(struct platform_device *dev, pm_message_t state)
479{ 656{
480 /* make frame buffer memory enter self-refresh mode */ 657 /* make frame buffer memory enter self-refresh mode */
481 writel(LMPWR_MC_PWR_SRM, LMPWR); 658 write_reg_dly(LMPWR_MC_PWR_SRM, LMPWR);
482 while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM) 659 while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM)
483 ; /* empty statement */ 660 ; /* empty statement */
484 661
485 /* reset the device, since it's initial state is 'mostly sleeping' */ 662 /* reset the device, since it's initial state is 'mostly sleeping' */
486 writel(SYSRST_RST, SYSRST); 663 write_reg_dly(SYSRST_RST, SYSRST);
487 return 0; 664 return 0;
488} 665}
489 666
@@ -495,7 +672,7 @@ static int mbxfb_resume(struct platform_device *dev)
495/* setup_graphics(fbi); */ 672/* setup_graphics(fbi); */
496/* setup_display(fbi); */ 673/* setup_display(fbi); */
497 674
498 writel((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL); 675 write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);
499 return 0; 676 return 0;
500} 677}
501#else 678#else
@@ -520,6 +697,12 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
520 697
521 dev_dbg(dev, "mbxfb_probe\n"); 698 dev_dbg(dev, "mbxfb_probe\n");
522 699
700 pdata = dev->dev.platform_data;
701 if (!pdata) {
702 dev_err(&dev->dev, "platform data is required\n");
703 return -EINVAL;
704 }
705
523 fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev); 706 fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);
524 if (fbi == NULL) { 707 if (fbi == NULL) {
525 dev_err(&dev->dev, "framebuffer_alloc failed\n"); 708 dev_err(&dev->dev, "framebuffer_alloc failed\n");
@@ -528,7 +711,8 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
528 711
529 mfbi = fbi->par; 712 mfbi = fbi->par;
530 fbi->pseudo_palette = mfbi->pseudo_palette; 713 fbi->pseudo_palette = mfbi->pseudo_palette;
531 pdata = dev->dev.platform_data; 714
715
532 if (pdata->probe) 716 if (pdata->probe)
533 mfbi->platform_probe = pdata->probe; 717 mfbi->platform_probe = pdata->probe;
534 if (pdata->remove) 718 if (pdata->remove)
@@ -578,16 +762,16 @@ static int __devinit mbxfb_probe(struct platform_device *dev)
578 goto err4; 762 goto err4;
579 } 763 }
580 764
581 /* FIXME: get from platform */
582 fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000); 765 fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);
583 fbi->screen_size = 8 * 1024 * 1024; /* 8 Megs */ 766 fbi->screen_size = pdata->memsize;
584 fbi->fbops = &mbxfb_ops; 767 fbi->fbops = &mbxfb_ops;
585 768
586 fbi->var = mbxfb_default; 769 fbi->var = mbxfb_default;
587 fbi->fix = mbxfb_fix; 770 fbi->fix = mbxfb_fix;
588 fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000; 771 fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000;
589 fbi->fix.smem_len = 8 * 1024 * 1024; 772 fbi->fix.smem_len = pdata->memsize;
590 fbi->fix.line_length = 640 * 2; 773 fbi->fix.line_length = mbxfb_default.xres_virtual *
774 mbxfb_default.bits_per_pixel / 8;
591 775
592 ret = fb_alloc_cmap(&fbi->cmap, 256, 0); 776 ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
593 if (ret < 0) { 777 if (ret < 0) {
@@ -636,8 +820,7 @@ static int __devexit mbxfb_remove(struct platform_device *dev)
636{ 820{
637 struct fb_info *fbi = platform_get_drvdata(dev); 821 struct fb_info *fbi = platform_get_drvdata(dev);
638 822
639 writel(SYSRST_RST, SYSRST); 823 write_reg_dly(SYSRST_RST, SYSRST);
640 udelay(1000);
641 824
642 mbxfb_debugfs_remove(fbi); 825 mbxfb_debugfs_remove(fbi);
643 826
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h
index c226a8e45312..9a24fb0c7d48 100644
--- a/drivers/video/mbx/reg_bits.h
+++ b/drivers/video/mbx/reg_bits.h
@@ -242,6 +242,67 @@
242#define GPLUT_LUTDATA Fld(24,0) 242#define GPLUT_LUTDATA Fld(24,0)
243#define Gplut_Lutdata(x) ((x) << FShft(GPLUT_LUTDATA)) 243#define Gplut_Lutdata(x) ((x) << FShft(GPLUT_LUTDATA))
244 244
245/* VSCTRL - Video Surface Control Register */
246#define VSCTRL_VPIXFMT Fld(4,27)
247#define VSCTRL_VPIXFMT_YUV12 ((0x9) << FShft(VSCTRL_VPIXFMT))
248#define VSCTRL_VPIXFMT_UY0VY1 ((0xc) << FShft(VSCTRL_VPIXFMT))
249#define VSCTRL_VPIXFMT_VY0UY1 ((0xd) << FShft(VSCTRL_VPIXFMT))
250#define VSCTRL_VPIXFMT_Y0UY1V ((0xe) << FShft(VSCTRL_VPIXFMT))
251#define VSCTRL_VPIXFMT_Y0VY1U ((0xf) << FShft(VSCTRL_VPIXFMT))
252#define VSCTRL_GAMMA_EN (1 << 26)
253#define VSCTRL_CSC_EN (1 << 25)
254#define VSCTRL_COSITED (1 << 22)
255#define VSCTRL_VSWIDTH Fld(11,11)
256#define Vsctrl_Width(Pixels) /* Video Width [1-2048] */ \
257 (((Pixels) - 1) << FShft(VSCTRL_VSWIDTH))
258#define VSCTRL_VSHEIGHT Fld(11,0)
259#define Vsctrl_Height(Pixels) /* Video Height [1-2048] */ \
260 (((Pixels) - 1) << FShft(VSCTRL_VSHEIGHT))
261
262/* VBBASE - Video Blending Base Register */
263#define VBBASE_GLALPHA Fld(8,24)
264#define Vbbase_Glalpha(x) ((x) << FShft(VBBASE_GLALPHA))
265
266#define VBBASE_COLKEY Fld(24,0)
267#define Vbbase_Colkey(x) ((x) << FShft(VBBASE_COLKEY))
268
269/* VCMSK - Video Color Key Mask Register */
270#define VCMSK_COLKEY_M Fld(24,0)
271#define Vcmsk_colkey_m(x) ((x) << FShft(VCMSK_COLKEY_M))
272
273/* VSCADR - Video Stream Control Rddress Register */
274#define VSCADR_STR_EN (1 << 31)
275#define VSCADR_COLKEY_EN (1 << 30)
276#define VSCADR_COLKEYSRC (1 << 29)
277#define VSCADR_BLEND_M Fld(2,27)
278#define VSCADR_BLEND_NONE ((0x0) << FShft(VSCADR_BLEND_M))
279#define VSCADR_BLEND_INV ((0x1) << FShft(VSCADR_BLEND_M))
280#define VSCADR_BLEND_GLOB ((0x2) << FShft(VSCADR_BLEND_M))
281#define VSCADR_BLEND_PIX ((0x3) << FShft(VSCADR_BLEND_M))
282#define VSCADR_BLEND_POS Fld(2,24)
283#define VSCADR_BLEND_GFX ((0x0) << FShft(VSCADR_BLEND_POS))
284#define VSCADR_BLEND_VID ((0x1) << FShft(VSCADR_BLEND_POS))
285#define VSCADR_BLEND_CUR ((0x2) << FShft(VSCADR_BLEND_POS))
286#define VSCADR_VBASE_ADR Fld(23,0)
287#define Vscadr_Vbase_Adr(x) ((x) << FShft(VSCADR_VBASE_ADR))
288
289/* VUBASE - Video U Base Register */
290#define VUBASE_UVHALFSTR (1 << 31)
291#define VUBASE_UBASE_ADR Fld(24,0)
292#define Vubase_Ubase_Adr(x) ((x) << FShft(VUBASE_UBASE_ADR))
293
294/* VVBASE - Video V Base Register */
295#define VVBASE_VBASE_ADR Fld(24,0)
296#define Vvbase_Vbase_Adr(x) ((x) << FShft(VVBASE_VBASE_ADR))
297
298/* VSADR - Video Stride Address Register */
299#define VSADR_SRCSTRIDE Fld(10,22)
300#define Vsadr_Srcstride(x) ((x) << FShft(VSADR_SRCSTRIDE))
301#define VSADR_XSTART Fld(11,11)
302#define Vsadr_Xstart(x) ((x) << FShft(VSADR_XSTART))
303#define VSADR_YSTART Fld(11,0)
304#define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART))
305
245/* HCCTRL - Hardware Cursor Register fields */ 306/* HCCTRL - Hardware Cursor Register fields */
246#define HCCTRL_CUR_EN (1 << 31) 307#define HCCTRL_CUR_EN (1 << 31)
247#define HCCTRL_COLKEY_EN (1 << 29) 308#define HCCTRL_COLKEY_EN (1 << 29)
@@ -394,6 +455,30 @@
394#define DMCTRL_BURSTLEN Fld(6,0) 455#define DMCTRL_BURSTLEN Fld(6,0)
395#define Dmctrl_Burstlen(x) ((x) << FShft(DMCTRL_BURSTLEN)) 456#define Dmctrl_Burstlen(x) ((x) << FShft(DMCTRL_BURSTLEN))
396 457
458/* DINTRS - Display Interrupt Status Register */
459#define DINTRS_CUR_OR_S (1 << 18)
460#define DINTRS_STR2_OR_S (1 << 17)
461#define DINTRS_STR1_OR_S (1 << 16)
462#define DINTRS_CUR_UR_S (1 << 6)
463#define DINTRS_STR2_UR_S (1 << 5)
464#define DINTRS_STR1_UR_S (1 << 4)
465#define DINTRS_VEVENT1_S (1 << 3)
466#define DINTRS_VEVENT0_S (1 << 2)
467#define DINTRS_HBLNK1_S (1 << 1)
468#define DINTRS_HBLNK0_S (1 << 0)
469
470/* DINTRE - Display Interrupt Enable Register */
471#define DINTRE_CUR_OR_EN (1 << 18)
472#define DINTRE_STR2_OR_EN (1 << 17)
473#define DINTRE_STR1_OR_EN (1 << 16)
474#define DINTRE_CUR_UR_EN (1 << 6)
475#define DINTRE_STR2_UR_EN (1 << 5)
476#define DINTRE_STR1_UR_EN (1 << 4)
477#define DINTRE_VEVENT1_EN (1 << 3)
478#define DINTRE_VEVENT0_EN (1 << 2)
479#define DINTRE_HBLNK1_EN (1 << 1)
480#define DINTRE_HBLNK0_EN (1 << 0)
481
397 482
398/* DLSTS - display load status register */ 483/* DLSTS - display load status register */
399#define DLSTS_RLD_ADONE (1 << 23) 484#define DLSTS_RLD_ADONE (1 << 23)
@@ -403,16 +488,41 @@
403#define DLLCTRL_RLD_ADRLN Fld(8,24) 488#define DLLCTRL_RLD_ADRLN Fld(8,24)
404#define Dllctrl_Rld_Adrln(x) ((x) << FShft(DLLCTRL_RLD_ADRLN)) 489#define Dllctrl_Rld_Adrln(x) ((x) << FShft(DLLCTRL_RLD_ADRLN))
405 490
491/* CLIPCTRL - Clipping Control Register */
492#define CLIPCTRL_HSKIP Fld(11,16)
493#define Clipctrl_Hskip ((x) << FShft(CLIPCTRL_HSKIP))
494#define CLIPCTRL_VSKIP Fld(11,0)
495#define Clipctrl_Vskip ((x) << FShft(CLIPCTRL_VSKIP))
496
406/* SPOCTRL - Scale Pitch/Order Control Register */ 497/* SPOCTRL - Scale Pitch/Order Control Register */
407#define SPOCTRL_H_SC_BP (1 << 31) 498#define SPOCTRL_H_SC_BP (1 << 31)
408#define SPOCTRL_V_SC_BP (1 << 30) 499#define SPOCTRL_V_SC_BP (1 << 30)
409#define SPOCTRL_HV_SC_OR (1 << 29) 500#define SPOCTRL_HV_SC_OR (1 << 29)
410#define SPOCTRL_VS_UR_C (1 << 27) 501#define SPOCTRL_VS_UR_C (1 << 27)
411#define SPOCTRL_VORDER Fld(2,16) 502#define SPOCTRL_VORDER Fld(2,16)
412#define SPOCTRL_VORDER_1TAP ((0x0) << FShft(SPOCTRL_VORDER)) 503#define SPOCTRL_VORDER_1TAP ((0x0) << FShft(SPOCTRL_VORDER))
413#define SPOCTRL_VORDER_2TAP ((0x1) << FShft(SPOCTRL_VORDER)) 504#define SPOCTRL_VORDER_2TAP ((0x1) << FShft(SPOCTRL_VORDER))
414#define SPOCTRL_VORDER_4TAP ((0x3) << FShft(SPOCTRL_VORDER)) 505#define SPOCTRL_VORDER_4TAP ((0x3) << FShft(SPOCTRL_VORDER))
415#define SPOCTRL_VPITCH Fld(16,0) 506#define SPOCTRL_VPITCH Fld(16,0)
416#define Spoctrl_Vpitch(x) ((x) << FShft(SPOCTRL_VPITCH)) 507#define Spoctrl_Vpitch(x) ((x) << FShft(SPOCTRL_VPITCH))
417 508
509/* SVCTRL - Scale Vertical Control Register */
510#define SVCTRL_INITIAL1 Fld(16,16)
511#define Svctrl_Initial1(x) ((x) << FShft(SVCTRL_INITIAL1))
512#define SVCTRL_INITIAL2 Fld(16,0)
513#define Svctrl_Initial2(x) ((x) << FShft(SVCTRL_INITIAL2))
514
515/* SHCTRL - Scale Horizontal Control Register */
516#define SHCTRL_HINITIAL Fld(16,16)
517#define Shctrl_Hinitial(x) ((x) << FShft(SHCTRL_HINITIAL))
518#define SHCTRL_HDECIM (1 << 15)
519#define SHCTRL_HPITCH Fld(15,0)
520#define Shctrl_Hpitch(x) ((x) << FShft(SHCTRL_HPITCH))
521
522/* SSSIZE - Scale Surface Size Register */
523#define SSSIZE_SC_WIDTH Fld(11,16)
524#define Sssize_Sc_Width(x) ((x) << FShft(SSSIZE_SC_WIDTH))
525#define SSSIZE_SC_HEIGHT Fld(11,0)
526#define Sssize_Sc_Height(x) ((x) << FShft(SSSIZE_SC_HEIGHT))
527
418#endif /* __REG_BITS_2700G_ */ 528#endif /* __REG_BITS_2700G_ */
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h
index ad20be07666b..a7c63d865aad 100644
--- a/drivers/video/mbx/regs.h
+++ b/drivers/video/mbx/regs.h
@@ -127,7 +127,7 @@
127#define HSCOEFF0 __REG_2700G(0x000021b4) 127#define HSCOEFF0 __REG_2700G(0x000021b4)
128#define HSCOEFF1 __REG_2700G(0x000021b8) 128#define HSCOEFF1 __REG_2700G(0x000021b8)
129#define HSCOEFF2 __REG_2700G(0x000021bc) 129#define HSCOEFF2 __REG_2700G(0x000021bc)
130#define HSCOEFF3 __REG_2700G(0x000021b0) 130#define HSCOEFF3 __REG_2700G(0x000021c0)
131#define HSCOEFF4 __REG_2700G(0x000021c4) 131#define HSCOEFF4 __REG_2700G(0x000021c4)
132#define HSCOEFF5 __REG_2700G(0x000021c8) 132#define HSCOEFF5 __REG_2700G(0x000021c8)
133#define HSCOEFF6 __REG_2700G(0x000021cc) 133#define HSCOEFF6 __REG_2700G(0x000021cc)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index d1267904c280..5df41f6f2b86 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -34,8 +34,6 @@ const char *global_mode_option;
34 * Standard video mode definitions (taken from XFree86) 34 * Standard video mode definitions (taken from XFree86)
35 */ 35 */
36 36
37#define DEFAULT_MODEDB_INDEX 0
38
39static const struct fb_videomode modedb[] = { 37static const struct fb_videomode modedb[] = {
40 { 38 {
41 /* 640x400 @ 70 Hz, 31.5 kHz hsync */ 39 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
@@ -505,8 +503,10 @@ int fb_find_mode(struct fb_var_screeninfo *var,
505 db = modedb; 503 db = modedb;
506 dbsize = ARRAY_SIZE(modedb); 504 dbsize = ARRAY_SIZE(modedb);
507 } 505 }
506
508 if (!default_mode) 507 if (!default_mode)
509 default_mode = &modedb[DEFAULT_MODEDB_INDEX]; 508 default_mode = &db[0];
509
510 if (!default_bpp) 510 if (!default_bpp)
511 default_bpp = 8; 511 default_bpp = 8;
512 512
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 59a6f5fa5ae6..deaf820cb38f 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -1932,7 +1932,7 @@ static int __devinit neo_init_hw(struct fb_info *info)
1932 printk(KERN_DEBUG "--- Neo extended register dump ---\n"); 1932 printk(KERN_DEBUG "--- Neo extended register dump ---\n");
1933 for (int w = 0; w < 0x85; w++) 1933 for (int w = 0; w < 0x85; w++)
1934 printk(KERN_DEBUG "CR %p: %p\n", (void *) w, 1934 printk(KERN_DEBUG "CR %p: %p\n", (void *) w,
1935 (void *) vga_rcrt(NULL, w); 1935 (void *) vga_rcrt(NULL, w));
1936 for (int w = 0; w < 0xC7; w++) 1936 for (int w = 0; w < 0xC7; w++)
1937 printk(KERN_DEBUG "GR %p: %p\n", (void *) w, 1937 printk(KERN_DEBUG "GR %p: %p\n", (void *) w,
1938 (void *) vga_rgfx(NULL, w)); 1938 (void *) vga_rgfx(NULL, w));
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/nvidia/nv_accel.c
index 4aefb8f41637..9efb8a3854e2 100644
--- a/drivers/video/nvidia/nv_accel.c
+++ b/drivers/video/nvidia/nv_accel.c
@@ -261,41 +261,6 @@ void NVResetGraphics(struct fb_info *info)
261 NVDmaKickoff(par); 261 NVDmaKickoff(par);
262} 262}
263 263
264u8 byte_rev[256] = {
265 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
266 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
267 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
268 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
269 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
270 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
271 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
272 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
273 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
274 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
275 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
276 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
277 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
278 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
279 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
280 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
281 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
282 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
283 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
284 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
285 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
286 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
287 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
288 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
289 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
290 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
291 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
292 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
293 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
294 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
295 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
296 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
297};
298
299int nvidiafb_sync(struct fb_info *info) 264int nvidiafb_sync(struct fb_info *info)
300{ 265{
301 struct nvidia_par *par = info->par; 266 struct nvidia_par *par = info->par;
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
index 9ed640d35728..ea426115c6f9 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/nvidia/nv_hw.c
@@ -145,12 +145,18 @@ static void nvGetClocks(struct nvidia_par *par, unsigned int *MClk,
145 145
146 if (par->Architecture >= NV_ARCH_40) { 146 if (par->Architecture >= NV_ARCH_40) {
147 pll = NV_RD32(par->PMC, 0x4020); 147 pll = NV_RD32(par->PMC, 0x4020);
148 P = (pll >> 16) & 0x03; 148 P = (pll >> 16) & 0x07;
149 pll = NV_RD32(par->PMC, 0x4024); 149 pll = NV_RD32(par->PMC, 0x4024);
150 M = pll & 0xFF; 150 M = pll & 0xFF;
151 N = (pll >> 8) & 0xFF; 151 N = (pll >> 8) & 0xFF;
152 MB = (pll >> 16) & 0xFF; 152 if (((par->Chipset & 0xfff0) == 0x0290) ||
153 NB = (pll >> 24) & 0xFF; 153 ((par->Chipset & 0xfff0) == 0x0390)) {
154 MB = 1;
155 NB = 1;
156 } else {
157 MB = (pll >> 16) & 0xFF;
158 NB = (pll >> 24) & 0xFF;
159 }
154 *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P; 160 *MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
155 161
156 pll = NV_RD32(par->PMC, 0x4000); 162 pll = NV_RD32(par->PMC, 0x4000);
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index 19eef3a09023..8454adf2d178 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -147,15 +147,15 @@ void nvidia_create_i2c_busses(struct nvidia_par *par)
147void nvidia_delete_i2c_busses(struct nvidia_par *par) 147void nvidia_delete_i2c_busses(struct nvidia_par *par)
148{ 148{
149 if (par->chan[0].par) 149 if (par->chan[0].par)
150 i2c_bit_del_bus(&par->chan[0].adapter); 150 i2c_del_adapter(&par->chan[0].adapter);
151 par->chan[0].par = NULL; 151 par->chan[0].par = NULL;
152 152
153 if (par->chan[1].par) 153 if (par->chan[1].par)
154 i2c_bit_del_bus(&par->chan[1].adapter); 154 i2c_del_adapter(&par->chan[1].adapter);
155 par->chan[1].par = NULL; 155 par->chan[1].par = NULL;
156 156
157 if (par->chan[2].par) 157 if (par->chan[2].par)
158 i2c_bit_del_bus(&par->chan[2].adapter); 158 i2c_del_adapter(&par->chan[2].adapter);
159 par->chan[2].par = NULL; 159 par->chan[2].par = NULL;
160 160
161} 161}
@@ -210,11 +210,8 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
210 /* try to get from firmware */ 210 /* try to get from firmware */
211 const u8 *e = fb_firmware_edid(info->device); 211 const u8 *e = fb_firmware_edid(info->device);
212 212
213 if (e != NULL) { 213 if (e != NULL)
214 edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 214 edid = kmemdup(e, EDID_LENGTH, GFP_KERNEL);
215 if (edid)
216 memcpy(edid, e, EDID_LENGTH);
217 }
218 } 215 }
219 216
220 *out_edid = edid; 217 *out_edid = edid;
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index 4243d7fae972..e009d242ea10 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -96,13 +96,16 @@
96#define READ_GET(par) (NV_RD32(&(par)->FIFO[0x0011], 0) >> 2) 96#define READ_GET(par) (NV_RD32(&(par)->FIFO[0x0011], 0) >> 2)
97 97
98#ifdef __LITTLE_ENDIAN 98#ifdef __LITTLE_ENDIAN
99
100#include <linux/bitrev.h>
101
99#define reverse_order(l) \ 102#define reverse_order(l) \
100do { \ 103do { \
101 u8 *a = (u8 *)(l); \ 104 u8 *a = (u8 *)(l); \
102 *a = byte_rev[*a], a++; \ 105 a[0] = bitrev8(a[0]); \
103 *a = byte_rev[*a], a++; \ 106 a[1] = bitrev8(a[1]); \
104 *a = byte_rev[*a], a++; \ 107 a[2] = bitrev8(a[2]); \
105 *a = byte_rev[*a]; \ 108 a[3] = bitrev8(a[3]); \
106} while(0) 109} while(0)
107#else 110#else
108#define reverse_order(l) do { } while(0) 111#define reverse_order(l) do { } while(0)
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index d9af88c2b580..181875fe35c6 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -72,10 +72,9 @@ int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
72 } 72 }
73 } 73 }
74 if (pedid) { 74 if (pedid) {
75 *out_edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 75 *out_edid = kmemdup(pedid, EDID_LENGTH, GFP_KERNEL);
76 if (*out_edid == NULL) 76 if (*out_edid == NULL)
77 return -1; 77 return -1;
78 memcpy(*out_edid, pedid, EDID_LENGTH);
79 printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn); 78 printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn);
80 return 0; 79 return 0;
81 } 80 }
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index 861271017655..43058d0cf5b7 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -62,7 +62,6 @@ extern void nvidiafb_fillrect(struct fb_info *info,
62extern void nvidiafb_imageblit(struct fb_info *info, 62extern void nvidiafb_imageblit(struct fb_info *info,
63 const struct fb_image *image); 63 const struct fb_image *image);
64extern int nvidiafb_sync(struct fb_info *info); 64extern int nvidiafb_sync(struct fb_info *info);
65extern u8 byte_rev[256];
66 65
67/* in nv_backlight.h */ 66/* in nv_backlight.h */
68#ifdef CONFIG_FB_NVIDIA_BACKLIGHT 67#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index a18a9aebf05f..eab3e282a4de 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -262,7 +262,7 @@ static void nv10GetConfig(struct nvidia_par *par)
262#endif 262#endif
263 263
264 dev = pci_find_slot(0, 1); 264 dev = pci_find_slot(0, 1);
265 if ((par->Chipset && 0xffff) == 0x01a0) { 265 if ((par->Chipset & 0xffff) == 0x01a0) {
266 int amt = 0; 266 int amt = 0;
267 267
268 pci_read_config_dword(dev, 0x7c, &amt); 268 pci_read_config_dword(dev, 0x7c, &amt);
@@ -359,6 +359,7 @@ int NVCommonSetup(struct fb_info *info)
359 case 0x0186: 359 case 0x0186:
360 case 0x0187: 360 case 0x0187:
361 case 0x018D: 361 case 0x018D:
362 case 0x0228:
362 case 0x0286: 363 case 0x0286:
363 case 0x028C: 364 case 0x028C:
364 case 0x0316: 365 case 0x0316:
@@ -382,6 +383,10 @@ int NVCommonSetup(struct fb_info *info)
382 case 0x034C: 383 case 0x034C:
383 case 0x0160: 384 case 0x0160:
384 case 0x0166: 385 case 0x0166:
386 case 0x0169:
387 case 0x016B:
388 case 0x016C:
389 case 0x016D:
385 case 0x00C8: 390 case 0x00C8:
386 case 0x00CC: 391 case 0x00CC:
387 case 0x0144: 392 case 0x0144:
@@ -639,12 +644,23 @@ int NVCommonSetup(struct fb_info *info)
639 par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1; 644 par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1;
640 par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033; 645 par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033;
641 646
642 printk("Panel size is %i x %i\n", par->fpWidth, par->fpHeight); 647 printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth, par->fpHeight);
643 } 648 }
644 649
645 if (monA) 650 if (monA)
646 info->monspecs = *monA; 651 info->monspecs = *monA;
647 652
653 if (!par->FlatPanel || !par->twoHeads)
654 par->FPDither = 0;
655
656 par->LVDS = 0;
657 if (par->FlatPanel && par->twoHeads) {
658 NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004);
659 if (par->PRAMDAC0[0x08b4] & 1)
660 par->LVDS = 1;
661 printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS");
662 }
663
648 kfree(edidA); 664 kfree(edidA);
649 kfree(edidB); 665 kfree(edidB);
650done: 666done:
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index acdc26693402..86e65dea60d3 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -129,6 +129,7 @@ struct nvidia_par {
129 int fpHeight; 129 int fpHeight;
130 int PanelTweak; 130 int PanelTweak;
131 int paneltweak; 131 int paneltweak;
132 int LVDS;
132 int pm_state; 133 int pm_state;
133 u32 crtcSync_read; 134 u32 crtcSync_read;
134 u32 fpSyncs; 135 u32 fpSyncs;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index eb24107bcc81..538e947610e1 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1160,20 +1160,20 @@ static u32 __devinit nvidia_get_arch(struct fb_info *info)
1160 case 0x0340: /* GeForceFX 5700 */ 1160 case 0x0340: /* GeForceFX 5700 */
1161 arch = NV_ARCH_30; 1161 arch = NV_ARCH_30;
1162 break; 1162 break;
1163 case 0x0040: 1163 case 0x0040: /* GeForce 6800 */
1164 case 0x00C0: 1164 case 0x00C0: /* GeForce 6800 */
1165 case 0x0120: 1165 case 0x0120: /* GeForce 6800 */
1166 case 0x0130: 1166 case 0x0130:
1167 case 0x0140: 1167 case 0x0140: /* GeForce 6600 */
1168 case 0x0160: 1168 case 0x0160: /* GeForce 6200 */
1169 case 0x01D0: 1169 case 0x01D0: /* GeForce 7200, 7300, 7400 */
1170 case 0x0090: 1170 case 0x0090: /* GeForce 7800 */
1171 case 0x0210: 1171 case 0x0210: /* GeForce 6800 */
1172 case 0x0220: 1172 case 0x0220: /* GeForce 6200 */
1173 case 0x0230: 1173 case 0x0230:
1174 case 0x0240: 1174 case 0x0240: /* GeForce 6100 */
1175 case 0x0290: 1175 case 0x0290: /* GeForce 7900 */
1176 case 0x0390: 1176 case 0x0390: /* GeForce 7600 */
1177 arch = NV_ARCH_40; 1177 arch = NV_ARCH_40;
1178 break; 1178 break;
1179 case 0x0020: /* TNT, TNT2 */ 1179 case 0x0020: /* TNT, TNT2 */
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index bad0e98fb3b6..9576a55eaf16 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -157,7 +157,7 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
157 out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue)); 157 out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
158 break; 158 break;
159 case cmap_gxt2000: 159 case cmap_gxt2000:
160 out_le32((unsigned __iomem *) par->cmap_adr + regno, 160 out_le32(((unsigned __iomem *) par->cmap_adr) + regno,
161 (red << 16 | green << 8 | blue)); 161 (red << 16 | green << 8 | blue));
162 break; 162 break;
163 } 163 }
@@ -213,7 +213,7 @@ static int offb_blank(int blank, struct fb_info *info)
213 out_le32(par->cmap_adr + 0xb4, 0); 213 out_le32(par->cmap_adr + 0xb4, 0);
214 break; 214 break;
215 case cmap_gxt2000: 215 case cmap_gxt2000:
216 out_le32((unsigned __iomem *) par->cmap_adr + i, 216 out_le32(((unsigned __iomem *) par->cmap_adr) + i,
217 0); 217 0);
218 break; 218 break;
219 } 219 }
@@ -226,13 +226,23 @@ static int offb_blank(int blank, struct fb_info *info)
226static void __iomem *offb_map_reg(struct device_node *np, int index, 226static void __iomem *offb_map_reg(struct device_node *np, int index,
227 unsigned long offset, unsigned long size) 227 unsigned long offset, unsigned long size)
228{ 228{
229 struct resource r; 229 const u32 *addrp;
230 230 u64 asize, taddr;
231 if (of_address_to_resource(np, index, &r)) 231 unsigned int flags;
232 return 0; 232
233 if ((r.start + offset + size) > r.end) 233 addrp = of_get_pci_address(np, index, &asize, &flags);
234 return 0; 234 if (addrp == NULL)
235 return ioremap(r.start + offset, size); 235 addrp = of_get_address(np, index, &asize, &flags);
236 if (addrp == NULL)
237 return NULL;
238 if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
239 return NULL;
240 if ((offset + size) > asize)
241 return NULL;
242 taddr = of_translate_address(np, addrp);
243 if (taddr == OF_BAD_ADDR)
244 return NULL;
245 return ioremap(taddr + offset, size);
236} 246}
237 247
238static void __init offb_init_fb(const char *name, const char *full_name, 248static void __init offb_init_fb(const char *name, const char *full_name,
@@ -289,7 +299,6 @@ static void __init offb_init_fb(const char *name, const char *full_name,
289 299
290 par->cmap_type = cmap_unknown; 300 par->cmap_type = cmap_unknown;
291 if (depth == 8) { 301 if (depth == 8) {
292 /* Palette hacks disabled for now */
293 if (dp && !strncmp(name, "ATY,Rage128", 11)) { 302 if (dp && !strncmp(name, "ATY,Rage128", 11)) {
294 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); 303 par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
295 if (par->cmap_adr) 304 if (par->cmap_adr)
@@ -313,7 +322,8 @@ static void __init offb_init_fb(const char *name, const char *full_name,
313 ioremap(base + 0x7ff000, 0x1000) + 0xcc0; 322 ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
314 par->cmap_data = par->cmap_adr + 1; 323 par->cmap_data = par->cmap_adr + 1;
315 par->cmap_type = cmap_m64; 324 par->cmap_type = cmap_m64;
316 } else if (dp && device_is_compatible(dp, "pci1014,b7")) { 325 } else if (dp && (device_is_compatible(dp, "pci1014,b7") ||
326 device_is_compatible(dp, "pci1014,21c"))) {
317 par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000); 327 par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
318 if (par->cmap_adr) 328 if (par->cmap_adr)
319 par->cmap_type = cmap_gxt2000; 329 par->cmap_type = cmap_gxt2000;
@@ -392,6 +402,9 @@ static void __init offb_init_fb(const char *name, const char *full_name,
392 fb_alloc_cmap(&info->cmap, 256, 0); 402 fb_alloc_cmap(&info->cmap, 256, 0);
393 403
394 if (register_framebuffer(info) < 0) { 404 if (register_framebuffer(info) < 0) {
405 iounmap(par->cmap_adr);
406 par->cmap_adr = NULL;
407 iounmap(info->screen_base);
395 kfree(info); 408 kfree(info);
396 release_mem_region(res_start, res_size); 409 release_mem_region(res_start, res_size);
397 return; 410 return;
@@ -433,7 +446,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
433 pp = get_property(dp, "linux,bootx-linebytes", &len); 446 pp = get_property(dp, "linux,bootx-linebytes", &len);
434 if (pp == NULL) 447 if (pp == NULL)
435 pp = get_property(dp, "linebytes", &len); 448 pp = get_property(dp, "linebytes", &len);
436 if (pp && len == sizeof(u32)) 449 if (pp && len == sizeof(u32) && (*pp != 0xffffffffu))
437 pitch = *pp; 450 pitch = *pp;
438 else 451 else
439 pitch = width * ((depth + 7) / 8); 452 pitch = width * ((depth + 7) / 8);
@@ -496,7 +509,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
496 offb_init_fb(no_real_node ? "bootx" : dp->name, 509 offb_init_fb(no_real_node ? "bootx" : dp->name,
497 no_real_node ? "display" : dp->full_name, 510 no_real_node ? "display" : dp->full_name,
498 width, height, depth, pitch, address, 511 width, height, depth, pitch, address,
499 no_real_node ? dp : NULL); 512 no_real_node ? NULL : dp);
500 } 513 }
501} 514}
502 515
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index fdb33cd21a27..233871655824 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -34,6 +34,7 @@
34#include <asm/prom.h> 34#include <asm/prom.h>
35#include <asm/pgtable.h> 35#include <asm/pgtable.h>
36#include <asm/of_device.h> 36#include <asm/of_device.h>
37#include <asm/of_platform.h>
37 38
38#include "macmodes.h" 39#include "macmodes.h"
39#include "platinumfb.h" 40#include "platinumfb.h"
@@ -626,6 +627,9 @@ static int __devinit platinumfb_probe(struct of_device* odev,
626 627
627 rc = platinum_init_fb(info); 628 rc = platinum_init_fb(info);
628 if (rc != 0) { 629 if (rc != 0) {
630 iounmap(pinfo->frame_buffer);
631 iounmap(pinfo->platinum_regs);
632 iounmap(pinfo->cmap_regs);
629 dev_set_drvdata(&odev->dev, NULL); 633 dev_set_drvdata(&odev->dev, NULL);
630 framebuffer_release(info); 634 framebuffer_release(info);
631 } 635 }
@@ -682,14 +686,14 @@ static int __init platinumfb_init(void)
682 return -ENODEV; 686 return -ENODEV;
683 platinumfb_setup(option); 687 platinumfb_setup(option);
684#endif 688#endif
685 of_register_driver(&platinum_driver); 689 of_register_platform_driver(&platinum_driver);
686 690
687 return 0; 691 return 0;
688} 692}
689 693
690static void __exit platinumfb_exit(void) 694static void __exit platinumfb_exit(void)
691{ 695{
692 of_unregister_driver(&platinum_driver); 696 of_unregister_platform_driver(&platinum_driver);
693} 697}
694 698
695MODULE_LICENSE("GPL"); 699MODULE_LICENSE("GPL");
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 73e2d7d16608..a06a064ad757 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -186,7 +186,7 @@ static void __init pmagbbfb_screen_setup(struct fb_info *info)
186static void __init pmagbbfb_osc_setup(struct fb_info *info) 186static void __init pmagbbfb_osc_setup(struct fb_info *info)
187{ 187{
188 static unsigned int pmagbbfb_freqs[] __initdata = { 188 static unsigned int pmagbbfb_freqs[] __initdata = {
189 130808, 119843, 104000, 92980, 74367, 72800, 189 130808, 119843, 104000, 92980, 74370, 72800,
190 69197, 66000, 65000, 50350, 36000, 32000, 25175 190 69197, 66000, 65000, 50350, 36000, 32000, 25175
191 }; 191 };
192 struct pmagbbfb_par *par = info->par; 192 struct pmagbbfb_par *par = info->par;
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
index 7d9453c91a42..f29e66e2d774 100644
--- a/drivers/video/pnx4008/pnxrgbfb.c
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -154,7 +154,8 @@ static int __devinit rgbfb_probe(struct platform_device *pdev)
154 goto err1; 154 goto err1;
155 } 155 }
156 156
157 if (!fb_get_options("pnxrgbfb", &option) && !strcmp(option, "nocursor")) 157 if (!fb_get_options("pnxrgbfb", &option) && option &&
158 !strcmp(option, "nocursor"))
158 rgbfb_ops.fb_cursor = no_cursor; 159 rgbfb_ops.fb_cursor = no_cursor;
159 160
160 info->node = -1; 161 info->node = -1;
@@ -191,7 +192,7 @@ err:
191 192
192static struct platform_driver rgbfb_driver = { 193static struct platform_driver rgbfb_driver = {
193 .driver = { 194 .driver = {
194 .name = "rgbfb", 195 .name = "pnx4008-rgbfb",
195 }, 196 },
196 .probe = rgbfb_probe, 197 .probe = rgbfb_probe,
197 .remove = rgbfb_remove, 198 .remove = rgbfb_remove,
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c
index 51f0ecc2a511..d23bf0d659b6 100644
--- a/drivers/video/pnx4008/sdum.c
+++ b/drivers/video/pnx4008/sdum.c
@@ -848,7 +848,7 @@ static int sdum_remove(struct platform_device *pdev)
848 848
849static struct platform_driver sdum_driver = { 849static struct platform_driver sdum_driver = {
850 .driver = { 850 .driver = {
851 .name = "sdum", 851 .name = "pnx4008-sdum",
852 }, 852 },
853 .probe = sdum_probe, 853 .probe = sdum_probe,
854 .remove = sdum_remove, 854 .remove = sdum_remove,
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index c7bc80921f16..a93618bc9d27 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -905,6 +905,15 @@ static int __init pvr2fb_dc_init(void)
905 905
906static void pvr2fb_dc_exit(void) 906static void pvr2fb_dc_exit(void)
907{ 907{
908 if (fb_info->screen_base) {
909 iounmap(fb_info->screen_base);
910 fb_info->screen_base = NULL;
911 }
912 if (currentpar->mmio_base) {
913 iounmap((void *)currentpar->mmio_base);
914 currentpar->mmio_base = 0;
915 }
916
908 free_irq(HW_EVENT_VSYNC, 0); 917 free_irq(HW_EVENT_VSYNC, 0);
909#ifdef CONFIG_SH_DMA 918#ifdef CONFIG_SH_DMA
910 free_dma(pvr2dma); 919 free_dma(pvr2dma);
@@ -946,6 +955,15 @@ static int __devinit pvr2fb_pci_probe(struct pci_dev *pdev,
946 955
947static void __devexit pvr2fb_pci_remove(struct pci_dev *pdev) 956static void __devexit pvr2fb_pci_remove(struct pci_dev *pdev)
948{ 957{
958 if (fb_info->screen_base) {
959 iounmap(fb_info->screen_base);
960 fb_info->screen_base = NULL;
961 }
962 if (currentpar->mmio_base) {
963 iounmap((void *)currentpar->mmio_base);
964 currentpar->mmio_base = 0;
965 }
966
949 pci_release_regions(pdev); 967 pci_release_regions(pdev);
950} 968}
951 969
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 8a8ae55a7403..38eb0b69c2d7 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -964,9 +964,10 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
964 * Our LCD controller task (which is called when we blank or unblank) 964 * Our LCD controller task (which is called when we blank or unblank)
965 * via keventd. 965 * via keventd.
966 */ 966 */
967static void pxafb_task(void *dummy) 967static void pxafb_task(struct work_struct *work)
968{ 968{
969 struct pxafb_info *fbi = dummy; 969 struct pxafb_info *fbi =
970 container_of(work, struct pxafb_info, task);
970 u_int state = xchg(&fbi->task_state, -1); 971 u_int state = xchg(&fbi->task_state, -1);
971 972
972 set_ctrlr_state(fbi, state); 973 set_ctrlr_state(fbi, state);
@@ -1159,7 +1160,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
1159 } 1160 }
1160 1161
1161 init_waitqueue_head(&fbi->ctrlr_wait); 1162 init_waitqueue_head(&fbi->ctrlr_wait);
1162 INIT_WORK(&fbi->task, pxafb_task, fbi); 1163 INIT_WORK(&fbi->task, pxafb_task);
1163 init_MUTEX(&fbi->ctrlr_sem); 1164 init_MUTEX(&fbi->ctrlr_sem);
1164 1165
1165 return fbi; 1166 return fbi;
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
index cf41ff177644..bc7ffc84e185 100644
--- a/drivers/video/retz3fb.c
+++ b/drivers/video/retz3fb.c
@@ -1423,8 +1423,10 @@ int __init retz3fb_init(void)
1423 1423
1424 do_install_cmap(0, fb_info); 1424 do_install_cmap(0, fb_info);
1425 1425
1426 if (register_framebuffer(fb_info) < 0) 1426 if (register_framebuffer(fb_info) < 0) {
1427 iounmap(zinfo->base);
1427 return -EINVAL; 1428 return -EINVAL;
1429 }
1428 1430
1429 printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of " 1431 printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of "
1430 "video memory\n", fb_info->node, 1432 "video memory\n", fb_info->node,
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index a160c4de2ca2..1a13966b7d5b 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -40,6 +40,7 @@
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/pci.h> 41#include <linux/pci.h>
42#include <linux/backlight.h> 42#include <linux/backlight.h>
43#include <linux/bitrev.h>
43#ifdef CONFIG_MTRR 44#ifdef CONFIG_MTRR
44#include <asm/mtrr.h> 45#include <asm/mtrr.h>
45#endif 46#endif
@@ -521,48 +522,13 @@ static inline unsigned char MISCin(struct riva_par *par)
521 return (VGA_RD08(par->riva.PVIO, 0x3cc)); 522 return (VGA_RD08(par->riva.PVIO, 0x3cc));
522} 523}
523 524
524static u8 byte_rev[256] = {
525 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
526 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
527 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
528 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
529 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
530 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
531 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
532 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
533 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
534 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
535 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
536 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
537 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
538 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
539 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
540 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
541 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
542 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
543 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
544 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
545 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
546 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
547 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
548 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
549 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
550 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
551 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
552 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
553 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
554 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
555 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
556 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
557};
558
559static inline void reverse_order(u32 *l) 525static inline void reverse_order(u32 *l)
560{ 526{
561 u8 *a = (u8 *)l; 527 u8 *a = (u8 *)l;
562 *a = byte_rev[*a], a++; 528 a[0] = bitrev8(a[0]);
563 *a = byte_rev[*a], a++; 529 a[1] = bitrev8(a[1]);
564 *a = byte_rev[*a], a++; 530 a[2] = bitrev8(a[2]);
565 *a = byte_rev[*a]; 531 a[3] = bitrev8(a[3]);
566} 532}
567 533
568/* ------------------------------------------------------------------------- * 534/* ------------------------------------------------------------------------- *
@@ -774,11 +740,12 @@ static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
774 * CALLED FROM: 740 * CALLED FROM:
775 * rivafb_set_par() 741 * rivafb_set_par()
776 */ 742 */
777static void riva_load_video_mode(struct fb_info *info) 743static int riva_load_video_mode(struct fb_info *info)
778{ 744{
779 int bpp, width, hDisplaySize, hDisplay, hStart, 745 int bpp, width, hDisplaySize, hDisplay, hStart,
780 hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock; 746 hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
781 int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd; 747 int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
748 int rc;
782 struct riva_par *par = info->par; 749 struct riva_par *par = info->par;
783 struct riva_regs newmode; 750 struct riva_regs newmode;
784 751
@@ -884,8 +851,10 @@ static void riva_load_video_mode(struct fb_info *info)
884 else 851 else
885 newmode.misc_output |= 0x80; 852 newmode.misc_output |= 0x80;
886 853
887 par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width, 854 rc = CalcStateExt(&par->riva, &newmode.ext, bpp, width,
888 hDisplaySize, height, dotClock); 855 hDisplaySize, height, dotClock);
856 if (rc)
857 goto out;
889 858
890 newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) & 859 newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) &
891 0xfff000ff; 860 0xfff000ff;
@@ -917,8 +886,12 @@ static void riva_load_video_mode(struct fb_info *info)
917 par->current_state = newmode; 886 par->current_state = newmode;
918 riva_load_state(par, &par->current_state); 887 riva_load_state(par, &par->current_state);
919 par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */ 888 par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
889
890out:
920 rivafb_blank(FB_BLANK_UNBLANK, info); 891 rivafb_blank(FB_BLANK_UNBLANK, info);
921 NVTRACE_LEAVE(); 892 NVTRACE_LEAVE();
893
894 return rc;
922} 895}
923 896
924static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb) 897static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
@@ -1286,12 +1259,15 @@ static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1286static int rivafb_set_par(struct fb_info *info) 1259static int rivafb_set_par(struct fb_info *info)
1287{ 1260{
1288 struct riva_par *par = info->par; 1261 struct riva_par *par = info->par;
1262 int rc = 0;
1289 1263
1290 NVTRACE_ENTER(); 1264 NVTRACE_ENTER();
1291 /* vgaHWunlock() + riva unlock (0x7F) */ 1265 /* vgaHWunlock() + riva unlock (0x7F) */
1292 CRTCout(par, 0x11, 0xFF); 1266 CRTCout(par, 0x11, 0xFF);
1293 par->riva.LockUnlock(&par->riva, 0); 1267 par->riva.LockUnlock(&par->riva, 0);
1294 riva_load_video_mode(info); 1268 rc = riva_load_video_mode(info);
1269 if (rc)
1270 goto out;
1295 if(!(info->flags & FBINFO_HWACCEL_DISABLED)) 1271 if(!(info->flags & FBINFO_HWACCEL_DISABLED))
1296 riva_setup_accel(info); 1272 riva_setup_accel(info);
1297 1273
@@ -1304,8 +1280,10 @@ static int rivafb_set_par(struct fb_info *info)
1304 info->pixmap.scan_align = 1; 1280 info->pixmap.scan_align = 1;
1305 else 1281 else
1306 info->pixmap.scan_align = 4; 1282 info->pixmap.scan_align = 4;
1283
1284out:
1307 NVTRACE_LEAVE(); 1285 NVTRACE_LEAVE();
1308 return 0; 1286 return rc;
1309} 1287}
1310 1288
1311/** 1289/**
diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c
index b6f8690b96c9..e0b8c521cc9c 100644
--- a/drivers/video/riva/riva_hw.c
+++ b/drivers/video/riva/riva_hw.c
@@ -1227,7 +1227,7 @@ static int CalcVClock
1227 * Calculate extended mode parameters (SVGA) and save in a 1227 * Calculate extended mode parameters (SVGA) and save in a
1228 * mode state structure. 1228 * mode state structure.
1229 */ 1229 */
1230static void CalcStateExt 1230int CalcStateExt
1231( 1231(
1232 RIVA_HW_INST *chip, 1232 RIVA_HW_INST *chip,
1233 RIVA_HW_STATE *state, 1233 RIVA_HW_STATE *state,
@@ -1249,7 +1249,8 @@ static void CalcStateExt
1249 * Extended RIVA registers. 1249 * Extended RIVA registers.
1250 */ 1250 */
1251 pixelDepth = (bpp + 1)/8; 1251 pixelDepth = (bpp + 1)/8;
1252 CalcVClock(dotClock, &VClk, &m, &n, &p, chip); 1252 if (!CalcVClock(dotClock, &VClk, &m, &n, &p, chip))
1253 return -EINVAL;
1253 1254
1254 switch (chip->Architecture) 1255 switch (chip->Architecture)
1255 { 1256 {
@@ -1327,6 +1328,8 @@ static void CalcStateExt
1327 state->pitch1 = 1328 state->pitch1 =
1328 state->pitch2 = 1329 state->pitch2 =
1329 state->pitch3 = pixelDepth * width; 1330 state->pitch3 = pixelDepth * width;
1331
1332 return 0;
1330} 1333}
1331/* 1334/*
1332 * Load fixed function state and pre-calculated/stored state. 1335 * Load fixed function state and pre-calculated/stored state.
@@ -2026,7 +2029,6 @@ static void nv3GetConfig
2026 */ 2029 */
2027 chip->Busy = nv3Busy; 2030 chip->Busy = nv3Busy;
2028 chip->ShowHideCursor = ShowHideCursor; 2031 chip->ShowHideCursor = ShowHideCursor;
2029 chip->CalcStateExt = CalcStateExt;
2030 chip->LoadStateExt = LoadStateExt; 2032 chip->LoadStateExt = LoadStateExt;
2031 chip->UnloadStateExt = UnloadStateExt; 2033 chip->UnloadStateExt = UnloadStateExt;
2032 chip->SetStartAddress = SetStartAddress3; 2034 chip->SetStartAddress = SetStartAddress3;
@@ -2084,7 +2086,6 @@ static void nv4GetConfig
2084 */ 2086 */
2085 chip->Busy = nv4Busy; 2087 chip->Busy = nv4Busy;
2086 chip->ShowHideCursor = ShowHideCursor; 2088 chip->ShowHideCursor = ShowHideCursor;
2087 chip->CalcStateExt = CalcStateExt;
2088 chip->LoadStateExt = LoadStateExt; 2089 chip->LoadStateExt = LoadStateExt;
2089 chip->UnloadStateExt = UnloadStateExt; 2090 chip->UnloadStateExt = UnloadStateExt;
2090 chip->SetStartAddress = SetStartAddress; 2091 chip->SetStartAddress = SetStartAddress;
@@ -2186,7 +2187,6 @@ static void nv10GetConfig
2186 */ 2187 */
2187 chip->Busy = nv10Busy; 2188 chip->Busy = nv10Busy;
2188 chip->ShowHideCursor = ShowHideCursor; 2189 chip->ShowHideCursor = ShowHideCursor;
2189 chip->CalcStateExt = CalcStateExt;
2190 chip->LoadStateExt = LoadStateExt; 2190 chip->LoadStateExt = LoadStateExt;
2191 chip->UnloadStateExt = UnloadStateExt; 2191 chip->UnloadStateExt = UnloadStateExt;
2192 chip->SetStartAddress = SetStartAddress; 2192 chip->SetStartAddress = SetStartAddress;
diff --git a/drivers/video/riva/riva_hw.h b/drivers/video/riva/riva_hw.h
index a1e71a626df2..c2769f73e0b2 100644
--- a/drivers/video/riva/riva_hw.h
+++ b/drivers/video/riva/riva_hw.h
@@ -463,7 +463,6 @@ typedef struct _riva_hw_inst
463 * Common chip functions. 463 * Common chip functions.
464 */ 464 */
465 int (*Busy)(struct _riva_hw_inst *); 465 int (*Busy)(struct _riva_hw_inst *);
466 void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int);
467 void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *); 466 void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
468 void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *); 467 void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
469 void (*SetStartAddress)(struct _riva_hw_inst *,U032); 468 void (*SetStartAddress)(struct _riva_hw_inst *,U032);
@@ -528,6 +527,22 @@ typedef struct _riva_hw_state
528 U032 pitch2; 527 U032 pitch2;
529 U032 pitch3; 528 U032 pitch3;
530} RIVA_HW_STATE; 529} RIVA_HW_STATE;
530
531/*
532 * function prototypes
533 */
534
535extern int CalcStateExt
536(
537 RIVA_HW_INST *chip,
538 RIVA_HW_STATE *state,
539 int bpp,
540 int width,
541 int hDisplaySize,
542 int height,
543 int dotClock
544);
545
531/* 546/*
532 * External routines. 547 * External routines.
533 */ 548 */
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c
index c15b259af644..01b85e3b0ae1 100644
--- a/drivers/video/riva/rivafb-i2c.c
+++ b/drivers/video/riva/rivafb-i2c.c
@@ -144,15 +144,15 @@ void riva_create_i2c_busses(struct riva_par *par)
144void riva_delete_i2c_busses(struct riva_par *par) 144void riva_delete_i2c_busses(struct riva_par *par)
145{ 145{
146 if (par->chan[0].par) 146 if (par->chan[0].par)
147 i2c_bit_del_bus(&par->chan[0].adapter); 147 i2c_del_adapter(&par->chan[0].adapter);
148 par->chan[0].par = NULL; 148 par->chan[0].par = NULL;
149 149
150 if (par->chan[1].par) 150 if (par->chan[1].par)
151 i2c_bit_del_bus(&par->chan[1].adapter); 151 i2c_del_adapter(&par->chan[1].adapter);
152 par->chan[1].par = NULL; 152 par->chan[1].par = NULL;
153 153
154 if (par->chan[2].par) 154 if (par->chan[2].par)
155 i2c_bit_del_bus(&par->chan[2].adapter); 155 i2c_del_adapter(&par->chan[2].adapter);
156 par->chan[2].par = NULL; 156 par->chan[2].par = NULL;
157} 157}
158 158
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 59407343cc73..ccef56d0c157 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -131,7 +131,7 @@ static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi)
131 saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8; 131 saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8;
132 saddr2>>= 1; 132 saddr2>>= 1;
133 133
134 saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH(var->xres); 134 saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH((var->xres * var->bits_per_pixel / 16) & 0x3ff);
135 135
136 dprintk("LCDSADDR1 = 0x%08lx\n", saddr1); 136 dprintk("LCDSADDR1 = 0x%08lx\n", saddr1);
137 dprintk("LCDSADDR2 = 0x%08lx\n", saddr2); 137 dprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
@@ -199,28 +199,86 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
199 var->bits_per_pixel = fbi->mach_info->bpp.min; 199 var->bits_per_pixel = fbi->mach_info->bpp.min;
200 200
201 /* set r/g/b positions */ 201 /* set r/g/b positions */
202 switch (var->bits_per_pixel) {
203 case 1:
204 case 2:
205 case 4:
206 var->red.offset = 0;
207 var->red.length = var->bits_per_pixel;
208 var->green = var->red;
209 var->blue = var->red;
210 var->transp.offset = 0;
211 var->transp.length = 0;
212 break;
213 case 8:
214 if ( fbi->mach_info->type != S3C2410_LCDCON1_TFT ) {
215 /* 8 bpp 332 */
216 var->red.length = 3;
217 var->red.offset = 5;
218 var->green.length = 3;
219 var->green.offset = 2;
220 var->blue.length = 2;
221 var->blue.offset = 0;
222 var->transp.length = 0;
223 } else {
224 var->red.offset = 0;
225 var->red.length = var->bits_per_pixel;
226 var->green = var->red;
227 var->blue = var->red;
228 var->transp.offset = 0;
229 var->transp.length = 0;
230 }
231 break;
232 case 12:
233 /* 12 bpp 444 */
234 var->red.length = 4;
235 var->red.offset = 8;
236 var->green.length = 4;
237 var->green.offset = 4;
238 var->blue.length = 4;
239 var->blue.offset = 0;
240 var->transp.length = 0;
241 break;
242
243 default:
244 case 16:
245 if (fbi->regs.lcdcon5 & S3C2410_LCDCON5_FRM565 ) {
246 /* 16 bpp, 565 format */
247 var->red.offset = 11;
248 var->green.offset = 5;
249 var->blue.offset = 0;
250 var->red.length = 5;
251 var->green.length = 6;
252 var->blue.length = 5;
253 var->transp.length = 0;
254 } else {
255 /* 16 bpp, 5551 format */
256 var->red.offset = 11;
257 var->green.offset = 6;
258 var->blue.offset = 1;
259 var->red.length = 5;
260 var->green.length = 5;
261 var->blue.length = 5;
262 var->transp.length = 0;
263 }
264 break;
265 case 24:
266 /* 24 bpp 888 */
267 var->red.length = 8;
268 var->red.offset = 16;
269 var->green.length = 8;
270 var->green.offset = 8;
271 var->blue.length = 8;
272 var->blue.offset = 0;
273 var->transp.length = 0;
274 break;
202 275
203 if (var->bits_per_pixel == 16) {
204 var->red.offset = 11;
205 var->green.offset = 5;
206 var->blue.offset = 0;
207 var->red.length = 5;
208 var->green.length = 6;
209 var->blue.length = 5;
210 var->transp.length = 0;
211 } else {
212 var->red.length = var->bits_per_pixel;
213 var->red.offset = 0;
214 var->green.length = var->bits_per_pixel;
215 var->green.offset = 0;
216 var->blue.length = var->bits_per_pixel;
217 var->blue.offset = 0;
218 var->transp.length = 0;
219 }
220 276
277 }
221 return 0; 278 return 0;
222} 279}
223 280
281
224/* s3c2410fb_activate_var 282/* s3c2410fb_activate_var
225 * 283 *
226 * activate (set) the controller from the given framebuffer 284 * activate (set) the controller from the given framebuffer
@@ -230,29 +288,61 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
230static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi, 288static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
231 struct fb_var_screeninfo *var) 289 struct fb_var_screeninfo *var)
232{ 290{
291 int hs;
292
233 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK; 293 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK;
294 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_TFT;
234 295
235 dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres); 296 dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres);
236 dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres); 297 dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
237 dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel); 298 dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
238 299
239 switch (var->bits_per_pixel) { 300 fbi->regs.lcdcon1 |= fbi->mach_info->type;
240 case 1: 301
241 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP; 302 if (fbi->mach_info->type == S3C2410_LCDCON1_TFT)
242 break; 303 switch (var->bits_per_pixel) {
243 case 2: 304 case 1:
244 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP; 305 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
245 break; 306 break;
246 case 4: 307 case 2:
247 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP; 308 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
248 break; 309 break;
249 case 8: 310 case 4:
250 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP; 311 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
251 break; 312 break;
252 case 16: 313 case 8:
253 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP; 314 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
254 break; 315 break;
255 } 316 case 16:
317 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
318 break;
319
320 default:
321 /* invalid pixel depth */
322 dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
323 }
324 else
325 switch (var->bits_per_pixel) {
326 case 1:
327 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
328 break;
329 case 2:
330 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
331 break;
332 case 4:
333 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
334 break;
335 case 8:
336 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
337 break;
338 case 12:
339 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
340 break;
341
342 default:
343 /* invalid pixel depth */
344 dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
345 }
256 346
257 /* check to see if we need to update sync/borders */ 347 /* check to see if we need to update sync/borders */
258 348
@@ -283,15 +373,44 @@ static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
283 fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff); 373 fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff);
284 fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1); 374 fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1);
285 375
376 switch(fbi->mach_info->type) {
377 case S3C2410_LCDCON1_DSCAN4:
378 case S3C2410_LCDCON1_STN8:
379 hs = var->xres / 8;
380 break;
381 case S3C2410_LCDCON1_STN4:
382 hs = var->xres / 4;
383 break;
384 default:
385 case S3C2410_LCDCON1_TFT:
386 hs = var->xres;
387 break;
388
389 }
390
391 /* Special cases : STN color displays */
392 if ( ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN8BPP) \
393 || ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN12BPP) ) {
394 hs = hs * 3;
395 }
396
397
286 fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff); 398 fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff);
287 fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(var->xres - 1); 399 fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(hs - 1);
288 400
289 if (var->pixclock > 0) { 401 if (var->pixclock > 0) {
290 int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock); 402 int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock);
291 403
292 clkdiv = (clkdiv / 2) -1; 404 if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) {
293 if (clkdiv < 0) 405 clkdiv = (clkdiv / 2) -1;
294 clkdiv = 0; 406 if (clkdiv < 0)
407 clkdiv = 0;
408 }
409 else {
410 clkdiv = (clkdiv / 2);
411 if (clkdiv < 2)
412 clkdiv = 2;
413 }
295 414
296 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_CLKVAL(0x3ff); 415 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_CLKVAL(0x3ff);
297 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv); 416 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);
@@ -329,10 +448,18 @@ static int s3c2410fb_set_par(struct fb_info *info)
329 struct s3c2410fb_info *fbi = info->par; 448 struct s3c2410fb_info *fbi = info->par;
330 struct fb_var_screeninfo *var = &info->var; 449 struct fb_var_screeninfo *var = &info->var;
331 450
332 if (var->bits_per_pixel == 16) 451 switch (var->bits_per_pixel)
333 fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR; 452 {
334 else 453 case 16:
335 fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR; 454 fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR;
455 break;
456 case 1:
457 fbi->fb->fix.visual = FB_VISUAL_MONO01;
458 break;
459 default:
460 fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR;
461 break;
462 }
336 463
337 fbi->fb->fix.line_length = (var->width*var->bits_per_pixel)/8; 464 fbi->fb->fix.line_length = (var->width*var->bits_per_pixel)/8;
338 465
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 3f94223b7f0c..1411f3b6a009 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -208,7 +208,7 @@ void savagefb_delete_i2c_busses(struct fb_info *info)
208 struct savagefb_par *par = info->par; 208 struct savagefb_par *par = info->par;
209 209
210 if (par->chan.par) 210 if (par->chan.par)
211 i2c_bit_del_bus(&par->chan.adapter); 211 i2c_del_adapter(&par->chan.adapter);
212 212
213 par->chan.par = NULL; 213 par->chan.par = NULL;
214} 214}
@@ -227,11 +227,8 @@ int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid)
227 /* try to get from firmware */ 227 /* try to get from firmware */
228 const u8 *e = fb_firmware_edid(info->device); 228 const u8 *e = fb_firmware_edid(info->device);
229 229
230 if (e) { 230 if (e)
231 edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 231 edid = kmemdup(e, EDID_LENGTH, GFP_KERNEL);
232 if (edid)
233 memcpy(edid, e, EDID_LENGTH);
234 }
235 } 232 }
236 233
237 *out_edid = edid; 234 *out_edid = edid;
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
index f13faddc6181..47e1896cffeb 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/sis/init301.c
@@ -445,11 +445,8 @@ SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
445void 445void
446SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime) 446SiS_DDC2Delay(struct SiS_Private *SiS_Pr, unsigned int delaytime)
447{ 447{
448 unsigned int i, j; 448 while (delaytime-- > 0)
449 449 SiS_GetReg(SiS_Pr->SiS_P3c4, 0x05);
450 for(i = 0; i < delaytime; i++) {
451 j += SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
452 }
453} 450}
454 451
455#if defined(SIS300) || defined(SIS315H) 452#if defined(SIS300) || defined(SIS315H)
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 711cb11d6eb3..59cd1e750f30 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -21,6 +21,11 @@
21 * Remove never finished and bogus 24/32bit support 21 * Remove never finished and bogus 24/32bit support
22 * Clean up macro abuse 22 * Clean up macro abuse
23 * Minor tidying for format. 23 * Minor tidying for format.
24 * 12/2006 Helge Deller <deller@gmx.de>
25 * add /sys/class/graphics/fbX/vgapass sysfs-interface
26 * add module option "mode_option" to set initial screen mode
27 * use fbdev default videomode database
28 * remove debug functions from ioctl
24 */ 29 */
25 30
26/* 31/*
@@ -65,19 +70,10 @@
65 * 70 *
66 * sstfb specific ioctls: 71 * sstfb specific ioctls:
67 * toggle vga (0x46db) : toggle vga_pass_through 72 * toggle vga (0x46db) : toggle vga_pass_through
68 * fill fb (0x46dc) : fills fb
69 * test disp (0x46de) : draws a test image
70 */ 73 */
71 74
72#undef SST_DEBUG 75#undef SST_DEBUG
73 76
74/*
75 Default video mode .
76 0 800x600@60 took from glide
77 1 640x480@75 took from glide
78 2 1024x768@76 std fb.mode
79 3 640x480@60 glide default */
80#define DEFAULT_MODE 3
81 77
82/* 78/*
83 * Includes 79 * Includes
@@ -92,20 +88,24 @@
92#include <linux/init.h> 88#include <linux/init.h>
93#include <linux/slab.h> 89#include <linux/slab.h>
94#include <asm/io.h> 90#include <asm/io.h>
95#include <asm/ioctl.h>
96#include <asm/uaccess.h> 91#include <asm/uaccess.h>
97#include <video/sstfb.h> 92#include <video/sstfb.h>
98 93
99 94
100/* initialized by setup */ 95/* initialized by setup */
101 96
102static int vgapass; /* enable Vga passthrough cable */ 97static int vgapass; /* enable VGA passthrough cable */
103static int mem; /* mem size in MB, 0 = autodetect */ 98static int mem; /* mem size in MB, 0 = autodetect */
104static int clipping = 1; /* use clipping (slower, safer) */ 99static int clipping = 1; /* use clipping (slower, safer) */
105static int gfxclk; /* force FBI freq in Mhz . Dangerous */ 100static int gfxclk; /* force FBI freq in Mhz . Dangerous */
106static int slowpci; /* slow PCI settings */ 101static int slowpci; /* slow PCI settings */
107 102
108static char *mode_option __devinitdata; 103/*
104 Possible default video modes: 800x600@60, 640x480@75, 1024x768@76, 640x480@60
105*/
106#define DEFAULT_VIDEO_MODE "640x480@60"
107
108static char *mode_option __devinitdata = DEFAULT_VIDEO_MODE;
109 109
110enum { 110enum {
111 ID_VOODOO1 = 0, 111 ID_VOODOO1 = 0,
@@ -119,48 +119,11 @@ static struct sst_spec voodoo_spec[] __devinitdata = {
119 { .name = "Voodoo2", .default_gfx_clock = 75000, .max_gfxclk = 85 }, 119 { .name = "Voodoo2", .default_gfx_clock = 75000, .max_gfxclk = 85 },
120}; 120};
121 121
122static struct fb_var_screeninfo sstfb_default =
123#if ( DEFAULT_MODE == 0 )
124 { /* 800x600@60, 16 bpp .borowed from glide/sst1/include/sst1init.h */
125 800, 600, 800, 600, 0, 0, 16, 0,
126 {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
127 0, 0, -1, -1, 0,
128 25000, 86, 41, 23, 1, 127, 4,
129 0, FB_VMODE_NONINTERLACED };
130#elif ( DEFAULT_MODE == 1 )
131 {/* 640x480@75, 16 bpp .borowed from glide/sst1/include/sst1init.h */
132 640, 480, 640, 480, 0, 0, 16, 0,
133 {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
134 0, 0, -1, -1, 0,
135 31746, 118, 17, 16, 1, 63, 3,
136 0, FB_VMODE_NONINTERLACED };
137#elif ( DEFAULT_MODE == 2 )
138 { /* 1024x768@76 took from my /etc/fb.modes */
139 1024, 768, 1024, 768,0, 0, 16,0,
140 {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
141 0, 0, -1, -1, 0,
142 11764, 208, 8, 36, 16, 120, 3 ,
143 0, FB_VMODE_NONINTERLACED };
144#elif ( DEFAULT_MODE == 3 )
145 { /* 640x480@60 , 16bpp glide default ?*/
146 640, 480, 640, 480, 0, 0, 16, 0,
147 {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
148 0, 0, -1, -1, 0,
149 39721 , 38, 26 , 25 ,18 , 96 ,2,
150 0, FB_VMODE_NONINTERLACED };
151#elif
152 #error "Invalid DEFAULT_MODE value !"
153#endif
154
155 122
156/* 123/*
157 * debug functions 124 * debug functions
158 */ 125 */
159 126
160static void sstfb_drawdebugimage(struct fb_info *info);
161static int sstfb_dump_regs(struct fb_info *info);
162
163
164#if (SST_DEBUG_REG > 0) 127#if (SST_DEBUG_REG > 0)
165static void sst_dbg_print_read_reg(u32 reg, u32 val) { 128static void sst_dbg_print_read_reg(u32 reg, u32 val) {
166 const char *regname; 129 const char *regname;
@@ -726,51 +689,77 @@ static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
726 return 0; 689 return 0;
727} 690}
728 691
729static int sstfb_ioctl(struct fb_info *info, u_int cmd, u_long arg) 692static void sstfb_setvgapass( struct fb_info *info, int enable )
730{ 693{
731 struct sstfb_par *par = info->par; 694 struct sstfb_par *par = info->par;
732 struct pci_dev *sst_dev = par->dev; 695 struct pci_dev *sst_dev = par->dev;
733 u32 fbiinit0, tmp, val; 696 u32 fbiinit0, tmp;
734 u_long p; 697
698 enable = enable ? 1:0;
699 if (par->vgapass == enable)
700 return;
701 par->vgapass = enable;
702
703 pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
704 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
705 tmp | PCI_EN_INIT_WR );
706 fbiinit0 = sst_read (FBIINIT0);
707 if (par->vgapass) {
708 sst_write(FBIINIT0, fbiinit0 & ~DIS_VGA_PASSTHROUGH);
709 printk(KERN_INFO "fb%d: Enabling VGA pass-through\n", info->node );
710 } else {
711 sst_write(FBIINIT0, fbiinit0 | DIS_VGA_PASSTHROUGH);
712 printk(KERN_INFO "fb%d: Disabling VGA pass-through\n", info->node );
713 }
714 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
715}
716
717static ssize_t store_vgapass(struct device *device, struct device_attribute *attr,
718 const char *buf, size_t count)
719{
720 struct fb_info *info = dev_get_drvdata(device);
721 char ** last = NULL;
722 int val;
723
724 val = simple_strtoul(buf, last, 0);
725 sstfb_setvgapass(info, val);
726
727 return count;
728}
729
730static ssize_t show_vgapass(struct device *device, struct device_attribute *attr,
731 char *buf)
732{
733 struct fb_info *info = dev_get_drvdata(device);
734 struct sstfb_par *par = info->par;
735 return snprintf(buf, PAGE_SIZE, "%d\n", par->vgapass);
736}
737
738static struct device_attribute device_attrs[] = {
739 __ATTR(vgapass, S_IRUGO|S_IWUSR, show_vgapass, store_vgapass)
740 };
741
742static int sstfb_ioctl(struct fb_info *info, unsigned int cmd,
743 unsigned long arg)
744{
745 struct sstfb_par *par;
746 u32 val;
735 747
736 switch (cmd) { 748 switch (cmd) {
737 749 /* set/get VGA pass_through mode */
738 /* dump current FBIINIT values to system log */ 750 case SSTFB_SET_VGAPASS:
739 case _IO('F', 0xdb): /* 0x46db */
740 return sstfb_dump_regs(info);
741
742 /* fills lfb with #arg pixels */
743 case _IOW('F', 0xdc, u32): /* 0x46dc */
744 if (copy_from_user(&val, (void __user *)arg, sizeof(val))) 751 if (copy_from_user(&val, (void __user *)arg, sizeof(val)))
745 return -EFAULT; 752 return -EFAULT;
746 if (val > info->fix.smem_len) 753 sstfb_setvgapass(info, val);
747 val = info->fix.smem_len;
748 for (p = 0 ; p < val; p += 2)
749 writew(p >> 6, info->screen_base + p);
750 return 0; 754 return 0;
751 755 case SSTFB_GET_VGAPASS:
752 /* change VGA pass_through mode */ 756 par = info->par;
753 case _IOW('F', 0xdd, u32): /* 0x46dd */ 757 val = par->vgapass;
754 if (copy_from_user(&val, (void __user *)arg, sizeof(val))) 758 if (copy_to_user((void __user *)arg, &val, sizeof(val)))
755 return -EFAULT; 759 return -EFAULT;
756 pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
757 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
758 tmp | PCI_EN_INIT_WR );
759 fbiinit0 = sst_read (FBIINIT0);
760 if (val)
761 sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
762 else
763 sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);
764 pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
765 return 0;
766
767 /* draw test image */
768 case _IO('F', 0xde): /* 0x46de */
769 f_dprintk("test color display at %d bpp\n",
770 info->var.bits_per_pixel);
771 sstfb_drawdebugimage(info);
772 return 0; 760 return 0;
773 } 761 }
762
774 return -EINVAL; 763 return -EINVAL;
775} 764}
776 765
@@ -804,6 +793,7 @@ static void sstfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
804/* 793/*
805 * FillRect 2D command (solidfill or invert (via ROP_XOR)) - Voodoo2 only 794 * FillRect 2D command (solidfill or invert (via ROP_XOR)) - Voodoo2 only
806 */ 795 */
796#if 0
807static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 797static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
808{ 798{
809 struct sstfb_par *par = info->par; 799 struct sstfb_par *par = info->par;
@@ -825,6 +815,7 @@ static void sstfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
825 | (BLT_16BPP_FMT << 3) /* | BIT(14) */ | BIT(15) | BIT(16) ); 815 | (BLT_16BPP_FMT << 3) /* | BIT(14) */ | BIT(15) | BIT(16) );
826 sst_wait_idle(); 816 sst_wait_idle();
827} 817}
818#endif
828 819
829 820
830 821
@@ -1156,6 +1147,7 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
1156 struct pll_timing gfx_timings; 1147 struct pll_timing gfx_timings;
1157 struct sst_spec *spec; 1148 struct sst_spec *spec;
1158 int Fout; 1149 int Fout;
1150 int gfx_clock;
1159 1151
1160 spec = &voodoo_spec[par->type]; 1152 spec = &voodoo_spec[par->type];
1161 f_ddprintk(" fbiinit0 fbiinit1 fbiinit2 fbiinit3 fbiinit4 " 1153 f_ddprintk(" fbiinit0 fbiinit1 fbiinit2 fbiinit3 fbiinit4 "
@@ -1196,15 +1188,15 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
1196 } 1188 }
1197 1189
1198 /* set graphic clock */ 1190 /* set graphic clock */
1199 par->gfx_clock = spec->default_gfx_clock; 1191 gfx_clock = spec->default_gfx_clock;
1200 if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) { 1192 if ((gfxclk >10 ) && (gfxclk < spec->max_gfxclk)) {
1201 printk(KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk); 1193 printk(KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk);
1202 par->gfx_clock = gfxclk *1000; 1194 gfx_clock = gfxclk *1000;
1203 } else if (gfxclk) { 1195 } else if (gfxclk) {
1204 printk(KERN_WARNING "sstfb: %dMhz is way out of spec! Using default\n", gfxclk); 1196 printk(KERN_WARNING "sstfb: %dMhz is way out of spec! Using default\n", gfxclk);
1205 } 1197 }
1206 1198
1207 sst_calc_pll(par->gfx_clock, &Fout, &gfx_timings); 1199 sst_calc_pll(gfx_clock, &Fout, &gfx_timings);
1208 par->dac_sw.set_pll(info, &gfx_timings, GFX_CLOCK); 1200 par->dac_sw.set_pll(info, &gfx_timings, GFX_CLOCK);
1209 1201
1210 /* disable fbiinit remap */ 1202 /* disable fbiinit remap */
@@ -1215,10 +1207,11 @@ static int __devinit sst_init(struct fb_info *info, struct sstfb_par *par)
1215 fbiinit0 = FBIINIT0_DEFAULT; 1207 fbiinit0 = FBIINIT0_DEFAULT;
1216 fbiinit1 = FBIINIT1_DEFAULT; 1208 fbiinit1 = FBIINIT1_DEFAULT;
1217 fbiinit4 = FBIINIT4_DEFAULT; 1209 fbiinit4 = FBIINIT4_DEFAULT;
1218 if (vgapass) 1210 par->vgapass = vgapass;
1219 fbiinit0 &= ~EN_VGA_PASSTHROUGH; 1211 if (par->vgapass)
1212 fbiinit0 &= ~DIS_VGA_PASSTHROUGH;
1220 else 1213 else
1221 fbiinit0 |= EN_VGA_PASSTHROUGH; 1214 fbiinit0 |= DIS_VGA_PASSTHROUGH;
1222 if (slowpci) { 1215 if (slowpci) {
1223 fbiinit1 |= SLOW_PCI_WRITES; 1216 fbiinit1 |= SLOW_PCI_WRITES;
1224 fbiinit4 |= SLOW_PCI_READS; 1217 fbiinit4 |= SLOW_PCI_READS;
@@ -1267,7 +1260,7 @@ static void __devexit sst_shutdown(struct fb_info *info)
1267 /* TODO maybe shutdown the dac, vrefresh and so on... */ 1260 /* TODO maybe shutdown the dac, vrefresh and so on... */
1268 pci_write_config_dword(dev, PCI_INIT_ENABLE, 1261 pci_write_config_dword(dev, PCI_INIT_ENABLE,
1269 PCI_EN_INIT_WR); 1262 PCI_EN_INIT_WR);
1270 sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | EN_VGA_PASSTHROUGH); 1263 sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | DIS_VGA_PASSTHROUGH);
1271 pci_write_config_dword(dev, PCI_VCLK_DISABLE,0); 1264 pci_write_config_dword(dev, PCI_VCLK_DISABLE,0);
1272 /* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct 1265 /* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct
1273 * from start ? */ 1266 * from start ? */
@@ -1278,8 +1271,7 @@ static void __devexit sst_shutdown(struct fb_info *info)
1278/* 1271/*
1279 * Interface to the world 1272 * Interface to the world
1280 */ 1273 */
1281#ifndef MODULE 1274static int __devinit sstfb_setup(char *options)
1282static int __init sstfb_setup(char *options)
1283{ 1275{
1284 char *this_opt; 1276 char *this_opt;
1285 1277
@@ -1312,7 +1304,7 @@ static int __init sstfb_setup(char *options)
1312 } 1304 }
1313 return 0; 1305 return 0;
1314} 1306}
1315#endif 1307
1316 1308
1317static struct fb_ops sstfb_ops = { 1309static struct fb_ops sstfb_ops = {
1318 .owner = THIS_MODULE, 1310 .owner = THIS_MODULE,
@@ -1416,15 +1408,10 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
1416 */ 1408 */
1417 fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */ 1409 fix->line_length = 2048; /* default value, for 24 or 32bit: 4096 */
1418 1410
1419 if ( mode_option && 1411 fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16);
1420 fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 16)) {
1421 printk(KERN_ERR "sstfb: can't set supplied video mode. Using default\n");
1422 info->var = sstfb_default;
1423 } else
1424 info->var = sstfb_default;
1425 1412
1426 if (sstfb_check_var(&info->var, info)) { 1413 if (sstfb_check_var(&info->var, info)) {
1427 printk(KERN_ERR "sstfb: invalid default video mode.\n"); 1414 printk(KERN_ERR "sstfb: invalid video mode.\n");
1428 goto fail; 1415 goto fail;
1429 } 1416 }
1430 1417
@@ -1442,10 +1429,11 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
1442 goto fail; 1429 goto fail;
1443 } 1430 }
1444 1431
1445 if (1) /* set to 0 to see an initial bitmap instead */ 1432 sstfb_clear_screen(info);
1446 sstfb_clear_screen(info); 1433
1447 else 1434 if (device_create_file(info->dev, &device_attrs[0]))
1448 sstfb_drawdebugimage(info); 1435 printk(KERN_WARNING "sstfb: can't create sysfs entry.\n");
1436
1449 1437
1450 printk(KERN_INFO "fb%d: %s frame buffer device at 0x%p\n", 1438 printk(KERN_INFO "fb%d: %s frame buffer device at 0x%p\n",
1451 info->node, fix->id, info->screen_base); 1439 info->node, fix->id, info->screen_base);
@@ -1453,6 +1441,7 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
1453 return 0; 1441 return 0;
1454 1442
1455fail: 1443fail:
1444 fb_dealloc_cmap(&info->cmap);
1456 iounmap(info->screen_base); 1445 iounmap(info->screen_base);
1457fail_fb_remap: 1446fail_fb_remap:
1458 iounmap(par->mmio_vbase); 1447 iounmap(par->mmio_vbase);
@@ -1473,21 +1462,23 @@ static void __devexit sstfb_remove(struct pci_dev *pdev)
1473 info = pci_get_drvdata(pdev); 1462 info = pci_get_drvdata(pdev);
1474 par = info->par; 1463 par = info->par;
1475 1464
1465 device_remove_file(info->dev, &device_attrs[0]);
1476 sst_shutdown(info); 1466 sst_shutdown(info);
1477 unregister_framebuffer(info);
1478 iounmap(info->screen_base); 1467 iounmap(info->screen_base);
1479 iounmap(par->mmio_vbase); 1468 iounmap(par->mmio_vbase);
1480 release_mem_region(info->fix.smem_start, 0x400000); 1469 release_mem_region(info->fix.smem_start, 0x400000);
1481 release_mem_region(info->fix.mmio_start, info->fix.mmio_len); 1470 release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
1471 fb_dealloc_cmap(&info->cmap);
1472 unregister_framebuffer(info);
1482 framebuffer_release(info); 1473 framebuffer_release(info);
1483} 1474}
1484 1475
1485 1476
1486static struct pci_device_id sstfb_id_tbl[] = { 1477static const struct pci_device_id sstfb_id_tbl[] = {
1487 { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO, 1478 { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO ),
1488 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO1 }, 1479 .driver_data = ID_VOODOO1, },
1489 { PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2, 1480 { PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO2),
1490 PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_VOODOO2 }, 1481 .driver_data = ID_VOODOO2, },
1491 { 0 }, 1482 { 0 },
1492}; 1483};
1493 1484
@@ -1501,142 +1492,23 @@ static struct pci_driver sstfb_driver = {
1501 1492
1502static int __devinit sstfb_init(void) 1493static int __devinit sstfb_init(void)
1503{ 1494{
1504#ifndef MODULE
1505 char *option = NULL; 1495 char *option = NULL;
1506 1496
1507 if (fb_get_options("sstfb", &option)) 1497 if (fb_get_options("sstfb", &option))
1508 return -ENODEV; 1498 return -ENODEV;
1509 sstfb_setup(option); 1499 sstfb_setup(option);
1510#endif 1500
1511 return pci_register_driver(&sstfb_driver); 1501 return pci_register_driver(&sstfb_driver);
1512} 1502}
1513 1503
1514#ifdef MODULE
1515static void __devexit sstfb_exit(void) 1504static void __devexit sstfb_exit(void)
1516{ 1505{
1517 pci_unregister_driver(&sstfb_driver); 1506 pci_unregister_driver(&sstfb_driver);
1518} 1507}
1519#endif
1520 1508
1521 1509
1522/*
1523 * testing and debugging functions
1524 */
1525
1526static int sstfb_dump_regs(struct fb_info *info)
1527{
1528#ifdef SST_DEBUG
1529 static struct { u32 reg ; const char *reg_name;} pci_regs[] = {
1530 { PCI_INIT_ENABLE, "initenable"},
1531 { PCI_VCLK_ENABLE, "enable vclk"},
1532 { PCI_VCLK_DISABLE, "disable vclk"},
1533 };
1534
1535 static struct { u32 reg ; const char *reg_name;} sst_regs[] = {
1536 {FBIINIT0,"fbiinit0"},
1537 {FBIINIT1,"fbiinit1"},
1538 {FBIINIT2,"fbiinit2"},
1539 {FBIINIT3,"fbiinit3"},
1540 {FBIINIT4,"fbiinit4"},
1541 {FBIINIT5,"fbiinit5"},
1542 {FBIINIT6,"fbiinit6"},
1543 {FBIINIT7,"fbiinit7"},
1544 {LFBMODE,"lfbmode"},
1545 {FBZMODE,"fbzmode"},
1546 };
1547
1548 const int pci_s = ARRAY_SIZE(pci_regs);
1549 const int sst_s = ARRAY_SIZE(sst_regs);
1550 struct sstfb_par *par = info->par;
1551 struct pci_dev *dev = par->dev;
1552 u32 pci_res[pci_s];
1553 u32 sst_res[sst_s];
1554 int i;
1555
1556 for (i=0; i<pci_s; i++) {
1557 pci_read_config_dword(dev, pci_regs[i].reg, &pci_res[i]);
1558 }
1559 for (i=0; i<sst_s; i++) {
1560 sst_res[i] = sst_read(sst_regs[i].reg);
1561 }
1562
1563 dprintk("hardware register dump:\n");
1564 for (i=0; i<pci_s; i++) {
1565 dprintk("%s %0#10x\n", pci_regs[i].reg_name, pci_res[i]);
1566 }
1567 for (i=0; i<sst_s; i++) {
1568 dprintk("%s %0#10x\n", sst_regs[i].reg_name, sst_res[i]);
1569 }
1570 return 0;
1571#else
1572 return -EINVAL;
1573#endif
1574}
1575
1576static void sstfb_fillrect_softw( struct fb_info *info, const struct fb_fillrect *rect)
1577{
1578 u8 __iomem *fbbase_virt = info->screen_base;
1579 int x, y, w = info->var.bits_per_pixel == 16 ? 2 : 4;
1580 u32 color = rect->color, height = rect->height;
1581 u8 __iomem *p;
1582
1583 if (w==2) color |= color<<16;
1584 for (y=rect->dy; height; y++, height--) {
1585 p = fbbase_virt + y*info->fix.line_length + rect->dx*w;
1586 x = rect->width;
1587 if (w==2) x>>=1;
1588 while (x) {
1589 writel(color, p);
1590 p += 4;
1591 x--;
1592 }
1593 }
1594}
1595
1596static void sstfb_drawrect_XY( struct fb_info *info, int x, int y,
1597 int w, int h, int color, int hwfunc)
1598{
1599 struct fb_fillrect rect;
1600 rect.dx = x;
1601 rect.dy = y;
1602 rect.height = h;
1603 rect.width = w;
1604 rect.color = color;
1605 rect.rop = ROP_COPY;
1606 if (hwfunc)
1607 sstfb_fillrect(info, &rect);
1608 else
1609 sstfb_fillrect_softw(info, &rect);
1610}
1611
1612/* print some squares on the fb */
1613static void sstfb_drawdebugimage(struct fb_info *info)
1614{
1615 static int idx;
1616
1617 /* clear screen */
1618 sstfb_clear_screen(info);
1619
1620 idx = (idx+1) & 1;
1621
1622 /* white rect */
1623 sstfb_drawrect_XY(info, 0, 0, 50, 50, 0xffff, idx);
1624
1625 /* blue rect */
1626 sstfb_drawrect_XY(info, 50, 50, 50, 50, 0x001f, idx);
1627
1628 /* green rect */
1629 sstfb_drawrect_XY(info, 100, 100, 80, 80, 0x07e0, idx);
1630
1631 /* red rect */
1632 sstfb_drawrect_XY(info, 250, 250, 120, 100, 0xf800, idx);
1633}
1634
1635module_init(sstfb_init); 1510module_init(sstfb_init);
1636
1637#ifdef MODULE
1638module_exit(sstfb_exit); 1511module_exit(sstfb_exit);
1639#endif
1640 1512
1641MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>"); 1513MODULE_AUTHOR("(c) 2000,2002 Ghozlane Toumi <gtoumi@laposte.net>");
1642MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards"); 1514MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
@@ -1652,3 +1524,6 @@ module_param(gfxclk, int, 0);
1652MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)"); 1524MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");
1653module_param(slowpci, bool, 0); 1525module_param(slowpci, bool, 0);
1654MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)"); 1526MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
1527module_param(mode_option, charp, 0);
1528MODULE_PARM_DESC(mode_option, "Initial video mode (default=" DEFAULT_VIDEO_MODE ")");
1529
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 3e16e2d9d55d..69f3b264a22e 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1291,6 +1291,7 @@ out_err3:
1291out_err2: 1291out_err2:
1292 release_mem_region(fix->smem_start, fix->smem_len); 1292 release_mem_region(fix->smem_start, fix->smem_len);
1293out_err1: 1293out_err1:
1294 iounmap(info->screen_base);
1294 fb_dealloc_cmap(&info->cmap); 1295 fb_dealloc_cmap(&info->cmap);
1295out_err0: 1296out_err0:
1296 kfree(fb); 1297 kfree(fb);
@@ -1364,6 +1365,8 @@ stifb_cleanup(void)
1364 unregister_framebuffer(sti->info); 1365 unregister_framebuffer(sti->info);
1365 release_mem_region(info->fix.mmio_start, info->fix.mmio_len); 1366 release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
1366 release_mem_region(info->fix.smem_start, info->fix.smem_len); 1367 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1368 if (info->screen_base)
1369 iounmap(info->screen_base);
1367 fb_dealloc_cmap(&info->cmap); 1370 fb_dealloc_cmap(&info->cmap);
1368 kfree(info); 1371 kfree(info);
1369 } 1372 }
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 94fde625a6c0..4b88fab83b74 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -23,6 +23,7 @@
23#include <linux/fb.h> 23#include <linux/fb.h>
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/selection.h> 25#include <linux/selection.h>
26#include <linux/bitrev.h>
26#include <asm/io.h> 27#include <asm/io.h>
27#include <video/tgafb.h> 28#include <video/tgafb.h>
28 29
@@ -517,41 +518,6 @@ tgafb_blank(int blank, struct fb_info *info)
517static void 518static void
518tgafb_imageblit(struct fb_info *info, const struct fb_image *image) 519tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
519{ 520{
520 static unsigned char const bitrev[256] = {
521 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
522 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
523 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
524 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
525 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
526 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
527 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
528 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
529 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
530 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
531 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
532 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
533 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
534 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
535 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
536 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
537 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
538 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
539 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
540 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
541 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
542 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
543 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
544 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
545 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
546 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
547 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
548 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
549 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
550 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
551 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
552 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
553 };
554
555 struct tga_par *par = (struct tga_par *) info->par; 521 struct tga_par *par = (struct tga_par *) info->par;
556 u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask; 522 u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask;
557 unsigned long rincr, line_length, shift, pos, is8bpp; 523 unsigned long rincr, line_length, shift, pos, is8bpp;
@@ -649,7 +615,7 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
649 /* The image data is bit big endian; we need 615 /* The image data is bit big endian; we need
650 little endian. */ 616 little endian. */
651 for (j = 0; j < bwidth; ++j) 617 for (j = 0; j < bwidth; ++j)
652 mask |= bitrev[data[j]] << (j * 8); 618 mask |= bitrev8(data[j]) << (j * 8);
653 619
654 __raw_writel(mask << shift, fb_base + pos); 620 __raw_writel(mask << shift, fb_base + pos);
655 621
@@ -676,10 +642,10 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
676 for (i = 0; i < height; ++i) { 642 for (i = 0; i < height; ++i) {
677 for (j = 0; j < bwidth; j += 4) { 643 for (j = 0; j < bwidth; j += 4) {
678 u32 mask = 0; 644 u32 mask = 0;
679 mask |= bitrev[data[j+0]] << (0 * 8); 645 mask |= bitrev8(data[j+0]) << (0 * 8);
680 mask |= bitrev[data[j+1]] << (1 * 8); 646 mask |= bitrev8(data[j+1]) << (1 * 8);
681 mask |= bitrev[data[j+2]] << (2 * 8); 647 mask |= bitrev8(data[j+2]) << (2 * 8);
682 mask |= bitrev[data[j+3]] << (3 * 8); 648 mask |= bitrev8(data[j+3]) << (3 * 8);
683 __raw_writel(mask, fb_base + pos + j*bincr); 649 __raw_writel(mask, fb_base + pos + j*bincr);
684 } 650 }
685 pos += line_length; 651 pos += line_length;
@@ -699,7 +665,7 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
699 for (i = 0; i < height; ++i) { 665 for (i = 0; i < height; ++i) {
700 u32 mask = 0; 666 u32 mask = 0;
701 for (j = 0; j < bwidth; ++j) 667 for (j = 0; j < bwidth; ++j)
702 mask |= bitrev[data[j]] << (j * 8); 668 mask |= bitrev8(data[j]) << (j * 8);
703 __raw_writel(mask, fb_base + pos); 669 __raw_writel(mask, fb_base + pos);
704 pos += line_length; 670 pos += line_length;
705 data += rincr; 671 data += rincr;
@@ -726,8 +692,8 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
726 for (i = 0; i < height; ++i) { 692 for (i = 0; i < height; ++i) {
727 for (j = 0; j < bwidth; j += 2) { 693 for (j = 0; j < bwidth; j += 2) {
728 u32 mask = 0; 694 u32 mask = 0;
729 mask |= bitrev[data[j+0]] << (0 * 8); 695 mask |= bitrev8(data[j+0]) << (0 * 8);
730 mask |= bitrev[data[j+1]] << (1 * 8); 696 mask |= bitrev8(data[j+1]) << (1 * 8);
731 mask <<= shift; 697 mask <<= shift;
732 __raw_writel(mask, fb_base + pos + j*bincr); 698 __raw_writel(mask, fb_base + pos + j*bincr);
733 } 699 }
@@ -746,9 +712,9 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
746 bwidth = (width & 15) > 8; 712 bwidth = (width & 15) > 8;
747 713
748 for (i = 0; i < height; ++i) { 714 for (i = 0; i < height; ++i) {
749 u32 mask = bitrev[data[0]]; 715 u32 mask = bitrev8(data[0]);
750 if (bwidth) 716 if (bwidth)
751 mask |= bitrev[data[1]] << 8; 717 mask |= bitrev8(data[1]) << 8;
752 mask <<= shift; 718 mask <<= shift;
753 __raw_writel(mask, fb_base + pos); 719 __raw_writel(mask, fb_base + pos);
754 pos += line_length; 720 pos += line_length;
@@ -1473,6 +1439,8 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
1473 return 0; 1439 return 0;
1474 1440
1475 err1: 1441 err1:
1442 if (mem_base)
1443 iounmap(mem_base);
1476 release_mem_region(bar0_start, bar0_len); 1444 release_mem_region(bar0_start, bar0_len);
1477 err0: 1445 err0:
1478 kfree(all); 1446 kfree(all);
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 14175cdb9c9c..55e8aa450bfa 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1130,7 +1130,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1130 1130
1131 if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { 1131 if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) {
1132 debug("request_mem_region failed!\n"); 1132 debug("request_mem_region failed!\n");
1133 return -1; 1133 err = -1;
1134 goto out_unmap;
1134 } 1135 }
1135 1136
1136 fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, 1137 fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start,
@@ -1139,7 +1140,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1139 if (!fb_info.screen_base) { 1140 if (!fb_info.screen_base) {
1140 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); 1141 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
1141 debug("ioremap failed\n"); 1142 debug("ioremap failed\n");
1142 return -1; 1143 err = -1;
1144 goto out_unmap;
1143 } 1145 }
1144 1146
1145 output("%s board found\n", pci_name(dev)); 1147 output("%s board found\n", pci_name(dev));
@@ -1162,8 +1164,10 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1162#endif 1164#endif
1163 fb_info.pseudo_palette = pseudo_pal; 1165 fb_info.pseudo_palette = pseudo_pal;
1164 1166
1165 if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp)) 1167 if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp)) {
1166 return -EINVAL; 1168 err = -EINVAL;
1169 goto out_unmap;
1170 }
1167 fb_alloc_cmap(&fb_info.cmap,256,0); 1171 fb_alloc_cmap(&fb_info.cmap,256,0);
1168 if (defaultaccel && acc) 1172 if (defaultaccel && acc)
1169 default_var.accel_flags |= FB_ACCELF_TEXT; 1173 default_var.accel_flags |= FB_ACCELF_TEXT;
@@ -1174,12 +1178,20 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1174 fb_info.device = &dev->dev; 1178 fb_info.device = &dev->dev;
1175 if (register_framebuffer(&fb_info) < 0) { 1179 if (register_framebuffer(&fb_info) < 0) {
1176 printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n"); 1180 printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n");
1177 return -EINVAL; 1181 err = -EINVAL;
1182 goto out_unmap;
1178 } 1183 }
1179 output("fb%d: %s frame buffer device %dx%d-%dbpp\n", 1184 output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
1180 fb_info.node, fb_info.fix.id,default_var.xres, 1185 fb_info.node, fb_info.fix.id,default_var.xres,
1181 default_var.yres,default_var.bits_per_pixel); 1186 default_var.yres,default_var.bits_per_pixel);
1182 return 0; 1187 return 0;
1188
1189out_unmap:
1190 if (default_par.io_virt)
1191 iounmap(default_par.io_virt);
1192 if (fb_info.screen_base)
1193 iounmap(fb_info.screen_base);
1194 return err;
1183} 1195}
1184 1196
1185static void __devexit trident_pci_remove(struct pci_dev * dev) 1197static void __devexit trident_pci_remove(struct pci_dev * dev)
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 2196448396ec..e16322d157d0 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -47,17 +47,16 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = {
47 .accel = FB_ACCEL_NONE, 47 .accel = FB_ACCEL_NONE,
48}; 48};
49 49
50static int inverse = 0; 50static int inverse __read_mostly;
51static int mtrr = 0; /* disable mtrr */ 51static int mtrr __read_mostly; /* disable mtrr */
52static int vram_remap __initdata = 0; /* Set amount of memory to be used */ 52static int vram_remap __initdata; /* Set amount of memory to be used */
53static int vram_total __initdata = 0; /* Set total amount of memory */ 53static int vram_total __initdata; /* Set total amount of memory */
54static int pmi_setpal = 1; /* pmi for palette changes ??? */ 54static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
55static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */ 55static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
56static unsigned short *pmi_base = NULL; 56static void (*pmi_start)(void) __read_mostly;
57static void (*pmi_start)(void); 57static void (*pmi_pal) (void) __read_mostly;
58static void (*pmi_pal)(void); 58static int depth __read_mostly;
59static int depth; 59static int vga_compat __read_mostly;
60static int vga_compat;
61/* --------------------------------------------------------------------- */ 60/* --------------------------------------------------------------------- */
62 61
63static int vesafb_pan_display(struct fb_var_screeninfo *var, 62static int vesafb_pan_display(struct fb_var_screeninfo *var,
@@ -312,6 +311,7 @@ static int __init vesafb_probe(struct platform_device *dev)
312 ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */ 311 ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */
313 312
314 if (ypan || pmi_setpal) { 313 if (ypan || pmi_setpal) {
314 unsigned short *pmi_base;
315 pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); 315 pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
316 pmi_start = (void*)((char*)pmi_base + pmi_base[1]); 316 pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
317 pmi_pal = (void*)((char*)pmi_base + pmi_base[2]); 317 pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
@@ -456,6 +456,8 @@ static int __init vesafb_probe(struct platform_device *dev)
456 info->node, info->fix.id); 456 info->node, info->fix.id);
457 return 0; 457 return 0;
458err: 458err:
459 if (info->screen_base)
460 iounmap(info->screen_base);
459 framebuffer_release(info); 461 framebuffer_release(info);
460 release_mem_region(vesafb_fix.smem_start, size_total); 462 release_mem_region(vesafb_fix.smem_start, size_total);
461 return err; 463 return err;
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 43d5a6d9c4a6..6aff63d5b295 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -264,7 +264,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
264 const struct fb_info *info, 264 const struct fb_info *info,
265 int mul, int div) 265 int mul, int div)
266{ 266{
267 static struct { 267 static const struct {
268 u32 pixclock; 268 u32 pixclock;
269 u8 misc; 269 u8 misc;
270 u8 seq_clock_mode; 270 u8 seq_clock_mode;
@@ -652,7 +652,7 @@ static int vga16fb_set_par(struct fb_info *info)
652 652
653static void ega16_setpalette(int regno, unsigned red, unsigned green, unsigned blue) 653static void ega16_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
654{ 654{
655 static unsigned char map[] = { 000, 001, 010, 011 }; 655 static const unsigned char map[] = { 000, 001, 010, 011 };
656 int val; 656 int val;
657 657
658 if (regno >= 16) 658 if (regno >= 16)
@@ -1139,23 +1139,19 @@ static void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
1139 } 1139 }
1140} 1140}
1141 1141
1142#ifdef __LITTLE_ENDIAN 1142#define TRANS_MASK_LOW {0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF}
1143static unsigned int transl_l[] = 1143#define TRANS_MASK_HIGH {0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00, \
1144{0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF}; 1144 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00}
1145static unsigned int transl_h[] = 1145
1146{0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00, 1146#if defined(__LITTLE_ENDIAN)
1147 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00}; 1147static const u16 transl_l[] = TRANS_MASK_LOW;
1148#else 1148static const u16 transl_h[] = TRANS_MASK_HIGH;
1149#ifdef __BIG_ENDIAN 1149#elif defined(__BIG_ENDIAN)
1150static unsigned int transl_h[] = 1150static const u16 transl_l[] = TRANS_MASK_HIGH;
1151{0x0,0x8,0x4,0xC,0x2,0xA,0x6,0xE,0x1,0x9,0x5,0xD,0x3,0xB,0x7,0xF}; 1151static const u16 transl_h[] = TRANS_MASK_LOW;
1152static unsigned int transl_l[] =
1153{0x000, 0x800, 0x400, 0xC00, 0x200, 0xA00, 0x600, 0xE00,
1154 0x100, 0x900, 0x500, 0xD00, 0x300, 0xB00, 0x700, 0xF00};
1155#else 1152#else
1156#error "Only __BIG_ENDIAN and __LITTLE_ENDIAN are supported in vga-planes" 1153#error "Only __BIG_ENDIAN and __LITTLE_ENDIAN are supported in vga-planes"
1157#endif 1154#endif
1158#endif
1159 1155
1160static void vga_8planes_imageblit(struct fb_info *info, const struct fb_image *image) 1156static void vga_8planes_imageblit(struct fb_info *info, const struct fb_image *image)
1161{ 1157{
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c
index 64378959dd7b..b9fb6fb3600d 100644
--- a/drivers/video/virgefb.c
+++ b/drivers/video/virgefb.c
@@ -1799,7 +1799,7 @@ int __init virgefb_init(void)
1799 #warning release resources 1799 #warning release resources
1800 printk(KERN_ERR "virgefb.c: register_framebuffer failed\n"); 1800 printk(KERN_ERR "virgefb.c: register_framebuffer failed\n");
1801 DPRINTK("EXIT\n"); 1801 DPRINTK("EXIT\n");
1802 return -EINVAL; 1802 goto out_unmap;
1803 } 1803 }
1804 1804
1805 printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n", 1805 printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n",
@@ -1809,6 +1809,21 @@ int __init virgefb_init(void)
1809 1809
1810 DPRINTK("EXIT\n"); 1810 DPRINTK("EXIT\n");
1811 return 0; 1811 return 0;
1812
1813out_unmap:
1814 if (board_addr >= 0x01000000) {
1815 if (v_ram)
1816 iounmap((void*)v_ram);
1817 if (vgaio_regs)
1818 iounmap(vgaio_regs);
1819 if (mmio_regs)
1820 iounmap(mmio_regs);
1821 if (vcode_switch_base)
1822 iounmap((void*)vcode_switch_base);
1823 v_ram = vcode_switch_base = 0;
1824 vgaio_regs = mmio_regs = NULL;
1825 }
1826 return -EINVAL;
1812} 1827}
1813 1828
1814 1829