linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: <sean.wang@mediatek.com>
To: <linus.walleij@linaro.org>, <linux-mediatek@lists.infradead.org>
Cc: <linux-arm-kernel@lists.infradead.org>,
	<linux-gpio@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	Sean Wang <sean.wang@mediatek.com>
Subject: [PATCH v2 14/22] pinctrl: mediatek: add multiple register bases support to pinctrl-mtk-common-v2.c
Date: Sat, 8 Sep 2018 19:07:30 +0800	[thread overview]
Message-ID: <8c4a741e7ed695d85844a1a550b956d767661b44.1536404280.git.sean.wang@mediatek.com> (raw)
In-Reply-To: <cover.1536404280.git.sean.wang@mediatek.com>

From: Sean Wang <sean.wang@mediatek.com>

Certain SoC own multiple register base for accessing each pin groups,
it's easy to be done with extend struct mtk_pin_field_calc to support
the kind of SoC such as MT8183.

Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
 drivers/pinctrl/mediatek/pinctrl-moore.c         | 30 +++++++++++++++-----
 drivers/pinctrl/mediatek/pinctrl-mt7622.c        |  2 ++
 drivers/pinctrl/mediatek/pinctrl-mt7623.c        | 16 ++++++-----
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 36 +++++++++++++++---------
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h | 24 ++++++++++++----
 5 files changed, 75 insertions(+), 33 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c
index 2f3e3b5..2817e47 100644
--- a/drivers/pinctrl/mediatek/pinctrl-moore.c
+++ b/drivers/pinctrl/mediatek/pinctrl-moore.c
@@ -713,25 +713,41 @@ int mtk_moore_pinctrl_probe(struct platform_device *pdev,
 {
 	struct resource *res;
 	struct mtk_pinctrl *hw;
-	int err;
+	int err, i;
 
 	hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL);
 	if (!hw)
 		return -ENOMEM;
 
 	hw->soc = soc;
+	hw->dev = &pdev->dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "missing IO resource\n");
-		return -ENXIO;
+	if (!hw->soc->nbase_names) {
+		dev_err(&pdev->dev,
+			"SoC should be assigned at least one register base\n");
+		return -EINVAL;
 	}
 
-	hw->dev = &pdev->dev;
-	hw->base = devm_ioremap_resource(&pdev->dev, res);
+	hw->base = devm_kmalloc_array(&pdev->dev, hw->soc->nbase_names,
+				      sizeof(*hw->base), GFP_KERNEL);
 	if (IS_ERR(hw->base))
 		return PTR_ERR(hw->base);
 
+	for (i = 0; i < hw->soc->nbase_names; i++) {
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						   hw->soc->base_names[i]);
+		if (!res) {
+			dev_err(&pdev->dev, "missing IO resource\n");
+			return -ENXIO;
+		}
+
+		hw->base[i] = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(hw->base[i]))
+			return PTR_ERR(hw->base[i]);
+	}
+
+	hw->nbase = hw->soc->nbase_names;
+
 	/* Setup pins descriptions per SoC types */
 	mtk_desc.pins = (const struct pinctrl_pin_desc *)hw->soc->pins;
 	mtk_desc.npins = hw->soc->npins;
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7622.c b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
index 9ac36ab..769b36a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt7622.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7622.c
@@ -768,6 +768,8 @@ static const struct mtk_pin_soc mt7622_data = {
 	.gpio_m	= 1,
 	.eint_m = 1,
 	.ies_present = false,
+	.base_names = mtk_default_register_base_names,
+	.nbase_names = ARRAY_SIZE(mtk_default_register_base_names),
 	.bias_disable_set = mtk_pinconf_bias_disable_set,
 	.bias_disable_get = mtk_pinconf_bias_disable_get,
 	.bias_set = mtk_pinconf_bias_set,
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7623.c b/drivers/pinctrl/mediatek/pinctrl-mt7623.c
index 30d2289..1f2030c 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt7623.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7623.c
@@ -18,15 +18,15 @@
 #define BOND_MSDC0E_CLR		0x1
 
 #define PIN_FIELD15(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)	\
-	PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+	PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit,	\
 		       _x_bits, 15, false)
 
 #define PIN_FIELD16(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)	\
