summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
diff options
context:
space:
mode:
authorMartin Peres <martin.peres@labri.fr>2013-08-12 02:48:51 (GMT)
committerBen Skeggs <bskeggs@redhat.com>2013-09-04 03:46:46 (GMT)
commitb925a75d6729cec8debd0c378b354d8c228b36aa (patch)
tree8a0050246254e8c07aca6658a6abae4453c32cf8 /drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
parent7fabd25393c7b5cb749d358772ccea2a570f4b49 (diff)
downloadlinux-fsl-qoriq-b925a75d6729cec8debd0c378b354d8c228b36aa.tar.xz
drm/nouveau/timer: add a way to cancel alarms
Since alarms don't play well with suspend, it is important every alarm user cancels his tasks before suspending. The task should be rescheduled on resume. Signed-off-by: Martin Peres <martin.peres@labri.fr> Tested-by: Martin Peres <martin.peres@labri.fr> Tested-by: Dash Four <mr.dash.four@googlemail.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c')
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
index 49350ea..57711ec 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
@@ -114,6 +114,25 @@ nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time,
}
static void
+nv04_timer_alarm_cancel(struct nouveau_timer *ptimer,
+ struct nouveau_alarm *alarm)
+{
+ struct nv04_timer_priv *priv = (void *)ptimer;
+ unsigned long flags;
+
+ /* avoid deleting an entry while the alarm intr is running */
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /* delete the alarm from the list */
+ list_del(&alarm->head);
+
+ /* reset the head so as list_empty returns 1 */
+ INIT_LIST_HEAD(&alarm->head);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static void
nv04_timer_intr(struct nouveau_subdev *subdev)
{
struct nv04_timer_priv *priv = (void *)subdev;
@@ -147,6 +166,7 @@ nv04_timer_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->base.base.intr = nv04_timer_intr;
priv->base.read = nv04_timer_read;
priv->base.alarm = nv04_timer_alarm;
+ priv->base.alarm_cancel = nv04_timer_alarm_cancel;
priv->suspend_time = 0;
INIT_LIST_HEAD(&priv->alarms);