summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2015-08-20 14:54:20 +1000
committerBen Skeggs <bskeggs@redhat.com>2015-08-28 12:40:44 +1000
commit8de65bd0901e2ee7a485a158bfe9e4631cc00644 (patch)
treeca9033713ff66a001a1697fa966cf86500094328
parent551d341755e2ade4a915d889524a4187f2cd210e (diff)
drm/nouveau/devinit: run devinit scripts right after preinit
This ensures we have a valid mask of disabled engines before we start trying to execute fini()/init() on the subdevs, potentially touching devices that don't exist. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/base.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c21
3 files changed, 15 insertions, 11 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h
index 9e053460a9c7..6c1407fd317b 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/devinit.h
@@ -13,6 +13,7 @@ u32 nvkm_devinit_mmio(struct nvkm_devinit *, u32 addr);
int nvkm_devinit_pll_set(struct nvkm_devinit *, u32 type, u32 khz);
void nvkm_devinit_meminit(struct nvkm_devinit *);
u64 nvkm_devinit_disable(struct nvkm_devinit *);
+int nvkm_devinit_post(struct nvkm_devinit *, u64 *disable);
int nv04_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
int nv05_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index 2d8ef80f32e7..99a07694a298 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -2167,7 +2167,9 @@ nvkm_device_preinit(struct nvkm_device *device)
}
}
- /*XXX: devinit */
+ ret = nvkm_devinit_post(device->devinit, &device->disable_mask);
+ if (ret)
+ goto fail;
time = ktime_to_us(ktime_get()) - time;
nvdev_trace(device, "preinit completed in %lldus\n", time);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
index 47823f5a2cdf..5f25402f6b09 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
@@ -50,11 +50,21 @@ nvkm_devinit_meminit(struct nvkm_devinit *init)
u64
nvkm_devinit_disable(struct nvkm_devinit *init)
{
- if (init->func->disable)
+ if (init && init->func->disable)
return init->func->disable(init);
return 0;
}
+int
+nvkm_devinit_post(struct nvkm_devinit *init, u64 *disable)
+{
+ int ret = 0;
+ if (init && init->func->post)
+ ret = init->func->post(init, init->post);
+ *disable = nvkm_devinit_disable(init);
+ return ret;
+}
+
static int
nvkm_devinit_fini(struct nvkm_subdev *subdev, bool suspend)
{
@@ -82,17 +92,8 @@ static int
nvkm_devinit_init(struct nvkm_subdev *subdev)
{
struct nvkm_devinit *init = nvkm_devinit(subdev);
- int ret;
-
- ret = init->func->post(init, init->post);
- if (ret)
- return ret;
-
if (init->func->init)
init->func->init(init);
-
- if (init->func->disable)
- subdev->device->disable_mask |= init->func->disable(init);
return 0;
}