1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "priv.h"
23
24#include <core/firmware.h>
25#include <subdev/top.h>
26
27static void
28nvkm_sec2_recv(struct work_struct *work)
29{
30 struct nvkm_sec2 *sec2 = container_of(work, typeof(*sec2), work);
31
32 if (!sec2->initmsg_received) {
33 int ret = sec2->func->initmsg(sec2);
34 if (ret) {
35 nvkm_error(&sec2->engine.subdev,
36 "error parsing init message: %d\n", ret);
37 return;
38 }
39
40 sec2->initmsg_received = true;
41 }
42
43 nvkm_falcon_msgq_recv(sec2->msgq);
44}
45
46static void
47nvkm_sec2_intr(struct nvkm_engine *engine)
48{
49 struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
50 sec2->func->intr(sec2);
51}
52
53static int
54nvkm_sec2_fini(struct nvkm_engine *engine, bool suspend)
55{
56 struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
57
58 flush_work(&sec2->work);
59
60 if (suspend) {
61 nvkm_falcon_cmdq_fini(sec2->cmdq);
62 sec2->initmsg_received = false;
63 }
64
65 return 0;
66}
67
68static void *
69nvkm_sec2_dtor(struct nvkm_engine *engine)
70{
71 struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
72 nvkm_falcon_msgq_del(&sec2->msgq);
73 nvkm_falcon_cmdq_del(&sec2->cmdq);
74 nvkm_falcon_qmgr_del(&sec2->qmgr);
75 nvkm_falcon_dtor(&sec2->falcon);
76 return sec2;
77}
78
79static const struct nvkm_engine_func
80nvkm_sec2 = {
81 .dtor = nvkm_sec2_dtor,
82 .fini = nvkm_sec2_fini,
83 .intr = nvkm_sec2_intr,
84};
85
86int
87nvkm_sec2_new_(const struct nvkm_sec2_fwif *fwif, struct nvkm_device *device,
88 int index, u32 addr, struct nvkm_sec2 **psec2)
89{
90 struct nvkm_sec2 *sec2;
91 int ret;
92
93 if (!(sec2 = *psec2 = kzalloc(sizeof(*sec2), GFP_KERNEL)))
94 return -ENOMEM;
95
96 ret = nvkm_engine_ctor(&nvkm_sec2, device, index, true, &sec2->engine);
97 if (ret)
98 return ret;
99
100 fwif = nvkm_firmware_load(&sec2->engine.subdev, fwif, "Sec2", sec2);
101 if (IS_ERR(fwif))
102 return PTR_ERR(fwif);
103
104 sec2->func = fwif->func;
105
106 ret = nvkm_falcon_ctor(sec2->func->flcn, &sec2->engine.subdev,
107 nvkm_subdev_name[index], addr, &sec2->falcon);
108 if (ret)
109 return ret;
110
111 if ((ret = nvkm_falcon_qmgr_new(&sec2->falcon, &sec2->qmgr)) ||
112 (ret = nvkm_falcon_cmdq_new(sec2->qmgr, "cmdq", &sec2->cmdq)) ||
113 (ret = nvkm_falcon_msgq_new(sec2->qmgr, "msgq", &sec2->msgq)))
114 return ret;
115
116 INIT_WORK(&sec2->work, nvkm_sec2_recv);
117 return 0;
118};
119