Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: cancel hotplug and dig_port work during suspend and unload

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>

authored by

Imre Deak and committed by
Jani Nikula
1d0d343a 6323751d

+18 -2
+16
drivers/gpu/drm/i915/i915_drv.c
··· 494 494 return true; 495 495 } 496 496 497 + void intel_hpd_cancel_work(struct drm_i915_private *dev_priv) 498 + { 499 + spin_lock_irq(&dev_priv->irq_lock); 500 + 501 + dev_priv->long_hpd_port_mask = 0; 502 + dev_priv->short_hpd_port_mask = 0; 503 + dev_priv->hpd_event_bits = 0; 504 + 505 + spin_unlock_irq(&dev_priv->irq_lock); 506 + 507 + cancel_work_sync(&dev_priv->dig_port_work); 508 + cancel_work_sync(&dev_priv->hotplug_work); 509 + cancel_delayed_work_sync(&dev_priv->hotplug_reenable_work); 510 + } 511 + 497 512 static int i915_drm_freeze(struct drm_device *dev) 498 513 { 499 514 struct drm_i915_private *dev_priv = dev->dev_private; ··· 553 538 flush_delayed_work(&dev_priv->rps.delayed_resume_work); 554 539 555 540 intel_runtime_pm_disable_interrupts(dev); 541 + intel_hpd_cancel_work(dev_priv); 556 542 557 543 intel_suspend_gt_powersave(dev); 558 544
+1
drivers/gpu/drm/i915/i915_drv.h
··· 2178 2178 extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); 2179 2179 extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); 2180 2180 int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on); 2181 + void intel_hpd_cancel_work(struct drm_i915_private *dev_priv); 2181 2182 2182 2183 extern void intel_console_resume(struct work_struct *work); 2183 2184
+1 -2
drivers/gpu/drm/i915/intel_display.c
··· 13103 13103 * experience fancy races otherwise. 13104 13104 */ 13105 13105 drm_irq_uninstall(dev); 13106 - cancel_work_sync(&dev_priv->hotplug_work); 13107 - cancel_delayed_work_sync(&dev_priv->hotplug_reenable_work); 13106 + intel_hpd_cancel_work(dev_priv); 13108 13107 dev_priv->pm._irqs_disabled = true; 13109 13108 13110 13109 /*