-	PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+	PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit,	\
 		       _x_bits, 16, 0)
 
-#define PINS_FIELD16(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)\
-	PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+#define PINS_FIELD16(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)	\
+	PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit,	\
 		       _x_bits, 16, 1)
 
 #define MT7623_PIN(_number, _name, _eint_n, _drv_grp)			\
@@ -1383,6 +1383,8 @@ static struct mtk_pin_soc mt7623_data = {
 	.gpio_m = 0,
 	.eint_m = 0,
 	.ies_present = true,
+	.base_names = mtk_default_register_base_names,
+	.nbase_names = ARRAY_SIZE(mtk_default_register_base_names),
 	.bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
 	.bias_disable_get = mtk_pinconf_bias_disable_get_rev1,
 	.bias_set = mtk_pinconf_bias_set_rev1,
@@ -1402,9 +1404,9 @@ static void mt7623_bonding_disable(struct platform_device *pdev)
 {
 	struct mtk_pinctrl *hw = platform_get_drvdata(pdev);
 
-	mtk_rmw(hw, PIN_BOND_REG0, BOND_PCIE_CLR, BOND_PCIE_CLR);
-	mtk_rmw(hw, PIN_BOND_REG1, BOND_I2S_CLR, BOND_I2S_CLR);
-	mtk_rmw(hw, PIN_BOND_REG2, BOND_MSDC0E_CLR, BOND_MSDC0E_CLR);
+	mtk_rmw(hw, 0, PIN_BOND_REG0, BOND_PCIE_CLR, BOND_PCIE_CLR);
+	mtk_rmw(hw, 0, PIN_BOND_REG1, BOND_I2S_CLR, BOND_I2S_CLR);
+	mtk_rmw(hw, 0, PIN_BOND_REG2, BOND_MSDC0E_CLR, BOND_MSDC0E_CLR);
 }
 
 static const struct of_device_id mt7623_pctrl_match[] = {
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index ed88b96..18a3548 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -39,24 +39,24 @@ const struct mtk_drive_desc mtk_drive[] = {
 	[DRV_GRP4] = { 2, 16, 2, 1 },
 };
 
-static void mtk_w32(struct mtk_pinctrl *pctl, u32 reg, u32 val)
+static void mtk_w32(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 val)
 {
-	writel_relaxed(val, pctl->base + reg);
+	writel_relaxed(val, pctl->base[i] + reg);
 }
 
-static u32 mtk_r32(struct mtk_pinctrl *pctl, u32 reg)
+static u32 mtk_r32(struct mtk_pinctrl *pctl, u8 i, u32 reg)
 {
-	return readl_relaxed(pctl->base + reg);
+	return readl_relaxed(pctl->base[i] + reg);
 }
 
-void mtk_rmw(struct mtk_pinctrl *pctl, u32 reg, u32 mask, u32 set)
+void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set)
 {
 	u32 val;
 
-	val = mtk_r32(pctl, reg);
+	val = mtk_r32(pctl, i, reg);
 	val &= ~mask;
 	val |= set;
-	mtk_w32(pctl, reg, val);
+	mtk_w32(pctl, i, reg, val);
 }
 
 static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
@@ -82,6 +82,12 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
 		return -EINVAL;
 	}
 
+	if (c->i_base > hw->nbase - 1) {
+		dev_err(hw->dev, "Invalid base is found for pin = %d (%s)\n",
+			desc->number, desc->name);
+		return -EINVAL;
+	}
+
 	/* Calculated bits as the overall offset the pin is located at,
 	 * if c->fixed is held, that determines the all the pins in the
 	 * range use the same field with the s_pin.
@@ -92,6 +98,7 @@ static int mtk_hw_pin_field_lookup(struct mtk_pinctrl *hw,
 	/* Fill pfd from bits. For example 32-bit register applied is assumed
 	 * when c->sz_reg is equal to 32.
 	 */
