firmware: arm_scmi: Add support for standalone transport drivers

Extend the core SCMI stack with structures and methods to allow for
transports to be split out as standalone drivers, while still supporting
old style transports, defined as built into the SCMI core stack.

No functional change.

Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Tested-by: Peng Fan <peng.fan@nxp.com>  #i.MX95 19x19 EVK
Tested-by: Florian Fainelli <florian.fainelli@broadcom.com>
Message-Id: <20240812173340.3912830-5-cristian.marussi@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
This commit is contained in:
Cristian Marussi
2024-08-12 18:33:35 +01:00
committed by Sudeep Holla
parent b6b7c77c98
commit 8b76a8c959
4 changed files with 136 additions and 2 deletions
+42 -2
View File
@@ -196,6 +196,11 @@ struct scmi_info {
#define bus_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, bus_nb)
#define req_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, dev_req_nb)
static struct scmi_transport_core_operations scmi_trans_core_ops = {
.bad_message_trace = scmi_bad_message_trace,
.rx_callback = scmi_rx_callback,
};
static unsigned long
scmi_vendor_protocol_signature(unsigned int protocol_id, char *vendor_id,
char *sub_vendor_id, u32 impl_ver)
@@ -3017,6 +3022,28 @@ static int scmi_debugfs_raw_mode_setup(struct scmi_info *info)
return ret;
}
static const struct scmi_desc *scmi_transport_setup(struct device *dev)
{
struct scmi_transport *trans;
trans = dev_get_platdata(dev);
if (!trans || !trans->desc || !trans->supplier || !trans->core_ops)
return NULL;
if (!device_link_add(dev, trans->supplier, DL_FLAG_AUTOREMOVE_CONSUMER)) {
dev_err(dev,
"Adding link to supplier transport device failed\n");
return NULL;
}
/* Provide core transport ops */
*trans->core_ops = &scmi_trans_core_ops;
dev_info(dev, "Using %s\n", dev_driver_string(trans->supplier));
return trans->desc;
}
static int scmi_probe(struct platform_device *pdev)
{
int ret;
@@ -3029,8 +3056,14 @@ static int scmi_probe(struct platform_device *pdev)
struct device_node *child, *np = dev->of_node;
desc = of_device_get_match_data(dev);
if (!desc)
return -EINVAL;
if (!desc) {
desc = scmi_transport_setup(dev);
if (!desc) {
err_str = "transport invalid\n";
ret = -EINVAL;
goto out_err;
}
}
info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
if (!info)
@@ -3197,6 +3230,7 @@ clear_txrx_setup:
clear_ida:
ida_free(&scmi_id, info->id);
out_err:
return dev_err_probe(dev, ret, "%s", err_str);
}
@@ -3388,6 +3422,12 @@ static int __init scmi_driver_init(void)
if (ret)
return ret;
if (IS_ENABLED(CONFIG_ARM_SCMI_HAVE_SHMEM))
scmi_trans_core_ops.shmem = scmi_shared_mem_operations_get();
if (IS_ENABLED(CONFIG_ARM_SCMI_HAVE_MSG))
scmi_trans_core_ops.msg = scmi_message_operations_get();
if (IS_ENABLED(CONFIG_ARM_SCMI_NEED_DEBUGFS))
scmi_top_dentry = scmi_debugfs_init();