All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
To: linux-omap@vger.kernel.org, linux-fbdev@vger.kernel.org
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Subject: [PATCH 04/19] OMAP: DSS2: DSI: add option to leave DSI lanes powered on
Date: Tue, 19 Apr 2011 09:22:07 +0000	[thread overview]
Message-ID: <1303204942-25450-5-git-send-email-tomi.valkeinen@ti.com> (raw)
In-Reply-To: <1303204942-25450-1-git-send-email-tomi.valkeinen@ti.com>

The DSI pins are powered by VDDS_DSI. If VDDS_DSI is off, the DSI pins
are floating even if they are pinmuxed to, say, safe mode and there's a
pull down/up.

This patch gives the panel drivers an option to leave the VDDS_DSI power
enabled while the DSS itself is turned off. This can be used to keep the
DSI lanes in a valid state while DSS is off, if the DSI pins are muxed
for pull down (not done in this patch).

There will be a slight power consumption increase (~100 uA?) when the
VDDS_DSI is left on, but because this option is used when the panel is
left on, the regulator consumption is negligible compared to panel power
consumption.

When the panel is fully turned off the VDDS_DSI is also turned off.

As an added bonus this will give us faster start up time when starting
up the DSS and the regulator is already enabled.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/plat-omap/include/plat/display.h |    3 +-
 drivers/video/omap2/displays/panel-taal.c |    4 +-
 drivers/video/omap2/dss/dpi.c             |    4 +-
 drivers/video/omap2/dss/dsi.c             |   35 +++++++++++++++++++---------
 drivers/video/omap2/dss/dss.h             |    2 +-
 5 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index 43b887b..205c6de 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -591,7 +591,8 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
 void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
 
 int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
-void omapdss_dsi_display_disable(struct omap_dss_device *dssdev);
+void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
+		bool disconnect_lanes);
 
 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 490998f..74ce9f8 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -932,7 +932,7 @@ err:
 
 	taal_hw_reset(dssdev);
 
-	omapdss_dsi_display_disable(dssdev);
+	omapdss_dsi_display_disable(dssdev, true);
 err0:
 	return r;
 }
@@ -955,7 +955,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
 		taal_hw_reset(dssdev);
 	}
 
-	omapdss_dsi_display_disable(dssdev);
+	omapdss_dsi_display_disable(dssdev, true);
 
 	td->enabled = 0;
 }
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 17d28d7..ba0b8da 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -206,7 +206,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 
 err4:
 	if (dpi_use_dsi_pll(dssdev))
-		dsi_pll_uninit();
+		dsi_pll_uninit(true);
 err3:
 	if (dpi_use_dsi_pll(dssdev))
 		dss_clk_disable(DSS_CLK_SYSCK);
@@ -227,7 +227,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
 	if (dpi_use_dsi_pll(dssdev)) {
 		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
-		dsi_pll_uninit();
+		dsi_pll_uninit(true);
 		dss_clk_disable(DSS_CLK_SYSCK);
 	}
 
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 5303548..54fc0f6 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -246,6 +246,7 @@ static struct
 
 	struct dsi_clock_info current_cinfo;
 
+	bool vdds_dsi_enabled;
 	struct regulator *vdds_dsi_reg;
 
 	struct {
@@ -1445,9 +1446,12 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
 	enable_clocks(1);
 	dsi_enable_pll_clock(1);
 
-	r = regulator_enable(dsi.vdds_dsi_reg);
-	if (r)
-		goto err0;
+	if (!dsi.vdds_dsi_enabled) {
+		r = regulator_enable(dsi.vdds_dsi_reg);
+		if (r)
+			goto err0;
+		dsi.vdds_dsi_enabled = true;
+	}
 
 	/* XXX PLL does not come out of reset without this... */
 	dispc_pck_free_enable(1);
@@ -1481,21 +1485,28 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
 
 	return 0;
 err1:
-	regulator_disable(dsi.vdds_dsi_reg);
+	if (dsi.vdds_dsi_enabled) {
+		regulator_disable(dsi.vdds_dsi_reg);
+		dsi.vdds_dsi_enabled = false;
+	}
 err0:
 	enable_clocks(0);
 	dsi_enable_pll_clock(0);
 	return r;
 }
 
