rk: ion: resolve build err
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / t6xx / kbase / src / common / mali_kbase_event.c
1 /*
2  *
3  * (C) COPYRIGHT ARM Limited. All rights reserved.
4  *
5  * This program is free software and is provided to you under the terms of the
6  * GNU General Public License version 2 as published by the Free Software
7  * Foundation, and any use by you of this program is subject to the terms
8  * of such GNU licence.
9  *
10  * A copy of the licence is included with the program, and can also be obtained
11  * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12  * Boston, MA  02110-1301, USA.
13  *
14  */
15
16
17
18
19
20 #include <kbase/src/common/mali_kbase.h>
21
22 #define beenthere(f, a...)      pr_debug("%s:" f, __func__, ##a)
23
24 STATIC base_jd_udata kbase_event_process(kbase_context *kctx, kbase_jd_atom *katom)
25 {
26         base_jd_udata data;
27
28         KBASE_DEBUG_ASSERT(kctx != NULL);
29         KBASE_DEBUG_ASSERT(katom != NULL);
30         KBASE_DEBUG_ASSERT(katom->status == KBASE_JD_ATOM_STATE_COMPLETED);
31
32         data = katom->udata;
33
34         KBASE_TIMELINE_ATOMS_IN_FLIGHT(kctx, atomic_sub_return(1, &kctx->timeline.jd_atoms_in_flight));
35
36         katom->status = KBASE_JD_ATOM_STATE_UNUSED;
37
38         wake_up(&katom->completed);
39
40         return data;
41 }
42
43 int kbase_event_pending(kbase_context *ctx)
44 {
45         int ret;
46
47         KBASE_DEBUG_ASSERT(ctx);
48
49         mutex_lock(&ctx->event_mutex);
50         ret = (!list_empty(&ctx->event_list)) || (MALI_TRUE == ctx->event_closed);
51         mutex_unlock(&ctx->event_mutex);
52
53         return ret;
54 }
55
56 KBASE_EXPORT_TEST_API(kbase_event_pending)
57
58 int kbase_event_dequeue(kbase_context *ctx, base_jd_event_v2 *uevent)
59 {
60         kbase_jd_atom *atom;
61
62         KBASE_DEBUG_ASSERT(ctx);
63
64         mutex_lock(&ctx->event_mutex);
65
66         if (list_empty(&ctx->event_list)) {
67                 if (ctx->event_closed) {
68                         /* generate the BASE_JD_EVENT_DRV_TERMINATED message on the fly */
69                         mutex_unlock(&ctx->event_mutex);
70                         uevent->event_code = BASE_JD_EVENT_DRV_TERMINATED;
71                         memset(&uevent->udata, 0, sizeof(uevent->udata));
72                         beenthere("event system closed, returning BASE_JD_EVENT_DRV_TERMINATED(0x%X)\n", BASE_JD_EVENT_DRV_TERMINATED);
73                         return 0;
74                 } else {
75                         mutex_unlock(&ctx->event_mutex);
76                         return -1;
77                 }
78         }
79
80         /* normal event processing */
81         atom = list_entry(ctx->event_list.next, kbase_jd_atom, dep_item[0]);
82         list_del(ctx->event_list.next);
83
84         mutex_unlock(&ctx->event_mutex);
85
86         beenthere("event dequeuing %p\n", (void *)atom);
87         uevent->event_code = atom->event_code;
88         uevent->atom_number = (atom - ctx->jctx.atoms);
89         uevent->udata = kbase_event_process(ctx, atom);
90
91         return 0;
92 }
93
94 KBASE_EXPORT_TEST_API(kbase_event_dequeue)
95
96 static void kbase_event_post_worker(struct work_struct *data)
97 {
98         kbase_jd_atom *atom = CONTAINER_OF(data, kbase_jd_atom, work);
99         kbase_context *ctx = atom->kctx;
100
101         if (atom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES)
102                 kbase_jd_free_external_resources(atom);
103
104         if (atom->core_req & BASE_JD_REQ_EVENT_ONLY_ON_FAILURE) {
105                 if (atom->event_code == BASE_JD_EVENT_DONE) {
106                         /* Don't report the event */
107                         kbase_event_process(ctx, atom);
108                         return;
109                 }
110         }
111
112         mutex_lock(&ctx->event_mutex);
113         list_add_tail(&atom->dep_item[0], &ctx->event_list);
114         mutex_unlock(&ctx->event_mutex);
115
116         kbase_event_wakeup(ctx);
117 }
118
119 void kbase_event_post(kbase_context *ctx, kbase_jd_atom *atom)
120 {
121         KBASE_DEBUG_ASSERT(ctx);
122         KBASE_DEBUG_ASSERT(ctx->event_workq);
123         KBASE_DEBUG_ASSERT(atom);
124
125         INIT_WORK(&atom->work, kbase_event_post_worker);
126         queue_work(ctx->event_workq, &atom->work);
127 }
128
129 KBASE_EXPORT_TEST_API(kbase_event_post)
130
131 void kbase_event_close(kbase_context *kctx)
132 {
133         mutex_lock(&kctx->event_mutex);
134         kctx->event_closed = MALI_TRUE;
135         mutex_unlock(&kctx->event_mutex);
136         kbase_event_wakeup(kctx);
137 }
138
139 mali_error kbase_event_init(kbase_context *kctx)
140 {
141         KBASE_DEBUG_ASSERT(kctx);
142
143         INIT_LIST_HEAD(&kctx->event_list);
144         mutex_init(&kctx->event_mutex);
145         kctx->event_closed = MALI_FALSE;
146         kctx->event_workq = alloc_workqueue("kbase_event", WQ_MEM_RECLAIM, 1);
147
148         if (NULL == kctx->event_workq)
149                 return MALI_ERROR_FUNCTION_FAILED;
150
151         return MALI_ERROR_NONE;
152 }
153
154 KBASE_EXPORT_TEST_API(kbase_event_init)
155
156 void kbase_event_cleanup(kbase_context *kctx)
157 {
158         KBASE_DEBUG_ASSERT(kctx);
159         KBASE_DEBUG_ASSERT(kctx->event_workq);
160
161         flush_workqueue(kctx->event_workq);
162         destroy_workqueue(kctx->event_workq);
163
164         /* We use kbase_event_dequeue to remove the remaining events as that
165          * deals with all the cleanup needed for the atoms.
166          *
167          * Note: use of kctx->event_list without a lock is safe because this must be the last
168          * thread using it (because we're about to terminate the lock)
169          */
170         while (!list_empty(&kctx->event_list)) {
171                 base_jd_event_v2 event;
172                 kbase_event_dequeue(kctx, &event);
173         }
174 }
175
176 KBASE_EXPORT_TEST_API(kbase_event_cleanup)