1 /* Copyright (c) 2017 The Linux Foundation. All rights reserved.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
14 #include <linux/kref.h>
17 void msm_submitqueue_destroy(struct kref
*kref
)
19 struct msm_gpu_submitqueue
*queue
= container_of(kref
,
20 struct msm_gpu_submitqueue
, ref
);
25 struct msm_gpu_submitqueue
*msm_submitqueue_get(struct msm_file_private
*ctx
,
28 struct msm_gpu_submitqueue
*entry
;
33 read_lock(&ctx
->queuelock
);
35 list_for_each_entry(entry
, &ctx
->submitqueues
, node
) {
36 if (entry
->id
== id
) {
37 kref_get(&entry
->ref
);
38 read_unlock(&ctx
->queuelock
);
44 read_unlock(&ctx
->queuelock
);
48 void msm_submitqueue_close(struct msm_file_private
*ctx
)
50 struct msm_gpu_submitqueue
*entry
, *tmp
;
56 * No lock needed in close and there won't
57 * be any more user ioctls coming our way
59 list_for_each_entry_safe(entry
, tmp
, &ctx
->submitqueues
, node
)
60 msm_submitqueue_put(entry
);
63 int msm_submitqueue_create(struct drm_device
*drm
, struct msm_file_private
*ctx
,
64 u32 prio
, u32 flags
, u32
*id
)
66 struct msm_drm_private
*priv
= drm
->dev_private
;
67 struct msm_gpu_submitqueue
*queue
;
72 queue
= kzalloc(sizeof(*queue
), GFP_KERNEL
);
77 kref_init(&queue
->ref
);
81 if (prio
>= priv
->gpu
->nr_rings
)
87 write_lock(&ctx
->queuelock
);
89 queue
->id
= ctx
->queueid
++;
94 list_add_tail(&queue
->node
, &ctx
->submitqueues
);
96 write_unlock(&ctx
->queuelock
);
101 int msm_submitqueue_init(struct drm_device
*drm
, struct msm_file_private
*ctx
)
103 struct msm_drm_private
*priv
= drm
->dev_private
;
110 * Select priority 2 as the "default priority" unless nr_rings is less
111 * than 2 and then pick the lowest pirority
113 default_prio
= priv
->gpu
?
114 clamp_t(uint32_t, 2, 0, priv
->gpu
->nr_rings
- 1) : 0;
116 INIT_LIST_HEAD(&ctx
->submitqueues
);
118 rwlock_init(&ctx
->queuelock
);
120 return msm_submitqueue_create(drm
, ctx
, default_prio
, 0, NULL
);
123 int msm_submitqueue_remove(struct msm_file_private
*ctx
, u32 id
)
125 struct msm_gpu_submitqueue
*entry
;
131 * id 0 is the "default" queue and can't be destroyed
137 write_lock(&ctx
->queuelock
);
139 list_for_each_entry(entry
, &ctx
->submitqueues
, node
) {
140 if (entry
->id
== id
) {
141 list_del(&entry
->node
);
142 write_unlock(&ctx
->queuelock
);
144 msm_submitqueue_put(entry
);
149 write_unlock(&ctx
->queuelock
);