xref: /OK3568_Linux_fs/kernel/drivers/gpu/arm/mali400/mali/common/mali_spinlock_reentrant.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2013, 2016-2017 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 #include "mali_spinlock_reentrant.h"
12 
13 #include "mali_osk.h"
14 #include "mali_kernel_common.h"
15 
mali_spinlock_reentrant_init(_mali_osk_lock_order_t lock_order)16 struct mali_spinlock_reentrant *mali_spinlock_reentrant_init(_mali_osk_lock_order_t lock_order)
17 {
18 	struct mali_spinlock_reentrant *spinlock;
19 
20 	spinlock = _mali_osk_calloc(1, sizeof(struct mali_spinlock_reentrant));
21 	if (NULL == spinlock) {
22 		return NULL;
23 	}
24 
25 	spinlock->lock = _mali_osk_spinlock_irq_init(_MALI_OSK_LOCKFLAG_ORDERED, lock_order);
26 	if (NULL == spinlock->lock) {
27 		mali_spinlock_reentrant_term(spinlock);
28 		return NULL;
29 	}
30 
31 	return spinlock;
32 }
33 
mali_spinlock_reentrant_term(struct mali_spinlock_reentrant * spinlock)34 void mali_spinlock_reentrant_term(struct mali_spinlock_reentrant *spinlock)
35 {
36 	MALI_DEBUG_ASSERT_POINTER(spinlock);
37 	MALI_DEBUG_ASSERT(0 == spinlock->counter && 0 == spinlock->owner);
38 
39 	if (NULL != spinlock->lock) {
40 		_mali_osk_spinlock_irq_term(spinlock->lock);
41 	}
42 
43 	_mali_osk_free(spinlock);
44 }
45 
mali_spinlock_reentrant_wait(struct mali_spinlock_reentrant * spinlock,u32 tid)46 void mali_spinlock_reentrant_wait(struct mali_spinlock_reentrant *spinlock, u32 tid)
47 {
48 	MALI_DEBUG_ASSERT_POINTER(spinlock);
49 	MALI_DEBUG_ASSERT_POINTER(spinlock->lock);
50 	MALI_DEBUG_ASSERT(0 != tid);
51 
52 	MALI_DEBUG_PRINT(5, ("%s ^\n", __FUNCTION__));
53 
54 	if (tid != spinlock->owner) {
55 		_mali_osk_spinlock_irq_lock(spinlock->lock);
56 		MALI_DEBUG_ASSERT(0 == spinlock->owner && 0 == spinlock->counter);
57 		spinlock->owner = tid;
58 	}
59 
60 	MALI_DEBUG_PRINT(5, ("%s v\n", __FUNCTION__));
61 
62 	++spinlock->counter;
63 }
64 
mali_spinlock_reentrant_signal(struct mali_spinlock_reentrant * spinlock,u32 tid)65 void mali_spinlock_reentrant_signal(struct mali_spinlock_reentrant *spinlock, u32 tid)
66 {
67 	MALI_DEBUG_ASSERT_POINTER(spinlock);
68 	MALI_DEBUG_ASSERT_POINTER(spinlock->lock);
69 	MALI_DEBUG_ASSERT(0 != tid && tid == spinlock->owner);
70 
71 	--spinlock->counter;
72 	if (0 == spinlock->counter) {
73 		spinlock->owner = 0;
74 		MALI_DEBUG_PRINT(5, ("%s release last\n", __FUNCTION__));
75 		_mali_osk_spinlock_irq_unlock(spinlock->lock);
76 	}
77 }
78