All of lore.kernel.org
 help / color / mirror / Atom feed
From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>
To: Liviu Dudau <Liviu.Dudau@arm.com>,
	"airlied@linux.ie" <airlied@linux.ie>,
	Brian Starkey <Brian.Starkey@arm.com>,
	"maarten.lankhorst@linux.intel.com" 
	<maarten.lankhorst@linux.intel.com>,
	"sean@poorly.run" <sean@poorly.run>
Cc: "Jonathan Chai (Arm Technology China)" <Jonathan.Chai@arm.com>,
	"Julien Yin (Arm Technology China)" <Julien.Yin@arm.com>,
	"Thomas Sun (Arm Technology China)" <thomas.Sun@arm.com>,
	"Lowry Li (Arm Technology China)" <Lowry.Li@arm.com>,
	Ayan Halder <Ayan.Halder@arm.com>,
	"Tiannan Zhu (Arm Technology China)" <Tiannan.Zhu@arm.com>,
	"Yiqi Kang (Arm Technology China)" <Yiqi.Kang@arm.com>,
	nd <nd@arm.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>, Ben Davis <Ben.Davis@arm.com>,
	"Oscar Zhang (Arm Technology China)" <Oscar.Zhang@arm.com>,
	"Channing Chen (Arm Technology China)" <Channing.Chen@arm.com>,
	Mihail Atanassov <Mihail.Atanassov@arm.com>,
	"james qian wang (Arm Technology China)"
	<james.qian.wang@arm.com>
Subject: [PATCH v2 1/4] drm/komeda: Introduce komeda_coeffs_table/manager
Date: Tue, 13 Aug 2019 04:56:01 +0000	[thread overview]
Message-ID: <20190813045536.28239-2-james.qian.wang@arm.com> (raw)
In-Reply-To: <20190813045536.28239-1-james.qian.wang@arm.com>

komeda display HWs have kinds of coefficient tables for various purposes
like gamma/degamma. ususally these tables are shared by multiple HW
component and have limited number.
Introduce komeda_coeffs_table/manager for describing and managing these
tables, like table reuse, racing.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 drivers/gpu/drm/arm/display/komeda/Makefile   |   1 +
 .../drm/arm/display/komeda/komeda_coeffs.c    | 119 ++++++++++++++++++
 .../drm/arm/display/komeda/komeda_coeffs.h    |  74 +++++++++++
 3 files changed, 194 insertions(+)
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_coeffs.c
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_coeffs.h

diff --git a/drivers/gpu/drm/arm/display/komeda/Makefile b/drivers/gpu/drm/arm/display/komeda/Makefile
index 5c3900c2e764..38aa5843c03a 100644
--- a/drivers/gpu/drm/arm/display/komeda/Makefile
+++ b/drivers/gpu/drm/arm/display/komeda/Makefile
@@ -8,6 +8,7 @@ komeda-y := \
 	komeda_drv.o \
 	komeda_dev.o \
 	komeda_format_caps.o \
