diff mbox

[1/2] drm/radeon: Handle irqs only based on irq ring, not irq status regs.

Message ID 1435896187-25908-1-git-send-email-mario.kleiner.de@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Mario Kleiner July 3, 2015, 4:03 a.m. UTC
Trying to resolve issues with missed vblanks and impossible
values inside delivered kms pageflip completion events showed
that radeon's irq handling sometimes doesn't handle valid irqs,
but silently skips them. This was observed for vblank interrupts.

Although those irqs have corresponding events queued in the gpu's
irq ring at time of interrupt, and therefore the corresponding
handling code gets triggered by these events, the handling code
sometimes silently skipped processing the irq. The reason for those
skips is that the handling code double-checks for each irq event if
the corresponding irq status bits in the irq status registers
are set. Sometimes those bits are not set at time of check
for valid irqs, maybe due to some hardware race on some setups?

The problem only seems to happen on some machine + card combos
sometimes, e.g., never happened during my testing of different PC
cards of the DCE-2/3/4 generation a year ago, but happens consistently
now on two different Apple Mac cards (RV730, DCE-3, Apple iMac and
Evergreen JUNIPER, DCE-4 in a Apple MacPro). It also doesn't happen
at each interrupt but only occassionally every couple of
hundred or thousand vblank interrupts.

This results in XOrg warning messages like

"[  7084.472] (WW) RADEON(0): radeon_dri2_flip_event_handler:
Pageflip completion event has impossible msc 420120 < target_msc 420121"

as well as skipped frames and problems for applications that
use kms pageflip events or vblank events, e.g., users of DRI2 and
DRI3/Present, Waylands Weston compositor, etc. See also

https://bugs.freedesktop.org/show_bug.cgi?id=85203

After some talking to Alex and Michel, we decided to fix this
by turning the double-check for asserted irq status bits into a
warning. Whenever a irq event is queued in the IH ring, always
execute the corresponding interrupt handler. Still check the irq
status bits, but only to log a DRM_DEBUG message on a mismatch.

This fixed the problems reliably on both previously failing
cards, RV-730 dual-head tested on both crtcs (pipes D1 and D2)
and a triple-output Juniper HD-5770 card tested on all three
available crtcs (D1/D2/D3). The r600 and evergreen irq handling
is therefore tested, but the cik an si handling is only compile
tested due to lack of hw.

Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
CC: Michel Dänzer <michel.daenzer@amd.com>
CC: Alex Deucher <alexander.deucher@amd.com>

CC: <stable@vger.kernel.org> # v3.16+
---
 drivers/gpu/drm/radeon/cik.c       | 336 +++++++++++++++++--------------
 drivers/gpu/drm/radeon/evergreen.c | 392 ++++++++++++++++++++-----------------
 drivers/gpu/drm/radeon/r600.c      | 155 ++++++++-------
 drivers/gpu/drm/radeon/si.c        | 336 +++++++++++++++++--------------
 4 files changed, 688 insertions(+), 531 deletions(-)

Comments

Christian König July 3, 2015, 9:51 a.m. UTC | #1
On 03.07.2015 06:03, Mario Kleiner wrote:
> Trying to resolve issues with missed vblanks and impossible
> values inside delivered kms pageflip completion events showed
> that radeon's irq handling sometimes doesn't handle valid irqs,
> but silently skips them. This was observed for vblank interrupts.
>
> Although those irqs have corresponding events queued in the gpu's
> irq ring at time of interrupt, and therefore the corresponding
> handling code gets triggered by these events, the handling code
> sometimes silently skipped processing the irq. The reason for those
> skips is that the handling code double-checks for each irq event if
> the corresponding irq status bits in the irq status registers
> are set. Sometimes those bits are not set at time of check
> for valid irqs, maybe due to some hardware race on some setups?
>
> The problem only seems to happen on some machine + card combos
> sometimes, e.g., never happened during my testing of different PC
> cards of the DCE-2/3/4 generation a year ago, but happens consistently
> now on two different Apple Mac cards (RV730, DCE-3, Apple iMac and
> Evergreen JUNIPER, DCE-4 in a Apple MacPro). It also doesn't happen
> at each interrupt but only occassionally every couple of
> hundred or thousand vblank interrupts.
>
> This results in XOrg warning messages like
>
> "[  7084.472] (WW) RADEON(0): radeon_dri2_flip_event_handler:
> Pageflip completion event has impossible msc 420120 < target_msc 420121"
>
> as well as skipped frames and problems for applications that
> use kms pageflip events or vblank events, e.g., users of DRI2 and
> DRI3/Present, Waylands Weston compositor, etc. See also
>
> https://bugs.freedesktop.org/show_bug.cgi?id=85203
>
> After some talking to Alex and Michel, we decided to fix this
> by turning the double-check for asserted irq status bits into a
> warning. Whenever a irq event is queued in the IH ring, always
> execute the corresponding interrupt handler. Still check the irq
> status bits, but only to log a DRM_DEBUG message on a mismatch.
>
> This fixed the problems reliably on both previously failing
> cards, RV-730 dual-head tested on both crtcs (pipes D1 and D2)
> and a triple-output Juniper HD-5770 card tested on all three
> available crtcs (D1/D2/D3). The r600 and evergreen irq handling
> is therefore tested, but the cik an si handling is only compile
> tested due to lack of hw.
>
> Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
> CC: Michel Dänzer <michel.daenzer@amd.com>
> CC: Alex Deucher <alexander.deucher@amd.com>
>
> CC: <stable@vger.kernel.org> # v3.16+

I've always wondered why we do so, but simply assumed that there was a 
good reason for filtering those.

Both patches are Reviewed-by: Christian König <christian.koenig@amd.com>

Regards,
Christian.

