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