]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 6 Jul 2025 09:00:17 +0000 (11:00 +0200)
commit 94a263f981a3fa3d93f65c31e0fed0756736be43 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/firmware/arm_scmi/driver.c
drivers/firmware/arm_scmi/protocols.h

index 24babf87adb91915c298dffb7db5245f38d80d01..d1fd2e492909e577c813dc6080234c4edb91c521 100644 (file)
@@ -1547,6 +1547,39 @@ out:
        return ret;
 }
 
+/**
+ * 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
@@ -1688,6 +1721,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;
@@ -1696,6 +1730,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;
@@ -1820,39 +1863,6 @@ static void scmi_common_fastchannel_db_ring(struct scmi_fc_db_info *db)
 #endif
 }
 
-/**
- * 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,
        .iter_response_init = scmi_iterator_init,
index 9fc2f1e293d4737bbe2792e9a73874e84ee7e008..095b14a2d0a3f607f172994167f0fdb2db570e76 100644 (file)
@@ -29,6 +29,8 @@
 #define PROTOCOL_REV_MAJOR(x)  ((u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x))))
 #define PROTOCOL_REV_MINOR(x)  ((u16)(FIELD_GET(PROTOCOL_REV_MINOR_MASK, (x))))
 
+#define MSG_SUPPORTS_FASTCHANNEL(x)    ((x) & BIT(0))
+
 enum scmi_common_cmd {
        PROTOCOL_VERSION = 0x0,
        PROTOCOL_ATTRIBUTES = 0x1,