diff options
Diffstat (limited to 'drivers/firmware/arm_scmi/driver.c')
-rw-r--r-- | drivers/firmware/arm_scmi/driver.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 09371f40d61f..3ea64b22cf0d 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: @@ -2820,7 +2834,7 @@ clear_ida: return ret; } -static int scmi_remove(struct platform_device *pdev) +static void scmi_remove(struct platform_device *pdev) { int id; struct scmi_info *info = platform_get_drvdata(pdev); @@ -2854,8 +2868,6 @@ static int scmi_remove(struct platform_device *pdev) scmi_cleanup_txrx_channels(info); ida_free(&scmi_id, info->id); - - return 0; } static ssize_t protocol_version_show(struct device *dev, @@ -2933,7 +2945,7 @@ static struct platform_driver scmi_driver = { .dev_groups = versions_groups, }, .probe = scmi_probe, - .remove = scmi_remove, + .remove_new = scmi_remove, }; /** |