summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2013-09-09 15:26:07 +1000
committerBen Skeggs <bskeggs@redhat.com>2013-11-08 15:37:43 +1000
commitab403ac96fc7e95548107d361c8ae17ed2179c75 (patch)
tree5e5e19c9ee62b37b6a2f252b488bcf4a91136470
parentb449a43f56d412a0260f3df08b061a5e937db77b (diff)
downloadlinux-ab403ac96fc7e95548107d361c8ae17ed2179c75.tar.gz
linux-ab403ac96fc7e95548107d361c8ae17ed2179c75.tar.bz2
linux-ab403ac96fc7e95548107d361c8ae17ed2179c75.zip
drm/nv31/mpeg: remove need for separate refcnt on engine use
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c39
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h1
2 files changed, 21 insertions, 19 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
index 77b630867010..7eb6d94c84e2 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
@@ -137,18 +137,23 @@ nv31_mpeg_context_ctor(struct nouveau_object *parent,
{
struct nv31_mpeg_priv *priv = (void *)engine;
struct nv31_mpeg_chan *chan;
+ unsigned long flags;
int ret;
- if (!atomic_add_unless(&priv->refcount, 1, 1))
- return -EBUSY;
-
ret = nouveau_object_create(parent, engine, oclass, 0, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
+ spin_lock_irqsave(&nv_engine(priv)->lock, flags);
+ if (priv->chan) {
+ spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
+ nouveau_object_destroy(&chan->base);
+ *pobject = NULL;
+ return -EBUSY;
+ }
priv->chan = chan;
-
+ spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
return 0;
}
@@ -157,11 +162,12 @@ nv31_mpeg_context_dtor(struct nouveau_object *object)
{
struct nv31_mpeg_priv *priv = (void *)object->engine;
struct nv31_mpeg_chan *chan = (void *)object;
+ unsigned long flags;
- WARN_ON(priv->chan != chan);
+ spin_lock_irqsave(&nv_engine(priv)->lock, flags);
priv->chan = NULL;
+ spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
nouveau_object_destroy(&chan->base);
- atomic_dec(&priv->refcount);
}
struct nouveau_oclass
@@ -193,20 +199,19 @@ nv31_mpeg_tile_prog(struct nouveau_engine *engine, int i)
void
nv31_mpeg_intr(struct nouveau_subdev *subdev)
{
+ struct nv31_mpeg_priv *priv = (void *)subdev;
struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
struct nouveau_handle *handle;
- struct nv31_mpeg_priv *priv = (void *)subdev;
- struct nouveau_object *engctx = &priv->chan->base;
+ struct nouveau_object *engctx;
u32 stat = nv_rd32(priv, 0x00b100);
u32 type = nv_rd32(priv, 0x00b230);
u32 mthd = nv_rd32(priv, 0x00b234);
u32 data = nv_rd32(priv, 0x00b238);
u32 show = stat;
- int chid = pfifo->chid(pfifo, engctx);
+ unsigned long flags;
- if (engctx)
- if (nouveau_object_inc(engctx))
- engctx = NULL;
+ spin_lock_irqsave(&nv_engine(priv)->lock, flags);
+ engctx = nv_object(priv->chan);
if (stat & 0x01000000) {
/* happens on initial binding of the object */
@@ -227,14 +232,12 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
nv_wr32(priv, 0x00b230, 0x00000001);
if (show) {
- nv_error(priv,
- "ch %d [%s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
- chid, nouveau_client_name(engctx), stat,
- type, mthd, data);
+ nv_error(priv, "ch %d [%s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ pfifo->chid(pfifo, engctx),
+ nouveau_client_name(engctx), stat, type, mthd, data);
}
- if (engctx)
- WARN_ON(nouveau_object_dec(engctx, false));
+ spin_unlock_irqrestore(&nv_engine(priv)->lock, flags);
}
static int
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
index 62d04e475315..d08629d0b6ad 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
@@ -9,7 +9,6 @@ struct nv31_mpeg_chan {
struct nv31_mpeg_priv {
struct nouveau_mpeg base;
- atomic_t refcount;
struct nv31_mpeg_chan *chan;
};