On Thu, May 31, 2012 at 4:16 PM, Christian K?nig <deathsimple at vodafone.de> wrote: > From: Christian Koenig <christian.koenig at amd.com> > > 1. It is really dangerous to have more than one > ? spinlock protecting the same information. > > 2. radeon_irq_set sometimes wasn't called with lock > ? protection, so it can happen that more than one > ? CPU would tamper with the irq regs at the same > ? time. > > 3. The pm.gui_idle variable was assuming that the 3D > ? engine wasn't becoming idle between testing the > ? register and setting the variable. So just remove > ? it and test the register directly. > > v2: Also handle the hpd irq code the same way.
couple of comments below for clarity, other than that: Reviewed-by: Alex Deucher <alexander.deucher at amd.com> > > Signed-off-by: Christian Koenig <christian.koenig at amd.com> > --- > ?drivers/gpu/drm/radeon/evergreen.c ? ? ?| ? 21 ++----- > ?drivers/gpu/drm/radeon/r100.c ? ? ? ? ? | ? 29 ++-------- > ?drivers/gpu/drm/radeon/r600.c ? ? ? ? ? | ? 38 ++++-------- > ?drivers/gpu/drm/radeon/r600_hdmi.c ? ? ?| ? ?6 +- > ?drivers/gpu/drm/radeon/radeon.h ? ? ? ? | ? 35 +++++------ > ?drivers/gpu/drm/radeon/radeon_irq_kms.c | ? 96 > +++++++++++++++++++++++++++---- > ?drivers/gpu/drm/radeon/radeon_kms.c ? ? | ? 12 +++- > ?drivers/gpu/drm/radeon/radeon_pm.c ? ? ?| ? 12 +--- > ?drivers/gpu/drm/radeon/rs600.c ? ? ? ? ?| ? 13 ++--- > ?drivers/gpu/drm/radeon/si.c ? ? ? ? ? ? | ? ?1 - > ?10 files changed, 144 insertions(+), 119 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/evergreen.c > b/drivers/gpu/drm/radeon/evergreen.c > index e4c3321..48ec1a0 100644 > --- a/drivers/gpu/drm/radeon/evergreen.c > +++ b/drivers/gpu/drm/radeon/evergreen.c > @@ -428,6 +428,7 @@ void evergreen_hpd_init(struct radeon_device *rdev) > ?{ > ? ? ? ?struct drm_device *dev = rdev->ddev; > ? ? ? ?struct drm_connector *connector; > + ? ? ? unsigned enabled = 0; > ? ? ? ?u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | > ? ? ? ? ? ? ? ?DC_HPDx_RX_INT_TIMER(0xfa) | DC_HPDx_EN; > > @@ -436,73 +437,64 @@ void evergreen_hpd_init(struct radeon_device *rdev) > ? ? ? ? ? ? ? ?switch (radeon_connector->hpd.hpd) { > ? ? ? ? ? ? ? ?case RADEON_HPD_1: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD1_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[0] = true; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_2: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD2_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[1] = true; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_3: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD3_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[2] = true; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_4: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD4_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[3] = true; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_5: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD5_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[4] = true; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_6: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD6_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[5] = true; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?default: > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); > + ? ? ? ? ? ? ? enabled |= 1 << radeon_connector->hpd.hpd; > ? ? ? ?} > - ? ? ? if (rdev->irq.installed) > - ? ? ? ? ? ? ? evergreen_irq_set(rdev); > + ? ? ? radeon_irq_kms_enable_hpd(rdev, enabled); > ?} > > ?void evergreen_hpd_fini(struct radeon_device *rdev) > ?{ > ? ? ? ?struct drm_device *dev = rdev->ddev; > ? ? ? ?struct drm_connector *connector; > + ? ? ? unsigned disabled = 0; > > ? ? ? ?list_for_each_entry(connector, &dev->mode_config.connector_list, head) > { > ? ? ? ? ? ? ? ?struct radeon_connector *radeon_connector = > to_radeon_connector(connector); > ? ? ? ? ? ? ? ?switch (radeon_connector->hpd.hpd) { > ? ? ? ? ? ? ? ?case RADEON_HPD_1: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD1_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[0] = false; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_2: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD2_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[1] = false; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_3: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD3_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[2] = false; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_4: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD4_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[3] = false; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_5: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD5_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[4] = false; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_6: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD6_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[5] = false; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?default: > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? disabled |= 1 << radeon_connector->hpd.hpd; > ? ? ? ?} > + ? ? ? radeon_irq_kms_disable_hpd(rdev, disabled); > ?} > > ?/* watermark setup */ > @@ -3252,7 +3244,6 @@ restart_ih: > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case 233: /* GUI IDLE */ > ? ? ? ? ? ? ? ? ? ? ? ?DRM_DEBUG("IH: GUI idle\n"); > - ? ? ? ? ? ? ? ? ? ? ? rdev->pm.gui_idle = true; > ? ? ? ? ? ? ? ? ? ? ? ?wake_up(&rdev->irq.idle_queue); > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?default: > diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c > index 415b7d8..e8fe4ae 100644 > --- a/drivers/gpu/drm/radeon/r100.c > +++ b/drivers/gpu/drm/radeon/r100.c > @@ -567,43 +567,27 @@ void r100_hpd_init(struct radeon_device *rdev) > ?{ > ? ? ? ?struct drm_device *dev = rdev->ddev; > ? ? ? ?struct drm_connector *connector; > + ? ? ? unsigned enable = 0; > > ? ? ? ?list_for_each_entry(connector, &dev->mode_config.connector_list, head) > { > ? ? ? ? ? ? ? ?struct radeon_connector *radeon_connector = > to_radeon_connector(connector); > - ? ? ? ? ? ? ? switch (radeon_connector->hpd.hpd) { > - ? ? ? ? ? ? ? case RADEON_HPD_1: > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[0] = true; > - ? ? ? ? ? ? ? ? ? ? ? break; > - ? ? ? ? ? ? ? case RADEON_HPD_2: > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[1] = true; > - ? ? ? ? ? ? ? ? ? ? ? break; > - ? ? ? ? ? ? ? default: > - ? ? ? ? ? ? ? ? ? ? ? break; > - ? ? ? ? ? ? ? } > + ? ? ? ? ? ? ? enable |= 1 << radeon_connector->hpd.hpd; > ? ? ? ? ? ? ? ?radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); > ? ? ? ?} > - ? ? ? if (rdev->irq.installed) > - ? ? ? ? ? ? ? r100_irq_set(rdev); > + ? ? ? radeon_irq_kms_enable_hpd(rdev, enable); > ?} > > ?void r100_hpd_fini(struct radeon_device *rdev) > ?{ > ? ? ? ?struct drm_device *dev = rdev->ddev; > ? ? ? ?struct drm_connector *connector; > + ? ? ? unsigned disable = 0; > > ? ? ? ?list_for_each_entry(connector, &dev->mode_config.connector_list, head) > { > ? ? ? ? ? ? ? ?struct radeon_connector *radeon_connector = > to_radeon_connector(connector); > - ? ? ? ? ? ? ? switch (radeon_connector->hpd.hpd) { > - ? ? ? ? ? ? ? case RADEON_HPD_1: > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[0] = false; > - ? ? ? ? ? ? ? ? ? ? ? break; > - ? ? ? ? ? ? ? case RADEON_HPD_2: > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[1] = false; > - ? ? ? ? ? ? ? ? ? ? ? break; > - ? ? ? ? ? ? ? default: > - ? ? ? ? ? ? ? ? ? ? ? break; > - ? ? ? ? ? ? ? } > + ? ? ? ? ? ? ? disable |= 1 << radeon_connector->hpd.hpd; > ? ? ? ?} > + ? ? ? radeon_irq_kms_disable_hpd(rdev, disable); > ?} > > ?/* > @@ -782,7 +766,6 @@ int r100_irq_process(struct radeon_device *rdev) > ? ? ? ? ? ? ? ?/* gui idle interrupt */ > ? ? ? ? ? ? ? ?if (status & RADEON_GUI_IDLE_STAT) { > ? ? ? ? ? ? ? ? ? ? ? ?rdev->irq.gui_idle_acked = true; > - ? ? ? ? ? ? ? ? ? ? ? rdev->pm.gui_idle = true; > ? ? ? ? ? ? ? ? ? ? ? ?wake_up(&rdev->irq.idle_queue); > ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?/* Vertical blank interrupts */ > diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c > index e1861ac..72b5084 100644 > --- a/drivers/gpu/drm/radeon/r600.c > +++ b/drivers/gpu/drm/radeon/r600.c > @@ -709,6 +709,7 @@ void r600_hpd_init(struct radeon_device *rdev) > ?{ > ? ? ? ?struct drm_device *dev = rdev->ddev; > ? ? ? ?struct drm_connector *connector; > + ? ? ? unsigned enable = 0; > > ? ? ? ?list_for_each_entry(connector, &dev->mode_config.connector_list, head) > { > ? ? ? ? ? ? ? ?struct radeon_connector *radeon_connector = > to_radeon_connector(connector); > @@ -729,28 +730,22 @@ void r600_hpd_init(struct radeon_device *rdev) > ? ? ? ? ? ? ? ? ? ? ? ?switch (radeon_connector->hpd.hpd) { > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_1: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD1_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[0] = true; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_2: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD2_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[1] = true; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_3: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD3_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[2] = true; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_4: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD4_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[3] = true; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* DCE 3.2 */ > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_5: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD5_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[4] = true; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_6: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD6_CONTROL, tmp); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[5] = true; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?default: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > @@ -759,85 +754,73 @@ void r600_hpd_init(struct radeon_device *rdev) > ? ? ? ? ? ? ? ? ? ? ? ?switch (radeon_connector->hpd.hpd) { > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_1: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HOT_PLUG_DETECT1_CONTROL, > DC_HOT_PLUG_DETECTx_EN); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[0] = true; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_2: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HOT_PLUG_DETECT2_CONTROL, > DC_HOT_PLUG_DETECTx_EN); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[1] = true; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_3: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HOT_PLUG_DETECT3_CONTROL, > DC_HOT_PLUG_DETECTx_EN); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[2] = true; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?default: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? enable |= 1 << radeon_connector->hpd.hpd; > ? ? ? ? ? ? ? ?radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); > ? ? ? ?} > - ? ? ? if (rdev->irq.installed) > - ? ? ? ? ? ? ? r600_irq_set(rdev); > + ? ? ? radeon_irq_kms_enable_hpd(rdev, enable); > ?} > > ?void r600_hpd_fini(struct radeon_device *rdev) > ?{ > ? ? ? ?struct drm_device *dev = rdev->ddev; > ? ? ? ?struct drm_connector *connector; > + ? ? ? unsigned disable = 0; > > - ? ? ? if (ASIC_IS_DCE3(rdev)) { > - ? ? ? ? ? ? ? list_for_each_entry(connector, > &dev->mode_config.connector_list, head) { > - ? ? ? ? ? ? ? ? ? ? ? struct radeon_connector *radeon_connector = > to_radeon_connector(connector); > + ? ? ? list_for_each_entry(connector, &dev->mode_config.connector_list, > head) { > + ? ? ? ? ? ? ? struct radeon_connector *radeon_connector = > to_radeon_connector(connector); > + ? ? ? ? ? ? ? if (ASIC_IS_DCE3(rdev)) { > ? ? ? ? ? ? ? ? ? ? ? ?switch (radeon_connector->hpd.hpd) { > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_1: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD1_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[0] = false; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_2: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD2_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[1] = false; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_3: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD3_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[2] = false; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_4: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD4_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[3] = false; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* DCE 3.2 */ > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_5: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD5_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[4] = false; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_6: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HPD6_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[5] = false; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?default: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?} > - ? ? ? ? ? ? ? } > - ? ? ? } else { > - ? ? ? ? ? ? ? list_for_each_entry(connector, > &dev->mode_config.connector_list, head) { > - ? ? ? ? ? ? ? ? ? ? ? struct radeon_connector *radeon_connector = > to_radeon_connector(connector); > + ? ? ? ? ? ? ? } else { > ? ? ? ? ? ? ? ? ? ? ? ?switch (radeon_connector->hpd.hpd) { > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_1: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[0] = false; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_2: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[1] = false; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?case RADEON_HPD_3: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0); > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[2] = false; > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?default: > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? disable |= 1 << radeon_connector->hpd.hpd; > ? ? ? ?} > + ? ? ? radeon_irq_kms_disable_hpd(rdev, disable); > ?} > > ?/* > @@ -3541,7 +3524,6 @@ restart_ih: > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case 233: /* GUI IDLE */ > ? ? ? ? ? ? ? ? ? ? ? ?DRM_DEBUG("IH: GUI idle\n"); > - ? ? ? ? ? ? ? ? ? ? ? rdev->pm.gui_idle = true; > ? ? ? ? ? ? ? ? ? ? ? ?wake_up(&rdev->irq.idle_queue); > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?default: > diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c > b/drivers/gpu/drm/radeon/r600_hdmi.c > index 226379e..b76c0f2 100644 > --- a/drivers/gpu/drm/radeon/r600_hdmi.c > +++ b/drivers/gpu/drm/radeon/r600_hdmi.c > @@ -523,8 +523,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder) > > ? ? ? ?if (rdev->irq.installed) { > ? ? ? ? ? ? ? ?/* if irq is available use it */ > - ? ? ? ? ? ? ? rdev->irq.afmt[dig->afmt->id] = true; > - ? ? ? ? ? ? ? radeon_irq_set(rdev); > + ? ? ? ? ? ? ? radeon_irq_kms_enable_afmt(rdev, dig->afmt->id); > ? ? ? ?} > > ? ? ? ?dig->afmt->enabled = true; > @@ -560,8 +559,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) > ? ? ? ? ? ? ? ? ?offset, radeon_encoder->encoder_id); > > ? ? ? ?/* disable irq */ > - ? ? ? rdev->irq.afmt[dig->afmt->id] = false; > - ? ? ? radeon_irq_set(rdev); > + ? ? ? radeon_irq_kms_disable_afmt(rdev, dig->afmt->id); > > ? ? ? ?/* Older chipsets not handled by AtomBIOS */ > ? ? ? ?if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { > diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h > index 378d43b..8a2a1f4 100644 > --- a/drivers/gpu/drm/radeon/radeon.h > +++ b/drivers/gpu/drm/radeon/radeon.h > @@ -610,21 +610,20 @@ union radeon_irq_stat_regs { > ?#define RADEON_MAX_AFMT_BLOCKS 6 > > ?struct radeon_irq { > - ? ? ? bool ? ? ? ? ? ?installed; > - ? ? ? bool ? ? ? ? ? ?sw_int[RADEON_NUM_RINGS]; > - ? ? ? bool ? ? ? ? ? ?crtc_vblank_int[RADEON_MAX_CRTCS]; > - ? ? ? bool ? ? ? ? ? ?pflip[RADEON_MAX_CRTCS]; > - ? ? ? wait_queue_head_t ? ? ? vblank_queue; > - ? ? ? bool ? ? ? ? ? ?hpd[RADEON_MAX_HPD_PINS]; > - ? ? ? bool ? ? ? ? ? ?gui_idle; > - ? ? ? bool ? ? ? ? ? ?gui_idle_acked; > - ? ? ? wait_queue_head_t ? ? ? idle_queue; > - ? ? ? bool ? ? ? ? ? ?afmt[RADEON_MAX_AFMT_BLOCKS]; > - ? ? ? spinlock_t sw_lock; > - ? ? ? int sw_refcount[RADEON_NUM_RINGS]; > - ? ? ? union radeon_irq_stat_regs stat_regs; > - ? ? ? spinlock_t pflip_lock[RADEON_MAX_CRTCS]; > - ? ? ? int pflip_refcount[RADEON_MAX_CRTCS]; > + ? ? ? bool ? ? ? ? ? ? ? ? ? ? ? ? ? ?installed; > + ? ? ? spinlock_t ? ? ? ? ? ? ? ? ? ? ?lock; > + ? ? ? bool ? ? ? ? ? ? ? ? ? ? ? ? ? ?sw_int[RADEON_NUM_RINGS]; > + ? ? ? int ? ? ? ? ? ? ? ? ? ? ? ? ? ? sw_refcount[RADEON_NUM_RINGS]; > + ? ? ? bool ? ? ? ? ? ? ? ? ? ? ? ? ? ?crtc_vblank_int[RADEON_MAX_CRTCS]; > + ? ? ? bool ? ? ? ? ? ? ? ? ? ? ? ? ? ?pflip[RADEON_MAX_CRTCS]; > + ? ? ? int ? ? ? ? ? ? ? ? ? ? ? ? ? ? pflip_refcount[RADEON_MAX_CRTCS]; > + ? ? ? wait_queue_head_t ? ? ? ? ? ? ? vblank_queue; > + ? ? ? bool ? ? ? ? ? ? ? ? ? ? ? ? ? ?hpd[RADEON_MAX_HPD_PINS]; > + ? ? ? bool ? ? ? ? ? ? ? ? ? ? ? ? ? ?gui_idle; > + ? ? ? bool ? ? ? ? ? ? ? ? ? ? ? ? ? ?gui_idle_acked; > + ? ? ? wait_queue_head_t ? ? ? ? ? ? ? idle_queue; > + ? ? ? bool ? ? ? ? ? ? ? ? ? ? ? ? ? ?afmt[RADEON_MAX_AFMT_BLOCKS]; > + ? ? ? union radeon_irq_stat_regs ? ? ?stat_regs; > ?}; > > ?int radeon_irq_kms_init(struct radeon_device *rdev); > @@ -633,6 +632,11 @@ void radeon_irq_kms_sw_irq_get(struct radeon_device > *rdev, int ring); > ?void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring); > ?void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc); > ?void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc); > +void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block); > +void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block); > +void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned crtcs); > +void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned crtcs); > +int radeon_irq_kms_wait_gui_idle(struct radeon_device *rdev); > > ?/* > ?* CP & rings. > @@ -1058,7 +1062,6 @@ struct radeon_pm { > ? ? ? ?int ? ? ? ? ? ? ? ? ? ? active_crtc_count; > ? ? ? ?int ? ? ? ? ? ? ? ? ? ? req_vblank; > ? ? ? ?bool ? ? ? ? ? ? ? ? ? ?vblank_sync; > - ? ? ? bool ? ? ? ? ? ? ? ? ? ?gui_idle; > ? ? ? ?fixed20_12 ? ? ? ? ? ? ?max_bandwidth; > ? ? ? ?fixed20_12 ? ? ? ? ? ? ?igp_sideport_mclk; > ? ? ? ?fixed20_12 ? ? ? ? ? ? ?igp_system_mclk; > diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c > b/drivers/gpu/drm/radeon/radeon_irq_kms.c > index 5df58d1..73cd0fd 100644 > --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c > +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c > @@ -32,6 +32,8 @@ > ?#include "radeon.h" > ?#include "atom.h" > > +#define RADEON_WAIT_IDLE_TIMEOUT 200 > + > ?irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) > ?{ > ? ? ? ?struct drm_device *dev = (struct drm_device *) arg; > @@ -62,8 +64,10 @@ static void radeon_hotplug_work_func(struct work_struct > *work) > ?void radeon_driver_irq_preinstall_kms(struct drm_device *dev) > ?{ > ? ? ? ?struct radeon_device *rdev = dev->dev_private; > + ? ? ? unsigned long irqflags; > ? ? ? ?unsigned i; > > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > ? ? ? ?/* Disable *all* interrupts */ > ? ? ? ?for (i = 0; i < RADEON_NUM_RINGS; i++) > ? ? ? ? ? ? ? ?rdev->irq.sw_int[i] = false; > @@ -76,6 +80,7 @@ void radeon_driver_irq_preinstall_kms(struct drm_device > *dev) > ? ? ? ? ? ? ? ?rdev->irq.afmt[i] = false; > ? ? ? ?} > ? ? ? ?radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > ? ? ? ?/* Clear bits */ > ? ? ? ?radeon_irq_process(rdev); > ?} > @@ -83,23 +88,28 @@ void radeon_driver_irq_preinstall_kms(struct drm_device > *dev) > ?int radeon_driver_irq_postinstall_kms(struct drm_device *dev) > ?{ > ? ? ? ?struct radeon_device *rdev = dev->dev_private; > + ? ? ? unsigned long irqflags; > ? ? ? ?unsigned i; > > ? ? ? ?dev->max_vblank_count = 0x001fffff; > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > ? ? ? ?for (i = 0; i < RADEON_NUM_RINGS; i++) > ? ? ? ? ? ? ? ?rdev->irq.sw_int[i] = true; > ? ? ? ?radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > ? ? ? ?return 0; > ?} > > ?void radeon_driver_irq_uninstall_kms(struct drm_device *dev) > ?{ > ? ? ? ?struct radeon_device *rdev = dev->dev_private; > + ? ? ? unsigned long irqflags; > ? ? ? ?unsigned i; > > ? ? ? ?if (rdev == NULL) { > ? ? ? ? ? ? ? ?return; > ? ? ? ?} > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > ? ? ? ?/* Disable *all* interrupts */ > ? ? ? ?for (i = 0; i < RADEON_NUM_RINGS; i++) > ? ? ? ? ? ? ? ?rdev->irq.sw_int[i] = false; > @@ -112,6 +122,7 @@ void radeon_driver_irq_uninstall_kms(struct drm_device > *dev) > ? ? ? ? ? ? ? ?rdev->irq.afmt[i] = false; > ? ? ? ?} > ? ? ? ?radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > ?} > > ?static bool radeon_msi_ok(struct radeon_device *rdev) > @@ -168,15 +179,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev) > > ?int radeon_irq_kms_init(struct radeon_device *rdev) > ?{ > - ? ? ? int i; > ? ? ? ?int r = 0; > > ? ? ? ?INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); > ? ? ? ?INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); > > - ? ? ? spin_lock_init(&rdev->irq.sw_lock); > - ? ? ? for (i = 0; i < rdev->num_crtc; i++) > - ? ? ? ? ? ? ? spin_lock_init(&rdev->irq.pflip_lock[i]); > + ? ? ? spin_lock_init(&rdev->irq.lock); > ? ? ? ?r = drm_vblank_init(rdev->ddev, rdev->num_crtc); > ? ? ? ?if (r) { > ? ? ? ? ? ? ? ?return r; > @@ -217,25 +225,25 @@ void radeon_irq_kms_sw_irq_get(struct radeon_device > *rdev, int ring) > ?{ > ? ? ? ?unsigned long irqflags; > > - ? ? ? spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > ? ? ? ?if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount[ring] == 1)) { > ? ? ? ? ? ? ? ?rdev->irq.sw_int[ring] = true; > ? ? ? ? ? ? ? ?radeon_irq_set(rdev); > ? ? ? ?} > - ? ? ? spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > ?} > > ?void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring) > ?{ > ? ? ? ?unsigned long irqflags; > > - ? ? ? spin_lock_irqsave(&rdev->irq.sw_lock, irqflags); > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > ? ? ? ?BUG_ON(rdev->ddev->irq_enabled && rdev->irq.sw_refcount[ring] <= 0); > ? ? ? ?if (rdev->ddev->irq_enabled && (--rdev->irq.sw_refcount[ring] == 0)) { > ? ? ? ? ? ? ? ?rdev->irq.sw_int[ring] = false; > ? ? ? ? ? ? ? ?radeon_irq_set(rdev); > ? ? ? ?} > - ? ? ? spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > ?} > > ?void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) > @@ -245,12 +253,12 @@ void radeon_irq_kms_pflip_irq_get(struct radeon_device > *rdev, int crtc) > ? ? ? ?if (crtc < 0 || crtc >= rdev->num_crtc) > ? ? ? ? ? ? ? ?return; > > - ? ? ? spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > ? ? ? ?if (rdev->ddev->irq_enabled && (++rdev->irq.pflip_refcount[crtc] == > 1)) { > ? ? ? ? ? ? ? ?rdev->irq.pflip[crtc] = true; > ? ? ? ? ? ? ? ?radeon_irq_set(rdev); > ? ? ? ?} > - ? ? ? spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > ?} > > ?void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) > @@ -260,12 +268,76 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device > *rdev, int crtc) > ? ? ? ?if (crtc < 0 || crtc >= rdev->num_crtc) > ? ? ? ? ? ? ? ?return; > > - ? ? ? spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > ? ? ? ?BUG_ON(rdev->ddev->irq_enabled && rdev->irq.pflip_refcount[crtc] <= 0); > ? ? ? ?if (rdev->ddev->irq_enabled && (--rdev->irq.pflip_refcount[crtc] == > 0)) { > ? ? ? ? ? ? ? ?rdev->irq.pflip[crtc] = false; > ? ? ? ? ? ? ? ?radeon_irq_set(rdev); > ? ? ? ?} > - ? ? ? spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > ?} > > +void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block) > +{ > + ? ? ? unsigned long irqflags; > + > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > + ? ? ? rdev->irq.afmt[block] = true; > + ? ? ? radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > + > +} > + > +void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block) > +{ > + ? ? ? unsigned long irqflags; > + > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > + ? ? ? rdev->irq.afmt[block] = false; > + ? ? ? radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > +} > + > +void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned crtcs) These aren't crtcs. I'd replace crtcs with hpd_mask for clarity. > +{ > + ? ? ? unsigned long irqflags; > + ? ? ? int i; > + > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > + ? ? ? for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) > + ? ? ? ? ? ? ? rdev->irq.hpd[i] |= !!(crtcs & (1 << i)); > + ? ? ? radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > +} > + > +void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned crtcs) same here. > +{ > + ? ? ? unsigned long irqflags; > + ? ? ? int i; > + > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > + ? ? ? for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) > + ? ? ? ? ? ? ? rdev->irq.hpd[i] &= !(crtcs & (1 << i)); > + ? ? ? radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > +} > + > +int radeon_irq_kms_wait_gui_idle(struct radeon_device *rdev) > +{ > + ? ? ? unsigned long irqflags; > + ? ? ? int r; > + > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > + ? ? ? rdev->irq.gui_idle = true; > + ? ? ? radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > + > + ? ? ? r = wait_event_timeout(rdev->irq.idle_queue, radeon_gui_idle(rdev), > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); > + > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > + ? ? ? rdev->irq.gui_idle = false; > + ? ? ? radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > + ? ? ? return r; > +} > diff --git a/drivers/gpu/drm/radeon/radeon_kms.c > b/drivers/gpu/drm/radeon/radeon_kms.c > index f1016a5..abbb04d 100644 > --- a/drivers/gpu/drm/radeon/radeon_kms.c > +++ b/drivers/gpu/drm/radeon/radeon_kms.c > @@ -382,29 +382,35 @@ u32 radeon_get_vblank_counter_kms(struct drm_device > *dev, int crtc) > ?int radeon_enable_vblank_kms(struct drm_device *dev, int crtc) > ?{ > ? ? ? ?struct radeon_device *rdev = dev->dev_private; > + ? ? ? unsigned long irqflags; > + ? ? ? int r; > > ? ? ? ?if (crtc < 0 || crtc >= rdev->num_crtc) { > ? ? ? ? ? ? ? ?DRM_ERROR("Invalid crtc %d\n", crtc); > ? ? ? ? ? ? ? ?return -EINVAL; > ? ? ? ?} > > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > ? ? ? ?rdev->irq.crtc_vblank_int[crtc] = true; > - > - ? ? ? return radeon_irq_set(rdev); > + ? ? ? r = radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > + ? ? ? return r; > ?} > > ?void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) > ?{ > ? ? ? ?struct radeon_device *rdev = dev->dev_private; > + ? ? ? unsigned long irqflags; > > ? ? ? ?if (crtc < 0 || crtc >= rdev->num_crtc) { > ? ? ? ? ? ? ? ?DRM_ERROR("Invalid crtc %d\n", crtc); > ? ? ? ? ? ? ? ?return; > ? ? ? ?} > > + ? ? ? spin_lock_irqsave(&rdev->irq.lock, irqflags); > ? ? ? ?rdev->irq.crtc_vblank_int[crtc] = false; > - > ? ? ? ?radeon_irq_set(rdev); > + ? ? ? spin_unlock_irqrestore(&rdev->irq.lock, irqflags); > ?} > > ?int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, > diff --git a/drivers/gpu/drm/radeon/radeon_pm.c > b/drivers/gpu/drm/radeon/radeon_pm.c > index d13b6ae..79642cd 100644 > --- a/drivers/gpu/drm/radeon/radeon_pm.c > +++ b/drivers/gpu/drm/radeon/radeon_pm.c > @@ -34,7 +34,6 @@ > ?#define RADEON_IDLE_LOOP_MS 100 > ?#define RADEON_RECLOCK_DELAY_MS 200 > ?#define RADEON_WAIT_VBLANK_TIMEOUT 200 > -#define RADEON_WAIT_IDLE_TIMEOUT 200 > > ?static const char *radeon_pm_state_type_name[5] = { > ? ? ? ?"Default", > @@ -257,15 +256,8 @@ static void radeon_pm_set_clocks(struct radeon_device > *rdev) > ? ? ? ?/* gui idle int has issues on older chips it seems */ > ? ? ? ?if (rdev->family >= CHIP_R600) { > ? ? ? ? ? ? ? ?if (rdev->irq.installed) { > - ? ? ? ? ? ? ? ? ? ? ? /* wait for GPU idle */ > - ? ? ? ? ? ? ? ? ? ? ? rdev->pm.gui_idle = false; > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.gui_idle = true; > - ? ? ? ? ? ? ? ? ? ? ? radeon_irq_set(rdev); > - ? ? ? ? ? ? ? ? ? ? ? wait_event_interruptible_timeout( > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rdev->irq.idle_queue, rdev->pm.gui_idle, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msecs_to_jiffies(RADEON_WAIT_IDLE_TIMEOUT)); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.gui_idle = false; > - ? ? ? ? ? ? ? ? ? ? ? radeon_irq_set(rdev); > + ? ? ? ? ? ? ? ? ? ? ? /* wait for GPU to become idle */ > + ? ? ? ? ? ? ? ? ? ? ? radeon_irq_kms_wait_gui_idle(rdev); > ? ? ? ? ? ? ? ?} > ? ? ? ?} else { > ? ? ? ? ? ? ? ?struct radeon_ring *ring = > &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; > diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c > index 25f9eef..8387709 100644 > --- a/drivers/gpu/drm/radeon/rs600.c > +++ b/drivers/gpu/drm/radeon/rs600.c > @@ -294,6 +294,7 @@ void rs600_hpd_init(struct radeon_device *rdev) > ?{ > ? ? ? ?struct drm_device *dev = rdev->ddev; > ? ? ? ?struct drm_connector *connector; > + ? ? ? unsigned enable = 0; > > ? ? ? ?list_for_each_entry(connector, &dev->mode_config.connector_list, head) > { > ? ? ? ? ? ? ? ?struct radeon_connector *radeon_connector = > to_radeon_connector(connector); > @@ -301,26 +302,25 @@ void rs600_hpd_init(struct radeon_device *rdev) > ? ? ? ? ? ? ? ?case RADEON_HPD_1: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? S_007D00_DC_HOT_PLUG_DETECT1_EN(1)); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[0] = true; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_2: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? S_007D10_DC_HOT_PLUG_DETECT2_EN(1)); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[1] = true; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?default: > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? enable |= 1 << radeon_connector->hpd.hpd; > ? ? ? ? ? ? ? ?radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); > ? ? ? ?} > - ? ? ? if (rdev->irq.installed) > - ? ? ? ? ? ? ? rs600_irq_set(rdev); > + ? ? ? radeon_irq_kms_enable_hpd(rdev, enable); > ?} > > ?void rs600_hpd_fini(struct radeon_device *rdev) > ?{ > ? ? ? ?struct drm_device *dev = rdev->ddev; > ? ? ? ?struct drm_connector *connector; > + ? ? ? unsigned disable = 0; > > ? ? ? ?list_for_each_entry(connector, &dev->mode_config.connector_list, head) > { > ? ? ? ? ? ? ? ?struct radeon_connector *radeon_connector = > to_radeon_connector(connector); > @@ -328,17 +328,17 @@ void rs600_hpd_fini(struct radeon_device *rdev) > ? ? ? ? ? ? ? ?case RADEON_HPD_1: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(R_007D00_DC_HOT_PLUG_DETECT1_CONTROL, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? S_007D00_DC_HOT_PLUG_DETECT1_EN(0)); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[0] = false; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case RADEON_HPD_2: > ? ? ? ? ? ? ? ? ? ? ? ?WREG32(R_007D10_DC_HOT_PLUG_DETECT2_CONTROL, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? S_007D10_DC_HOT_PLUG_DETECT2_EN(0)); > - ? ? ? ? ? ? ? ? ? ? ? rdev->irq.hpd[1] = false; > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?default: > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?} > + ? ? ? ? ? ? ? disable |= 1 << radeon_connector->hpd.hpd; > ? ? ? ?} > + ? ? ? radeon_irq_kms_disable_hpd(rdev, disable); > ?} > > ?int rs600_asic_reset(struct radeon_device *rdev) > @@ -686,7 +686,6 @@ int rs600_irq_process(struct radeon_device *rdev) > ? ? ? ? ? ? ? ?/* GUI idle */ > ? ? ? ? ? ? ? ?if (G_000040_GUI_IDLE(status)) { > ? ? ? ? ? ? ? ? ? ? ? ?rdev->irq.gui_idle_acked = true; > - ? ? ? ? ? ? ? ? ? ? ? rdev->pm.gui_idle = true; > ? ? ? ? ? ? ? ? ? ? ? ?wake_up(&rdev->irq.idle_queue); > ? ? ? ? ? ? ? ?} > ? ? ? ? ? ? ? ?/* Vertical blank interrupts */ > diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c > index 93da01c..9e691b5 100644 > --- a/drivers/gpu/drm/radeon/si.c > +++ b/drivers/gpu/drm/radeon/si.c > @@ -3771,7 +3771,6 @@ restart_ih: > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?case 233: /* GUI IDLE */ > ? ? ? ? ? ? ? ? ? ? ? ?DRM_DEBUG("IH: GUI idle\n"); > - ? ? ? ? ? ? ? ? ? ? ? rdev->pm.gui_idle = true; > ? ? ? ? ? ? ? ? ? ? ? ?wake_up(&rdev->irq.idle_queue); > ? ? ? ? ? ? ? ? ? ? ? ?break; > ? ? ? ? ? ? ? ?default: > -- > 1.7.9.5 > > _______________________________________________ > dri-devel mailing list > dri-devel at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel