mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Beleswar Padhi <b-padhi@ti.com>
To: <nm@ti.com>, <kristo@kernel.org>, <ssantosh@kernel.org>,
	<afd@ti.com>, <vigneshr@ti.com>, <u-kumar1@ti.com>
Cc: <linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>, <b-padhi@ti.com>
Subject: [PATCH 19/22] firmware: ti: ti_sci_clock: Move clock ops into its own file
Date: Wed, 30 Sep 2026 01:47:43 +0530	[thread overview]
Message-ID: <20260929201746.4078803-20-b-padhi@ti.com> (raw)
In-Reply-To: <20260929201746.4078803-1-b-padhi@ti.com>

From: Andrew Davis <afd@ti.com>

Extract the clock operations related functions and services from
ti_sci_core.c into its own file. This breaks down the single large
file into smaller logical files for better readability and maintenance.

Signed-off-by: Andrew Davis <afd@ti.com>
Signed-off-by: Beleswar Padhi <b-padhi@ti.com>
---
 drivers/firmware/ti/Makefile       |   1 +
 drivers/firmware/ti/ti_sci.h       |   1 +
 drivers/firmware/ti/ti_sci_clock.c | 553 +++++++++++++++++++++++++++++
 drivers/firmware/ti/ti_sci_core.c  | 535 +---------------------------
 4 files changed, 556 insertions(+), 534 deletions(-)
 create mode 100644 drivers/firmware/ti/ti_sci_clock.c

diff --git a/drivers/firmware/ti/Makefile b/drivers/firmware/ti/Makefile
index a3a056eedd9a5..c4233542ad57d 100644
--- a/drivers/firmware/ti/Makefile
+++ b/drivers/firmware/ti/Makefile
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 ti_sci-y			:= ti_sci_core.o
+ti_sci-y			+= ti_sci_clock.o
 ti_sci-y			+= ti_sci_device.o
 obj-$(CONFIG_TI_SCI_PROTOCOL)	+= ti_sci.o
diff --git a/drivers/firmware/ti/ti_sci.h b/drivers/firmware/ti/ti_sci.h
index 79f56699faf29..cce59cac35ed6 100644
--- a/drivers/firmware/ti/ti_sci.h
+++ b/drivers/firmware/ti/ti_sci.h
@@ -1566,5 +1566,6 @@ int ti_sci_do_xfer(const struct ti_sci_handle *handle,
 		   void *rx_message, size_t rx_message_size);
 
 void ti_sci_setup_device_ops(struct ti_sci_dev_ops *dops);
+void ti_sci_setup_clock_ops(struct ti_sci_clk_ops *cops);
 
 #endif /* __TI_SCI_H */
