]> Git Repo - linux.git/blob - drivers/gpu/drm/lima/lima_ctx.c
Merge tag 'for-linus-6.14-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / gpu / drm / lima / lima_ctx.c
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /* Copyright 2018-2019 Qiang Yu <[email protected]> */
3
4 #include <linux/pid.h>
5 #include <linux/slab.h>
6
7 #include "lima_device.h"
8 #include "lima_ctx.h"
9
10 int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id)
11 {
12         struct lima_ctx *ctx;
13         int i, err;
14
15         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
16         if (!ctx)
17                 return -ENOMEM;
18         ctx->dev = dev;
19         kref_init(&ctx->refcnt);
20
21         for (i = 0; i < lima_pipe_num; i++) {
22                 err = lima_sched_context_init(dev->pipe + i, ctx->context + i);
23                 if (err)
24                         goto err_out0;
25         }
26
27         err = xa_alloc(&mgr->handles, id, ctx, xa_limit_32b, GFP_KERNEL);
28         if (err < 0)
29                 goto err_out0;
30
31         ctx->pid = task_pid_nr(current);
32         get_task_comm(ctx->pname, current);
33
34         return 0;
35
36 err_out0:
37         for (i--; i >= 0; i--)
38                 lima_sched_context_fini(dev->pipe + i, ctx->context + i);
39         kfree(ctx);
40         return err;
41 }
42
43 static void lima_ctx_do_release(struct kref *ref)
44 {
45         struct lima_ctx *ctx = container_of(ref, struct lima_ctx, refcnt);
46         int i;
47
48         for (i = 0; i < lima_pipe_num; i++)
49                 lima_sched_context_fini(ctx->dev->pipe + i, ctx->context + i);
50         kfree(ctx);
51 }
52
53 int lima_ctx_free(struct lima_ctx_mgr *mgr, u32 id)
54 {
55         struct lima_ctx *ctx;
56         int ret = 0;
57
58         mutex_lock(&mgr->lock);
59         ctx = xa_erase(&mgr->handles, id);
60         if (ctx)
61                 kref_put(&ctx->refcnt, lima_ctx_do_release);
62         else
63                 ret = -EINVAL;
64         mutex_unlock(&mgr->lock);
65         return ret;
66 }
67
68 struct lima_ctx *lima_ctx_get(struct lima_ctx_mgr *mgr, u32 id)
69 {
70         struct lima_ctx *ctx;
71
72         mutex_lock(&mgr->lock);
73         ctx = xa_load(&mgr->handles, id);
74         if (ctx)
75                 kref_get(&ctx->refcnt);
76         mutex_unlock(&mgr->lock);
77         return ctx;
78 }
79
80 void lima_ctx_put(struct lima_ctx *ctx)
81 {
82         kref_put(&ctx->refcnt, lima_ctx_do_release);
83 }
84
85 void lima_ctx_mgr_init(struct lima_ctx_mgr *mgr)
86 {
87         mutex_init(&mgr->lock);
88         xa_init_flags(&mgr->handles, XA_FLAGS_ALLOC);
89 }
90
91 void lima_ctx_mgr_fini(struct lima_ctx_mgr *mgr)
92 {
93         struct lima_ctx *ctx;
94         unsigned long id;
95
96         xa_for_each(&mgr->handles, id, ctx) {
97                 kref_put(&ctx->refcnt, lima_ctx_do_release);
98         }
99
100         xa_destroy(&mgr->handles);
101         mutex_destroy(&mgr->lock);
102 }
This page took 0.033217 seconds and 4 git commands to generate.