drm/nouveau/bar: implement bar1 teardown

Will prevent spurious MMU fault interrupts if something decides to touch
BAR1 after we've unloaded the driver.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs 2017-11-01 03:56:19 +10:00
parent 7313cfa4f6
commit bbb163e189
6 changed files with 30 additions and 0 deletions

View File

@ -45,6 +45,14 @@ nvkm_bar_umap(struct nvkm_bar *bar, u64 size, int type, struct nvkm_vma *vma)
return bar->func->umap(bar, size, type, vma); return bar->func->umap(bar, size, type, vma);
} }
static int
nvkm_bar_fini(struct nvkm_subdev *subdev, bool suspend)
{
struct nvkm_bar *bar = nvkm_bar(subdev);
bar->func->bar1.fini(bar);
return 0;
}
static int static int
nvkm_bar_init(struct nvkm_subdev *subdev) nvkm_bar_init(struct nvkm_subdev *subdev)
{ {
@ -74,6 +82,7 @@ nvkm_bar = {
.dtor = nvkm_bar_dtor, .dtor = nvkm_bar_dtor,
.oneinit = nvkm_bar_oneinit, .oneinit = nvkm_bar_oneinit,
.init = nvkm_bar_init, .init = nvkm_bar_init,
.fini = nvkm_bar_fini,
}; };
void void

View File

@ -45,6 +45,7 @@ g84_bar_func = {
.oneinit = nv50_bar_oneinit, .oneinit = nv50_bar_oneinit,
.init = nv50_bar_init, .init = nv50_bar_init,
.bar1.init = nv50_bar_bar1_init, .bar1.init = nv50_bar_bar1_init,
.bar1.fini = nv50_bar_bar1_fini,
.bar1.wait = nv50_bar_bar1_wait, .bar1.wait = nv50_bar_bar1_wait,
.kmap = nv50_bar_kmap, .kmap = nv50_bar_kmap,
.umap = nv50_bar_umap, .umap = nv50_bar_umap,

View File

@ -49,6 +49,12 @@ gf100_bar_bar1_wait(struct nvkm_bar *base)
nvkm_bar_flush(base); nvkm_bar_flush(base);
} }
void
gf100_bar_bar1_fini(struct nvkm_bar *bar)
{
nvkm_mask(bar->subdev.device, 0x001704, 0x80000000, 0x00000000);
}
void void
gf100_bar_bar1_init(struct nvkm_bar *base) gf100_bar_bar1_init(struct nvkm_bar *base)
{ {
@ -186,6 +192,7 @@ gf100_bar_func = {
.oneinit = gf100_bar_oneinit, .oneinit = gf100_bar_oneinit,
.init = gf100_bar_init, .init = gf100_bar_init,
.bar1.init = gf100_bar_bar1_init, .bar1.init = gf100_bar_bar1_init,
.bar1.fini = gf100_bar_bar1_fini,
.bar1.wait = gf100_bar_bar1_wait, .bar1.wait = gf100_bar_bar1_wait,
.kmap = gf100_bar_kmap, .kmap = gf100_bar_kmap,
.umap = gf100_bar_umap, .umap = gf100_bar_umap,

View File

@ -26,6 +26,7 @@ gk20a_bar_func = {
.dtor = gf100_bar_dtor, .dtor = gf100_bar_dtor,
.oneinit = gf100_bar_oneinit, .oneinit = gf100_bar_oneinit,
.bar1.init = gf100_bar_bar1_init, .bar1.init = gf100_bar_bar1_init,
.bar1.fini = gf100_bar_bar1_fini,
.bar1.wait = gf100_bar_bar1_wait, .bar1.wait = gf100_bar_bar1_wait,
.umap = gf100_bar_umap, .umap = gf100_bar_umap,
.flush = g84_bar_flush, .flush = g84_bar_flush,

View File

@ -62,6 +62,12 @@ nv50_bar_bar1_wait(struct nvkm_bar *base)
nvkm_bar_flush(base); nvkm_bar_flush(base);
} }
void
nv50_bar_bar1_fini(struct nvkm_bar *bar)
{
nvkm_wr32(bar->subdev.device, 0x001708, 0x00000000);
}
void void
nv50_bar_bar1_init(struct nvkm_bar *base) nv50_bar_bar1_init(struct nvkm_bar *base)
{ {
@ -208,6 +214,7 @@ nv50_bar_func = {
.oneinit = nv50_bar_oneinit, .oneinit = nv50_bar_oneinit,
.init = nv50_bar_init, .init = nv50_bar_init,
.bar1.init = nv50_bar_bar1_init, .bar1.init = nv50_bar_bar1_init,
.bar1.fini = nv50_bar_bar1_fini,
.bar1.wait = nv50_bar_bar1_wait, .bar1.wait = nv50_bar_bar1_wait,
.kmap = nv50_bar_kmap, .kmap = nv50_bar_kmap,
.umap = nv50_bar_umap, .umap = nv50_bar_umap,

View File

@ -13,6 +13,7 @@ struct nvkm_bar_func {
struct { struct {
void (*init)(struct nvkm_bar *); void (*init)(struct nvkm_bar *);
void (*fini)(struct nvkm_bar *);
void (*wait)(struct nvkm_bar *); void (*wait)(struct nvkm_bar *);
} bar1; } bar1;
@ -21,5 +22,9 @@ struct nvkm_bar_func {
void (*flush)(struct nvkm_bar *); void (*flush)(struct nvkm_bar *);
}; };
void nv50_bar_bar1_fini(struct nvkm_bar *);
void g84_bar_flush(struct nvkm_bar *); void g84_bar_flush(struct nvkm_bar *);
void gf100_bar_bar1_fini(struct nvkm_bar *);
#endif #endif