Skip to content

Commit b925a75

Browse files
mupufBen Skeggs
authored andcommitted
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 <[email protected]> Tested-by: Martin Peres <[email protected]> Tested-by: Dash Four <[email protected]> Signed-off-by: Ben Skeggs <[email protected]>
1 parent 7fabd25 commit b925a75

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

drivers/gpu/drm/nouveau/core/include/subdev/timer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ bool nouveau_timer_wait_eq(void *, u64 nsec, u32 addr, u32 mask, u32 data);
2222
bool nouveau_timer_wait_ne(void *, u64 nsec, u32 addr, u32 mask, u32 data);
2323
bool nouveau_timer_wait_cb(void *, u64 nsec, bool (*func)(void *), void *data);
2424
void nouveau_timer_alarm(void *, u32 nsec, struct nouveau_alarm *);
25+
void nouveau_timer_alarm_cancel(void *, struct nouveau_alarm *);
2526

2627
#define NV_WAIT_DEFAULT 2000000000ULL
2728
#define nv_wait(o,a,m,v) \
@@ -35,6 +36,7 @@ struct nouveau_timer {
3536
struct nouveau_subdev base;
3637
u64 (*read)(struct nouveau_timer *);
3738
void (*alarm)(struct nouveau_timer *, u64 time, struct nouveau_alarm *);
39+
void (*alarm_cancel)(struct nouveau_timer *, struct nouveau_alarm *);
3840
};
3941

4042
static inline struct nouveau_timer *

drivers/gpu/drm/nouveau/core/subdev/timer/base.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,10 @@ nouveau_timer_alarm(void *obj, u32 nsec, struct nouveau_alarm *alarm)
8585
struct nouveau_timer *ptimer = nouveau_timer(obj);
8686
ptimer->alarm(ptimer, nsec, alarm);
8787
}
88+
89+
void
90+
nouveau_timer_alarm_cancel(void *obj, struct nouveau_alarm *alarm)
91+
{
92+
struct nouveau_timer *ptimer = nouveau_timer(obj);
93+
ptimer->alarm_cancel(ptimer, alarm);
94+
}

drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,25 @@ nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time,
113113
nv04_timer_alarm_trigger(ptimer);
114114
}
115115

116+
static void
117+
nv04_timer_alarm_cancel(struct nouveau_timer *ptimer,
118+
struct nouveau_alarm *alarm)
119+
{
120+
struct nv04_timer_priv *priv = (void *)ptimer;
121+
unsigned long flags;
122+
123+
/* avoid deleting an entry while the alarm intr is running */
124+
spin_lock_irqsave(&priv->lock, flags);
125+
126+
/* delete the alarm from the list */
127+
list_del(&alarm->head);
128+
129+
/* reset the head so as list_empty returns 1 */
130+
INIT_LIST_HEAD(&alarm->head);
131+
132+
spin_unlock_irqrestore(&priv->lock, flags);
133+
}
134+
116135
static void
117136
nv04_timer_intr(struct nouveau_subdev *subdev)
118137
{
@@ -147,6 +166,7 @@ nv04_timer_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
147166
priv->base.base.intr = nv04_timer_intr;
148167
priv->base.read = nv04_timer_read;
149168
priv->base.alarm = nv04_timer_alarm;
169+
priv->base.alarm_cancel = nv04_timer_alarm_cancel;
150170
priv->suspend_time = 0;
151171

152172
INIT_LIST_HEAD(&priv->alarms);

0 commit comments

Comments
 (0)