diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2017-02-26 21:34:42 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2017-02-26 21:34:42 +0100 |
commit | 8e22e1b3499a446df48c2b26667ca36c55bf864c (patch) | |
tree | 5329f98b3eb3c95a9dcbab0fa4f9b6e62f0e788d /drivers/gpu/drm/nouveau/nvkm/core/client.c | |
parent | 00d3c14f14d51babd8aeafd5fa734ccf04f5ca3d (diff) | |
parent | 64a577196d66b44e37384bc5c4d78c61f59d5b2a (diff) |
Merge airlied/drm-next into drm-misc-next
Backmerge the main pull request to sync up with all the newly landed
drivers. Otherwise we'll have chaos even before 4.12 started in
earnest.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/core/client.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/core/client.c | 170 |
1 files changed, 83 insertions, 87 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c index e1943910858e..0d3a896892b4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/client.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c @@ -31,6 +31,43 @@ #include <nvif/if0000.h> #include <nvif/unpack.h> +static int +nvkm_uclient_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, + struct nvkm_object **pobject) +{ + union { + struct nvif_client_v0 v0; + } *args = argv; + struct nvkm_client *client; + int ret = -ENOSYS; + + if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))){ + args->v0.name[sizeof(args->v0.name) - 1] = 0; + ret = nvkm_client_new(args->v0.name, args->v0.device, NULL, + NULL, oclass->client->ntfy, &client); + if (ret) + return ret; + } else + return ret; + + client->object.client = oclass->client; + client->object.handle = oclass->handle; + client->object.route = oclass->route; + client->object.token = oclass->token; + client->object.object = oclass->object; + client->debug = oclass->client->debug; + *pobject = &client->object; + return 0; +} + +const struct nvkm_sclass +nvkm_uclient_sclass = { + .oclass = NVIF_CLASS_CLIENT, + .minver = 0, + .maxver = 0, + .ctor = nvkm_uclient_new, +}; + struct nvkm_client_notify { struct nvkm_client *client; struct nvkm_notify n; @@ -138,17 +175,30 @@ nvkm_client_notify_new(struct nvkm_object *object, return ret; } +static const struct nvkm_object_func nvkm_client; +struct nvkm_client * +nvkm_client_search(struct nvkm_client *client, u64 handle) +{ + struct nvkm_object *object; + + object = nvkm_object_search(client, handle, &nvkm_client); + if (IS_ERR(object)) + return (void *)object; + + return nvkm_client(object); +} + static int -nvkm_client_mthd_devlist(struct nvkm_object *object, void *data, u32 size) +nvkm_client_mthd_devlist(struct nvkm_client *client, void *data, u32 size) { union { - struct nv_client_devlist_v0 v0; + struct nvif_client_devlist_v0 v0; } *args = data; int ret = -ENOSYS; - nvif_ioctl(object, "client devlist size %d\n", size); + nvif_ioctl(&client->object, "client devlist size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) { - nvif_ioctl(object, "client devlist vers %d count %d\n", + nvif_ioctl(&client->object, "client devlist vers %d count %d\n", args->v0.version, args->v0.count); if (size == sizeof(args->v0.device[0]) * args->v0.count) { ret = nvkm_device_list(args->v0.device, args->v0.count); @@ -167,9 +217,10 @@ nvkm_client_mthd_devlist(struct nvkm_object *object, void *data, u32 size) static int nvkm_client_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) { + struct nvkm_client *client = nvkm_client(object); switch (mthd) { - case NV_CLIENT_DEVLIST: - return nvkm_client_mthd_devlist(object, data, size); + case NVIF_CLIENT_V0_DEVLIST: + return nvkm_client_mthd_devlist(client, data, size); default: break; } @@ -190,7 +241,8 @@ nvkm_client_child_get(struct nvkm_object *object, int index, const struct nvkm_sclass *sclass; switch (index) { - case 0: sclass = &nvkm_udevice_sclass; break; + case 0: sclass = &nvkm_uclient_sclass; break; + case 1: sclass = &nvkm_udevice_sclass; break; default: return -EINVAL; } @@ -200,110 +252,54 @@ nvkm_client_child_get(struct nvkm_object *object, int index, return 0; } -static const struct nvkm_object_func -nvkm_client_object_func = { - .mthd = nvkm_client_mthd, - .sclass = nvkm_client_child_get, -}; - -void -nvkm_client_remove(struct nvkm_client *client, struct nvkm_object *object) -{ - if (!RB_EMPTY_NODE(&object->node)) - rb_erase(&object->node, &client->objroot); -} - -bool -nvkm_client_insert(struct nvkm_client *client, struct nvkm_object *object) -{ - struct rb_node **ptr = &client->objroot.rb_node; - struct rb_node *parent = NULL; - - while (*ptr) { - struct nvkm_object *this = - container_of(*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, &client->objroot); - return true; -} - -struct nvkm_object * -nvkm_client_search(struct nvkm_client *client, u64 handle) -{ - struct rb_node *node = client->objroot.rb_node; - while (node) { - struct nvkm_object *object = - container_of(node, typeof(*object), node); - if (handle < object->object) - node = node->rb_left; - else - if (handle > object->object) - node = node->rb_right; - else - return object; - } - return NULL; -} - -int -nvkm_client_fini(struct nvkm_client *client, bool suspend) +static int +nvkm_client_fini(struct nvkm_object *object, bool suspend) { - struct nvkm_object *object = &client->object; + struct nvkm_client *client = nvkm_client(object); const char *name[2] = { "fini", "suspend" }; int i; nvif_debug(object, "%s notify\n", name[suspend]); for (i = 0; i < ARRAY_SIZE(client->notify); i++) nvkm_client_notify_put(client, i); - return nvkm_object_fini(&client->object, suspend); -} - -int -nvkm_client_init(struct nvkm_client *client) -{ - return nvkm_object_init(&client->object); + return 0; } -void -nvkm_client_del(struct nvkm_client **pclient) +static void * +nvkm_client_dtor(struct nvkm_object *object) { - struct nvkm_client *client = *pclient; + struct nvkm_client *client = nvkm_client(object); int i; - if (client) { - nvkm_client_fini(client, false); - for (i = 0; i < ARRAY_SIZE(client->notify); i++) - nvkm_client_notify_del(client, i); - nvkm_object_dtor(&client->object); - kfree(*pclient); - *pclient = NULL; - } + for (i = 0; i < ARRAY_SIZE(client->notify); i++) + nvkm_client_notify_del(client, i); + return client; } +static const struct nvkm_object_func +nvkm_client = { + .dtor = nvkm_client_dtor, + .fini = nvkm_client_fini, + .mthd = nvkm_client_mthd, + .sclass = nvkm_client_child_get, +}; + int nvkm_client_new(const char *name, u64 device, const char *cfg, - const char *dbg, struct nvkm_client **pclient) + const char *dbg, + int (*ntfy)(const void *, u32, const void *, u32), + struct nvkm_client **pclient) { - struct nvkm_oclass oclass = {}; + struct nvkm_oclass oclass = { .base = nvkm_uclient_sclass }; struct nvkm_client *client; if (!(client = *pclient = kzalloc(sizeof(*client), GFP_KERNEL))) return -ENOMEM; oclass.client = client; - nvkm_object_ctor(&nvkm_client_object_func, &oclass, &client->object); + nvkm_object_ctor(&nvkm_client, &oclass, &client->object); snprintf(client->name, sizeof(client->name), "%s", name); client->device = device; client->debug = nvkm_dbgopt(dbg, "CLIENT"); client->objroot = RB_ROOT; - client->dmaroot = RB_ROOT; + client->ntfy = ntfy; return 0; } |