Skip to content

Commit

Permalink
drm/i915: cancel hotplug and dig_port work during suspend and unload
Browse files Browse the repository at this point in the history
Make sure these work handlers don't run after we system suspend or
unload the driver. Note that we don't cancel the handlers during runtime
suspend. That could lead to a lockup, since we take a runtime PM ref
from the handlers themselves. Fortunaltely canceling there is not needed
since the RPM ref itself provides for the needed serialization.

v2:
- fix the order of canceling dig_port_work wrt. hotplug_work (Ville)
- zero out {long,short}_hpd_port_mask and hpd_event_bits for speed
  (Ville)

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: stable@vger.kernel.org (3.16+)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
  • Loading branch information
Imre Deak authored and Jani Nikula committed Aug 18, 2014
1 parent 6323751 commit 1d0d343
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
16 changes: 16 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,21 @@ bool i915_semaphore_is_enabled(struct drm_device *dev)
return true;
}

void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
{
spin_lock_irq(&dev_priv->irq_lock);

dev_priv->long_hpd_port_mask = 0;
dev_priv->short_hpd_port_mask = 0;
dev_priv->hpd_event_bits = 0;

spin_unlock_irq(&dev_priv->irq_lock);

cancel_work_sync(&dev_priv->dig_port_work);
cancel_work_sync(&dev_priv->hotplug_work);
cancel_delayed_work_sync(&dev_priv->hotplug_reenable_work);
}

static int i915_drm_freeze(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
Expand Down Expand Up @@ -538,6 +553,7 @@ static int i915_drm_freeze(struct drm_device *dev)
flush_delayed_work(&dev_priv->rps.delayed_resume_work);

intel_runtime_pm_disable_interrupts(dev);
intel_hpd_cancel_work(dev_priv);

intel_suspend_gt_powersave(dev);

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2178,6 +2178,7 @@ extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
extern void i915_update_gfx_val(struct drm_i915_private *dev_priv);
int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on);
void intel_hpd_cancel_work(struct drm_i915_private *dev_priv);

extern void intel_console_resume(struct work_struct *work);

Expand Down
3 changes: 1 addition & 2 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -13103,8 +13103,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
* experience fancy races otherwise.
*/
drm_irq_uninstall(dev);
cancel_work_sync(&dev_priv->hotplug_work);
cancel_delayed_work_sync(&dev_priv->hotplug_reenable_work);
intel_hpd_cancel_work(dev_priv);
dev_priv->pm._irqs_disabled = true;

/*
Expand Down

0 comments on commit 1d0d343

Please sign in to comment.