From: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
To: "Oded Gabbay" <ogabbay@kernel.org>,
"Jonathan Corbet" <corbet@lwn.net>,
"Shuah Khan" <skhan@linuxfoundation.org>,
"Randy Dunlap" <rdunlap@infradead.org>,
"Ekansh Gupta" <ekansh.gupta@oss.qualcomm.com>,
"Srinivas Kandagatla" <srini@kernel.org>,
"Arnd Bergmann" <arnd@arndb.de>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"Sumit Semwal" <sumit.semwal@linaro.org>,
"Christian König" <christian.koenig@amd.com>,
"Philipp Stanner" <phasta@kernel.org>,
dmitry.baryshkov@oss.qualcomm.com, andersson@kernel.org,
krzk@kernel.org, rob.clark@oss.qualcomm.com, jgg@ziepe.ca
Cc: lingtong@qti.qualcomm.com, cacar@qti.qualcomm.com,
sandheep@qti.qualcomm.com,
Bharath Kumar <bkumar@qti.qualcomm.com>,
Chenna Kesava Raju <chennak@qti.qualcomm.com>,
dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org,
Bharath Kumar <quic_bkumar@quicinc.com>,
Chenna Kesava Raju <quic_chennak@quicinc.com>,
Ekansh Gupta <ekangupt@qti.qualcomm.com>
Subject: [PATCH v4 02/25] accel/qda: Add initial QDA DRM accelerator driver
Date: Mon, 02 Nov 2026 03:51:15 +0530 [thread overview]
Message-ID: <20261102-v4-v4-2-88f2f24a5f0b@qti.qualcomm.com> (raw)
In-Reply-To: <20261102-v4-v4-0-88f2f24a5f0b@qti.qualcomm.com>
Qualcomm SoCs offload work to Hexagon DSPs today through
drivers/misc/fastrpc.c, a misc character device driver written before
the DRM accel subsystem existed. QDA is a new driver for the same
hardware, built around GEM and DMA-BUF instead of the ad hoc buffer
tracking the legacy driver has to do on its own, and exposed through
/dev/accel/accelN like other compute accelerators.
This patch lays the skeleton: a drm_driver with DRIVER_COMPUTE_ACCEL,
per-session state that later patches share between the native UAPI and
the legacy compatibility shim, and an rpmsg binding that brings the
device up when the DSP's RPMsg channel appears. The DSP domain name
comes from the "label" property already used on this node, since that
is how the platform identifies which Hexagon instance a given channel
talks to.
Both compatibles the binding defines are matched, so the driver probes
on every platform the legacy driver supports. The glymur, hawi, maili
and nord nodes name "qcom,kaanapali-fastrpc" as their fallback
compatible and so are matched by that entry. The DSP parameters that
differ between these platforms - the stream ID position in a
DSP-visible address, the DMA address width, and whether the firmware
supports invoke completion polling - are added as match data together
with the code that uses them, since the values are only meaningful
next to it.
The rpmsg binding targets the same compatibles that
drivers/misc/fastrpc.c binds to, because both drivers talk to the same
physical DSP behind the same RPMsg channel. Two rpmsg_drivers cannot
share a device, and driver_register() refuses two drivers with the same
name on one bus, so drivers/misc/Kconfig now makes QCOM_FASTRPC depend
on !DRM_ACCEL_QDA: a given kernel build contains one or the other. The
dependency is expressed on the legacy symbol so that enabling QDA is
what turns fastrpc off, rather than the reverse.
Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
---
MAINTAINERS | 1 +
drivers/accel/Kconfig | 1 +
drivers/accel/Makefile | 3 +-
drivers/accel/qda/Kconfig | 27 +++++++++++++
drivers/accel/qda/Makefile | 10 +++++
drivers/accel/qda/qda_drv.c | 84 +++++++++++++++++++++++++++++++++++++++
drivers/accel/qda/qda_drv.h | 65 +++++++++++++++++++++++++++++++
drivers/accel/qda/qda_rpmsg.c | 91 +++++++++++++++++++++++++++++++++++++++++++
drivers/misc/Kconfig | 1 +
9 files changed, 282 insertions(+), 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 6803c60cbc64..77687a35ac13 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22981,6 +22981,7 @@ L: dri-devel@lists.freedesktop.org
S: Supported
T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/accel/qda/
+F: drivers/accel/qda/
QUALCOMM EMAC GIGABIT ETHERNET DRIVER
M: Timur Tabi <timur@kernel.org>
diff --git a/drivers/accel/Kconfig b/drivers/accel/Kconfig
index bdf48ccafcf2..74ac0f71bc9d 100644
--- a/drivers/accel/Kconfig
+++ b/drivers/accel/Kconfig
@@ -29,6 +29,7 @@ source "drivers/accel/ethosu/Kconfig"
source "drivers/accel/habanalabs/Kconfig"
source "drivers/accel/ivpu/Kconfig"
source "drivers/accel/qaic/Kconfig"
+source "drivers/accel/qda/Kconfig"
source "drivers/accel/rocket/Kconfig"
endif
diff --git a/drivers/accel/Makefile b/drivers/accel/Makefile
index 1d3a7251b950..17686a592900 100644
--- a/drivers/accel/Makefile
+++ b/drivers/accel/Makefile
@@ -5,4 +5,5 @@ obj-$(CONFIG_DRM_ACCEL_ARM_ETHOSU) += ethosu/
obj-$(CONFIG_DRM_ACCEL_HABANALABS) += habanalabs/
obj-$(CONFIG_DRM_ACCEL_IVPU) += ivpu/
obj-$(CONFIG_DRM_ACCEL_QAIC) += qaic/
-obj-$(CONFIG_DRM_ACCEL_ROCKET) += rocket/
\ No newline at end of file
+obj-$(CONFIG_DRM_ACCEL_QDA) += qda/
+obj-$(CONFIG_DRM_ACCEL_ROCKET) += rocket/
diff --git a/drivers/accel/qda/Kconfig b/drivers/accel/qda/Kconfig
new file mode 100644
index 000000000000..e2f3f01016c6
--- /dev/null
+++ b/drivers/accel/qda/Kconfig
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Qualcomm DSP accelerator driver
+#
+
+config DRM_ACCEL_QDA
+ tristate "Qualcomm DSP accelerator"
+ depends on DRM_ACCEL
+ depends on ARCH_QCOM || COMPILE_TEST
+ depends on RPMSG
+ help
+ Enables the DRM-based accelerator driver for Qualcomm's Hexagon DSPs.
+ This driver provides a standardized interface for offloading computational
+ tasks to the DSP, including audio processing, sensor offload, computer
+ vision, and AI inference workloads.
+
+ The driver supports all DSP domains (ADSP, CDSP, SDSP, GDSP) and
+ implements the FastRPC protocol for communication between the application
+ processor and DSP. It integrates with the Linux kernel's Compute
+ Accelerators subsystem (drivers/accel/) and is intended to replace the
+ FastRPC driver in drivers/misc/. Both drivers bind the same device tree
+ nodes, so only one of them can be built.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called qda.
diff --git a/drivers/accel/qda/Makefile b/drivers/accel/qda/Makefile
new file mode 100644
index 000000000000..dbe809067a8b
--- /dev/null
+++ b/drivers/accel/qda/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Makefile for Qualcomm DSP accelerator driver
+#
+
+obj-$(CONFIG_DRM_ACCEL_QDA) := qda.o
+
+qda-y := \
+ qda_drv.o \
+ qda_rpmsg.o
diff --git a/drivers/accel/qda/qda_drv.c b/drivers/accel/qda/qda_drv.c
new file mode 100644
index 000000000000..f4430332ff6e
--- /dev/null
+++ b/drivers/accel/qda/qda_drv.c
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <drm/drm_accel.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_file.h>
+#include <drm/drm_gem.h>
+#include <drm/drm_ioctl.h>
+#include <drm/drm_print.h>
+
+#include "qda_drv.h"
+
+static struct qda_session *qda_session_alloc(struct qda_dev *qdev)
+{
+ struct qda_session *session;
+
+ session = kzalloc_obj(*session);
+ if (!session)
+ return ERR_PTR(-ENOMEM);
+
+ session->qda_dev = qdev;
+
+ return session;
+}
+
+static int qda_open(struct drm_device *dev, struct drm_file *file)
+{
+ struct qda_dev *qdev = qda_dev_from_drm(dev);
+ struct qda_session *session;
+
+ session = qda_session_alloc(qdev);
+ if (IS_ERR(session))
+ return PTR_ERR(session);
+
+ session->file = file;
+ file->driver_priv = session;
+
+ return 0;
+}
+
+static void qda_postclose(struct drm_device *dev, struct drm_file *file)
+{
+ struct qda_session *session = file->driver_priv;
+
+ kfree(session);
+}
+
+DEFINE_DRM_ACCEL_FOPS(qda_accel_fops);
+
+static const struct drm_driver qda_drm_driver = {
+ .driver_features = DRIVER_COMPUTE_ACCEL,
+ .fops = &qda_accel_fops,
+ .open = qda_open,
+ .postclose = qda_postclose,
+ .name = QDA_DRIVER_NAME,
+ .desc = "Qualcomm DSP Accelerator Driver",
+};
+
+struct qda_dev *qda_alloc_device(struct device *dev)
+{
+ struct qda_dev *qdev;
+
+ qdev = devm_drm_dev_alloc(dev, &qda_drm_driver, struct qda_dev, drm_dev);
+ if (IS_ERR(qdev))
+ return ERR_CAST(qdev);
+
+ return qdev;
+}
+
+int qda_register_device(struct qda_dev *qdev)
+{
+ int ret;
+
+ ret = drm_dev_register(&qdev->drm_dev, 0);
+ if (ret)
+ drm_err(&qdev->drm_dev, "Failed to register DRM device: %d\n", ret);
+
+ return ret;
+}
+
+MODULE_AUTHOR("Qualcomm AI Infra Team");
+MODULE_DESCRIPTION("Qualcomm DSP Accelerator Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/accel/qda/qda_drv.h b/drivers/accel/qda/qda_drv.h
new file mode 100644
index 000000000000..dd3345b6a5ad
--- /dev/null
+++ b/drivers/accel/qda/qda_drv.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef __QDA_DRV_H__
+#define __QDA_DRV_H__
+
+#include <linux/device.h>
+#include <linux/rpmsg.h>
+#include <linux/types.h>
+#include <drm/drm_device.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_file.h>
+
+/* Driver identification */
+#define QDA_DRIVER_NAME "qda"
+
+/**
+ * struct qda_session - Per-open-file private data
+ *
+ * Allocated in qda_open() and stored in drm_file::driver_priv.
+ */
+struct qda_session {
+ /** @qda_dev: Back-pointer to device structure */
+ struct qda_dev *qda_dev;
+ /** @file: The drm_file this session belongs to */
+ struct drm_file *file;
+};
+
+/**
+ * struct qda_dev - Main device structure for QDA driver
+ *
+ * The DRM device is embedded as the first member so that container_of()
+ * can recover the qda_dev from any drm_device pointer.
+ */
+struct qda_dev {
+ /** @drm_dev: Embedded DRM device; recover via qda_dev_from_drm() */
+ struct drm_device drm_dev;
+ /** @rpdev: RPMsg device for communication with the remote processor */
+ struct rpmsg_device *rpdev;
+ /** @dev: Underlying Linux device */
+ struct device *dev;
+ /** @dsp_name: Name of the DSP domain (e.g. "cdsp", "adsp") */
+ const char *dsp_name;
+};
+
+/**
+ * qda_dev_from_drm - Recover qda_dev from an embedded drm_device pointer
+ * @dev: Pointer to the embedded drm_device
+ *
+ * Return: Pointer to the enclosing qda_dev.
+ */
+static inline struct qda_dev *qda_dev_from_drm(struct drm_device *dev)
+{
+ return container_of(dev, struct qda_dev, drm_dev);
+}
+
+/* Device allocation (uses devm_drm_dev_alloc internally) */
+struct qda_dev *qda_alloc_device(struct device *dev);
+
+/* Core device lifecycle */
+int qda_register_device(struct qda_dev *qdev);
+
+#endif /* __QDA_DRV_H__ */
diff --git a/drivers/accel/qda/qda_rpmsg.c b/drivers/accel/qda/qda_rpmsg.c
new file mode 100644
index 000000000000..6bd977e8d68a
--- /dev/null
+++ b/drivers/accel/qda/qda_rpmsg.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/rpmsg.h>
+#include <drm/drm_print.h>
+
+#include "qda_drv.h"
+
+/*
+ * Both compatibles the binding defines are matched here. The glymur, hawi,
+ * maili and nord nodes name "qcom,kaanapali-fastrpc" as their fallback
+ * compatible and so are matched by that entry. Per-SoC DSP parameters are
+ * attached as match data by a later patch, once there is something that
+ * consumes them.
+ */
+static const struct of_device_id qda_rpmsg_of_match[] = {
+ { .compatible = "qcom,kaanapali-fastrpc" },
+ { .compatible = "qcom,fastrpc" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, qda_rpmsg_of_match);
+
+static struct qda_dev *qda_rpmsg_alloc_and_init_qdev(struct rpmsg_device *rpdev)
+{
+ struct qda_dev *qdev;
+
+ qdev = qda_alloc_device(&rpdev->dev);
+ if (IS_ERR(qdev))
+ return qdev;
+
+ qdev->dev = &rpdev->dev;
+ qdev->rpdev = rpdev;
+ dev_set_drvdata(&rpdev->dev, qdev);
+
+ return qdev;
+}
+
+/*
+ * The rpmsg core requires a callback, so one is registered from the start.
+ * Responses are dispatched here once there are invocations to answer.
+ */
+static int qda_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
+ void *priv, u32 src)
+{
+ return 0;
+}
+
+static void qda_rpmsg_remove(struct rpmsg_device *rpdev)
+{
+ struct qda_dev *qdev = dev_get_drvdata(&rpdev->dev);
+
+ /*
+ * Unplug before clearing @rpdev: once there are ioctls that reach the
+ * DSP, this is what stops a new one from starting and waits for the
+ * ones already running, so that none of them sees a transport that has
+ * gone away.
+ */
+ drm_dev_unplug(&qdev->drm_dev);
+ qdev->rpdev = NULL;
+}
+
+static int qda_rpmsg_probe(struct rpmsg_device *rpdev)
+{
+ struct qda_dev *qdev;
+ int ret;
+
+ qdev = qda_rpmsg_alloc_and_init_qdev(rpdev);
+ if (IS_ERR(qdev))
+ return PTR_ERR(qdev);
+
+ ret = of_property_read_string(rpdev->dev.of_node, "label", &qdev->dsp_name);
+ if (ret) {
+ dev_err(&rpdev->dev, "Missing 'label' property in DT node: %d\n", ret);
+ return ret;
+ }
+
+ return qda_register_device(qdev);
+}
+
+static struct rpmsg_driver qda_rpmsg_driver = {
+ .probe = qda_rpmsg_probe,
+ .remove = qda_rpmsg_remove,
+ .callback = qda_rpmsg_cb,
+ .drv = {
+ .name = QDA_DRIVER_NAME,
+ .of_match_table = qda_rpmsg_of_match,
+ },
+};
+
+module_rpmsg_driver(qda_rpmsg_driver);
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index c40e89cc5724..14b7bbaadcaa 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -269,6 +269,7 @@ config QCOM_FASTRPC
tristate "Qualcomm FastRPC"
depends on ARCH_QCOM || COMPILE_TEST
depends on RPMSG
+ depends on !DRM_ACCEL_QDA
select DMA_SHARED_BUFFER
select QCOM_SCM
help
--
2.34.1
next prev parent reply other threads:[~2026-11-01 22:21 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-01 22:21 [PATCH v4 00/25] accel/qda: Qualcomm DSP Accelerator driver Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 01/25] accel/qda: Add QDA driver documentation Ekansh Gupta
2026-11-01 22:21 ` Ekansh Gupta [this message]
2026-11-02 8:42 ` [PATCH v4 02/25] accel/qda: Add initial QDA DRM accelerator driver Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 03/25] accel/qda: Add compute context bank devices Ekansh Gupta
2026-11-02 8:43 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 04/25] accel/qda: Assign a context bank to each session Ekansh Gupta
2026-11-02 8:45 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 05/25] accel/qda: Add UAPI header and DSP query ioctl Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 06/25] accel/qda: Add buffer allocation for the DSP Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 07/25] accel/qda: Add DMA-BUF import Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 08/25] accel/qda: Add legacy ops base and auxiliary device Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 09/25] accel/qda: Add legacy FastRPC shim skeleton Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 10/25] accel/qda: Add FastRPC invocation contexts Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 11/25] accel/qda: Add RPMsg send and response dispatch Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 12/25] accel/qda: Add invocation argument validation and packing Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 13/25] accel/qda: Add the invocation ioctl and teardown on unplug Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 14/25] accel/qda: Add invocation through the legacy FastRPC shim Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 15/25] accel/qda: Add DSP process creation and release Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 16/25] accel/qda: Add DSP process creation and release to the legacy shim Ekansh Gupta
2026-11-02 8:47 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 17/25] accel/qda: Add remote memory mapping to the DSP address space Ekansh Gupta
2026-11-02 9:24 ` Konrad Dybcio
2026-11-01 22:21 ` [PATCH v4 18/25] accel/qda: Add remote memory unmapping from " Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 19/25] accel/qda: Add remote memory map and unmap to the legacy shim Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 20/25] accel/qda: Add remote attach to root and sensors protection domains Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 21/25] accel/qda: Add Audio protection domain attach and its remote heap Ekansh Gupta
2026-11-02 8:43 ` Arnd Bergmann
2026-11-02 8:50 ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 22/25] accel/qda: Add remote session attach to the legacy shim Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 23/25] accel/qda: Add DSP capability query Ekansh Gupta
2026-11-02 8:46 ` Arnd Bergmann
2026-11-01 22:21 ` [PATCH v4 24/25] accel/qda: Add legacy shim support for " Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 25/25] accel/qda: Add poll mode for invocation completion Ekansh Gupta
2026-11-02 8:53 ` [PATCH v4 00/25] accel/qda: Qualcomm DSP Accelerator driver Krzysztof Kozlowski
2026-11-02 10:08 ` Ekansh Gupta
2026-11-02 10:12 ` Krzysztof Kozlowski
2026-11-02 10:52 ` Ekansh Gupta
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=20261102-v4-v4-2-88f2f24a5f0b@qti.qualcomm.com \
--to=ekansh.gupta@oss.qualcomm.com \
--cc=airlied@gmail.com \
--cc=andersson@kernel.org \
--cc=arnd@arndb.de \
--cc=bkumar@qti.qualcomm.com \
--cc=cacar@qti.qualcomm.com \
--cc=chennak@qti.qualcomm.com \
--cc=christian.koenig@amd.com \
--cc=corbet@lwn.net \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=ekangupt@qti.qualcomm.com \
--cc=gregkh@linuxfoundation.org \
--cc=jgg@ziepe.ca \
--cc=krzk@kernel.org \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=lingtong@qti.qualcomm.com \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=ogabbay@kernel.org \
--cc=phasta@kernel.org \
--cc=quic_bkumar@quicinc.com \
--cc=quic_chennak@quicinc.com \
--cc=rdunlap@infradead.org \
--cc=rob.clark@oss.qualcomm.com \
--cc=sandheep@qti.qualcomm.com \
--cc=simona@ffwll.ch \
--cc=skhan@linuxfoundation.org \
--cc=srini@kernel.org \
--cc=sumit.semwal@linaro.org \
--cc=tzimmermann@suse.de \
/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
all inboxes | Powered by JetHome®