summaryrefslogtreecommitdiffstats
path: root/drivers/firmware/arm_scmi/base.c
diff options
context:
space:
mode:
authorCristian Marussi <cristian.marussi@arm.com>2022-03-30 16:05:34 +0100
committerSudeep Holla <sudeep.holla@arm.com>2022-04-28 18:22:51 +0100
commit776b6c8a25a36b5f46ed182ed6514c208e76720d (patch)
tree78d2d101cc31f40680ef20d8a4204ad728e2bf99 /drivers/firmware/arm_scmi/base.c
parent3b0041f6e10e5bdbb646d98172be43e88734ed62 (diff)
downloadlinux-776b6c8a25a36b5f46ed182ed6514c208e76720d.tar.gz
linux-776b6c8a25a36b5f46ed182ed6514c208e76720d.tar.bz2
linux-776b6c8a25a36b5f46ed182ed6514c208e76720d.zip
firmware: arm_scmi: Dynamically allocate implemented protocols array
Move away from a statically allocated array for holding the current set of protocols implemented by the platform in favour of allocating it dynamically based on the number of protocols effectively advertised by the platform via BASE protocol exchanges. While at that, rectify the BASE_DISCOVER_LIST_PROTOCOLS loop iterations to terminate only when a number of protocols equal to the advertised ones has been received, instead of looping till the platform returns no more protocols descriptors. This new behaviour is better compliant with the specification and it has been tested to work equally well against an SCMI stack running on top of an official SCP firmware on a JUNO board. Link: https://lore.kernel.org/r/20220330150551.2573938-6-cristian.marussi@arm.com Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Diffstat (limited to 'drivers/firmware/arm_scmi/base.c')
-rw-r--r--drivers/firmware/arm_scmi/base.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c
index dc5b0c70a700..20fba7370f4e 100644
--- a/drivers/firmware/arm_scmi/base.c
+++ b/drivers/firmware/arm_scmi/base.c
@@ -178,6 +178,7 @@ scmi_base_implementation_list_get(const struct scmi_protocol_handle *ph,
__le32 *num_skip, *num_ret;
u32 tot_num_ret = 0, loop_num_ret;
struct device *dev = ph->dev;
+ struct scmi_revision_info *rev = ph->get_priv(ph);
ret = ph->xops->xfer_get_init(ph, BASE_DISCOVER_LIST_PROTOCOLS,
sizeof(*num_skip), 0, &t);
@@ -203,8 +204,9 @@ scmi_base_implementation_list_get(const struct scmi_protocol_handle *ph,
if (!loop_num_ret)
break;
- if (loop_num_ret > MAX_PROTOCOLS_IMP - tot_num_ret) {
- dev_err(dev, "No. of Protocol > MAX_PROTOCOLS_IMP");
+ if (loop_num_ret > rev->num_protocols - tot_num_ret) {
+ dev_err(dev,
+ "No. Returned protocols > Total protocols.\n");
break;
}
@@ -232,7 +234,7 @@ scmi_base_implementation_list_get(const struct scmi_protocol_handle *ph,
tot_num_ret += loop_num_ret;
ph->xops->reset_rx_to_maxsz(ph, t);
- } while (loop_num_ret);
+ } while (tot_num_ret < rev->num_protocols);
ph->xops->xfer_put(ph, t);
@@ -375,10 +377,6 @@ static int scmi_base_protocol_init(const struct scmi_protocol_handle *ph)
if (ret)
return ret;
- prot_imp = devm_kcalloc(dev, MAX_PROTOCOLS_IMP, sizeof(u8), GFP_KERNEL);
- if (!prot_imp)
- return -ENOMEM;
-
rev->major_ver = PROTOCOL_REV_MAJOR(version),
rev->minor_ver = PROTOCOL_REV_MINOR(version);
ph->set_priv(ph, rev);
@@ -387,6 +385,11 @@ static int scmi_base_protocol_init(const struct scmi_protocol_handle *ph)
if (ret)
return ret;
+ prot_imp = devm_kcalloc(dev, rev->num_protocols, sizeof(u8),
+ GFP_KERNEL);
+ if (!prot_imp)
+ return -ENOMEM;
+
scmi_base_vendor_id_get(ph, false);
scmi_base_vendor_id_get(ph, true);
scmi_base_implementation_version_get(ph);