| /* |
| * Copyright (c) 2019 Peter Bigot Consulting, LLC |
| * Copyright (c) 2020 Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/kernel.h> |
| #include <zephyr/sys/notify.h> |
| |
| int sys_notify_validate(struct sys_notify *notify) |
| { |
| int rv = 0; |
| |
| if (notify == NULL) { |
| return -EINVAL; |
| } |
| |
| /* Validate configuration based on mode */ |
| switch (sys_notify_get_method(notify)) { |
| case SYS_NOTIFY_METHOD_SPINWAIT: |
| break; |
| case SYS_NOTIFY_METHOD_CALLBACK: |
| if (notify->method.callback == NULL) { |
| rv = -EINVAL; |
| } |
| break; |
| #ifdef CONFIG_POLL |
| case SYS_NOTIFY_METHOD_SIGNAL: |
| if (notify->method.signal == NULL) { |
| rv = -EINVAL; |
| } |
| break; |
| #endif /* CONFIG_POLL */ |
| default: |
| rv = -EINVAL; |
| break; |
| } |
| |
| /* Clear the result here instead of in all callers. */ |
| if (rv == 0) { |
| notify->result = 0; |
| } |
| |
| return rv; |
| } |
| |
| sys_notify_generic_callback sys_notify_finalize(struct sys_notify *notify, |
| int res) |
| { |
| struct k_poll_signal *sig = NULL; |
| sys_notify_generic_callback rv = NULL; |
| uint32_t method = sys_notify_get_method(notify); |
| |
| /* Store the result and capture secondary notification |
| * information. |
| */ |
| notify->result = res; |
| switch (method) { |
| case SYS_NOTIFY_METHOD_SPINWAIT: |
| break; |
| case SYS_NOTIFY_METHOD_CALLBACK: |
| rv = notify->method.callback; |
| break; |
| case SYS_NOTIFY_METHOD_SIGNAL: |
| sig = notify->method.signal; |
| break; |
| default: |
| __ASSERT_NO_MSG(false); |
| } |
| |
| /* Mark completion by clearing the flags field to the |
| * completed state, releasing any spin-waiters, then complete |
| * secondary notification. |
| */ |
| compiler_barrier(); |
| notify->flags = SYS_NOTIFY_METHOD_COMPLETED; |
| |
| if (IS_ENABLED(CONFIG_POLL) && (sig != NULL)) { |
| k_poll_signal_raise(sig, res); |
| } |
| |
| return rv; |
| } |