summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-12-05 11:26:23 +1000
committerBen Skeggs <bskeggs@redhat.com>2015-01-22 12:14:48 +1000
commit490d595f321d16f34040836c494d7875eb8f66a4 (patch)
tree73b1ed8cf6daf2b7813d385b6726a3ddbf36abec /drivers/gpu
parenta38f37a7e06b7ea1bca966805e7a0d03191731f4 (diff)
downloadlinux-490d595f321d16f34040836c494d7875eb8f66a4.tar.gz
drm/nouveau/core: fix subdev/engine/device lookup to not require engine pointer
It's about to not be valid for objects that aren't in the client object tree. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/core/core/engine.c8
-rw-r--r--drivers/gpu/drm/nouveau/core/core/subdev.c11
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/base.c22
3 files changed, 20 insertions, 21 deletions
diff --git a/drivers/gpu/drm/nouveau/core/core/engine.c b/drivers/gpu/drm/nouveau/core/core/engine.c
index 4835056b0689..85bf4b3d1fe4 100644
--- a/drivers/gpu/drm/nouveau/core/core/engine.c
+++ b/drivers/gpu/drm/nouveau/core/core/engine.c
@@ -27,11 +27,11 @@
#include <core/option.h>
struct nouveau_engine *
-nouveau_engine(void *obj, int sub)
+nouveau_engine(void *obj, int idx)
{
- struct nouveau_subdev *subdev = nouveau_subdev(obj, sub);
- if (subdev && nv_iclass(subdev, NV_ENGINE_CLASS))
- return nv_engine(subdev);
+ obj = nouveau_subdev(obj, idx);
+ if (obj && nv_iclass(obj, NV_ENGINE_CLASS))
+ return nv_engine(obj);
return NULL;
}
diff --git a/drivers/gpu/drm/nouveau/core/core/subdev.c b/drivers/gpu/drm/nouveau/core/core/subdev.c
index edae535406e5..69ba1482c3f5 100644
--- a/drivers/gpu/drm/nouveau/core/core/subdev.c
+++ b/drivers/gpu/drm/nouveau/core/core/subdev.c
@@ -28,11 +28,14 @@
#include <core/option.h>
struct nouveau_subdev *
-nouveau_subdev(void *obj, int sub)
+nouveau_subdev(void *obj, int idx)
{
- if (nv_device(obj)->subdev[sub])
- return nv_subdev(nv_device(obj)->subdev[sub]);
- return NULL;
+ struct nouveau_object *object = nv_object(obj);
+ while (object && !nv_iclass(object, NV_SUBDEV_CLASS))
+ object = object->parent;
+ if (object == NULL || nv_subidx(object) != idx)
+ object = nv_device(obj)->subdev[idx];
+ return object ? nv_subdev(object) : NULL;
}
void
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c
index e2da1d4029cd..7c0cbcde7b2f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c
@@ -511,22 +511,18 @@ nouveau_devobj_ofuncs = {
struct nouveau_device *
nv_device(void *obj)
{
- struct nouveau_object *object = nv_object(obj);
- struct nouveau_object *device = object;
-
- if (device->engine)
- device = device->engine;
- if (device->parent)
+ struct nouveau_object *device = nv_object(obj);
+ while (device && device->parent)
device = device->parent;
-
-#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
- if (unlikely(!nv_iclass(device, NV_SUBDEV_CLASS) ||
- (nv_hclass(device) & 0xff) != NVDEV_ENGINE_DEVICE)) {
- nv_assert("BAD CAST -> NvDevice, 0x%08x 0x%08x",
- nv_hclass(object), nv_hclass(device));
+ if (!nv_iclass(device, NV_ENGINE_CLASS)) {
+ device = nv_object(obj)->engine;
+ if (device && device->parent)
+ device = device->parent;
}
+#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
+ if (unlikely(!device))
+ nv_assert("BAD CAST -> NvDevice, 0x%08x\n", nv_hclass(obj));
#endif
-
return (void *)device;
}