> ---
>   drivers/gpu/drm/radeon/cik.c       | 336 +++++++++++++++++--------------
>   drivers/gpu/drm/radeon/evergreen.c | 392 ++++++++++++++++++++-----------------
>   drivers/gpu/drm/radeon/r600.c      | 155 ++++++++-------
>   drivers/gpu/drm/radeon/si.c        | 336 +++++++++++++++++--------------
>   4 files changed, 688 insertions(+), 531 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
> index b0688b0..35917e7 100644
> --- a/drivers/gpu/drm/radeon/cik.c
> +++ b/drivers/gpu/drm/radeon/cik.c
> @@ -7930,23 +7930,27 @@ restart_ih:
>   		case 1: /* D1 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D1 vblank */
> -				if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[0]) {
> -						drm_handle_vblank(rdev->ddev, 0);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[0]))
> -						radeon_crtc_handle_vblank(rdev, 0);
> -					rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D1 vblank\n");
> +				if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[0]) {
> +					drm_handle_vblank(rdev->ddev, 0);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[0]))
> +					radeon_crtc_handle_vblank(rdev, 0);
> +				rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D1 vblank\n");
> +
>   				break;
>   			case 1: /* D1 vline */
> -				if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D1 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D1 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -7956,23 +7960,27 @@ restart_ih:
>   		case 2: /* D2 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D2 vblank */
> -				if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[1]) {
> -						drm_handle_vblank(rdev->ddev, 1);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[1]))
> -						radeon_crtc_handle_vblank(rdev, 1);
> -					rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D2 vblank\n");
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[1]) {
> +					drm_handle_vblank(rdev->ddev, 1);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[1]))
> +					radeon_crtc_handle_vblank(rdev, 1);
> +				rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D2 vblank\n");
> +
>   				break;
>   			case 1: /* D2 vline */
> -				if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D2 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D2 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -7982,23 +7990,27 @@ restart_ih:
>   		case 3: /* D3 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D3 vblank */
> -				if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[2]) {
> -						drm_handle_vblank(rdev->ddev, 2);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[2]))
> -						radeon_crtc_handle_vblank(rdev, 2);
> -					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D3 vblank\n");
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[2]) {
> +					drm_handle_vblank(rdev->ddev, 2);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[2]))
> +					radeon_crtc_handle_vblank(rdev, 2);
> +				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D3 vblank\n");
> +
>   				break;
>   			case 1: /* D3 vline */
> -				if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D3 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D3 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -8008,23 +8020,27 @@ restart_ih:
>   		case 4: /* D4 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D4 vblank */
> -				if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[3]) {
> -						drm_handle_vblank(rdev->ddev, 3);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[3]))
> -						radeon_crtc_handle_vblank(rdev, 3);
> -					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D4 vblank\n");
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[3]) {
> +					drm_handle_vblank(rdev->ddev, 3);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[3]))
> +					radeon_crtc_handle_vblank(rdev, 3);
> +				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D4 vblank\n");
> +
>   				break;
>   			case 1: /* D4 vline */
> -				if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D4 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D4 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -8034,23 +8050,27 @@ restart_ih:
>   		case 5: /* D5 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D5 vblank */
> -				if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[4]) {
> -						drm_handle_vblank(rdev->ddev, 4);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[4]))
> -						radeon_crtc_handle_vblank(rdev, 4);
> -					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D5 vblank\n");
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[4]) {
> +					drm_handle_vblank(rdev->ddev, 4);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[4]))
> +					radeon_crtc_handle_vblank(rdev, 4);
> +				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D5 vblank\n");
> +
>   				break;
>   			case 1: /* D5 vline */
> -				if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D5 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D5 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -8060,23 +8080,27 @@ restart_ih:
>   		case 6: /* D6 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D6 vblank */
> -				if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[5]) {
> -						drm_handle_vblank(rdev->ddev, 5);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[5]))
> -						radeon_crtc_handle_vblank(rdev, 5);
> -					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D6 vblank\n");
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[5]) {
> +					drm_handle_vblank(rdev->ddev, 5);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[5]))
> +					radeon_crtc_handle_vblank(rdev, 5);
> +				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D6 vblank\n");
> +
>   				break;
>   			case 1: /* D6 vline */
> -				if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D6 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D6 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -8096,88 +8120,112 @@ restart_ih:
>   		case 42: /* HPD hotplug */
>   			switch (src_data) {
>   			case 0:
> -				if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD1\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD1\n");
> +
>   				break;
>   			case 1:
> -				if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD2\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD2\n");
> +
>   				break;
>   			case 2:
> -				if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD3\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD3\n");
> +
>   				break;
>   			case 3:
> -				if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD4\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD4\n");
> +
>   				break;
>   			case 4:
> -				if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD5\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD5\n");
> +
>   				break;
>   			case 5:
> -				if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD6\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD6\n");
> +
>   				break;
>   			case 6:
> -				if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 1\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 1\n");
> +
>   				break;
>   			case 7:
> -				if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 2\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 2\n");
> +
>   				break;
>   			case 8:
> -				if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 3\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 3\n");
> +
>   				break;
>   			case 9:
> -				if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 4\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 4\n");
> +
>   				break;
>   			case 10:
> -				if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 5\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 5\n");
> +
>   				break;
>   			case 11:
> -				if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 6\n");
> -				}
> +				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 6\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
> index 3a6d483..0acde19 100644
> --- a/drivers/gpu/drm/radeon/evergreen.c
> +++ b/drivers/gpu/drm/radeon/evergreen.c
> @@ -4924,7 +4924,7 @@ restart_ih:
>   		return IRQ_NONE;
>   
>   	rptr = rdev->ih.rptr;
> -	DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
> +	DRM_DEBUG("evergreen_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
>   
>   	/* Order reading of wptr vs. reading of IH ring data */
>   	rmb();
> @@ -4942,23 +4942,27 @@ restart_ih:
>   		case 1: /* D1 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D1 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[0]) {
> -						drm_handle_vblank(rdev->ddev, 0);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[0]))
> -						radeon_crtc_handle_vblank(rdev, 0);
> -					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D1 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[0]) {
> +					drm_handle_vblank(rdev->ddev, 0);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[0]))
> +					radeon_crtc_handle_vblank(rdev, 0);
> +				rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D1 vblank\n");
> +
>   				break;
>   			case 1: /* D1 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D1 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: D1 vline - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D1 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -4968,23 +4972,27 @@ restart_ih:
>   		case 2: /* D2 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D2 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[1]) {
> -						drm_handle_vblank(rdev->ddev, 1);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[1]))
> -						radeon_crtc_handle_vblank(rdev, 1);
> -					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D2 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[1]) {
> +					drm_handle_vblank(rdev->ddev, 1);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[1]))
> +					radeon_crtc_handle_vblank(rdev, 1);
> +				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D2 vblank\n");
> +
>   				break;
>   			case 1: /* D2 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D2 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: D2 vline - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D2 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -4994,23 +5002,27 @@ restart_ih:
>   		case 3: /* D3 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D3 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[2]) {
> -						drm_handle_vblank(rdev->ddev, 2);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[2]))
> -						radeon_crtc_handle_vblank(rdev, 2);
> -					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D3 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: D3 vblank - IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[2]) {
> +					drm_handle_vblank(rdev->ddev, 2);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[2]))
> +					radeon_crtc_handle_vblank(rdev, 2);
> +				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D3 vblank\n");
> +
>   				break;
>   			case 1: /* D3 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D3 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: D3 vline - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D3 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -5020,23 +5032,27 @@ restart_ih:
>   		case 4: /* D4 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D4 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[3]) {
> -						drm_handle_vblank(rdev->ddev, 3);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[3]))
> -						radeon_crtc_handle_vblank(rdev, 3);
> -					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D4 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: D4 vblank - IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[3]) {
> +					drm_handle_vblank(rdev->ddev, 3);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[3]))
> +					radeon_crtc_handle_vblank(rdev, 3);
> +				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D4 vblank\n");
> +
>   				break;
>   			case 1: /* D4 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D4 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: D4 vline - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D4 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -5046,23 +5062,27 @@ restart_ih:
>   		case 5: /* D5 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D5 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[4]) {
> -						drm_handle_vblank(rdev->ddev, 4);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[4]))
> -						radeon_crtc_handle_vblank(rdev, 4);
> -					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D5 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: D5 vblank - IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[4]) {
> +					drm_handle_vblank(rdev->ddev, 4);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[4]))
> +					radeon_crtc_handle_vblank(rdev, 4);
> +				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D5 vblank\n");
> +
>   				break;
>   			case 1: /* D5 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D5 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: D5 vline - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D5 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -5072,23 +5092,27 @@ restart_ih:
>   		case 6: /* D6 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D6 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[5]) {
> -						drm_handle_vblank(rdev->ddev, 5);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[5]))
> -						radeon_crtc_handle_vblank(rdev, 5);
> -					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D6 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: D6 vblank - IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[5]) {
> +					drm_handle_vblank(rdev->ddev, 5);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[5]))
> +					radeon_crtc_handle_vblank(rdev, 5);
> +				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D6 vblank\n");
> +
>   				break;
>   			case 1: /* D6 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D6 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: D6 vline - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D6 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -5108,88 +5132,100 @@ restart_ih:
>   		case 42: /* HPD hotplug */
>   			switch (src_data) {
>   			case 0:
> -				if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD1\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD1\n");
>   				break;
>   			case 1:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD2\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD2\n");
>   				break;
>   			case 2:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD3\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD3\n");
>   				break;
>   			case 3:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD4\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD4\n");
>   				break;
>   			case 4:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD5\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD5\n");
>   				break;
>   			case 5:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD6\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD6\n");
>   				break;
>   			case 6:
> -				if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 1\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 1\n");
>   				break;
>   			case 7:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 2\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 2\n");
>   				break;
>   			case 8:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 3\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 3\n");
>   				break;
>   			case 9:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 4\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 4\n");
>   				break;
>   			case 10:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 5\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 5\n");
>   				break;
>   			case 11:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 6\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 6\n");
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -5199,46 +5235,52 @@ restart_ih:
>   		case 44: /* hdmi */
>   			switch (src_data) {
>   			case 0:
> -				if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) {
> -					rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG;
> -					queue_hdmi = true;
> -					DRM_DEBUG("IH: HDMI0\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG;
> +				queue_hdmi = true;
> +				DRM_DEBUG("IH: HDMI0\n");
>   				break;
>   			case 1:
> -				if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) {
> -					rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG;
> -					queue_hdmi = true;
> -					DRM_DEBUG("IH: HDMI1\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG;
> +				queue_hdmi = true;
> +				DRM_DEBUG("IH: HDMI1\n");
>   				break;
>   			case 2:
> -				if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) {
> -					rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG;
> -					queue_hdmi = true;
> -					DRM_DEBUG("IH: HDMI2\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG;
> +				queue_hdmi = true;
> +				DRM_DEBUG("IH: HDMI2\n");
>   				break;
>   			case 3:
> -				if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) {
> -					rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG;
> -					queue_hdmi = true;
> -					DRM_DEBUG("IH: HDMI3\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG;
> +				queue_hdmi = true;
> +				DRM_DEBUG("IH: HDMI3\n");
>   				break;
>   			case 4:
> -				if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) {
> -					rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG;
> -					queue_hdmi = true;
> -					DRM_DEBUG("IH: HDMI4\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG;
> +				queue_hdmi = true;
> +				DRM_DEBUG("IH: HDMI4\n");
>   				break;
>   			case 5:
> -				if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) {
> -					rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG;
> -					queue_hdmi = true;
> -					DRM_DEBUG("IH: HDMI5\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG;
> +				queue_hdmi = true;
> +				DRM_DEBUG("IH: HDMI5\n");
>   				break;
>   			default:
>   				DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
> diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
> index 35dafd7..4ea5b10 100644
> --- a/drivers/gpu/drm/radeon/r600.c
> +++ b/drivers/gpu/drm/radeon/r600.c
> @@ -4086,23 +4086,27 @@ restart_ih:
>   		case 1: /* D1 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D1 vblank */
> -				if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[0]) {
> -						drm_handle_vblank(rdev->ddev, 0);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[0]))
> -						radeon_crtc_handle_vblank(rdev, 0);
> -					rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D1 vblank\n");
> +				if (!(rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[0]) {
> +					drm_handle_vblank(rdev->ddev, 0);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[0]))
> +					radeon_crtc_handle_vblank(rdev, 0);
> +				rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D1 vblank\n");
> +
>   				break;
>   			case 1: /* D1 vline */
> -				if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D1 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT))
> +				    DRM_DEBUG("IH: D1 vline - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D1 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -4112,23 +4116,27 @@ restart_ih:
>   		case 5: /* D2 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D2 vblank */
> -				if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[1]) {
> -						drm_handle_vblank(rdev->ddev, 1);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[1]))
> -						radeon_crtc_handle_vblank(rdev, 1);
> -					rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D2 vblank\n");
> +				if (!(rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[1]) {
> +					drm_handle_vblank(rdev->ddev, 1);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[1]))
> +					radeon_crtc_handle_vblank(rdev, 1);
> +				rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D2 vblank\n");
> +
>   				break;
>   			case 1: /* D1 vline */
> -				if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D2 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: D2 vline - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D2 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -4148,46 +4156,53 @@ restart_ih:
>   		case 19: /* HPD/DAC hotplug */
>   			switch (src_data) {
>   			case 0:
> -				if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) {
> -					rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD1\n");
> -				}
> +				if (!(rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT))
> +					DRM_DEBUG("IH: HPD1 - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD1\n");
>   				break;
>   			case 1:
> -				if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) {
> -					rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD2\n");
> -				}
> +				if (!(rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT))
> +					DRM_DEBUG("IH: HPD2 - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD2\n");
>   				break;
>   			case 4:
> -				if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) {
> -					rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD3\n");
> -				}
> +				if (!(rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT))
> +					DRM_DEBUG("IH: HPD3 - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD3\n");
>   				break;
>   			case 5:
> -				if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) {
> -					rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD4\n");
> -				}
> +				if (!(rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT))
> +					DRM_DEBUG("IH: HPD4 - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD4\n");
>   				break;
>   			case 10:
> -				if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) {
> -					rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD5\n");
> -				}
> +				if (!(rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT))
> +					DRM_DEBUG("IH: HPD5 - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD5\n");
>   				break;
>   			case 12:
> -				if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) {
> -					rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD6\n");
> -				}
> +				if (!(rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT))
> +					DRM_DEBUG("IH: HPD6 - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD6\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -4197,18 +4212,22 @@ restart_ih:
>   		case 21: /* hdmi */
>   			switch (src_data) {
>   			case 4:
> -				if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) {
> -					rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG;
> -					queue_hdmi = true;
> -					DRM_DEBUG("IH: HDMI0\n");
> -				}
> +				if (!(rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG))
> +					DRM_DEBUG("IH: HDMI0 - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG;
> +				queue_hdmi = true;
> +				DRM_DEBUG("IH: HDMI0\n");
> +
>   				break;
>   			case 5:
> -				if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) {
> -					rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG;
> -					queue_hdmi = true;
> -					DRM_DEBUG("IH: HDMI1\n");
> -				}
> +				if (!(rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG))
> +					DRM_DEBUG("IH: HDMI1 - IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG;
> +				queue_hdmi = true;
> +				DRM_DEBUG("IH: HDMI1\n");
> +
>   				break;
>   			default:
>   				DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
> diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
> index 26388b5..07037e3 100644
> --- a/drivers/gpu/drm/radeon/si.c
> +++ b/drivers/gpu/drm/radeon/si.c
> @@ -6466,23 +6466,27 @@ restart_ih:
>   		case 1: /* D1 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D1 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[0]) {
> -						drm_handle_vblank(rdev->ddev, 0);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[0]))
> -						radeon_crtc_handle_vblank(rdev, 0);
> -					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D1 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[0]) {
> +					drm_handle_vblank(rdev->ddev, 0);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[0]))
> +					radeon_crtc_handle_vblank(rdev, 0);
> +				rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D1 vblank\n");
> +
>   				break;
>   			case 1: /* D1 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D1 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D1 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -6492,23 +6496,27 @@ restart_ih:
>   		case 2: /* D2 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D2 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[1]) {
> -						drm_handle_vblank(rdev->ddev, 1);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[1]))
> -						radeon_crtc_handle_vblank(rdev, 1);
> -					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D2 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[1]) {
> +					drm_handle_vblank(rdev->ddev, 1);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[1]))
> +					radeon_crtc_handle_vblank(rdev, 1);
> +				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D2 vblank\n");
> +
>   				break;
>   			case 1: /* D2 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D2 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D2 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -6518,23 +6526,27 @@ restart_ih:
>   		case 3: /* D3 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D3 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[2]) {
> -						drm_handle_vblank(rdev->ddev, 2);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[2]))
> -						radeon_crtc_handle_vblank(rdev, 2);
> -					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D3 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[2]) {
> +					drm_handle_vblank(rdev->ddev, 2);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[2]))
> +					radeon_crtc_handle_vblank(rdev, 2);
> +				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D3 vblank\n");
> +
>   				break;
>   			case 1: /* D3 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D3 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D3 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -6544,23 +6556,27 @@ restart_ih:
>   		case 4: /* D4 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D4 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[3]) {
> -						drm_handle_vblank(rdev->ddev, 3);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[3]))
> -						radeon_crtc_handle_vblank(rdev, 3);
> -					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D4 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[3]) {
> +					drm_handle_vblank(rdev->ddev, 3);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[3]))
> +					radeon_crtc_handle_vblank(rdev, 3);
> +				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D4 vblank\n");
> +
>   				break;
>   			case 1: /* D4 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D4 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D4 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -6570,23 +6586,27 @@ restart_ih:
>   		case 5: /* D5 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D5 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[4]) {
> -						drm_handle_vblank(rdev->ddev, 4);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[4]))
> -						radeon_crtc_handle_vblank(rdev, 4);
> -					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D5 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[4]) {
> +					drm_handle_vblank(rdev->ddev, 4);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[4]))
> +					radeon_crtc_handle_vblank(rdev, 4);
> +				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D5 vblank\n");
> +
>   				break;
>   			case 1: /* D5 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D5 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D5 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -6596,23 +6616,27 @@ restart_ih:
>   		case 6: /* D6 vblank/vline */
>   			switch (src_data) {
>   			case 0: /* D6 vblank */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) {
> -					if (rdev->irq.crtc_vblank_int[5]) {
> -						drm_handle_vblank(rdev->ddev, 5);
> -						rdev->pm.vblank_sync = true;
> -						wake_up(&rdev->irq.vblank_queue);
> -					}
> -					if (atomic_read(&rdev->irq.pflip[5]))
> -						radeon_crtc_handle_vblank(rdev, 5);
> -					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
> -					DRM_DEBUG("IH: D6 vblank\n");
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				if (rdev->irq.crtc_vblank_int[5]) {
> +					drm_handle_vblank(rdev->ddev, 5);
> +					rdev->pm.vblank_sync = true;
> +					wake_up(&rdev->irq.vblank_queue);
>   				}
> +				if (atomic_read(&rdev->irq.pflip[5]))
> +					radeon_crtc_handle_vblank(rdev, 5);
> +				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
> +				DRM_DEBUG("IH: D6 vblank\n");
> +
>   				break;
>   			case 1: /* D6 vline */
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
> -					DRM_DEBUG("IH: D6 vline\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
> +				DRM_DEBUG("IH: D6 vline\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
> @@ -6632,88 +6656,112 @@ restart_ih:
>   		case 42: /* HPD hotplug */
>   			switch (src_data) {
>   			case 0:
> -				if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD1\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD1\n");
> +
>   				break;
>   			case 1:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD2\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD2\n");
> +
>   				break;
>   			case 2:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD3\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD3\n");
> +
>   				break;
>   			case 3:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD4\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD4\n");
> +
>   				break;
>   			case 4:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD5\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD5\n");
> +
>   				break;
>   			case 5:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
> -					queue_hotplug = true;
> -					DRM_DEBUG("IH: HPD6\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
> +				queue_hotplug = true;
> +				DRM_DEBUG("IH: HPD6\n");
> +
>   				break;
>   			case 6:
> -				if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 1\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 1\n");
> +
>   				break;
>   			case 7:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 2\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 2\n");
> +
>   				break;
>   			case 8:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 3\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 3\n");
> +
>   				break;
>   			case 9:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 4\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 4\n");
> +
>   				break;
>   			case 10:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 5\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 5\n");
> +
>   				break;
>   			case 11:
> -				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) {
> -					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
> -					queue_dp = true;
> -					DRM_DEBUG("IH: HPD_RX 6\n");
> -				}
> +				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT))
> +					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
> +
> +				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
> +				queue_dp = true;
> +				DRM_DEBUG("IH: HPD_RX 6\n");
> +
>   				break;
>   			default:
>   				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
Alex Deucher July 6, 2015, 9:05 p.m. UTC | #2
On Fri, Jul 3, 2015 at 5:51 AM, Christian König <deathsimple@vodafone.de> wrote:
> On 03.07.2015 06:03, Mario Kleiner wrote:
>>
>> Trying to resolve issues with missed vblanks and impossible
>> values inside delivered kms pageflip completion events showed
>> that radeon's irq handling sometimes doesn't handle valid irqs,
>> but silently skips them. This was observed for vblank interrupts.
>>
>> Although those irqs have corresponding events queued in the gpu's
>> irq ring at time of interrupt, and therefore the corresponding
>> handling code gets triggered by these events, the handling code
>> sometimes silently skipped processing the irq. The reason for those
>> skips is that the handling code double-checks for each irq event if
>> the corresponding irq status bits in the irq status registers
>> are set. Sometimes those bits are not set at time of check
>> for valid irqs, maybe due to some hardware race on some setups?
>>
>> The problem only seems to happen on some machine + card combos
>> sometimes, e.g., never happened during my testing of different PC
>> cards of the DCE-2/3/4 generation a year ago, but happens consistently
>> now on two different Apple Mac cards (RV730, DCE-3, Apple iMac and
>> Evergreen JUNIPER, DCE-4 in a Apple MacPro). It also doesn't happen
>> at each interrupt but only occassionally every couple of
>> hundred or thousand vblank interrupts.
>>
>> This results in XOrg warning messages like
>>
>> "[  7084.472] (WW) RADEON(0): radeon_dri2_flip_event_handler:
>> Pageflip completion event has impossible msc 420120 < target_msc 420121"
>>
>> as well as skipped frames and problems for applications that
>> use kms pageflip events or vblank events, e.g., users of DRI2 and
>> DRI3/Present, Waylands Weston compositor, etc. See also
>>
>> https://bugs.freedesktop.org/show_bug.cgi?id=85203
>>
>> After some talking to Alex and Michel, we decided to fix this
>> by turning the double-check for asserted irq status bits into a
>> warning. Whenever a irq event is queued in the IH ring, always
>> execute the corresponding interrupt handler. Still check the irq
>> status bits, but only to log a DRM_DEBUG message on a mismatch.
>>
>> This fixed the problems reliably on both previously failing
>> cards, RV-730 dual-head tested on both crtcs (pipes D1 and D2)
>> and a triple-output Juniper HD-5770 card tested on all three
>> available crtcs (D1/D2/D3). The r600 and evergreen irq handling
>> is therefore tested, but the cik an si handling is only compile
>> tested due to lack of hw.
>>
>> Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
>> CC: Michel Dänzer <michel.daenzer@amd.com>
>> CC: Alex Deucher <alexander.deucher@amd.com>
>>
>> CC: <stable@vger.kernel.org> # v3.16+
>

Applied the series.  Thanks!

Alex


>
> I've always wondered why we do so, but simply assumed that there was a good
> reason for filtering those.
>
> Both patches are Reviewed-by: Christian König <christian.koenig@amd.com>
>
> Regards,
> Christian.
>
>> ---
>>   drivers/gpu/drm/radeon/cik.c       | 336 +++++++++++++++++--------------
>>   drivers/gpu/drm/radeon/evergreen.c | 392
>> ++++++++++++++++++++-----------------
>>   drivers/gpu/drm/radeon/r600.c      | 155 ++++++++-------
>>   drivers/gpu/drm/radeon/si.c        | 336 +++++++++++++++++--------------
>>   4 files changed, 688 insertions(+), 531 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
>> index b0688b0..35917e7 100644
>> --- a/drivers/gpu/drm/radeon/cik.c
>> +++ b/drivers/gpu/drm/radeon/cik.c
>> @@ -7930,23 +7930,27 @@ restart_ih:
>>                 case 1: /* D1 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D1 vblank */
>> -                               if (rdev->irq.stat_regs.cik.disp_int &
>> LB_D1_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[0])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 0);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[0]))
>> -
>> radeon_crtc_handle_vblank(rdev, 0);
>> -                                       rdev->irq.stat_regs.cik.disp_int
>> &= ~LB_D1_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D1 vblank\n");
>> +                               if (!(rdev->irq.stat_regs.cik.disp_int &
>> LB_D1_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[0]) {
>> +                                       drm_handle_vblank(rdev->ddev, 0);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[0]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 0);
>> +                               rdev->irq.stat_regs.cik.disp_int &=
>> ~LB_D1_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D1 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D1 vline */
>> -                               if (rdev->irq.stat_regs.cik.disp_int &
>> LB_D1_VLINE_INTERRUPT) {
>> -                                       rdev->irq.stat_regs.cik.disp_int
>> &= ~LB_D1_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D1 vline\n");
>> -                               }
>> +                               if (!(rdev->irq.stat_regs.cik.disp_int &
>> LB_D1_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int &=
>> ~LB_D1_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D1 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -7956,23 +7960,27 @@ restart_ih:
>>                 case 2: /* D2 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D2 vblank */
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont
>> & LB_D2_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[1])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 1);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[1]))
>> -
>> radeon_crtc_handle_vblank(rdev, 1);
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D2 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[1]) {
>> +                                       drm_handle_vblank(rdev->ddev, 1);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[1]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 1);
>> +                               rdev->irq.stat_regs.cik.disp_int_cont &=
>> ~LB_D2_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D2 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D2 vline */
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont
>> & LB_D2_VLINE_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D2 vline\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont &=
>> ~LB_D2_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D2 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -7982,23 +7990,27 @@ restart_ih:
>>                 case 3: /* D3 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D3 vblank */
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont2
>> & LB_D3_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[2])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 2);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[2]))
>> -
>> radeon_crtc_handle_vblank(rdev, 2);
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D3 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[2]) {
>> +                                       drm_handle_vblank(rdev->ddev, 2);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[2]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 2);
>> +                               rdev->irq.stat_regs.cik.disp_int_cont2 &=
>> ~LB_D3_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D3 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D3 vline */
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont2
>> & LB_D3_VLINE_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D3 vline\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont2 &=
>> ~LB_D3_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D3 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -8008,23 +8020,27 @@ restart_ih:
>>                 case 4: /* D4 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D4 vblank */
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont3
>> & LB_D4_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[3])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 3);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[3]))
>> -
>> radeon_crtc_handle_vblank(rdev, 3);
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D4 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[3]) {
>> +                                       drm_handle_vblank(rdev->ddev, 3);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[3]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 3);
>> +                               rdev->irq.stat_regs.cik.disp_int_cont3 &=
>> ~LB_D4_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D4 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D4 vline */
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont3
>> & LB_D4_VLINE_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D4 vline\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont3 &=
>> ~LB_D4_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D4 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -8034,23 +8050,27 @@ restart_ih:
>>                 case 5: /* D5 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D5 vblank */
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont4
>> & LB_D5_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[4])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 4);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[4]))
>> -
>> radeon_crtc_handle_vblank(rdev, 4);
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D5 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[4]) {
>> +                                       drm_handle_vblank(rdev->ddev, 4);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[4]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 4);
>> +                               rdev->irq.stat_regs.cik.disp_int_cont4 &=
>> ~LB_D5_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D5 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D5 vline */
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont4
>> & LB_D5_VLINE_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D5 vline\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont4 &=
>> ~LB_D5_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D5 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -8060,23 +8080,27 @@ restart_ih:
>>                 case 6: /* D6 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D6 vblank */
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont5
>> & LB_D6_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[5])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 5);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[5]))
>> -
>> radeon_crtc_handle_vblank(rdev, 5);
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D6 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[5]) {
>> +                                       drm_handle_vblank(rdev->ddev, 5);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[5]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 5);
>> +                               rdev->irq.stat_regs.cik.disp_int_cont5 &=
>> ~LB_D6_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D6 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D6 vline */
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont5
>> & LB_D6_VLINE_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D6 vline\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont5 &=
>> ~LB_D6_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D6 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -8096,88 +8120,112 @@ restart_ih:
>>                 case 42: /* HPD hotplug */
>>                         switch (src_data) {
>>                         case 0:
>> -                               if (rdev->irq.stat_regs.cik.disp_int &
>> DC_HPD1_INTERRUPT) {
>> -                                       rdev->irq.stat_regs.cik.disp_int
>> &= ~DC_HPD1_INTERRUPT;
>> -                                       queue_hotplug = true;
>> -                                       DRM_DEBUG("IH: HPD1\n");
>> -                               }
>> +                               if (!(rdev->irq.stat_regs.cik.disp_int &
>> DC_HPD1_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int &=
>> ~DC_HPD1_INTERRUPT;
>> +                               queue_hotplug = true;
>> +                               DRM_DEBUG("IH: HPD1\n");
>> +
>>                                 break;
>>                         case 1:
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont
>> & DC_HPD2_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT;
>> -                                       queue_hotplug = true;
>> -                                       DRM_DEBUG("IH: HPD2\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont &=
>> ~DC_HPD2_INTERRUPT;
>> +                               queue_hotplug = true;
>> +                               DRM_DEBUG("IH: HPD2\n");
>> +
>>                                 break;
>>                         case 2:
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont2
>> & DC_HPD3_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
>> -                                       queue_hotplug = true;
>> -                                       DRM_DEBUG("IH: HPD3\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont2 &=
>> ~DC_HPD3_INTERRUPT;
>> +                               queue_hotplug = true;
>> +                               DRM_DEBUG("IH: HPD3\n");
>> +
>>                                 break;
>>                         case 3:
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont3
>> & DC_HPD4_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
>> -                                       queue_hotplug = true;
>> -                                       DRM_DEBUG("IH: HPD4\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont3 &=
>> ~DC_HPD4_INTERRUPT;
>> +                               queue_hotplug = true;
>> +                               DRM_DEBUG("IH: HPD4\n");
>> +
>>                                 break;
>>                         case 4:
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont4
>> & DC_HPD5_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
>> -                                       queue_hotplug = true;
>> -                                       DRM_DEBUG("IH: HPD5\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont4 &=
>> ~DC_HPD5_INTERRUPT;
>> +                               queue_hotplug = true;
>> +                               DRM_DEBUG("IH: HPD5\n");
>> +
>>                                 break;
>>                         case 5:
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont5
>> & DC_HPD6_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
>> -                                       queue_hotplug = true;
>> -                                       DRM_DEBUG("IH: HPD6\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont5 &=
>> ~DC_HPD6_INTERRUPT;
>> +                               queue_hotplug = true;
>> +                               DRM_DEBUG("IH: HPD6\n");
>> +
>>                                 break;
>>                         case 6:
>> -                               if (rdev->irq.stat_regs.cik.disp_int &
>> DC_HPD1_RX_INTERRUPT) {
>> -                                       rdev->irq.stat_regs.cik.disp_int
>> &= ~DC_HPD1_RX_INTERRUPT;
>> -                                       queue_dp = true;
>> -                                       DRM_DEBUG("IH: HPD_RX 1\n");
>> -                               }
>> +                               if (!(rdev->irq.stat_regs.cik.disp_int &
>> DC_HPD1_RX_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int &=
>> ~DC_HPD1_RX_INTERRUPT;
>> +                               queue_dp = true;
>> +                               DRM_DEBUG("IH: HPD_RX 1\n");
>> +
>>                                 break;
>>                         case 7:
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont
>> & DC_HPD2_RX_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
>> -                                       queue_dp = true;
>> -                                       DRM_DEBUG("IH: HPD_RX 2\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont &=
>> ~DC_HPD2_RX_INTERRUPT;
>> +                               queue_dp = true;
>> +                               DRM_DEBUG("IH: HPD_RX 2\n");
>> +
>>                                 break;
>>                         case 8:
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont2
>> & DC_HPD3_RX_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
>> -                                       queue_dp = true;
>> -                                       DRM_DEBUG("IH: HPD_RX 3\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont2 &=
>> ~DC_HPD3_RX_INTERRUPT;
>> +                               queue_dp = true;
>> +                               DRM_DEBUG("IH: HPD_RX 3\n");
>> +
>>                                 break;
>>                         case 9:
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont3
>> & DC_HPD4_RX_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
>> -                                       queue_dp = true;
>> -                                       DRM_DEBUG("IH: HPD_RX 4\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont3 &=
>> ~DC_HPD4_RX_INTERRUPT;
>> +                               queue_dp = true;
>> +                               DRM_DEBUG("IH: HPD_RX 4\n");
>> +
>>                                 break;
>>                         case 10:
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont4
>> & DC_HPD5_RX_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
>> -                                       queue_dp = true;
>> -                                       DRM_DEBUG("IH: HPD_RX 5\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont4 &=
>> ~DC_HPD5_RX_INTERRUPT;
>> +                               queue_dp = true;
>> +                               DRM_DEBUG("IH: HPD_RX 5\n");
>> +
>>                                 break;
>>                         case 11:
>> -                               if (rdev->irq.stat_regs.cik.disp_int_cont5
>> & DC_HPD6_RX_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
>> -                                       queue_dp = true;
>> -                                       DRM_DEBUG("IH: HPD_RX 6\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT))
>> +                                       DRM_DEBUG("IH: IH event w/o
>> asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.cik.disp_int_cont5 &=
>> ~DC_HPD6_RX_INTERRUPT;
>> +                               queue_dp = true;
>> +                               DRM_DEBUG("IH: HPD_RX 6\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> diff --git a/drivers/gpu/drm/radeon/evergreen.c
>> b/drivers/gpu/drm/radeon/evergreen.c
>> index 3a6d483..0acde19 100644
>> --- a/drivers/gpu/drm/radeon/evergreen.c
>> +++ b/drivers/gpu/drm/radeon/evergreen.c
>> @@ -4924,7 +4924,7 @@ restart_ih:
>>                 return IRQ_NONE;
>>         rptr = rdev->ih.rptr;
>> -       DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr,
>> wptr);
>> +       DRM_DEBUG("evergreen_irq_process start: rptr %d, wptr %d\n", rptr,
>> wptr);
>>         /* Order reading of wptr vs. reading of IH ring data */
>>         rmb();
>> @@ -4942,23 +4942,27 @@ restart_ih:
>>                 case 1: /* D1 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D1 vblank */
>> -                               if (rdev->irq.stat_regs.evergreen.disp_int
>> & LB_D1_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[0])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 0);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[0]))
>> -
>> radeon_crtc_handle_vblank(rdev, 0);
>> -
>> rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D1 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: D1 vblank - IH
>> event w/o asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[0]) {
>> +                                       drm_handle_vblank(rdev->ddev, 0);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[0]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 0);
>> +                               rdev->irq.stat_regs.evergreen.disp_int &=
>> ~LB_D1_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D1 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D1 vline */
>> -                               if (rdev->irq.stat_regs.evergreen.disp_int
>> & LB_D1_VLINE_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D1 vline\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: D1 vline - IH event
>> w/o asserted irq bit?\n");
>> +
>> +                               rdev->irq.stat_regs.evergreen.disp_int &=
>> ~LB_D1_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D1 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -4968,23 +4972,27 @@ restart_ih:
>>                 case 2: /* D2 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D2 vblank */
>> -                               if
>> (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[1])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 1);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[1]))
>> -
>> radeon_crtc_handle_vblank(rdev, 1);
>> -
>> rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D2 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: D2 vblank - IH
>> event w/o asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[1]) {
>> +                                       drm_handle_vblank(rdev->ddev, 1);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[1]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 1);
>> +
>> rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D2 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D2 vline */
>> -                               if
>> (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D2 vline\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: D2 vline - IH event
>> w/o asserted irq bit?\n");
>> +
>> +
>> rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D2 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -4994,23 +5002,27 @@ restart_ih:
>>                 case 3: /* D3 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D3 vblank */
>> -                               if
>> (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[2])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 2);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[2]))
>> -
>> radeon_crtc_handle_vblank(rdev, 2);
>> -
>> rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D3 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: D3 vblank - IH
>> event w/o asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[2]) {
>> +                                       drm_handle_vblank(rdev->ddev, 2);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[2]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 2);
>> +
>> rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D3 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D3 vline */
>> -                               if
>> (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D3 vline\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: D3 vline - IH event
>> w/o asserted irq bit?\n");
>> +
>> +
>> rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D3 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -5020,23 +5032,27 @@ restart_ih:
>>                 case 4: /* D4 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D4 vblank */
>> -                               if
>> (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[3])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 3);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[3]))
>> -
>> radeon_crtc_handle_vblank(rdev, 3);
>> -
>> rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D4 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: D4 vblank - IH
>> event w/o asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[3]) {
>> +                                       drm_handle_vblank(rdev->ddev, 3);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[3]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 3);
>> +
>> rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D4 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D4 vline */
>> -                               if
>> (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D4 vline\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: D4 vline - IH event
>> w/o asserted irq bit?\n");
>> +
>> +
>> rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D4 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -5046,23 +5062,27 @@ restart_ih:
>>                 case 5: /* D5 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D5 vblank */
>> -                               if
>> (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[4])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 4);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[4]))
>> -
>> radeon_crtc_handle_vblank(rdev, 4);
>> -
>> rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D5 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT))
>> +                                       DRM_DEBUG("IH: D5 vblank - IH
>> event w/o asserted irq bit?\n");
>> +
>> +                               if (rdev->irq.crtc_vblank_int[4]) {
>> +                                       drm_handle_vblank(rdev->ddev, 4);
>> +                                       rdev->pm.vblank_sync = true;
>> +                                       wake_up(&rdev->irq.vblank_queue);
>>                                 }
>> +                               if (atomic_read(&rdev->irq.pflip[4]))
>> +                                       radeon_crtc_handle_vblank(rdev,
>> 4);
>> +
>> rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
>> +                               DRM_DEBUG("IH: D5 vblank\n");
>> +
>>                                 break;
>>                         case 1: /* D5 vline */
>> -                               if
>> (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) {
>> -
>> rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D5 vline\n");
>> -                               }
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT))
>> +                                       DRM_DEBUG("IH: D5 vline - IH event
>> w/o asserted irq bit?\n");
>> +
>> +
>> rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
>> +                               DRM_DEBUG("IH: D5 vline\n");
>> +
>>                                 break;
>>                         default:
>>                                 DRM_DEBUG("Unhandled interrupt: %d %d\n",
>> src_id, src_data);
>> @@ -5072,23 +5092,27 @@ restart_ih:
>>                 case 6: /* D6 vblank/vline */
>>                         switch (src_data) {
>>                         case 0: /* D6 vblank */
>> -                               if
>> (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) {
>> -                                       if (rdev->irq.crtc_vblank_int[5])
>> {
>> -
>> drm_handle_vblank(rdev->ddev, 5);
>> -                                               rdev->pm.vblank_sync =
>> true;
>> -
>> wake_up(&rdev->irq.vblank_queue);
>> -                                       }
>> -                                       if
>> (atomic_read(&rdev->irq.pflip[5]))
>> -
>> radeon_crtc_handle_vblank(rdev, 5);
>> -
>> rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
>> -                                       DRM_DEBUG("IH: D6 vblank\n");
>> +                               if
>> (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT))
diff mbox

Patch

diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index b0688b0..35917e7 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -7930,23 +7930,27 @@  restart_ih:
 		case 1: /* D1 vblank/vline */
 			switch (src_data) {
 			case 0: /* D1 vblank */
-				if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[0]) {
-						drm_handle_vblank(rdev->ddev, 0);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[0]))
-						radeon_crtc_handle_vblank(rdev, 0);
-					rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D1 vblank\n");
+				if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[0]) {
+					drm_handle_vblank(rdev->ddev, 0);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[0]))
+					radeon_crtc_handle_vblank(rdev, 0);
+				rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D1 vblank\n");
+
 				break;
 			case 1: /* D1 vline */
