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->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 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 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 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 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