Commit 2b19efeb authored by Imre Deak's avatar Imre Deak

drm/i915: add support for checking RPM atomic sections

In some cases we want to check whether we hold an RPM wakelock reference
for the whole duration of a sequence. To achieve this add a new RPM
atomic sequence counter that we increment any time the wakelock refcount
drops to zero.  Check whether the sequence number stays the same during
the atomic section and that we hold the wakelock at the beginning of the
section.

Motivated by Chris.

v2-v3:
- unchanged
v4:
- swap the order of atomic_read() and assert_rpm_wakelock_held() in
  assert_rpm_atomic_begin() to avoid race
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> (v3)
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1450203038-5150-10-git-send-email-imre.deak@intel.com
parent 542db3cd
...@@ -1606,6 +1606,7 @@ struct skl_wm_level { ...@@ -1606,6 +1606,7 @@ struct skl_wm_level {
*/ */
struct i915_runtime_pm { struct i915_runtime_pm {
atomic_t wakeref_count; atomic_t wakeref_count;
atomic_t atomic_seq;
bool suspended; bool suspended;
bool irqs_enabled; bool irqs_enabled;
}; };
......
...@@ -1446,6 +1446,23 @@ assert_rpm_wakelock_held(struct drm_i915_private *dev_priv) ...@@ -1446,6 +1446,23 @@ assert_rpm_wakelock_held(struct drm_i915_private *dev_priv)
"RPM wakelock ref not held during HW access"); "RPM wakelock ref not held during HW access");
} }
static inline int
assert_rpm_atomic_begin(struct drm_i915_private *dev_priv)
{
int seq = atomic_read(&dev_priv->pm.atomic_seq);
assert_rpm_wakelock_held(dev_priv);
return seq;
}
static inline void
assert_rpm_atomic_end(struct drm_i915_private *dev_priv, int begin_seq)
{
WARN_ONCE(atomic_read(&dev_priv->pm.atomic_seq) != begin_seq,
"HW access outside of RPM atomic section\n");
}
/** /**
* disable_rpm_wakeref_asserts - disable the RPM assert checks * disable_rpm_wakeref_asserts - disable the RPM assert checks
* @dev_priv: i915 device instance * @dev_priv: i915 device instance
......
...@@ -7247,4 +7247,5 @@ void intel_pm_setup(struct drm_device *dev) ...@@ -7247,4 +7247,5 @@ void intel_pm_setup(struct drm_device *dev)
dev_priv->pm.suspended = false; dev_priv->pm.suspended = false;
atomic_set(&dev_priv->pm.wakeref_count, 0); atomic_set(&dev_priv->pm.wakeref_count, 0);
atomic_set(&dev_priv->pm.atomic_seq, 0);
} }
...@@ -2287,7 +2287,8 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv) ...@@ -2287,7 +2287,8 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv)
struct device *device = &dev->pdev->dev; struct device *device = &dev->pdev->dev;
assert_rpm_wakelock_held(dev_priv); assert_rpm_wakelock_held(dev_priv);
atomic_dec(&dev_priv->pm.wakeref_count); if (atomic_dec_and_test(&dev_priv->pm.wakeref_count))
atomic_inc(&dev_priv->pm.atomic_seq);
pm_runtime_mark_last_busy(device); pm_runtime_mark_last_busy(device);
pm_runtime_put_autosuspend(device); pm_runtime_put_autosuspend(device);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment