Commit 110cccff authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/core/object: support lookup of specific object types



It turns out we have a nice and convenient way of looking up a specific
object type already, by using the func pointer as a key.

This will be used to remove the separate object trees for each type we
need to be able to search for.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 05073cae
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -62,6 +62,11 @@ int nvkm_object_wr32(struct nvkm_object *, u64 addr, u32 data);
int nvkm_object_bind(struct nvkm_object *, struct nvkm_gpuobj *, int align,
		     struct nvkm_gpuobj **);

bool nvkm_object_insert(struct nvkm_object *);
void nvkm_object_remove(struct nvkm_object *);
struct nvkm_object *nvkm_object_search(struct nvkm_client *, u64 object,
				       const struct nvkm_object_func *);

struct nvkm_sclass {
	int minver;
	int maxver;
+60 −1
Original line number Diff line number Diff line
@@ -25,6 +25,65 @@
#include <core/client.h>
#include <core/engine.h>

struct nvkm_object *
nvkm_object_search(struct nvkm_client *client, u64 handle,
		   const struct nvkm_object_func *func)
{
	struct nvkm_object *object;

	if (handle) {
		struct rb_node *node = client->objroot.rb_node;
		while (node) {
			object = rb_entry(node, typeof(*object), node);
			if (handle < object->object)
				node = node->rb_left;
			else
			if (handle > object->object)
				node = node->rb_right;
			else
				goto done;
		}
		return ERR_PTR(-ENOENT);
	} else {
		object = &client->object;
	}

done:
	if (unlikely(func && object->func != func))
		return ERR_PTR(-EINVAL);
	return object;
}

void
nvkm_object_remove(struct nvkm_object *object)
{
	if (!RB_EMPTY_NODE(&object->node))
		rb_erase(&object->node, &object->client->objroot);
}

bool
nvkm_object_insert(struct nvkm_object *object)
{
	struct rb_node **ptr = &object->client->objroot.rb_node;
	struct rb_node *parent = NULL;

	while (*ptr) {
		struct nvkm_object *this = rb_entry(*ptr, typeof(*this), node);
		parent = *ptr;
		if (object->object < this->object)
			ptr = &parent->rb_left;
		else
		if (object->object > this->object)
			ptr = &parent->rb_right;
		else
			return false;
	}

	rb_link_node(&object->node, parent, ptr);
	rb_insert_color(&object->node, &object->client->objroot);
	return true;
}

int
nvkm_object_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
@@ -214,7 +273,7 @@ nvkm_object_del(struct nvkm_object **pobject)
	struct nvkm_object *object = *pobject;
	if (object && !WARN_ON(!object->func)) {
		*pobject = nvkm_object_dtor(object);
		nvkm_client_remove(object->client, object);
		nvkm_object_remove(object);
		list_del(&object->head);
		kfree(*pobject);
		*pobject = NULL;