drm/nv31/mpeg: remove need for separate refcnt on engine use
authorBen Skeggs <bskeggs@redhat.com>
Mon, 9 Sep 2013 05:26:07 +0000 (15:26 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 8 Nov 2013 05:37:43 +0000 (15:37 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h

index 77b6308..7eb6d94 100644 (file)
@@ -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
index 62d04e4..d08629d 100644 (file)
@@ -9,7 +9,6 @@ struct nv31_mpeg_chan {
 
 struct nv31_mpeg_priv {
        struct nouveau_mpeg base;
-       atomic_t refcount;
        struct nv31_mpeg_chan *chan;
 };