1 /*
2  * Copyright (c) 2017, Texas Instruments Incorporated
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr.h>
8 #include <sys/__assert.h>
9 #include <kernel/zephyr/dpl/dpl.h>
10 #include <ti/drivers/dpl/MutexP.h>
11 
12 /*
13  * Zephyr kernel object pools:
14  *
15  * This bit of code enables the simplelink host driver, which assumes dynamic
16  * allocation of kernel objects (semaphores, mutexes, hwis), to be
17  * more easily ported to Zephyr (which supports static allocation).
18  *
19  * It leverages the Zephyr memory slab, enabling us to define a mutex object
20  * pool for use by the SimpleLink host driver.
21  */
22 
23 /* Define a Mutex pool: */
24 #define DPL_MAX_MUTEXES	 4  /* From simplelink driver code inspection */
25 K_MEM_SLAB_DEFINE(mutex_slab, sizeof(struct k_mutex), DPL_MAX_MUTEXES,\
26 		  MEM_ALIGN);
27 
dpl_mutex_pool_alloc()28 static struct k_mutex *dpl_mutex_pool_alloc()
29 {
30 	struct k_mutex *mutex_ptr = NULL;
31 
32 	if (k_mem_slab_alloc(&mutex_slab, (void **)&mutex_ptr,
33 			     K_NO_WAIT) < 0) {
34 		/*
35 		 * We assert, as this is a logic error, due to a change in #
36 		 * of mutexes needed by the simplelink driver. In that case,
37 		 * the mutex pool must be increased programmatically to match.
38 		 */
39 		 __ASSERT(0, "Increase size of DPL mutex pool");
40 	}
41 	return mutex_ptr;
42 }
43 
dpl_mutex_pool_free(struct k_mutex * mutex)44 static MutexP_Status dpl_mutex_pool_free(struct k_mutex *mutex)
45 {
46 	k_mem_slab_free(&mutex_slab, (void **)&mutex);
47 	return MutexP_OK;
48 }
49 
MutexP_create(MutexP_Params * params)50 MutexP_Handle MutexP_create(MutexP_Params *params)
51 {
52 	struct k_mutex *mutex;
53 
54 	ARG_UNUSED(params);
55 
56 	mutex = dpl_mutex_pool_alloc();
57 	__ASSERT(mutex, "MutexP_create failed\r\n");
58 
59 	if (mutex) {
60 		k_mutex_init(mutex);
61 	}
62 	return ((MutexP_Handle)mutex);
63 }
64 
MutexP_delete(MutexP_Handle handle)65 void MutexP_delete(MutexP_Handle handle)
66 {
67 	/* No way in Zephyr to "reset" the lock, so just re-init: */
68 	k_mutex_init((struct k_mutex *)handle);
69 
70 	dpl_mutex_pool_free((struct k_mutex *)handle);
71 }
72 
MutexP_lock(MutexP_Handle handle)73 uintptr_t MutexP_lock(MutexP_Handle handle)
74 {
75 	unsigned int key = 0;
76 	int retval;
77 
78 	retval = k_mutex_lock((struct k_mutex *)handle, K_FOREVER);
79 	__ASSERT(retval == 0,
80 		 "MutexP_lock: retval: %d\r\n", retval);
81 
82 	return ((uintptr_t)key);
83 }
84 
MutexP_Params_init(MutexP_Params * params)85 void MutexP_Params_init(MutexP_Params *params)
86 {
87 	params->callback = NULL;
88 }
89 
MutexP_unlock(MutexP_Handle handle,uintptr_t key)90 void MutexP_unlock(MutexP_Handle handle, uintptr_t key)
91 {
92 	ARG_UNUSED(key);
93 
94 	k_mutex_unlock((struct k_mutex *)handle);
95 }
96