All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
To: Peter De Schrijver
	<pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Cc: Russell King <linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org>,
	Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>,
	Thierry Reding
	<thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Andrew Morton
	<akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>,
	Linus Walleij
	<linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH v8 1/6] ARM: tegra: export apb dma readl/writel
Date: Thu, 12 Jun 2014 18:36:35 +0300	[thread overview]
Message-ID: <1402587400-1544-2-git-send-email-pdeschrijver@nvidia.com> (raw)
In-Reply-To: <1402587400-1544-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

Export APB DMA readl and writel. These are needed because we can't access
the fuses directly on Tegra20 without potentially causing a system hang.
Also have the APB DMA readl and writel return an error in case of a read
failure instead of just returning zero or ignore write failures.

Signed-off-by: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 arch/arm/mach-tegra/apbio.c |   51 ++++++++++++++++++++++++++----------------
 include/linux/tegra-soc.h   |   14 +++++++++++
 2 files changed, 45 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index bc47197..e0bf49d 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -32,8 +32,8 @@ static u32 *tegra_apb_bb;
 static dma_addr_t tegra_apb_bb_phys;
 static DECLARE_COMPLETION(tegra_apb_wait);
 
-static u32 tegra_apb_readl_direct(unsigned long offset);
-static void tegra_apb_writel_direct(u32 value, unsigned long offset);
+static int tegra_apb_readl_direct(unsigned long offset, u32 *value);
+static int tegra_apb_writel_direct(u32 value, unsigned long offset);
 
 static struct dma_chan *tegra_apb_dma_chan;
 static struct dma_slave_config dma_sconfig;
@@ -128,58 +128,64 @@ static int do_dma_transfer(unsigned long apb_add,
 	return 0;
 }
 
-static u32 tegra_apb_readl_using_dma(unsigned long offset)
+int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
 {
 	int ret;
 
 	if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
-		return tegra_apb_readl_direct(offset);
+		return tegra_apb_readl_direct(offset, value);
 
 	mutex_lock(&tegra_apb_dma_lock);
 	ret = do_dma_transfer(offset, DMA_DEV_TO_MEM);
-	if (ret < 0) {
+	if (ret < 0)
 		pr_err("error in reading offset 0x%08lx using dma\n", offset);
-		*(u32 *)tegra_apb_bb = 0;
-	}
+	else
+		*value = *tegra_apb_bb;
+
 	mutex_unlock(&tegra_apb_dma_lock);
-	return *((u32 *)tegra_apb_bb);
+
+	return ret;
 }
 
-static void tegra_apb_writel_using_dma(u32 value, unsigned long offset)
+int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
 {
 	int ret;
 
-	if (!tegra_apb_dma_chan && !tegra_apb_dma_init()) {
-		tegra_apb_writel_direct(value, offset);
-		return;
-	}
+	if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
+		return tegra_apb_writel_direct(value, offset);
 
 	mutex_lock(&tegra_apb_dma_lock);
 	*((u32 *)tegra_apb_bb) = value;
 	ret = do_dma_transfer(offset, DMA_MEM_TO_DEV);
+	mutex_unlock(&tegra_apb_dma_lock);
 	if (ret < 0)
 		pr_err("error in writing offset 0x%08lx using dma\n", offset);
-	mutex_unlock(&tegra_apb_dma_lock);
+
+	return ret;
 }
 #else
 #define tegra_apb_readl_using_dma tegra_apb_readl_direct
 #define tegra_apb_writel_using_dma tegra_apb_writel_direct
 #endif
 
-typedef u32 (*apbio_read_fptr)(unsigned long offset);
-typedef void (*apbio_write_fptr)(u32 value, unsigned long offset);
+typedef int (*apbio_read_fptr)(unsigned long offset, u32 *value);
+typedef int (*apbio_write_fptr)(u32 value, unsigned long offset);
 
 static apbio_read_fptr apbio_read;
 static apbio_write_fptr apbio_write;
 
