diff options
author | Cristian Marussi <cristian.marussi@arm.com> | 2022-12-22 19:50:43 +0100 |
---|---|---|
committer | Sudeep Holla <sudeep.holla@arm.com> | 2023-01-19 10:44:53 +0100 |
commit | 9115c20ac1ee9e92a3e751e352db818b7f95746a (patch) | |
tree | e92fd0a097b4cff076ec95ae5d3e32dae955d968 /drivers/firmware/arm_scmi/driver.c | |
parent | firmware: arm_scmi: Use dedicated devices to initialize channels (diff) | |
download | linux-9115c20ac1ee9e92a3e751e352db818b7f95746a.tar.xz linux-9115c20ac1ee9e92a3e751e352db818b7f95746a.zip |
firmware: arm_scmi: Move protocol registration helpers
Move protocol registration helpers and logic out of bus.c compilation
unit into driver.c.
No functional change.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Link: https://lore.kernel.org/r/20221222185049.737625-4-cristian.marussi@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Diffstat (limited to 'drivers/firmware/arm_scmi/driver.c')
-rw-r--r-- | drivers/firmware/arm_scmi/driver.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index f85b34e69d01..d1e32ea6d90a 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -51,6 +51,9 @@ enum scmi_error_codes { SCMI_ERR_PROTOCOL = -10,/* Protocol Error */ }; +static DEFINE_IDR(scmi_protocols); +static DEFINE_SPINLOCK(protocol_lock); + /* List of all SCMI devices active in system */ static LIST_HEAD(scmi_list); /* Protection for the entire list */ @@ -194,6 +197,70 @@ static inline int scmi_to_linux_errno(int errno) return -EIO; } +static const struct scmi_protocol *scmi_protocol_get(int protocol_id) +{ + const struct scmi_protocol *proto; + + proto = idr_find(&scmi_protocols, protocol_id); + 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); + + return proto; +} + +static void scmi_protocol_put(int protocol_id) +{ + const struct scmi_protocol *proto; + + proto = idr_find(&scmi_protocols, protocol_id); + if (proto) + module_put(proto->owner); +} + +int scmi_protocol_register(const struct scmi_protocol *proto) +{ + int ret; + + if (!proto) { + pr_err("invalid protocol\n"); + return -EINVAL; + } + + if (!proto->instance_init) { + pr_err("missing init for protocol 0x%x\n", proto->id); + return -EINVAL; + } + + spin_lock(&protocol_lock); + ret = idr_alloc(&scmi_protocols, (void *)proto, + proto->id, proto->id + 1, GFP_ATOMIC); + spin_unlock(&protocol_lock); + if (ret != proto->id) { + pr_err("unable to allocate SCMI idr slot for 0x%x - err %d\n", + proto->id, ret); + return ret; + } + + pr_debug("Registered SCMI Protocol 0x%x\n", proto->id); + + return 0; +} +EXPORT_SYMBOL_GPL(scmi_protocol_register); + +void scmi_protocol_unregister(const struct scmi_protocol *proto) +{ + spin_lock(&protocol_lock); + idr_remove(&scmi_protocols, proto->id); + spin_unlock(&protocol_lock); + + pr_debug("Unregistered SCMI Protocol 0x%x\n", proto->id); +} +EXPORT_SYMBOL_GPL(scmi_protocol_unregister); + void scmi_notification_instance_data_set(const struct scmi_handle *handle, void *priv) { |