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