Commit 7097f298 authored by Cristian Marussi's avatar Cristian Marussi Committed by Sudeep Holla

firmware: arm_scmi: Add SCMI v3.1 System Power extensions

Add support for SCMIv3.1 System Power optional timeout field while
dispatching SYSTEM_POWER_STATE_NOTIFIER notification.

Link: https://lore.kernel.org/r/20220704101933.2981635-3-cristian.marussi@arm.comSigned-off-by: default avatarCristian Marussi <cristian.marussi@arm.com>
Signed-off-by: default avatarSudeep Holla <sudeep.holla@arm.com>
parent a0db3962
...@@ -27,10 +27,12 @@ struct scmi_system_power_state_notifier_payld { ...@@ -27,10 +27,12 @@ struct scmi_system_power_state_notifier_payld {
__le32 agent_id; __le32 agent_id;
__le32 flags; __le32 flags;
__le32 system_state; __le32 system_state;
__le32 timeout;
}; };
struct scmi_system_info { struct scmi_system_info {
u32 version; u32 version;
bool graceful_timeout_supported;
}; };
static int scmi_system_request_notify(const struct scmi_protocol_handle *ph, static int scmi_system_request_notify(const struct scmi_protocol_handle *ph,
...@@ -72,17 +74,27 @@ scmi_system_fill_custom_report(const struct scmi_protocol_handle *ph, ...@@ -72,17 +74,27 @@ scmi_system_fill_custom_report(const struct scmi_protocol_handle *ph,
const void *payld, size_t payld_sz, const void *payld, size_t payld_sz,
void *report, u32 *src_id) void *report, u32 *src_id)
{ {
size_t expected_sz;
const struct scmi_system_power_state_notifier_payld *p = payld; const struct scmi_system_power_state_notifier_payld *p = payld;
struct scmi_system_power_state_notifier_report *r = report; struct scmi_system_power_state_notifier_report *r = report;
struct scmi_system_info *pinfo = ph->get_priv(ph);
expected_sz = pinfo->graceful_timeout_supported ?
sizeof(*p) : sizeof(*p) - sizeof(__le32);
if (evt_id != SCMI_EVENT_SYSTEM_POWER_STATE_NOTIFIER || if (evt_id != SCMI_EVENT_SYSTEM_POWER_STATE_NOTIFIER ||
sizeof(*p) != payld_sz) payld_sz != expected_sz)
return NULL; return NULL;
r->timestamp = timestamp; r->timestamp = timestamp;
r->agent_id = le32_to_cpu(p->agent_id); r->agent_id = le32_to_cpu(p->agent_id);
r->flags = le32_to_cpu(p->flags); r->flags = le32_to_cpu(p->flags);
r->system_state = le32_to_cpu(p->system_state); r->system_state = le32_to_cpu(p->system_state);
if (pinfo->graceful_timeout_supported &&
r->system_state == SCMI_SYSTEM_SHUTDOWN &&
SCMI_SYSPOWER_IS_REQUEST_GRACEFUL(r->flags))
r->timeout = le32_to_cpu(p->timeout);
else
r->timeout = 0x00;
*src_id = 0; *src_id = 0;
return r; return r;
...@@ -129,6 +141,9 @@ static int scmi_system_protocol_init(const struct scmi_protocol_handle *ph) ...@@ -129,6 +141,9 @@ static int scmi_system_protocol_init(const struct scmi_protocol_handle *ph)
return -ENOMEM; return -ENOMEM;
pinfo->version = version; pinfo->version = version;
if (PROTOCOL_REV_MAJOR(pinfo->version) >= 0x2)
pinfo->graceful_timeout_supported = true;
return ph->set_priv(ph, pinfo); return ph->set_priv(ph, pinfo);
} }
......
...@@ -781,8 +781,10 @@ struct scmi_clock_rate_notif_report { ...@@ -781,8 +781,10 @@ struct scmi_clock_rate_notif_report {
struct scmi_system_power_state_notifier_report { struct scmi_system_power_state_notifier_report {
ktime_t timestamp; ktime_t timestamp;
unsigned int agent_id; unsigned int agent_id;
#define SCMI_SYSPOWER_IS_REQUEST_GRACEFUL(flags) ((flags) & BIT(0))
unsigned int flags; unsigned int flags;
unsigned int system_state; unsigned int system_state;
unsigned int timeout;
}; };
struct scmi_perf_limits_report { struct scmi_perf_limits_report {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment