]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
drm/nouveau/fifo: trigger engine context unload before zeroing context pointer
authorBen Skeggs <bskeggs@redhat.com>
Tue, 27 Nov 2012 01:05:36 +0000 (11:05 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 28 Nov 2012 23:58:12 +0000 (09:58 +1000)
Fixes a PCE0 page fault noticed on NVD9 during module unload.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c

index 3d3ed547ed4c6d762c27ebeeedeb225349c93ab0..bd096364f6803c616ec039a56d97c7e99c5a873d 100644 (file)
@@ -112,14 +112,6 @@ nv50_fifo_context_detach(struct nouveau_object *parent, bool suspend,
                return -EINVAL;
        }
 
-       nv_wo32(base->eng, addr + 0x00, 0x00000000);
-       nv_wo32(base->eng, addr + 0x04, 0x00000000);
-       nv_wo32(base->eng, addr + 0x08, 0x00000000);
-       nv_wo32(base->eng, addr + 0x0c, 0x00000000);
-       nv_wo32(base->eng, addr + 0x10, 0x00000000);
-       nv_wo32(base->eng, addr + 0x14, 0x00000000);
-       bar->flush(bar);
-
        /* HW bug workaround:
         *
         * PFIFO will hang forever if the connected engines don't report
@@ -141,8 +133,18 @@ nv50_fifo_context_detach(struct nouveau_object *parent, bool suspend,
                if (suspend)
                        ret = -EBUSY;
        }
-
        nv_wr32(priv, 0x00b860, me);
+
+       if (ret == 0) {
+               nv_wo32(base->eng, addr + 0x00, 0x00000000);
+               nv_wo32(base->eng, addr + 0x04, 0x00000000);
+               nv_wo32(base->eng, addr + 0x08, 0x00000000);
+               nv_wo32(base->eng, addr + 0x0c, 0x00000000);
+               nv_wo32(base->eng, addr + 0x10, 0x00000000);
+               nv_wo32(base->eng, addr + 0x14, 0x00000000);
+               bar->flush(bar);
+       }
+
        return ret;
 }
 
index 7969df948cfa66f990e9d41f3064f2ee5d73e2ba..1eb1c512f5032048b29db31d7c9781698f4847de 100644 (file)
@@ -95,14 +95,6 @@ nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend,
                return -EINVAL;
        }
 
-       nv_wo32(base->eng, addr + 0x00, 0x00000000);
-       nv_wo32(base->eng, addr + 0x04, 0x00000000);
-       nv_wo32(base->eng, addr + 0x08, 0x00000000);
-       nv_wo32(base->eng, addr + 0x0c, 0x00000000);
-       nv_wo32(base->eng, addr + 0x10, 0x00000000);
-       nv_wo32(base->eng, addr + 0x14, 0x00000000);
-       bar->flush(bar);
-
        save = nv_mask(priv, 0x002520, 0x0000003f, 1 << engn);
        nv_wr32(priv, 0x0032fc, nv_gpuobj(base)->addr >> 12);
        done = nv_wait_ne(priv, 0x0032fc, 0xffffffff, 0xffffffff);
@@ -112,6 +104,14 @@ nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend,
                if (suspend)
                        return -EBUSY;
        }
+
+       nv_wo32(base->eng, addr + 0x00, 0x00000000);
+       nv_wo32(base->eng, addr + 0x04, 0x00000000);
+       nv_wo32(base->eng, addr + 0x08, 0x00000000);
+       nv_wo32(base->eng, addr + 0x0c, 0x00000000);
+       nv_wo32(base->eng, addr + 0x10, 0x00000000);
+       nv_wo32(base->eng, addr + 0x14, 0x00000000);
+       bar->flush(bar);
        return 0;
 }
 
index 8f25255247e503a16bc3423101963b7880ba228a..b4365dde1859bfd332a11548e9034b662c3ce51a 100644 (file)
@@ -147,10 +147,6 @@ nvc0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
                return -EINVAL;
        }
 
-       nv_wo32(base, addr + 0x00, 0x00000000);
-       nv_wo32(base, addr + 0x04, 0x00000000);
-       bar->flush(bar);
-
        nv_wr32(priv, 0x002634, chan->base.chid);
        if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) {
                nv_error(priv, "channel %d kick timeout\n", chan->base.chid);
@@ -158,6 +154,9 @@ nvc0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
                        return -EBUSY;
        }
 
+       nv_wo32(base, addr + 0x00, 0x00000000);
+       nv_wo32(base, addr + 0x04, 0x00000000);
+       bar->flush(bar);
        return 0;
 }
 
index 9df59c028e45cde4aaf2a700f1cbfbdf4dce6de4..c930da99c2c16df8f0185d6b0a41d8196fe884fe 100644 (file)
@@ -182,10 +182,6 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
                return -EINVAL;
        }
 
-       nv_wo32(base, addr + 0x00, 0x00000000);
-       nv_wo32(base, addr + 0x04, 0x00000000);
-       bar->flush(bar);
-
        nv_wr32(priv, 0x002634, chan->base.chid);
        if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) {
                nv_error(priv, "channel %d kick timeout\n", chan->base.chid);
@@ -193,6 +189,9 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
                        return -EBUSY;
        }
 
+       nv_wo32(base, addr + 0x00, 0x00000000);
+       nv_wo32(base, addr + 0x04, 0x00000000);
+       bar->flush(bar);
        return 0;
 }