diff options
-rw-r--r-- | drivers/video/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/savage/savagefb.h | 10 | ||||
-rw-r--r-- | drivers/video/savage/savagefb_driver.c | 39 |
3 files changed, 48 insertions, 3 deletions
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index c8b43eb..1e1845d 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -38,7 +38,7 @@ obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o obj-$(CONFIG_FB_RADEON) += aty/ obj-$(CONFIG_FB_SIS) += sis/ obj-$(CONFIG_FB_KYRO) += kyro/ -obj-$(CONFIG_FB_SAVAGE) += savage/ +obj-$(CONFIG_FB_SAVAGE) += savage/ vgastate.o obj-$(CONFIG_FB_GEODE) += geode/ obj-$(CONFIG_FB_MBX) += mbx/ obj-$(CONFIG_FB_I810) += vgastate.o diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h index e648a6c..8bfdfc3 100644 --- a/drivers/video/savage/savagefb.h +++ b/drivers/video/savage/savagefb.h @@ -15,6 +15,8 @@ #include <linux/i2c.h> #include <linux/i2c-id.h> #include <linux/i2c-algo-bit.h> +#include <linux/mutex.h> +#include <video/vga.h> #include "../edid.h" #ifdef SAVAGEFB_DEBUG @@ -189,8 +191,12 @@ struct savagefb_par { struct savagefb_i2c_chan chan; struct savage_reg state; struct savage_reg save; + struct savage_reg initial; + struct vgastate vgastate; + struct mutex open_lock; unsigned char *edid; u32 pseudo_palette[16]; + u32 open_count; int paletteEnabled; int pm_state; int display_type; @@ -203,7 +209,7 @@ struct savagefb_par { int clock[4]; int MCLK, REFCLK, LCDclk; struct { - u8 __iomem *vbase; + void __iomem *vbase; u32 pbase; u32 len; #ifdef CONFIG_MTRR @@ -212,7 +218,7 @@ struct savagefb_par { } video; struct { - volatile u8 __iomem *vbase; + void __iomem *vbase; u32 pbase; u32 len; } mmio; diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 0166ec2..3d7507a 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -1623,8 +1623,46 @@ static void savagefb_restore_state(struct fb_info *info) savagefb_blank(FB_BLANK_UNBLANK, info); } +static int savagefb_open(struct fb_info *info, int user) +{ + struct savagefb_par *par = info->par; + + mutex_lock(&par->open_lock); + + if (!par->open_count) { + memset(&par->vgastate, 0, sizeof(par->vgastate)); + par->vgastate.flags = VGA_SAVE_CMAP | VGA_SAVE_FONTS | + VGA_SAVE_MODE; + par->vgastate.vgabase = par->mmio.vbase + 0x8000; + save_vga(&par->vgastate); + savage_get_default_par(par, &par->initial); + } + + par->open_count++; + mutex_unlock(&par->open_lock); + return 0; +} + +static int savagefb_release(struct fb_info *info, int user) +{ + struct savagefb_par *par = info->par; + + mutex_lock(&par->open_lock); + + if (par->open_count == 1) { + savage_set_default_par(par, &par->initial); + restore_vga(&par->vgastate); + } + + par->open_count--; + mutex_unlock(&par->open_lock); + return 0; +} + static struct fb_ops savagefb_ops = { .owner = THIS_MODULE, + .fb_open = savagefb_open, + .fb_release = savagefb_release, .fb_check_var = savagefb_check_var, .fb_set_par = savagefb_set_par, .fb_setcolreg = savagefb_setcolreg, @@ -2173,6 +2211,7 @@ static int __devinit savagefb_probe(struct pci_dev* dev, if (!info) return -ENOMEM; par = info->par; + mutex_init(&par->open_lock); err = pci_enable_device(dev); if (err) goto failed_enable; |