aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorDamien Lespiau <damien.lespiau@intel.com>2013-10-21 09:29:30 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-10-21 18:27:49 -0400
commitd538bbdfde34028b5c5b0ba92b3c2096c5afb82c (patch)
tree20bd5f906e81cf13ae577048608d8f77be8f72b4 /drivers/gpu/drm/i915/i915_irq.c
parentc459787294e8375210a3d26fe8ed83f40eca3276 (diff)
drm/i915: Use a spin lock to protect the pipe crc struct
Daniel pointed out that it was hard to get anything lockless to work correctly, so don't even try for this non critical piece of code and just use a spin lock. v2: Make intel_pipe_crc->opened a bool v3: Use assert_spin_locked() instead of a comment (Daniel Vetter) v4: Use spin_lock_irq() in the debugfs functions (they can only be called from process context), Use spin_lock() in the pipe_crc_update() function that can only be called from an interrupt handler, Use wait_event_interruptible_lock_irq() when waiting for data in the cicular buffer to ensure proper locking around the condition we are waiting for. (Daniel Vetter) Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 8f7baad72316..1a7dc7754e2f 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1200,15 +1200,19 @@ static void display_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe,
1200 struct intel_pipe_crc_entry *entry; 1200 struct intel_pipe_crc_entry *entry;
1201 int head, tail; 1201 int head, tail;
1202 1202
1203 spin_lock(&pipe_crc->lock);
1204
1203 if (!pipe_crc->entries) { 1205 if (!pipe_crc->entries) {
1206 spin_unlock(&pipe_crc->lock);
1204 DRM_ERROR("spurious interrupt\n"); 1207 DRM_ERROR("spurious interrupt\n");
1205 return; 1208 return;
1206 } 1209 }
1207 1210
1208 head = atomic_read(&pipe_crc->head); 1211 head = pipe_crc->head;
1209 tail = atomic_read(&pipe_crc->tail); 1212 tail = pipe_crc->tail;
1210 1213
1211 if (CIRC_SPACE(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) < 1) { 1214 if (CIRC_SPACE(head, tail, INTEL_PIPE_CRC_ENTRIES_NR) < 1) {
1215 spin_unlock(&pipe_crc->lock);
1212 DRM_ERROR("CRC buffer overflowing\n"); 1216 DRM_ERROR("CRC buffer overflowing\n");
1213 return; 1217 return;
1214 } 1218 }
@@ -1223,7 +1227,9 @@ static void display_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe,
1223 entry->crc[4] = crc4; 1227 entry->crc[4] = crc4;
1224 1228
1225 head = (head + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1); 1229 head = (head + 1) & (INTEL_PIPE_CRC_ENTRIES_NR - 1);
1226 atomic_set(&pipe_crc->head, head); 1230 pipe_crc->head = head;
1231
1232 spin_unlock(&pipe_crc->lock);
1227 1233
1228 wake_up_interruptible(&pipe_crc->wq); 1234 wake_up_interruptible(&pipe_crc->wq);
1229} 1235}