Backlight is fiddled both through backlight sysfs files and asle interrupts. Protect the relevant data. Signed-off-by: Jani Nikula <jani.nikula at intel.com> --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_panel.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5e38a2c..2e59610 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -943,6 +943,7 @@ typedef struct drm_i915_private { struct { int level; bool enabled; + spinlock_t lock; struct backlight_device *device; } backlight; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 0e7e873..2a95297 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -285,6 +285,9 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level void intel_panel_set_backlight(struct drm_device *dev, u32 level) { struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->backlight.lock, flags); dev_priv->backlight.level = level; if (dev_priv->backlight.device) @@ -292,11 +295,16 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level) if (dev_priv->backlight.enabled) intel_panel_actually_set_backlight(dev, level); + + spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); } void intel_panel_disable_backlight(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->backlight.lock, flags); dev_priv->backlight.enabled = false; intel_panel_actually_set_backlight(dev, 0); @@ -314,12 +322,17 @@ void intel_panel_disable_backlight(struct drm_device *dev) I915_WRITE(BLC_PWM_PCH_CTL1, tmp); } } + + spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); } void intel_panel_enable_backlight(struct drm_device *dev, enum pipe pipe) { struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->backlight.lock, flags); if (dev_priv->backlight.level == 0) { dev_priv->backlight.level = intel_panel_get_max_backlight(dev); @@ -372,12 +385,15 @@ set_level: */ if (!intel_panel_get_backlight(dev)) intel_panel_actually_set_backlight(dev, dev_priv->backlight.level); + + spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); } static void intel_panel_init_backlight(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + spin_lock_init(&dev_priv->backlight.lock); dev_priv->backlight.level = intel_panel_get_backlight(dev); dev_priv->backlight.enabled = dev_priv->backlight.level != 0; } -- 1.7.9.5