xref: /linux/drivers/gpu/drm/nouveau/nvkm/core/object.c (revision b7cc4ff7)
1c39f472eSBen Skeggs /*
2c39f472eSBen Skeggs  * Copyright 2012 Red Hat Inc.
3c39f472eSBen Skeggs  *
4c39f472eSBen Skeggs  * Permission is hereby granted, free of charge, to any person obtaining a
5c39f472eSBen Skeggs  * copy of this software and associated documentation files (the "Software"),
6c39f472eSBen Skeggs  * to deal in the Software without restriction, including without limitation
7c39f472eSBen Skeggs  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8c39f472eSBen Skeggs  * and/or sell copies of the Software, and to permit persons to whom the
9c39f472eSBen Skeggs  * Software is furnished to do so, subject to the following conditions:
10c39f472eSBen Skeggs  *
11c39f472eSBen Skeggs  * The above copyright notice and this permission notice shall be included in
12c39f472eSBen Skeggs  * all copies or substantial portions of the Software.
13c39f472eSBen Skeggs  *
14c39f472eSBen Skeggs  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15c39f472eSBen Skeggs  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16c39f472eSBen Skeggs  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17c39f472eSBen Skeggs  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18c39f472eSBen Skeggs  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19c39f472eSBen Skeggs  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20c39f472eSBen Skeggs  * OTHER DEALINGS IN THE SOFTWARE.
21c39f472eSBen Skeggs  *
22c39f472eSBen Skeggs  * Authors: Ben Skeggs
23c39f472eSBen Skeggs  */
24c39f472eSBen Skeggs #include <core/object.h>
25fbd58ebdSBen Skeggs #include <core/client.h>
26c39f472eSBen Skeggs #include <core/engine.h>
27c39f472eSBen Skeggs 
28110cccffSBen Skeggs struct nvkm_object *
nvkm_object_search(struct nvkm_client * client,u64 handle,const struct nvkm_object_func * func)29110cccffSBen Skeggs nvkm_object_search(struct nvkm_client *client, u64 handle,
30110cccffSBen Skeggs 		   const struct nvkm_object_func *func)
31110cccffSBen Skeggs {
32110cccffSBen Skeggs 	struct nvkm_object *object;
33*b7cc4ff7SDave Airlie 	unsigned long flags;
34110cccffSBen Skeggs 
35110cccffSBen Skeggs 	if (handle) {
36*b7cc4ff7SDave Airlie 		spin_lock_irqsave(&client->obj_lock, flags);
37110cccffSBen Skeggs 		struct rb_node *node = client->objroot.rb_node;
38110cccffSBen Skeggs 		while (node) {
39110cccffSBen Skeggs 			object = rb_entry(node, typeof(*object), node);
40110cccffSBen Skeggs 			if (handle < object->object)
41110cccffSBen Skeggs 				node = node->rb_left;
42110cccffSBen Skeggs 			else
43110cccffSBen Skeggs 			if (handle > object->object)
44110cccffSBen Skeggs 				node = node->rb_right;
45*b7cc4ff7SDave Airlie 			else {
46*b7cc4ff7SDave Airlie 				spin_unlock_irqrestore(&client->obj_lock, flags);
47110cccffSBen Skeggs 				goto done;
48110cccffSBen Skeggs 			}
49*b7cc4ff7SDave Airlie 		}
50*b7cc4ff7SDave Airlie 		spin_unlock_irqrestore(&client->obj_lock, flags);
51110cccffSBen Skeggs 		return ERR_PTR(-ENOENT);
52110cccffSBen Skeggs 	} else {
53110cccffSBen Skeggs 		object = &client->object;
54110cccffSBen Skeggs 	}
55110cccffSBen Skeggs 
56110cccffSBen Skeggs done:
57110cccffSBen Skeggs 	if (unlikely(func && object->func != func))
58110cccffSBen Skeggs 		return ERR_PTR(-EINVAL);
59110cccffSBen Skeggs 	return object;
60110cccffSBen Skeggs }
61110cccffSBen Skeggs 
62110cccffSBen Skeggs void
nvkm_object_remove(struct nvkm_object * object)63110cccffSBen Skeggs nvkm_object_remove(struct nvkm_object *object)
64110cccffSBen Skeggs {
65*b7cc4ff7SDave Airlie 	unsigned long flags;
66*b7cc4ff7SDave Airlie 
67*b7cc4ff7SDave Airlie 	spin_lock_irqsave(&object->client->obj_lock, flags);
68110cccffSBen Skeggs 	if (!RB_EMPTY_NODE(&object->node))
69110cccffSBen Skeggs 		rb_erase(&object->node, &object->client->objroot);
70*b7cc4ff7SDave Airlie 	spin_unlock_irqrestore(&object->client->obj_lock, flags);
71110cccffSBen Skeggs }
72110cccffSBen Skeggs 
73110cccffSBen Skeggs bool
nvkm_object_insert(struct nvkm_object * object)74110cccffSBen Skeggs nvkm_object_insert(struct nvkm_object *object)
75110cccffSBen Skeggs {
76*b7cc4ff7SDave Airlie 	struct rb_node **ptr;
77110cccffSBen Skeggs 	struct rb_node *parent = NULL;
78*b7cc4ff7SDave Airlie 	unsigned long flags;
79110cccffSBen Skeggs 
80*b7cc4ff7SDave Airlie 	spin_lock_irqsave(&object->client->obj_lock, flags);
81*b7cc4ff7SDave Airlie 	ptr = &object->client->objroot.rb_node;
82110cccffSBen Skeggs 	while (*ptr) {
83110cccffSBen Skeggs 		struct nvkm_object *this = rb_entry(*ptr, typeof(*this), node);
84110cccffSBen Skeggs 		parent = *ptr;
85*b7cc4ff7SDave Airlie 		if (object->object < this->object) {
86110cccffSBen Skeggs 			ptr = &parent->rb_left;
87*b7cc4ff7SDave Airlie 		} else if (object->object > this->object) {
88110cccffSBen Skeggs 			ptr = &parent->rb_right;
89*b7cc4ff7SDave Airlie 		} else {
90*b7cc4ff7SDave Airlie 			spin_unlock_irqrestore(&object->client->obj_lock, flags);
91110cccffSBen Skeggs 			return false;
92110cccffSBen Skeggs 		}
93*b7cc4ff7SDave Airlie 	}
94110cccffSBen Skeggs 
95110cccffSBen Skeggs 	rb_link_node(&object->node, parent, ptr);
96110cccffSBen Skeggs 	rb_insert_color(&object->node, &object->client->objroot);
97*b7cc4ff7SDave Airlie 	spin_unlock_irqrestore(&object->client->obj_lock, flags);
98110cccffSBen Skeggs 	return true;
99110cccffSBen Skeggs }
100110cccffSBen Skeggs 
101c39f472eSBen Skeggs int
nvkm_object_mthd(struct nvkm_object * object,u32 mthd,void * data,u32 size)102cbea21e2SBen Skeggs nvkm_object_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
103cbea21e2SBen Skeggs {
104cbea21e2SBen Skeggs 	if (likely(object->func->mthd))
105cbea21e2SBen Skeggs 		return object->func->mthd(object, mthd, data, size);
106cbea21e2SBen Skeggs 	return -ENODEV;
107cbea21e2SBen Skeggs }
108cbea21e2SBen Skeggs 
109cbea21e2SBen Skeggs int
nvkm_object_ntfy(struct nvkm_object * object,u32 mthd,struct nvkm_event ** pevent)110cbea21e2SBen Skeggs nvkm_object_ntfy(struct nvkm_object *object, u32 mthd,
111cbea21e2SBen Skeggs 		 struct nvkm_event **pevent)
112cbea21e2SBen Skeggs {
113cbea21e2SBen Skeggs 	if (likely(object->func->ntfy))
114cbea21e2SBen Skeggs 		return object->func->ntfy(object, mthd, pevent);
115cbea21e2SBen Skeggs 	return -ENODEV;
116cbea21e2SBen Skeggs }
117cbea21e2SBen Skeggs 
118cbea21e2SBen Skeggs int
nvkm_object_map(struct nvkm_object * object,void * argv,u32 argc,enum nvkm_object_map * type,u64 * addr,u64 * size)11901326050SBen Skeggs nvkm_object_map(struct nvkm_object *object, void *argv, u32 argc,
12001326050SBen Skeggs 		enum nvkm_object_map *type, u64 *addr, u64 *size)
121cbea21e2SBen Skeggs {
122cbea21e2SBen Skeggs 	if (likely(object->func->map))
12301326050SBen Skeggs 		return object->func->map(object, argv, argc, type, addr, size);
124cbea21e2SBen Skeggs 	return -ENODEV;
125cbea21e2SBen Skeggs }
126cbea21e2SBen Skeggs 
127cbea21e2SBen Skeggs int
nvkm_object_unmap(struct nvkm_object * object)1288e0042d5SBen Skeggs nvkm_object_unmap(struct nvkm_object *object)
1298e0042d5SBen Skeggs {
1308e0042d5SBen Skeggs 	if (likely(object->func->unmap))
1318e0042d5SBen Skeggs 		return object->func->unmap(object);
1328e0042d5SBen Skeggs 	return -ENODEV;
1338e0042d5SBen Skeggs }
1348e0042d5SBen Skeggs 
1358e0042d5SBen Skeggs int
nvkm_object_rd08(struct nvkm_object * object,u64 addr,u8 * data)136cfdc4c44SBen Skeggs nvkm_object_rd08(struct nvkm_object *object, u64 addr, u8 *data)
137cfdc4c44SBen Skeggs {
138cbea21e2SBen Skeggs 	if (likely(object->func->rd08))
139cbea21e2SBen Skeggs 		return object->func->rd08(object, addr, data);
140cbea21e2SBen Skeggs 	return -ENODEV;
141cbea21e2SBen Skeggs }
142cfdc4c44SBen Skeggs 
143cfdc4c44SBen Skeggs int
nvkm_object_rd16(struct nvkm_object * object,u64 addr,u16 * data)144cfdc4c44SBen Skeggs nvkm_object_rd16(struct nvkm_object *object, u64 addr, u16 *data)
145cfdc4c44SBen Skeggs {
146cbea21e2SBen Skeggs 	if (likely(object->func->rd16))
147cbea21e2SBen Skeggs 		return object->func->rd16(object, addr, data);
148cbea21e2SBen Skeggs 	return -ENODEV;
149cbea21e2SBen Skeggs }
150cfdc4c44SBen Skeggs 
151cfdc4c44SBen Skeggs int
nvkm_object_rd32(struct nvkm_object * object,u64 addr,u32 * data)152cfdc4c44SBen Skeggs nvkm_object_rd32(struct nvkm_object *object, u64 addr, u32 *data)
153cfdc4c44SBen Skeggs {
154cbea21e2SBen Skeggs 	if (likely(object->func->rd32))
155cbea21e2SBen Skeggs 		return object->func->rd32(object, addr, data);
156cfdc4c44SBen Skeggs 	return -ENODEV;
157cfdc4c44SBen Skeggs }
158cfdc4c44SBen Skeggs 
159cfdc4c44SBen Skeggs int
nvkm_object_wr08(struct nvkm_object * object,u64 addr,u8 data)160cfdc4c44SBen Skeggs nvkm_object_wr08(struct nvkm_object *object, u64 addr, u8 data)
161cfdc4c44SBen Skeggs {
162cbea21e2SBen Skeggs 	if (likely(object->func->wr08))
163cbea21e2SBen Skeggs 		return object->func->wr08(object, addr, data);
164cbea21e2SBen Skeggs 	return -ENODEV;
165cbea21e2SBen Skeggs }
166cfdc4c44SBen Skeggs 
167cfdc4c44SBen Skeggs int
nvkm_object_wr16(struct nvkm_object * object,u64 addr,u16 data)168cfdc4c44SBen Skeggs nvkm_object_wr16(struct nvkm_object *object, u64 addr, u16 data)
169cfdc4c44SBen Skeggs {
170cbea21e2SBen Skeggs 	if (likely(object->func->wr16))
171cbea21e2SBen Skeggs 		return object->func->wr16(object, addr, data);
172cbea21e2SBen Skeggs 	return -ENODEV;
173cbea21e2SBen Skeggs }
174cfdc4c44SBen Skeggs 
175cfdc4c44SBen Skeggs int
nvkm_object_wr32(struct nvkm_object * object,u64 addr,u32 data)176cfdc4c44SBen Skeggs nvkm_object_wr32(struct nvkm_object *object, u64 addr, u32 data)
177cfdc4c44SBen Skeggs {
178cbea21e2SBen Skeggs 	if (likely(object->func->wr32))
179cbea21e2SBen Skeggs 		return object->func->wr32(object, addr, data);
180cbea21e2SBen Skeggs 	return -ENODEV;
181cbea21e2SBen Skeggs }
182cbea21e2SBen Skeggs 
183cbea21e2SBen Skeggs int
nvkm_object_bind(struct nvkm_object * object,struct nvkm_gpuobj * gpuobj,int align,struct nvkm_gpuobj ** pgpuobj)184cbea21e2SBen Skeggs nvkm_object_bind(struct nvkm_object *object, struct nvkm_gpuobj *gpuobj,
185cbea21e2SBen Skeggs 		 int align, struct nvkm_gpuobj **pgpuobj)
186cbea21e2SBen Skeggs {
187cbea21e2SBen Skeggs 	if (object->func->bind)
188cbea21e2SBen Skeggs 		return object->func->bind(object, gpuobj, align, pgpuobj);
189cbea21e2SBen Skeggs 	return -ENODEV;
190cbea21e2SBen Skeggs }
191cbea21e2SBen Skeggs 
192cbea21e2SBen Skeggs int
nvkm_object_fini(struct nvkm_object * object,bool suspend)193cbea21e2SBen Skeggs nvkm_object_fini(struct nvkm_object *object, bool suspend)
194cbea21e2SBen Skeggs {
195fbd58ebdSBen Skeggs 	const char *action = suspend ? "suspend" : "fini";
196fbd58ebdSBen Skeggs 	struct nvkm_object *child;
197fbd58ebdSBen Skeggs 	s64 time;
198fbd58ebdSBen Skeggs 	int ret;
199fbd58ebdSBen Skeggs 
200fbd58ebdSBen Skeggs 	nvif_debug(object, "%s children...\n", action);
201fbd58ebdSBen Skeggs 	time = ktime_to_us(ktime_get());
20283775e15SBen Skeggs 	list_for_each_entry_reverse(child, &object->tree, head) {
203fbd58ebdSBen Skeggs 		ret = nvkm_object_fini(child, suspend);
204fbd58ebdSBen Skeggs 		if (ret && suspend)
205fbd58ebdSBen Skeggs 			goto fail_child;
206fbd58ebdSBen Skeggs 	}
207fbd58ebdSBen Skeggs 
208fbd58ebdSBen Skeggs 	nvif_debug(object, "%s running...\n", action);
209fbd58ebdSBen Skeggs 	if (object->func->fini) {
210fbd58ebdSBen Skeggs 		ret = object->func->fini(object, suspend);
211fbd58ebdSBen Skeggs 		if (ret) {
212fbd58ebdSBen Skeggs 			nvif_error(object, "%s failed with %d\n", action, ret);
213fbd58ebdSBen Skeggs 			if (suspend)
214fbd58ebdSBen Skeggs 				goto fail;
215fbd58ebdSBen Skeggs 		}
216fbd58ebdSBen Skeggs 	}
217fbd58ebdSBen Skeggs 
218fbd58ebdSBen Skeggs 	time = ktime_to_us(ktime_get()) - time;
219fbd58ebdSBen Skeggs 	nvif_debug(object, "%s completed in %lldus\n", action, time);
220cbea21e2SBen Skeggs 	return 0;
221fbd58ebdSBen Skeggs 
222fbd58ebdSBen Skeggs fail:
223fbd58ebdSBen Skeggs 	if (object->func->init) {
224fbd58ebdSBen Skeggs 		int rret = object->func->init(object);
225fbd58ebdSBen Skeggs 		if (rret)
226fbd58ebdSBen Skeggs 			nvif_fatal(object, "failed to restart, %d\n", rret);
227fbd58ebdSBen Skeggs 	}
228fbd58ebdSBen Skeggs fail_child:
229fbd58ebdSBen Skeggs 	list_for_each_entry_continue_reverse(child, &object->tree, head) {
230fbd58ebdSBen Skeggs 		nvkm_object_init(child);
231fbd58ebdSBen Skeggs 	}
232fbd58ebdSBen Skeggs 	return ret;
233cbea21e2SBen Skeggs }
234cbea21e2SBen Skeggs 
235cbea21e2SBen Skeggs int
nvkm_object_init(struct nvkm_object * object)236cbea21e2SBen Skeggs nvkm_object_init(struct nvkm_object *object)
237cbea21e2SBen Skeggs {
238fbd58ebdSBen Skeggs 	struct nvkm_object *child;
239fbd58ebdSBen Skeggs 	s64 time;
240fbd58ebdSBen Skeggs 	int ret;
241fbd58ebdSBen Skeggs 
242fbd58ebdSBen Skeggs 	nvif_debug(object, "init running...\n");
243fbd58ebdSBen Skeggs 	time = ktime_to_us(ktime_get());
244fbd58ebdSBen Skeggs 	if (object->func->init) {
245fbd58ebdSBen Skeggs 		ret = object->func->init(object);
246fbd58ebdSBen Skeggs 		if (ret)
247fbd58ebdSBen Skeggs 			goto fail;
248cbea21e2SBen Skeggs 	}
249cbea21e2SBen Skeggs 
250fbd58ebdSBen Skeggs 	nvif_debug(object, "init children...\n");
251fbd58ebdSBen Skeggs 	list_for_each_entry(child, &object->tree, head) {
252fbd58ebdSBen Skeggs 		ret = nvkm_object_init(child);
253fbd58ebdSBen Skeggs 		if (ret)
254fbd58ebdSBen Skeggs 			goto fail_child;
255fbd58ebdSBen Skeggs 	}
256fbd58ebdSBen Skeggs 
257fbd58ebdSBen Skeggs 	time = ktime_to_us(ktime_get()) - time;
258fbd58ebdSBen Skeggs 	nvif_debug(object, "init completed in %lldus\n", time);
259fbd58ebdSBen Skeggs 	return 0;
260fbd58ebdSBen Skeggs 
261fbd58ebdSBen Skeggs fail_child:
262fbd58ebdSBen Skeggs 	list_for_each_entry_continue_reverse(child, &object->tree, head)
263fbd58ebdSBen Skeggs 		nvkm_object_fini(child, false);
264fbd58ebdSBen Skeggs fail:
265fbd58ebdSBen Skeggs 	nvif_error(object, "init failed with %d\n", ret);
266fbd58ebdSBen Skeggs 	if (object->func->fini)
267fbd58ebdSBen Skeggs 		object->func->fini(object, false);
268fbd58ebdSBen Skeggs 	return ret;
269fbd58ebdSBen Skeggs }
270fbd58ebdSBen Skeggs 
271fbd58ebdSBen Skeggs void *
nvkm_object_dtor(struct nvkm_object * object)272fbd58ebdSBen Skeggs nvkm_object_dtor(struct nvkm_object *object)
273fbd58ebdSBen Skeggs {
274fbd58ebdSBen Skeggs 	struct nvkm_object *child, *ctemp;
275fbd58ebdSBen Skeggs 	void *data = object;
276fbd58ebdSBen Skeggs 	s64 time;
277fbd58ebdSBen Skeggs 
278fbd58ebdSBen Skeggs 	nvif_debug(object, "destroy children...\n");
279fbd58ebdSBen Skeggs 	time = ktime_to_us(ktime_get());
280fbd58ebdSBen Skeggs 	list_for_each_entry_safe(child, ctemp, &object->tree, head) {
281fbd58ebdSBen Skeggs 		nvkm_object_del(&child);
282fbd58ebdSBen Skeggs 	}
283fbd58ebdSBen Skeggs 
284fbd58ebdSBen Skeggs 	nvif_debug(object, "destroy running...\n");
2858e0042d5SBen Skeggs 	nvkm_object_unmap(object);
286fbd58ebdSBen Skeggs 	if (object->func->dtor)
287fbd58ebdSBen Skeggs 		data = object->func->dtor(object);
288fbd58ebdSBen Skeggs 	nvkm_engine_unref(&object->engine);
289fbd58ebdSBen Skeggs 	time = ktime_to_us(ktime_get()) - time;
290fbd58ebdSBen Skeggs 	nvif_debug(object, "destroy completed in %lldus...\n", time);
291fbd58ebdSBen Skeggs 	return data;
292fbd58ebdSBen Skeggs }
293fbd58ebdSBen Skeggs 
294fbd58ebdSBen Skeggs void
nvkm_object_del(struct nvkm_object ** pobject)295cbea21e2SBen Skeggs nvkm_object_del(struct nvkm_object **pobject)
296cbea21e2SBen Skeggs {
297cbea21e2SBen Skeggs 	struct nvkm_object *object = *pobject;
298cbea21e2SBen Skeggs 	if (object && !WARN_ON(!object->func)) {
299fbd58ebdSBen Skeggs 		*pobject = nvkm_object_dtor(object);
300110cccffSBen Skeggs 		nvkm_object_remove(object);
301fbd58ebdSBen Skeggs 		list_del(&object->head);
302cbea21e2SBen Skeggs 		kfree(*pobject);
303cbea21e2SBen Skeggs 		*pobject = NULL;
304cbea21e2SBen Skeggs 	}
305cbea21e2SBen Skeggs }
306cbea21e2SBen Skeggs 
307cbea21e2SBen Skeggs void
nvkm_object_ctor(const struct nvkm_object_func * func,const struct nvkm_oclass * oclass,struct nvkm_object * object)308cbea21e2SBen Skeggs nvkm_object_ctor(const struct nvkm_object_func *func,
309cbea21e2SBen Skeggs 		 const struct nvkm_oclass *oclass, struct nvkm_object *object)
310cbea21e2SBen Skeggs {
311cbea21e2SBen Skeggs 	object->func = func;
312cbea21e2SBen Skeggs 	object->client = oclass->client;
3136cf813fbSBen Skeggs 	object->engine = nvkm_engine_ref(oclass->engine);
31468f3f702SBen Skeggs 	object->oclass = oclass->base.oclass;
315cbea21e2SBen Skeggs 	object->handle = oclass->handle;
316843faa03SBen Skeggs 	object->route  = oclass->route;
317843faa03SBen Skeggs 	object->token  = oclass->token;
318843faa03SBen Skeggs 	object->object = oclass->object;
319fbd58ebdSBen Skeggs 	INIT_LIST_HEAD(&object->head);
320fbd58ebdSBen Skeggs 	INIT_LIST_HEAD(&object->tree);
321fbd58ebdSBen Skeggs 	RB_CLEAR_NODE(&object->node);
32289ed10a5SBen Skeggs 	WARN_ON(IS_ERR(object->engine));
323cbea21e2SBen Skeggs }
324cbea21e2SBen Skeggs 
325cbea21e2SBen Skeggs int
nvkm_object_new_(const struct nvkm_object_func * func,const struct nvkm_oclass * oclass,void * data,u32 size,struct nvkm_object ** pobject)326cbea21e2SBen Skeggs nvkm_object_new_(const struct nvkm_object_func *func,
327cbea21e2SBen Skeggs 		 const struct nvkm_oclass *oclass, void *data, u32 size,
328cbea21e2SBen Skeggs 		 struct nvkm_object **pobject)
329cbea21e2SBen Skeggs {
330cbea21e2SBen Skeggs 	if (size == 0) {
331cbea21e2SBen Skeggs 		if (!(*pobject = kzalloc(sizeof(**pobject), GFP_KERNEL)))
332cbea21e2SBen Skeggs 			return -ENOMEM;
333cbea21e2SBen Skeggs 		nvkm_object_ctor(func, oclass, *pobject);
334cbea21e2SBen Skeggs 		return 0;
335cbea21e2SBen Skeggs 	}
336cbea21e2SBen Skeggs 	return -ENOSYS;
337cbea21e2SBen Skeggs }
338cbea21e2SBen Skeggs 
339cbea21e2SBen Skeggs static const struct nvkm_object_func
340cbea21e2SBen Skeggs nvkm_object_func = {
341cbea21e2SBen Skeggs };
342cbea21e2SBen Skeggs 
343cbea21e2SBen Skeggs int
nvkm_object_new(const struct nvkm_oclass * oclass,void * data,u32 size,struct nvkm_object ** pobject)344cbea21e2SBen Skeggs nvkm_object_new(const struct nvkm_oclass *oclass, void *data, u32 size,
345cbea21e2SBen Skeggs 		struct nvkm_object **pobject)
346cbea21e2SBen Skeggs {
347cbea21e2SBen Skeggs 	const struct nvkm_object_func *func =
348cbea21e2SBen Skeggs 		oclass->base.func ? oclass->base.func : &nvkm_object_func;
349cbea21e2SBen Skeggs 	return nvkm_object_new_(func, oclass, data, size, pobject);
350cbea21e2SBen Skeggs }
351