diff options
author | Eric Hustvedt <ehustvedt@cecropia.com> | 2006-06-20 14:36:41 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2006-07-03 18:59:46 +1000 |
commit | 7649757bd900bc900adcd95ab08903cdc28342fa (patch) | |
tree | 4c710d9e458ff3c6731180aca738123886f7adec /drivers/video/intelfb/intelfbdrv.c | |
parent | 9a5f019b1a9ea6a75ba36d7c312ff069006ed479 (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.c | 39 |
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; |