firmware: arm_scmi: Add multiple protocols registration support
authorCristian Marussi <cristian.marussi@arm.com>
Thu, 21 Dec 2023 15:11:29 +0000 (15:11 +0000)
committerSudeep Holla <sudeep.holla@arm.com>
Tue, 20 Feb 2024 06:29:37 +0000 (06:29 +0000)
Add the capability for a SCMI driver to register to the core SCMI stack
with multiple SCMI protocols. In such a case the SCMI driver probe
function will end up being called once for each registered protocol
which have been also found as implemented on the platform.

This is especially useful in testing scenarios.

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

index c15928b8c5cc9976b9f12ca5a7e4154dcbb0e888..1f9735dbebec712f577898d914939682e50cbf1b 100644 (file)
@@ -141,6 +141,17 @@ out:
        return ret;
 }
 
+static int scmi_protocol_table_register(const struct scmi_device_id *id_table)
+{
+       int ret = 0;
+       const struct scmi_device_id *entry;
+
+       for (entry = id_table; entry->name && ret == 0; entry++)
+               ret = scmi_protocol_device_request(entry);
+
+       return ret;
+}
+
 /**
  * scmi_protocol_device_unrequest  - Helper to unrequest a device
  *
@@ -186,6 +197,15 @@ static void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table
        mutex_unlock(&scmi_requested_devices_mtx);
 }
 
+static void
+scmi_protocol_table_unregister(const struct scmi_device_id *id_table)
+{
+       const struct scmi_device_id *entry;
+
+       for (entry = id_table; entry->name; entry++)
+               scmi_protocol_device_unrequest(entry);
+}
+
 static const struct scmi_device_id *
 scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv)
 {
@@ -279,7 +299,7 @@ int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
        if (!driver->probe)
                return -EINVAL;
 
-       retval = scmi_protocol_device_request(driver->id_table);
+       retval = scmi_protocol_table_register(driver->id_table);
        if (retval)
                return retval;
 
@@ -299,7 +319,7 @@ EXPORT_SYMBOL_GPL(scmi_driver_register);
 void scmi_driver_unregister(struct scmi_driver *driver)
 {
        driver_unregister(&driver->driver);
-       scmi_protocol_device_unrequest(driver->id_table);
+       scmi_protocol_table_unregister(driver->id_table);
 }
 EXPORT_SYMBOL_GPL(scmi_driver_unregister);