diff --git a/drivers/firmware/ti/ti_sci_clock.c b/drivers/firmware/ti/ti_sci_clock.c
new file mode 100644
index 0000000000000..f266522fb7d08
--- /dev/null
+++ b/drivers/firmware/ti/ti_sci_clock.c
@@ -0,0 +1,553 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Texas Instruments System Control Interface Protocol Driver
+ *
+ * Copyright (C) 2015-2026 Texas Instruments Incorporated - https://www.ti.com/
+ *	Nishanth Menon
+ */
+
+#include <linux/errno.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+
+#include "ti_sci.h"
+
+/**
+ * ti_sci_set_clock_state() - Set clock state helper
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @flags:	Header flags as needed
+ * @state:	State to request for the clock.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
+				  u32 dev_id, u32 clk_id,
+				  u32 flags, u8 state)
+{
+	struct ti_sci_msg_req_set_clock_state req;
+	struct ti_sci_msg_hdr resp;
+	int ret = 0;
+
+	req.dev_id = dev_id;
+	if (clk_id < 255) {
+		req.clk_id = clk_id;
+	} else {
+		req.clk_id = 255;
+		req.clk_id_32 = clk_id;
+	}
+	req.request_state = state;
+
+	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_SET_CLOCK_STATE,
+			     flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+			     &req, sizeof(req),
+			     &resp, sizeof(resp));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/**
+ * ti_sci_cmd_get_clock_state() - Get clock state helper
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @programmed_state:	State requested for clock to move to
+ * @current_state:	State that the clock is currently in
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle,
+				      u32 dev_id, u32 clk_id,
+				      u8 *programmed_state, u8 *current_state)
+{
+	struct ti_sci_msg_req_get_clock_state req;
+	struct ti_sci_msg_resp_get_clock_state resp;
+	int ret = 0;
+
+	if (!programmed_state && !current_state)
+		return -EINVAL;
+
+	req.dev_id = dev_id;
+	if (clk_id < 255) {
+		req.clk_id = clk_id;
+	} else {
+		req.clk_id = 255;
+		req.clk_id_32 = clk_id;
+	}
+
+	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_GET_CLOCK_STATE,
+			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+			     &req, sizeof(req),
+			     &resp, sizeof(resp));
+	if (ret)
+		return ret;
+
+	if (programmed_state)
+		*programmed_state = resp.programmed_state;
+	if (current_state)
+		*current_state = resp.current_state;
+
+	return 0;
+}
+
+/**
+ * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false'
+ * @can_change_freq: 'true' if frequency change is desired, else 'false'
+ * @enable_input_term: 'true' if input termination is desired, else 'false'
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id,
+				u32 clk_id, bool needs_ssc,
+				bool can_change_freq, bool enable_input_term)
+{
+	u32 flags = 0;
+
+	flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0;
+	flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0;
+	flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0;
+
+	return ti_sci_set_clock_state(handle, dev_id, clk_id, flags,
+				      MSG_CLOCK_SW_STATE_REQ);
+}
+
+/**
+ * ti_sci_cmd_idle_clock() - Idle a clock which is in our control
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ *
+ * NOTE: This clock must have been requested by get_clock previously.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle,
+				 u32 dev_id, u32 clk_id)
+{
+	return ti_sci_set_clock_state(handle, dev_id, clk_id,
+				      MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
+				      MSG_CLOCK_SW_STATE_UNREQ);
+}
+
+/**
+ * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ *
+ * NOTE: This clock must have been requested by get_clock previously.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle,
+				u32 dev_id, u32 clk_id)
+{
+	return ti_sci_set_clock_state(handle, dev_id, clk_id,
+				      MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
+				      MSG_CLOCK_SW_STATE_AUTO);
+}
+
+/**
+ * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @req_state: state indicating if the clock is auto managed
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle,
+				  u32 dev_id, u32 clk_id, bool *req_state)
+{
+	u8 state = 0;
+	int ret;
+
+	if (!req_state)
+		return -EINVAL;
+
+	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL);
+	if (ret)
+		return ret;
+
+	*req_state = (state == MSG_CLOCK_SW_STATE_AUTO);
+	return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_is_on() - Is the clock ON
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @req_state: state indicating if the clock is managed by us and enabled
+ * @curr_state: state indicating if the clock is ready for operation
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id,
+				u32 clk_id, bool *req_state, bool *curr_state)
+{
+	u8 c_state = 0, r_state = 0;
+	int ret;
+
+	if (!req_state && !curr_state)
+		return -EINVAL;
+
+	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
+					 &r_state, &c_state);
+	if (ret)
+		return ret;
+
+	if (req_state)
+		*req_state = (r_state == MSG_CLOCK_SW_STATE_REQ);
+	if (curr_state)
+		*curr_state = (c_state == MSG_CLOCK_HW_STATE_READY);
+	return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_is_off() - Is the clock OFF
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @req_state: state indicating if the clock is managed by us and disabled
+ * @curr_state: state indicating if the clock is NOT ready for operation
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id,
+				 u32 clk_id, bool *req_state, bool *curr_state)
+{
+	u8 c_state = 0, r_state = 0;
+	int ret;
+
+	if (!req_state && !curr_state)
+		return -EINVAL;
+
+	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
+					 &r_state, &c_state);
+	if (ret)
+		return ret;
+
+	if (req_state)
+		*req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ);
+	if (curr_state)
+		*curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY);
+	return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @parent_id:	Parent clock identifier to set
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
+				     u32 dev_id, u32 clk_id, u32 parent_id)
+{
+	struct ti_sci_msg_req_set_clock_parent req;
+	struct ti_sci_msg_hdr resp;
+	int ret = 0;
+
+	req.dev_id = dev_id;
+	if (clk_id < 255) {
+		req.clk_id = clk_id;
+	} else {
+		req.clk_id = 255;
+		req.clk_id_32 = clk_id;
+	}
+	if (parent_id < 255) {
+		req.parent_id = parent_id;
+	} else {
+		req.parent_id = 255;
+		req.parent_id_32 = parent_id;
+	}
+
+	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_SET_CLOCK_PARENT,
+			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+			     &req, sizeof(req),
+			     &resp, sizeof(resp));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_get_parent() - Get current parent clock source
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @parent_id:	Current clock parent
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle,
+				     u32 dev_id, u32 clk_id, u32 *parent_id)
+{
+	struct ti_sci_msg_req_get_clock_parent req;
+	struct ti_sci_msg_resp_get_clock_parent resp;
+	int ret = 0;
+
+	if (!parent_id)
+		return -EINVAL;
+
+	req.dev_id = dev_id;
+	if (clk_id < 255) {
+		req.clk_id = clk_id;
+	} else {
+		req.clk_id = 255;
+		req.clk_id_32 = clk_id;
+	}
+
+	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_GET_CLOCK_PARENT,
+			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+			     &req, sizeof(req),
+			     &resp, sizeof(resp));
+	if (ret)
+		return ret;
+
+	if (resp.parent_id < 255)
+		*parent_id = resp.parent_id;
+	else
+		*parent_id = resp.parent_id_32;
+
+	return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @num_parents: Returns he number of parents to the current clock.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle,
+					  u32 dev_id, u32 clk_id,
+					  u32 *num_parents)
+{
+	struct ti_sci_msg_req_get_clock_num_parents req;
+	struct ti_sci_msg_resp_get_clock_num_parents resp;
+	int ret = 0;
+
+	if (!num_parents)
+		return -EINVAL;
+
+	req.dev_id = dev_id;
+	if (clk_id < 255) {
+		req.clk_id = clk_id;
+	} else {
+		req.clk_id = 255;
+		req.clk_id_32 = clk_id;
+	}
+
+	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS,
+			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+			     &req, sizeof(req),
+			     &resp, sizeof(resp));
+	if (ret)
+		return ret;
+
+	if (resp.num_parents < 255)
+		*num_parents = resp.num_parents;
+	else
+		*num_parents = resp.num_parents_32;
+
+	return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @min_freq:	The minimum allowable frequency in Hz. This is the minimum
+ *		allowable programmed frequency and does not account for clock
+ *		tolerances and jitter.
+ * @target_freq: The target clock frequency in Hz. A frequency will be
+ *		processed as close to this target frequency as possible.
+ * @max_freq:	The maximum allowable frequency in Hz. This is the maximum
+ *		allowable programmed frequency and does not account for clock
+ *		tolerances and jitter.
+ * @match_freq:	Frequency match in Hz response.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
+					 u32 dev_id, u32 clk_id, u64 min_freq,
+					 u64 target_freq, u64 max_freq,
+					 u64 *match_freq)
+{
+	struct ti_sci_msg_req_query_clock_freq req;
+	struct ti_sci_msg_resp_query_clock_freq resp;
+	int ret = 0;
+
+	if (!match_freq)
+		return -EINVAL;
+
+	req.dev_id = dev_id;
+	if (clk_id < 255) {
+		req.clk_id = clk_id;
+	} else {
+		req.clk_id = 255;
+		req.clk_id_32 = clk_id;
+	}
+	req.min_freq_hz = min_freq;
+	req.target_freq_hz = target_freq;
+	req.max_freq_hz = max_freq;
+
+	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_QUERY_CLOCK_FREQ,
+			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+			     &req, sizeof(req),
+			     &resp, sizeof(resp));
+	if (ret)
+		return ret;
+
+	*match_freq = resp.freq_hz;
+
+	return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_set_freq() - Set a frequency for clock
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @min_freq:	The minimum allowable frequency in Hz. This is the minimum
+ *		allowable programmed frequency and does not account for clock
+ *		tolerances and jitter.
+ * @target_freq: The target clock frequency in Hz. A frequency will be
+ *		processed as close to this target frequency as possible.
+ * @max_freq:	The maximum allowable frequency in Hz. This is the maximum
+ *		allowable programmed frequency and does not account for clock
+ *		tolerances and jitter.
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
+				   u32 dev_id, u32 clk_id, u64 min_freq,
+				   u64 target_freq, u64 max_freq)
+{
+	struct ti_sci_msg_req_set_clock_freq req;
+	struct ti_sci_msg_hdr resp;
+	int ret = 0;
+
+	req.dev_id = dev_id;
+	if (clk_id < 255) {
+		req.clk_id = clk_id;
+	} else {
+		req.clk_id = 255;
+		req.clk_id_32 = clk_id;
+	}
+	req.min_freq_hz = min_freq;
+	req.target_freq_hz = target_freq;
+	req.max_freq_hz = max_freq;
+
+	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_SET_CLOCK_FREQ,
+			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+			     &req, sizeof(req),
+			     &resp, sizeof(resp));
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/**
+ * ti_sci_cmd_clk_get_freq() - Get current frequency
+ * @handle:	pointer to TI SCI handle
+ * @dev_id:	Device identifier this request is for
+ * @clk_id:	Clock identifier for the device for this request.
+ *		Each device has it's own set of clock inputs. This indexes
+ *		which clock input to modify.
+ * @freq:	Currently frequency in Hz
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
+				   u32 dev_id, u32 clk_id, u64 *freq)
+{
+	struct ti_sci_msg_req_get_clock_freq req;
+	struct ti_sci_msg_resp_get_clock_freq resp;
+	int ret = 0;
+
+	if (!freq)
+		return -EINVAL;
+
+	req.dev_id = dev_id;
+	if (clk_id < 255) {
+		req.clk_id = clk_id;
+	} else {
+		req.clk_id = 255;
+		req.clk_id_32 = clk_id;
+	}
+
+	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_GET_CLOCK_FREQ,
+			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+			     &req, sizeof(req),
+			     &resp, sizeof(resp));
+	if (ret)
+		return ret;
+
+	*freq = resp.freq_hz;
+
+	return 0;
+}
+
+/*
+ * ti_sci_setup_clock_ops() - Setup the clock operations structures
+ * @cops:	pointer to TISCI clock operations structure
+ */
+void ti_sci_setup_clock_ops(struct ti_sci_clk_ops *cops)
+{
+	cops->get_clock = ti_sci_cmd_get_clock;
+	cops->idle_clock = ti_sci_cmd_idle_clock;
+	cops->put_clock = ti_sci_cmd_put_clock;
+	cops->is_auto = ti_sci_cmd_clk_is_auto;
+	cops->is_on = ti_sci_cmd_clk_is_on;
+	cops->is_off = ti_sci_cmd_clk_is_off;
+
+	cops->set_parent = ti_sci_cmd_clk_set_parent;
+	cops->get_parent = ti_sci_cmd_clk_get_parent;
+	cops->get_num_parents = ti_sci_cmd_clk_get_num_parents;
+
+	cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
+	cops->set_freq = ti_sci_cmd_clk_set_freq;
+	cops->get_freq = ti_sci_cmd_clk_get_freq;
+}
diff --git a/drivers/firmware/ti/ti_sci_core.c b/drivers/firmware/ti/ti_sci_core.c
index e98bf3c5f9dc1..848c040f598e0 100644
--- a/drivers/firmware/ti/ti_sci_core.c
+++ b/drivers/firmware/ti/ti_sci_core.c
@@ -565,525 +565,6 @@ static int ti_sci_cmd_get_revision(struct ti_sci_info *info)
 	return 0;
 }
 