-void dsi_pll_uninit(void)
+void dsi_pll_uninit(bool disconnect_lanes)
 {
 	enable_clocks(0);
 	dsi_enable_pll_clock(0);
 
 	dsi.pll_locked = 0;
 	dsi_pll_power(DSI_PLL_POWER_OFF);
-	regulator_disable(dsi.vdds_dsi_reg);
+	if (disconnect_lanes) {
+		WARN_ON(!dsi.vdds_dsi_enabled);
+		regulator_disable(dsi.vdds_dsi_reg);
+		dsi.vdds_dsi_enabled = false;
+	}
 	DSSDBG("PLL uninit done\n");
 }
 
@@ -3642,12 +3653,13 @@ err2:
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK);
 err1:
-	dsi_pll_uninit();
+	dsi_pll_uninit(true);
 err0:
 	return r;
 }
 
-static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
+static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
+		bool disconnect_lanes)
 {
 	if (!dsi.ulps_enabled)
 		dsi_enter_ulps();
@@ -3662,7 +3674,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dsi_complexio_uninit();
-	dsi_pll_uninit();
+	dsi_pll_uninit(disconnect_lanes);
 }
 
 static int dsi_core_init(void)
@@ -3731,7 +3743,8 @@ err0:
 }
 EXPORT_SYMBOL(omapdss_dsi_display_enable);
 
-void omapdss_dsi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
+		bool disconnect_lanes)
 {
 	DSSDBG("dsi_display_disable\n");
 
@@ -3741,7 +3754,7 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev)
 
 	dsi_display_uninit_dispc(dssdev);
 
-	dsi_display_uninit_dsi(dssdev);
+	dsi_display_uninit_dsi(dssdev, disconnect_lanes);
 
 	enable_clocks(0);
 	dsi_enable_pll_clock(0);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d3b5697..eea5c7d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -294,7 +294,7 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
 		struct dispc_clock_info *dispc_cinfo);
 int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
 		bool enable_hsdiv);
-void dsi_pll_uninit(void);
+void dsi_pll_uninit(bool disconnect_lanes);
 void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
 		u32 fifo_size, enum omap_burst_size *burst_size,
 		u32 *fifo_low, u32 *fifo_high);
-- 
1.7.1


WARNING: multiple messages have this Message-ID (diff)
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
To: linux-omap@vger.kernel.org, linux-fbdev@vger.kernel.org
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Subject: [PATCH 04/19] OMAP: DSS2: DSI: add option to leave DSI lanes powered on
Date: Tue, 19 Apr 2011 12:22:07 +0300	[thread overview]
Message-ID: <1303204942-25450-5-git-send-email-tomi.valkeinen@ti.com> (raw)
In-Reply-To: <1303204942-25450-1-git-send-email-tomi.valkeinen@ti.com>

The DSI pins are powered by VDDS_DSI. If VDDS_DSI is off, the DSI pins
are floating even if they are pinmuxed to, say, safe mode and there's a
pull down/up.

This patch gives the panel drivers an option to leave the VDDS_DSI power
enabled while the DSS itself is turned off. This can be used to keep the
DSI lanes in a valid state while DSS is off, if the DSI pins are muxed
for pull down (not done in this patch).

There will be a slight power consumption increase (~100 uA?) when the
VDDS_DSI is left on, but because this option is used when the panel is
left on, the regulator consumption is negligible compared to panel power
consumption.

When the panel is fully turned off the VDDS_DSI is also turned off.

