summaryrefslogtreecommitdiffstats
path: root/drivers/video/savage
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/savage')
-rw-r--r--drivers/video/savage/savagefb-i2c.c22
-rw-r--r--drivers/video/savage/savagefb.h10
-rw-r--r--drivers/video/savage/savagefb_driver.c39
3 files changed, 55 insertions, 16 deletions
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 8db066ccca6..35c1ce62b21 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -41,10 +41,6 @@
#define SAVAGE4_I2C_SCL_IN 0x00000008
#define SAVAGE4_I2C_SDA_IN 0x00000010
-#define SET_CR_IX(base, val) writeb((val), base + 0x8000 + VGA_CR_IX)
-#define SET_CR_DATA(base, val) writeb((val), base + 0x8000 + VGA_CR_DATA)
-#define GET_CR_DATA(base) readb(base + 0x8000 + VGA_CR_DATA)
-
static void savage4_gpio_setscl(void *data, int val)
{
struct savagefb_i2c_chan *chan = data;
@@ -92,15 +88,15 @@ static void prosavage_gpio_setscl(void* data, int val)
struct savagefb_i2c_chan *chan = data;
u32 r;
- SET_CR_IX(chan->ioaddr, chan->reg);
- r = GET_CR_DATA(chan->ioaddr);
+ r = VGArCR(chan->reg, chan->par);
r |= PROSAVAGE_I2C_ENAB;
if (val) {
r |= PROSAVAGE_I2C_SCL_OUT;
} else {
r &= ~PROSAVAGE_I2C_SCL_OUT;
}
- SET_CR_DATA(chan->ioaddr, r);
+
+ VGAwCR(chan->reg, r, chan->par);
}
static void prosavage_gpio_setsda(void* data, int val)
@@ -108,31 +104,29 @@ static void prosavage_gpio_setsda(void* data, int val)
struct savagefb_i2c_chan *chan = data;
unsigned int r;
- SET_CR_IX(chan->ioaddr, chan->reg);
- r = GET_CR_DATA(chan->ioaddr);
+ r = VGArCR(chan->reg, chan->par);
r |= PROSAVAGE_I2C_ENAB;
if (val) {
r |= PROSAVAGE_I2C_SDA_OUT;
} else {
r &= ~PROSAVAGE_I2C_SDA_OUT;
}
- SET_CR_DATA(chan->ioaddr, r);
+
+ VGAwCR(chan->reg, r, chan->par);
}
static int prosavage_gpio_getscl(void* data)
{
struct savagefb_i2c_chan *chan = data;
- SET_CR_IX(chan->ioaddr, chan->reg);
- return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SCL_IN));
+ return (VGArCR(chan->reg, chan->par) & PROSAVAGE_I2C_SCL_IN) ? 1 : 0;
}
static int prosavage_gpio_getsda(void* data)
{
struct savagefb_i2c_chan *chan = data;
- SET_CR_IX(chan->ioaddr, chan->reg);
- return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN));
+ return (VGArCR(chan->reg, chan->par) & PROSAVAGE_I2C_SDA_IN) ? 1 : 0;
}
static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index e648a6c0f6d..8bfdfc3c523 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 0166ec2ccf3..3d7507ad55f 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;