+	komeda_coeffs.o \
 	komeda_color_mgmt.o \
 	komeda_pipeline.o \
 	komeda_pipeline_state.o \
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.c b/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.c
new file mode 100644
index 000000000000..d9d35e23003c
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
+ * Author: James.Qian.Wang <james.qian.wang@arm.com>
+ *
+ */
+#include <linux/slab.h>
+#include "komeda_coeffs.h"
+
+static inline bool is_table_in_using(struct komeda_coeffs_table *table)
+{
+	return refcount_read(&table->refcount) > 1;
+}
+
+/* request a coeffs table for the coeffs data specified by argument coeffs */
+struct komeda_coeffs_table *
+komeda_coeffs_request(struct komeda_coeffs_manager *mgr, void *coeffs)
+{
+	struct komeda_coeffs_table *table;
+	u32 i;
+
+	mutex_lock(&mgr->mutex);
+
+	/* search table list to find if there is a in-using table with the
+	 * same coefficient content, if find, reuse this table.
+	 */
+	for (i = 0; i < mgr->n_tables; i++) {
+		table = mgr->tables[i];
+
+		/* skip the unused table */
+		if (!is_table_in_using(table))
+			continue;
+
+		if (!memcmp(table->coeffs, coeffs, mgr->coeffs_sz))
+			goto found;
+	}
+
+	/* can not reuse the existing in-using table, loop for a new one */
+	for (i = 0; i < mgr->n_tables; i++) {
+		table = mgr->tables[i];
+
+		if (!is_table_in_using(table)) {
+			memcpy(table->coeffs, coeffs, mgr->coeffs_sz);
+			table->needs_update = true;
+			goto found;
+		}
+	}
+
+	/* Since previous two search loop will directly goto found if found an
+	 * available table, so once program ran here means search failed.
+	 * clear the table to NULL, unlock(mgr->mutex) and return NULL.
+	 */
+	table = NULL;
+
+found:
+	komeda_coeffs_get(table);
+	mutex_unlock(&mgr->mutex);
+	return table;
+}
+
+/* Add a coeffs table to manager */
+int komeda_coeffs_add(struct komeda_coeffs_manager *mgr,
+		      u32 hw_id, u32 __iomem *reg,
+		      void (*update)(struct komeda_coeffs_table *table))
+{
+	struct komeda_coeffs_table *table;
+
+	if (mgr->n_tables >= ARRAY_SIZE(mgr->tables))
+		return -ENOSPC;
+
+	table = kzalloc(sizeof(*table), GFP_KERNEL);
+	if (!table)
+		return -ENOMEM;
+
+	table->coeffs = kzalloc(mgr->coeffs_sz, GFP_KERNEL);
+	if (!table->coeffs) {
+		kfree(table);
+		return -ENOMEM;
+	}
+
+	refcount_set(&table->refcount, 1);
+	table->mgr = mgr;
+	table->hw_id = hw_id;
+	table->update = update;
+	table->reg = reg;
+
+	mgr->tables[mgr->n_tables++] = table;
+	return 0;
+}
+
+struct komeda_coeffs_manager *komeda_coeffs_create_manager(u32 coeffs_sz)
+{
+	struct komeda_coeffs_manager *mgr;
+
+	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+	if (!mgr)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&mgr->mutex);
+	mgr->coeffs_sz = coeffs_sz;
+
+	return mgr;
+}
+
+void komeda_coeffs_destroy_manager(struct komeda_coeffs_manager *mgr)
+{
+	u32 i;
+
+	if (!mgr)
+		return;
+
+	for (i = 0; i < mgr->n_tables; i++) {
+		WARN_ON(is_table_in_using(mgr->tables[i]));
+		kfree(mgr->tables[i]->coeffs);
+		kfree(mgr->tables[i]);
+	}
+
+	kfree(mgr);
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.h b/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.h
new file mode 100644
index 000000000000..172ac2ea17ba
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
+ * Author: James.Qian.Wang <james.qian.wang@arm.com>
+ *
+ */
+#ifndef _KOMEDA_COEFFS_H_
+#define _KOMEDA_COEFFS_H_
+
+#include <linux/refcount.h>
+
+/* Komeda display HWs have kinds of coefficient tables for various purposes,
+ * like gamma/degamma. ususally these tables are shared by multiple HW component
+ * and limited number.
+ * The komeda_coeffs_table/manager are imported for describing and managing
+ * these tables for table reuse and racing.
+ */
+struct komeda_coeffs_table {
+	struct komeda_coeffs_manager *mgr;
+	refcount_t refcount;
+	bool needs_update;
+	u32 hw_id;
+	void *coeffs;
+	u32 __iomem *reg;
+	void (*update)(struct komeda_coeffs_table *table);
+};
+
+struct komeda_coeffs_manager {
+	struct mutex mutex; /* for tables accessing */
+	u32 n_tables;
+	u32 coeffs_sz;
+	struct komeda_coeffs_table *tables[8];
+};
+
+static inline struct komeda_coeffs_table *
+komeda_coeffs_get(struct komeda_coeffs_table *table)
+{
+	if (table)
+		refcount_inc(&table->refcount);
+
+	return table;
+}
+
+static inline void __komeda_coeffs_put(struct komeda_coeffs_table *table)
+{
+	if (table)
+		refcount_dec(&table->refcount);
+}
+
+#define komeda_coeffs_put(table) \
+do { \
+	__komeda_coeffs_put(table); \
+	(table) = NULL; \
+} while (0)
+
+static inline void komeda_coeffs_update(struct komeda_coeffs_table *table)
+{
+	if (!table || !table->needs_update)
+		return;
+
+	table->update(table);
+	table->needs_update = false;
+}
+
+struct komeda_coeffs_manager *komeda_coeffs_create_manager(u32 coeffs_sz);
+void komeda_coeffs_destroy_manager(struct komeda_coeffs_manager *mgr);
+
+int komeda_coeffs_add(struct komeda_coeffs_manager *mgr,
+		      u32 hw_id, u32 __iomem *reg,
+		      void (*update)(struct komeda_coeffs_table *table));
+struct komeda_coeffs_table *
+komeda_coeffs_request(struct komeda_coeffs_manager *mgr, void *coeffs);
+
+#endif /*_KOMEDA_COEFFS_H_*/
-- 
2.20.1


WARNING: multiple messages have this Message-ID (diff)
From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>
To: Liviu Dudau <Liviu.Dudau@arm.com>,
	"airlied@linux.ie" <airlied@linux.ie>,
	Brian Starkey <Brian.Starkey@arm.com>,
	"maarten.lankhorst@linux.intel.com"
	<maarten.lankhorst@linux.intel.com>,
	"sean@poorly.run" <sean@poorly.run>
Cc: nd <nd@arm.com>, Ayan Halder <Ayan.Halder@arm.com>,
	"Oscar Zhang (Arm Technology China)" <Oscar.Zhang@arm.com>,
	"Tiannan Zhu (Arm Technology China)" <Tiannan.Zhu@arm.com>,
	Mihail Atanassov <Mihail.Atanassov@arm.com>,
	"Jonathan Chai (Arm Technology China)" <Jonathan.Chai@arm.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>,
	"Julien Yin (Arm Technology China)" <Julien.Yin@arm.com>,
	"Channing Chen (Arm Technology China)" <Channing.Chen@arm.com>,
	"james qian wang (Arm Technology China)"
	<james.qian.wang@arm.com>,
	"Yiqi Kang (Arm Technology China)" <Yiqi.Kang@arm.com>,
	"Thomas Sun (Arm Technology China)" <thomas.Sun@arm.com>,
	"Lowry Li (Arm Technology China)" <Lowry.Li@arm.com>,
	Ben Davis <Ben.Davis@arm.com>
Subject: [PATCH v2 1/4] drm/komeda: Introduce komeda_coeffs_table/manager
Date: Tue, 13 Aug 2019 04:56:01 +0000	[thread overview]
Message-ID: <20190813045536.28239-2-james.qian.wang@arm.com> (raw)
In-Reply-To: <20190813045536.28239-1-james.qian.wang@arm.com>

komeda display HWs have kinds of coefficient tables for various purposes
like gamma/degamma. ususally these tables are shared by multiple HW
component and have limited number.
Introduce komeda_coeffs_table/manager for describing and managing these
tables, like table reuse, racing.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 drivers/gpu/drm/arm/display/komeda/Makefile   |   1 +
 .../drm/arm/display/komeda/komeda_coeffs.c    | 119 ++++++++++++++++++
 .../drm/arm/display/komeda/komeda_coeffs.h    |  74 +++++++++++
 3 files changed, 194 insertions(+)
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_coeffs.c
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_coeffs.h

diff --git a/drivers/gpu/drm/arm/display/komeda/Makefile b/drivers/gpu/drm/arm/display/komeda/Makefile
index 5c3900c2e764..38aa5843c03a 100644
--- a/drivers/gpu/drm/arm/display/komeda/Makefile
+++ b/drivers/gpu/drm/arm/display/komeda/Makefile
@@ -8,6 +8,7 @@ komeda-y := \
 	komeda_drv.o \
 	komeda_dev.o \
 	komeda_format_caps.o \
+	komeda_coeffs.o \
 	komeda_color_mgmt.o \
 	komeda_pipeline.o \
 	komeda_pipeline_state.o \
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.c b/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.c
new file mode 100644
index 000000000000..d9d35e23003c
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
+ * Author: James.Qian.Wang <james.qian.wang@arm.com>
+ *
+ */
+#include <linux/slab.h>
+#include "komeda_coeffs.h"
+
+static inline bool is_table_in_using(struct komeda_coeffs_table *table)
+{
+	return refcount_read(&table->refcount) > 1;
+}
+
+/* request a coeffs table for the coeffs data specified by argument coeffs */
+struct komeda_coeffs_table *
+komeda_coeffs_request(struct komeda_coeffs_manager *mgr, void *coeffs)
+{
+	struct komeda_coeffs_table *table;
+	u32 i;
+
+	mutex_lock(&mgr->mutex);
+
+	/* search table list to find if there is a in-using table with the
+	 * same coefficient content, if find, reuse this table.
+	 */
+	for (i = 0; i < mgr->n_tables; i++) {
+		table = mgr->tables[i];
+
+		/* skip the unused table */
+		if (!is_table_in_using(table))
+			continue;
+
+		if (!memcmp(table->coeffs, coeffs, mgr->coeffs_sz))
+			goto found;
+	}
+
+	/* can not reuse the existing in-using table, loop for a new one */
+	for (i = 0; i < mgr->n_tables; i++) {
+		table = mgr->tables[i];
+
+		if (!is_table_in_using(table)) {
+			memcpy(table->coeffs, coeffs, mgr->coeffs_sz);
+			table->needs_update = true;
+			goto found;
+		}
+	}
+
+	/* Since previous two search loop will directly goto found if found an
+	 * available table, so once program ran here means search failed.
+	 * clear the table to NULL, unlock(mgr->mutex) and return NULL.
+	 */
+	table = NULL;
+
+found:
+	komeda_coeffs_get(table);
+	mutex_unlock(&mgr->mutex);
+	return table;
+}
+
+/* Add a coeffs table to manager */
+int komeda_coeffs_add(struct komeda_coeffs_manager *mgr,
+		      u32 hw_id, u32 __iomem *reg,
+		      void (*update)(struct komeda_coeffs_table *table))
+{
+	struct komeda_coeffs_table *table;
+
+	if (mgr->n_tables >= ARRAY_SIZE(mgr->tables))
+		return -ENOSPC;
+
+	table = kzalloc(sizeof(*table), GFP_KERNEL);
+	if (!table)
+		return -ENOMEM;
+
+	table->coeffs = kzalloc(mgr->coeffs_sz, GFP_KERNEL);
+	if (!table->coeffs) {
+		kfree(table);
+		return -ENOMEM;
+	}
+
+	refcount_set(&table->refcount, 1);
+	table->mgr = mgr;
+	table->hw_id = hw_id;
+	table->update = update;
+	table->reg = reg;
+
+	mgr->tables[mgr->n_tables++] = table;
+	return 0;
+}
+
+struct komeda_coeffs_manager *komeda_coeffs_create_manager(u32 coeffs_sz)
+{
+	struct komeda_coeffs_manager *mgr;
+
+	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+	if (!mgr)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&mgr->mutex);
+	mgr->coeffs_sz = coeffs_sz;
+
+	return mgr;
+}
+
+void komeda_coeffs_destroy_manager(struct komeda_coeffs_manager *mgr)
+{
+	u32 i;
+
+	if (!mgr)
+		return;
+
+	for (i = 0; i < mgr->n_tables; i++) {
+		WARN_ON(is_table_in_using(mgr->tables[i]));
+		kfree(mgr->tables[i]->coeffs);
+		kfree(mgr->tables[i]);
+	}
+
+	kfree(mgr);
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.h b/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.h
new file mode 100644
index 000000000000..172ac2ea17ba
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_coeffs.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
+ * Author: James.Qian.Wang <james.qian.wang@arm.com>
+ *
+ */
+#ifndef _KOMEDA_COEFFS_H_
+#define _KOMEDA_COEFFS_H_
+
+#include <linux/refcount.h>
+
+/* Komeda display HWs have kinds of coefficient tables for various purposes,
+ * like gamma/degamma. ususally these tables are shared by multiple HW component
+ * and limited number.
+ * The komeda_coeffs_table/manager are imported for describing and managing
+ * these tables for table reuse and racing.
+ */
+struct komeda_coeffs_table {
+	struct komeda_coeffs_manager *mgr;
+	refcount_t refcount;
+	bool needs_update;
+	u32 hw_id;
+	void *coeffs;
+	u32 __iomem *reg;
+	void (*update)(struct komeda_coeffs_table *table);
+};
+
+struct komeda_coeffs_manager {
+	struct mutex mutex; /* for tables accessing */
+	u32 n_tables;
+	u32 coeffs_sz;
+	struct komeda_coeffs_table *tables[8];
+};
+
+static inline struct komeda_coeffs_table *
+komeda_coeffs_get(struct komeda_coeffs_table *table)
+{
+	if (table)
+		refcount_inc(&table->refcount);
+
+	return table;
+}
+
+static inline void __komeda_coeffs_put(struct komeda_coeffs_table *table)
+{
+	if (table)
+		refcount_dec(&table->refcount);
+}
+
+#define komeda_coeffs_put(table) \
+do { \
+	__komeda_coeffs_put(table); \
+	(table) = NULL; \
+} while (0)
+
+static inline void komeda_coeffs_update(struct komeda_coeffs_table *table)
+{
+	if (!table || !table->needs_update)
+		return;
+
+	table->update(table);
+	table->needs_update = false;
+}
+
+struct komeda_coeffs_manager *komeda_coeffs_create_manager(u32 coeffs_sz);
+void komeda_coeffs_destroy_manager(struct komeda_coeffs_manager *mgr);
+
+int komeda_coeffs_add(struct komeda_coeffs_manager *mgr,
+		      u32 hw_id, u32 __iomem *reg,
+		      void (*update)(struct komeda_coeffs_table *table));
+struct komeda_coeffs_table *
+komeda_coeffs_request(struct komeda_coeffs_manager *mgr, void *coeffs);
+
+#endif /*_KOMEDA_COEFFS_H_*/
-- 
2.20.1

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

  reply	other threads:[~2019-08-13  4:56 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-13  4:55 [PATCH v2 0/4] drm/komeda: Enable layer/plane color mgmt james qian wang (Arm Technology China)
2019-08-13  4:55 ` james qian wang (Arm Technology China)
2019-08-13  4:56 ` james qian wang (Arm Technology China) [this message]
2019-08-13  4:56   ` [PATCH v2 1/4] drm/komeda: Introduce komeda_coeffs_table/manager james qian wang (Arm Technology China)
2019-08-13  4:56 ` [PATCH v2 2/4] drm/komeda: Introduce komeda_color_manager/state james qian wang (Arm Technology China)
2019-08-13  4:56   ` james qian wang (Arm Technology China)
2019-08-13  9:51   ` Mihail Atanassov
2019-08-13  9:51     ` Mihail Atanassov
2019-08-14  7:52     ` james qian wang (Arm Technology China)
2019-08-14  7:52       ` james qian wang (Arm Technology China)
2019-08-14 10:47       ` Mihail Atanassov
2019-08-14 10:47         ` Mihail Atanassov
2019-08-19  8:50         ` james qian wang (Arm Technology China)
2019-08-19  8:50           ` james qian wang (Arm Technology China)
2019-08-19 10:45           ` Mihail Atanassov
2019-08-19 10:45             ` Mihail Atanassov
2019-08-13  4:56 ` [PATCH v2 3/4] drm: Increase DRM_OBJECT_MAX_PROPERTY to 32 james qian wang (Arm Technology China)
2019-08-13  4:56   ` james qian wang (Arm Technology China)
2019-08-13  4:56 ` [PATCH v2 4/4] drm/komeda: Enable Layer color management for komeda james qian wang (Arm Technology China)
2019-08-13  4:56   ` james qian wang (Arm Technology China)
2019-08-13 10:07   ` Mihail Atanassov
2019-08-13 10:07     ` Mihail Atanassov
2019-08-14  8:10     ` james qian wang (Arm Technology China)
2019-08-14  8:10       ` james qian wang (Arm Technology China)

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=20190813045536.28239-2-james.qian.wang@arm.com \
    --to=james.qian.wang@arm.com \
    --cc=Ayan.Halder@arm.com \
    --cc=Ben.Davis@arm.com \
    --cc=Brian.Starkey@arm.com \
    --cc=Channing.Chen@arm.com \
    --cc=Jonathan.Chai@arm.com \
    --cc=Julien.Yin@arm.com \
    --cc=Liviu.Dudau@arm.com \
    --cc=Lowry.Li@arm.com \
    --cc=Mihail.Atanassov@arm.com \
    --cc=Oscar.Zhang@arm.com \
    --cc=Tiannan.Zhu@arm.com \
    --cc=Yiqi.Kang@arm.com \
    --cc=airlied@linux.ie \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=nd@arm.com \
    --cc=sean@poorly.run \
    --cc=thomas.Sun@arm.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 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.