intelfb: add vsync interrupt support

[05/05] intelfb: Honor FB_ACTIVATE_VBL for display panning

Extends the intelfb_vsync struct to store panning offset. The interrupt service routine uses the stored panning offset if a pan is requested for the vsync. intelfbhw_disable_irq also pans the display if there is a pending request.

Signed-off-by: Eric Hustvedt <ehustvedt@cecropia.com>
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 0f9631c..8038f55 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -371,7 +371,13 @@
 
 	offset += dinfo->fb.offset << 12;
 
-	OUTREG(DSPABASE, offset);
+	dinfo->vsync.pan_offset = offset;
+	if ((var->activate & FB_ACTIVATE_VBL) && !intelfbhw_enable_irq(dinfo, 0)) {
+		dinfo->vsync.pan_display = 1;
+	} else {
+		dinfo->vsync.pan_display = 0;
+		OUTREG(DSPABASE, offset);
+	}
 
 	return 0;
 }
@@ -1965,6 +1971,10 @@
 
 	if (tmp & VSYNC_PIPE_A_INTERRUPT) {
 		dinfo->vsync.count++;
+		if (dinfo->vsync.pan_display) {
+			dinfo->vsync.pan_display = 0;
+			OUTREG(DSPABASE, dinfo->vsync.pan_offset);
+		}
 		wake_up_interruptible(&dinfo->vsync.wait);
 		handled = 1;
 	}
@@ -2007,6 +2017,10 @@
 	u16 tmp;
 
 	if (test_and_clear_bit(0, &dinfo->irq_flags)) {
+		if (dinfo->vsync.pan_display) {
+			dinfo->vsync.pan_display = 0;
+			OUTREG(DSPABASE, dinfo->vsync.pan_offset);
+		}
 		spin_lock_irq(&dinfo->int_lock);
 		OUTREG16(HWSTAM, 0xffff);
 		OUTREG16(IMR, 0xffff);