-static u32 tegra_apb_readl_direct(unsigned long offset)
+static int tegra_apb_readl_direct(unsigned long offset, u32 *value)
 {
-	return readl(IO_ADDRESS(offset));
+	*value = readl(IO_ADDRESS(offset));
+
+	return 0;
 }
 
-static void tegra_apb_writel_direct(u32 value, unsigned long offset)
+static int tegra_apb_writel_direct(u32 value, unsigned long offset)
 {
 	writel(value, IO_ADDRESS(offset));
+
+	return 0;
 }
 
 void tegra_apb_io_init(void)
@@ -197,7 +203,12 @@ void tegra_apb_io_init(void)
 
 u32 tegra_apb_readl(unsigned long offset)
 {
-	return apbio_read(offset);
+	u32 val;
+
+	if (apbio_read(offset, &val) < 0)
+		return 0;
+	else
+		return val;
 }
 
 void tegra_apb_writel(u32 value, unsigned long offset)
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
index 95f611d..b02d73b 100644
--- a/include/linux/tegra-soc.h
+++ b/include/linux/tegra-soc.h
@@ -19,4 +19,18 @@
 
 u32 tegra_read_chipid(void);
 
+
+#if defined(CONFIG_TEGRA20_APB_DMA)
+int tegra_apb_readl_using_dma(unsigned long offset, u32 *value);
+int tegra_apb_writel_using_dma(u32 value, unsigned long offset);
+#else
+static inline int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
+{
+	return -EINVAL;
+}
+static inline int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
+{
+	return -EINVAL;
+}
+#endif
 #endif /* __LINUX_TEGRA_SOC_H_ */
-- 
1.7.7.rc0.72.g4b5ea.dirty

WARNING: multiple messages have this Message-ID (diff)
From: Peter De Schrijver <pdeschrijver@nvidia.com>
To: Peter De Schrijver <pdeschrijver@nvidia.com>
Cc: Russell King <linux@arm.linux.org.uk>,
	Stephen Warren <swarren@wwwdotorg.org>,
	Thierry Reding <thierry.reding@gmail.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	Wolfram Sang <wsa@the-dreams.de>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-tegra@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH v8 1/6] ARM: tegra: export apb dma readl/writel
Date: Thu, 12 Jun 2014 18:36:35 +0300	[thread overview]
Message-ID: <1402587400-1544-2-git-send-email-pdeschrijver@nvidia.com> (raw)
In-Reply-To: <1402587400-1544-1-git-send-email-pdeschrijver@nvidia.com>

Export APB DMA readl and writel. These are needed because we can't access
the fuses directly on Tegra20 without potentially causing a system hang.
Also have the APB DMA readl and writel return an error in case of a read
failure instead of just returning zero or ignore write failures.

Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
 arch/arm/mach-tegra/apbio.c |   51 ++++++++++++++++++++++++++----------------
 include/linux/tegra-soc.h   |   14 +++++++++++
 2 files changed, 45 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index bc47197..e0bf49d 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -32,8 +32,8 @@ static u32 *tegra_apb_bb;
 static dma_addr_t tegra_apb_bb_phys;
 static DECLARE_COMPLETION(tegra_apb_wait);
 
-static u32 tegra_apb_readl_direct(unsigned long offset);
-static void tegra_apb_writel_direct(u32 value, unsigned long offset);
+static int tegra_apb_readl_direct(unsigned long offset, u32 *value);
+static int tegra_apb_writel_direct(u32 value, unsigned long offset);
 
 static struct dma_chan *tegra_apb_dma_chan;
 static struct dma_slave_config dma_sconfig;
@@ -128,58 +128,64 @@ static int do_dma_transfer(unsigned long apb_add,
 	return 0;
 }
 
-static u32 tegra_apb_readl_using_dma(unsigned long offset)
+int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
 {
 	int ret;
 
 	if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
-		return tegra_apb_readl_direct(offset);
+		return tegra_apb_readl_direct(offset, value);
 
 	mutex_lock(&tegra_apb_dma_lock);
 	ret = do_dma_transfer(offset, DMA_DEV_TO_MEM);
-	if (ret < 0) {
+	if (ret < 0)
 		pr_err("error in reading offset 0x%08lx using dma\n", offset);
-		*(u32 *)tegra_apb_bb = 0;
-	}
+	else
+		*value = *tegra_apb_bb;
+
 	mutex_unlock(&tegra_apb_dma_lock);
-	return *((u32 *)tegra_apb_bb);
+
+	return ret;
 }
 