+	pfd->index = c->i_base;
 	pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
 	pfd->bitpos = bits % c->sz_reg;
 	pfd->mask = (1 << c->x_bits) - 1;
@@ -139,10 +146,10 @@ static void mtk_hw_write_cross_field(struct mtk_pinctrl *hw,
 
 	mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
 
-	mtk_rmw(hw, pf->offset, pf->mask << pf->bitpos,
+	mtk_rmw(hw, pf->index, pf->offset, pf->mask << pf->bitpos,
 		(value & pf->mask) << pf->bitpos);
 
-	mtk_rmw(hw, pf->offset + pf->next, BIT(nbits_h) - 1,
+	mtk_rmw(hw, pf->index, pf->offset + pf->next, BIT(nbits_h) - 1,
 		(value & pf->mask) >> nbits_l);
 }
 
@@ -153,8 +160,10 @@ static void mtk_hw_read_cross_field(struct mtk_pinctrl *hw,
 
 	mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
 
-	l  = (mtk_r32(hw, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
-	h  = (mtk_r32(hw, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
+	l  = (mtk_r32(hw, pf->index, pf->offset)
+	      >> pf->bitpos) & (BIT(nbits_l) - 1);
+	h  = (mtk_r32(hw, pf->index, pf->offset + pf->next))
+	      & (BIT(nbits_h) - 1);
 
 	*value = (h << nbits_l) | l;
 }
@@ -170,7 +179,7 @@ int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 		return err;
 
 	if (!pf.next)
-		mtk_rmw(hw, pf.offset, pf.mask << pf.bitpos,
+		mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos,
 			(value & pf.mask) << pf.bitpos);
 	else
 		mtk_hw_write_cross_field(hw, &pf, value);
@@ -189,7 +198,8 @@ int mtk_hw_get_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 		return err;
 
 	if (!pf.next)
-		*value = (mtk_r32(hw, pf.offset) >> pf.bitpos) & pf.mask;
+		*value = (mtk_r32(hw, pf.index, pf.offset)
+			  >> pf.bitpos) & pf.mask;
 	else
 		mtk_hw_read_cross_field(hw, &pf, value);
 
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
index 6e66bdc..040c6b7 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h
@@ -18,10 +18,11 @@
 
 #define EINT_NA	-1
 
-#define PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
-			_x_bits, _sz_reg, _fixed) {			\
+#define PIN_FIELD_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs,      \
+		       _s_bit, _x_bits, _sz_reg, _fixed) {		\
 		.s_pin = _s_pin,					\
 		.e_pin = _e_pin,					\
+		.i_base = _i_base,					\
 		.s_addr = _s_addr,					\
 		.x_addrs = _x_addrs,					\
 		.s_bit = _s_bit,					\
@@ -31,11 +32,11 @@
 	}
 
 #define PIN_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)	\
-	PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+	PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit,	\
 		       _x_bits, 32, 0)
 
 #define PINS_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)	\
-	PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit,	\
+	PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit,	\
 		       _x_bits, 32, 1)
 
 /* List these attributes which could be modified for the pin */
@@ -73,8 +74,13 @@ enum {
 	DRV_GRP_MAX,
 };
 
+static const char * const mtk_default_register_base_names[] = {
+	"base",
+};
+
 /* struct mtk_pin_field - the structure that holds the information of the field
  *			  used to describe the attribute for the pin
+ * @base:		the index pointing to the entry in base address list
  * @offset:		the register offset relative to the base address
  * @mask:		the mask used to filter out the field from the register
  * @bitpos:		the start bit relative to the register
@@ -82,6 +88,7 @@ enum {
 			next register
  */
 struct mtk_pin_field {
+	u8  index;
 	u32 offset;
 	u32 mask;
 	u8  bitpos;
@@ -92,6 +99,7 @@ struct mtk_pin_field {
  *			       the guide used to look up the relevant field
  * @s_pin:		the start pin within the range
  * @e_pin:		the end pin within the range
+ * @i_base:		the index pointing to the entry in base address list
  * @s_addr:		the start address for the range
  * @x_addrs:		the address distance between two consecutive registers
  *			within the range
@@ -105,6 +113,7 @@ struct mtk_pin_field {
 struct mtk_pin_field_calc {
 	u16 s_pin;
 	u16 e_pin;
+	u8  i_base;
 	u32 s_addr;
 	u8  x_addrs;
 	u8  s_bit;
@@ -157,6 +166,8 @@ struct mtk_pin_soc {
 	u8				gpio_m;
 	u8				eint_m;
 	bool				ies_present;
+	const char * const		*base_names;
+	unsigned int			nbase_names;
 
 	/* Specific pinconfig operations */
 	int (*bias_disable_set)(struct mtk_pinctrl *hw,
@@ -183,14 +194,15 @@ struct mtk_pin_soc {
 
 struct mtk_pinctrl {
 	struct pinctrl_dev		*pctrl;
-	void __iomem			*base;
+	void __iomem			**base;
+	u8				nbase;
 	struct device			*dev;
 	struct gpio_chip		chip;
 	const struct mtk_pin_soc        *soc;
 	struct mtk_eint			*eint;
 };
 
-void mtk_rmw(struct mtk_pinctrl *pctl, u32 reg, u32 mask, u32 set);
+void mtk_rmw(struct mtk_pinctrl *pctl, u8 i, u32 reg, u32 mask, u32 set);
 
 int mtk_hw_set_value(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc,
 		     int field, int value);
-- 
2.7.4


  parent reply	other threads:[~2018-09-08 11:07 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-08 11:07 [PATCH v2 00/22] Unify MediaTek pinctrl in preparation for MT8183 and MT6765 sean.wang
2018-09-08 11:07 ` [PATCH v2 03/22] pinctrl: mediatek: extend struct mtk_pin_field_calc to pinctrl-mtk-common-v2.c sean.wang
2018-09-18 19:43   ` Linus Walleij
2018-09-08 11:07 ` [PATCH v2 12/22] pinctrl: mediatek: add MT7623 pinctrl driver based on generic pinctrl binding sean.wang
2018-09-18 19:52   ` Linus Walleij
2018-09-08 11:07 ` [PATCH v2 13/22] pinctrl: mediatek: use pin descriptor all in pinctrl-mtk-common-v2.c sean.wang
2018-09-18 19:53   ` Linus Walleij
2018-09-08 11:07 ` sean.wang [this message]
2018-09-18 19:56   ` [PATCH v2 14/22] pinctrl: mediatek: add multiple register bases support to pinctrl-mtk-common-v2.c Linus Walleij
2018-09-08 11:07 ` [PATCH v2 15/22] pinctrl: mediatek: adjust error code and message when some register not supported is found sean.wang
2018-09-18 19:57   ` Linus Walleij
2018-09-08 11:07 ` [PATCH v2 16/22] pinctrl: mediatek: extend struct mtk_pin_desc which per-pin driver depends on sean.wang
2018-09-18 19:58   ` Linus Walleij
2018-09-08 11:07 ` [PATCH v2 17/22] pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings sean.wang
2018-09-18 19:59   ` Linus Walleij
2018-09-08 11:07 ` [PATCH v2 18/22] pinctrl: mediatek: add MT8183 pinctrl driver sean.wang
2018-09-18 20:01   ` Linus Walleij
2018-09-08 11:07 ` [PATCH v2 19/22] pinctrl: mediatek: extend advanced pull support in pinctrl-mtk-common-v2.c sean.wang
2018-09-18 20:02   ` Linus Walleij
2018-09-08 11:07 ` [PATCH v2 20/22] pintcrl: mediatek: add pull tweaks for I2C related pins on MT8183 sean.wang
2018-09-18 20:03   ` Linus Walleij
2018-09-08 11:07 ` [PATCH v2 21/22] pinctrl: mediatek: extend eint build to pinctrl-mtk-common-v2.c sean.wang
2018-09-08 11:07 ` [PATCH v2 22/22] pinctrl: mediatek: add eint support to MT8183 pinctrl driver sean.wang
     [not found] ` <75d8f8c745d60b49ee1ec60de7f776ef51f97f79.1536404280.git.sean.wang@mediatek.com>
2018-09-18 19:36   ` [PATCH v2 01/22] pinctrl: mediatek: add pinctrl-mtk-common-v2 for all MediaTek pinctrls Linus Walleij
     [not found] ` <5001a940525e9da7b0e1ac1afead629e1373fe33.1536404280.git.sean.wang@mediatek.com>
2018-09-18 19:42   ` [PATCH v2 02/22] pinctrl: mediatek: add pinctrl-moore that implements the generic pinctrl dt-bindings Linus Walleij
     [not found] ` <8afc61bff2a4146731e5696f440c0eeaaf0ea341.1536404280.git.sean.wang@mediatek.com>
2018-09-18 19:44   ` [PATCH v2 04/22] pinctrl: mediatek: extend struct mtk_pin_desc to pinctrl-mtk-common-v2.c Linus Walleij
     [not found] ` <17ff79fcf3df7c7208b6cda6f207e5e96c4d6c7e.1536404280.git.sean.wang@mediatek.com>
2018-09-18 19:45   ` [PATCH v2 05/22] pinctrl: mediatek: extend struct mtk_pin_soc " Linus Walleij
     [not found] ` <ffa1fc0c62bc9408524619c8b530759351fd366c.1536404280.git.sean.wang@mediatek.com>
2018-09-18 19:46   ` [PATCH v2 06/22] pinctrl: mediatek: add driving strength related support " Linus Walleij
     [not found] ` <5a7880e3885ba8a1c51ca28a0753228eeeeb9ec7.1536404280.git.sean.wang@mediatek.com>
2018-09-18 19:47   ` [PATCH v2 07/22] pinctrl: mediatek: add drv register " Linus Walleij
     [not found] ` <f5324a24d1a70c37a5e011f859ce90867e9ad3fb.1536404280.git.sean.wang@mediatek.com>
2018-09-18 19:48   ` [PATCH v2 08/22] pinctrl: mediatek: add pull related " Linus Walleij
     [not found] ` <aa213c9af6f9261f2ba91055785f0058d615bc4d.1536404280.git.sean.wang@mediatek.com>
2018-09-18 19:49   ` [PATCH v2 09/22] pinctrl: mediatek: add advanced " Linus Walleij
     [not found] ` <af007cdcec1d4e8512faf47182aa4b17b17c1093.1536404280.git.sean.wang@mediatek.com>
2018-09-18 19:50   ` [PATCH v2 10/22] pinctrl: mediatek: add ies register " Linus Walleij
     [not found] ` <f698dee4dcac1b5acfde7133773f7dc1e8c40583.1536404280.git.sean.wang@mediatek.com>
2018-09-18 19:51   ` [PATCH v2 11/22] pinctrl: mediatek: add pullen, pullsel " Linus Walleij
2018-09-18 22:07 ` [PATCH v2 00/22] Unify MediaTek pinctrl in preparation for MT8183 and MT6765 Linus Walleij
2018-09-19  2:54   ` Sean Wang
2018-09-19  4:37     ` Manivannan Sadhasivam
2018-09-21  4:22       ` Sean Wang
2018-09-25 10:48         ` Matthias Brugger
2018-09-25 13:07           ` Manivannan Sadhasivam
2018-09-25 13:09             ` Manivannan Sadhasivam

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=8c4a741e7ed695d85844a1a550b956d767661b44.1536404280.git.sean.wang@mediatek.com \
    --to=sean.wang@mediatek.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    /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).