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);
 /* 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,
        if (!dinfo)
                return;
 
+       intelfbhw_disable_irq(dinfo);
+
        fb_dealloc_cmap(&dinfo->info->cmap);
        kfree(dinfo->info->pixmap.addr);
 
        }
 
        dinfo->registered = 1;
+       dinfo->open = 0;
+
+       init_waitqueue_head(&dinfo->vsync.wait);
+       spin_lock_init(&dinfo->int_lock);
+       dinfo->irq_flags = 0;
 
        return 0;
 
  *                       fbdev interface                       *
  ***************************************************************/
 
+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)
 {
 
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
+#include <linux/interrupt.h>
 
 #include <asm/io.h>
 
                addr += 16;
        }
 }
+
+static irqreturn_t
+intelfbhw_irq(int irq, void *dev_id, struct pt_regs *fp) {
+       int handled = 0;
+       u16 tmp;
+       struct intelfb_info *dinfo = (struct intelfb_info *)dev_id;
+
+       spin_lock(&dinfo->int_lock);
+
+       tmp = INREG16(IIR);
+       tmp &= VSYNC_PIPE_A_INTERRUPT;
+
+       if (tmp == 0) {
+               spin_unlock(&dinfo->int_lock);
+               return IRQ_RETVAL(handled);
+       }
+
+       OUTREG16(IIR, tmp);
+
+       if (tmp & VSYNC_PIPE_A_INTERRUPT) {
+               dinfo->vsync.count++;
+               wake_up_interruptible(&dinfo->vsync.wait);
+               handled = 1;
+       }
+
+       spin_unlock(&dinfo->int_lock);
+
+       return IRQ_RETVAL(handled);
+}
+
+int
+intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable) {
+
+       if (!test_and_set_bit(0, &dinfo->irq_flags)) {
+               if (request_irq(dinfo->pdev->irq, intelfbhw_irq, SA_SHIRQ, "intelfb", dinfo)) {
+                       clear_bit(0, &dinfo->irq_flags);
+                       return -EINVAL;
+               }
+
+               spin_lock_irq(&dinfo->int_lock);
+               OUTREG16(HWSTAM, 0xfffe);
+               OUTREG16(IMR, 0x0);
+               OUTREG16(IER, VSYNC_PIPE_A_INTERRUPT);
+               spin_unlock_irq(&dinfo->int_lock);
+       } else if (reenable) {
+               u16 ier;
+
+               spin_lock_irq(&dinfo->int_lock);
+               ier = INREG16(IER);
+               if ((ier & VSYNC_PIPE_A_INTERRUPT)) {
+                       DBG_MSG("someone disabled the IRQ [%08X]\n", ier);
+                       OUTREG(IER, VSYNC_PIPE_A_INTERRUPT);
+               }
+               spin_unlock_irq(&dinfo->int_lock);
+       }
+       return 0;
+}
+
+void
+intelfbhw_disable_irq(struct intelfb_info *dinfo) {
+       u16 tmp;
+
+       if (test_and_clear_bit(0, &dinfo->irq_flags)) {
+               spin_lock_irq(&dinfo->int_lock);
+               OUTREG16(HWSTAM, 0xffff);
+               OUTREG16(IMR, 0xffff);
+               OUTREG16(IER, 0x0);
+
+               tmp = INREG16(IIR);
+               OUTREG16(IIR, tmp);
+               spin_unlock_irq(&dinfo->int_lock);
+
+               free_irq(dinfo->pdev->irq, dinfo);
+       }
+}