#include <linux/io.h>
 #include <linux/io-64-nonatomic-hi-lo.h>
 #include <linux/kernel.h>
+#include <linux/kmod.h>
 #include <linux/ktime.h>
 #include <linux/hashtable.h>
 #include <linux/list.h>
 #define CREATE_TRACE_POINTS
 #include <trace/events/scmi.h>
 
+#define SCMI_VENDOR_MODULE_ALIAS_FMT   "scmi-protocol-0x%02x-%s"
+
 static DEFINE_IDA(scmi_id);
 
 static DEFINE_XARRAY(scmi_protocols);
        return proto;
 }
 
+static const struct scmi_protocol *
+scmi_vendor_protocol_get(int protocol_id, struct scmi_revision_info *version)
+{
+       const struct scmi_protocol *proto;
+
+       proto = scmi_vendor_protocol_lookup(protocol_id, version->vendor_id,
+                                           version->sub_vendor_id,
+                                           version->impl_ver);
+       if (!proto) {
+               int ret;
+
+               pr_debug("Looking for '" SCMI_VENDOR_MODULE_ALIAS_FMT "'\n",
+                        protocol_id, version->vendor_id);
+
+               /* Note that vendor_id is mandatory for vendor protocols */
+               ret = request_module(SCMI_VENDOR_MODULE_ALIAS_FMT,
+                                    protocol_id, version->vendor_id);
+               if (ret) {
+                       pr_warn("Problem loading module for protocol 0x%x\n",
+                               protocol_id);
+                       return NULL;
+               }
+
+               /* Lookup again, once modules loaded */
+               proto = scmi_vendor_protocol_lookup(protocol_id,
+                                                   version->vendor_id,
+                                                   version->sub_vendor_id,
+                                                   version->impl_ver);
+       }
+
+       if (proto)
+               pr_info("Loaded SCMI Vendor Protocol 0x%x - %s %s %X\n",
+                       protocol_id, proto->vendor_id ?: "",
+                       proto->sub_vendor_id ?: "", proto->impl_ver);
+
+       return proto;
+}
+
 static const struct scmi_protocol *
 scmi_protocol_get(int protocol_id, struct scmi_revision_info *version)
 {
        if (protocol_id < SCMI_PROTOCOL_VENDOR_BASE)
                proto = xa_load(&scmi_protocols, protocol_id);
        else
-               proto = scmi_vendor_protocol_lookup(protocol_id,
-                                                   version->vendor_id,
-                                                   version->sub_vendor_id,
-                                                   version->impl_ver);
+               proto = scmi_vendor_protocol_get(protocol_id, version);
+
        if (!proto || !try_module_get(proto->owner)) {
                pr_warn("SCMI Protocol 0x%x not found!\n", protocol_id);
                return NULL;
 
        pr_debug("Found SCMI Protocol 0x%x\n", protocol_id);
 
-       if (protocol_id >= SCMI_PROTOCOL_VENDOR_BASE)
-               pr_info("Loaded SCMI Vendor Protocol 0x%x - %s %s %X\n",
-                       protocol_id, proto->vendor_id ?: "",
-                       proto->sub_vendor_id ?: "", proto->impl_ver);
-
        return proto;
 }
 
                return ret;
        }
 
-       pr_debug("Registered SCMI Protocol 0x%x\n", proto->id);
+       pr_debug("Registered SCMI Protocol 0x%x - %s  %s  0x%08X\n",
+                proto->id, proto->vendor_id, proto->sub_vendor_id,
+                proto->impl_ver);
 
        return 0;
 }