summaryrefslogtreecommitdiff
path: root/drivers/firmware/arm_scmi/driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware/arm_scmi/driver.c')
-rw-r--r--drivers/firmware/arm_scmi/driver.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 09371f40d61f..a9f70e6e58ac 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -85,6 +85,7 @@ struct scmi_xfers_info {
* @gid: A reference for per-protocol devres management.
* @users: A refcount to track effective users of this protocol.
* @priv: Reference for optional protocol private data.
+ * @version: Protocol version supported by the platform as detected at runtime.
* @ph: An embedded protocol handle that will be passed down to protocol
* initialization code to identify this instance.
*
@@ -97,6 +98,7 @@ struct scmi_protocol_instance {
void *gid;
refcount_t users;
void *priv;
+ unsigned int version;
struct scmi_protocol_handle ph;
};
@@ -1392,15 +1394,17 @@ static int version_get(const struct scmi_protocol_handle *ph, u32 *version)
*
* @ph: A reference to the protocol handle.
* @priv: The private data to set.
+ * @version: The detected protocol version for the core to register.
*
* Return: 0 on Success
*/
static int scmi_set_protocol_priv(const struct scmi_protocol_handle *ph,
- void *priv)
+ void *priv, u32 version)
{
struct scmi_protocol_instance *pi = ph_to_pi(ph);
pi->priv = priv;
+ pi->version = version;
return 0;
}
@@ -1438,6 +1442,7 @@ struct scmi_msg_resp_domain_name_get {
* @ph: A protocol handle reference.
* @cmd_id: The specific command ID to use.
* @res_id: The specific resource ID to use.
+ * @flags: A pointer to specific flags to use, if any.
* @name: A pointer to the preallocated area where the retrieved name will be
* stored as a NULL terminated string.
* @len: The len in bytes of the @name char array.
@@ -1445,19 +1450,22 @@ struct scmi_msg_resp_domain_name_get {
* Return: 0 on Succcess
*/
static int scmi_common_extended_name_get(const struct scmi_protocol_handle *ph,
- u8 cmd_id, u32 res_id, char *name,
- size_t len)
+ u8 cmd_id, u32 res_id, u32 *flags,
+ char *name, size_t len)
{
int ret;
+ size_t txlen;
struct scmi_xfer *t;
struct scmi_msg_resp_domain_name_get *resp;
- ret = ph->xops->xfer_get_init(ph, cmd_id, sizeof(res_id),
- sizeof(*resp), &t);
+ txlen = !flags ? sizeof(res_id) : sizeof(res_id) + sizeof(*flags);
+ ret = ph->xops->xfer_get_init(ph, cmd_id, txlen, sizeof(*resp), &t);
if (ret)
goto out;
put_unaligned_le32(res_id, t->tx.buf);
+ if (flags)
+ put_unaligned_le32(*flags, t->tx.buf + sizeof(res_id));
resp = t->rx.buf;
ret = ph->xops->do_xfer(ph, t);
@@ -1845,6 +1853,12 @@ scmi_alloc_init_protocol_instance(struct scmi_info *info,
devres_close_group(handle->dev, pi->gid);
dev_dbg(handle->dev, "Initialized protocol: 0x%X\n", pi->proto->id);
+ if (pi->version > proto->supported_version)
+ dev_warn(handle->dev,
+ "Detected UNSUPPORTED higher version 0x%X for protocol 0x%X."
+ "Backward compatibility is NOT assured.\n",
+ pi->version, pi->proto->id);
+
return pi;
clean: