firmware: arm_scmi: Add atomic support to clock protocol
authorCristian Marussi <cristian.marussi@arm.com>
Thu, 17 Feb 2022 13:12:32 +0000 (13:12 +0000)
committerSudeep Holla <sudeep.holla@arm.com>
Mon, 21 Feb 2022 10:36:48 +0000 (10:36 +0000)
Introduce new _atomic variant for SCMI clock protocol operations related
to enable disable operations: when an atomic operation is required the xfer
poll_completion flag is set for that transaction.

Link: https://lore.kernel.org/r/20220217131234.50328-7-cristian.marussi@arm.com
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
drivers/firmware/arm_scmi/clock.c
include/linux/scmi_protocol.h

index 35b56c8..72f930c 100644 (file)
@@ -273,7 +273,7 @@ static int scmi_clock_rate_set(const struct scmi_protocol_handle *ph,
 
 static int
 scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
-                     u32 config)
+                     u32 config, bool atomic)
 {
        int ret;
        struct scmi_xfer *t;
@@ -284,6 +284,8 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
        if (ret)
                return ret;
 
+       t->hdr.poll_completion = atomic;
+
        cfg = t->tx.buf;
        cfg->id = cpu_to_le32(clk_id);
        cfg->attributes = cpu_to_le32(config);
@@ -296,12 +298,24 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
 
 static int scmi_clock_enable(const struct scmi_protocol_handle *ph, u32 clk_id)
 {
-       return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE);
+       return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, false);
 }
 
 static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id)
 {
-       return scmi_clock_config_set(ph, clk_id, 0);
+       return scmi_clock_config_set(ph, clk_id, 0, false);
+}
+
+static int scmi_clock_enable_atomic(const struct scmi_protocol_handle *ph,
+                                   u32 clk_id)
+{
+       return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, true);
+}
+
+static int scmi_clock_disable_atomic(const struct scmi_protocol_handle *ph,
+                                    u32 clk_id)
+{
+       return scmi_clock_config_set(ph, clk_id, 0, true);
 }
 
 static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)
@@ -330,6 +344,8 @@ static const struct scmi_clk_proto_ops clk_proto_ops = {
        .rate_set = scmi_clock_rate_set,
        .enable = scmi_clock_enable,
        .disable = scmi_clock_disable,
+       .enable_atomic = scmi_clock_enable_atomic,
+       .disable_atomic = scmi_clock_disable_atomic,
 };
 
 static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
index fdf6bd8..306e576 100644 (file)
@@ -82,6 +82,9 @@ struct scmi_clk_proto_ops {
                        u64 rate);
        int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id);
        int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id);
+       int (*enable_atomic)(const struct scmi_protocol_handle *ph, u32 clk_id);
+       int (*disable_atomic)(const struct scmi_protocol_handle *ph,
+                             u32 clk_id);
 };
 
 /**