drm/radeon/kms: switch to condition waiting for reclocking
Rafał Miłecki [Tue, 2 Mar 2010 21:06:51 +0000 (22:06 +0100)]
We tried to implement interruptible waiting with timeout (it was broken
anyway) which was not a good idea as explained by Andrew. It's possible
to avoid using additional variable but actually it inroduces using more
complex in-kernel tools. So simply add one variable for condition.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/rs600.c

index 91eb762..73f9a79 100644 (file)
@@ -312,10 +312,12 @@ int r100_irq_process(struct radeon_device *rdev)
                /* Vertical blank interrupts */
                if (status & RADEON_CRTC_VBLANK_STAT) {
                        drm_handle_vblank(rdev->ddev, 0);
+                       rdev->pm.vblank_sync = true;
                        wake_up(&rdev->irq.vblank_queue);
                }
                if (status & RADEON_CRTC2_VBLANK_STAT) {
                        drm_handle_vblank(rdev->ddev, 1);
+                       rdev->pm.vblank_sync = true;
                        wake_up(&rdev->irq.vblank_queue);
                }
                if (status & RADEON_FP_DETECT_STAT) {
index c522901..5b56a1b 100644 (file)
@@ -2765,6 +2765,7 @@ restart_ih:
                        case 0: /* D1 vblank */
                                if (disp_int & LB_D1_VBLANK_INTERRUPT) {
                                        drm_handle_vblank(rdev->ddev, 0);
+                                       rdev->pm.vblank_sync = true;
                                        wake_up(&rdev->irq.vblank_queue);
                                        disp_int &= ~LB_D1_VBLANK_INTERRUPT;
                                        DRM_DEBUG("IH: D1 vblank\n");
@@ -2786,6 +2787,7 @@ restart_ih:
                        case 0: /* D2 vblank */
                                if (disp_int & LB_D2_VBLANK_INTERRUPT) {
                                        drm_handle_vblank(rdev->ddev, 1);
+                                       rdev->pm.vblank_sync = true;
                                        wake_up(&rdev->irq.vblank_queue);
                                        disp_int &= ~LB_D2_VBLANK_INTERRUPT;
                                        DRM_DEBUG("IH: D2 vblank\n");
index ba93e5a..b54d4f3 100644 (file)
@@ -687,6 +687,7 @@ struct radeon_pm {
        bool                    downclocked;
        int                     active_crtcs;
        int                     req_vblank;
+       bool                    vblank_sync;
        fixed20_12              max_bandwidth;
        fixed20_12              igp_sideport_mclk;
        fixed20_12              igp_system_mclk;
index d4d1c39..d800b86 100644 (file)
@@ -353,10 +353,12 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
                rdev->pm.req_vblank |= (1 << 1);
                drm_vblank_get(rdev->ddev, 1);
        }
-       if (rdev->pm.active_crtcs)
-               wait_event_interruptible_timeout(
-                       rdev->irq.vblank_queue, 0,
+       if (rdev->pm.active_crtcs) {
+               rdev->pm.vblank_sync = false;
+               wait_event_timeout(
+                       rdev->irq.vblank_queue, rdev->pm.vblank_sync,
                        msecs_to_jiffies(RADEON_WAIT_VBLANK_TIMEOUT));
+       }
        if (rdev->pm.req_vblank & (1 << 0)) {
                rdev->pm.req_vblank &= ~(1 << 0);
                drm_vblank_put(rdev->ddev, 0);
index 47f046b..ac7c27a 100644 (file)
@@ -392,10 +392,12 @@ int rs600_irq_process(struct radeon_device *rdev)
                /* Vertical blank interrupts */
                if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) {
                        drm_handle_vblank(rdev->ddev, 0);
+                       rdev->pm.vblank_sync = true;
                        wake_up(&rdev->irq.vblank_queue);
                }
                if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) {
                        drm_handle_vblank(rdev->ddev, 1);
+                       rdev->pm.vblank_sync = true;
                        wake_up(&rdev->irq.vblank_queue);
                }
                if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) {