drm/irq: track the irq installed in drm_irq_install in dev->irq
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / gpu / drm / drm_irq.c
index 91e8b4c..2c00b01 100644 (file)
@@ -271,14 +271,16 @@ static void drm_irq_vgaarb_nokms(void *cookie, bool state)
  */
 int drm_irq_install(struct drm_device *dev)
 {
-       int ret;
+       int ret, irq;
        unsigned long sh_flags = 0;
        char *irqname;
 
+       irq = drm_dev_to_irq(dev);
+
        if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
                return -EINVAL;
 
-       if (drm_dev_to_irq(dev) == 0)
+       if (irq == 0)
                return -EINVAL;
 
        mutex_lock(&dev->struct_mutex);
@@ -296,7 +298,7 @@ int drm_irq_install(struct drm_device *dev)
        dev->irq_enabled = true;
        mutex_unlock(&dev->struct_mutex);
 
-       DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
+       DRM_DEBUG("irq=%d\n", irq);
 
        /* Before installing handler */
        if (dev->driver->irq_preinstall)
@@ -311,7 +313,7 @@ int drm_irq_install(struct drm_device *dev)
        else
                irqname = dev->driver->name;
 
-       ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
+       ret = request_irq(irq, dev->driver->irq_handler,
                          sh_flags, irqname, dev);
 
        if (ret < 0) {
@@ -334,7 +336,9 @@ int drm_irq_install(struct drm_device *dev)
                mutex_unlock(&dev->struct_mutex);
                if (!drm_core_check_feature(dev, DRIVER_MODESET))
                        vga_client_register(dev->pdev, NULL, NULL, NULL);
-               free_irq(drm_dev_to_irq(dev), dev);
+               free_irq(irq, dev);
+       } else {
+               dev->irq = irq;
        }
 
        return ret;
@@ -379,7 +383,7 @@ int drm_irq_uninstall(struct drm_device *dev)
        if (!irq_enabled)
                return -EINVAL;
 
-       DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
+       DRM_DEBUG("irq=%d\n", dev->irq);
 
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                vga_client_register(dev->pdev, NULL, NULL, NULL);
@@ -387,7 +391,7 @@ int drm_irq_uninstall(struct drm_device *dev)
        if (dev->driver->irq_uninstall)
                dev->driver->irq_uninstall(dev);
 
-       free_irq(drm_dev_to_irq(dev), dev);
+       free_irq(dev->irq, dev);
 
        return 0;
 }
@@ -453,12 +457,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
        int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
        int dotclock = mode->crtc_clock;
 
-       /* Fields of interlaced scanout modes are only half a frame duration.
-        * Double the dotclock to get half the frame-/line-/pixelduration.
-        */
-       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-               dotclock *= 2;
-
        /* Valid dotclock? */
        if (dotclock > 0) {
                int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
@@ -471,6 +469,12 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
                pixeldur_ns = 1000000 / dotclock;
                linedur_ns  = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
                framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
+
+               /*
+                * Fields of interlaced scanout modes are only half a frame duration.
+                */
+               if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+                       framedur_ns /= 2;
        } else
                DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
                          crtc->base.id);
@@ -542,7 +546,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
 {
        ktime_t stime, etime, mono_time_offset;
        struct timeval tv_etime;
-       int vbl_status, vtotal, vdisplay;
+       int vbl_status;
        int vpos, hpos, i;
        int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns;
        bool invbl;
@@ -558,9 +562,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
                return -EIO;
        }
 
-       vtotal = mode->crtc_vtotal;
-       vdisplay = mode->crtc_vdisplay;
-
        /* Durations of frames, lines, pixels in nanoseconds. */
        framedur_ns = refcrtc->framedur_ns;
        linedur_ns  = refcrtc->linedur_ns;
@@ -569,7 +570,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
        /* If mode timing undefined, just return as no-op:
         * Happens during initial modesetting of a crtc.
         */
-       if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) {
+       if (framedur_ns == 0) {
                DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc);
                return -EAGAIN;
        }
@@ -586,7 +587,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
                 * Get vertical and horizontal scanout position vpos, hpos,
                 * and bounding timestamps stime, etime, pre/post query.
                 */
-               vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos,
+               vbl_status = dev->driver->get_scanout_position(dev, crtc, flags, &vpos,
                                                               &hpos, &stime, &etime);
 
                /*
@@ -633,24 +634,6 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
         */
        delta_ns = vpos * linedur_ns + hpos * pixeldur_ns;
 
-       /* Is vpos outside nominal vblank area, but less than
-        * 1/100 of a frame height away from start of vblank?
-        * If so, assume this isn't a massively delayed vblank
-        * interrupt, but a vblank interrupt that fired a few
-        * microseconds before true start of vblank. Compensate
-        * by adding a full frame duration to the final timestamp.
-        * Happens, e.g., on ATI R500, R600.
-        *
-        * We only do this if DRM_CALLED_FROM_VBLIRQ.
-        */
-       if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl &&
-           ((vdisplay - vpos) < vtotal / 100)) {
-               delta_ns = delta_ns - framedur_ns;
-
-               /* Signal this correction as "applied". */
-               vbl_status |= 0x8;
-       }
-
        if (!drm_timestamp_monotonic)
                etime = ktime_sub(etime, mono_time_offset);