diff options
author | Martin Peres <martin.peres@labri.fr> | 2013-08-12 02:48:51 (GMT) |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-09-04 03:46:46 (GMT) |
commit | b925a75d6729cec8debd0c378b354d8c228b36aa (patch) | |
tree | 8a0050246254e8c07aca6658a6abae4453c32cf8 /drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c | |
parent | 7fabd25393c7b5cb749d358772ccea2a570f4b49 (diff) | |
download | linux-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.c | 20 |
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); |