xref: /optee_os/core/drivers/rstctrl/rstctrl.c (revision 9e3c57c88b0cdd41de57107725621c8c0857a838)
1c78b2c66SEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause
2c78b2c66SEtienne Carriere /*
3c78b2c66SEtienne Carriere  * Copyright (c) 2021, Linaro Limited
4c78b2c66SEtienne Carriere  */
5c78b2c66SEtienne Carriere 
6c78b2c66SEtienne Carriere #include <assert.h>
7c78b2c66SEtienne Carriere #include <drivers/rstctrl.h>
8c78b2c66SEtienne Carriere #include <io.h>
9c78b2c66SEtienne Carriere #include <kernel/spinlock.h>
10c78b2c66SEtienne Carriere #include <libfdt.h>
11c78b2c66SEtienne Carriere #include <stdint.h>
12c78b2c66SEtienne Carriere 
13c78b2c66SEtienne Carriere /* Global reset controller access lock */
14c78b2c66SEtienne Carriere 
rstctrl_get_exclusive(struct rstctrl * rstctrl)15c78b2c66SEtienne Carriere TEE_Result rstctrl_get_exclusive(struct rstctrl *rstctrl)
16c78b2c66SEtienne Carriere {
17c78b2c66SEtienne Carriere 	uint32_t exceptions = 0;
18c78b2c66SEtienne Carriere 	TEE_Result res = TEE_ERROR_ACCESS_CONFLICT;
19c78b2c66SEtienne Carriere 	static unsigned int rstctrl_lock = SPINLOCK_UNLOCK;
20c78b2c66SEtienne Carriere 
21c78b2c66SEtienne Carriere 	exceptions = cpu_spin_lock_xsave(&rstctrl_lock);
22c78b2c66SEtienne Carriere 
23c78b2c66SEtienne Carriere 	if (!rstctrl->exclusive) {
24c78b2c66SEtienne Carriere 		rstctrl->exclusive = true;
25c78b2c66SEtienne Carriere 		res = TEE_SUCCESS;
26c78b2c66SEtienne Carriere 	}
27c78b2c66SEtienne Carriere 
28c78b2c66SEtienne Carriere 	cpu_spin_unlock_xrestore(&rstctrl_lock, exceptions);
29c78b2c66SEtienne Carriere 
30c78b2c66SEtienne Carriere 	return res;
31c78b2c66SEtienne Carriere }
32c78b2c66SEtienne Carriere 
rstctrl_put_exclusive(struct rstctrl * rstctrl)33c78b2c66SEtienne Carriere void rstctrl_put_exclusive(struct rstctrl *rstctrl)
34c78b2c66SEtienne Carriere {
35c78b2c66SEtienne Carriere 	assert(rstctrl->exclusive);
36c78b2c66SEtienne Carriere 
37c78b2c66SEtienne Carriere 	WRITE_ONCE(rstctrl->exclusive, false);
38c78b2c66SEtienne Carriere }
39c78b2c66SEtienne Carriere 
rstctrl_dt_get_by_name(const void * fdt,int nodeoffset,const char * name,struct rstctrl ** rstctrl)40c78b2c66SEtienne Carriere TEE_Result rstctrl_dt_get_by_name(const void *fdt, int nodeoffset,
41c78b2c66SEtienne Carriere 				  const char *name, struct rstctrl **rstctrl)
42c78b2c66SEtienne Carriere {
43c78b2c66SEtienne Carriere 	int index = 0;
44c78b2c66SEtienne Carriere 
45c78b2c66SEtienne Carriere 	index = fdt_stringlist_search(fdt, nodeoffset, "reset-names", name);
46c78b2c66SEtienne Carriere 	if (index < 0)
47*7c102742SGatien Chevallier 		return TEE_ERROR_ITEM_NOT_FOUND;
48c78b2c66SEtienne Carriere 
49c78b2c66SEtienne Carriere 	return rstctrl_dt_get_by_index(fdt, nodeoffset, index, rstctrl);
50c78b2c66SEtienne Carriere }
51