-static void tegra_apb_writel_using_dma(u32 value, unsigned long offset)
+int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
 {
 	int ret;
 
-	if (!tegra_apb_dma_chan && !tegra_apb_dma_init()) {
-		tegra_apb_writel_direct(value, offset);
-		return;
-	}
+	if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
+		return tegra_apb_writel_direct(value, offset);
 
 	mutex_lock(&tegra_apb_dma_lock);
 	*((u32 *)tegra_apb_bb) = value;
 	ret = do_dma_transfer(offset, DMA_MEM_TO_DEV);
+	mutex_unlock(&tegra_apb_dma_lock);
 	if (ret < 0)
 		pr_err("error in writing offset 0x%08lx using dma\n", offset);
-	mutex_unlock(&tegra_apb_dma_lock);
+
+	return ret;
 }
 #else
 #define tegra_apb_readl_using_dma tegra_apb_readl_direct
 #define tegra_apb_writel_using_dma tegra_apb_writel_direct
 #endif
 
-typedef u32 (*apbio_read_fptr)(unsigned long offset);
-typedef void (*apbio_write_fptr)(u32 value, unsigned long offset);
+typedef int (*apbio_read_fptr)(unsigned long offset, u32 *value);
+typedef int (*apbio_write_fptr)(u32 value, unsigned long offset);
 
 static apbio_read_fptr apbio_read;
 static apbio_write_fptr apbio_write;
 
-static u32 tegra_apb_readl_direct(unsigned long offset)
+static int tegra_apb_readl_direct(unsigned long offset, u32 *value)
 {
-	return readl(IO_ADDRESS(offset));
+	*value = readl(IO_ADDRESS(offset));
+
+	return 0;
 }
 
-static void tegra_apb_writel_direct(u32 value, unsigned long offset)
+static int tegra_apb_writel_direct(u32 value, unsigned long offset)
 {
 	writel(value, IO_ADDRESS(offset));
+
+	return 0;
 }
 
 void tegra_apb_io_init(void)
@@ -197,7 +203,12 @@ void tegra_apb_io_init(void)
 
 u32 tegra_apb_readl(unsigned long offset)
 {
-	return apbio_read(offset);
+	u32 val;
+
+	if (apbio_read(offset, &val) < 0)
+		return 0;
+	else
+		return val;
 }
 
 void tegra_apb_writel(u32 value, unsigned long offset)
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
index 95f611d..b02d73b 100644
--- a/include/linux/tegra-soc.h
+++ b/include/linux/tegra-soc.h
@@ -19,4 +19,18 @@
 
 u32 tegra_read_chipid(void);
 
+
+#if defined(CONFIG_TEGRA20_APB_DMA)
+int tegra_apb_readl_using_dma(unsigned long offset, u32 *value);
+int tegra_apb_writel_using_dma(u32 value, unsigned long offset);
+#else
+static inline int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
+{
+	return -EINVAL;
+}
+static inline int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
+{
+	return -EINVAL;
+}
+#endif
 #endif /* __LINUX_TEGRA_SOC_H_ */
-- 
1.7.7.rc0.72.g4b5ea.dirty


WARNING: multiple messages have this Message-ID (diff)
From: pdeschrijver@nvidia.com (Peter De Schrijver)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v8 1/6] ARM: tegra: export apb dma readl/writel
Date: Thu, 12 Jun 2014 18:36:35 +0300	[thread overview]
Message-ID: <1402587400-1544-2-git-send-email-pdeschrijver@nvidia.com> (raw)
In-Reply-To: <1402587400-1544-1-git-send-email-pdeschrijver@nvidia.com>

