firmware: arm_scmi: Make protocols initialisation fail on basic errors
authorCristian Marussi <cristian.marussi@arm.com>
Wed, 30 Mar 2022 15:05:31 +0000 (16:05 +0100)
committerSudeep Holla <sudeep.holla@arm.com>
Thu, 28 Apr 2022 09:47:19 +0000 (10:47 +0100)
Bail out of protocol initialisation routine early when basic information
about protocol version and attributes could not be retrieved. Failing to
act this way can lead to a successfully initialized SCMI protocol which
is in fact not fully functional.

Link: https://lore.kernel.org/r/20220330150551.2573938-3-cristian.marussi@arm.com
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
drivers/firmware/arm_scmi/base.c
drivers/firmware/arm_scmi/clock.c
drivers/firmware/arm_scmi/perf.c
drivers/firmware/arm_scmi/power.c
drivers/firmware/arm_scmi/reset.c
drivers/firmware/arm_scmi/sensors.c
drivers/firmware/arm_scmi/system.c

index f521933..ebaef5d 100644 (file)
@@ -359,7 +359,10 @@ static int scmi_base_protocol_init(const struct scmi_protocol_handle *ph)
        rev->minor_ver = PROTOCOL_REV_MINOR(version);
        ph->set_priv(ph, rev);
 
-       scmi_base_attributes_get(ph);
+       ret = scmi_base_attributes_get(ph);
+       if (ret)
+               return ret;
+
        scmi_base_vendor_id_get(ph, false);
        scmi_base_vendor_id_get(ph, true);
        scmi_base_implementation_version_get(ph);
index 45600ac..9f61020 100644 (file)
@@ -361,7 +361,9 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
        int clkid, ret;
        struct clock_info *cinfo;
 
-       ph->xops->version_get(ph, &version);
+       ret = ph->xops->version_get(ph, &version);
+       if (ret)
+               return ret;
 
        dev_dbg(ph->dev, "Clock Version %d.%d\n",
                PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
@@ -370,7 +372,9 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
        if (!cinfo)
                return -ENOMEM;
 
-       scmi_clock_protocol_attributes_get(ph, cinfo);
+       ret = scmi_clock_protocol_attributes_get(ph, cinfo);
+       if (ret)
+               return ret;
 
        cinfo->clk = devm_kcalloc(ph->dev, cinfo->num_clocks,
                                  sizeof(*cinfo->clk), GFP_KERNEL);
index f4cd519..e9f68b9 100644 (file)
@@ -873,11 +873,13 @@ static const struct scmi_protocol_events perf_protocol_events = {
 
 static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph)
 {
-       int domain;
+       int domain, ret;
        u32 version;
        struct scmi_perf_info *pinfo;
 
-       ph->xops->version_get(ph, &version);
+       ret = ph->xops->version_get(ph, &version);
+       if (ret)
+               return ret;
 
        dev_dbg(ph->dev, "Performance Version %d.%d\n",
                PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
@@ -886,7 +888,9 @@ static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph)
        if (!pinfo)
                return -ENOMEM;
 
-       scmi_perf_attributes_get(ph, pinfo);
+       ret = scmi_perf_attributes_get(ph, pinfo);
+       if (ret)
+               return ret;
 
        pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains,
                                       sizeof(*pinfo->dom_info), GFP_KERNEL);
index ad2ab08..0f0b94f 100644 (file)
@@ -280,11 +280,13 @@ static const struct scmi_protocol_events power_protocol_events = {
 
 static int scmi_power_protocol_init(const struct scmi_protocol_handle *ph)
 {
-       int domain;
+       int domain, ret;
        u32 version;
        struct scmi_power_info *pinfo;
 
-       ph->xops->version_get(ph, &version);
+       ret = ph->xops->version_get(ph, &version);
+       if (ret)
+               return ret;
 
        dev_dbg(ph->dev, "Power Version %d.%d\n",
                PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
@@ -293,7 +295,9 @@ static int scmi_power_protocol_init(const struct scmi_protocol_handle *ph)
        if (!pinfo)
                return -ENOMEM;
 
-       scmi_power_attributes_get(ph, pinfo);
+       ret = scmi_power_attributes_get(ph, pinfo);
+       if (ret)
+               return ret;
 
        pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains,
                                       sizeof(*pinfo->dom_info), GFP_KERNEL);
index 9bf2478..9cdbd13 100644 (file)
@@ -293,11 +293,13 @@ static const struct scmi_protocol_events reset_protocol_events = {
 
 static int scmi_reset_protocol_init(const struct scmi_protocol_handle *ph)
 {
-       int domain;
+       int domain, ret;
        u32 version;
        struct scmi_reset_info *pinfo;
 
-       ph->xops->version_get(ph, &version);
+       ret = ph->xops->version_get(ph, &version);
+       if (ret)
+               return ret;
 
        dev_dbg(ph->dev, "Reset Version %d.%d\n",
                PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
@@ -306,7 +308,9 @@ static int scmi_reset_protocol_init(const struct scmi_protocol_handle *ph)
        if (!pinfo)
                return -ENOMEM;
 
-       scmi_reset_attributes_get(ph, pinfo);
+       ret = scmi_reset_attributes_get(ph, pinfo);
+       if (ret)
+               return ret;
 
        pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains,
                                       sizeof(*pinfo->dom_info), GFP_KERNEL);
index cdbb287..f37ac98 100644 (file)
@@ -966,7 +966,9 @@ static int scmi_sensors_protocol_init(const struct scmi_protocol_handle *ph)
        int ret;
        struct sensors_info *sinfo;
 
-       ph->xops->version_get(ph, &version);
+       ret = ph->xops->version_get(ph, &version);
+       if (ret)
+               return ret;
 
        dev_dbg(ph->dev, "Sensor Version %d.%d\n",
                PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
index e5175ef..cbfc19f 100644 (file)
@@ -113,10 +113,13 @@ static const struct scmi_protocol_events system_protocol_events = {
 
 static int scmi_system_protocol_init(const struct scmi_protocol_handle *ph)
 {
+       int ret;
        u32 version;
        struct scmi_system_info *pinfo;
 
-       ph->xops->version_get(ph, &version);
+       ret = ph->xops->version_get(ph, &version);
+       if (ret)
+               return ret;
 
        dev_dbg(ph->dev, "System Power Version %d.%d\n",
                PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));