diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2015-08-20 00:54:22 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-27 22:40:47 -0400 |
commit | fbd58ebda9c8572ca6285b88e3348c7712f125ec (patch) | |
tree | 1c72cee029d928003eadb62cbee945dee2c5298e | |
parent | 68f3f702b6a430a8d1e909455a60d26c0f2da530 (diff) |
drm/nouveau/object: merge with handle
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
18 files changed, 219 insertions, 442 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h index 5485bbac5677..eaf5905a87a3 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h | |||
@@ -12,8 +12,6 @@ struct nvkm_client { | |||
12 | struct rb_root objroot; | 12 | struct rb_root objroot; |
13 | struct rb_root dmaroot; | 13 | struct rb_root dmaroot; |
14 | 14 | ||
15 | struct nvkm_handle *root; | ||
16 | |||
17 | bool super; | 15 | bool super; |
18 | void *data; | 16 | void *data; |
19 | int (*ntfy)(const void *, u32, const void *, u32); | 17 | int (*ntfy)(const void *, u32, const void *, u32); |
@@ -21,9 +19,9 @@ struct nvkm_client { | |||
21 | struct nvkm_vm *vm; | 19 | struct nvkm_vm *vm; |
22 | }; | 20 | }; |
23 | 21 | ||
24 | bool nvkm_client_insert(struct nvkm_client *, struct nvkm_handle *); | 22 | bool nvkm_client_insert(struct nvkm_client *, struct nvkm_object *); |
25 | void nvkm_client_remove(struct nvkm_client *, struct nvkm_handle *); | 23 | void nvkm_client_remove(struct nvkm_client *, struct nvkm_object *); |
26 | struct nvkm_handle *nvkm_client_search(struct nvkm_client *, u64 handle); | 24 | struct nvkm_object *nvkm_client_search(struct nvkm_client *, u64 object); |
27 | 25 | ||
28 | int nvkm_client_new(const char *name, u64 device, const char *cfg, | 26 | int nvkm_client_new(const char *name, u64 device, const char *cfg, |
29 | const char *dbg, struct nvkm_client **); | 27 | const char *dbg, struct nvkm_client **); |
@@ -31,14 +29,6 @@ void nvkm_client_del(struct nvkm_client **); | |||
31 | int nvkm_client_init(struct nvkm_client *); | 29 | int nvkm_client_init(struct nvkm_client *); |
32 | int nvkm_client_fini(struct nvkm_client *, bool suspend); | 30 | int nvkm_client_fini(struct nvkm_client *, bool suspend); |
33 | 31 | ||
34 | static inline struct nvkm_client * | ||
35 | nvkm_client(struct nvkm_object *object) | ||
36 | { | ||
37 | while (object && object->parent) | ||
38 | object = object->parent; | ||
39 | return container_of(object, struct nvkm_client, object); | ||
40 | } | ||
41 | |||
42 | int nvkm_client_notify_new(struct nvkm_object *, struct nvkm_event *, | 32 | int nvkm_client_notify_new(struct nvkm_object *, struct nvkm_event *, |
43 | void *data, u32 size); | 33 | void *data, u32 size); |
44 | int nvkm_client_notify_del(struct nvkm_client *, int index); | 34 | int nvkm_client_notify_del(struct nvkm_client *, int index); |
@@ -48,12 +38,15 @@ int nvkm_client_notify_put(struct nvkm_client *, int index); | |||
48 | /* logging for client-facing objects */ | 38 | /* logging for client-facing objects */ |
49 | #define nvif_printk(o,l,p,f,a...) do { \ | 39 | #define nvif_printk(o,l,p,f,a...) do { \ |
50 | struct nvkm_object *_object = (o); \ | 40 | struct nvkm_object *_object = (o); \ |
51 | struct nvkm_client *_client = nvkm_client(_object); \ | 41 | struct nvkm_client *_client = _object->client; \ |
52 | if (_client->debug >= NV_DBG_##l) \ | 42 | if (_client->debug >= NV_DBG_##l) \ |
53 | printk(KERN_##p "nouveau: %s: "f, _client->name, ##a); \ | 43 | printk(KERN_##p "nouveau: %s:%08x:%08x: "f, _client->name, \ |
44 | _object->handle, _object->oclass, ##a); \ | ||
54 | } while(0) | 45 | } while(0) |
46 | #define nvif_fatal(o,f,a...) nvif_printk((o), FATAL, CRIT, f, ##a) | ||
55 | #define nvif_error(o,f,a...) nvif_printk((o), ERROR, ERR, f, ##a) | 47 | #define nvif_error(o,f,a...) nvif_printk((o), ERROR, ERR, f, ##a) |
56 | #define nvif_debug(o,f,a...) nvif_printk((o), DEBUG, INFO, f, ##a) | 48 | #define nvif_debug(o,f,a...) nvif_printk((o), DEBUG, INFO, f, ##a) |
57 | #define nvif_trace(o,f,a...) nvif_printk((o), TRACE, INFO, f, ##a) | 49 | #define nvif_trace(o,f,a...) nvif_printk((o), TRACE, INFO, f, ##a) |
50 | #define nvif_info(o,f,a...) nvif_printk((o), INFO, INFO, f, ##a) | ||
58 | #define nvif_ioctl(o,f,a...) nvif_trace((o), "ioctl: "f, ##a) | 51 | #define nvif_ioctl(o,f,a...) nvif_trace((o), "ioctl: "f, ##a) |
59 | #endif | 52 | #endif |
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h b/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h deleted file mode 100644 index 539278916d23..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/handle.h +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | #ifndef __NVKM_HANDLE_H__ | ||
2 | #define __NVKM_HANDLE_H__ | ||
3 | #include <core/os.h> | ||
4 | struct nvkm_object; | ||
5 | |||
6 | struct nvkm_handle { | ||
7 | struct list_head node; | ||
8 | |||
9 | struct list_head head; | ||
10 | struct list_head tree; | ||
11 | u32 name; | ||
12 | u32 priv; | ||
13 | |||
14 | u8 route; | ||
15 | u64 token; | ||
16 | |||
17 | struct nvkm_handle *parent; | ||
18 | struct nvkm_object *object; | ||
19 | |||
20 | struct rb_node rb; | ||
21 | u64 handle; | ||
22 | }; | ||
23 | |||
24 | int nvkm_handle_create(struct nvkm_handle *, u32 handle, | ||
25 | struct nvkm_object *, struct nvkm_handle **); | ||
26 | void nvkm_handle_destroy(struct nvkm_handle *); | ||
27 | int nvkm_handle_init(struct nvkm_handle *); | ||
28 | int nvkm_handle_fini(struct nvkm_handle *, bool suspend); | ||
29 | |||
30 | struct nvkm_handle *nvkm_handle_get_class(struct nvkm_object *, u16); | ||
31 | struct nvkm_handle *nvkm_handle_get_vinst(struct nvkm_object *, u64); | ||
32 | struct nvkm_handle *nvkm_handle_get_cinst(struct nvkm_object *, u32); | ||
33 | void nvkm_handle_put(struct nvkm_handle *); | ||
34 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h index b4b822f6155c..dcd048b91fac 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h | |||
@@ -10,12 +10,15 @@ struct nvkm_object { | |||
10 | const struct nvkm_object_func *func; | 10 | const struct nvkm_object_func *func; |
11 | struct nvkm_client *client; | 11 | struct nvkm_client *client; |
12 | struct nvkm_engine *engine; | 12 | struct nvkm_engine *engine; |
13 | u32 oclass; | 13 | s32 oclass; |
14 | u32 handle; | 14 | u32 handle; |
15 | struct nvkm_object *parent; | 15 | |
16 | u32 pclass; | 16 | struct list_head head; |
17 | atomic_t refcount; | 17 | struct list_head tree; |
18 | atomic_t usecount; | 18 | u8 route; |
19 | u64 token; | ||
20 | u64 object; | ||
21 | struct rb_node node; | ||
19 | }; | 22 | }; |
20 | 23 | ||
21 | struct nvkm_object_func { | 24 | struct nvkm_object_func { |
@@ -43,6 +46,8 @@ int nvkm_object_new_(const struct nvkm_object_func *, | |||
43 | struct nvkm_object **); | 46 | struct nvkm_object **); |
44 | int nvkm_object_new(const struct nvkm_oclass *, void *data, u32 size, | 47 | int nvkm_object_new(const struct nvkm_oclass *, void *data, u32 size, |
45 | struct nvkm_object **); | 48 | struct nvkm_object **); |
49 | void nvkm_object_del(struct nvkm_object **); | ||
50 | void *nvkm_object_dtor(struct nvkm_object *); | ||
46 | int nvkm_object_init(struct nvkm_object *); | 51 | int nvkm_object_init(struct nvkm_object *); |
47 | int nvkm_object_fini(struct nvkm_object *, bool suspend); | 52 | int nvkm_object_fini(struct nvkm_object *, bool suspend); |
48 | int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size); | 53 | int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size); |
@@ -72,14 +77,12 @@ struct nvkm_oclass { | |||
72 | struct nvkm_sclass base; | 77 | struct nvkm_sclass base; |
73 | const void *priv; | 78 | const void *priv; |
74 | const void *engn; | 79 | const void *engn; |
75 | s32 handle; | 80 | u32 handle; |
81 | u8 route; | ||
82 | u64 token; | ||
76 | u64 object; | 83 | u64 object; |
77 | struct nvkm_client *client; | 84 | struct nvkm_client *client; |
78 | struct nvkm_object *parent; | 85 | struct nvkm_object *parent; |
79 | struct nvkm_engine *engine; | 86 | struct nvkm_engine *engine; |
80 | }; | 87 | }; |
81 | |||
82 | void nvkm_object_ref(struct nvkm_object *, struct nvkm_object **); | ||
83 | int nvkm_object_inc(struct nvkm_object *); | ||
84 | int nvkm_object_dec(struct nvkm_object *, bool suspend); | ||
85 | #endif | 88 | #endif |
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 6634f420ded3..40a903b79343 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c | |||
@@ -134,6 +134,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, | |||
134 | /* destroy channel object, all children will be killed too */ | 134 | /* destroy channel object, all children will be killed too */ |
135 | if (chan->chan) { | 135 | if (chan->chan) { |
136 | abi16->handles &= ~(1ULL << (chan->chan->user.handle & 0xffff)); | 136 | abi16->handles &= ~(1ULL << (chan->chan->user.handle & 0xffff)); |
137 | nouveau_channel_idle(chan->chan); | ||
137 | nouveau_channel_del(&chan->chan); | 138 | nouveau_channel_del(&chan->chan); |
138 | } | 139 | } |
139 | 140 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 4a13bda1475b..8c88c5e5bf0b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c | |||
@@ -43,20 +43,26 @@ module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); | |||
43 | int | 43 | int |
44 | nouveau_channel_idle(struct nouveau_channel *chan) | 44 | nouveau_channel_idle(struct nouveau_channel *chan) |
45 | { | 45 | { |
46 | struct nouveau_cli *cli = (void *)chan->user.client; | 46 | if (likely(chan && chan->fence)) { |
47 | struct nouveau_fence *fence = NULL; | 47 | struct nouveau_cli *cli = (void *)chan->user.client; |
48 | int ret; | 48 | struct nouveau_fence *fence = NULL; |
49 | int ret; | ||
50 | |||
51 | ret = nouveau_fence_new(chan, false, &fence); | ||
52 | if (!ret) { | ||
53 | ret = nouveau_fence_wait(fence, false, false); | ||
54 | nouveau_fence_unref(&fence); | ||
55 | } | ||
49 | 56 | ||
50 | ret = nouveau_fence_new(chan, false, &fence); | 57 | if (ret) { |
51 | if (!ret) { | 58 | NV_PRINTK(err, cli, "failed to idle channel " |
52 | ret = nouveau_fence_wait(fence, false, false); | 59 | "0x%08x [%s]\n", |
53 | nouveau_fence_unref(&fence); | 60 | chan->user.handle, |
61 | nvxx_client(&cli->base)->name); | ||
62 | return ret; | ||
63 | } | ||
54 | } | 64 | } |
55 | 65 | return 0; | |
56 | if (ret) | ||
57 | NV_PRINTK(err, cli, "failed to idle channel 0x%08x [%s]\n", | ||
58 | chan->user.handle, nvxx_client(&cli->base)->name); | ||
59 | return ret; | ||
60 | } | 66 | } |
61 | 67 | ||
62 | void | 68 | void |
@@ -64,10 +70,8 @@ nouveau_channel_del(struct nouveau_channel **pchan) | |||
64 | { | 70 | { |
65 | struct nouveau_channel *chan = *pchan; | 71 | struct nouveau_channel *chan = *pchan; |
66 | if (chan) { | 72 | if (chan) { |
67 | if (chan->fence) { | 73 | if (chan->fence) |
68 | nouveau_channel_idle(chan); | ||
69 | nouveau_fence(chan->drm)->context_del(chan); | 74 | nouveau_fence(chan->drm)->context_del(chan); |
70 | } | ||
71 | nvif_object_fini(&chan->nvsw); | 75 | nvif_object_fini(&chan->nvsw); |
72 | nvif_object_fini(&chan->gart); | 76 | nvif_object_fini(&chan->gart); |
73 | nvif_object_fini(&chan->vram); | 77 | nvif_object_fini(&chan->vram); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index d04d08cc546d..14a13486c27f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -139,13 +139,17 @@ nouveau_cli_destroy(struct nouveau_cli *cli) | |||
139 | static void | 139 | static void |
140 | nouveau_accel_fini(struct nouveau_drm *drm) | 140 | nouveau_accel_fini(struct nouveau_drm *drm) |
141 | { | 141 | { |
142 | nvif_notify_fini(&drm->flip); | 142 | nouveau_channel_idle(drm->channel); |
143 | nouveau_channel_del(&drm->channel); | ||
144 | nvif_object_fini(&drm->ntfy); | 143 | nvif_object_fini(&drm->ntfy); |
145 | nvkm_gpuobj_del(&drm->notify); | 144 | nvkm_gpuobj_del(&drm->notify); |
145 | nvif_notify_fini(&drm->flip); | ||
146 | nvif_object_fini(&drm->nvsw); | 146 | nvif_object_fini(&drm->nvsw); |
147 | nouveau_channel_del(&drm->cechan); | 147 | nouveau_channel_del(&drm->channel); |
148 | |||
149 | nouveau_channel_idle(drm->cechan); | ||
148 | nvif_object_fini(&drm->ttm.copy); | 150 | nvif_object_fini(&drm->ttm.copy); |
151 | nouveau_channel_del(&drm->cechan); | ||
152 | |||
149 | if (drm->fence) | 153 | if (drm->fence) |
150 | nouveau_fence(drm)->dtor(drm); | 154 | nouveau_fence(drm)->dtor(drm); |
151 | } | 155 | } |
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/Kbuild b/drivers/gpu/drm/nouveau/nvkm/core/Kbuild index 09044cf0d9ff..7f66963f305c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/core/Kbuild | |||
@@ -3,7 +3,6 @@ nvkm-y += nvkm/core/engine.o | |||
3 | nvkm-y += nvkm/core/enum.o | 3 | nvkm-y += nvkm/core/enum.o |
4 | nvkm-y += nvkm/core/event.o | 4 | nvkm-y += nvkm/core/event.o |
5 | nvkm-y += nvkm/core/gpuobj.o | 5 | nvkm-y += nvkm/core/gpuobj.o |
6 | nvkm-y += nvkm/core/handle.o | ||
7 | nvkm-y += nvkm/core/ioctl.o | 6 | nvkm-y += nvkm/core/ioctl.o |
8 | nvkm-y += nvkm/core/memory.o | 7 | nvkm-y += nvkm/core/memory.o |
9 | nvkm-y += nvkm/core/mm.o | 8 | nvkm-y += nvkm/core/mm.o |
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c index ab98f8c45950..297e1e953fa6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/client.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c | |||
@@ -23,7 +23,6 @@ | |||
23 | */ | 23 | */ |
24 | #include <core/client.h> | 24 | #include <core/client.h> |
25 | #include <core/device.h> | 25 | #include <core/device.h> |
26 | #include <core/handle.h> | ||
27 | #include <core/notify.h> | 26 | #include <core/notify.h> |
28 | #include <core/option.h> | 27 | #include <core/option.h> |
29 | 28 | ||
@@ -91,7 +90,7 @@ int | |||
91 | nvkm_client_notify_new(struct nvkm_object *object, | 90 | nvkm_client_notify_new(struct nvkm_object *object, |
92 | struct nvkm_event *event, void *data, u32 size) | 91 | struct nvkm_event *event, void *data, u32 size) |
93 | { | 92 | { |
94 | struct nvkm_client *client = nvkm_client(object); | 93 | struct nvkm_client *client = object->client; |
95 | struct nvkm_client_notify *notify; | 94 | struct nvkm_client_notify *notify; |
96 | union { | 95 | union { |
97 | struct nvif_notify_req_v0 v0; | 96 | struct nvif_notify_req_v0 v0; |
@@ -207,47 +206,47 @@ nvkm_client_object_func = { | |||
207 | }; | 206 | }; |
208 | 207 | ||
209 | void | 208 | void |
210 | nvkm_client_remove(struct nvkm_client *client, struct nvkm_handle *object) | 209 | nvkm_client_remove(struct nvkm_client *client, struct nvkm_object *object) |
211 | { | 210 | { |
212 | if (!RB_EMPTY_NODE(&object->rb)) | 211 | if (!RB_EMPTY_NODE(&object->node)) |
213 | rb_erase(&object->rb, &client->objroot); | 212 | rb_erase(&object->node, &client->objroot); |
214 | } | 213 | } |
215 | 214 | ||
216 | bool | 215 | bool |
217 | nvkm_client_insert(struct nvkm_client *client, struct nvkm_handle *object) | 216 | nvkm_client_insert(struct nvkm_client *client, struct nvkm_object *object) |
218 | { | 217 | { |
219 | struct rb_node **ptr = &client->objroot.rb_node; | 218 | struct rb_node **ptr = &client->objroot.rb_node; |
220 | struct rb_node *parent = NULL; | 219 | struct rb_node *parent = NULL; |
221 | 220 | ||
222 | while (*ptr) { | 221 | while (*ptr) { |
223 | struct nvkm_handle *this = | 222 | struct nvkm_object *this = |
224 | container_of(*ptr, typeof(*this), rb); | 223 | container_of(*ptr, typeof(*this), node); |
225 | parent = *ptr; | 224 | parent = *ptr; |
226 | if (object->handle < this->handle) | 225 | if (object->object < this->object) |
227 | ptr = &parent->rb_left; | 226 | ptr = &parent->rb_left; |
228 | else | 227 | else |
229 | if (object->handle > this->handle) | 228 | if (object->object > this->object) |
230 | ptr = &parent->rb_right; | 229 | ptr = &parent->rb_right; |
231 | else | 230 | else |
232 | return false; | 231 | return false; |
233 | } | 232 | } |
234 | 233 | ||
235 | rb_link_node(&object->rb, parent, ptr); | 234 | rb_link_node(&object->node, parent, ptr); |
236 | rb_insert_color(&object->rb, &client->objroot); | 235 | rb_insert_color(&object->node, &client->objroot); |
237 | return true; | 236 | return true; |
238 | } | 237 | } |
239 | 238 | ||
240 | struct nvkm_handle * | 239 | struct nvkm_object * |
241 | nvkm_client_search(struct nvkm_client *client, u64 handle) | 240 | nvkm_client_search(struct nvkm_client *client, u64 handle) |
242 | { | 241 | { |
243 | struct rb_node *node = client->objroot.rb_node; | 242 | struct rb_node *node = client->objroot.rb_node; |
244 | while (node) { | 243 | while (node) { |
245 | struct nvkm_handle *object = | 244 | struct nvkm_object *object = |
246 | container_of(node, typeof(*object), rb); | 245 | container_of(node, typeof(*object), node); |
247 | if (handle < object->handle) | 246 | if (handle < object->object) |
248 | node = node->rb_left; | 247 | node = node->rb_left; |
249 | else | 248 | else |
250 | if (handle > object->handle) | 249 | if (handle > object->object) |
251 | node = node->rb_right; | 250 | node = node->rb_right; |
252 | else | 251 | else |
253 | return object; | 252 | return object; |
@@ -260,26 +259,17 @@ nvkm_client_fini(struct nvkm_client *client, bool suspend) | |||
260 | { | 259 | { |
261 | struct nvkm_object *object = &client->object; | 260 | struct nvkm_object *object = &client->object; |
262 | const char *name[2] = { "fini", "suspend" }; | 261 | const char *name[2] = { "fini", "suspend" }; |
263 | int ret, i; | 262 | int i; |
264 | nvif_trace(object, "%s running\n", name[suspend]); | 263 | nvif_debug(object, "%s notify\n", name[suspend]); |
265 | nvif_trace(object, "%s notify\n", name[suspend]); | ||
266 | for (i = 0; i < ARRAY_SIZE(client->notify); i++) | 264 | for (i = 0; i < ARRAY_SIZE(client->notify); i++) |
267 | nvkm_client_notify_put(client, i); | 265 | nvkm_client_notify_put(client, i); |
268 | nvif_trace(object, "%s object\n", name[suspend]); | 266 | return nvkm_object_fini(&client->object, suspend); |
269 | ret = nvkm_handle_fini(client->root, suspend); | ||
270 | nvif_trace(object, "%s completed with %d\n", name[suspend], ret); | ||
271 | return ret; | ||
272 | } | 267 | } |
273 | 268 | ||
274 | int | 269 | int |
275 | nvkm_client_init(struct nvkm_client *client) | 270 | nvkm_client_init(struct nvkm_client *client) |
276 | { | 271 | { |
277 | struct nvkm_object *object = &client->object; | 272 | return nvkm_object_init(&client->object); |
278 | int ret; | ||
279 | nvif_trace(object, "init running\n"); | ||
280 | ret = nvkm_handle_init(client->root); | ||
281 | nvif_trace(object, "init completed with %d\n", ret); | ||
282 | return ret; | ||
283 | } | 273 | } |
284 | 274 | ||
285 | void | 275 | void |
@@ -291,7 +281,7 @@ nvkm_client_del(struct nvkm_client **pclient) | |||
291 | nvkm_client_fini(client, false); | 281 | nvkm_client_fini(client, false); |
292 | for (i = 0; i < ARRAY_SIZE(client->notify); i++) | 282 | for (i = 0; i < ARRAY_SIZE(client->notify); i++) |
293 | nvkm_client_notify_del(client, i); | 283 | nvkm_client_notify_del(client, i); |
294 | nvkm_handle_destroy(client->root); | 284 | nvkm_object_dtor(&client->object); |
295 | kfree(*pclient); | 285 | kfree(*pclient); |
296 | *pclient = NULL; | 286 | *pclient = NULL; |
297 | } | 287 | } |
@@ -303,7 +293,6 @@ nvkm_client_new(const char *name, u64 device, const char *cfg, | |||
303 | { | 293 | { |
304 | struct nvkm_oclass oclass = {}; | 294 | struct nvkm_oclass oclass = {}; |
305 | struct nvkm_client *client; | 295 | struct nvkm_client *client; |
306 | int ret; | ||
307 | 296 | ||
308 | if (!(client = *pclient = kzalloc(sizeof(*client), GFP_KERNEL))) | 297 | if (!(client = *pclient = kzalloc(sizeof(*client), GFP_KERNEL))) |
309 | return -ENOMEM; | 298 | return -ENOMEM; |
@@ -315,9 +304,5 @@ nvkm_client_new(const char *name, u64 device, const char *cfg, | |||
315 | client->debug = nvkm_dbgopt(dbg, "CLIENT"); | 304 | client->debug = nvkm_dbgopt(dbg, "CLIENT"); |
316 | client->objroot = RB_ROOT; | 305 | client->objroot = RB_ROOT; |
317 | client->dmaroot = RB_ROOT; | 306 | client->dmaroot = RB_ROOT; |
318 | 307 | return 0; | |
319 | ret = nvkm_handle_create(NULL, ~0, &client->object, &client->root); | ||
320 | if (ret) | ||
321 | nvkm_client_del(pclient); | ||
322 | return ret; | ||
323 | } | 308 | } |
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/handle.c b/drivers/gpu/drm/nouveau/nvkm/core/handle.c deleted file mode 100644 index d185cae0fbba..000000000000 --- a/drivers/gpu/drm/nouveau/nvkm/core/handle.c +++ /dev/null | |||
@@ -1,139 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | #include <core/handle.h> | ||
25 | #include <core/client.h> | ||
26 | |||
27 | #define hprintk(h,l,f,a...) do { \ | ||
28 | struct nvkm_handle *p = (h)->parent; u32 n = p ? p->name : ~0; \ | ||
29 | nvif_printk((h)->object, l, INFO, "0x%08x:0x%08x "f, n, (h)->name, ##a);\ | ||
30 | } while(0) | ||
31 | |||
32 | int | ||
33 | nvkm_handle_init(struct nvkm_handle *handle) | ||
34 | { | ||
35 | struct nvkm_handle *item; | ||
36 | int ret; | ||
37 | |||
38 | hprintk(handle, TRACE, "init running\n"); | ||
39 | ret = nvkm_object_inc(handle->object); | ||
40 | if (ret) | ||
41 | return ret; | ||
42 | |||
43 | hprintk(handle, TRACE, "init children\n"); | ||
44 | list_for_each_entry(item, &handle->tree, head) { | ||
45 | ret = nvkm_handle_init(item); | ||
46 | if (ret) | ||
47 | goto fail; | ||
48 | } | ||
49 | |||
50 | hprintk(handle, TRACE, "init completed\n"); | ||
51 | return 0; | ||
52 | fail: | ||
53 | hprintk(handle, ERROR, "init failed with %d\n", ret); | ||
54 | list_for_each_entry_continue_reverse(item, &handle->tree, head) { | ||
55 | nvkm_handle_fini(item, false); | ||
56 | } | ||
57 | |||
58 | nvkm_object_dec(handle->object, false); | ||
59 | return ret; | ||
60 | } | ||
61 | |||
62 | int | ||
63 | nvkm_handle_fini(struct nvkm_handle *handle, bool suspend) | ||
64 | { | ||
65 | static char *name[2] = { "fini", "suspend" }; | ||
66 | struct nvkm_handle *item; | ||
67 | int ret; | ||
68 | |||
69 | hprintk(handle, TRACE, "%s children\n", name[suspend]); | ||
70 | list_for_each_entry(item, &handle->tree, head) { | ||
71 | ret = nvkm_handle_fini(item, suspend); | ||
72 | if (ret && suspend) | ||
73 | goto fail; | ||
74 | } | ||
75 | |||
76 | hprintk(handle, TRACE, "%s running\n", name[suspend]); | ||
77 | if (handle->object) { | ||
78 | ret = nvkm_object_dec(handle->object, suspend); | ||
79 | if (ret && suspend) | ||
80 | goto fail; | ||
81 | } | ||
82 | |||
83 | hprintk(handle, TRACE, "%s completed\n", name[suspend]); | ||
84 | return 0; | ||
85 | fail: | ||
86 | hprintk(handle, ERROR, "%s failed with %d\n", name[suspend], ret); | ||
87 | list_for_each_entry_continue_reverse(item, &handle->tree, head) { | ||
88 | int rret = nvkm_handle_init(item); | ||
89 | if (rret) | ||
90 | hprintk(handle, FATAL, "failed to restart, %d\n", rret); | ||
91 | } | ||
92 | |||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | int | ||
97 | nvkm_handle_create(struct nvkm_handle *parent, u32 _handle, | ||
98 | struct nvkm_object *object, struct nvkm_handle **phandle) | ||
99 | { | ||
100 | struct nvkm_handle *handle; | ||
101 | |||
102 | handle = kzalloc(sizeof(*handle), GFP_KERNEL); | ||
103 | if (!handle) | ||
104 | return -ENOMEM; | ||
105 | |||
106 | INIT_LIST_HEAD(&handle->head); | ||
107 | INIT_LIST_HEAD(&handle->tree); | ||
108 | handle->name = _handle; | ||
109 | handle->priv = ~0; | ||
110 | RB_CLEAR_NODE(&handle->rb); | ||
111 | handle->parent = parent; | ||
112 | nvkm_object_ref(object, &handle->object); | ||
113 | |||
114 | if (parent) | ||
115 | list_add(&handle->head, &handle->parent->tree); | ||
116 | |||
117 | hprintk(handle, TRACE, "created\n"); | ||
118 | *phandle = handle; | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | void | ||
123 | nvkm_handle_destroy(struct nvkm_handle *handle) | ||
124 | { | ||
125 | struct nvkm_client *client = nvkm_client(handle->object); | ||
126 | struct nvkm_handle *item, *temp; | ||
127 | |||
128 | hprintk(handle, TRACE, "destroy running\n"); | ||
129 | list_for_each_entry_safe(item, temp, &handle->tree, head) { | ||
130 | nvkm_handle_destroy(item); | ||
131 | } | ||
132 | |||
133 | nvkm_client_remove(client, handle); | ||
134 | list_del(&handle->head); | ||
135 | |||
136 | hprintk(handle, TRACE, "destroy completed\n"); | ||
137 | nvkm_object_ref(NULL, &handle->object); | ||
138 | kfree(handle); | ||
139 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c index d9bb0394d83f..d87d6ab03cc7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c | |||
@@ -24,15 +24,13 @@ | |||
24 | #include <core/ioctl.h> | 24 | #include <core/ioctl.h> |
25 | #include <core/client.h> | 25 | #include <core/client.h> |
26 | #include <core/engine.h> | 26 | #include <core/engine.h> |
27 | #include <core/handle.h> | ||
28 | 27 | ||
29 | #include <nvif/unpack.h> | 28 | #include <nvif/unpack.h> |
30 | #include <nvif/ioctl.h> | 29 | #include <nvif/ioctl.h> |
31 | 30 | ||
32 | static int | 31 | static int |
33 | nvkm_ioctl_nop(struct nvkm_handle *handle, void *data, u32 size) | 32 | nvkm_ioctl_nop(struct nvkm_object *object, void *data, u32 size) |
34 | { | 33 | { |
35 | struct nvkm_object *object = handle->object; | ||
36 | union { | 34 | union { |
37 | struct nvif_ioctl_nop_v0 v0; | 35 | struct nvif_ioctl_nop_v0 v0; |
38 | } *args = data; | 36 | } *args = data; |
@@ -48,9 +46,8 @@ nvkm_ioctl_nop(struct nvkm_handle *handle, void *data, u32 size) | |||
48 | } | 46 | } |
49 | 47 | ||
50 | static int | 48 | static int |
51 | nvkm_ioctl_sclass(struct nvkm_handle *handle, void *data, u32 size) | 49 | nvkm_ioctl_sclass(struct nvkm_object *object, void *data, u32 size) |
52 | { | 50 | { |
53 | struct nvkm_object *object = handle->object; | ||
54 | union { | 51 | union { |
55 | struct nvif_ioctl_sclass_v0 v0; | 52 | struct nvif_ioctl_sclass_v0 v0; |
56 | } *args = data; | 53 | } *args = data; |
@@ -81,13 +78,12 @@ nvkm_ioctl_sclass(struct nvkm_handle *handle, void *data, u32 size) | |||
81 | } | 78 | } |
82 | 79 | ||
83 | static int | 80 | static int |
84 | nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) | 81 | nvkm_ioctl_new(struct nvkm_object *parent, void *data, u32 size) |
85 | { | 82 | { |
86 | union { | 83 | union { |
87 | struct nvif_ioctl_new_v0 v0; | 84 | struct nvif_ioctl_new_v0 v0; |
88 | } *args = data; | 85 | } *args = data; |
89 | struct nvkm_client *client = handle->object->client; | 86 | struct nvkm_client *client = parent->client; |
90 | struct nvkm_object *parent = handle->object; | ||
91 | struct nvkm_object *object = NULL; | 87 | struct nvkm_object *object = NULL; |
92 | struct nvkm_oclass oclass; | 88 | struct nvkm_oclass oclass; |
93 | int ret, i = 0; | 89 | int ret, i = 0; |
@@ -124,38 +120,30 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size) | |||
124 | } | 120 | } |
125 | 121 | ||
126 | ret = oclass.ctor(&oclass, data, size, &object); | 122 | ret = oclass.ctor(&oclass, data, size, &object); |
127 | if (ret) | ||
128 | goto fail_object; | ||
129 | |||
130 | ret = nvkm_object_inc(object); | ||
131 | if (ret) | ||
132 | goto fail_object; | ||
133 | |||
134 | ret = nvkm_handle_create(handle, args->v0.handle, object, &handle); | ||
135 | if (ret) | ||
136 | goto fail_handle; | ||
137 | |||
138 | ret = nvkm_handle_init(handle); | ||
139 | handle->route = args->v0.route; | ||
140 | handle->token = args->v0.token; | ||
141 | if (ret) | ||
142 | nvkm_handle_destroy(handle); | ||
143 | |||
144 | handle->handle = args->v0.object; | ||
145 | nvkm_client_insert(client, handle); | ||
146 | client->data = object; | ||
147 | fail_handle: | ||
148 | nvkm_object_dec(object, false); | ||
149 | fail_object: | ||
150 | nvkm_object_ref(NULL, &object); | ||
151 | nvkm_engine_unref(&oclass.engine); | 123 | nvkm_engine_unref(&oclass.engine); |
124 | if (ret == 0) { | ||
125 | ret = nvkm_object_init(object); | ||
126 | if (ret == 0) { | ||
127 | list_add(&object->head, &parent->tree); | ||
128 | object->route = args->v0.route; | ||
129 | object->token = args->v0.token; | ||
130 | object->object = args->v0.object; | ||
131 | if (nvkm_client_insert(client, object)) { | ||
132 | client->data = object; | ||
133 | return 0; | ||
134 | } | ||
135 | ret = -EEXIST; | ||
136 | } | ||
137 | nvkm_object_fini(object, false); | ||
138 | } | ||
139 | |||
140 | nvkm_object_del(&object); | ||
152 | return ret; | 141 | return ret; |
153 | } | 142 | } |
154 | 143 | ||
155 | static int | 144 | static int |
156 | nvkm_ioctl_del(struct nvkm_handle *handle, void *data, u32 size) | 145 | nvkm_ioctl_del(struct nvkm_object *object, void *data, u32 size) |
157 | { | 146 | { |
158 | struct nvkm_object *object = handle->object; | ||
159 | union { | 147 | union { |
160 | struct nvif_ioctl_del none; | 148 | struct nvif_ioctl_del none; |
161 | } *args = data; | 149 | } *args = data; |
@@ -164,17 +152,16 @@ nvkm_ioctl_del(struct nvkm_handle *handle, void *data, u32 size) | |||
164 | nvif_ioctl(object, "delete size %d\n", size); | 152 | nvif_ioctl(object, "delete size %d\n", size); |
165 | if (nvif_unvers(args->none)) { | 153 | if (nvif_unvers(args->none)) { |
166 | nvif_ioctl(object, "delete\n"); | 154 | nvif_ioctl(object, "delete\n"); |
167 | nvkm_handle_fini(handle, false); | 155 | nvkm_object_fini(object, false); |
168 | nvkm_handle_destroy(handle); | 156 | nvkm_object_del(&object); |
169 | } | 157 | } |
170 | 158 | ||
171 | return ret; | 159 | return ret; |
172 | } | 160 | } |
173 | 161 | ||
174 | static int | 162 | static int |
175 | nvkm_ioctl_mthd(struct nvkm_handle *handle, void *data, u32 size) | 163 | nvkm_ioctl_mthd(struct nvkm_object *object, void *data, u32 size) |
176 | { | 164 | { |
177 | struct nvkm_object *object = handle->object; | ||
178 | union { | 165 | union { |
179 | struct nvif_ioctl_mthd_v0 v0; | 166 | struct nvif_ioctl_mthd_v0 v0; |
180 | } *args = data; | 167 | } *args = data; |
@@ -192,9 +179,8 @@ nvkm_ioctl_mthd(struct nvkm_handle *handle, void *data, u32 size) | |||
192 | 179 | ||
193 | 180 | ||
194 | static int | 181 | static int |
195 | nvkm_ioctl_rd(struct nvkm_handle *handle, void *data, u32 size) | 182 | nvkm_ioctl_rd(struct nvkm_object *object, void *data, u32 size) |
196 | { | 183 | { |
197 | struct nvkm_object *object = handle->object; | ||
198 | union { | 184 | union { |
199 | struct nvif_ioctl_rd_v0 v0; | 185 | struct nvif_ioctl_rd_v0 v0; |
200 | } *args = data; | 186 | } *args = data; |
@@ -232,9 +218,8 @@ nvkm_ioctl_rd(struct nvkm_handle *handle, void *data, u32 size) | |||
232 | } | 218 | } |
233 | 219 | ||
234 | static int | 220 | static int |
235 | nvkm_ioctl_wr(struct nvkm_handle *handle, void *data, u32 size) | 221 | nvkm_ioctl_wr(struct nvkm_object *object, void *data, u32 size) |
236 | { | 222 | { |
237 | struct nvkm_object *object = handle->object; | ||
238 | union { | 223 | union { |
239 | struct nvif_ioctl_wr_v0 v0; | 224 | struct nvif_ioctl_wr_v0 v0; |
240 | } *args = data; | 225 | } *args = data; |
@@ -261,9 +246,8 @@ nvkm_ioctl_wr(struct nvkm_handle *handle, void *data, u32 size) | |||
261 | } | 246 | } |
262 | 247 | ||
263 | static int | 248 | static int |
264 | nvkm_ioctl_map(struct nvkm_handle *handle, void *data, u32 size) | 249 | nvkm_ioctl_map(struct nvkm_object *object, void *data, u32 size) |
265 | { | 250 | { |
266 | struct nvkm_object *object = handle->object; | ||
267 | union { | 251 | union { |
268 | struct nvif_ioctl_map_v0 v0; | 252 | struct nvif_ioctl_map_v0 v0; |
269 | } *args = data; | 253 | } *args = data; |
@@ -280,9 +264,8 @@ nvkm_ioctl_map(struct nvkm_handle *handle, void *data, u32 size) | |||
280 | } | 264 | } |
281 | 265 | ||
282 | static int | 266 | static int |
283 | nvkm_ioctl_unmap(struct nvkm_handle *handle, void *data, u32 size) | 267 | nvkm_ioctl_unmap(struct nvkm_object *object, void *data, u32 size) |
284 | { | 268 | { |
285 | struct nvkm_object *object = handle->object; | ||
286 | union { | 269 | union { |
287 | struct nvif_ioctl_unmap none; | 270 | struct nvif_ioctl_unmap none; |
288 | } *args = data; | 271 | } *args = data; |
@@ -297,9 +280,8 @@ nvkm_ioctl_unmap(struct nvkm_handle *handle, void *data, u32 size) | |||
297 | } | 280 | } |
298 | 281 | ||
299 | static int | 282 | static int |
300 | nvkm_ioctl_ntfy_new(struct nvkm_handle *handle, void *data, u32 size) | 283 | nvkm_ioctl_ntfy_new(struct nvkm_object *object, void *data, u32 size) |
301 | { | 284 | { |
302 | struct nvkm_object *object = handle->object; | ||
303 | union { | 285 | union { |
304 | struct nvif_ioctl_ntfy_new_v0 v0; | 286 | struct nvif_ioctl_ntfy_new_v0 v0; |
305 | } *args = data; | 287 | } *args = data; |
@@ -324,10 +306,9 @@ nvkm_ioctl_ntfy_new(struct nvkm_handle *handle, void *data, u32 size) | |||
324 | } | 306 | } |
325 | 307 | ||
326 | static int | 308 | static int |
327 | nvkm_ioctl_ntfy_del(struct nvkm_handle *handle, void *data, u32 size) | 309 | nvkm_ioctl_ntfy_del(struct nvkm_object *object, void *data, u32 size) |
328 | { | 310 | { |
329 | struct nvkm_client *client = nvkm_client(handle->object); | 311 | struct nvkm_client *client = object->client; |
330 | struct nvkm_object *object = handle->object; | ||
331 | union { | 312 | union { |
332 | struct nvif_ioctl_ntfy_del_v0 v0; | 313 | struct nvif_ioctl_ntfy_del_v0 v0; |
333 | } *args = data; | 314 | } *args = data; |
@@ -344,10 +325,9 @@ nvkm_ioctl_ntfy_del(struct nvkm_handle *handle, void *data, u32 size) | |||
344 | } | 325 | } |
345 | 326 | ||
346 | static int | 327 | static int |
347 | nvkm_ioctl_ntfy_get(struct nvkm_handle *handle, void *data, u32 size) | 328 | nvkm_ioctl_ntfy_get(struct nvkm_object *object, void *data, u32 size) |
348 | { | 329 | { |
349 | struct nvkm_client *client = nvkm_client(handle->object); | 330 | struct nvkm_client *client = object->client; |
350 | struct nvkm_object *object = handle->object; | ||
351 | union { | 331 | union { |
352 | struct nvif_ioctl_ntfy_get_v0 v0; | 332 | struct nvif_ioctl_ntfy_get_v0 v0; |
353 | } *args = data; | 333 | } *args = data; |
@@ -364,10 +344,9 @@ nvkm_ioctl_ntfy_get(struct nvkm_handle *handle, void *data, u32 size) | |||
364 | } | 344 | } |
365 | 345 | ||
366 | static int | 346 | static int |
367 | nvkm_ioctl_ntfy_put(struct nvkm_handle *handle, void *data, u32 size) | 347 | nvkm_ioctl_ntfy_put(struct nvkm_object *object, void *data, u32 size) |
368 | { | 348 | { |
369 | struct nvkm_client *client = nvkm_client(handle->object); | 349 | struct nvkm_client *client = object->client; |
370 | struct nvkm_object *object = handle->object; | ||
371 | union { | 350 | union { |
372 | struct nvif_ioctl_ntfy_put_v0 v0; | 351 | struct nvif_ioctl_ntfy_put_v0 v0; |
373 | } *args = data; | 352 | } *args = data; |
@@ -385,7 +364,7 @@ nvkm_ioctl_ntfy_put(struct nvkm_handle *handle, void *data, u32 size) | |||
385 | 364 | ||
386 | static struct { | 365 | static struct { |
387 | int version; | 366 | int version; |
388 | int (*func)(struct nvkm_handle *, void *, u32); | 367 | int (*func)(struct nvkm_object *, void *, u32); |
389 | } | 368 | } |
390 | nvkm_ioctl_v0[] = { | 369 | nvkm_ioctl_v0[] = { |
391 | { 0x00, nvkm_ioctl_nop }, | 370 | { 0x00, nvkm_ioctl_nop }, |
@@ -407,13 +386,13 @@ static int | |||
407 | nvkm_ioctl_path(struct nvkm_client *client, u64 handle, u32 type, | 386 | nvkm_ioctl_path(struct nvkm_client *client, u64 handle, u32 type, |
408 | void *data, u32 size, u8 owner, u8 *route, u64 *token) | 387 | void *data, u32 size, u8 owner, u8 *route, u64 *token) |
409 | { | 388 | { |
410 | struct nvkm_handle *object; | 389 | struct nvkm_object *object; |
411 | int ret; | 390 | int ret; |
412 | 391 | ||
413 | if (handle) | 392 | if (handle) |
414 | object = nvkm_client_search(client, handle); | 393 | object = nvkm_client_search(client, handle); |
415 | else | 394 | else |
416 | object = client->root; | 395 | object = &client->object; |
417 | if (unlikely(!object)) { | 396 | if (unlikely(!object)) { |
418 | nvif_ioctl(&client->object, "object not found\n"); | 397 | nvif_ioctl(&client->object, "object not found\n"); |
419 | return -ENOENT; | 398 | return -ENOENT; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/object.c b/drivers/gpu/drm/nouveau/nvkm/core/object.c index 8976526b1c8f..67aa7223dcd7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/object.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/object.c | |||
@@ -22,6 +22,7 @@ | |||
22 | * Authors: Ben Skeggs | 22 | * Authors: Ben Skeggs |
23 | */ | 23 | */ |
24 | #include <core/object.h> | 24 | #include <core/object.h> |
25 | #include <core/client.h> | ||
25 | #include <core/engine.h> | 26 | #include <core/engine.h> |
26 | 27 | ||
27 | int | 28 | int |
@@ -109,28 +110,112 @@ nvkm_object_bind(struct nvkm_object *object, struct nvkm_gpuobj *gpuobj, | |||
109 | int | 110 | int |
110 | nvkm_object_fini(struct nvkm_object *object, bool suspend) | 111 | nvkm_object_fini(struct nvkm_object *object, bool suspend) |
111 | { | 112 | { |
112 | if (object->func->fini) | 113 | const char *action = suspend ? "suspend" : "fini"; |
113 | return object->func->fini(object, suspend); | 114 | struct nvkm_object *child; |
115 | s64 time; | ||
116 | int ret; | ||
117 | |||
118 | nvif_debug(object, "%s children...\n", action); | ||
119 | time = ktime_to_us(ktime_get()); | ||
120 | list_for_each_entry(child, &object->tree, head) { | ||
121 | ret = nvkm_object_fini(child, suspend); | ||
122 | if (ret && suspend) | ||
123 | goto fail_child; | ||
124 | } | ||
125 | |||
126 | nvif_debug(object, "%s running...\n", action); | ||
127 | if (object->func->fini) { | ||
128 | ret = object->func->fini(object, suspend); | ||
129 | if (ret) { | ||
130 | nvif_error(object, "%s failed with %d\n", action, ret); | ||
131 | if (suspend) | ||
132 | goto fail; | ||
133 | } | ||
134 | } | ||
135 | |||
136 | time = ktime_to_us(ktime_get()) - time; | ||
137 | nvif_debug(object, "%s completed in %lldus\n", action, time); | ||
114 | return 0; | 138 | return 0; |
139 | |||
140 | fail: | ||
141 | if (object->func->init) { | ||
142 | int rret = object->func->init(object); | ||
143 | if (rret) | ||
144 | nvif_fatal(object, "failed to restart, %d\n", rret); | ||
145 | } | ||
146 | fail_child: | ||
147 | list_for_each_entry_continue_reverse(child, &object->tree, head) { | ||
148 | nvkm_object_init(child); | ||
149 | } | ||
150 | return ret; | ||
115 | } | 151 | } |
116 | 152 | ||
117 | int | 153 | int |
118 | nvkm_object_init(struct nvkm_object *object) | 154 | nvkm_object_init(struct nvkm_object *object) |
119 | { | 155 | { |
120 | if (object->func->init) | 156 | struct nvkm_object *child; |
121 | return object->func->init(object); | 157 | s64 time; |
158 | int ret; | ||
159 | |||
160 | nvif_debug(object, "init running...\n"); | ||
161 | time = ktime_to_us(ktime_get()); | ||
162 | if (object->func->init) { | ||
163 | ret = object->func->init(object); | ||
164 | if (ret) | ||
165 | goto fail; | ||
166 | } | ||
167 | |||
168 | nvif_debug(object, "init children...\n"); | ||
169 | list_for_each_entry(child, &object->tree, head) { | ||
170 | ret = nvkm_object_init(child); | ||
171 | if (ret) | ||
172 | goto fail_child; | ||
173 | } | ||
174 | |||
175 | time = ktime_to_us(ktime_get()) - time; | ||
176 | nvif_debug(object, "init completed in %lldus\n", time); | ||
122 | return 0; | 177 | return 0; |
178 | |||
179 | fail_child: | ||
180 | list_for_each_entry_continue_reverse(child, &object->tree, head) | ||
181 | nvkm_object_fini(child, false); | ||
182 | fail: | ||
183 | nvif_error(object, "init failed with %d\n", ret); | ||
184 | if (object->func->fini) | ||
185 | object->func->fini(object, false); | ||
186 | return ret; | ||
123 | } | 187 | } |
124 | 188 | ||
125 | static void | 189 | void * |
190 | nvkm_object_dtor(struct nvkm_object *object) | ||
191 | { | ||
192 | struct nvkm_object *child, *ctemp; | ||
193 | void *data = object; | ||
194 | s64 time; | ||
195 | |||
196 | nvif_debug(object, "destroy children...\n"); | ||
197 | time = ktime_to_us(ktime_get()); | ||
198 | list_for_each_entry_safe(child, ctemp, &object->tree, head) { | ||
199 | nvkm_object_del(&child); | ||
200 | } | ||
201 | |||
202 | nvif_debug(object, "destroy running...\n"); | ||
203 | if (object->func->dtor) | ||
204 | data = object->func->dtor(object); | ||
205 | nvkm_engine_unref(&object->engine); | ||
206 | time = ktime_to_us(ktime_get()) - time; | ||
207 | nvif_debug(object, "destroy completed in %lldus...\n", time); | ||
208 | return data; | ||
209 | } | ||
210 | |||
211 | void | ||
126 | nvkm_object_del(struct nvkm_object **pobject) | 212 | nvkm_object_del(struct nvkm_object **pobject) |
127 | { | 213 | { |
128 | struct nvkm_object *object = *pobject; | 214 | struct nvkm_object *object = *pobject; |
129 | |||
130 | if (object && !WARN_ON(!object->func)) { | 215 | if (object && !WARN_ON(!object->func)) { |
131 | if (object->func->dtor) | 216 | *pobject = nvkm_object_dtor(object); |
132 | *pobject = object->func->dtor(object); | 217 | nvkm_client_remove(object->client, object); |
133 | nvkm_engine_unref(&object->engine); | 218 | list_del(&object->head); |
134 | kfree(*pobject); | 219 | kfree(*pobject); |
135 | *pobject = NULL; | 220 | *pobject = NULL; |
136 | } | 221 | } |
@@ -145,9 +230,10 @@ nvkm_object_ctor(const struct nvkm_object_func *func, | |||
145 | object->engine = nvkm_engine_ref(oclass->engine); | 230 | object->engine = nvkm_engine_ref(oclass->engine); |
146 | object->oclass = oclass->base.oclass; | 231 | object->oclass = oclass->base.oclass; |
147 | object->handle = oclass->handle; | 232 | object->handle = oclass->handle; |
148 | object->parent = oclass->parent; | 233 | INIT_LIST_HEAD(&object->head); |
149 | atomic_set(&object->refcount, 1); | 234 | INIT_LIST_HEAD(&object->tree); |
150 | atomic_set(&object->usecount, 0); | 235 | RB_CLEAR_NODE(&object->node); |
236 | WARN_ON(oclass->engine && !object->engine); | ||
151 | } | 237 | } |
152 | 238 | ||
153 | int | 239 | int |
@@ -176,106 +262,3 @@ nvkm_object_new(const struct nvkm_oclass *oclass, void *data, u32 size, | |||
176 | oclass->base.func ? oclass->base.func : &nvkm_object_func; | 262 | oclass->base.func ? oclass->base.func : &nvkm_object_func; |
177 | return nvkm_object_new_(func, oclass, data, size, pobject); | 263 | return nvkm_object_new_(func, oclass, data, size, pobject); |
178 | } | 264 | } |
179 | |||
180 | void | ||
181 | nvkm_object_ref(struct nvkm_object *obj, struct nvkm_object **ref) | ||
182 | { | ||
183 | if (obj) { | ||
184 | atomic_inc(&obj->refcount); | ||
185 | } | ||
186 | |||
187 | if (*ref) { | ||
188 | int dead = atomic_dec_and_test(&(*ref)->refcount); | ||
189 | if (dead) | ||
190 | nvkm_object_del(ref); | ||
191 | } | ||
192 | |||
193 | *ref = obj; | ||
194 | } | ||
195 | |||
196 | int | ||
197 | nvkm_object_inc(struct nvkm_object *object) | ||
198 | { | ||
199 | int ref = atomic_add_return(1, &object->usecount); | ||
200 | int ret; | ||
201 | |||
202 | if (ref != 1) | ||
203 | return 0; | ||
204 | |||
205 | if (object->parent) { | ||
206 | ret = nvkm_object_inc(object->parent); | ||
207 | if (ret) | ||
208 | goto fail_parent; | ||
209 | } | ||
210 | |||
211 | ret = nvkm_object_init(object); | ||
212 | atomic_set(&object->usecount, 1); | ||
213 | if (ret) | ||
214 | goto fail_self; | ||
215 | |||
216 | return 0; | ||
217 | |||
218 | fail_self: | ||
219 | if (object->parent) | ||
220 | nvkm_object_dec(object->parent, false); | ||
221 | fail_parent: | ||
222 | atomic_dec(&object->usecount); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | static int | ||
227 | nvkm_object_decf(struct nvkm_object *object) | ||
228 | { | ||
229 | nvkm_object_fini(object, false); | ||
230 | atomic_set(&object->usecount, 0); | ||
231 | |||
232 | if (object->parent) | ||
233 | nvkm_object_dec(object->parent, false); | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static int | ||
239 | nvkm_object_decs(struct nvkm_object *object) | ||
240 | { | ||
241 | int ret; | ||
242 | |||
243 | ret = nvkm_object_fini(object, true); | ||
244 | atomic_set(&object->usecount, 0); | ||
245 | if (ret) | ||
246 | return ret; | ||
247 | |||
248 | if (object->parent) { | ||
249 | ret = nvkm_object_dec(object->parent, true); | ||
250 | if (ret) | ||
251 | goto fail_parent; | ||
252 | } | ||
253 | |||
254 | return 0; | ||
255 | |||
256 | fail_parent: | ||
257 | nvkm_object_init(object); | ||
258 | |||
259 | return ret; | ||
260 | } | ||
261 | |||
262 | int | ||
263 | nvkm_object_dec(struct nvkm_object *object, bool suspend) | ||
264 | { | ||
265 | int ref = atomic_add_return(-1, &object->usecount); | ||
266 | int ret; | ||
267 | |||
268 | if (ref == 0) { | ||
269 | if (suspend) | ||
270 | ret = nvkm_object_decs(object); | ||
271 | else | ||
272 | ret = nvkm_object_decf(object); | ||
273 | |||
274 | if (ret) { | ||
275 | atomic_inc(&object->usecount); | ||
276 | return ret; | ||
277 | } | ||
278 | } | ||
279 | |||
280 | return 0; | ||
281 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c b/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c index f32aa0dc425b..e31a0479add0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c | |||
@@ -109,9 +109,11 @@ nvkm_oproxy_fini(struct nvkm_object *object, bool suspend) | |||
109 | return ret; | 109 | return ret; |
110 | } | 110 | } |
111 | 111 | ||
112 | ret = nvkm_object_fini(oproxy->object, suspend); | 112 | if (oproxy->object->func->fini) { |
113 | if (ret && suspend) | 113 | ret = oproxy->object->func->fini(oproxy->object, suspend); |
114 | return ret; | 114 | if (ret && suspend) |
115 | return ret; | ||
116 | } | ||
115 | 117 | ||
116 | if (oproxy->func->fini[1]) { | 118 | if (oproxy->func->fini[1]) { |
117 | ret = oproxy->func->fini[1](oproxy, suspend); | 119 | ret = oproxy->func->fini[1](oproxy, suspend); |
@@ -134,9 +136,11 @@ nvkm_oproxy_init(struct nvkm_object *object) | |||
134 | return ret; | 136 | return ret; |
135 | } | 137 | } |
136 | 138 | ||
137 | ret = nvkm_object_init(oproxy->object); | 139 | if (oproxy->object->func->init) { |
138 | if (ret) | 140 | ret = oproxy->object->func->init(oproxy->object); |
139 | return ret; | 141 | if (ret) |
142 | return ret; | ||
143 | } | ||
140 | 144 | ||
141 | if (oproxy->func->init[1]) { | 145 | if (oproxy->func->init[1]) { |
142 | ret = oproxy->func->init[1](oproxy); | 146 | ret = oproxy->func->init[1](oproxy); |
@@ -153,7 +157,7 @@ nvkm_oproxy_dtor(struct nvkm_object *object) | |||
153 | struct nvkm_oproxy *oproxy = nvkm_oproxy(object); | 157 | struct nvkm_oproxy *oproxy = nvkm_oproxy(object); |
154 | if (oproxy->func->dtor[0]) | 158 | if (oproxy->func->dtor[0]) |
155 | oproxy->func->dtor[0](oproxy); | 159 | oproxy->func->dtor[0](oproxy); |
156 | nvkm_object_ref(NULL, &oproxy->object); | 160 | nvkm_object_del(&oproxy->object); |
157 | if (oproxy->func->dtor[1]) | 161 | if (oproxy->func->dtor[1]) |
158 | oproxy->func->dtor[1](oproxy); | 162 | oproxy->func->dtor[1](oproxy); |
159 | return oproxy; | 163 | return oproxy; |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c index b05c04a209be..9c6645a357b9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dmacnv50.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include "rootnv50.h" | 25 | #include "rootnv50.h" |
26 | 26 | ||
27 | #include <core/client.h> | 27 | #include <core/client.h> |
28 | #include <core/handle.h> | ||
29 | #include <core/oproxy.h> | 28 | #include <core/oproxy.h> |
30 | #include <core/ramht.h> | 29 | #include <core/ramht.h> |
31 | #include <subdev/fb.h> | 30 | #include <subdev/fb.h> |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c index a56e56eed57b..9921482fc162 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c | |||
@@ -116,7 +116,7 @@ nvkm_fifo_chan_child_del(struct nvkm_oproxy *base) | |||
116 | if (!--engn->refcount) { | 116 | if (!--engn->refcount) { |
117 | if (chan->func->engine_dtor) | 117 | if (chan->func->engine_dtor) |
118 | chan->func->engine_dtor(chan, engine); | 118 | chan->func->engine_dtor(chan, engine); |
119 | nvkm_object_ref(NULL, &engn->object); | 119 | nvkm_object_del(&engn->object); |
120 | if (chan->vm) | 120 | if (chan->vm) |
121 | atomic_dec(&chan->vm->engref[engine->subdev.index]); | 121 | atomic_dec(&chan->vm->engref[engine->subdev.index]); |
122 | } | 122 | } |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index 172f24301113..ff6fcbda615b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <core/client.h> | 27 | #include <core/client.h> |
28 | #include <core/enum.h> | 28 | #include <core/enum.h> |
29 | #include <core/gpuobj.h> | 29 | #include <core/gpuobj.h> |
30 | #include <core/handle.h> | ||
31 | #include <subdev/bar.h> | 30 | #include <subdev/bar.h> |
32 | #include <engine/sw.h> | 31 | #include <engine/sw.h> |
33 | 32 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index fc0ff2d37d06..98970a0b7a66 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <core/client.h> | 27 | #include <core/client.h> |
28 | #include <core/enum.h> | 28 | #include <core/enum.h> |
29 | #include <core/gpuobj.h> | 29 | #include <core/gpuobj.h> |
30 | #include <core/handle.h> | ||
31 | #include <subdev/bar.h> | 30 | #include <subdev/bar.h> |
32 | #include <engine/sw.h> | 31 | #include <engine/sw.h> |
33 | 32 | ||
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c index e6f04e87139a..ad707ff176cc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include "regsnv04.h" | 26 | #include "regsnv04.h" |
27 | 27 | ||
28 | #include <core/client.h> | 28 | #include <core/client.h> |
29 | #include <core/handle.h> | ||
30 | #include <core/ramht.h> | 29 | #include <core/ramht.h> |
31 | #include <subdev/instmem.h> | 30 | #include <subdev/instmem.h> |
32 | #include <subdev/timer.h> | 31 | #include <subdev/timer.h> |
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c index ef36ba18bff8..a381196af69d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include "nv50.h" | 24 | #include "nv50.h" |
25 | 25 | ||
26 | #include <core/gpuobj.h> | 26 | #include <core/gpuobj.h> |
27 | #include <core/handle.h> | ||
28 | #include <engine/disp.h> | 27 | #include <engine/disp.h> |
29 | #include <engine/fifo/chan.h> | 28 | #include <engine/fifo/chan.h> |
30 | #include <subdev/bar.h> | 29 | #include <subdev/bar.h> |