+static int omapfb_do_vsync(struct fb_info *fbi,
+ struct omap_dss_device *display, u32 *frame, bool force)
+{
+ unsigned long timeout = usecs_to_jiffies(16667 * 2);
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ static u32 frame_tv;
+ bool is_tv = false;
+ u32 frame_dummy = 0;
+ int i, r;
+
+ if (frame == NULL)
+ frame = &frame_dummy;
+
+ /* try to find the first enabled overlay+display pair */
+ for (i = 0; i < ofbi->num_overlays; i++) {
+ struct omap_overlay_manager *manager;
+
+ if (!ofbi->overlays[i]->info.enabled)
+ continue;
+
+ manager = ofbi->overlays[i]->manager;
+ if (!manager)
+ continue;
+
+ if (manager->device->state
+ == OMAP_DSS_DISPLAY_ACTIVE)
+ {
+ display = manager->device;
+ break;
+ }
+ }
+
+ if (display->type == OMAP_DISPLAY_TYPE_VENC)
+ is_tv = true;
+
+ r = dispc_runtime_get();
+ if (r)
+ return r;
+
+ /* this is unsafe pandora hack, but should work as fb
+ * is compiled in (no worry about rmmod) and there
+ * is no way to rm fb instances at runtime */
+ unlock_fb_info(fbi);
+
+ if (is_tv) {
+ u32 irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
+ r = omap_dispc_wait_for_irq_interruptible_timeout(irq,
+ timeout);
+ /* there is no real frame counter for TV */
+ *frame = ++frame_tv;
+ }
+ else {
+ r = omap_dispc_wait_for_vsync_on_frame(frame,
+ timeout, force);
+ }
+
+ if (!lock_fb_info(fbi))
+ printk(KERN_ERR "omapfb: lock_fb_info failed\n");
+
+ dispc_runtime_put();
+
+ return r;
+}
+