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