dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
To: Rob Clark <robdclark@gmail.com>, Sean Paul <sean@poorly.run>,
	Jonathan Marek <jonathan@marek.ca>
Cc: Stephen Boyd <sboyd@kernel.org>,
	linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org,
	David Airlie <airlied@linux.ie>,
	freedreno@lists.freedesktop.org
Subject: [PATCH 19/21] drm/msm/dpu: call hw_vbif ops directly
Date: Wed, 24 Mar 2021 18:00:22 +0300	[thread overview]
Message-ID: <20210324150024.2768215-20-dmitry.baryshkov@linaro.org> (raw)
In-Reply-To: <20210324150024.2768215-1-dmitry.baryshkov@linaro.org>

Replace dpu_hw_vbif callbacks with direct functions calls.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c |  30 +---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h | 159 ++++++++++----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c    |  39 ++---
 3 files changed, 100 insertions(+), 128 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c
index 377d5e8ae615..d7d2e7edc0e3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.c
@@ -32,7 +32,7 @@
 #define VBIF_XINL_QOS_RP_REMAP_000	0x0550
 #define VBIF_XINL_QOS_LVL_REMAP_000(v)	(v < DPU_HW_VER_400 ? 0x570 : 0x0590)
 
-static void dpu_hw_clear_errors(struct dpu_hw_vbif *vbif,
+void dpu_hw_vbif_clear_errors(struct dpu_hw_vbif *vbif,
 		u32 *pnd_errors, u32 *src_errors)
 {
 	struct dpu_hw_blk_reg_map *c;
@@ -52,7 +52,7 @@ static void dpu_hw_clear_errors(struct dpu_hw_vbif *vbif,
 	DPU_REG_WRITE(c, VBIF_XIN_CLR_ERR, pnd | src);
 }
 
-static void dpu_hw_set_mem_type(struct dpu_hw_vbif *vbif,
+void dpu_hw_vbif_set_mem_type(struct dpu_hw_vbif *vbif,
 		u32 xin_id, u32 value)
 {
 	struct dpu_hw_blk_reg_map *c;
@@ -82,7 +82,7 @@ static void dpu_hw_set_mem_type(struct dpu_hw_vbif *vbif,
 	DPU_REG_WRITE(c, reg_off, reg_val);
 }
 
-static void dpu_hw_set_limit_conf(struct dpu_hw_vbif *vbif,
+void dpu_hw_vbif_set_limit_conf(struct dpu_hw_vbif *vbif,
 		u32 xin_id, bool rd, u32 limit)
 {
 	struct dpu_hw_blk_reg_map *c = &vbif->hw;
@@ -103,7 +103,7 @@ static void dpu_hw_set_limit_conf(struct dpu_hw_vbif *vbif,
 	DPU_REG_WRITE(c, reg_off, reg_val);
 }
 
-static u32 dpu_hw_get_limit_conf(struct dpu_hw_vbif *vbif,
+u32 dpu_hw_vbif_get_limit_conf(struct dpu_hw_vbif *vbif,
 		u32 xin_id, bool rd)
 {
 	struct dpu_hw_blk_reg_map *c = &vbif->hw;
@@ -125,7 +125,7 @@ static u32 dpu_hw_get_limit_conf(struct dpu_hw_vbif *vbif,
 	return limit;
 }
 
-static void dpu_hw_set_halt_ctrl(struct dpu_hw_vbif *vbif,
+void dpu_hw_vbif_set_halt_ctrl(struct dpu_hw_vbif *vbif,
 		u32 xin_id, bool enable)
 {
 	struct dpu_hw_blk_reg_map *c = &vbif->hw;
@@ -141,7 +141,7 @@ static void dpu_hw_set_halt_ctrl(struct dpu_hw_vbif *vbif,
 	DPU_REG_WRITE(c, VBIF_XIN_HALT_CTRL0, reg_val);
 }
 
-static bool dpu_hw_get_halt_ctrl(struct dpu_hw_vbif *vbif,
+bool dpu_hw_vbif_get_halt_ctrl(struct dpu_hw_vbif *vbif,
 		u32 xin_id)
 {
 	struct dpu_hw_blk_reg_map *c = &vbif->hw;
@@ -152,7 +152,7 @@ static bool dpu_hw_get_halt_ctrl(struct dpu_hw_vbif *vbif,
 	return (reg_val & BIT(xin_id)) ? true : false;
 }
 
-static void dpu_hw_set_qos_remap(struct dpu_hw_vbif *vbif,
+void dpu_hw_vbif_set_qos_remap(struct dpu_hw_vbif *vbif,
 		u32 xin_id, u32 level, u32 remap_level)
 {
 	struct dpu_hw_blk_reg_map *c;
@@ -182,7 +182,7 @@ static void dpu_hw_set_qos_remap(struct dpu_hw_vbif *vbif,
 	DPU_REG_WRITE(c, reg_lvl + reg_high, reg_val_lvl);
 }
 
-static void dpu_hw_set_write_gather_en(struct dpu_hw_vbif *vbif, u32 xin_id)
+void dpu_hw_vbif_set_write_gather_en(struct dpu_hw_vbif *vbif, u32 xin_id)
 {
 	struct dpu_hw_blk_reg_map *c;
 	u32 reg_val;
@@ -197,19 +197,6 @@ static void dpu_hw_set_write_gather_en(struct dpu_hw_vbif *vbif, u32 xin_id)
 	DPU_REG_WRITE(c, VBIF_WRITE_GATHER_EN, reg_val);
 }
 
-static void _setup_vbif_ops(struct dpu_hw_vbif_ops *ops,
-		unsigned long cap)
-{
-	ops->set_limit_conf = dpu_hw_set_limit_conf;
-	ops->get_limit_conf = dpu_hw_get_limit_conf;
-	ops->set_halt_ctrl = dpu_hw_set_halt_ctrl;
-	ops->get_halt_ctrl = dpu_hw_get_halt_ctrl;
-	ops->set_qos_remap = dpu_hw_set_qos_remap;
-	ops->set_mem_type = dpu_hw_set_mem_type;
-	ops->clear_errors = dpu_hw_clear_errors;
-	ops->set_write_gather_en = dpu_hw_set_write_gather_en;
-}
-
 static const struct dpu_vbif_cfg *_top_offset(enum dpu_vbif vbif,
 		const struct dpu_mdss_cfg *m,
 		void __iomem *addr,
@@ -253,7 +240,6 @@ struct dpu_hw_vbif *dpu_hw_vbif_init(enum dpu_vbif idx,
 	 */
 	c->idx = idx;
 	c->cap = cfg;
-	_setup_vbif_ops(&c->ops, c->cap->features);
 
 	/* no need to register sub-range in dpu dbg, dump entire vbif io base */
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h
index 6417aa28d32c..7a81f0729d9b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h
@@ -11,87 +11,85 @@
 
 struct dpu_hw_vbif;
 
-/**
- * struct dpu_hw_vbif_ops : Interface to the VBIF hardware driver functions
+/*
  *  Assumption is these functions will be called after clocks are enabled
  */
-struct dpu_hw_vbif_ops {
-	/**
-	 * set_limit_conf - set transaction limit config
-	 * @vbif: vbif context driver
-	 * @xin_id: client interface identifier
-	 * @rd: true for read limit; false for write limit
-	 * @limit: outstanding transaction limit
-	 */
-	void (*set_limit_conf)(struct dpu_hw_vbif *vbif,
-			u32 xin_id, bool rd, u32 limit);
-
-	/**
-	 * get_limit_conf - get transaction limit config
-	 * @vbif: vbif context driver
-	 * @xin_id: client interface identifier
-	 * @rd: true for read limit; false for write limit
-	 * @return: outstanding transaction limit
-	 */
-	u32 (*get_limit_conf)(struct dpu_hw_vbif *vbif,
-			u32 xin_id, bool rd);
-
-	/**
-	 * set_halt_ctrl - set halt control
-	 * @vbif: vbif context driver
-	 * @xin_id: client interface identifier
-	 * @enable: halt control enable
-	 */
-	void (*set_halt_ctrl)(struct dpu_hw_vbif *vbif,
-			u32 xin_id, bool enable);
-
-	/**
-	 * get_halt_ctrl - get halt control
-	 * @vbif: vbif context driver
-	 * @xin_id: client interface identifier
-	 * @return: halt control enable
-	 */
-	bool (*get_halt_ctrl)(struct dpu_hw_vbif *vbif,
-			u32 xin_id);
-
-	/**
-	 * set_qos_remap - set QoS priority remap
-	 * @vbif: vbif context driver
-	 * @xin_id: client interface identifier
-	 * @level: priority level
-	 * @remap_level: remapped level
-	 */
-	void (*set_qos_remap)(struct dpu_hw_vbif *vbif,
-			u32 xin_id, u32 level, u32 remap_level);
-
-	/**
-	 * set_mem_type - set memory type
-	 * @vbif: vbif context driver
-	 * @xin_id: client interface identifier
-	 * @value: memory type value
-	 */
-	void (*set_mem_type)(struct dpu_hw_vbif *vbif,
-			u32 xin_id, u32 value);
-
-	/**
-	 * clear_errors - clear any vbif errors
-	 *	This function clears any detected pending/source errors
-	 *	on the VBIF interface, and optionally returns the detected
-	 *	error mask(s).
-	 * @vbif: vbif context driver
-	 * @pnd_errors: pointer to pending error reporting variable
-	 * @src_errors: pointer to source error reporting variable
-	 */
-	void (*clear_errors)(struct dpu_hw_vbif *vbif,
-		u32 *pnd_errors, u32 *src_errors);
-
-	/**
-	 * set_write_gather_en - set write_gather enable
-	 * @vbif: vbif context driver
-	 * @xin_id: client interface identifier
-	 */
-	void (*set_write_gather_en)(struct dpu_hw_vbif *vbif, u32 xin_id);
-};
+
+/**
+ * dpu_hw_vbif_set_limit_conf - set transaction limit config
+ * @vbif: vbif context driver
+ * @xin_id: client interface identifier
+ * @rd: true for read limit; false for write limit
+ * @limit: outstanding transaction limit
+ */
+void dpu_hw_vbif_set_limit_conf(struct dpu_hw_vbif *vbif,
+		u32 xin_id, bool rd, u32 limit);
+
+/**
+ * dpu_hw_vbif_get_limit_conf - get transaction limit config
+ * @vbif: vbif context driver
+ * @xin_id: client interface identifier
+ * @rd: true for read limit; false for write limit
+ * @return: outstanding transaction limit
+ */
+u32 dpu_hw_vbif_get_limit_conf(struct dpu_hw_vbif *vbif,
+		u32 xin_id, bool rd);
+
+/**
+ * dpu_hw_vbif_set_halt_ctrl - set halt control
+ * @vbif: vbif context driver
+ * @xin_id: client interface identifier
+ * @enable: halt control enable
+ */
+void dpu_hw_vbif_set_halt_ctrl(struct dpu_hw_vbif *vbif,
+		u32 xin_id, bool enable);
+
+/**
+ * dpu_hw_vbif_get_halt_ctrl - get halt control
+ * @vbif: vbif context driver
+ * @xin_id: client interface identifier
+ * @return: halt control enable
+ */
+bool dpu_hw_vbif_get_halt_ctrl(struct dpu_hw_vbif *vbif,
+		u32 xin_id);
+
+/**
+ * dpu_hw_vbif_set_qos_remap - set QoS priority remap
+ * @vbif: vbif context driver
+ * @xin_id: client interface identifier
+ * @level: priority level
+ * @remap_level: remapped level
+ */
+void dpu_hw_vbif_set_qos_remap(struct dpu_hw_vbif *vbif,
+		u32 xin_id, u32 level, u32 remap_level);
+
+/**
+ * dpu_hw_vbif_set_mem_type - set memory type
+ * @vbif: vbif context driver
+ * @xin_id: client interface identifier
+ * @value: memory type value
+ */
+void dpu_hw_vbif_set_mem_type(struct dpu_hw_vbif *vbif,
+		u32 xin_id, u32 value);
+
+/**
+ * dpu_hw_vbif_clear_errors - clear any vbif errors
+ *	This function clears any detected pending/source errors
+ *	on the VBIF interface, and optionally returns the detected
+ *	error mask(s).
+ * @vbif: vbif context driver
+ * @pnd_errors: pointer to pending error reporting variable
+ * @src_errors: pointer to source error reporting variable
+ */
+void dpu_hw_vbif_clear_errors(struct dpu_hw_vbif *vbif,
+	u32 *pnd_errors, u32 *src_errors);
+
+/**
+ * dpu_hw_vbif_set_write_gather_en - set write_gather enable
+ * @vbif: vbif context driver
+ * @xin_id: client interface identifier
+ */
+void dpu_hw_vbif_set_write_gather_en(struct dpu_hw_vbif *vbif, u32 xin_id);
 
 struct dpu_hw_vbif {
 	/* base */
@@ -100,9 +98,6 @@ struct dpu_hw_vbif {
 	/* vbif */
 	enum dpu_vbif idx;
 	const struct dpu_vbif_cfg *cap;
-
-	/* ops */
-	struct dpu_hw_vbif_ops ops;
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
index c9351c69834a..776da9e834a0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
@@ -23,18 +23,18 @@ static int _dpu_vbif_wait_for_xin_halt(struct dpu_hw_vbif *vbif, u32 xin_id)
 	bool status;
 	int rc;
 
-	if (!vbif || !vbif->cap || !vbif->ops.get_halt_ctrl) {
+	if (!vbif || !vbif->cap) {
 		DPU_ERROR("invalid arguments vbif %d\n", vbif != NULL);
 		return -EINVAL;
 	}
 
 	timeout = ktime_add_us(ktime_get(), vbif->cap->xin_halt_timeout);
 	for (;;) {
-		status = vbif->ops.get_halt_ctrl(vbif, xin_id);
+		status = dpu_hw_vbif_get_halt_ctrl(vbif, xin_id);
 		if (status)
 			break;
 		if (ktime_compare_safe(ktime_get(), timeout) > 0) {
-			status = vbif->ops.get_halt_ctrl(vbif, xin_id);
+			status = dpu_hw_vbif_get_halt_ctrl(vbif, xin_id);
 			break;
 		}
 		usleep_range(501, 1000);
@@ -125,8 +125,8 @@ static u32 _dpu_vbif_get_ot_limit(struct dpu_hw_vbif *vbif,
 	/* Modify the limits if the target and the use case requires it */
 	_dpu_vbif_apply_dynamic_ot_limit(vbif, &ot_lim, params);
 
-	if (vbif && vbif->ops.get_limit_conf) {
-		val = vbif->ops.get_limit_conf(vbif,
+	if (vbif) {
+		val = dpu_hw_vbif_get_limit_conf(vbif,
 				params->xin_id, params->rd);
 		if (val == ot_lim)
 			ot_lim = 0;
@@ -168,13 +168,9 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,
 		return;
 	}
 
-	if (!vbif->ops.set_limit_conf ||
-	    !vbif->ops.set_halt_ctrl)
-		return;
-
 	/* set write_gather_en for all write clients */
-	if (vbif->ops.set_write_gather_en && !params->rd)
-		vbif->ops.set_write_gather_en(vbif, params->xin_id);
+	if (!params->rd)
+		dpu_hw_vbif_set_write_gather_en(vbif, params->xin_id);
 
 	ot_lim = _dpu_vbif_get_ot_limit(vbif, params) & 0xFF;
 
@@ -186,15 +182,15 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,
 
 	forced_on = dpu_hw_setup_clk_force_ctrl(mdp, params->clk_ctrl, true);
 
-	vbif->ops.set_limit_conf(vbif, params->xin_id, params->rd, ot_lim);
+	dpu_hw_vbif_set_limit_conf(vbif, params->xin_id, params->rd, ot_lim);
 
-	vbif->ops.set_halt_ctrl(vbif, params->xin_id, true);
+	dpu_hw_vbif_set_halt_ctrl(vbif, params->xin_id, true);
 
 	ret = _dpu_vbif_wait_for_xin_halt(vbif, params->xin_id);
 	if (ret)
 		trace_dpu_vbif_wait_xin_halt_fail(vbif->idx, params->xin_id);
 
-	vbif->ops.set_halt_ctrl(vbif, params->xin_id, false);
+	dpu_hw_vbif_set_halt_ctrl(vbif, params->xin_id, false);
 
 	if (forced_on)
 		dpu_hw_setup_clk_force_ctrl(mdp, params->clk_ctrl, false);
@@ -228,11 +224,6 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
 		return;
 	}
 
-	if (!vbif->ops.set_qos_remap) {
-		DPU_DEBUG("qos remap not supported\n");
-		return;
-	}
-
 	qos_tbl = params->is_rt ? &vbif->cap->qos_rt_tbl :
 			&vbif->cap->qos_nrt_tbl;
 
@@ -247,7 +238,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
 		DPU_DEBUG("vbif:%d xin:%d lvl:%d/%d\n",
 				params->vbif_idx, params->xin_id, i,
 				qos_tbl->priority_lvl[i]);
-		vbif->ops.set_qos_remap(vbif, params->xin_id, i,
+		dpu_hw_vbif_set_qos_remap(vbif, params->xin_id, i,
 				qos_tbl->priority_lvl[i]);
 	}
 
@@ -262,8 +253,8 @@ void dpu_vbif_clear_errors(struct dpu_kms *dpu_kms)
 
 	for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
 		vbif = dpu_kms->hw_vbif[i];
-		if (vbif && vbif->ops.clear_errors) {
-			vbif->ops.clear_errors(vbif, &pnd, &src);
+		if (vbif) {
+			dpu_hw_vbif_clear_errors(vbif, &pnd, &src);
 			if (pnd || src) {
 				DRM_DEBUG_KMS("VBIF %d: pnd 0x%X, src 0x%X\n",
 					      vbif->idx - VBIF_0, pnd, src);
@@ -279,9 +270,9 @@ void dpu_vbif_init_memtypes(struct dpu_kms *dpu_kms)
 
 	for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
 		vbif = dpu_kms->hw_vbif[i];
-		if (vbif && vbif->cap && vbif->ops.set_mem_type) {
+		if (vbif && vbif->cap) {
 			for (j = 0; j < vbif->cap->memtype_count; j++)
-				vbif->ops.set_mem_type(
+				dpu_hw_vbif_set_mem_type(
 						vbif, j, vbif->cap->memtype[j]);
 		}
 	}
-- 
2.30.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2021-03-24 15:01 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-24 15:00 [PATCH 00/21] drm/msm/dpu: cleanup callbacks, resource manager Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 01/21] drm/msm/dpu: enable DPU_SSPP_QOS_8LVL for SM8250 Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 02/21] drm/msm/dpu: remove unused dpu_hw_blk features Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 03/21] drm/msm/dpu: drop dpu_hw_blk_destroy function Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 04/21] drm/msm/dpu: get DSPP blocks directly rather than through RM Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 05/21] drm/msm/dpu: get MERGE_3D " Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 06/21] drm/msm/dpu: get PINGPONG " Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 07/21] drm/msm/dpu: drop unused lm_max_width from RM Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 08/21] drm/msm/dpu: simplify peer LM handling Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 09/21] drm/msm/dpu: drop dpu_encoder_phys's get_hw_resources() callback Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 10/21] drm/msm/dpu: drop dpu_hw_lm_setup_blend_config() Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 11/21] drm/msm/dpu: call hw_lm ops directly Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 12/21] drm/msm/dpu: call hw_dspp " Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 13/21] drm/msm/dpu: hw_pp: make setup_dither mandatory Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 14/21] drm/msm/dpu: call hw_pingpong ops directly Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 15/21] drm/msm/dpu: call hw_merge_3d " Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 16/21] drm/msm/dpu: call hw_intf " Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 17/21] drm/msm/dpu: call hw_top " Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 18/21] drm/msm/dpu: hw_vbif: make set_qos_remap mandatory Dmitry Baryshkov
2021-03-24 15:00 ` Dmitry Baryshkov [this message]
2021-03-24 15:00 ` [PATCH 20/21] drm/msm/dpu: fix smart dma support Dmitry Baryshkov
2021-03-24 15:00 ` [PATCH 21/21] drm/msm/dpu: call hw_intr ops directly Dmitry Baryshkov
2021-03-24 17:56   ` kernel test robot
2021-03-24 20:21   ` kernel test robot

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=20210324150024.2768215-20-dmitry.baryshkov@linaro.org \
    --to=dmitry.baryshkov@linaro.org \
    --cc=airlied@linux.ie \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=freedreno@lists.freedesktop.org \
    --cc=jonathan@marek.ca \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=robdclark@gmail.com \
    --cc=sboyd@kernel.org \
    --cc=sean@poorly.run \
    /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;
as well as URLs for NNTP newsgroup(s).