xref: /optee_os/core/include/kernel/mutex_pm_aware.h (revision 3a20c6612811bf408eca3316b49702b767803de2)
1*3a20c661SEtienne Carriere /* SPDX-License-Identifier: BSD-2-Clause */
2*3a20c661SEtienne Carriere /*
3*3a20c661SEtienne Carriere  * Copyright (c) 2024, STMicroelectronics
4*3a20c661SEtienne Carriere  */
5*3a20c661SEtienne Carriere #ifndef __KERNEL_MUTEX_PM_AWARE_H
6*3a20c661SEtienne Carriere #define __KERNEL_MUTEX_PM_AWARE_H
7*3a20c661SEtienne Carriere 
8*3a20c661SEtienne Carriere #include <kernel/mutex.h>
9*3a20c661SEtienne Carriere #include <kernel/spinlock.h>
10*3a20c661SEtienne Carriere 
11*3a20c661SEtienne Carriere /*
12*3a20c661SEtienne Carriere  * struct mutex_pm_aware - Mutex usable in PM atomic sequence
13*3a20c661SEtienne Carriere  *
14*3a20c661SEtienne Carriere  * Some resources need a mutex protection for runtime operations but are
15*3a20c661SEtienne Carriere  * also accessed during specific system power transition (PM power off,
16*3a20c661SEtienne Carriere  * suspend and resume) that operate in atomic execution environment where
17*3a20c661SEtienne Carriere  * non-secure world is not operational, for example in fastcall SMC entries
18*3a20c661SEtienne Carriere  * of the PSCI services. In such case we cannot take a mutex and we expect
19*3a20c661SEtienne Carriere  * the mutex is unlocked. Additionally a spinning lock is attempted to be
20*3a20c661SEtienne Carriere  * locked to check the resource access consistency.
21*3a20c661SEtienne Carriere  *
22*3a20c661SEtienne Carriere  * Core intentionally panics in case of unexpected resource access contention:
23*3a20c661SEtienne Carriere  * - When a thread requests a mutex held by a non-thread context;
24*3a20c661SEtienne Carriere  * - When a non-thread context requests a mutex held by a thread;
25*3a20c661SEtienne Carriere  * - When a non-thread context requests a mutex held by a non-thread context.
26*3a20c661SEtienne Carriere  */
27*3a20c661SEtienne Carriere struct mutex_pm_aware {
28*3a20c661SEtienne Carriere 	struct mutex mutex;	/* access protection in thread context */
29*3a20c661SEtienne Carriere 	unsigned int lock;	/* access consistency in PM context */
30*3a20c661SEtienne Carriere };
31*3a20c661SEtienne Carriere 
32*3a20c661SEtienne Carriere #define MUTEX_PM_AWARE_INITIALIZER { \
33*3a20c661SEtienne Carriere 		.mutex = MUTEX_INITIALIZER, \
34*3a20c661SEtienne Carriere 		.lock = SPINLOCK_UNLOCK, \
35*3a20c661SEtienne Carriere 	}
36*3a20c661SEtienne Carriere 
37*3a20c661SEtienne Carriere void mutex_pm_aware_init(struct mutex_pm_aware *m);
38*3a20c661SEtienne Carriere void mutex_pm_aware_destroy(struct mutex_pm_aware *m);
39*3a20c661SEtienne Carriere void mutex_pm_aware_lock(struct mutex_pm_aware *m);
40*3a20c661SEtienne Carriere void mutex_pm_aware_unlock(struct mutex_pm_aware *m);
41*3a20c661SEtienne Carriere 
42*3a20c661SEtienne Carriere #endif /*__KERNEL_MUTEX_PM_AWARE_H*/
43*3a20c661SEtienne Carriere 
44