diff options
Diffstat (limited to 'drivers/firmware/arm_scmi/power.c')
-rw-r--r-- | drivers/firmware/arm_scmi/power.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/drivers/firmware/arm_scmi/power.c b/drivers/firmware/arm_scmi/power.c index e378a3eb0d07..964882cc8747 100644 --- a/drivers/firmware/arm_scmi/power.c +++ b/drivers/firmware/arm_scmi/power.c @@ -18,6 +18,7 @@ enum scmi_power_protocol_cmd { POWER_STATE_SET = 0x4, POWER_STATE_GET = 0x5, POWER_STATE_NOTIFY = 0x6, + POWER_DOMAIN_NAME_GET = 0x8, }; struct scmi_msg_resp_power_attributes { @@ -33,7 +34,8 @@ struct scmi_msg_resp_power_domain_attributes { #define SUPPORTS_STATE_SET_NOTIFY(x) ((x) & BIT(31)) #define SUPPORTS_STATE_SET_ASYNC(x) ((x) & BIT(30)) #define SUPPORTS_STATE_SET_SYNC(x) ((x) & BIT(29)) - u8 name[SCMI_MAX_STR_SIZE]; +#define SUPPORTS_EXTENDED_NAMES(x) ((x) & BIT(27)) + u8 name[SCMI_SHORT_NAME_MAX_SIZE]; }; struct scmi_power_set_state { @@ -97,9 +99,11 @@ static int scmi_power_attributes_get(const struct scmi_protocol_handle *ph, static int scmi_power_domain_attributes_get(const struct scmi_protocol_handle *ph, - u32 domain, struct power_dom_info *dom_info) + u32 domain, struct power_dom_info *dom_info, + u32 version) { int ret; + u32 flags; struct scmi_xfer *t; struct scmi_msg_resp_power_domain_attributes *attr; @@ -113,15 +117,26 @@ scmi_power_domain_attributes_get(const struct scmi_protocol_handle *ph, ret = ph->xops->do_xfer(ph, t); if (!ret) { - u32 flags = le32_to_cpu(attr->flags); + flags = le32_to_cpu(attr->flags); dom_info->state_set_notify = SUPPORTS_STATE_SET_NOTIFY(flags); dom_info->state_set_async = SUPPORTS_STATE_SET_ASYNC(flags); dom_info->state_set_sync = SUPPORTS_STATE_SET_SYNC(flags); strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE); } - ph->xops->xfer_put(ph, t); + + /* + * If supported overwrite short name with the extended one; + * on error just carry on and use already provided short name. + */ + if (!ret && PROTOCOL_REV_MAJOR(version) >= 0x3 && + SUPPORTS_EXTENDED_NAMES(flags)) { + ph->hops->extended_name_get(ph, POWER_DOMAIN_NAME_GET, + domain, dom_info->name, + SCMI_MAX_STR_SIZE); + } + return ret; } @@ -308,7 +323,7 @@ static int scmi_power_protocol_init(const struct scmi_protocol_handle *ph) for (domain = 0; domain < pinfo->num_domains; domain++) { struct power_dom_info *dom = pinfo->dom_info + domain; - scmi_power_domain_attributes_get(ph, domain, dom); + scmi_power_domain_attributes_get(ph, domain, dom, version); } pinfo->version = version; |