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