Hello Takahiro-san, > From: AKASHI Takahiro <takahiro.aka...@linaro.org> > Sent: Wednesday, July 26, 2023 10:37 > > SCMI base protocol is mandatory according to the SCMI specification. > > With this patch, SCMI base protocol can be accessed via SCMI transport > layers. All the commands, except SCMI_BASE_NOTIFY_ERRORS, are supported. > This is because U-Boot doesn't support interrupts and the current transport > layers are not able to handle asynchronous messages properly. > > Signed-off-by: AKASHI Takahiro <takahiro.aka...@linaro.org> > --- > v2 > * add helper functions, removing direct uses of ops > * add function descriptions for each of functions in ops
A reported typo and a question on use of strcpy(). Otherwise the patch look to me. If you strongly feel strcpy() is safe, please get my R-b tag: Reviewed-by: Etienne Carriere <etienne.carri...@foss.st.com> > --- > drivers/firmware/scmi/Makefile | 1 + > drivers/firmware/scmi/base.c | 637 +++++++++++++++++++++++++++++++++ > include/dm/uclass-id.h | 1 + > include/scmi_protocols.h | 345 ++++++++++++++++++ > 4 files changed, 984 insertions(+) > create mode 100644 drivers/firmware/scmi/base.c > > diff --git a/drivers/firmware/scmi/Makefile b/drivers/firmware/scmi/Makefile > index b2ff483c75a1..1a23d4981709 100644 > --- a/drivers/firmware/scmi/Makefile > +++ b/drivers/firmware/scmi/Makefile > @@ -1,4 +1,5 @@ > obj-y += scmi_agent-uclass.o > +obj-y += base.o > obj-y += smt.o > obj-$(CONFIG_SCMI_AGENT_SMCCC) += smccc_agent.o > obj-$(CONFIG_SCMI_AGENT_MAILBOX) += mailbox_agent.o > diff --git a/drivers/firmware/scmi/base.c b/drivers/firmware/scmi/base.c > new file mode 100644 > index 000000000000..2b61fa650d15 > --- /dev/null > +++ b/drivers/firmware/scmi/base.c > @@ -0,0 +1,637 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * SCMI Base protocol as U-Boot device > + * > + * Copyright (C) 2023 Linaro Limited > + * author: AKASHI Takahiro <takahiro.aka...@linaro.org> > + */ > + > +#include <common.h> > +#include <dm.h> > +#include <scmi_agent.h> > +#include <scmi_protocols.h> > +#include <stdlib.h> > +#include <asm/types.h> > +#include <dm/device_compat.h> > +#include <linux/kernel.h> > + > +/** > + * scmi_generic_protocol_version - get protocol version > + * @dev: SCMI device > + * @id: SCMI protocol ID > + * @version: Pointer to SCMI protocol version > + * > + * Obtain the protocol version number in @version. > + * > + * Return: 0 on success, error code otherwise > + */ > +int scmi_generic_protocol_version(struct udevice *dev, > + enum scmi_std_protocol id, u32 *version) > +{ > + struct scmi_protocol_version_out out; > + struct scmi_msg msg = { > + .protocol_id = id, > + .message_id = SCMI_PROTOCOL_VERSION, > + .out_msg = (u8 *)&out, > + .out_msg_sz = sizeof(out), > + }; > + int ret; > + > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + return ret; > + if (out.status) > + return scmi_to_linux_errno(out.status); > + > + *version = out.version; > + > + return 0; > +} > + > +/** > + * scmi_base_protocol_version_int - get Base protocol version > + * @dev: SCMI device > + * @version: Pointer to SCMI protocol version > + * > + * Obtain the protocol version number in @version for Base protocol. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_base_protocol_version_int(struct udevice *dev, u32 *version) > +{ > + return scmi_generic_protocol_version(dev, SCMI_PROTOCOL_ID_BASE, > + version); > +} > + > +/** > + * scmi_protocol_attrs_int - get protocol attributes > + * @dev: SCMI device > + * @num_agents: Number of SCMI agents > + * @num_protocols: Number of SCMI protocols > + * > + * Obtain the protocol attributes, the number of agents and the number > + * of protocols, in @num_agents and @num_protocols respectively, that > + * the device provides. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_protocol_attrs_int(struct udevice *dev, u32 *num_agents, > + u32 *num_protocols) > +{ > + struct scmi_protocol_attrs_out out; > + struct scmi_msg msg = { > + .protocol_id = SCMI_PROTOCOL_ID_BASE, > + .message_id = SCMI_PROTOCOL_ATTRIBUTES, > + .out_msg = (u8 *)&out, > + .out_msg_sz = sizeof(out), > + }; > + int ret; > + > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + return ret; > + if (out.status) > + return scmi_to_linux_errno(out.status); > + > + *num_agents = SCMI_PROTOCOL_ATTRS_NUM_AGENTS(out.attributes); > + *num_protocols = SCMI_PROTOCOL_ATTRS_NUM_PROTOCOLS(out.attributes); > + > + return 0; > +} > + > +/** > + * scmi_protocol_message_attrs_int - get message-specific attributes > + * @dev: SCMI device > + * @message_id: SCMI message ID > + * @attributes: Message-specific attributes > + * > + * Obtain the message-specific attributes in @attributes. > + * This command succeeds if the message is implemented and available. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_protocol_message_attrs_int(struct udevice *dev, u32 > message_id, > + u32 *attributes) > +{ > + struct scmi_protocol_msg_attrs_out out; > + struct scmi_msg msg = { > + .protocol_id = SCMI_PROTOCOL_ID_BASE, > + .message_id = SCMI_PROTOCOL_MESSAGE_ATTRIBUTES, > + .in_msg = (u8 *)&message_id, > + .in_msg_sz = sizeof(message_id), > + .out_msg = (u8 *)&out, > + .out_msg_sz = sizeof(out), > + }; > + int ret; > + > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + return ret; > + if (out.status) > + return scmi_to_linux_errno(out.status); > + > + *attributes = out.attributes; > + > + return 0; > +} > + > +/** > + * scmi_base_discover_vendor_int - get vendor name > + * @dev: SCMI device > + * @vendor: Vendor name > + * > + * Obtain the vendor's name in @vendor. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_base_discover_vendor_int(struct udevice *dev, u8 *vendor) > +{ > + struct scmi_base_discover_vendor_out out; > + struct scmi_msg msg = { > + .protocol_id = SCMI_PROTOCOL_ID_BASE, > + .message_id = SCMI_BASE_DISCOVER_VENDOR, > + .out_msg = (u8 *)&out, > + .out_msg_sz = sizeof(out), > + }; > + int ret; > + > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + return ret; > + if (out.status) > + return scmi_to_linux_errno(out.status); > + > + strcpy(vendor, out.vendor_identifier); Nitpicking: there are no check on output string buffer size. The implementation looks good as we expect SCMI platform firmware complies with the specification. However I wonder if here it's better to either use strncpy() or to explicit vendor[] argument size: -static int scmi_base_discover_vendor_int(struct udevice *dev, u8 *vendor) +static int scmi_base_discover_vendor_int(struct udevice *dev, u8 vendor[SCMI_BASE_NAME_LENGTH_MAX]) Ditto in scmi_base_discover_sub_vendor_int() and scmi_base_discover_agent_int(). > + > + return 0; > +} > + > +/** > + * scmi_base_discover_sub_vendor_int - get sub-vendor name > + * @dev: SCMI device > + * @sub_vendor: Sub-vendor name > + * > + * Obtain the sub-vendor's name in @sub_vendor. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_base_discover_sub_vendor_int(struct udevice *dev, > + u8 *sub_vendor) > +{ > + struct scmi_base_discover_vendor_out out; > + struct scmi_msg msg = { > + .protocol_id = SCMI_PROTOCOL_ID_BASE, > + .message_id = SCMI_BASE_DISCOVER_SUB_VENDOR, > + .out_msg = (u8 *)&out, > + .out_msg_sz = sizeof(out), > + }; > + int ret; > + > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + return ret; > + if (out.status) > + return scmi_to_linux_errno(out.status); > + > + strcpy(sub_vendor, out.vendor_identifier); > + > + return 0; > +} > + > +/** > + * scmi_base_discover_impl_version_int - get implementation version > + * @dev: SCMI device > + * @impl_version: Pointer to implementation version > + * > + * Obtain the implementation version number in @impl_version. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_base_discover_impl_version_int(struct udevice *dev, > + u32 *impl_version) > +{ > + struct scmi_base_discover_impl_version_out out; > + struct scmi_msg msg = { > + .protocol_id = SCMI_PROTOCOL_ID_BASE, > + .message_id = SCMI_BASE_DISCOVER_IMPL_VERSION, > + .out_msg = (u8 *)&out, > + .out_msg_sz = sizeof(out), > + }; > + int ret; > + > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + return ret; > + if (out.status) > + return scmi_to_linux_errno(out.status); > + > + *impl_version = out.impl_version; > + > + return 0; > +} > + > +/** > + * scmi_base_discover_list_protocols_int - get list of protocols > + * @dev: SCMI device > + * @protocols: Pointer to array of SCMI protocols > + * > + * Obtain the list of protocols provided in @protocols. > + * The number of elements in @protocols always match to the number of > + * protocols returned by smci_protocol_attrs() when this function succeeds. > + * It is a caller's responsibility to free @protocols. > + * > + * Return: the number of protocols in @protocols on success, error code > otherwise > + */ > +static int scmi_base_discover_list_protocols_int(struct udevice *dev, > + u8 **protocols) > +{ > + struct scmi_base_discover_list_protocols_out out; > + int cur; > + struct scmi_msg msg = { > + .protocol_id = SCMI_PROTOCOL_ID_BASE, > + .message_id = SCMI_BASE_DISCOVER_LIST_PROTOCOLS, > + .in_msg = (u8 *)&cur, > + .in_msg_sz = sizeof(cur), > + .out_msg = (u8 *)&out, > + .out_msg_sz = sizeof(out), > + }; > + u32 num_agents, num_protocols; > + u8 *buf; > + int i, ret; > + > + ret = scmi_base_protocol_attrs(dev, &num_agents, &num_protocols); > + if (ret) > + return ret; > + > + buf = calloc(sizeof(u8), num_protocols); > + if (!buf) > + return -ENOMEM; > + > + cur = 0; > + do { > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + goto err; > + if (out.status) { > + ret = scmi_to_linux_errno(out.status); > + goto err; > + } > + > + for (i = 0; i < out.num_protocols; i++, cur++) > + buf[cur] = out.protocols[i / 4] >> ((i % 4) * 8); > + } while (cur < num_protocols); > + > + *protocols = buf; > + > + return num_protocols; > +err: > + free(buf); > + > + return ret; > +} > + > +/** > + * scmi_base_discover_agent_int - identify agent > + * @dev: SCMI device > + * @agent_id: SCMI agent ID > + * @ret_agent_id: Pointer to SCMI agent ID > + * @name: SCMI agent name > + * > + * Obtain the agent's name in @name. If @agent_id is equal to 0xffffffff, > + * this function returns the caller's agent id in @ret_agent_id. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_base_discover_agent_int(struct udevice *dev, u32 agent_id, > + u32 *ret_agent_id, u8 *name) > +{ > + struct scmi_base_discover_agent_out out; > + struct scmi_msg msg = { > + .protocol_id = SCMI_PROTOCOL_ID_BASE, > + .message_id = SCMI_BASE_DISCOVER_AGENT, > + .in_msg = (u8 *)&agent_id, > + .in_msg_sz = sizeof(agent_id), > + .out_msg = (u8 *)&out, > + .out_msg_sz = sizeof(out), > + }; > + int ret; > + > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + return ret; > + if (out.status) > + return scmi_to_linux_errno(out.status); > + > + strcpy(name, out.name); > + *ret_agent_id = out.agent_id; > + > + return 0; > +} > + > +/** > + * scmi_base_set_device_permissions_int - configure access permission to > device > + * @dev: SCMI device > + * @agent_id: SCMI agent ID > + * @device_id: ID of device to access > + * @flags: A set of flags > + * > + * Ask for allowing or denying access permission to the device, @device_id. > + * The meaning of @flags is defined in SCMI specification. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_base_set_device_permissions_int(struct udevice *dev, u32 > agent_id, > + u32 device_id, u32 flags) > +{ > + struct scmi_base_set_device_permissions_in in = { > + .agent_id = agent_id, > + .device_id = device_id, > + .flags = flags, > + }; > + s32 status; > + struct scmi_msg msg = { > + .protocol_id = SCMI_PROTOCOL_ID_BASE, > + .message_id = SCMI_BASE_SET_DEVICE_PERMISSIONS, > + .in_msg = (u8 *)&in, > + .in_msg_sz = sizeof(in), > + .out_msg = (u8 *)&status, > + .out_msg_sz = sizeof(status), > + }; > + int ret; > + > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + return ret; > + if (status) > + return scmi_to_linux_errno(status); > + > + return 0; > +} > + > +/** > + * scmi_base_set_protocol_permissions_int - configure access permission to > + protocol on device > + * @dev: SCMI device > + * @agent_id: SCMI agent ID > + * @device_id: ID of device to access > + * @command_id: SCMI command ID > + * @flags: A set of flags > + * > + * Ask for allowing or denying access permission to the protocol, > @command_id, > + * on the device, @device_id. > + * The meaning of @flags is defined in SCMI specification. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_base_set_protocol_permissions_int(struct udevice *dev, > + u32 agent_id, u32 device_id, > + u32 command_id, u32 flags) > +{ > + struct scmi_base_set_protocol_permissions_in in = { > + .agent_id = agent_id, > + .device_id = device_id, > + .command_id = command_id, > + .flags = flags, > + }; > + s32 status; > + struct scmi_msg msg = { > + .protocol_id = SCMI_PROTOCOL_ID_BASE, > + .message_id = SCMI_BASE_SET_PROTOCOL_PERMISSIONS, > + .in_msg = (u8 *)&in, > + .in_msg_sz = sizeof(in), > + .out_msg = (u8 *)&status, > + .out_msg_sz = sizeof(status), > + }; > + int ret; > + > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + return ret; > + if (status) > + return scmi_to_linux_errno(status); > + > + return 0; > +} > + > +/** > + * scmi_base_reset_agent_configuration_int - reset resource settings > + * @dev: SCMI device > + * @agent_id: SCMI agent ID > + * @flags: A set of flags > + * > + * Ask for allowing or denying access permission to the protocol, > @command_id, > + * on the device, @device_id. > + * The meaning of @flags is defined in SCMI specification. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_base_reset_agent_configuration_int(struct udevice *dev, > + u32 agent_id, u32 flags) > +{ > + struct scmi_base_reset_agent_configuration_in in = { > + .agent_id = agent_id, > + .flags = flags, > + }; > + s32 status; > + struct scmi_msg msg = { > + .protocol_id = SCMI_PROTOCOL_ID_BASE, > + .message_id = SCMI_BASE_RESET_AGENT_CONFIGURATION, > + .in_msg = (u8 *)&in, > + .in_msg_sz = sizeof(in), > + .out_msg = (u8 *)&status, > + .out_msg_sz = sizeof(status), > + }; > + int ret; > + > + ret = devm_scmi_process_msg(dev, &msg); > + if (ret) > + return ret; > + if (status) > + return scmi_to_linux_errno(status); > + > + return 0; > +} > + > +/** > + * scmi_base_probe - probe base protocol device > + * @dev: SCMI device > + * > + * Probe the device for SCMI base protocol and initialize the private data. > + * > + * Return: 0 on success, error code otherwise > + */ > +static int scmi_base_probe(struct udevice *dev) > +{ > + int ret; > + > + ret = devm_scmi_of_get_channel(dev); > + if (ret) { > + dev_err(dev, "get_channel failed\n"); > + return ret; > + } > + > + return ret; > +} > + > +struct scmi_base_ops scmi_base_ops = { > + /* Commands */ > + .protocol_version = scmi_base_protocol_version_int, > + .protocol_attrs = scmi_protocol_attrs_int, > + .protocol_message_attrs = scmi_protocol_message_attrs_int, > + .base_discover_vendor = scmi_base_discover_vendor_int, > + .base_discover_sub_vendor = scmi_base_discover_sub_vendor_int, > + .base_discover_impl_version = scmi_base_discover_impl_version_int, > + .base_discover_list_protocols = scmi_base_discover_list_protocols_int, > + .base_discover_agent = scmi_base_discover_agent_int, > + .base_notify_errors = NULL, > + .base_set_device_permissions = scmi_base_set_device_permissions_int, > + .base_set_protocol_permissions = > scmi_base_set_protocol_permissions_int, > + .base_reset_agent_configuration = > + scmi_base_reset_agent_configuration_int, > +}; > + > +int scmi_base_protocol_version(struct udevice *dev, u32 *version) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->protocol_version) > + return (*ops->protocol_version)(dev, version); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_protocol_attrs(struct udevice *dev, u32 *num_agents, > + u32 *num_protocols) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->protocol_attrs) > + return (*ops->protocol_attrs)(dev, num_agents, num_protocols); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_protocol_message_attrs(struct udevice *dev, u32 message_id, > + u32 *attributes) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->protocol_message_attrs) > + return (*ops->protocol_message_attrs)(dev, message_id, > + attributes); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_discover_vendor(struct udevice *dev, u8 *vendor) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->base_discover_vendor) > + return (*ops->base_discover_vendor)(dev, vendor); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_discover_sub_vendor(struct udevice *dev, u8 *sub_vendor) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->base_discover_sub_vendor) > + return (*ops->base_discover_sub_vendor)(dev, sub_vendor); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_discover_impl_version(struct udevice *dev, u32 *impl_version) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->base_discover_impl_version) > + return (*ops->base_discover_impl_version)(dev, impl_version); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_discover_list_protocols(struct udevice *dev, u8 **protocols) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->base_discover_list_protocols) > + return (*ops->base_discover_list_protocols)(dev, protocols); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_discover_agent(struct udevice *dev, u32 agent_id, > + u32 *ret_agent_id, u8 *name) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->base_discover_agent) > + return (*ops->base_discover_agent)(dev, agent_id, > ret_agent_id, > + name); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_notify_errors(struct udevice *dev, u32 enable) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->base_notify_errors) > + return (*ops->base_notify_errors)(dev, enable); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_set_device_permissions(struct udevice *dev, u32 agent_id, > + u32 device_id, u32 flags) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->base_set_device_permissions) > + return (*ops->base_set_device_permissions)(dev, agent_id, > + device_id, flags); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_set_protocol_permissions(struct udevice *dev, > + u32 agent_id, u32 device_id, > + u32 command_id, u32 flags) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->base_set_protocol_permissions) > + return (*ops->base_set_protocol_permissions)(dev, agent_id, > + device_id, > + command_id, > + flags); > + > + return -EOPNOTSUPP; > +} > + > +int scmi_base_reset_agent_configuration(struct udevice *dev, u32 agent_id, > + u32 flags) > +{ > + const struct scmi_base_ops *ops = device_get_ops(dev); > + > + if (ops->base_reset_agent_configuration) > + return (*ops->base_reset_agent_configuration)(dev, agent_id, > + flags); > + > + return -EOPNOTSUPP; > +} > + > +U_BOOT_DRIVER(scmi_base_drv) = { > + .id = UCLASS_SCMI_BASE, > + .name = "scmi_base_drv", > + .ops = &scmi_base_ops, > + .probe = scmi_base_probe, > +}; > + > +UCLASS_DRIVER(scmi_base) = { > + .id = UCLASS_SCMI_BASE, > + .name = "scmi_base", > +}; > diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h > index 307ad6931ca7..f7a110852321 100644 > --- a/include/dm/uclass-id.h > +++ b/include/dm/uclass-id.h > @@ -116,6 +116,7 @@ enum uclass_id { > UCLASS_RNG, /* Random Number Generator */ > UCLASS_RTC, /* Real time clock device */ > UCLASS_SCMI_AGENT, /* Interface with an SCMI server */ > + UCLASS_SCMI_BASE, /* Interface for SCMI Base protocol */ > UCLASS_SCSI, /* SCSI device */ > UCLASS_SERIAL, /* Serial UART */ > UCLASS_SIMPLE_BUS, /* Bus with child devices */ > diff --git a/include/scmi_protocols.h b/include/scmi_protocols.h > index a220cb2a91ad..64fd740472b5 100644 > --- a/include/scmi_protocols.h > +++ b/include/scmi_protocols.h > @@ -49,6 +49,351 @@ enum scmi_discovery_id { > SCMI_PROTOCOL_MESSAGE_ATTRIBUTES = 0x2, > }; > > +/* > + * SCMI Base Protocol > + */ > +#define SCMI_BASE_PROTOCOL_VERSION 0x20000 > + > +enum scmi_base_message_id { > + SCMI_BASE_DISCOVER_VENDOR = 0x3, > + SCMI_BASE_DISCOVER_SUB_VENDOR = 0x4, > + SCMI_BASE_DISCOVER_IMPL_VERSION = 0x5, > + SCMI_BASE_DISCOVER_LIST_PROTOCOLS = 0x6, > + SCMI_BASE_DISCOVER_AGENT = 0x7, > + SCMI_BASE_NOTIFY_ERRORS = 0x8, > + SCMI_BASE_SET_DEVICE_PERMISSIONS = 0x9, > + SCMI_BASE_SET_PROTOCOL_PERMISSIONS = 0xa, > + SCMI_BASE_RESET_AGENT_CONFIGURATION = 0xb, > +}; > + > +#define SCMI_BASE_NAME_LENGTH_MAX 16 > + > +/** > + * struct scmi_protocol_version_out - Response for SCMI_PROTOCOL_VERSION > + * command > + * @status: SCMI command status > + * @version: Protocol version > + */ > +struct scmi_protocol_version_out { > + s32 status; > + u32 version; > +}; > + > +/** > + * struct scmi_protocol_attrs_out - Response for SCMI_PROTOCOL_ATTRIBUTES > + * command > + * @status: SCMI command status > + * @attributes: Protocol attributes or implementation details > + */ > +struct scmi_protocol_attrs_out { > + s32 status; > + u32 attributes; > +}; > + > +#define SCMI_PROTOCOL_ATTRS_NUM_AGENTS(attributes) \ > + (((attributes) & GENMASK(15, 8)) >> 8) > +#define SCMI_PROTOCOL_ATTRS_NUM_PROTOCOLS(attributes) \ > + ((attributes) & GENMASK(7, 0)) > + > +/** > + * struct scmi_protocol_msg_attrs_out - Response for > + * SCMI_PROTOCOL_MESSAGE_ATTRIBUTES > command > + * @status: SCMI command status > + * @attributes: Message-specific attributes > + */ > +struct scmi_protocol_msg_attrs_out { > + s32 status; > + u32 attributes; > +}; > + > +/** > + * struct scmi_base_discover_vendor_out - Response for > + * SCMI_BASE_DISCOVER_VENDOR or > + * SCMI_BASE_DISCOVER_SUB_VENDOR > command > + * @status: SCMI command status > + * @vendor_identifier: Name of vendor or sub-vendor in string > + */ > +struct scmi_base_discover_vendor_out { > + s32 status; > + u8 vendor_identifier[SCMI_BASE_NAME_LENGTH_MAX]; > +}; > + > +/** > + * struct scmi_base_discover_impl_version_out - Response for > + * SCMI_BASE_DISCOVER_IMPL_VERSION > command > + * @status: SCMI command status > + * @impl_version: Vendor-specific implementation version > + */ > +struct scmi_base_discover_impl_version_out { > + s32 status; > + u32 impl_version; > +}; > + > +/** > + * struct scmi_base_discover_list_protocols_out - Response for > + * SCMI_BASE_DISCOVER_LIST_PROTOCOLS command > + * @status: SCMI command status > + * @num_protocols: Number of SCMI protocols in @protocol > + * @protocols: Array of packed SCMI protocol ID's > + */ > +struct scmi_base_discover_list_protocols_out { > + s32 status; > + u32 num_protocols; > + u32 protocols[3]; > +}; > + > +/** > + * struct scmi_base_discover_agent_out - Response for > + * SCMI_BASE_DISCOVER_AGENT command > + * @status: SCMI command status > + * @agent_id: SCMI agent ID > + * @name: Name of agent in string > + */ > +struct scmi_base_discover_agent_out { > + s32 status; > + u32 agent_id; > + u8 name[SCMI_BASE_NAME_LENGTH_MAX]; > +}; > + > +#define SCMI_BASE_NOTIFY_ERRORS_ENABLE BIT(0) > + > +/** > + * struct scmi_base_set_device_permissions_in - Parameters for > + * SCMI_BASE_SET_DEVICE_PERMISSIONS > command > + * @agent_id: SCMI agent ID > + * @device_id: device ID > + * @flags: A set of flags > + */ > +struct scmi_base_set_device_permissions_in { > + u32 agent_id; > + u32 device_id; > + u32 flags; > +}; > + > +#define SCMI_BASE_SET_DEVICE_PERMISSIONS_ACCESS BIT(0) > + > +/** > + * struct scmi_base_set_protocol_permissions_in - Parameters for > + * SCMI_BASE_SET_PROTOCOL_PERMISSIONS command > + * @agent_id: SCMI agent ID > + * @device_id: device ID > + * @command_id: command ID > + * @flags: A set of flags > + */ > +struct scmi_base_set_protocol_permissions_in { > + u32 agent_id; > + u32 device_id; > + u32 command_id; > + u32 flags; > +}; > + > +#define SCMI_BASE_SET_PROTOCOL_PERMISSIONS_COMMAND GENMASK(7, 0) > +#define SCMI_BASE_SET_PROTOCOL_PERMISSIONS_ACCESS BIT(0) > + > +/** > + * struct scmi_base_reset_agent_configuration_in - Parameters for > + * SCMI_BASE_RESET_AGENT_CONFIGURATION command > + * @agent_id: SCMI agent ID > + * @flags: A set of flags > + */ > +struct scmi_base_reset_agent_configuration_in { > + u32 agent_id; > + u32 flags; > +}; > + > +#define SCMI_BASE_RESET_ALL_ACCESS_PERMISSIONS BIT(0) > + > +/** > + * struct scmi_base_ops - SCMI base protocol interfaces > + */ > +struct scmi_base_ops { > + /** > + * protocol_version - get Base protocol version > + * @dev: SCMI device > + * @version: Pointer to SCMI protocol version > + * > + * Obtain the protocol version number in @version for Base protocol. > + * > + * Return: 0 on success, error code otherwise > + */ > + int (*protocol_version)(struct udevice *dev, u32 *version); > + /** > + * protocol_attrs - get protocol attributes > + * @dev: SCMI device > + * @num_agents: Number of SCMI agents > + * @num_protocols: Number of SCMI protocols > + * > + * Obtain the protocol attributes, the number of agents and the number > + * of protocols, in @num_agents and @num_protocols respectively, that > + * the device provides. > + * > + * Return: 0 on success, error code otherwise > + */ > + int (*protocol_attrs)(struct udevice *dev, u32 *num_agents, > + u32 *num_protocols); > + /** > + * protocol_message_attrs - get message-specific attributes > + * @dev: SCMI device > + * @message_id: SCMI message ID > + * @attributes: Message-specific attributes > + * > + * Obtain the message-specific attributes in @attributes. > + * This command succeeds if the message is implemented and available. > + * > + * Return: 0 on success, error code otherwise > + */ > + int (*protocol_message_attrs)(struct udevice *dev, u32 message_id, > + u32 *attributes); > + /** > + * base_discover_vendor - get vendor name > + * @dev: SCMI device > + * @vendor: Vendor name > + * > + * Obtain the vendor's name in @vendor. > + * > + * Return: 0 on success, error code otherwise > + */ > + int (*base_discover_vendor)(struct udevice *dev, u8 *vendor); > + /** > + * base_discover_sub_vendor - get sub-vendor name > + * @dev: SCMI device > + * @sub_vendor: Sub-vendor name > + * > + * Obtain the sub-vendor's name in @sub_vendor. > + * > + * Return: 0 on success, error code otherwise > + */ > + int (*base_discover_sub_vendor)(struct udevice *dev, u8 *sub_vendor); > + /** > + * base_discover_impl_version - get implementation version > + * @dev: SCMI device > + * @impl_version: Pointer to implementation version > + * > + * Obtain the implementation version number in @impl_version. > + * > + * Return: 0 on success, error code otherwise > + */ > + int (*base_discover_impl_version)(struct udevice *dev, u32 > *impl_version); > + /** > + * base_discover_list_protocols - get list of protocols > + * @dev: SCMI device > + * @protocols: Pointer to array of SCMI protocols > + * > + * Obtain the list of protocols provided in @protocols. > + * The number of elements in @protocols always match to the number of > + * protocols returned by smci_protocol_attrs() when this function > succeeds. > + * It is a caller's responsibility to free @protocols. > + * > + * Return: the number of protocols in @protocols on success, error > code otherwise > + */ > + int (*base_discover_list_protocols)(struct udevice *dev, u8 > **protocols); > + /** > + * base_discover_agent - identify agent > + * @dev: SCMI device > + * @agent_id: SCMI agent ID > + * @ret_agent_id: Pointer to SCMI agent ID > + * @name: SCMI agent name > + * > + * Obtain the agent's name in @name. If @agent_id is equal to > 0xffffffff, > + * this function returns the caller's agent id in @ret_agent_id. > + * > + * Return: 0 on success, error code otherwise > + */ > + int (*base_discover_agent)(struct udevice *dev, u32 agent_id, > + u32 *ret_agent_id, u8 *name); > + /** > + * base_notify_errors - configure error notification > + * @dev: SCMI device > + * @enable: Operation > + * > + * This function is not yet implemented. > + * > + * Return: always -EOPNOTSUPP > + */ > + int (*base_notify_errors)(struct udevice *dev, u32 enable); > + /** > + * base_set_device_permissions - configure access permission to device > + * @dev: SCMI device > + * @agent_id: SCMI agent ID > + * @device_id: ID of device to access > + * @flags: A set of flags > + * > + * Ask for allowing or denying access permission to the device, > @device_id. > + * The meaning of @flags is defined in SCMI specification. > + * > + * Return: 0 on success, error code otherwise > + */ > + int (*base_set_device_permissions)(struct udevice *dev, u32 agent_id, > + u32 device_id, u32 flags); > + /** > + * base_set_protocol_permissions - configure access permission to > + * protocol on device > + * @dev: SCMI device > + * @agent_id: SCMI agent ID > + * @device_id: ID of device to access > + * @command_id: command ID > + * @flags: A set of flags > + * > + * Ask for allowing or denying access permission to the protocol, > @command_id, > + * on the device, @device_id. > + * The meaning of @flags is defined in SCMI specification. > + * > + * Return: 0 on success, error code otherwise > + */ > + int (*base_set_protocol_permissions)(struct udevice *dev, u32 > agent_id, > + u32 device_id, u32 command_id, > + u32 flags); > + /** > + * base_reset_agent_configuration - reset resource settings > + * @dev: SCMI device > + * @agent_id: SCMI agent ID > + * @flags: A set of flags > + * > + * Ask for allowing or denying access permission to the protocol, > @command_id, > + * on the device, @device_id. > + * The meaning of @flags is defined in SCMI specification. > + * > + * Return: 0 on success, error code otherwise > + */ > + int (*base_reset_agent_configuration)(struct udevice *dev, u32 > agent_id, > + u32 flags); > +}; > + > +int scmi_base_protocol_version(struct udevice *dev, u32 *version); > +int scmi_base_protocol_attrs(struct udevice *dev, u32 *num_agents, > + u32 *num_protocols); > +int scmi_base_protocol_message_attrs(struct udevice *dev, u32 message_id, > + u32 *attributes); > +int scmi_base_discover_vendor(struct udevice *dev, u8 *vendor); > +int scmi_base_discover_sub_vendor(struct udevice *dev, u8 *sub_vendor); > +int scmi_base_discover_impl_version(struct udevice *dev, u32 *impl_version); > +int scmi_base_discover_list_protocols(struct udevice *dev, u8 **protocols); > +int scmi_base_discover_agent(struct udevice *dev, u32 agent_id, > + u32 *ret_agent_id, u8 *name); > +int scmi_base_notify_errors(struct udevice *dev, u32 enable); > +int scmi_base_set_device_permissions(struct udevice *dev, u32 agent_id, > + u32 device_id, u32 flags); > +int scmi_base_set_device_permissions(struct udevice *dev, u32 agent_id, > + u32 device_id, u32 flags); typo: duplicated declaration. BR, Etienne > +int scmi_base_set_protocol_permissions(struct udevice *dev, > + u32 agent_id, u32 device_id, > + u32 command_id, u32 flags); > +int scmi_base_reset_agent_configuration(struct udevice *dev, u32 agent_id, > + u32 flags); > + > +/** > + * scmi_generic_protocol_version - get protocol version > + * @dev: SCMI device > + * @id: SCMI protocol ID > + * @version: Pointer to SCMI protocol version > + * > + * Obtain the protocol version number in @version. > + * > + * Return: 0 on success, error code otherwise > + */ > +int scmi_generic_protocol_version(struct udevice *dev, > + enum scmi_std_protocol id, u32 *version); > + > /* > * SCMI Clock Protocol > */ > -- > 2.41.0 >