1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
6*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
7*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
9*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * The above copyright notice and this permission notice shall be included in
12*4882a593Smuzhiyun * all copies or substantial portions of the Software.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17*4882a593Smuzhiyun * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*4882a593Smuzhiyun * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*4882a593Smuzhiyun * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*4882a593Smuzhiyun * OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun *
22*4882a593Smuzhiyun */
23*4882a593Smuzhiyun #include "qmgr.h"
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun struct nvkm_falcon_qmgr_seq *
nvkm_falcon_qmgr_seq_acquire(struct nvkm_falcon_qmgr * qmgr)26*4882a593Smuzhiyun nvkm_falcon_qmgr_seq_acquire(struct nvkm_falcon_qmgr *qmgr)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun const struct nvkm_subdev *subdev = qmgr->falcon->owner;
29*4882a593Smuzhiyun struct nvkm_falcon_qmgr_seq *seq;
30*4882a593Smuzhiyun u32 index;
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun mutex_lock(&qmgr->seq.mutex);
33*4882a593Smuzhiyun index = find_first_zero_bit(qmgr->seq.tbl, NVKM_FALCON_QMGR_SEQ_NUM);
34*4882a593Smuzhiyun if (index >= NVKM_FALCON_QMGR_SEQ_NUM) {
35*4882a593Smuzhiyun nvkm_error(subdev, "no free sequence available\n");
36*4882a593Smuzhiyun mutex_unlock(&qmgr->seq.mutex);
37*4882a593Smuzhiyun return ERR_PTR(-EAGAIN);
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun set_bit(index, qmgr->seq.tbl);
41*4882a593Smuzhiyun mutex_unlock(&qmgr->seq.mutex);
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun seq = &qmgr->seq.id[index];
44*4882a593Smuzhiyun seq->state = SEQ_STATE_PENDING;
45*4882a593Smuzhiyun return seq;
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun void
nvkm_falcon_qmgr_seq_release(struct nvkm_falcon_qmgr * qmgr,struct nvkm_falcon_qmgr_seq * seq)49*4882a593Smuzhiyun nvkm_falcon_qmgr_seq_release(struct nvkm_falcon_qmgr *qmgr,
50*4882a593Smuzhiyun struct nvkm_falcon_qmgr_seq *seq)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun /* no need to acquire seq.mutex since clear_bit is atomic */
53*4882a593Smuzhiyun seq->state = SEQ_STATE_FREE;
54*4882a593Smuzhiyun seq->callback = NULL;
55*4882a593Smuzhiyun reinit_completion(&seq->done);
56*4882a593Smuzhiyun clear_bit(seq->id, qmgr->seq.tbl);
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun void
nvkm_falcon_qmgr_del(struct nvkm_falcon_qmgr ** pqmgr)60*4882a593Smuzhiyun nvkm_falcon_qmgr_del(struct nvkm_falcon_qmgr **pqmgr)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun struct nvkm_falcon_qmgr *qmgr = *pqmgr;
63*4882a593Smuzhiyun if (qmgr) {
64*4882a593Smuzhiyun kfree(*pqmgr);
65*4882a593Smuzhiyun *pqmgr = NULL;
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun int
nvkm_falcon_qmgr_new(struct nvkm_falcon * falcon,struct nvkm_falcon_qmgr ** pqmgr)70*4882a593Smuzhiyun nvkm_falcon_qmgr_new(struct nvkm_falcon *falcon,
71*4882a593Smuzhiyun struct nvkm_falcon_qmgr **pqmgr)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun struct nvkm_falcon_qmgr *qmgr;
74*4882a593Smuzhiyun int i;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun if (!(qmgr = *pqmgr = kzalloc(sizeof(*qmgr), GFP_KERNEL)))
77*4882a593Smuzhiyun return -ENOMEM;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun qmgr->falcon = falcon;
80*4882a593Smuzhiyun mutex_init(&qmgr->seq.mutex);
81*4882a593Smuzhiyun for (i = 0; i < NVKM_FALCON_QMGR_SEQ_NUM; i++) {
82*4882a593Smuzhiyun qmgr->seq.id[i].id = i;
83*4882a593Smuzhiyun init_completion(&qmgr->seq.id[i].done);
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun return 0;
87*4882a593Smuzhiyun }
88