]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
firmware: arm_scmi: Ensure that the message-id supports fastchannel
authorSibi Sankar <quic_sibis@quicinc.com>
Tue, 29 Apr 2025 14:11:06 +0000 (15:11 +0100)
committerSudeep Holla <sudeep.holla@arm.com>
Tue, 6 May 2025 10:12:30 +0000 (11:12 +0100)
Currently the perf and powercap protocol relies on the protocol domain
attributes, which just ensures that one fastchannel per domain, before
instantiating fastchannels for all possible message-ids. Fix this by
ensuring that each message-id supports fastchannel before initialization.

Logs:
  |  scmi: Failed to get FC for protocol 13 [MSG_ID:6 / RES_ID:0] - ret:-95. Using regular messaging
  |  scmi: Failed to get FC for protocol 13 [MSG_ID:6 / RES_ID:1] - ret:-95. Using regular messaging
  |  scmi: Failed to get FC for protocol 13 [MSG_ID:6 / RES_ID:2] - ret:-95. Using regular messaging

CC: stable@vger.kernel.org
Reported-by: Johan Hovold <johan+linaro@kernel.org>
Closes: https://lore.kernel.org/lkml/ZoQjAWse2YxwyRJv@hovoldconsulting.com/
Fixes: 6f9ea4dabd2d ("firmware: arm_scmi: Generalize the fast channel support")
Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
Tested-by: Johan Hovold <johan+linaro@kernel.org>
Signed-off-by: Sibi Sankar <quic_sibis@quicinc.com>
[Cristian: Modified the condition checked to establish support or not]
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Message-Id: <20250429141108.406045-2-cristian.marussi@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
drivers/firmware/arm_scmi/driver.c
drivers/firmware/arm_scmi/protocols.h

index 520aa5846916724c5cfb87f3d27f96512f03d451..cf2bc8b8d8812fa96be65243bbc04ec7d7a403e0 100644 (file)
@@ -1729,6 +1729,39 @@ static int scmi_common_get_max_msg_size(const struct scmi_protocol_handle *ph)
        return info->desc->max_msg_size;
 }
 
+/**
+ * scmi_protocol_msg_check  - Check protocol message attributes
+ *
+ * @ph: A reference to the protocol handle.
+ * @message_id: The ID of the message to check.
+ * @attributes: A parameter to optionally return the retrieved message
+ *             attributes, in case of Success.
+ *
+ * An helper to check protocol message attributes for a specific protocol
+ * and message pair.
+ *
+ * Return: 0 on SUCCESS
+ */
+static int scmi_protocol_msg_check(const struct scmi_protocol_handle *ph,
+                                  u32 message_id, u32 *attributes)
+{
+       int ret;
+       struct scmi_xfer *t;
+
+       ret = xfer_get_init(ph, PROTOCOL_MESSAGE_ATTRIBUTES,
+                           sizeof(__le32), 0, &t);
+       if (ret)
+               return ret;
+
+       put_unaligned_le32(message_id, t->tx.buf);
+       ret = do_xfer(ph, t);
+       if (!ret && attributes)
+               *attributes = get_unaligned_le32(t->rx.buf);
+       xfer_put(ph, t);
+
+       return ret;
+}
+
 /**
  * struct scmi_iterator  - Iterator descriptor
  * @msg: A reference to the message TX buffer; filled by @prepare_message with
@@ -1870,6 +1903,7 @@ scmi_common_fastchannel_init(const struct scmi_protocol_handle *ph,
        int ret;
        u32 flags;
        u64 phys_addr;
+       u32 attributes;
        u8 size;
        void __iomem *addr;
        struct scmi_xfer *t;
@@ -1878,6 +1912,15 @@ scmi_common_fastchannel_init(const struct scmi_protocol_handle *ph,
        struct scmi_msg_resp_desc_fc *resp;
        const struct scmi_protocol_instance *pi = ph_to_pi(ph);
 
+       /* Check if the MSG_ID supports fastchannel */
+       ret = scmi_protocol_msg_check(ph, message_id, &attributes);
+       if (ret || !MSG_SUPPORTS_FASTCHANNEL(attributes)) {
+               dev_dbg(ph->dev,
+                       "Skip FC init for 0x%02X/%d  domain:%d - ret:%d\n",
+                       pi->proto->id, message_id, domain, ret);
+               return;
+       }
+
        if (!p_addr) {
                ret = -EINVAL;
                goto err_out;
@@ -1995,39 +2038,6 @@ static void scmi_common_fastchannel_db_ring(struct scmi_fc_db_info *db)
                SCMI_PROTO_FC_RING_DB(64);
 }
 
-/**
- * scmi_protocol_msg_check  - Check protocol message attributes
- *
- * @ph: A reference to the protocol handle.
- * @message_id: The ID of the message to check.
- * @attributes: A parameter to optionally return the retrieved message
- *             attributes, in case of Success.
- *
- * An helper to check protocol message attributes for a specific protocol
- * and message pair.
- *
- * Return: 0 on SUCCESS
- */
-static int scmi_protocol_msg_check(const struct scmi_protocol_handle *ph,
-                                  u32 message_id, u32 *attributes)
-{
-       int ret;
-       struct scmi_xfer *t;
-
-       ret = xfer_get_init(ph, PROTOCOL_MESSAGE_ATTRIBUTES,
-                           sizeof(__le32), 0, &t);
-       if (ret)
-               return ret;
-
-       put_unaligned_le32(message_id, t->tx.buf);
-       ret = do_xfer(ph, t);
-       if (!ret && attributes)
-               *attributes = get_unaligned_le32(t->rx.buf);
-       xfer_put(ph, t);
-
-       return ret;
-}
-
 static const struct scmi_proto_helpers_ops helpers_ops = {
        .extended_name_get = scmi_common_extended_name_get,
        .get_max_msg_size = scmi_common_get_max_msg_size,
index aaee57cdcd5589ee8c3f28f782ba5f84fd83d792..d62c4469d1fd9f1f3eb9f09327d1dcb4c18b2f7b 100644 (file)
@@ -31,6 +31,8 @@
 
 #define SCMI_PROTOCOL_VENDOR_BASE      0x80
 
+#define MSG_SUPPORTS_FASTCHANNEL(x)    ((x) & BIT(0))
+
 enum scmi_common_cmd {
        PROTOCOL_VERSION = 0x0,
        PROTOCOL_ATTRIBUTES = 0x1,