1 /*
2  * Copyright (c) 2019 Peter Bigot Consulting, LLC
3  * Copyright (c) 2020 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/kernel.h>
9 #include <zephyr/sys/notify.h>
10 
sys_notify_validate(struct sys_notify * notify)11 int sys_notify_validate(struct sys_notify *notify)
12 {
13 	int rv = 0;
14 
15 	if (notify == NULL) {
16 		return -EINVAL;
17 	}
18 
19 	/* Validate configuration based on mode */
20 	switch (sys_notify_get_method(notify)) {
21 	case SYS_NOTIFY_METHOD_SPINWAIT:
22 		break;
23 	case SYS_NOTIFY_METHOD_CALLBACK:
24 		if (notify->method.callback == NULL) {
25 			rv = -EINVAL;
26 		}
27 		break;
28 #ifdef CONFIG_POLL
29 	case SYS_NOTIFY_METHOD_SIGNAL:
30 		if (notify->method.signal == NULL) {
31 			rv = -EINVAL;
32 		}
33 		break;
34 #endif /* CONFIG_POLL */
35 	default:
36 		rv = -EINVAL;
37 		break;
38 	}
39 
40 	/* Clear the result here instead of in all callers. */
41 	if (rv == 0) {
42 		notify->result = 0;
43 	}
44 
45 	return rv;
46 }
47 
sys_notify_finalize(struct sys_notify * notify,int res)48 sys_notify_generic_callback sys_notify_finalize(struct sys_notify *notify,
49 						    int res)
50 {
51 	struct k_poll_signal *sig = NULL;
52 	sys_notify_generic_callback rv = NULL;
53 	uint32_t method = sys_notify_get_method(notify);
54 
55 	/* Store the result and capture secondary notification
56 	 * information.
57 	 */
58 	notify->result = res;
59 	switch (method) {
60 	case SYS_NOTIFY_METHOD_SPINWAIT:
61 		break;
62 	case SYS_NOTIFY_METHOD_CALLBACK:
63 		rv = notify->method.callback;
64 		break;
65 	case SYS_NOTIFY_METHOD_SIGNAL:
66 		sig = notify->method.signal;
67 		break;
68 	default:
69 		__ASSERT_NO_MSG(false);
70 	}
71 
72 	/* Mark completion by clearing the flags field to the
73 	 * completed state, releasing any spin-waiters, then complete
74 	 * secondary notification.
75 	 */
76 	compiler_barrier();
77 	notify->flags = SYS_NOTIFY_METHOD_COMPLETED;
78 
79 	if (IS_ENABLED(CONFIG_POLL) && (sig != NULL)) {
80 		k_poll_signal_raise(sig, res);
81 	}
82 
83 	return rv;
84 }
85