-/**
- * ti_sci_set_clock_state() - Set clock state helper
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @flags:	Header flags as needed
- * @state:	State to request for the clock.
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_set_clock_state(const struct ti_sci_handle *handle,
-				  u32 dev_id, u32 clk_id,
-				  u32 flags, u8 state)
-{
-	struct ti_sci_msg_req_set_clock_state req;
-	struct ti_sci_msg_hdr resp;
-	int ret = 0;
-
-	req.dev_id = dev_id;
-	if (clk_id < 255) {
-		req.clk_id = clk_id;
-	} else {
-		req.clk_id = 255;
-		req.clk_id_32 = clk_id;
-	}
-	req.request_state = state;
-
-	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_SET_CLOCK_STATE,
-			     flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
-			     &req, sizeof(req),
-			     &resp, sizeof(resp));
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
-/**
- * ti_sci_cmd_get_clock_state() - Get clock state helper
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @programmed_state:	State requested for clock to move to
- * @current_state:	State that the clock is currently in
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle,
-				      u32 dev_id, u32 clk_id,
-				      u8 *programmed_state, u8 *current_state)
-{
-	struct ti_sci_msg_req_get_clock_state req;
-	struct ti_sci_msg_resp_get_clock_state resp;
-	int ret = 0;
-
-	if (!programmed_state && !current_state)
-		return -EINVAL;
-
-	req.dev_id = dev_id;
-	if (clk_id < 255) {
-		req.clk_id = clk_id;
-	} else {
-		req.clk_id = 255;
-		req.clk_id_32 = clk_id;
-	}
-
-	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_GET_CLOCK_STATE,
-			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
-			     &req, sizeof(req),
-			     &resp, sizeof(resp));
-	if (ret)
-		return ret;
-
-	if (programmed_state)
-		*programmed_state = resp.programmed_state;
-	if (current_state)
-		*current_state = resp.current_state;
-
-	return 0;
-}
-
-/**
- * ti_sci_cmd_get_clock() - Get control of a clock from TI SCI
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @needs_ssc: 'true' if Spread Spectrum clock is desired, else 'false'
- * @can_change_freq: 'true' if frequency change is desired, else 'false'
- * @enable_input_term: 'true' if input termination is desired, else 'false'
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_get_clock(const struct ti_sci_handle *handle, u32 dev_id,
-				u32 clk_id, bool needs_ssc,
-				bool can_change_freq, bool enable_input_term)
-{
-	u32 flags = 0;
-
-	flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0;
-	flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0;
-	flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0;
-
-	return ti_sci_set_clock_state(handle, dev_id, clk_id, flags,
-				      MSG_CLOCK_SW_STATE_REQ);
-}
-
-/**
- * ti_sci_cmd_idle_clock() - Idle a clock which is in our control
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- *
- * NOTE: This clock must have been requested by get_clock previously.
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_idle_clock(const struct ti_sci_handle *handle,
-				 u32 dev_id, u32 clk_id)
-{
-	return ti_sci_set_clock_state(handle, dev_id, clk_id,
-				      MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
-				      MSG_CLOCK_SW_STATE_UNREQ);
-}
-
-/**
- * ti_sci_cmd_put_clock() - Release a clock from our control back to TISCI
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- *
- * NOTE: This clock must have been requested by get_clock previously.
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_put_clock(const struct ti_sci_handle *handle,
-				u32 dev_id, u32 clk_id)
-{
-	return ti_sci_set_clock_state(handle, dev_id, clk_id,
-				      MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE,
-				      MSG_CLOCK_SW_STATE_AUTO);
-}
-
-/**
- * ti_sci_cmd_clk_is_auto() - Is the clock being auto managed
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @req_state: state indicating if the clock is auto managed
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_clk_is_auto(const struct ti_sci_handle *handle,
-				  u32 dev_id, u32 clk_id, bool *req_state)
-{
-	u8 state = 0;
-	int ret;
-
-	if (!req_state)
-		return -EINVAL;
-
-	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id, &state, NULL);
-	if (ret)
-		return ret;
-
-	*req_state = (state == MSG_CLOCK_SW_STATE_AUTO);
-	return 0;
-}
-
-/**
- * ti_sci_cmd_clk_is_on() - Is the clock ON
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @req_state: state indicating if the clock is managed by us and enabled
- * @curr_state: state indicating if the clock is ready for operation
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_clk_is_on(const struct ti_sci_handle *handle, u32 dev_id,
-				u32 clk_id, bool *req_state, bool *curr_state)
-{
-	u8 c_state = 0, r_state = 0;
-	int ret;
-
-	if (!req_state && !curr_state)
-		return -EINVAL;
-
-	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
-					 &r_state, &c_state);
-	if (ret)
-		return ret;
-
-	if (req_state)
-		*req_state = (r_state == MSG_CLOCK_SW_STATE_REQ);
-	if (curr_state)
-		*curr_state = (c_state == MSG_CLOCK_HW_STATE_READY);
-	return 0;
-}
-
-/**
- * ti_sci_cmd_clk_is_off() - Is the clock OFF
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @req_state: state indicating if the clock is managed by us and disabled
- * @curr_state: state indicating if the clock is NOT ready for operation
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_clk_is_off(const struct ti_sci_handle *handle, u32 dev_id,
-				 u32 clk_id, bool *req_state, bool *curr_state)
-{
-	u8 c_state = 0, r_state = 0;
-	int ret;
-
-	if (!req_state && !curr_state)
-		return -EINVAL;
-
-	ret = ti_sci_cmd_get_clock_state(handle, dev_id, clk_id,
-					 &r_state, &c_state);
-	if (ret)
-		return ret;
-
-	if (req_state)
-		*req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ);
-	if (curr_state)
-		*curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY);
-	return 0;
-}
-
-/**
- * ti_sci_cmd_clk_set_parent() - Set the clock source of a specific device clock
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @parent_id:	Parent clock identifier to set
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle,
-				     u32 dev_id, u32 clk_id, u32 parent_id)
-{
-	struct ti_sci_msg_req_set_clock_parent req;
-	struct ti_sci_msg_hdr resp;
-	int ret = 0;
-
-	req.dev_id = dev_id;
-	if (clk_id < 255) {
-		req.clk_id = clk_id;
-	} else {
-		req.clk_id = 255;
-		req.clk_id_32 = clk_id;
-	}
-	if (parent_id < 255) {
-		req.parent_id = parent_id;
-	} else {
-		req.parent_id = 255;
-		req.parent_id_32 = parent_id;
-	}
-
-	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_SET_CLOCK_PARENT,
-			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
-			     &req, sizeof(req),
-			     &resp, sizeof(resp));
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
-/**
- * ti_sci_cmd_clk_get_parent() - Get current parent clock source
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @parent_id:	Current clock parent
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle,
-				     u32 dev_id, u32 clk_id, u32 *parent_id)
-{
-	struct ti_sci_msg_req_get_clock_parent req;
-	struct ti_sci_msg_resp_get_clock_parent resp;
-	int ret = 0;
-
-	if (!parent_id)
-		return -EINVAL;
-
-	req.dev_id = dev_id;
-	if (clk_id < 255) {
-		req.clk_id = clk_id;
-	} else {
-		req.clk_id = 255;
-		req.clk_id_32 = clk_id;
-	}
-
-	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_GET_CLOCK_PARENT,
-			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
-			     &req, sizeof(req),
-			     &resp, sizeof(resp));
-	if (ret)
-		return ret;
-
-	if (resp.parent_id < 255)
-		*parent_id = resp.parent_id;
-	else
-		*parent_id = resp.parent_id_32;
-
-	return 0;
-}
-
-/**
- * ti_sci_cmd_clk_get_num_parents() - Get num parents of the current clk source
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @num_parents: Returns he number of parents to the current clock.
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle,
-					  u32 dev_id, u32 clk_id,
-					  u32 *num_parents)
-{
-	struct ti_sci_msg_req_get_clock_num_parents req;
-	struct ti_sci_msg_resp_get_clock_num_parents resp;
-	int ret = 0;
-
-	if (!num_parents)
-		return -EINVAL;
-
-	req.dev_id = dev_id;
-	if (clk_id < 255) {
-		req.clk_id = clk_id;
-	} else {
-		req.clk_id = 255;
-		req.clk_id_32 = clk_id;
-	}
-
-	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_GET_NUM_CLOCK_PARENTS,
-			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
-			     &req, sizeof(req),
-			     &resp, sizeof(resp));
-	if (ret)
-		return ret;
-
-	if (resp.num_parents < 255)
-		*num_parents = resp.num_parents;
-	else
-		*num_parents = resp.num_parents_32;
-
-	return 0;
-}
-
-/**
- * ti_sci_cmd_clk_get_match_freq() - Find a good match for frequency
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @min_freq:	The minimum allowable frequency in Hz. This is the minimum
- *		allowable programmed frequency and does not account for clock
- *		tolerances and jitter.
- * @target_freq: The target clock frequency in Hz. A frequency will be
- *		processed as close to this target frequency as possible.
- * @max_freq:	The maximum allowable frequency in Hz. This is the maximum
- *		allowable programmed frequency and does not account for clock
- *		tolerances and jitter.
- * @match_freq:	Frequency match in Hz response.
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle,
-					 u32 dev_id, u32 clk_id, u64 min_freq,
-					 u64 target_freq, u64 max_freq,
-					 u64 *match_freq)
-{
-	struct ti_sci_msg_req_query_clock_freq req;
-	struct ti_sci_msg_resp_query_clock_freq resp;
-	int ret = 0;
-
-	if (!match_freq)
-		return -EINVAL;
-
-	req.dev_id = dev_id;
-	if (clk_id < 255) {
-		req.clk_id = clk_id;
-	} else {
-		req.clk_id = 255;
-		req.clk_id_32 = clk_id;
-	}
-	req.min_freq_hz = min_freq;
-	req.target_freq_hz = target_freq;
-	req.max_freq_hz = max_freq;
-
-	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_QUERY_CLOCK_FREQ,
-			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
-			     &req, sizeof(req),
-			     &resp, sizeof(resp));
-	if (ret)
-		return ret;
-
-	*match_freq = resp.freq_hz;
-
-	return 0;
-}
-
-/**
- * ti_sci_cmd_clk_set_freq() - Set a frequency for clock
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @min_freq:	The minimum allowable frequency in Hz. This is the minimum
- *		allowable programmed frequency and does not account for clock
- *		tolerances and jitter.
- * @target_freq: The target clock frequency in Hz. A frequency will be
- *		processed as close to this target frequency as possible.
- * @max_freq:	The maximum allowable frequency in Hz. This is the maximum
- *		allowable programmed frequency and does not account for clock
- *		tolerances and jitter.
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle,
-				   u32 dev_id, u32 clk_id, u64 min_freq,
-				   u64 target_freq, u64 max_freq)
-{
-	struct ti_sci_msg_req_set_clock_freq req;
-	struct ti_sci_msg_hdr resp;
-	int ret = 0;
-
-	req.dev_id = dev_id;
-	if (clk_id < 255) {
-		req.clk_id = clk_id;
-	} else {
-		req.clk_id = 255;
-		req.clk_id_32 = clk_id;
-	}
-	req.min_freq_hz = min_freq;
-	req.target_freq_hz = target_freq;
-	req.max_freq_hz = max_freq;
-
-	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_SET_CLOCK_FREQ,
-			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
-			     &req, sizeof(req),
-			     &resp, sizeof(resp));
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
-/**
- * ti_sci_cmd_clk_get_freq() - Get current frequency
- * @handle:	pointer to TI SCI handle
- * @dev_id:	Device identifier this request is for
- * @clk_id:	Clock identifier for the device for this request.
- *		Each device has it's own set of clock inputs. This indexes
- *		which clock input to modify.
- * @freq:	Currently frequency in Hz
- *
- * Return: 0 if all went well, else returns appropriate error value.
- */
-static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle,
-				   u32 dev_id, u32 clk_id, u64 *freq)
-{
-	struct ti_sci_msg_req_get_clock_freq req;
-	struct ti_sci_msg_resp_get_clock_freq resp;
-	int ret = 0;
-
-	if (!freq)
-		return -EINVAL;
-
-	req.dev_id = dev_id;
-	if (clk_id < 255) {
-		req.clk_id = clk_id;
-	} else {
-		req.clk_id = 255;
-		req.clk_id_32 = clk_id;
-	}
-
-	ret = ti_sci_do_xfer(handle, TI_SCI_MSG_GET_CLOCK_FREQ,
-			     TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
-			     &req, sizeof(req),
-			     &resp, sizeof(resp));
-	if (ret)
-		return ret;
-
-	*freq = resp.freq_hz;
-
-	return 0;
-}
-
 /**
  * ti_sci_cmd_prepare_sleep() - Prepare system for system suspend
  * @handle:		pointer to TI SCI handle
@@ -2223,21 +1704,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
 	struct ti_sci_proc_ops *pops = &ops->proc_ops;
 
 	ti_sci_setup_device_ops(dops);
-
-	cops->get_clock = ti_sci_cmd_get_clock;
-	cops->idle_clock = ti_sci_cmd_idle_clock;
-	cops->put_clock = ti_sci_cmd_put_clock;
-	cops->is_auto = ti_sci_cmd_clk_is_auto;
-	cops->is_on = ti_sci_cmd_clk_is_on;
-	cops->is_off = ti_sci_cmd_clk_is_off;
-
-	cops->set_parent = ti_sci_cmd_clk_set_parent;
-	cops->get_parent = ti_sci_cmd_clk_get_parent;
-	cops->get_num_parents = ti_sci_cmd_clk_get_num_parents;
-
-	cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
-	cops->set_freq = ti_sci_cmd_clk_set_freq;
-	cops->get_freq = ti_sci_cmd_clk_get_freq;
+	ti_sci_setup_clock_ops(cops);
 
 	if (info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED) {
 		pr_debug("detected DM managed LPM in fw_caps\n");
-- 
2.34.1


  parent reply	other threads:[~2026-09-29 20:19 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-29 20:17 [PATCH 00/22] Cleanup and Refactor TI-SCI driver Beleswar Padhi
2026-09-29 20:17 ` [PATCH 01/22] firmware: ti_sci: Move error message handling into ti_sci_get_one_xfer() Beleswar Padhi
2026-09-29 20:17 ` [PATCH 02/22] firmware: ti_sci: Move error message handling into ti_sci_do_xfer() Beleswar Padhi
2026-09-29 20:17 ` [PATCH 03/22] firmware: ti_sci: Move check for ACK " Beleswar Padhi
2026-09-29 20:17 ` [PATCH 04/22] firmware: ti_sci: Remove out of place RM debug messages Beleswar Padhi
2026-09-29 20:17 ` [PATCH 05/22] firmware: ti_sci: Name response variable resp for consistency Beleswar Padhi
2026-09-29 20:17 ` [PATCH 06/22] firmware: ti_sci: Handle xfer cleanup inside ti_sci_do_xfer() Beleswar Padhi
2026-09-29 20:17 ` [PATCH 07/22] firmware: ti_sci: Pass request struct into ti_sci_do_xfer() Beleswar Padhi
2026-09-29 20:17 ` [PATCH 08/22] firmware: ti_sci: Combine xfer allocation and transfer functions Beleswar Padhi
2026-09-29 20:17 ` [PATCH 09/22] firmware: ti_sci: Fetch info struct from handle inside ti_sci_do_xfer() Beleswar Padhi
2026-09-29 20:17 ` [PATCH 10/22] firmware: ti_sci: Use tx_message as message buffer directly Beleswar Padhi
2026-09-29 20:17 ` [PATCH 11/22] firmware: ti_sci: Use rx_message as message receive buffer Beleswar Padhi
2026-09-29 20:17 ` [PATCH 12/22] firmware: ti_sci: Fix some kernel-doc references in structs Beleswar Padhi
2026-09-29 20:17 ` [PATCH 13/22] soc: ti: ti_sci_protocol.h: Add missing documentation for structs Beleswar Padhi
2026-09-29 20:17 ` [PATCH 14/22] firmware: ti_sci: Do not export reboot control Beleswar Padhi
2026-09-29 20:17 ` [PATCH 15/22] firmware: ti_sci: Use pmops fxn pointers in suspend/resume hooks Beleswar Padhi
2026-09-29 20:17 ` [PATCH 16/22] firmware: ti_sci: Move the huge ti_sci file into its own directory Beleswar Padhi
2026-09-29 20:17 ` [PATCH 17/22] firmware: ti: ti_sci: Add missing includes for self-contained headers Beleswar Padhi
2026-09-29 20:17 ` [PATCH 18/22] firmware: ti: ti_sci_device: Move device ops into its own file Beleswar Padhi
2026-09-29 20:17 ` Beleswar Padhi [this message]
2026-09-29 20:17 ` [PATCH 20/22] firmware: ti: ti_sci_pm: Move pm " Beleswar Padhi
2026-09-29 20:17 ` [PATCH 21/22] firmware: ti: ti_sci_rm: Move rm " Beleswar Padhi
2026-09-29 20:17 ` [PATCH 22/22] firmware: ti: ti_sci_proc: Move processor " Beleswar Padhi
2026-09-30  5:38 ` [PATCH 00/22] Cleanup and Refactor TI-SCI driver Nishanth Menon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260929201746.4078803-20-b-padhi@ti.com \
    --to=b-padhi@ti.com \
    --cc=afd@ti.com \
    --cc=kristo@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nm@ti.com \
    --cc=ssantosh@kernel.org \
    --cc=u-kumar1@ti.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®