Export APB DMA readl and writel. These are needed because we can't access
the fuses directly on Tegra20 without potentially causing a system hang.
Also have the APB DMA readl and writel return an error in case of a read
failure instead of just returning zero or ignore write failures.

Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
---
 arch/arm/mach-tegra/apbio.c |   51 ++++++++++++++++++++++++++----------------
 include/linux/tegra-soc.h   |   14 +++++++++++
 2 files changed, 45 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
index bc47197..e0bf49d 100644
--- a/arch/arm/mach-tegra/apbio.c
+++ b/arch/arm/mach-tegra/apbio.c
@@ -32,8 +32,8 @@ static u32 *tegra_apb_bb;
 static dma_addr_t tegra_apb_bb_phys;
 static DECLARE_COMPLETION(tegra_apb_wait);
 
-static u32 tegra_apb_readl_direct(unsigned long offset);
-static void tegra_apb_writel_direct(u32 value, unsigned long offset);
+static int tegra_apb_readl_direct(unsigned long offset, u32 *value);
+static int tegra_apb_writel_direct(u32 value, unsigned long offset);
 
 static struct dma_chan *tegra_apb_dma_chan;
 static struct dma_slave_config dma_sconfig;
@@ -128,58 +128,64 @@ static int do_dma_transfer(unsigned long apb_add,
 	return 0;
 }
 
-static u32 tegra_apb_readl_using_dma(unsigned long offset)
+int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
 {
 	int ret;
 
 	if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
-		return tegra_apb_readl_direct(offset);
+		return tegra_apb_readl_direct(offset, value);
 
 	mutex_lock(&tegra_apb_dma_lock);
 	ret = do_dma_transfer(offset, DMA_DEV_TO_MEM);
-	if (ret < 0) {
+	if (ret < 0)
 		pr_err("error in reading offset 0x%08lx using dma\n", offset);
-		*(u32 *)tegra_apb_bb = 0;
-	}
+	else
+		*value = *tegra_apb_bb;
+
 	mutex_unlock(&tegra_apb_dma_lock);
-	return *((u32 *)tegra_apb_bb);
+
+	return ret;
 }
 
-static void tegra_apb_writel_using_dma(u32 value, unsigned long offset)
+int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
 {
 	int ret;
 
-	if (!tegra_apb_dma_chan && !tegra_apb_dma_init()) {
-		tegra_apb_writel_direct(value, offset);
-		return;
-	}
+	if (!tegra_apb_dma_chan && !tegra_apb_dma_init())
+		return tegra_apb_writel_direct(value, offset);
 
 	mutex_lock(&tegra_apb_dma_lock);
 	*((u32 *)tegra_apb_bb) = value;
 	ret = do_dma_transfer(offset, DMA_MEM_TO_DEV);
+	mutex_unlock(&tegra_apb_dma_lock);
 	if (ret < 0)
 		pr_err("error in writing offset 0x%08lx using dma\n", offset);
-	mutex_unlock(&tegra_apb_dma_lock);
+
+	return ret;
 }
 #else
 #define tegra_apb_readl_using_dma tegra_apb_readl_direct
 #define tegra_apb_writel_using_dma tegra_apb_writel_direct
 #endif
 
-typedef u32 (*apbio_read_fptr)(unsigned long offset);
-typedef void (*apbio_write_fptr)(u32 value, unsigned long offset);
+typedef int (*apbio_read_fptr)(unsigned long offset, u32 *value);
+typedef int (*apbio_write_fptr)(u32 value, unsigned long offset);
 
 static apbio_read_fptr apbio_read;
 static apbio_write_fptr apbio_write;
 
-static u32 tegra_apb_readl_direct(unsigned long offset)
+static int tegra_apb_readl_direct(unsigned long offset, u32 *value)
 {
-	return readl(IO_ADDRESS(offset));
+	*value = readl(IO_ADDRESS(offset));
+
+	return 0;
 }
 
-static void tegra_apb_writel_direct(u32 value, unsigned long offset)
+static int tegra_apb_writel_direct(u32 value, unsigned long offset)
 {
 	writel(value, IO_ADDRESS(offset));
+
+	return 0;
 }
 
 void tegra_apb_io_init(void)
