]> git.itanic.dy.fi Git - linux-stable/commitdiff
firmware: arm_scmi: Populate fastchannel info only if set operations are allowed
authorSudeep Holla <sudeep.holla@arm.com>
Mon, 13 Nov 2023 14:32:52 +0000 (14:32 +0000)
committerSudeep Holla <sudeep.holla@arm.com>
Mon, 13 Nov 2023 14:40:10 +0000 (14:40 +0000)
Certain SCMI performance domains may have restrictions on the set level
and/or limits operation. If the SCMI domain supports fastchannel and the
set operations are not allowed, then any attempts to fetch the fastchannel
information for set level and/or limits operation will result in the
SCMI platform returning SCMI_ERR_SUPPORT. However, since this information
about the domain is already known to the agent(OSPM here) obtained via
PERF_DOMAIN_ATTRIBUTES, the agent(OSPM) can avoid calls to the firmware
trying to fetch the fastchannel information for the same.

Add those checks and skip querying the fastchannel information from the
firmware based on the information collected during the domain enumeration
stage.

Link: https://lore.kernel.org/r/20231113143252.37160-1-sudeep.holla@arm.com
Reviewed-by: Cristian Marussi <cristian.marussi@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
drivers/firmware/arm_scmi/perf.c

index f5a063b0b1ab9c23d62a6910c6920479dc2d3428..36cdcfaf43247b723832db0010aff077deb0e0eb 100644 (file)
@@ -762,29 +762,36 @@ static void scmi_perf_domain_init_fc(const struct scmi_protocol_handle *ph,
                                     u32 domain, struct scmi_fc_info **p_fc)
 {
        struct scmi_fc_info *fc;
+       struct perf_dom_info *dom;
+
+       dom = scmi_perf_domain_lookup(ph, domain);
+       if (IS_ERR(dom))
+               return;
 
        fc = devm_kcalloc(ph->dev, PERF_FC_MAX, sizeof(*fc), GFP_KERNEL);
        if (!fc)
                return;
 
-       ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
-                                  PERF_LEVEL_SET, 4, domain,
-                                  &fc[PERF_FC_LEVEL].set_addr,
-                                  &fc[PERF_FC_LEVEL].set_db);
-
        ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
                                   PERF_LEVEL_GET, 4, domain,
                                   &fc[PERF_FC_LEVEL].get_addr, NULL);
 
-       ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
-                                  PERF_LIMITS_SET, 8, domain,
-                                  &fc[PERF_FC_LIMIT].set_addr,
-                                  &fc[PERF_FC_LIMIT].set_db);
-
        ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
                                   PERF_LIMITS_GET, 8, domain,
                                   &fc[PERF_FC_LIMIT].get_addr, NULL);
 
+       if (dom->info.set_perf)
+               ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
+                                          PERF_LEVEL_SET, 4, domain,
+                                          &fc[PERF_FC_LEVEL].set_addr,
+                                          &fc[PERF_FC_LEVEL].set_db);
+
+       if (dom->set_limits)
+               ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL,
+                                          PERF_LIMITS_SET, 8, domain,
+                                          &fc[PERF_FC_LIMIT].set_addr,
+                                          &fc[PERF_FC_LIMIT].set_db);
+
        *p_fc = fc;
 }