Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7dfe50b3aac2b3500139ab10a6e228d34fed9a49
Commit:     7dfe50b3aac2b3500139ab10a6e228d34fed9a49
Parent:     19f3d3a5546be431f3846d8a8581e7a2f169dba3
Author:     Antonino A. Daplas <[EMAIL PROTECTED]>
AuthorDate: Tue May 8 00:38:33 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Tue May 8 11:15:28 2007 -0700

    nvidiafb: VGA state save and restore
    
    Allow the saving and restoration of VGA text mode.  The state is saved on 
the
    first open and restored on the last close.  Because of the non-linear 
mapping
    of the VGA registers to the MMIO space, this will be done only on X86
    platforms where the device is the primary display.
    
    An echo 0 > /sys/class/vtconsole/vtcon1/bind will convert the display from
    graphics to text mode.
    
    Signed-off-by: Antonino Daplas <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 drivers/video/Makefile         |    2 +-
 drivers/video/nvidia/nv_type.h |    6 +++
 drivers/video/nvidia/nvidia.c  |   74 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 49d01eb..c8b43eb 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -32,7 +32,7 @@ obj-$(CONFIG_FB_PM3)            += pm3fb.o
 
 obj-$(CONFIG_FB_MATROX)                  += matrox/
 obj-$(CONFIG_FB_RIVA)            += riva/ vgastate.o
-obj-$(CONFIG_FB_NVIDIA)                  += nvidia/
+obj-$(CONFIG_FB_NVIDIA)                  += nvidia/ vgastate.o
 obj-$(CONFIG_FB_ATY)             += aty/ macmodes.o
 obj-$(CONFIG_FB_ATY128)                  += aty/ macmodes.o
 obj-$(CONFIG_FB_RADEON)                  += aty/
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index ee430af..38f7cc0 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -5,6 +5,8 @@
 #include <linux/types.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
+#include <linux/mutex.h>
+#include <video/vga.h>
 
 #define NV_ARCH_04  0x04
 #define NV_ARCH_10  0x10
@@ -93,7 +95,10 @@ struct riva_regs {
 struct nvidia_par {
        RIVA_HW_STATE SavedReg;
        RIVA_HW_STATE ModeReg;
+       RIVA_HW_STATE initial_state;
        RIVA_HW_STATE *CurrentState;
+       struct vgastate vgastate;
+       struct mutex open_lock;
        u32 pseudo_palette[16];
        struct pci_dev *pci_dev;
        u32 Architecture;
@@ -141,6 +146,7 @@ struct nvidia_par {
        int BlendingPossible;
        u32 paletteEnabled;
        u32 forceCRTC;
+       u32 open_count;
        u8 DDCBase;
 #ifdef CONFIG_MTRR
        struct {
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index c6afafc..6105753 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -949,8 +949,80 @@ static int nvidiafb_blank(int blank, struct fb_info *info)
        return 0;
 }
 
+/*
+ * Because the VGA registers are not mapped linearly in its MMIO space,
+ * restrict VGA register saving and restore to x86 only, where legacy VGA IO
+ * access is legal. Consequently, we must also check if the device is the
+ * primary display.
+ */
+#ifdef CONFIG_X86
+static void save_vga_x86(struct nvidia_par *par)
+{
+       struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
+
+       if (res && res->flags & IORESOURCE_ROM_SHADOW) {
+               memset(&par->vgastate, 0, sizeof(par->vgastate));
+               par->vgastate.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS |
+                       VGA_SAVE_CMAP;
+               save_vga(&par->vgastate);
+       }
+}
+
+static void restore_vga_x86(struct nvidia_par *par)
+{
+       struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
+
+       if (res && res->flags & IORESOURCE_ROM_SHADOW)
+               restore_vga(&par->vgastate);
+}
+#else
+#define save_vga_x86(x) do {} while (0)
+#define restore_vga_x86(x) do {} while (0)
+#endif /* X86 */
+
+static int nvidiafb_open(struct fb_info *info, int user)
+{
+       struct nvidia_par *par = info->par;
+
+       mutex_lock(&par->open_lock);
+
+       if (!par->open_count) {
+               save_vga_x86(par);
+               nvidia_save_vga(par, &par->initial_state);
+       }
+
+       par->open_count++;
+       mutex_unlock(&par->open_lock);
+       return 0;
+}
+
+static int nvidiafb_release(struct fb_info *info, int user)
+{
+       struct nvidia_par *par = info->par;
+       int err = 0;
+
+       mutex_lock(&par->open_lock);
+
+       if (!par->open_count) {
+               err = -EINVAL;
+               goto done;
+       }
+
+       if (par->open_count == 1) {
+               nvidia_write_regs(par, &par->initial_state);
+               restore_vga_x86(par);
+       }
+
+       par->open_count--;
+done:
+       mutex_unlock(&par->open_lock);
+       return 0;
+}
+
 static struct fb_ops nvidia_fb_ops = {
        .owner          = THIS_MODULE,
+       .fb_open        = nvidiafb_open,
+       .fb_release     = nvidiafb_release,
        .fb_check_var   = nvidiafb_check_var,
        .fb_set_par     = nvidiafb_set_par,
        .fb_setcolreg   = nvidiafb_setcolreg,
@@ -1208,7 +1280,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
 
        par = info->par;
        par->pci_dev = pd;
-
+       mutex_init(&par->open_lock);
        info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
 
        if (info->pixmap.addr == NULL)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to