Merge tag 'drm-intel-next-2015-04-23-fixed' of git://anongit.freedesktop.org/drm...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / intel_uncore.c
index ff2a74651dd48561c0170427ca9b89f3db54c9d4..a6d8a3ee7750adecb552415c8ffab06d599f46ff 100644 (file)
@@ -383,6 +383,26 @@ void intel_uncore_sanitize(struct drm_device *dev)
        intel_disable_gt_powersave(dev);
 }
 
+static void __intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
+                                        enum forcewake_domains fw_domains)
+{
+       struct intel_uncore_forcewake_domain *domain;
+       enum forcewake_domain_id id;
+
+       if (!dev_priv->uncore.funcs.force_wake_get)
+               return;
+
+       fw_domains &= dev_priv->uncore.fw_domains;
+
+       for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
+               if (domain->wake_count++)
+                       fw_domains &= ~(1 << id);
+       }
+
+       if (fw_domains)
+               dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
+}
+
 /**
  * intel_uncore_forcewake_get - grab forcewake domain references
  * @dev_priv: i915 device instance
@@ -400,41 +420,39 @@ void intel_uncore_forcewake_get(struct drm_i915_private *dev_priv,
                                enum forcewake_domains fw_domains)
 {
        unsigned long irqflags;
-       struct intel_uncore_forcewake_domain *domain;
-       enum forcewake_domain_id id;
 
        if (!dev_priv->uncore.funcs.force_wake_get)
                return;
 
        WARN_ON(dev_priv->pm.suspended);
 
-       fw_domains &= dev_priv->uncore.fw_domains;
-
        spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
-       for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
-               if (domain->wake_count++)
-                       fw_domains &= ~(1 << id);
-       }
-
-       if (fw_domains)
-               dev_priv->uncore.funcs.force_wake_get(dev_priv, fw_domains);
-
+       __intel_uncore_forcewake_get(dev_priv, fw_domains);
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 /**
- * intel_uncore_forcewake_put - release a forcewake domain reference
+ * intel_uncore_forcewake_get__locked - grab forcewake domain references
  * @dev_priv: i915 device instance
- * @fw_domains: forcewake domains to put references
+ * @fw_domains: forcewake domains to get reference on
  *
- * This function drops the device-level forcewakes for specified
- * domains obtained by intel_uncore_forcewake_get().
+ * See intel_uncore_forcewake_get(). This variant places the onus
+ * on the caller to explicitly handle the dev_priv->uncore.lock spinlock.
  */
-void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
-                               enum forcewake_domains fw_domains)
+void intel_uncore_forcewake_get__locked(struct drm_i915_private *dev_priv,
+                                       enum forcewake_domains fw_domains)
+{
+       assert_spin_locked(&dev_priv->uncore.lock);
+
+       if (!dev_priv->uncore.funcs.force_wake_get)
+               return;
+
+       __intel_uncore_forcewake_get(dev_priv, fw_domains);
+}
+
+static void __intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
+                                        enum forcewake_domains fw_domains)
 {
-       unsigned long irqflags;
        struct intel_uncore_forcewake_domain *domain;
        enum forcewake_domain_id id;
 
@@ -443,8 +461,6 @@ void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
 
        fw_domains &= dev_priv->uncore.fw_domains;
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        for_each_fw_domain_mask(domain, fw_domains, dev_priv, id) {
                if (WARN_ON(domain->wake_count == 0))
                        continue;
@@ -455,10 +471,48 @@ void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
                domain->wake_count++;
                fw_domain_arm_timer(domain);
        }
+}
 
+/**
+ * intel_uncore_forcewake_put - release a forcewake domain reference
+ * @dev_priv: i915 device instance
+ * @fw_domains: forcewake domains to put references
+ *
+ * This function drops the device-level forcewakes for specified
+ * domains obtained by intel_uncore_forcewake_get().
+ */
+void intel_uncore_forcewake_put(struct drm_i915_private *dev_priv,
+                               enum forcewake_domains fw_domains)
+{
+       unsigned long irqflags;
+
+       if (!dev_priv->uncore.funcs.force_wake_put)
+               return;
+
+       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+       __intel_uncore_forcewake_put(dev_priv, fw_domains);
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
+/**
+ * intel_uncore_forcewake_put__locked - grab forcewake domain references
+ * @dev_priv: i915 device instance
+ * @fw_domains: forcewake domains to get reference on
+ *
+ * See intel_uncore_forcewake_put(). This variant places the onus
+ * on the caller to explicitly handle the dev_priv->uncore.lock spinlock.
+ */
+void intel_uncore_forcewake_put__locked(struct drm_i915_private *dev_priv,
+                                       enum forcewake_domains fw_domains)
+{
+       assert_spin_locked(&dev_priv->uncore.lock);
+
+       if (!dev_priv->uncore.funcs.force_wake_put)
+               return;
+
+       __intel_uncore_forcewake_put(dev_priv, fw_domains);
+}
+
 void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
 {
        struct intel_uncore_forcewake_domain *domain;