[PATCH] [DEBUG] firmware: arm_scmi: Add SCMI Raw mode COEXISTENCE support

From: Cristian Marussi
Date: Sun Aug 21 2022 - 14:09:39 EST


When Raw mode support is configured in coexistence mode, normal SCMI
drivers are allowed to register and work as usual with the SCMI core.
Normal and raw SCMI message transactions will remain anyway segregated from
each other, it is just that any SCMI test suite using the Raw mode
access could report unreliable results due to possible interferences
from the regular drivers access to shared SCMI resources.

Signed-off-by: Cristian Marussi <cristian.marussi@xxxxxxx>
---
drivers/firmware/arm_scmi/Kconfig | 10 ++++++++++
drivers/firmware/arm_scmi/driver.c | 21 +++++++++++++++------
drivers/firmware/arm_scmi/protocols.h | 2 ++
drivers/firmware/arm_scmi/raw_mode.c | 2 +-
4 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index ab726a92ac2f..743f53fbe2f8 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -36,6 +36,16 @@ config ARM_SCMI_RAW_MODE_SUPPORT
order to avoid unexpected interactions with the SCMI Raw message
flow. If unsure say N.

+config ARM_SCMI_RAW_MODE_SUPPORT_COEX
+ bool "Allow SCMI Raw mode coexistence with normal SCMI stack"
+ depends on ARM_SCMI_RAW_MODE_SUPPORT
+ help
+ Allow SCMI Raw transmission mode to coexist with normal SCMI stack.
+
+ This will allow regular SCMI drivers to register with the core and
+ operate normally, thing which could make an SCMI test suite using the
+ SCMI Raw mode support unreliable. If unsure, say N.
+
config ARM_SCMI_HAVE_TRANSPORT
bool
help
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 32374fdba997..f0b06b6e8dc2 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -449,9 +449,14 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle,
*/
struct scmi_xfer *scmi_xfer_raw_get(const struct scmi_handle *handle)
{
+ struct scmi_xfer *xfer;
struct scmi_info *info = handle_to_scmi_info(handle);

- return scmi_xfer_get(handle, &info->tx_minfo);
+ xfer = scmi_xfer_get(handle, &info->tx_minfo);
+ if (!IS_ERR(xfer))
+ xfer->is_raw = true;
+
+ return xfer;
}

/**
@@ -531,6 +536,7 @@ void scmi_xfer_raw_put(const struct scmi_handle *handle, struct scmi_xfer *xfer)
{
struct scmi_info *info = handle_to_scmi_info(handle);

+ xfer->is_raw = false;
return __scmi_xfer_put(&info->tx_minfo, xfer);
}

@@ -2401,7 +2407,8 @@ int scmi_protocol_device_request(const struct scmi_device_id *id_table)
pr_debug("Requesting SCMI device (%s) for protocol %x\n",
id_table->name, id_table->protocol_id);

- if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) {
+ if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT) &&
+ !IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX)) {
pr_warn("SCMI Raw mode active. Rejecting '%s'/0x%02X\n",
id_table->name, id_table->protocol_id);
return -EINVAL;
@@ -2634,11 +2641,13 @@ static int scmi_probe(struct platform_device *pdev)
info->tx_minfo.max_msg);
if (!IS_ERR(info->raw)) {
dev_info(dev, "SCMI RAW Mode initialized.\n");
- return 0;
+ if (!IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX))
+ return 0;
+ dev_info(dev, "SCMI RAW Mode COEX enabled !\n");
+ } else {
+ dev_err(dev, "Failed to initialize SCMI RAW Mode !\n");
+ info->raw = NULL;
}
-
- dev_err(dev, "Failed to initialize SCMI RAW Mode !\n");
- info->raw = NULL;
}

if (scmi_notification_init(handle))
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h
index 2f3bf691db7c..70a48adcc320 100644
--- a/drivers/firmware/arm_scmi/protocols.h
+++ b/drivers/firmware/arm_scmi/protocols.h
@@ -88,6 +88,7 @@ struct scmi_msg_hdr {
/**
* struct scmi_xfer - Structure representing a message flow
*
+ * @is_raw: Flag to state if this xfer has been generated by RAW mode
* @transfer_id: Unique ID for debug & profiling purpose
* @hdr: Transmit message header
* @tx: Transmit message
@@ -119,6 +120,7 @@ struct scmi_msg_hdr {
* @priv: A pointer for transport private usage.
*/
struct scmi_xfer {
+ bool is_raw;
int transfer_id;
struct scmi_msg_hdr hdr;
struct scmi_msg tx;
diff --git a/drivers/firmware/arm_scmi/raw_mode.c b/drivers/firmware/arm_scmi/raw_mode.c
index 3fdfc0564286..0edaeb405267 100644
--- a/drivers/firmware/arm_scmi/raw_mode.c
+++ b/drivers/firmware/arm_scmi/raw_mode.c
@@ -1154,7 +1154,7 @@ void scmi_raw_message_report(void *r, struct scmi_xfer *xfer, unsigned int idx)
struct device *dev;
struct scmi_raw_mode_info *raw = r;

- if (!raw)
+ if (!raw || (idx == SCMI_RAW_REPLY_QUEUE && !xfer->is_raw))
return;

dev = raw->handle->dev;
--
2.34.1


----8<-----