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 <kernel.h> 9 #include <sys/notify.h> 10 sys_notify_validate(struct sys_notify * notify)11int 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)48sys_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