3 * (C) COPYRIGHT ARM Limited. All rights reserved.
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
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.
20 #include <mali_kbase.h>
21 #include <mali_kbase_debug.h>
23 STATIC base_jd_udata kbase_event_process(kbase_context *kctx, kbase_jd_atom *katom)
27 KBASE_DEBUG_ASSERT(kctx != NULL);
28 KBASE_DEBUG_ASSERT(katom != NULL);
29 KBASE_DEBUG_ASSERT(katom->status == KBASE_JD_ATOM_STATE_COMPLETED);
33 KBASE_TIMELINE_ATOMS_IN_FLIGHT(kctx, atomic_sub_return(1, &kctx->timeline.jd_atoms_in_flight));
35 mutex_lock(&kctx->jctx.lock);
36 katom->status = KBASE_JD_ATOM_STATE_UNUSED;
37 mutex_unlock(&kctx->jctx.lock);
39 wake_up(&katom->completed);
44 int kbase_event_pending(kbase_context *ctx)
48 KBASE_DEBUG_ASSERT(ctx);
50 mutex_lock(&ctx->event_mutex);
51 ret = (!list_empty(&ctx->event_list)) || (MALI_TRUE == ctx->event_closed);
52 mutex_unlock(&ctx->event_mutex);
57 KBASE_EXPORT_TEST_API(kbase_event_pending)
59 int kbase_event_dequeue(kbase_context *ctx, base_jd_event_v2 *uevent)
63 KBASE_DEBUG_ASSERT(ctx);
65 mutex_lock(&ctx->event_mutex);
67 if (list_empty(&ctx->event_list)) {
68 if (ctx->event_closed) {
69 /* generate the BASE_JD_EVENT_DRV_TERMINATED message on the fly */
70 mutex_unlock(&ctx->event_mutex);
71 uevent->event_code = BASE_JD_EVENT_DRV_TERMINATED;
72 memset(&uevent->udata, 0, sizeof(uevent->udata));
73 dev_dbg(ctx->kbdev->dev,
74 "event system closed, returning BASE_JD_EVENT_DRV_TERMINATED(0x%X)\n",
75 BASE_JD_EVENT_DRV_TERMINATED);
78 mutex_unlock(&ctx->event_mutex);
83 /* normal event processing */
84 atom = list_entry(ctx->event_list.next, kbase_jd_atom, dep_item[0]);
85 list_del(ctx->event_list.next);
87 mutex_unlock(&ctx->event_mutex);
89 dev_dbg(ctx->kbdev->dev, "event dequeuing %p\n", (void *)atom);
90 uevent->event_code = atom->event_code;
91 uevent->atom_number = (atom - ctx->jctx.atoms);
92 uevent->udata = kbase_event_process(ctx, atom);
97 KBASE_EXPORT_TEST_API(kbase_event_dequeue)
99 static void kbase_event_post_worker(struct work_struct *data)
101 kbase_jd_atom *atom = CONTAINER_OF(data, kbase_jd_atom, work);
102 kbase_context *ctx = atom->kctx;
104 if (atom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES)
105 kbase_jd_free_external_resources(atom);
107 if (atom->core_req & BASE_JD_REQ_EVENT_ONLY_ON_FAILURE) {
108 if (atom->event_code == BASE_JD_EVENT_DONE) {
109 /* Don't report the event */
110 kbase_event_process(ctx, atom);
115 if (atom->core_req & BASEP_JD_REQ_EVENT_NEVER) {
116 /* Don't report the event */
117 kbase_event_process(ctx, atom);
121 mutex_lock(&ctx->event_mutex);
122 list_add_tail(&atom->dep_item[0], &ctx->event_list);
123 mutex_unlock(&ctx->event_mutex);
125 kbase_event_wakeup(ctx);
128 void kbase_event_post(kbase_context *ctx, kbase_jd_atom *atom)
130 KBASE_DEBUG_ASSERT(ctx);
131 KBASE_DEBUG_ASSERT(ctx->event_workq);
132 KBASE_DEBUG_ASSERT(atom);
134 INIT_WORK(&atom->work, kbase_event_post_worker);
135 queue_work(ctx->event_workq, &atom->work);
138 KBASE_EXPORT_TEST_API(kbase_event_post)
140 void kbase_event_close(kbase_context *kctx)
142 mutex_lock(&kctx->event_mutex);
143 kctx->event_closed = MALI_TRUE;
144 mutex_unlock(&kctx->event_mutex);
145 kbase_event_wakeup(kctx);
148 mali_error kbase_event_init(kbase_context *kctx)
150 KBASE_DEBUG_ASSERT(kctx);
152 INIT_LIST_HEAD(&kctx->event_list);
153 mutex_init(&kctx->event_mutex);
154 kctx->event_closed = MALI_FALSE;
155 kctx->event_workq = alloc_workqueue("kbase_event", WQ_MEM_RECLAIM, 1);
157 if (NULL == kctx->event_workq)
158 return MALI_ERROR_FUNCTION_FAILED;
160 return MALI_ERROR_NONE;
163 KBASE_EXPORT_TEST_API(kbase_event_init)
165 void kbase_event_cleanup(kbase_context *kctx)
167 KBASE_DEBUG_ASSERT(kctx);
168 KBASE_DEBUG_ASSERT(kctx->event_workq);
170 flush_workqueue(kctx->event_workq);
171 destroy_workqueue(kctx->event_workq);
173 /* We use kbase_event_dequeue to remove the remaining events as that
174 * deals with all the cleanup needed for the atoms.
176 * Note: use of kctx->event_list without a lock is safe because this must be the last
177 * thread using it (because we're about to terminate the lock)
179 while (!list_empty(&kctx->event_list)) {
180 base_jd_event_v2 event;
181 kbase_event_dequeue(kctx, &event);
185 KBASE_EXPORT_TEST_API(kbase_event_cleanup)