2020-02-19 20:01:07 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2019 Peter Bigot Consulting, LLC
|
|
|
|
* Copyright (c) 2020 Nordic Semiconductor ASA
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
2022-05-06 17:23:05 +08:00
|
|
|
#include <zephyr/kernel.h>
|
|
|
|
#include <zephyr/sys/notify.h>
|
2020-02-19 20:01:07 +08:00
|
|
|
|
|
|
|
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;
|
2021-04-28 02:40:56 +08:00
|
|
|
sys_notify_generic_callback rv = NULL;
|
2020-05-28 00:26:57 +08:00
|
|
|
uint32_t method = sys_notify_get_method(notify);
|
2020-02-19 20:01:07 +08:00
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|