nvidiafb: ensure that CRTC registers are accessible
[pandora-kernel.git] / drivers / video / nvidia / nvidia.c
index 538e947..c6afafc 100644 (file)
@@ -83,6 +83,11 @@ static int bpp __devinitdata = 8;
 #ifdef CONFIG_MTRR
 static int nomtrr __devinitdata = 0;
 #endif
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int backlight __devinitdata = 1;
+#else
+static int backlight __devinitdata = 0;
+#endif
 
 static char *mode_option __devinitdata = NULL;
 
@@ -195,7 +200,7 @@ static int nvidia_panel_tweak(struct nvidia_par *par,
    return tweak;
 }
 
-static void nvidia_vga_protect(struct nvidia_par *par, int on)
+static void nvidia_screen_off(struct nvidia_par *par, int on)
 {
        unsigned char tmp;
 
@@ -644,7 +649,7 @@ static int nvidiafb_set_par(struct fb_info *info)
                NVLockUnlock(par, 0);
        }
 
-       nvidia_vga_protect(par, 1);
+       nvidia_screen_off(par, 1);
 
        nvidia_write_regs(par, &par->ModeReg);
        NVSetStartAddress(par, 0);
@@ -682,7 +687,7 @@ static int nvidiafb_set_par(struct fb_info *info)
 
        par->cursor_reset = 1;
 
-       nvidia_vga_protect(par, 0);
+       nvidia_screen_off(par, 0);
 
 #ifdef CONFIG_BOOTX_TEXT
        /* Update debug text engine */
@@ -691,6 +696,7 @@ static int nvidiafb_set_par(struct fb_info *info)
                             info->var.bits_per_pixel, info->fix.line_length);
 #endif
 
+       NVLockUnlock(par, 0);
        NVTRACE_LEAVE();
        return 0;
 }
@@ -829,7 +835,7 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var,
        }
 
        if (!mode_valid) {
-               struct fb_videomode *mode;
+               const struct fb_videomode *mode;
 
                mode = fb_find_best_mode(var, &info->modelist);
                if (mode) {
@@ -938,8 +944,6 @@ static int nvidiafb_blank(int blank, struct fb_info *info)
        NVWriteSeq(par, 0x01, tmp);
        NVWriteCrtc(par, 0x1a, vesa);
 
-       nvidia_bl_set_power(info, blank);
-
        NVTRACE_LEAVE();
 
        return 0;
@@ -1046,10 +1050,10 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
        }
 
        if (specs->modedb != NULL) {
-               struct fb_videomode *modedb;
+               const struct fb_videomode *mode;
 
-               modedb = fb_find_best_display(specs, &info->modelist);
-               fb_videomode_to_var(&nvidiafb_default_var, modedb);
+               mode = fb_find_best_display(specs, &info->modelist);
+               fb_videomode_to_var(&nvidiafb_default_var, mode);
                nvidiafb_default_var.bits_per_pixel = bpp;
        } else if (par->fpWidth && par->fpHeight) {
                char buf[16];
@@ -1205,13 +1209,11 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
        par = info->par;
        par->pci_dev = pd;
 
-       info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
+       info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
 
        if (info->pixmap.addr == NULL)
                goto err_out_kfree;
 
-       memset(info->pixmap.addr, 0, 8 * 1024);
-
        if (pci_enable_device(pd)) {
                printk(KERN_ERR PFX "cannot enable PCI device\n");
                goto err_out_enable;
@@ -1315,7 +1317,10 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
        nvidia_save_vga(par, &par->SavedReg);
 
        pci_set_drvdata(pd, info);
-       nvidia_bl_init(par);
+
+       if (backlight)
+               nvidia_bl_init(par);
+
        if (register_framebuffer(info) < 0) {
                printk(KERN_ERR PFX "error registering nVidia framebuffer\n");
                goto err_out_iounmap_fb;
@@ -1347,16 +1352,17 @@ err_out:
        return -ENODEV;
 }
 
-static void __exit nvidiafb_remove(struct pci_dev *pd)
+static void __devexit nvidiafb_remove(struct pci_dev *pd)
 {
        struct fb_info *info = pci_get_drvdata(pd);
        struct nvidia_par *par = info->par;
 
        NVTRACE_ENTER();
 
+       unregister_framebuffer(info);
+
        nvidia_bl_exit(par);
 
-       unregister_framebuffer(info);
 #ifdef CONFIG_MTRR
        if (par->mtrr.vram_valid)
                mtrr_del(par->mtrr.vram, info->fix.smem_start,
@@ -1411,6 +1417,8 @@ static int __devinit nvidiafb_setup(char *options)
                        paneltweak = simple_strtoul(this_opt+11, NULL, 0);
                } else if (!strncmp(this_opt, "vram:", 5)) {
                        vram = simple_strtoul(this_opt+5, NULL, 0);
+               } else if (!strncmp(this_opt, "backlight:", 10)) {
+                       backlight = simple_strtoul(this_opt+10, NULL, 0);
 #ifdef CONFIG_MTRR
                } else if (!strncmp(this_opt, "nomtrr", 6)) {
                        nomtrr = 1;
@@ -1433,7 +1441,7 @@ static struct pci_driver nvidiafb_driver = {
        .probe    = nvidiafb_probe,
        .suspend  = nvidiafb_suspend,
        .resume   = nvidiafb_resume,
-       .remove   = __exit_p(nvidiafb_remove),
+       .remove   = __devexit_p(nvidiafb_remove),
 };
 
 /* ------------------------------------------------------------------------- *