xref: /optee_os/core/drivers/rstctrl/stm32_rstctrl.c (revision 3ef177b4f15359331455239c7cf374bd2b8a7f67)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2021-2022, Linaro Limited
4  * Copyright (c) 2018-2022, STMicroelectronics
5  */
6 
7 #include <drivers/rstctrl.h>
8 #include <mm/core_memprot.h>
9 #include <stm32_util.h>
10 
11 #include "stm32_rstctrl.h"
12 
13 static struct stm32_reset_data *stm32_reset_pdata;
14 
15 static SLIST_HEAD(, stm32_rstline) stm32_rst_list =
16 	SLIST_HEAD_INITIALIZER(stm32_rst_list);
17 
18 static struct stm32_rstline *find_rstctrl_device(unsigned int control_id)
19 {
20 	struct stm32_rstline *stm32_rstline = NULL;
21 
22 	SLIST_FOREACH(stm32_rstline, &stm32_rst_list, link)
23 		if (stm32_rstline->id == control_id)
24 			break;
25 
26 	return stm32_rstline;
27 }
28 
29 static struct
30 stm32_rstline *find_or_allocate_rstline(unsigned int binding_id,
31 					const struct stm32_reset_data *pdata)
32 {
33 	struct stm32_rstline *stm32_rstline = find_rstctrl_device(binding_id);
34 
35 	if (stm32_rstline)
36 		return stm32_rstline;
37 
38 	stm32_rstline = calloc(1, sizeof(*stm32_rstline));
39 	if (stm32_rstline) {
40 		assert(pdata->get_rstctrl_ops);
41 
42 		stm32_rstline->id = binding_id;
43 		stm32_rstline->rstctrl.ops = pdata->get_rstctrl_ops(binding_id);
44 
45 		SLIST_INSERT_HEAD(&stm32_rst_list, stm32_rstline, link);
46 	}
47 
48 	return stm32_rstline;
49 }
50 
51 struct stm32_rstline *to_stm32_rstline(struct rstctrl *rstctrl)
52 {
53 	assert(rstctrl);
54 
55 	return container_of(rstctrl, struct stm32_rstline, rstctrl);
56 }
57 
58 struct rstctrl *stm32mp_rcc_reset_id_to_rstctrl(unsigned int binding_id)
59 {
60 	struct stm32_rstline *rstline = NULL;
61 
62 	rstline = find_or_allocate_rstline(binding_id, stm32_reset_pdata);
63 
64 	assert(rstline);
65 	return &rstline->rstctrl;
66 }
67 
68 static TEE_Result stm32_rstctrl_get_dev(struct dt_pargs *arg,
69 					void *priv_data,
70 					struct rstctrl **out_device)
71 {
72 	struct stm32_rstline *stm32_rstline = NULL;
73 	uintptr_t control_id = 0;
74 
75 	if (arg->args_count != 1)
76 		return TEE_ERROR_BAD_PARAMETERS;
77 
78 	control_id = arg->args[0];
79 
80 	stm32_rstline = find_or_allocate_rstline(control_id, priv_data);
81 	if (!stm32_rstline)
82 		return TEE_ERROR_OUT_OF_MEMORY;
83 
84 	*out_device = &stm32_rstline->rstctrl;
85 
86 	return TEE_SUCCESS;
87 }
88 
89 TEE_Result stm32_rstctrl_provider_probe(const void *fdt, int offs,
90 					const void *compat_data)
91 {
92 	struct dt_node_info info = { };
93 
94 	stm32_reset_pdata = (struct stm32_reset_data *)compat_data;
95 
96 	fdt_fill_device_info(fdt, &info, offs);
97 
98 	assert(info.reg == RCC_BASE &&
99 	       info.reg_size != DT_INFO_INVALID_REG_SIZE);
100 
101 	return rstctrl_register_provider(fdt, offs, stm32_rstctrl_get_dev,
102 					 stm32_reset_pdata);
103 }
104