As an added bonus this will give us faster start up time when starting
up the DSS and the regulator is already enabled.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/plat-omap/include/plat/display.h |    3 +-
 drivers/video/omap2/displays/panel-taal.c |    4 +-
 drivers/video/omap2/dss/dpi.c             |    4 +-
 drivers/video/omap2/dss/dsi.c             |   35 +++++++++++++++++++---------
 drivers/video/omap2/dss/dss.h             |    2 +-
 5 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index 43b887b..205c6de 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -591,7 +591,8 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
 void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
 
 int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
-void omapdss_dsi_display_disable(struct omap_dss_device *dssdev);
+void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
+		bool disconnect_lanes);
 
 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 490998f..74ce9f8 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -932,7 +932,7 @@ err:
 
 	taal_hw_reset(dssdev);
 
-	omapdss_dsi_display_disable(dssdev);
+	omapdss_dsi_display_disable(dssdev, true);
 err0:
 	return r;
 }
@@ -955,7 +955,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
 		taal_hw_reset(dssdev);
 	}
 
-	omapdss_dsi_display_disable(dssdev);
+	omapdss_dsi_display_disable(dssdev, true);
 
 	td->enabled = 0;
 }
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 17d28d7..ba0b8da 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -206,7 +206,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 
 err4:
 	if (dpi_use_dsi_pll(dssdev))
-		dsi_pll_uninit();
+		dsi_pll_uninit(true);
 err3:
 	if (dpi_use_dsi_pll(dssdev))
 		dss_clk_disable(DSS_CLK_SYSCK);
@@ -227,7 +227,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 
 	if (dpi_use_dsi_pll(dssdev)) {
 		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
-		dsi_pll_uninit();
+		dsi_pll_uninit(true);
 		dss_clk_disable(DSS_CLK_SYSCK);
 	}
 
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 5303548..54fc0f6 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -246,6 +246,7 @@ static struct
 
 	struct dsi_clock_info current_cinfo;
 
+	bool vdds_dsi_enabled;
 	struct regulator *vdds_dsi_reg;
 
 	struct {
@@ -1445,9 +1446,12 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
 	enable_clocks(1);
 	dsi_enable_pll_clock(1);
 
-	r = regulator_enable(dsi.vdds_dsi_reg);
-	if (r)
-		goto err0;
+	if (!dsi.vdds_dsi_enabled) {
+		r = regulator_enable(dsi.vdds_dsi_reg);
+		if (r)
+			goto err0;
+		dsi.vdds_dsi_enabled = true;
+	}
 
 	/* XXX PLL does not come out of reset without this... */
 	dispc_pck_free_enable(1);
@@ -1481,21 +1485,28 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
 
 	return 0;
 err1:
-	regulator_disable(dsi.vdds_dsi_reg);
+	if (dsi.vdds_dsi_enabled) {
+		regulator_disable(dsi.vdds_dsi_reg);
+		dsi.vdds_dsi_enabled = false;
+	}
 err0:
 	enable_clocks(0);
 	dsi_enable_pll_clock(0);
 	return r;
 }
 
-void dsi_pll_uninit(void)
+void dsi_pll_uninit(bool disconnect_lanes)
 {
 	enable_clocks(0);
 	dsi_enable_pll_clock(0);
 
 	dsi.pll_locked = 0;
 	dsi_pll_power(DSI_PLL_POWER_OFF);
-	regulator_disable(dsi.vdds_dsi_reg);
+	if (disconnect_lanes) {
+		WARN_ON(!dsi.vdds_dsi_enabled);
+		regulator_disable(dsi.vdds_dsi_reg);
+		dsi.vdds_dsi_enabled = false;
+	}
 	DSSDBG("PLL uninit done\n");
 }
 
@@ -3642,12 +3653,13 @@ err2:
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK);
 err1:
-	dsi_pll_uninit();
+	dsi_pll_uninit(true);
 err0:
 	return r;
 }
 
