tizen 2.4 release
[kernel/linux-3.0.git] / drivers / gpu / arm / mali400 / mali / linux / mali_osk_wq.c
1 /*
2  * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
3  *
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  *
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10
11 /**
12  * @file mali_osk_wq.c
13  * Implementation of the OS abstraction layer for the kernel device driver
14  */
15
16 #include <linux/slab.h> /* For memory allocation */
17 #include <linux/workqueue.h>
18 #include <linux/version.h>
19
20 #include "mali_osk.h"
21 #include "mali_kernel_common.h"
22 #include "mali_kernel_license.h"
23 #include "mali_kernel_linux.h"
24
25 typedef struct _mali_osk_wq_work_t_struct
26 {
27         _mali_osk_wq_work_handler_t handler;
28         void *data;
29         struct work_struct work_handle;
30 } mali_osk_wq_work_object_t;
31
32 #if MALI_LICENSE_IS_GPL
33 struct workqueue_struct *mali_wq = NULL;
34 #endif
35
36 static void _mali_osk_wq_work_func ( struct work_struct *work );
37
38 _mali_osk_errcode_t _mali_osk_wq_init(void)
39 {
40 #if MALI_LICENSE_IS_GPL
41         MALI_DEBUG_ASSERT(NULL == mali_wq);
42
43 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
44         mali_wq = alloc_workqueue("mali", WQ_UNBOUND, 0);
45 #else
46         mali_wq = create_workqueue("mali");
47 #endif
48         if(NULL == mali_wq)
49         {
50                 MALI_PRINT_ERROR(("Unable to create Mali workqueue\n"));
51                 return _MALI_OSK_ERR_FAULT;
52         }
53 #endif
54
55         return _MALI_OSK_ERR_OK;
56 }
57
58 void _mali_osk_wq_flush(void)
59 {
60 #if MALI_LICENSE_IS_GPL
61        flush_workqueue(mali_wq);
62 #else
63        flush_scheduled_work();
64 #endif
65 }
66
67 void _mali_osk_wq_term(void)
68 {
69 #if MALI_LICENSE_IS_GPL
70         MALI_DEBUG_ASSERT(NULL != mali_wq);
71
72         flush_workqueue(mali_wq);
73         destroy_workqueue(mali_wq);
74         mali_wq = NULL;
75 #else
76         flush_scheduled_work();
77 #endif
78 }
79
80 _mali_osk_wq_work_t *_mali_osk_wq_create_work( _mali_osk_wq_work_handler_t handler, void *data )
81 {
82         mali_osk_wq_work_object_t *work = kmalloc(sizeof(mali_osk_wq_work_object_t), GFP_KERNEL);
83
84         if (NULL == work) return NULL;
85
86         work->handler = handler;
87         work->data = data;
88
89         INIT_WORK( &work->work_handle, _mali_osk_wq_work_func );
90
91         return work;
92 }
93
94 void _mali_osk_wq_delete_work( _mali_osk_wq_work_t *work )
95 {
96         mali_osk_wq_work_object_t *work_object = (mali_osk_wq_work_object_t *)work;
97         _mali_osk_wq_flush();
98         kfree(work_object);
99 }
100
101 void _mali_osk_wq_schedule_work( _mali_osk_wq_work_t *work )
102 {
103         mali_osk_wq_work_object_t *work_object = (mali_osk_wq_work_object_t *)work;
104 #if MALI_LICENSE_IS_GPL
105         queue_work(mali_wq, &work_object->work_handle);
106 #else
107         schedule_work(&work_object->work_handle);
108 #endif
109 }
110
111 static void _mali_osk_wq_work_func ( struct work_struct *work )
112 {
113         mali_osk_wq_work_object_t *work_object;
114
115         work_object = _MALI_OSK_CONTAINER_OF(work, mali_osk_wq_work_object_t, work_handle);
116         work_object->handler(work_object->data);
117 }
118