Skip to content

Commit

Permalink
drm/nouveau/timer: add a way to cancel alarms
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Martin Peres authored and Ben Skeggs committed Sep 4, 2013
1 parent 7fabd25 commit b925a75
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/core/include/subdev/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ bool nouveau_timer_wait_eq(void *, u64 nsec, u32 addr, u32 mask, u32 data);
bool nouveau_timer_wait_ne(void *, u64 nsec, u32 addr, u32 mask, u32 data);
bool nouveau_timer_wait_cb(void *, u64 nsec, bool (*func)(void *), void *data);
void nouveau_timer_alarm(void *, u32 nsec, struct nouveau_alarm *);
void nouveau_timer_alarm_cancel(void *, struct nouveau_alarm *);

#define NV_WAIT_DEFAULT 2000000000ULL
#define nv_wait(o,a,m,v) \
Expand All @@ -35,6 +36,7 @@ struct nouveau_timer {
struct nouveau_subdev base;
u64 (*read)(struct nouveau_timer *);
void (*alarm)(struct nouveau_timer *, u64 time, struct nouveau_alarm *);
void (*alarm_cancel)(struct nouveau_timer *, struct nouveau_alarm *);
};

static inline struct nouveau_timer *
Expand Down
7 changes: 7 additions & 0 deletions drivers/gpu/drm/nouveau/core/subdev/timer/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,10 @@ nouveau_timer_alarm(void *obj, u32 nsec, struct nouveau_alarm *alarm)
struct nouveau_timer *ptimer = nouveau_timer(obj);
ptimer->alarm(ptimer, nsec, alarm);
}

void
nouveau_timer_alarm_cancel(void *obj, struct nouveau_alarm *alarm)
{
struct nouveau_timer *ptimer = nouveau_timer(obj);
ptimer->alarm_cancel(ptimer, alarm);
}
20 changes: 20 additions & 0 deletions drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,25 @@ nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time,
nv04_timer_alarm_trigger(ptimer);
}

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)
{
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit b925a75

Please sign in to comment.