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
find_rstctrl_device(unsigned int control_id)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
find_or_allocate_rstline(unsigned int binding_id,const struct stm32_reset_data * pdata)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->data = pdata;
44 stm32_rstline->rstctrl.ops = pdata->get_rstctrl_ops(binding_id);
45
46 SLIST_INSERT_HEAD(&stm32_rst_list, stm32_rstline, link);
47 }
48
49 return stm32_rstline;
50 }
51
to_stm32_rstline(struct rstctrl * rstctrl)52 struct stm32_rstline *to_stm32_rstline(struct rstctrl *rstctrl)
53 {
54 assert(rstctrl);
55
56 return container_of(rstctrl, struct stm32_rstline, rstctrl);
57 }
58
stm32mp_rcc_reset_id_to_rstctrl(unsigned int binding_id)59 struct rstctrl *stm32mp_rcc_reset_id_to_rstctrl(unsigned int binding_id)
60 {
61 struct stm32_rstline *rstline = NULL;
62
63 rstline = find_or_allocate_rstline(binding_id, stm32_reset_pdata);
64
65 assert(rstline);
66 return &rstline->rstctrl;
67 }
68
stm32_rstctrl_get_dev(struct dt_pargs * arg,void * priv_data,struct rstctrl ** out_device)69 static TEE_Result stm32_rstctrl_get_dev(struct dt_pargs *arg,
70 void *priv_data,
71 struct rstctrl **out_device)
72 {
73 struct stm32_rstline *stm32_rstline = NULL;
74 uintptr_t control_id = 0;
75
76 if (arg->args_count != 1)
77 return TEE_ERROR_BAD_PARAMETERS;
78
79 control_id = arg->args[0];
80
81 stm32_rstline = find_or_allocate_rstline(control_id, priv_data);
82 if (!stm32_rstline)
83 return TEE_ERROR_OUT_OF_MEMORY;
84
85 *out_device = &stm32_rstline->rstctrl;
86
87 return TEE_SUCCESS;
88 }
89
stm32_rstctrl_provider_probe(const void * fdt,int offs,const void * compat_data)90 TEE_Result stm32_rstctrl_provider_probe(const void *fdt, int offs,
91 const void *compat_data)
92 {
93 struct dt_node_info info = { };
94
95 stm32_reset_pdata = (struct stm32_reset_data *)compat_data;
96
97 fdt_fill_device_info(fdt, &info, offs);
98
99 assert(info.reg == RCC_BASE &&
100 info.reg_size != DT_INFO_INVALID_REG_SIZE);
101
102 return rstctrl_register_provider(fdt, offs, stm32_rstctrl_get_dev,
103 stm32_reset_pdata);
104 }
105