-				if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D1 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D1 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -7956,23 +7960,27 @@  restart_ih:
 		case 2: /* D2 vblank/vline */
 			switch (src_data) {
 			case 0: /* D2 vblank */
-				if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[1]) {
-						drm_handle_vblank(rdev->ddev, 1);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[1]))
-						radeon_crtc_handle_vblank(rdev, 1);
-					rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D2 vblank\n");
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[1]) {
+					drm_handle_vblank(rdev->ddev, 1);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[1]))
+					radeon_crtc_handle_vblank(rdev, 1);
+				rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D2 vblank\n");
+
 				break;
 			case 1: /* D2 vline */
-				if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D2 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D2 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -7982,23 +7990,27 @@  restart_ih:
 		case 3: /* D3 vblank/vline */
 			switch (src_data) {
 			case 0: /* D3 vblank */
-				if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[2]) {
-						drm_handle_vblank(rdev->ddev, 2);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[2]))
-						radeon_crtc_handle_vblank(rdev, 2);
-					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D3 vblank\n");
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[2]) {
+					drm_handle_vblank(rdev->ddev, 2);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[2]))
+					radeon_crtc_handle_vblank(rdev, 2);
+				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D3 vblank\n");
+
 				break;
 			case 1: /* D3 vline */
-				if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D3 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D3 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -8008,23 +8020,27 @@  restart_ih:
 		case 4: /* D4 vblank/vline */
 			switch (src_data) {
 			case 0: /* D4 vblank */
-				if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[3]) {
-						drm_handle_vblank(rdev->ddev, 3);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[3]))
-						radeon_crtc_handle_vblank(rdev, 3);
-					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D4 vblank\n");
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[3]) {
+					drm_handle_vblank(rdev->ddev, 3);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[3]))
+					radeon_crtc_handle_vblank(rdev, 3);
+				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D4 vblank\n");
+
 				break;
 			case 1: /* D4 vline */
