1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2019-2020 Linaro Limited 4 */ 5 #include <common.h> 6 #include <dm.h> 7 #include <errno.h> 8 #include <reset-uclass.h> 9 #include <scmi_agent.h> 10 #include <scmi_protocols.h> 11 #include <asm/types.h> 12 13 static int scmi_reset_set_level(struct reset_ctl *rst, bool assert_not_deassert) 14 { 15 struct scmi_rd_reset_in in = { 16 .domain_id = rst->id, 17 .flags = assert_not_deassert ? SCMI_RD_RESET_FLAG_ASSERT : 0, 18 .reset_state = 0, 19 }; 20 struct scmi_rd_reset_out out; 21 struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_RESET_DOMAIN, 22 SCMI_RESET_DOMAIN_RESET, 23 in, out); 24 int ret; 25 26 ret = devm_scmi_process_msg(rst->dev->parent, &msg); 27 if (ret) 28 return ret; 29 30 return scmi_to_linux_errno(out.status); 31 } 32 33 static int scmi_reset_assert(struct reset_ctl *rst) 34 { 35 return scmi_reset_set_level(rst, true); 36 } 37 38 static int scmi_reset_deassert(struct reset_ctl *rst) 39 { 40 return scmi_reset_set_level(rst, false); 41 } 42 43 static int scmi_reset_request(struct reset_ctl *rst) 44 { 45 struct scmi_rd_attr_in in = { 46 .domain_id = rst->id, 47 }; 48 struct scmi_rd_attr_out out; 49 struct scmi_msg msg = SCMI_MSG_IN(SCMI_PROTOCOL_ID_RESET_DOMAIN, 50 SCMI_RESET_DOMAIN_ATTRIBUTES, 51 in, out); 52 int ret; 53 54 /* 55 * We don't really care about the attribute, just check 56 * the reset domain exists. 57 */ 58 ret = devm_scmi_process_msg(rst->dev->parent, &msg); 59 if (ret) 60 return ret; 61 62 return scmi_to_linux_errno(out.status); 63 } 64 65 static int scmi_reset_rfree(struct reset_ctl *rst) 66 { 67 return 0; 68 } 69 70 static const struct reset_ops scmi_reset_domain_ops = { 71 .request = scmi_reset_request, 72 .rfree = scmi_reset_rfree, 73 .rst_assert = scmi_reset_assert, 74 .rst_deassert = scmi_reset_deassert, 75 }; 76 77 U_BOOT_DRIVER(scmi_reset_domain) = { 78 .name = "scmi_reset_domain", 79 .id = UCLASS_RESET, 80 .ops = &scmi_reset_domain_ops, 81 }; 82