@@ -197,7 +203,12 @@ void tegra_apb_io_init(void)
 
 u32 tegra_apb_readl(unsigned long offset)
 {
-	return apbio_read(offset);
+	u32 val;
+
+	if (apbio_read(offset, &val) < 0)
+		return 0;
+	else
+		return val;
 }
 
 void tegra_apb_writel(u32 value, unsigned long offset)
diff --git a/include/linux/tegra-soc.h b/include/linux/tegra-soc.h
index 95f611d..b02d73b 100644
--- a/include/linux/tegra-soc.h
+++ b/include/linux/tegra-soc.h
@@ -19,4 +19,18 @@
 
 u32 tegra_read_chipid(void);
 
+
+#if defined(CONFIG_TEGRA20_APB_DMA)
+int tegra_apb_readl_using_dma(unsigned long offset, u32 *value);
+int tegra_apb_writel_using_dma(u32 value, unsigned long offset);
+#else
+static inline int tegra_apb_readl_using_dma(unsigned long offset, u32 *value)
+{
+	return -EINVAL;
+}
+static inline int tegra_apb_writel_using_dma(u32 value, unsigned long offset)
+{
+	return -EINVAL;
+}
+#endif
 #endif /* __LINUX_TEGRA_SOC_H_ */
-- 
1.7.7.rc0.72.g4b5ea.dirty

  parent reply	other threads:[~2014-06-12 15:36 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-12 15:36 [PATCH v8 0/6] efuse driver for Tegra Peter De Schrijver
2014-06-12 15:36 ` Peter De Schrijver
     [not found] ` <1402587400-1544-1-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-06-12 15:36   ` Peter De Schrijver [this message]
2014-06-12 15:36     ` [PATCH v8 1/6] ARM: tegra: export apb dma readl/writel Peter De Schrijver
2014-06-12 15:36     ` Peter De Schrijver
2014-06-12 15:36   ` [PATCH v8 2/6] ARM: tegra: move fuse exports to tegra-soc.h Peter De Schrijver
2014-06-12 15:36     ` Peter De Schrijver
2014-06-12 15:36     ` Peter De Schrijver
2014-06-12 15:36   ` [PATCH v8 3/6] misc: fuse: Add efuse driver for Tegra Peter De Schrijver
2014-06-12 15:36     ` Peter De Schrijver
2014-06-12 15:36   ` [PATCH v8 4/6] ARM: tegra: Add efuse and apbmisc bindings Peter De Schrijver
2014-06-12 15:36     ` Peter De Schrijver
2014-06-12 15:36     ` Peter De Schrijver
2014-06-12 15:36   ` [PATCH v8 5/6] ARM: tegra: build new fuse driver in drivers/misc Peter De Schrijver
2014-06-12 15:36     ` Peter De Schrijver
2014-06-12 15:36     ` Peter De Schrijver
2014-06-12 15:36   ` [PATCH v8 6/6] misc: fuse: move APB DMA into Tegra20 fuse driver Peter De Schrijver
2014-06-12 15:36     ` Peter De Schrijver
2014-06-12 15:36     ` Peter De Schrijver
2014-06-12 22:17 ` [PATCH v8 0/6] efuse driver for Tegra Stephen Warren
2014-06-12 22:17   ` Stephen Warren
2014-06-13  7:23   ` Peter De Schrijver
2014-06-13  7:23     ` Peter De Schrijver
2014-06-13  8:00     ` Peter De Schrijver
2014-06-13  8:00       ` Peter De Schrijver
2014-06-13 16:38       ` Stephen Warren
2014-06-13 16:38         ` Stephen Warren
2014-06-16 18:42 ` Stephen Warren
2014-06-16 18:42   ` Stephen Warren

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=1402587400-1544-2-git-send-email-pdeschrijver@nvidia.com \
    --to=pdeschrijver-ddmlm1+adcrqt0dzr+alfa@public.gmane.org \
    --cc=akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org \
    --cc=linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org \
    --cc=thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.