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