summaryrefslogtreecommitdiffstats
path: root/drivers/video/intelfb/intelfbdrv.c
diff options
context:
space:
mode:
authorEric Hustvedt <ehustvedt@cecropia.com>2006-06-20 14:36:41 -0400
committerDave Airlie <airlied@linux.ie>2006-07-03 18:59:46 +1000
commit7649757bd900bc900adcd95ab08903cdc28342fa (patch)
tree4c710d9e458ff3c6731180aca738123886f7adec /drivers/video/intelfb/intelfbdrv.c
parent9a5f019b1a9ea6a75ba36d7c312ff069006ed479 (diff)
intelfb: add vsync interrupt support
[03/05] intelfb: Implement basic interrupt handling Functions have been added to enable and disable interrupts using the MMIO registers. Currently only pipe A vsync interrupts are enabled. A generalized vsync accounting struct is defined, with the intent that it can encapsulate per-pipe vsync related info in the future. Currently a single instance is hard-coded. The interrupt service routine currently only looks for vsync interrupts on pipe A, and increments a counter and wakes up anyone waiting on it. This implementation is heavily influenced by similar implementations in the atyfb and matroxfb drivers. Signed-off-by: Eric Hustvedt <ehustvedt@cecropia.com>
Diffstat (limited to 'drivers/video/intelfb/intelfbdrv.c')
-rw-r--r--drivers/video/intelfb/intelfbdrv.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 0a0a8b199ec..068c56d4e65 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -137,6 +137,8 @@
static void __devinit get_initial_mode(struct intelfb_info *dinfo);
static void update_dinfo(struct intelfb_info *dinfo,
struct fb_var_screeninfo *var);
+static int intelfb_open(struct fb_info *info, int user);
+static int intelfb_release(struct fb_info *info, int user);
static int intelfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info);
static int intelfb_set_par(struct fb_info *info);
@@ -195,6 +197,8 @@ static int num_registered = 0;
/* fb ops */
static struct fb_ops intel_fb_ops = {
.owner = THIS_MODULE,
+ .fb_open = intelfb_open,
+ .fb_release = intelfb_release,
.fb_check_var = intelfb_check_var,
.fb_set_par = intelfb_set_par,
.fb_setcolreg = intelfb_setcolreg,
@@ -447,6 +451,8 @@ cleanup(struct intelfb_info *dinfo)
if (!dinfo)
return;
+ intelfbhw_disable_irq(dinfo);
+
fb_dealloc_cmap(&dinfo->info->cmap);
kfree(dinfo->info->pixmap.addr);
@@ -889,6 +895,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
}
dinfo->registered = 1;
+ dinfo->open = 0;
+
+ init_waitqueue_head(&dinfo->vsync.wait);
+ spin_lock_init(&dinfo->int_lock);
+ dinfo->irq_flags = 0;
return 0;
@@ -1189,6 +1200,34 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
***************************************************************/
static int
+intelfb_open(struct fb_info *info, int user)
+{
+ struct intelfb_info *dinfo = GET_DINFO(info);
+
+ if (user) {
+ dinfo->open++;
+ }
+
+ return 0;
+}
+
+static int
+intelfb_release(struct fb_info *info, int user)
+{
+ struct intelfb_info *dinfo = GET_DINFO(info);
+
+ if (user) {
+ dinfo->open--;
+ msleep(1);
+ if (!dinfo->open) {
+ intelfbhw_disable_irq(dinfo);
+ }
+ }
+
+ return 0;
+}
+
+static int
intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
int change_var = 0;