diff options
author | Damien Lespiau <damien.lespiau@intel.com> | 2013-10-21 09:29:30 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-10-21 18:27:49 -0400 |
commit | d538bbdfde34028b5c5b0ba92b3c2096c5afb82c (patch) | |
tree | 20bd5f906e81cf13ae577048608d8f77be8f72b4 /drivers/gpu/drm/i915/i915_irq.c | |
parent | c459787294e8375210a3d26fe8ed83f40eca3276 (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.c | 12 |
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 | } |