[PATCH v3 8/9] firmware: arm_scmi: Add scmi_driver optional setup/teardown callbacks

From: Cristian Marussi
Date: Mon Jun 27 2022 - 08:31:38 EST


Add optional .setup and .teardown methods to the scmi_driver descriptor:
such callbacks, if provided, will be called by the SCIM core at driver
registration time, so that, an SCMI driver, registered as usual with the
module_scmi_driver() helper macro, can provide custom callbacks to be
run once for all at module load/unload time to perform specific setup
or teardown operations before/after .probe and .remove steps.

Signed-off-by: Cristian Marussi <cristian.marussi@xxxxxxx>
---
drivers/firmware/arm_scmi/bus.c | 15 +++++++++++++--
include/linux/scmi_protocol.h | 2 ++
2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c
index f6fe723ab869..e95085a66bc4 100644
--- a/drivers/firmware/arm_scmi/bus.c
+++ b/drivers/firmware/arm_scmi/bus.c
@@ -132,12 +132,21 @@ int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
{
int retval;

- if (!driver->probe)
+ if (!driver->probe || !driver->id_table)
return -EINVAL;

+ if (driver->setup) {
+ retval = driver->setup();
+ if (retval)
+ return retval;
+ }
+
retval = scmi_protocol_device_request(driver->id_table);
- if (retval)
+ if (retval) {
+ if (driver->teardown)
+ driver->teardown();
return retval;
+ }

driver->driver.bus = &scmi_bus_type;
driver->driver.name = driver->name;
@@ -156,6 +165,8 @@ void scmi_driver_unregister(struct scmi_driver *driver)
{
driver_unregister(&driver->driver);
scmi_protocol_device_unrequest(driver->id_table);
+ if (driver->teardown)
+ driver->teardown();
}
EXPORT_SYMBOL_GPL(scmi_driver_unregister);

diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index ad9641dbdd25..a922707bdfe8 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -805,6 +805,8 @@ struct scmi_device_id {

struct scmi_driver {
const char *name;
+ int (*setup)(void);
+ void (*teardown)(void);
int (*probe)(struct scmi_device *sdev);
void (*remove)(struct scmi_device *sdev);
const struct scmi_device_id *id_table;
--
2.32.0