[PATCH v10 19/24] firmware: arm_scmi: Add un-managed methods to get/put protocols operations
From: Cristian Marussi
Date: Sat Aug 15 2026 - 19:30:17 EST
Add a couple of simple common methods to be able to manually get and put
protocol operations to address situation in which devres managed methods
cannot be used.
Signed-off-by: Cristian Marussi <cristian.marussi@xxxxxxx>
---
drivers/firmware/arm_scmi/driver.c | 39 ++++++++++++++++++++++++++++++
include/linux/scmi_protocol.h | 7 ++++++
2 files changed, 46 insertions(+)
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index e02b4bfb4e4d..fd17adeed2d9 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -2570,6 +2570,31 @@ scmi_devm_protocol_get(struct scmi_device *sdev, u8 protocol_id,
return pi->proto->ops;
}
+/**
+ * scmi_protocol_operations_get - UnManaged get protocol operations
+ *
+ * @handle: A reference to the SCMI platform instance.
+ * @protocol_id: The protocol being released.
+ * @ph: A pointer reference used to pass back the associated protocol handle.
+ */
+static const void __must_check *
+scmi_protocol_operations_get(const struct scmi_handle *handle, u8 protocol_id,
+ struct scmi_protocol_handle **ph)
+{
+ struct scmi_protocol_instance *pi;
+
+ if (!ph)
+ return ERR_PTR(-EINVAL);
+
+ pi = scmi_get_protocol_instance(handle, protocol_id);
+ if (IS_ERR(pi))
+ return pi;
+
+ *ph = &pi->ph;
+
+ return pi->proto->ops;
+}
+
/**
* scmi_devm_protocol_acquire - Devres managed helper to get hold of a protocol
* @sdev: A reference to an scmi_device whose embedded struct device is to
@@ -2626,6 +2651,18 @@ static void scmi_devm_protocol_put(struct scmi_device *sdev, u8 protocol_id)
WARN_ON(ret);
}
+/**
+ * scmi_protocol_operations_put - UnManaged gut protocol operations
+ *
+ * @handle: A reference to the SCMI platform instance.
+ * @protocol_id: The protocol being released.
+ */
+static void scmi_protocol_operations_put(const struct scmi_handle *handle,
+ u8 protocol_id)
+{
+ scmi_protocol_release(handle, protocol_id);
+}
+
/**
* scmi_is_transport_atomic - Method to check if underlying transport for an
* SCMI instance is configured as atomic.
@@ -3340,6 +3377,8 @@ static int scmi_probe(struct platform_device *pdev)
handle->devm_protocol_acquire = scmi_devm_protocol_acquire;
handle->devm_protocol_get = scmi_devm_protocol_get;
handle->devm_protocol_put = scmi_devm_protocol_put;
+ handle->protocol_get = scmi_protocol_operations_get;
+ handle->protocol_put = scmi_protocol_operations_put;
handle->is_transport_atomic = scmi_is_transport_atomic;
/* Setup all channels described in the DT at first */
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index a85c00bf72f2..11ed0b95536e 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -1137,6 +1137,9 @@ struct scmi_notify_ops {
* @devm_protocol_get: devres managed method to acquire a protocol and get specific
* operations and a dedicated protocol handler
* @devm_protocol_put: devres managed method to release a protocol
+ * @protocol_get: unmanaged method to acquire a protocol and get specific
+ * operations and a dedicated protocol handler
+ * @protocol_put: unmanaged method to release a protocol
* @is_transport_atomic: method to check if the underlying transport for this
* instance handle is configured to support atomic
* transactions for commands.
@@ -1159,6 +1162,10 @@ struct scmi_handle {
(*devm_protocol_get)(struct scmi_device *sdev, u8 proto,
struct scmi_protocol_handle **ph);
void (*devm_protocol_put)(struct scmi_device *sdev, u8 proto);
+ const void __must_check *
+ (*protocol_get)(const struct scmi_handle *handle, u8 proto,
+ struct scmi_protocol_handle **ph);
+ void (*protocol_put)(const struct scmi_handle *handle, u8 proto);
bool (*is_transport_atomic)(const struct scmi_handle *handle,
unsigned int *atomic_threshold);
const struct scmi_notify_ops *notify_ops;
--
2.54.0