aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
index 07dc82bfe346..182f27c73aeb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
@@ -65,14 +65,17 @@ nvkm_timer_alarm(struct nvkm_timer *tmr, u32 nsec, struct nvkm_alarm *alarm)
65 struct nvkm_alarm *list; 65 struct nvkm_alarm *list;
66 unsigned long flags; 66 unsigned long flags;
67 67
68 alarm->timestamp = nvkm_timer_read(tmr) + nsec; 68 /* Remove alarm from pending list.
69 69 *
70 /* append new alarm to list, in soonest-alarm-first order */ 70 * This both protects against the corruption of the list,
71 * and implements alarm rescheduling/cancellation.
72 */
71 spin_lock_irqsave(&tmr->lock, flags); 73 spin_lock_irqsave(&tmr->lock, flags);
72 if (!nsec) { 74 list_del_init(&alarm->head);
73 if (!list_empty(&alarm->head)) 75
74 list_del(&alarm->head); 76 if (nsec) {
75 } else { 77 /* Insert into pending list, ordered earliest to latest. */
78 alarm->timestamp = nvkm_timer_read(tmr) + nsec;
76 list_for_each_entry(list, &tmr->alarms, head) { 79 list_for_each_entry(list, &tmr->alarms, head) {
77 if (list->timestamp > alarm->timestamp) 80 if (list->timestamp > alarm->timestamp)
78 break; 81 break;