-				if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D4 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D4 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -8034,23 +8050,27 @@  restart_ih:
 		case 5: /* D5 vblank/vline */
 			switch (src_data) {
 			case 0: /* D5 vblank */
-				if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[4]) {
-						drm_handle_vblank(rdev->ddev, 4);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[4]))
-						radeon_crtc_handle_vblank(rdev, 4);
-					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D5 vblank\n");
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[4]) {
+					drm_handle_vblank(rdev->ddev, 4);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[4]))
+					radeon_crtc_handle_vblank(rdev, 4);
+				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D5 vblank\n");
+
 				break;
 			case 1: /* D5 vline */
-				if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D5 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D5 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -8060,23 +8080,27 @@  restart_ih:
 		case 6: /* D6 vblank/vline */
 			switch (src_data) {
 			case 0: /* D6 vblank */
-				if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[5]) {
-						drm_handle_vblank(rdev->ddev, 5);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[5]))
-						radeon_crtc_handle_vblank(rdev, 5);
-					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D6 vblank\n");
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[5]) {
+					drm_handle_vblank(rdev->ddev, 5);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[5]))
+					radeon_crtc_handle_vblank(rdev, 5);
+				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D6 vblank\n");
+
 				break;
 			case 1: /* D6 vline */
-				if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D6 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D6 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -8096,88 +8120,112 @@  restart_ih:
 		case 42: /* HPD hotplug */
 			switch (src_data) {
 			case 0:
-				if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD1\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD1\n");
+
 				break;
 			case 1:
-				if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD2\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD2\n");
+
 				break;
 			case 2:
-				if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD3\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD3\n");
+
 				break;
 			case 3:
-				if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD4\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD4\n");
+
 				break;
 			case 4:
-				if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD5\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD5\n");
+
 				break;
 			case 5:
-				if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD6\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD6\n");
+
 				break;
 			case 6:
-				if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 1\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 1\n");
+
 				break;
 			case 7:
-				if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 2\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 2\n");
+
 				break;
 			case 8:
-				if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 3\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 3\n");
+
 				break;
 			case 9:
-				if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 4\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 4\n");
+
 				break;
 			case 10:
-				if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 5\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 5\n");
+
 				break;
 			case 11:
-				if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) {
-					rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 6\n");
-				}
+				if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 6\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 3a6d483..0acde19 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -4924,7 +4924,7 @@  restart_ih:
 		return IRQ_NONE;
 
 	rptr = rdev->ih.rptr;
