Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * System Control and Management Interface (SCMI) Reset Protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2019-2020 ARM Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #define pr_fmt(fmt) "SCMI Notifications RESET - " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/scmi_protocol.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "notify.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) enum scmi_reset_protocol_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	RESET_DOMAIN_ATTRIBUTES = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	RESET = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	RESET_NOTIFY = 0x5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define NUM_RESET_DOMAIN_MASK	0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define RESET_NOTIFY_ENABLE	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) struct scmi_msg_resp_reset_domain_attributes {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	__le32 attributes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define SUPPORTS_ASYNC_RESET(x)		((x) & BIT(31))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define SUPPORTS_NOTIFY_RESET(x)	((x) & BIT(30))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	__le32 latency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	    u8 name[SCMI_MAX_STR_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) struct scmi_msg_reset_domain_reset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	__le32 domain_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	__le32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define AUTONOMOUS_RESET	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define EXPLICIT_RESET_ASSERT	BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define ASYNCHRONOUS_RESET	BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	__le32 reset_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define ARCH_COLD_RESET		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) struct scmi_msg_reset_notify {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	__le32 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	__le32 event_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define RESET_TP_NOTIFY_ALL	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) struct scmi_reset_issued_notify_payld {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	__le32 agent_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	__le32 domain_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	__le32 reset_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) struct reset_dom_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	bool async_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	bool reset_notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	u32 latency_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	char name[SCMI_MAX_STR_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) struct scmi_reset_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	int num_domains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct reset_dom_info *dom_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) static int scmi_reset_attributes_get(const struct scmi_protocol_handle *ph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 				     struct scmi_reset_info *pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct scmi_xfer *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	u32 attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 				      0, sizeof(attr), &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	ret = ph->xops->do_xfer(ph, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		attr = get_unaligned_le32(t->rx.buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		pi->num_domains = attr & NUM_RESET_DOMAIN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	ph->xops->xfer_put(ph, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) scmi_reset_domain_attributes_get(const struct scmi_protocol_handle *ph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 				 u32 domain, struct reset_dom_info *dom_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	struct scmi_xfer *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	struct scmi_msg_resp_reset_domain_attributes *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	ret = ph->xops->xfer_get_init(ph, RESET_DOMAIN_ATTRIBUTES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 				      sizeof(domain), sizeof(*attr), &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	put_unaligned_le32(domain, t->tx.buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	attr = t->rx.buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	ret = ph->xops->do_xfer(ph, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		u32 attributes = le32_to_cpu(attr->attributes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		dom_info->async_reset = SUPPORTS_ASYNC_RESET(attributes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		dom_info->reset_notify = SUPPORTS_NOTIFY_RESET(attributes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		dom_info->latency_us = le32_to_cpu(attr->latency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		if (dom_info->latency_us == U32_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			dom_info->latency_us = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	ph->xops->xfer_put(ph, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int scmi_reset_num_domains_get(const struct scmi_protocol_handle *ph)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	struct scmi_reset_info *pi = ph->get_priv(ph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	return pi->num_domains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static char *scmi_reset_name_get(const struct scmi_protocol_handle *ph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 				 u32 domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	struct scmi_reset_info *pi = ph->get_priv(ph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	struct reset_dom_info *dom = pi->dom_info + domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	return dom->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static int scmi_reset_latency_get(const struct scmi_protocol_handle *ph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 				  u32 domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	struct scmi_reset_info *pi = ph->get_priv(ph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct reset_dom_info *dom = pi->dom_info + domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	return dom->latency_us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			     u32 flags, u32 state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct scmi_xfer *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	struct scmi_msg_reset_domain_reset *dom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	struct scmi_reset_info *pi = ph->get_priv(ph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	struct reset_dom_info *rdom = pi->dom_info + domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (rdom->async_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		flags |= ASYNCHRONOUS_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	ret = ph->xops->xfer_get_init(ph, RESET, sizeof(*dom), 0, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	dom = t->tx.buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	dom->domain_id = cpu_to_le32(domain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	dom->flags = cpu_to_le32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	dom->reset_state = cpu_to_le32(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	if (rdom->async_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		ret = ph->xops->do_xfer_with_response(ph, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		ret = ph->xops->do_xfer(ph, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	ph->xops->xfer_put(ph, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static int scmi_reset_domain_reset(const struct scmi_protocol_handle *ph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 				   u32 domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	return scmi_domain_reset(ph, domain, AUTONOMOUS_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 				 ARCH_COLD_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) scmi_reset_domain_assert(const struct scmi_protocol_handle *ph, u32 domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	return scmi_domain_reset(ph, domain, EXPLICIT_RESET_ASSERT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 				 ARCH_COLD_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) scmi_reset_domain_deassert(const struct scmi_protocol_handle *ph, u32 domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	return scmi_domain_reset(ph, domain, 0, ARCH_COLD_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static const struct scmi_reset_proto_ops reset_proto_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	.num_domains_get = scmi_reset_num_domains_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	.name_get = scmi_reset_name_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	.latency_get = scmi_reset_latency_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	.reset = scmi_reset_domain_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	.assert = scmi_reset_domain_assert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	.deassert = scmi_reset_domain_deassert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static int scmi_reset_notify(const struct scmi_protocol_handle *ph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			     u32 domain_id, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	u32 evt_cntl = enable ? RESET_TP_NOTIFY_ALL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	struct scmi_xfer *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	struct scmi_msg_reset_notify *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	ret = ph->xops->xfer_get_init(ph, RESET_NOTIFY, sizeof(*cfg), 0, &t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	cfg = t->tx.buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	cfg->id = cpu_to_le32(domain_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	cfg->event_control = cpu_to_le32(evt_cntl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	ret = ph->xops->do_xfer(ph, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	ph->xops->xfer_put(ph, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int scmi_reset_set_notify_enabled(const struct scmi_protocol_handle *ph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 					 u8 evt_id, u32 src_id, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	ret = scmi_reset_notify(ph, src_id, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		pr_debug("FAIL_ENABLED - evt[%X] dom[%d] - ret:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			 evt_id, src_id, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) scmi_reset_fill_custom_report(const struct scmi_protocol_handle *ph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			      u8 evt_id, ktime_t timestamp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			      const void *payld, size_t payld_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			      void *report, u32 *src_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	const struct scmi_reset_issued_notify_payld *p = payld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	struct scmi_reset_issued_report *r = report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	if (evt_id != SCMI_EVENT_RESET_ISSUED || sizeof(*p) != payld_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	r->timestamp = timestamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	r->agent_id = le32_to_cpu(p->agent_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	r->domain_id = le32_to_cpu(p->domain_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	r->reset_state = le32_to_cpu(p->reset_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	*src_id = r->domain_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int scmi_reset_get_num_sources(const struct scmi_protocol_handle *ph)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	struct scmi_reset_info *pinfo = ph->get_priv(ph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	if (!pinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	return pinfo->num_domains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static const struct scmi_event reset_events[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		.id = SCMI_EVENT_RESET_ISSUED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		.max_payld_sz = sizeof(struct scmi_reset_issued_notify_payld),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		.max_report_sz = sizeof(struct scmi_reset_issued_report),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static const struct scmi_event_ops reset_event_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	.get_num_sources = scmi_reset_get_num_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	.set_notify_enabled = scmi_reset_set_notify_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	.fill_custom_report = scmi_reset_fill_custom_report,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static const struct scmi_protocol_events reset_protocol_events = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	.queue_sz = SCMI_PROTO_QUEUE_SZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	.ops = &reset_event_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	.evts = reset_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	.num_events = ARRAY_SIZE(reset_events),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int scmi_reset_protocol_init(const struct scmi_protocol_handle *ph)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	int domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	struct scmi_reset_info *pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	ph->xops->version_get(ph, &version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	dev_dbg(ph->dev, "Reset Version %d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	pinfo = devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	if (!pinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	scmi_reset_attributes_get(ph, pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 				       sizeof(*pinfo->dom_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (!pinfo->dom_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	for (domain = 0; domain < pinfo->num_domains; domain++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		struct reset_dom_info *dom = pinfo->dom_info + domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		scmi_reset_domain_attributes_get(ph, domain, dom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	pinfo->version = version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	return ph->set_priv(ph, pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static const struct scmi_protocol scmi_reset = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	.id = SCMI_PROTOCOL_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	.init_instance = &scmi_reset_protocol_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	.ops = &reset_proto_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	.events = &reset_protocol_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(reset, scmi_reset)