At Thu, 23 May 2013 01:04:13 +0800, Wang Xingchao wrote: > > Haswell Display audio depends on power well in graphic side, it should > request power well before use it and release power well after use. > I915 will not shutdown power well if it detects audio is using. > This patch protects display audio crash for Intel Haswell C3 stepping board. > > Signed-off-by: Wang Xingchao <xingchao.wang at linux.intel.com> Just minor points: > +/* Display audio driver power well request */ > +void i915_request_power_well(void) > +{ > + if (hsw_pwr == NULL) > + return; > + > + spin_lock_irq(&hsw_pwr->lock); If both functions are supposed to be called only in non-sleepable state, there is no merit to use _irq version of spinlock. OTOH, if this function can be called from non-sleepable context, spin_lock_irq() is wrong. That is, the lock here should be either spin_lock() (supposing all places are not from interrupt context) or spin_lock_irqsave() (allowing from interrupt context). > + if (!hsw_pwr->count++ && > + !hsw_pwr->i915_request) > + __intel_set_power_well(hsw_pwr->device, true); > + spin_unlock_irq(&hsw_pwr->lock); > +} > +EXPORT_SYMBOL_GPL(i915_request_power_well); > + > +/* Display audio driver power well release */ > +void i915_release_power_well(void) > +{ > + if (hsw_pwr == NULL) > + return; > + > + spin_lock_irq(&hsw_pwr->lock); > + WARN_ON(!hsw_pwr->count); > + if (!--hsw_pwr->count && > + !hsw_pwr->i915_request) > + __intel_set_power_well(hsw_pwr->device, false); > + spin_unlock_irq(&hsw_pwr->lock); > +} > +EXPORT_SYMBOL_GPL(i915_release_power_well); > + > +int i915_init_power_well(struct drm_device *dev) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; Since this is a global variable that must be initialized only once, safer to have WARN_ON(hsw_pwr); > + hsw_pwr = kzalloc(sizeof *hsw_pwr, GFP_KERNEL); > + if (hsw_pwr == NULL) > + return -ENOMEM; > + > + dev_priv->hsw_pwr = hsw_pwr; > + > + hsw_pwr->device = dev; > + spin_lock_init(&hsw_pwr->lock); > + hsw_pwr->count = 0; > + > + return 0; > +} > + > +void i915_remove_power_well(struct drm_device *dev) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; ... and WARN_ON(hsw_ptr != dev_priv->hsw_pwr); > + kfree(dev_priv->hsw_pwr); > + dev_priv->hsw_pwr = NULL; > + hsw_pwr = NULL; > +} Takashi > + > +void intel_set_power_well(struct drm_device *dev, bool enable) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct i915_power_well *power_well = dev_priv->hsw_pwr; > + > + if (!HAS_POWER_WELL(dev)) > + return; > + > + if (!i915_disable_power_well && !enable) > + return; > + > + if (!power_well) > + return; > + > + spin_lock_irq(&power_well->lock); > + power_well->i915_request = enable; > + > + /* only reject "disable" power well request */ > + if (power_well->count && !enable) { > + spin_unlock_irq(&power_well->lock); > + return; > + } > + > + __intel_set_power_well(dev, enable); > + spin_unlock_irq(&power_well->lock); > +} > + > /* > * Starting with Haswell, we have a "Power Down Well" that can be turned off > * when not needed anymore. We have 4 registers that can request the power well > diff --git a/include/drm/i915_powerwell.h b/include/drm/i915_powerwell.h > new file mode 100644 > index 0000000..cfdc884 > --- /dev/null > +++ b/include/drm/i915_powerwell.h > @@ -0,0 +1,36 @@ > +/************************************************************************** > + * > + * Copyright 2013 Intel Inc. > + * All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the > + * "Software"), to deal in the Software without restriction, including > + * without limitation the rights to use, copy, modify, merge, publish, > + * distribute, sub license, and/or sell copies of the Software, and to > + * permit persons to whom the Software is furnished to do so, subject to > + * the following conditions: > + * > + * The above copyright notice and this permission notice (including the > + * next paragraph) shall be included in all copies or substantial portions > + * of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, > + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR > + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE > + * USE OR OTHER DEALINGS IN THE SOFTWARE. > + * > + * > + **************************************************************************/ > + > +#ifndef _I915_POWERWELL_H_ > +#define _I915_POWERWELL_H_ > + > +/* For use by hda_i915 driver */ > +extern void i915_request_power_well(void); > +extern void i915_release_power_well(void); > + > +#endif /* _I915_POWERWELL_H_ */ > -- > 1.8.1.2 >