-	DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
+	DRM_DEBUG("evergreen_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
 
 	/* Order reading of wptr vs. reading of IH ring data */
 	rmb();
@@ -4942,23 +4942,27 @@  restart_ih:
 		case 1: /* D1 vblank/vline */
 			switch (src_data) {
 			case 0: /* D1 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[0]) {
-						drm_handle_vblank(rdev->ddev, 0);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[0]))
-						radeon_crtc_handle_vblank(rdev, 0);
-					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D1 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[0]) {
+					drm_handle_vblank(rdev->ddev, 0);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[0]))
+					radeon_crtc_handle_vblank(rdev, 0);
+				rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D1 vblank\n");
+
 				break;
 			case 1: /* D1 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D1 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: D1 vline - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D1 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -4968,23 +4972,27 @@  restart_ih:
 		case 2: /* D2 vblank/vline */
 			switch (src_data) {
 			case 0: /* D2 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[1]) {
-						drm_handle_vblank(rdev->ddev, 1);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[1]))
-						radeon_crtc_handle_vblank(rdev, 1);
-					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D2 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[1]) {
+					drm_handle_vblank(rdev->ddev, 1);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[1]))
+					radeon_crtc_handle_vblank(rdev, 1);
+				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D2 vblank\n");
+
 				break;
 			case 1: /* D2 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D2 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: D2 vline - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D2 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -4994,23 +5002,27 @@  restart_ih:
 		case 3: /* D3 vblank/vline */
 			switch (src_data) {
 			case 0: /* D3 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[2]) {
-						drm_handle_vblank(rdev->ddev, 2);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[2]))
-						radeon_crtc_handle_vblank(rdev, 2);
-					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D3 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: D3 vblank - IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[2]) {
+					drm_handle_vblank(rdev->ddev, 2);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[2]))
+					radeon_crtc_handle_vblank(rdev, 2);
+				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D3 vblank\n");
+
 				break;
 			case 1: /* D3 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D3 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: D3 vline - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D3 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -5020,23 +5032,27 @@  restart_ih:
 		case 4: /* D4 vblank/vline */
 			switch (src_data) {
 			case 0: /* D4 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[3]) {
-						drm_handle_vblank(rdev->ddev, 3);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[3]))
-						radeon_crtc_handle_vblank(rdev, 3);
-					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D4 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: D4 vblank - IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[3]) {
+					drm_handle_vblank(rdev->ddev, 3);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[3]))
+					radeon_crtc_handle_vblank(rdev, 3);
+				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D4 vblank\n");
+
 				break;
 			case 1: /* D4 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D4 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: D4 vline - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D4 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -5046,23 +5062,27 @@  restart_ih:
 		case 5: /* D5 vblank/vline */
 			switch (src_data) {
 			case 0: /* D5 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[4]) {
-						drm_handle_vblank(rdev->ddev, 4);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[4]))
-						radeon_crtc_handle_vblank(rdev, 4);
-					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D5 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: D5 vblank - IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[4]) {
+					drm_handle_vblank(rdev->ddev, 4);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[4]))
+					radeon_crtc_handle_vblank(rdev, 4);
+				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D5 vblank\n");
+
 				break;
 			case 1: /* D5 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D5 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: D5 vline - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D5 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -5072,23 +5092,27 @@  restart_ih:
 		case 6: /* D6 vblank/vline */
 			switch (src_data) {
 			case 0: /* D6 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[5]) {
-						drm_handle_vblank(rdev->ddev, 5);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[5]))
-						radeon_crtc_handle_vblank(rdev, 5);
-					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D6 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: D6 vblank - IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[5]) {
+					drm_handle_vblank(rdev->ddev, 5);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[5]))
+					radeon_crtc_handle_vblank(rdev, 5);
+				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D6 vblank\n");
+
 				break;
 			case 1: /* D6 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D6 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: D6 vline - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D6 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -5108,88 +5132,100 @@  restart_ih:
 		case 42: /* HPD hotplug */
 			switch (src_data) {
 			case 0:
-				if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD1\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD1\n");
 				break;
 			case 1:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD2\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD2\n");
 				break;
 			case 2:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD3\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD3\n");
 				break;
 			case 3:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD4\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD4\n");
 				break;
 			case 4:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD5\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD5\n");
 				break;
 			case 5:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD6\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD6\n");
 				break;
 			case 6:
-				if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 1\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 1\n");
 				break;
 			case 7:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 2\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 2\n");
 				break;
 			case 8:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 3\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 3\n");
 				break;
 			case 9:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 4\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 4\n");
 				break;
 			case 10:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 5\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 5\n");
 				break;
 			case 11:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 6\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 6\n");
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -5199,46 +5235,52 @@  restart_ih:
 		case 44: /* hdmi */
 			switch (src_data) {
 			case 0:
-				if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) {
-					rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG;
-					queue_hdmi = true;
-					DRM_DEBUG("IH: HDMI0\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG;
+				queue_hdmi = true;
+				DRM_DEBUG("IH: HDMI0\n");
 				break;
 			case 1:
-				if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) {
-					rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG;
-					queue_hdmi = true;
-					DRM_DEBUG("IH: HDMI1\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG;
+				queue_hdmi = true;
+				DRM_DEBUG("IH: HDMI1\n");
 				break;
 			case 2:
-				if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) {
-					rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG;
-					queue_hdmi = true;
-					DRM_DEBUG("IH: HDMI2\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG;
+				queue_hdmi = true;
+				DRM_DEBUG("IH: HDMI2\n");
 				break;
 			case 3:
-				if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) {
-					rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG;
-					queue_hdmi = true;
-					DRM_DEBUG("IH: HDMI3\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG;
+				queue_hdmi = true;
+				DRM_DEBUG("IH: HDMI3\n");
 				break;
 			case 4:
-				if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) {
-					rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG;
-					queue_hdmi = true;
-					DRM_DEBUG("IH: HDMI4\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG;
+				queue_hdmi = true;
+				DRM_DEBUG("IH: HDMI4\n");
 				break;
 			case 5:
-				if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) {
-					rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG;
-					queue_hdmi = true;
-					DRM_DEBUG("IH: HDMI5\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG;
+				queue_hdmi = true;
+				DRM_DEBUG("IH: HDMI5\n");
 				break;
 			default:
 				DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 35dafd7..4ea5b10 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -4086,23 +4086,27 @@  restart_ih:
 		case 1: /* D1 vblank/vline */
 			switch (src_data) {
 			case 0: /* D1 vblank */
-				if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[0]) {
-						drm_handle_vblank(rdev->ddev, 0);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[0]))
-						radeon_crtc_handle_vblank(rdev, 0);
-					rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D1 vblank\n");
+				if (!(rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[0]) {
+					drm_handle_vblank(rdev->ddev, 0);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[0]))
+					radeon_crtc_handle_vblank(rdev, 0);
+				rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D1 vblank\n");
+
 				break;
 			case 1: /* D1 vline */
-				if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D1 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT))
+				    DRM_DEBUG("IH: D1 vline - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D1 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -4112,23 +4116,27 @@  restart_ih:
 		case 5: /* D2 vblank/vline */
 			switch (src_data) {
 			case 0: /* D2 vblank */
-				if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[1]) {
-						drm_handle_vblank(rdev->ddev, 1);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[1]))
-						radeon_crtc_handle_vblank(rdev, 1);
-					rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D2 vblank\n");
+				if (!(rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[1]) {
+					drm_handle_vblank(rdev->ddev, 1);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[1]))
+					radeon_crtc_handle_vblank(rdev, 1);
+				rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D2 vblank\n");
+
 				break;
 			case 1: /* D1 vline */
-				if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D2 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: D2 vline - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D2 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -4148,46 +4156,53 @@  restart_ih:
 		case 19: /* HPD/DAC hotplug */
 			switch (src_data) {
 			case 0:
-				if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) {
-					rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD1\n");
-				}
+				if (!(rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT))
+					DRM_DEBUG("IH: HPD1 - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD1\n");
 				break;
 			case 1:
-				if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) {
-					rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD2\n");
-				}
+				if (!(rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT))
+					DRM_DEBUG("IH: HPD2 - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD2\n");
 				break;
 			case 4:
-				if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) {
-					rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD3\n");
-				}
+				if (!(rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT))
+					DRM_DEBUG("IH: HPD3 - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD3\n");
 				break;
 			case 5:
-				if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) {
-					rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD4\n");
-				}
+				if (!(rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT))
+					DRM_DEBUG("IH: HPD4 - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD4\n");
 				break;
 			case 10:
-				if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) {
-					rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD5\n");
-				}
+				if (!(rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT))
+					DRM_DEBUG("IH: HPD5 - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD5\n");
 				break;
 			case 12:
-				if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) {
-					rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD6\n");
-				}
+				if (!(rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT))
+					DRM_DEBUG("IH: HPD6 - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD6\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -4197,18 +4212,22 @@  restart_ih:
 		case 21: /* hdmi */
 			switch (src_data) {
 			case 4:
-				if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) {
-					rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG;
-					queue_hdmi = true;
-					DRM_DEBUG("IH: HDMI0\n");
-				}
+				if (!(rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG))
+					DRM_DEBUG("IH: HDMI0 - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG;
+				queue_hdmi = true;
+				DRM_DEBUG("IH: HDMI0\n");
+
 				break;
 			case 5:
-				if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) {
-					rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG;
-					queue_hdmi = true;
-					DRM_DEBUG("IH: HDMI1\n");
-				}
+				if (!(rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG))
+					DRM_DEBUG("IH: HDMI1 - IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG;
+				queue_hdmi = true;
+				DRM_DEBUG("IH: HDMI1\n");
+
 				break;
 			default:
 				DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index 26388b5..07037e3 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -6466,23 +6466,27 @@  restart_ih:
 		case 1: /* D1 vblank/vline */
 			switch (src_data) {
 			case 0: /* D1 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[0]) {
-						drm_handle_vblank(rdev->ddev, 0);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[0]))
-						radeon_crtc_handle_vblank(rdev, 0);
-					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D1 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[0]) {
+					drm_handle_vblank(rdev->ddev, 0);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[0]))
+					radeon_crtc_handle_vblank(rdev, 0);
+				rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D1 vblank\n");
+
 				break;
 			case 1: /* D1 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D1 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D1 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -6492,23 +6496,27 @@  restart_ih:
 		case 2: /* D2 vblank/vline */
 			switch (src_data) {
 			case 0: /* D2 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[1]) {
-						drm_handle_vblank(rdev->ddev, 1);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[1]))
-						radeon_crtc_handle_vblank(rdev, 1);
-					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D2 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[1]) {
+					drm_handle_vblank(rdev->ddev, 1);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[1]))
+					radeon_crtc_handle_vblank(rdev, 1);
+				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D2 vblank\n");
+
 				break;
 			case 1: /* D2 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D2 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D2 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -6518,23 +6526,27 @@  restart_ih:
 		case 3: /* D3 vblank/vline */
 			switch (src_data) {
 			case 0: /* D3 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[2]) {
-						drm_handle_vblank(rdev->ddev, 2);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[2]))
-						radeon_crtc_handle_vblank(rdev, 2);
-					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D3 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[2]) {
+					drm_handle_vblank(rdev->ddev, 2);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[2]))
+					radeon_crtc_handle_vblank(rdev, 2);
+				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D3 vblank\n");
+
 				break;
 			case 1: /* D3 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D3 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D3 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -6544,23 +6556,27 @@  restart_ih:
 		case 4: /* D4 vblank/vline */
 			switch (src_data) {
 			case 0: /* D4 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[3]) {
-						drm_handle_vblank(rdev->ddev, 3);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[3]))
-						radeon_crtc_handle_vblank(rdev, 3);
-					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D4 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[3]) {
+					drm_handle_vblank(rdev->ddev, 3);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[3]))
+					radeon_crtc_handle_vblank(rdev, 3);
+				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D4 vblank\n");
+
 				break;
 			case 1: /* D4 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D4 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D4 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -6570,23 +6586,27 @@  restart_ih:
 		case 5: /* D5 vblank/vline */
 			switch (src_data) {
 			case 0: /* D5 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[4]) {
-						drm_handle_vblank(rdev->ddev, 4);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[4]))
-						radeon_crtc_handle_vblank(rdev, 4);
-					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D5 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[4]) {
+					drm_handle_vblank(rdev->ddev, 4);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[4]))
+					radeon_crtc_handle_vblank(rdev, 4);
+				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D5 vblank\n");
+
 				break;
 			case 1: /* D5 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D5 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D5 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -6596,23 +6616,27 @@  restart_ih:
 		case 6: /* D6 vblank/vline */
 			switch (src_data) {
 			case 0: /* D6 vblank */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) {
-					if (rdev->irq.crtc_vblank_int[5]) {
-						drm_handle_vblank(rdev->ddev, 5);
-						rdev->pm.vblank_sync = true;
-						wake_up(&rdev->irq.vblank_queue);
-					}
-					if (atomic_read(&rdev->irq.pflip[5]))
-						radeon_crtc_handle_vblank(rdev, 5);
-					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
-					DRM_DEBUG("IH: D6 vblank\n");
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				if (rdev->irq.crtc_vblank_int[5]) {
+					drm_handle_vblank(rdev->ddev, 5);
+					rdev->pm.vblank_sync = true;
+					wake_up(&rdev->irq.vblank_queue);
 				}
+				if (atomic_read(&rdev->irq.pflip[5]))
+					radeon_crtc_handle_vblank(rdev, 5);
+				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
+				DRM_DEBUG("IH: D6 vblank\n");
+
 				break;
 			case 1: /* D6 vline */
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
-					DRM_DEBUG("IH: D6 vline\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
+				DRM_DEBUG("IH: D6 vline\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
@@ -6632,88 +6656,112 @@  restart_ih:
 		case 42: /* HPD hotplug */
 			switch (src_data) {
 			case 0:
-				if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD1\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD1\n");
+
 				break;
 			case 1:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD2\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD2\n");
+
 				break;
 			case 2:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD3\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD3\n");
+
 				break;
 			case 3:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD4\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD4\n");
+
 				break;
 			case 4:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD5\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD5\n");
+
 				break;
 			case 5:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
-					queue_hotplug = true;
-					DRM_DEBUG("IH: HPD6\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
+				queue_hotplug = true;
+				DRM_DEBUG("IH: HPD6\n");
+
 				break;
 			case 6:
-				if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 1\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 1\n");
+
 				break;
 			case 7:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 2\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 2\n");
+
 				break;
 			case 8:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 3\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 3\n");
+
 				break;
 			case 9:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 4\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 4\n");
+
 				break;
 			case 10:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 5\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 5\n");
+
 				break;
 			case 11:
-				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) {
-					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
-					queue_dp = true;
-					DRM_DEBUG("IH: HPD_RX 6\n");
-				}
+				if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT))
+					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
+
+				rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT;
+				queue_dp = true;
+				DRM_DEBUG("IH: HPD_RX 6\n");
+
 				break;
 			default:
 				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);