On 3/21/25 8:15 AM, Alice Guo (OSS) wrote:
[...]

@@ -352,6 +358,22 @@ static int scmi_fill_base_info(struct udevice *agent, 
struct udevice *dev)
        return 0;
  }
+static struct driver *scmi_proto_driver_get(unsigned int proto_id)
+{
+       struct scmi_proto_driver *start, *entry;
+       int n_ents;
+
+       start = ll_entry_start(struct scmi_proto_driver, scmi_proto_driver);
+       n_ents = ll_entry_count(struct scmi_proto_driver, scmi_proto_driver);
+
+       for (entry = start; entry != start + n_ents; entry++) {
+               if (entry->match->proto_id == proto_id)
+                       return entry->driver;
+       }
+
+       return NULL;
+}

Ideally, the addition of core code like scmi_proto_driver_get() should be a separate preparatory patch.

Please also make sure to convert the four SCMI protocol drivers to U_BOOT_SCMI_PROTO_DRIVER() , otherwise the code become inconsistent. That should be easy, since there are literally four SCMI protocol drivers.

  /*
   * SCMI agent devices binds devices of various uclasses depending on
   * the FDT description. scmi_bind_protocol() is a generic bind sequence
@@ -436,6 +458,9 @@ static int scmi_bind_protocols(struct udevice *dev)
                                drv = DM_DRIVER_GET(scmi_voltage_domain);
                        }
                        break;
+               case SCMI_PROTOCOL_ID_PINCTRL:
+                       drv = scmi_proto_driver_get(SCMI_PROTOCOL_ID_PINCTRL);

Please have a look at patch I just sent and give it a try:

[PATCH] power: regulator: scmi: Move regulator subnode hack to scmi_regulator

With that and the conversion above in place, you should be able to entirely eliminate this switch-case code and make use of the full potential of your newly added scmi_proto_driver_get(), this way:

diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c
index 09a25d0067c..98e0c4d7c93 100644
--- a/drivers/firmware/scmi/scmi_agent-uclass.c
+++ b/drivers/firmware/scmi/scmi_agent-uclass.c
@@ -431,34 +431,10 @@ static int scmi_bind_protocols(struct udevice *dev)

                drv = NULL;
                name = ofnode_get_name(node);
-               switch (protocol_id) {
-               case SCMI_PROTOCOL_ID_POWER_DOMAIN:
-                       if (CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN) &&
-                           scmi_protocol_is_supported(dev, protocol_id))
-                               drv = DM_DRIVER_GET(scmi_power_domain);
-                       break;
-               case SCMI_PROTOCOL_ID_CLOCK:
-                       if (CONFIG_IS_ENABLED(CLK_SCMI) &&
-                           scmi_protocol_is_supported(dev, protocol_id))
-                               drv = DM_DRIVER_GET(scmi_clock);
-                       break;
-               case SCMI_PROTOCOL_ID_RESET_DOMAIN:
-                       if (IS_ENABLED(CONFIG_RESET_SCMI) &&
-                           scmi_protocol_is_supported(dev, protocol_id))
-                               drv = DM_DRIVER_GET(scmi_reset_domain);
-                       break;
-               case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN:
-                       if (IS_ENABLED(CONFIG_DM_REGULATOR_SCMI) &&
-                           scmi_protocol_is_supported(dev, protocol_id))
-                               drv = DM_DRIVER_GET(scmi_voltage_domain);
-                       break;
-               case SCMI_PROTOCOL_ID_PINCTRL:
-                       drv = scmi_proto_driver_get(SCMI_PROTOCOL_ID_PINCTRL);
-                       break;
-               default:
-                       break;
-               }
+               if (!scmi_protocol_is_supported(dev, protocol_id))
+                       continue;

+               drv = scmi_proto_driver_get(protocol_id);
                if (!drv) {
                        dev_dbg(dev, "Ignore unsupported SCMI protocol %#x\n",
                                protocol_id);

+                       break;
                default:
                        break;
                }
diff --git a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c 
b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
index 0ed971369a3..dbd6ff437e5 100644
--- a/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
+++ b/drivers/pinctrl/nxp/pinctrl-imx-scmi.c
@@ -9,6 +9,7 @@
  #include <dm/device_compat.h>
  #include <dm/pinctrl.h>
  #include <scmi_agent.h>
+#include <scmi_agent-uclass.h>
  #include <scmi_protocols.h>
#include "pinctrl-imx.h"
@@ -150,3 +151,9 @@ U_BOOT_DRIVER(scmi_pinctrl_imx) = {
        .ops = &imx_scmi_pinctrl_ops,
        .flags = DM_FLAG_PRE_RELOC,
  };
+
+static struct scmi_proto_match match = {
+       .proto_id = SCMI_PROTOCOL_ID_PINCTRL,
+};


This should be a zero terminated array I think ?

static struct scmi_proto_match match[] = {
  { SCMI_PROTOCOL_ID_PINCTRL },
  { /* Sentinel */ }
};

[...]

Reply via email to