mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 02:53:36 +02:00
firmware: arm_scmi: Ensure that the message-id supports fastchannel
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: 6f9ea4dabd ("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>
This commit is contained in:
parent
b0a1c9d489
commit
94a263f981
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user