diff options
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/arm_scmi/driver.c | 50 | ||||
-rw-r--r-- | drivers/firmware/arm_scmi/protocols.h | 15 |
2 files changed, 65 insertions, 0 deletions
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index a284a3fa85eb..ae2fed4af133 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1103,6 +1103,55 @@ static const struct scmi_xfer_ops xfer_ops = { .xfer_put = xfer_put, }; +struct scmi_msg_resp_domain_name_get { + __le32 flags; + u8 name[SCMI_MAX_STR_SIZE]; +}; + +/** + * scmi_common_extended_name_get - Common helper to get extended resources name + * @ph: A protocol handle reference. + * @cmd_id: The specific command ID to use. + * @res_id: The specific resource ID to use. + * @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. + * + * 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) +{ + int ret; + 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); + if (ret) + goto out; + + put_unaligned_le32(res_id, t->tx.buf); + resp = t->rx.buf; + + ret = ph->xops->do_xfer(ph, t); + if (!ret) + strscpy(name, resp->name, len); + + ph->xops->xfer_put(ph, t); +out: + if (ret) + dev_warn(ph->dev, + "Failed to get extended name - id:%u (ret:%d). Using %s\n", + res_id, ret, name); + return ret; +} + +static const struct scmi_proto_helpers_ops helpers_ops = { + .extended_name_get = scmi_common_extended_name_get, +}; + /** * scmi_revision_area_get - Retrieve version memory area. * @@ -1163,6 +1212,7 @@ scmi_alloc_init_protocol_instance(struct scmi_info *info, pi->handle = handle; pi->ph.dev = handle->dev; pi->ph.xops = &xfer_ops; + pi->ph.hops = &helpers_ops; pi->ph.set_priv = scmi_set_protocol_priv; pi->ph.get_priv = scmi_get_protocol_priv; refcount_set(&pi->users, 1); diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h index b2a92d2b2986..5461fa333152 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -141,6 +141,7 @@ struct scmi_xfer { }; struct scmi_xfer_ops; +struct scmi_proto_helpers_ops; /** * struct scmi_protocol_handle - Reference to an initialized protocol instance @@ -165,11 +166,25 @@ struct scmi_xfer_ops; struct scmi_protocol_handle { struct device *dev; const struct scmi_xfer_ops *xops; + const struct scmi_proto_helpers_ops *hops; int (*set_priv)(const struct scmi_protocol_handle *ph, void *priv); void *(*get_priv)(const struct scmi_protocol_handle *ph); }; /** + * struct scmi_proto_helpers_ops - References to common protocol helpers + * @extended_name_get: A common helper function to retrieve extended naming + * for the specified resource using the specified command. + * Result is returned as a NULL terminated string in the + * pre-allocated area pointed to by @name with maximum + * capacity of @len bytes. + */ +struct scmi_proto_helpers_ops { + int (*extended_name_get)(const struct scmi_protocol_handle *ph, + u8 cmd_id, u32 res_id, char *name, size_t len); +}; + +/** * struct scmi_xfer_ops - References to the core SCMI xfer operations. * @version_get: Get this version protocol. * @xfer_get_init: Initialize one struct xfer if any xfer slot is free. |