diff --git a/debian/changelog b/debian/changelog index 001f33e5e..d4beab840 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,7 @@ linux-2.6 (3.0.0~rc5-1~experimental.2) UNRELEASED; urgency=low SENSORS_MAX6642, BT_WILINK. * [x86_32] enable modular I2C_PXA. * [x86] enable modular SENSORS_FAM15H_POWER. + * drm/i915: Hold struct_mutex during i915_save_state/i915_restore_state. -- maximilian attems Tue, 28 Jun 2011 12:10:21 +0200 diff --git a/debian/patches/bugfix/all/drm_i915_hold_struct_mutex.patch b/debian/patches/bugfix/all/drm_i915_hold_struct_mutex.patch new file mode 100644 index 000000000..450f5a33d --- /dev/null +++ b/debian/patches/bugfix/all/drm_i915_hold_struct_mutex.patch @@ -0,0 +1,135 @@ +From: Keith Packard +Date: Wed, 29 Jun 2011 07:30:34 +0000 (-0700) +Subject: drm/i915: Hold struct_mutex during i915_save_state/i915_restore_state + +Lots of register access in these functions, some of which requires the +struct mutex. + +These functions now hold the struct mutex across the calls to +i915_save_display and i915_restore_display, and so the internal mutex +calls in those functions have been removed. To ensure that no-one else +was calling them (and hence violating the new required locking +invarient), those functions have been made static. + +gen6_enable_rps locks the struct mutex, and so i915_restore_state +unlocks the mutex around calls to that function. + +Reviewed-by: Ben Widawsky +Signed-off-by: Keith Packard +--- + +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index eddabf6..1c8bfb1 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -997,8 +997,6 @@ extern unsigned int i915_enable_fbc; + + extern int i915_suspend(struct drm_device *dev, pm_message_t state); + extern int i915_resume(struct drm_device *dev); +-extern void i915_save_display(struct drm_device *dev); +-extern void i915_restore_display(struct drm_device *dev); + extern int i915_master_create(struct drm_device *dev, struct drm_master *master); + extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); + +diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c +index e8152d2..5257cfc 100644 +--- a/drivers/gpu/drm/i915/i915_suspend.c ++++ b/drivers/gpu/drm/i915/i915_suspend.c +@@ -597,7 +597,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) + return; + } + +-void i915_save_display(struct drm_device *dev) ++static void i915_save_display(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + +@@ -678,7 +678,6 @@ void i915_save_display(struct drm_device *dev) + } + + /* VGA state */ +- mutex_lock(&dev->struct_mutex); + dev_priv->saveVGA0 = I915_READ(VGA0); + dev_priv->saveVGA1 = I915_READ(VGA1); + dev_priv->saveVGA_PD = I915_READ(VGA_PD); +@@ -688,10 +687,9 @@ void i915_save_display(struct drm_device *dev) + dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); + + i915_save_vga(dev); +- mutex_unlock(&dev->struct_mutex); + } + +-void i915_restore_display(struct drm_device *dev) ++static void i915_restore_display(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; + +@@ -783,7 +781,6 @@ void i915_restore_display(struct drm_device *dev) + else + I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); + +- mutex_lock(&dev->struct_mutex); + I915_WRITE(VGA0, dev_priv->saveVGA0); + I915_WRITE(VGA1, dev_priv->saveVGA1); + I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); +@@ -791,7 +788,6 @@ void i915_restore_display(struct drm_device *dev) + udelay(150); + + i915_restore_vga(dev); +- mutex_unlock(&dev->struct_mutex); + } + + int i915_save_state(struct drm_device *dev) +@@ -801,6 +797,8 @@ int i915_save_state(struct drm_device *dev) + + pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); + ++ mutex_lock(&dev->struct_mutex); ++ + /* Hardware status page */ + dev_priv->saveHWS = I915_READ(HWS_PGA); + +@@ -840,6 +838,8 @@ int i915_save_state(struct drm_device *dev) + for (i = 0; i < 3; i++) + dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); + ++ mutex_unlock(&dev->struct_mutex); ++ + return 0; + } + +@@ -850,6 +850,8 @@ int i915_restore_state(struct drm_device *dev) + + pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); + ++ mutex_lock(&dev->struct_mutex); ++ + /* Hardware status page */ + I915_WRITE(HWS_PGA, dev_priv->saveHWS); + +@@ -867,6 +869,7 @@ int i915_restore_state(struct drm_device *dev) + I915_WRITE(IER, dev_priv->saveIER); + I915_WRITE(IMR, dev_priv->saveIMR); + } ++ mutex_unlock(&dev->struct_mutex); + + intel_init_clock_gating(dev); + +@@ -878,6 +881,8 @@ int i915_restore_state(struct drm_device *dev) + if (IS_GEN6(dev)) + gen6_enable_rps(dev_priv); + ++ mutex_lock(&dev->struct_mutex); ++ + /* Cache mode state */ + I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); + +@@ -891,6 +896,8 @@ int i915_restore_state(struct drm_device *dev) + for (i = 0; i < 3; i++) + I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); + ++ mutex_unlock(&dev->struct_mutex); ++ + intel_i2c_reset(dev); + + return 0; diff --git a/debian/patches/series/base b/debian/patches/series/base index f758dff6e..ecc7d7ed6 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -45,3 +45,4 @@ + bugfix/mips/mips-i8259-use-struct-syscore_ops-instead-of-sysdevs.patch + bugfix/ia64/nouveau-ACPI-support-is-dependent-on-X86.patch + features/all/rt2x00-Add-device-ID-for-RT539F-device.patch ++ bugfix/all/drm_i915_hold_struct_mutex.patch