-static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
+static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
+		bool disconnect_lanes)
 {
 	if (!dsi.ulps_enabled)
 		dsi_enter_ulps();
@@ -3662,7 +3674,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dsi_complexio_uninit();
-	dsi_pll_uninit();
+	dsi_pll_uninit(disconnect_lanes);
 }
 
 static int dsi_core_init(void)
@@ -3731,7 +3743,8 @@ err0:
 }
 EXPORT_SYMBOL(omapdss_dsi_display_enable);
 
-void omapdss_dsi_display_disable(struct omap_dss_device *dssdev)
+void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
+		bool disconnect_lanes)
 {
 	DSSDBG("dsi_display_disable\n");
 
@@ -3741,7 +3754,7 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev)
 
 	dsi_display_uninit_dispc(dssdev);
 
-	dsi_display_uninit_dsi(dssdev);
+	dsi_display_uninit_dsi(dssdev, disconnect_lanes);
 
 	enable_clocks(0);
 	dsi_enable_pll_clock(0);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d3b5697..eea5c7d 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -294,7 +294,7 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
 		struct dispc_clock_info *dispc_cinfo);
 int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
 		bool enable_hsdiv);
-void dsi_pll_uninit(void);
+void dsi_pll_uninit(bool disconnect_lanes);
 void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
 		u32 fifo_size, enum omap_burst_size *burst_size,
 		u32 *fifo_low, u32 *fifo_high);
-- 
1.7.1


  parent reply	other threads:[~2011-04-19  9:22 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-19  9:22 [PATCH 00/19] OMAP: DSS2: ULPS support Tomi Valkeinen
2011-04-19  9:22 ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 01/19] OMAP: DSS2: DSI: Add lane override functions Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 02/19] OMAP: DSS2: DSI: Remove CIO LDO status check Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 03/19] OMAP: DSS2: DSI: implement ULPS enter and exit Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` Tomi Valkeinen [this message]
2011-04-19  9:22   ` [PATCH 04/19] OMAP: DSS2: DSI: add option to leave DSI lanes powered on Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 05/19] OMAP: DSS2: DSI: rename complexio related functions Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 06/19] OMAP: DSS2: Add FEAT_DSI_REVERSE_TXCLKESC Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 07/19] OMAP: DSS2: DSI: fix _dsi_print_reset_status Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 08/19] OMAP: DSS2: DSI: implement enable/disable SCP clk Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 09/19] OMAP: DSS2: DSI: fix CIO init and uninit Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 10/19] OMAP: DSS2: DSI: wait for TXCLKESC domain to come out of reset Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 11/19] OMAP: DSS2: DSI: add parameter to enter ulps on disable Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 12/19] OMAP: DSS2: DSI: Add DSI pad muxing support Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 13/19] OMAP: DSS2: DSI: ensure VDDS_DSI is disabled on exit Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 14/19] OMAP: DSS2: Taal: Implement configurable ESD interval Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 15/19] OMAP: DSS2: Taal: Clean up ESD queueing Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 16/19] OMAP: DSS2: Taal: Add sysfs file for ESD interval Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 17/19] OMAP: DSS2: Taal: Separate panel reset Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 18/19] OMAP: DSS2: Taal: Rename esd_wq to workqueue Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-19  9:22 ` [PATCH 19/19] OMAP: DSS2: Taal: Implement ULPS functionality Tomi Valkeinen
2011-04-19  9:22   ` Tomi Valkeinen
2011-04-20  5:43 ` [PATCH 00/19] OMAP: DSS2: ULPS support Archit Taneja
2011-04-20  5:55   ` Archit Taneja
2011-04-20  6:08   ` Tomi Valkeinen
2011-04-20  6:08     ` Tomi Valkeinen

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=1303204942-25450-5-git-send-email-tomi.valkeinen@ti.com \
    --to=tomi.valkeinen@ti.com \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-omap@vger.kernel.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.