From: "Benoît Monin" <benoit.monin@bootlin.com>
To: Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Jun Chang <jun.chang@metanoia-comm.com>,
Paul Walmsley <pjw@kernel.org>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Alexandre Ghiti <alex@ghiti.fr>,
Philipp Zabel <p.zabel@pengutronix.de>,
Sebastian Reichel <sre@kernel.org>,
Vinod Koul <vkoul@kernel.org>,
Neil Armstrong <neil.armstrong@linaro.org>,
Manivannan Sadhasivam <mani@kernel.org>,
Conor Dooley <conor@kernel.org>,
Jonathan Cameron <jic23@kernel.org>,
Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>,
Thomas Gleixner <tglx@kernel.org>, Radu Rendec <radu@rendec.net>,
Samuel Holland <samuel.holland@sifive.com>,
Ben Zong-You Xie <ben717@andestech.com>,
Daniel Lezcano <daniel.lezcano@kernel.org>,
Ulf Hansson <ulfh@kernel.org>,
Jisheng Zhang <jszhang@kernel.org>,
CL Wang <cl634@andestech.com>, Mark Brown <broonie@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Wim Van Sebroeck <wim@linux-watchdog.org>,
Guenter Roeck <linux@roeck-us.net>,
Adrian Hunter <adrian.hunter@intel.com>,
Minas Harutyunyan <hminas@synopsys.com>
Cc: "Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
"Randolph Sheng-Kai Lin(林聖凱)" <randolph@andestech.com>,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-riscv@lists.infradead.org, linux-pm@vger.kernel.org,
linux-phy@lists.infradead.org,
"Paul Walmsley" <paul.walmsley@sifive.com>,
linux-mmc@vger.kernel.org, linux-spi@vger.kernel.org,
linux-usb@vger.kernel.org, linux-watchdog@vger.kernel.org,
"Benoît Monin" <benoit.monin@bootlin.com>
Subject: [PATCH 17/25] spi: atcspi200: add optional interrupt support
Date: Fri, 06 Nov 2026 10:30:14 +0100 [thread overview]
Message-ID: <20261106-mt2824-v1-17-86087eaf5af4@bootlin.com> (raw)
In-Reply-To: <20261106-mt2824-v1-0-86087eaf5af4@bootlin.com>
For PIO transfers, the driver busy-polls the FIFO empty/full flags and
the SPI active bit for completion. When the controller's interrupt is
available, use it instead of polling to keep the FIFO serviced and to
detect the end of transfer.
Interrupts are optional. Controllers without an interrupt keep using the
polling path, as do command-only transfers; the driver also falls back to
polling when the interrupt cannot be requested.
The command register is now written when a transfer is started instead of
in atcspi_prepare_trans(), so the interrupt path can enable interrupts
before starting the transfer and the first FIFO or end-of-transfer
event is not missed. As a result, it is also set at the beginning of
atcspi_dma_trans() and atcspi_xfer_data_poll(), and in the command-only
path of atcspi_exec_mem_op().
Introduce atcspi_reset_engine() as a helper to reset the SPI controller
and the FIFOs, and use on transfer error and in atcspi_setup().
The interrupt path configures the FIFO thresholds for the transfer and
restores them afterwards. It acknowledges the interrupt status before
servicing the FIFOs so events arriving during servicing are not lost,
and resets the controller if a transfer times out or completes with
transmit/receive words left unhandled.
Originally-by: Jun Chang <jun.chang@metanoia-comm.com>
Signed-off-by: Benoît Monin <benoit.monin@bootlin.com>
---
drivers/spi/spi-atcspi200.c | 255 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 245 insertions(+), 10 deletions(-)
diff --git a/drivers/spi/spi-atcspi200.c b/drivers/spi/spi-atcspi200.c
index b532c58c0ab9..df932620a690 100644
--- a/drivers/spi/spi-atcspi200.c
+++ b/drivers/spi/spi-atcspi200.c
@@ -12,6 +12,7 @@
#include <linux/dmaengine.h>
#include <linux/err.h>
#include <linux/errno.h>
+#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/minmax.h>
#include <linux/module.h>
@@ -20,6 +21,7 @@
#include <linux/regmap.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>
+#include <linux/unaligned.h>
/* Register definitions */
#define ATCSPI_TRANS_FMT 0x10 /* SPI transfer format register */
@@ -29,6 +31,8 @@
#define ATCSPI_DATA 0x2C /* SPI data register */
#define ATCSPI_CTRL 0x30 /* SPI control register */
#define ATCSPI_STATUS 0x34 /* SPI status register */
+#define ATCSPI_INTR_EN 0x38 /* SPI interrupt enable register */
+#define ATCSPI_INTR_ST 0x3C /* SPI interrupt status register */
#define ATCSPI_TIMING 0x40 /* SPI interface timing register */
#define ATCSPI_CONFIG 0x7C /* SPI configuration register */
@@ -62,11 +66,23 @@
#define CTRL_TX_FIFO_RST BIT(2)
#define CTRL_RX_DMA_EN BIT(3)
#define CTRL_TX_DMA_EN BIT(4)
+#define CTRL_TX_THRES GENMASK(23, 16)
+#define CTRL_RX_THRES GENMASK(15, 8)
/* Status register */
#define ATCSPI_ACTIVE BIT(0)
#define ATCSPI_RX_EMPTY BIT(14)
#define ATCSPI_TX_FULL BIT(23)
+#define ATCSPI_RXNUM_LO(x) FIELD_GET(GENMASK(13, 8), (x))
+#define ATCSPI_RXNUM_HI(x) FIELD_GET(GENMASK(25, 24), (x))
+#define ATCSPI_TXNUM_LO(x) FIELD_GET(GENMASK(21, 16), (x))
+#define ATCSPI_TXNUM_HI(x) FIELD_GET(GENMASK(29, 28), (x))
+
+/* Interrupt enable/status registers */
+#define ATCSPI_END_INT BIT(4)
+#define ATCSPI_TX_FIFO_INT BIT(3)
+#define ATCSPI_RX_FIFO_INT BIT(2)
+#define ATCSPI_INTR_ALL GENMASK(5, 0)
/* Interface timing setting */
#define TIMING_SCLK_DIV_MASK GENMASK(7, 0)
@@ -104,6 +120,12 @@
* the current transfer.
* @use_dma: Enable DMA mode if ATCSPI_DMA_SUPPORT is set and DMA is
* successfully configured.
+ * @irq: The controller interrupt, or 0 when it is not wired.
+ * @xfer_done: Completion signalled by the interrupt handler.
+ * @tx_ptr: Current position in the transmit buffer.
+ * @tx_words: Number of FIFO entries left to transmit.
+ * @rx_ptr: Current position in the receive buffer.
+ * @rx_words: Number of FIFO entries left to receive.
*/
struct atcspi_dev {
struct spi_controller *host;
@@ -119,6 +141,12 @@ struct atcspi_dev {
unsigned int rxfifo_size;
bool data_merge;
bool use_dma;
+ int irq;
+ struct completion xfer_done;
+ const void *tx_ptr;
+ unsigned int tx_words;
+ void *rx_ptr;
+ unsigned int rx_words;
};
static int atcspi_wait_fifo_ready(struct atcspi_dev *spi,
@@ -141,6 +169,193 @@ static int atcspi_wait_fifo_ready(struct atcspi_dev *spi,
return ret;
}
+static unsigned int atcspi_rx_fifo_avail(unsigned int status)
+{
+ return ATCSPI_RXNUM_LO(status) | (ATCSPI_RXNUM_HI(status) << 6);
+}
+
+static unsigned int atcspi_tx_fifo_avail(struct atcspi_dev *spi, unsigned int status)
+{
+ unsigned int n = ATCSPI_TXNUM_LO(status) | (ATCSPI_TXNUM_HI(status) << 6);
+
+ return n < spi->txfifo_size ? spi->txfifo_size - n : 0;
+}
+
+static void atcspi_fifo_read(struct atcspi_dev *spi, void *dst, unsigned int nb_words)
+{
+ unsigned int val, i;
+
+ if (spi->data_merge) {
+ unsigned int *buf = dst;
+
+ for (i = 0; i < nb_words; i++) {
+ regmap_read(spi->regmap, ATCSPI_DATA, &val);
+ put_unaligned(val, buf++);
+ }
+ } else {
+ unsigned char *buf = dst;
+
+ for (i = 0; i < nb_words; i++) {
+ regmap_read(spi->regmap, ATCSPI_DATA, &val);
+ *buf++ = (unsigned char)val;
+ }
+ }
+}
+
+static void atcspi_fifo_write(struct atcspi_dev *spi, const void *src, unsigned int nb_words)
+{
+ unsigned int val, i;
+
+ if (spi->data_merge) {
+ const unsigned int *buf = src;
+
+ for (i = 0; i < nb_words; i++) {
+ val = get_unaligned(buf++);
+ regmap_write(spi->regmap, ATCSPI_DATA, val);
+ }
+ } else {
+ const unsigned char *buf = src;
+
+ for (i = 0; i < nb_words; i++) {
+ val = *buf++;
+ regmap_write(spi->regmap, ATCSPI_DATA, val);
+ }
+ }
+}
+
+static irqreturn_t atcspi_irq(int irq, void *dev_id)
+{
+ struct atcspi_dev *spi = dev_id;
+ int num_byte = spi->data_merge ? 4 : 1;
+ unsigned int st, en, status, n;
+
+ regmap_read(spi->regmap, ATCSPI_INTR_ST, &st);
+ regmap_read(spi->regmap, ATCSPI_INTR_EN, &en);
+ st &= en;
+ if (!st)
+ return IRQ_NONE;
+
+ regmap_write(spi->regmap, ATCSPI_INTR_ST, st);
+
+ regmap_read(spi->regmap, ATCSPI_STATUS, &status);
+
+ if (st & (ATCSPI_RX_FIFO_INT | ATCSPI_END_INT)) {
+ n = min(atcspi_rx_fifo_avail(status), spi->rx_words);
+ atcspi_fifo_read(spi, spi->rx_ptr, n);
+ spi->rx_words -= n;
+ spi->rx_ptr = (unsigned char *)spi->rx_ptr + n * num_byte;
+ }
+
+ if (st & ATCSPI_TX_FIFO_INT) {
+ n = min(atcspi_tx_fifo_avail(spi, status), spi->tx_words);
+ atcspi_fifo_write(spi, spi->tx_ptr, n);
+ spi->tx_words -= n;
+ spi->tx_ptr = (unsigned char *)spi->tx_ptr + n * num_byte;
+ if (!spi->tx_words) {
+ en &= ~ATCSPI_TX_FIFO_INT;
+ regmap_write(spi->regmap, ATCSPI_INTR_EN, en);
+ }
+ }
+
+ if (st & ATCSPI_END_INT) {
+ regmap_write(spi->regmap, ATCSPI_INTR_EN, 0);
+ complete(&spi->xfer_done);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int atcspi_reset_engine(struct atcspi_dev *spi)
+{
+ unsigned int ctrl_val = CTRL_SPI_RST | CTRL_TX_FIFO_RST | CTRL_RX_FIFO_RST;
+ unsigned int val;
+
+ regmap_write(spi->regmap, ATCSPI_CTRL, ctrl_val);
+
+ return regmap_read_poll_timeout(spi->regmap,
+ ATCSPI_CTRL,
+ val,
+ !(val & ctrl_val),
+ 0,
+ ATCSPI_RDY_TIMEOUT_US);
+}
+
+static int atcspi_xfer_data_irq(struct atcspi_dev *spi,
+ const struct spi_mem_op *op)
+{
+ unsigned int ctrl, en = ATCSPI_END_INT;
+ int num_byte = spi->data_merge ? 4 : 1;
+ bool has_timedout = false;
+ int timeout;
+
+ spi->rx_words = 0;
+ spi->tx_words = 0;
+ spi->rx_ptr = op->data.buf.in;
+ spi->tx_ptr = op->data.buf.out;
+
+ if (op->data.dir == SPI_MEM_DATA_IN) {
+ spi->rx_words = op->data.nbytes / num_byte;
+ en |= ATCSPI_RX_FIFO_INT;
+ } else {
+ spi->tx_words = op->data.nbytes / num_byte;
+ en |= ATCSPI_TX_FIFO_INT;
+ }
+
+ regmap_read(spi->regmap, ATCSPI_CTRL, &ctrl);
+ ctrl &= ~(CTRL_TX_THRES | CTRL_RX_THRES);
+ ctrl |= FIELD_PREP(CTRL_TX_THRES, spi->txfifo_size / 2) |
+ FIELD_PREP(CTRL_RX_THRES, spi->rxfifo_size / 2);
+ regmap_write(spi->regmap, ATCSPI_CTRL, ctrl);
+
+ reinit_completion(&spi->xfer_done);
+
+ if (spi->tx_words) {
+ unsigned int status, nb_words;
+
+ regmap_read(spi->regmap, ATCSPI_STATUS, &status);
+ nb_words = min(atcspi_tx_fifo_avail(spi, status), spi->tx_words);
+ atcspi_fifo_write(spi, spi->tx_ptr, nb_words);
+ spi->tx_words -= nb_words;
+ spi->tx_ptr = (unsigned char *)spi->tx_ptr + nb_words * num_byte;
+ }
+
+ regmap_write(spi->regmap, ATCSPI_INTR_ST, ATCSPI_INTR_ALL);
+ regmap_write(spi->regmap, ATCSPI_INTR_EN, en);
+
+ regmap_write(spi->regmap, ATCSPI_CMD, op->cmd.opcode);
+
+ timeout = msecs_to_jiffies(ATCSPI_XFER_TIMEOUT(op->data.nbytes));
+ if (!wait_for_completion_timeout(&spi->xfer_done, timeout)) {
+ regmap_write(spi->regmap, ATCSPI_INTR_EN, 0);
+ synchronize_irq(spi->irq);
+
+ if (!completion_done(&spi->xfer_done))
+ has_timedout = true;
+ }
+
+ regmap_write(spi->regmap, ATCSPI_INTR_EN, 0);
+ regmap_write(spi->regmap, ATCSPI_INTR_ST, ATCSPI_INTR_ALL);
+
+ /* Reset the SPI controller if the transfer never completed */
+ if (has_timedout) {
+ atcspi_reset_engine(spi);
+
+ return -ETIMEDOUT;
+ }
+
+ /* Reset the controller for completed but truncated transfer */
+ if (spi->rx_words || spi->tx_words) {
+ atcspi_reset_engine(spi);
+
+ return -EIO;
+ }
+
+ /* restore FIFO thresholds for other transfer paths */
+ regmap_clear_bits(spi->regmap, ATCSPI_CTRL, CTRL_TX_THRES | CTRL_RX_THRES);
+
+ return 0;
+}
+
static int atcspi_xfer_data_poll(struct atcspi_dev *spi,
const struct spi_mem_op *op)
{
@@ -151,6 +366,8 @@ static int atcspi_xfer_data_poll(struct atcspi_dev *spi,
int num_byte;
int ret = 0;
+ regmap_write(spi->regmap, ATCSPI_CMD, op->cmd.opcode);
+
num_byte = spi->data_merge ? 4 : 1;
while (trans_bytes) {
if (op->data.dir == SPI_MEM_DATA_OUT) {
@@ -249,7 +466,6 @@ static void atcspi_prepare_trans(struct atcspi_dev *spi,
atcspi_set_trans_ctl(spi, op);
if (op->addr.nbytes)
regmap_write(spi->regmap, ATCSPI_ADDR, op->addr.val);
- regmap_write(spi->regmap, ATCSPI_CMD, op->cmd.opcode);
}
static int atcspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
@@ -313,6 +529,8 @@ static int atcspi_dma_trans(struct atcspi_dev *spi,
int timeout;
int ret;
+ regmap_write(spi->regmap, ATCSPI_CMD, op->cmd.opcode);
+
regmap_read(spi->regmap, ATCSPI_CTRL, &ctrl);
ctrl |= CTRL_TX_DMA_EN | CTRL_RX_DMA_EN;
regmap_write(spi->regmap, ATCSPI_CTRL, ctrl);
@@ -373,12 +591,16 @@ static int atcspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
if (op->data.nbytes) {
if (spi->use_dma && op->data.nbytes >= ATCSPI_DMA_THRESHOLD)
ret = atcspi_dma_trans(spi, op);
+ else if (spi->irq)
+ ret = atcspi_xfer_data_irq(spi, op);
else
ret = atcspi_xfer_data_poll(spi, op);
if (ret) {
dev_info(spi->dev, "SPI transmission failed\n");
goto exec_mem_exit;
}
+ } else {
+ regmap_write(spi->regmap, ATCSPI_CMD, op->cmd.opcode);
}
ret = regmap_read_poll_timeout(spi->regmap,
@@ -403,20 +625,12 @@ static const struct spi_controller_mem_ops atcspi_mem_ops = {
static int atcspi_setup(struct atcspi_dev *spi)
{
- unsigned int ctrl_val;
unsigned int val;
int actual_spi_sclk_f;
int ret;
unsigned char div;
- ctrl_val = CTRL_TX_FIFO_RST | CTRL_RX_FIFO_RST | CTRL_SPI_RST;
- regmap_write(spi->regmap, ATCSPI_CTRL, ctrl_val);
- ret = regmap_read_poll_timeout(spi->regmap,
- ATCSPI_CTRL,
- val,
- !(val & ctrl_val),
- 0,
- ATCSPI_RDY_TIMEOUT_US);
+ ret = atcspi_reset_engine(spi);
if (ret)
return dev_err_probe(spi->dev, ret,
"Timed out waiting for ATCSPI_CTRL\n");
@@ -586,6 +800,27 @@ static int atcspi_probe(struct platform_device *pdev)
spi->use_dma = true;
}
+ spi->irq = platform_get_irq_optional(pdev, 0);
+ if (spi->irq == -ENXIO)
+ spi->irq = 0;
+ else if (spi->irq < 0)
+ return dev_err_probe(spi->dev, spi->irq,
+ "Failed to get IRQ\n");
+
+ if (spi->irq) {
+ init_completion(&spi->xfer_done);
+ regmap_write(spi->regmap, ATCSPI_INTR_EN, 0);
+
+ ret = devm_request_irq(&pdev->dev, spi->irq, atcspi_irq, 0,
+ dev_name(&pdev->dev), spi);
+ if (ret) {
+ dev_info(spi->dev,
+ "Failed to request IRQ %d, fallback to polling\n",
+ spi->irq);
+ spi->irq = 0;
+ }
+ }
+
ret = devm_spi_register_controller(&pdev->dev, host);
if (ret)
return dev_err_probe(spi->dev, ret,
--
2.56.0
next prev parent reply other threads:[~2026-11-06 9:32 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 9:29 [PATCH 00/25] riscv: add support for the Metanoia MT2824 SoC and MT5824 EVB Benoît Monin
2026-11-06 9:29 ` [PATCH 01/25] dt-bindings: vendor-prefixes: add Metanoia Communications Benoît Monin
2026-11-06 11:17 ` Krzysztof Kozlowski
2026-11-06 11:39 ` Mark Brown
2026-11-06 11:50 ` Krzysztof Kozlowski
2026-11-06 9:29 ` [PATCH 02/25] dt-bindings: riscv: add Metanoia SoC-based boards Benoît Monin
2026-11-06 9:30 ` [PATCH 03/25] dt-bindings: reset: add Metanoia MT2824 Benoît Monin
2026-11-06 11:19 ` Krzysztof Kozlowski
2026-11-06 9:30 ` [PATCH 04/25] dt-bindings: power: reset: add Metanoia MT2824 reboot Benoît Monin
2026-11-06 11:23 ` Krzysztof Kozlowski
2026-11-06 9:30 ` [PATCH 05/25] dt-bindings: phy: add Metanoia USB2 PHY Benoît Monin
2026-11-06 9:30 ` [PATCH 06/25] dt-bindings: cache: andestech,ax45mp-cache: add MT2824 compatible Benoît Monin
2026-11-06 9:30 ` [PATCH 07/25] dt-bindings: interrupt-controller: sifive,plic-1.0.0: add Metanoia MT2824 Benoît Monin
2026-11-06 9:30 ` [PATCH 08/25] dt-bindings: interrupt-controller: andestech,plicsw: " Benoît Monin
2026-11-06 9:30 ` [PATCH 09/25] dt-bindings: timer: andestech,plmt0: " Benoît Monin
2026-11-06 9:30 ` [PATCH 10/25] dt-bindings: mmc: snps,dwcmshc-sdhci: " Benoît Monin
2026-11-06 9:30 ` [PATCH 11/25] dt-bindings: spi: andestech,ae350-spi: make DMA and interrupts optional Benoît Monin
2026-11-06 11:11 ` Mark Brown
2026-11-06 11:49 ` Krzysztof Kozlowski
2026-11-06 9:30 ` [PATCH 12/25] dt-bindings: spi: andestech,ae350-spi: add Metanoia MT2824 Benoît Monin
2026-11-06 9:30 ` [PATCH 13/25] dt-bindings: usb: dwc2: " Benoît Monin
2026-11-06 11:54 ` Krzysztof Kozlowski
2026-11-06 9:30 ` [PATCH 14/25] dt-bindings: watchdog: andestech,ae350-wdt: " Benoît Monin
2026-11-06 9:30 ` [PATCH 15/25] riscv: add ARCH_METANOIA Kconfig entry Benoît Monin
2026-11-06 9:30 ` [PATCH 16/25] reset: simple: add Metanoia MT2824 support Benoît Monin
2026-11-06 9:30 ` Benoît Monin [this message]
2026-11-06 9:30 ` [PATCH 18/25] spi: atcspi200: allow building for Metanoia SoCs Benoît Monin
2026-11-06 9:30 ` [PATCH 19/25] watchdog: atcwdt200: " Benoît Monin
2026-11-06 9:30 ` [PATCH 20/25] mmc: sdhci-of-dwcmshc: add MT2824 support Benoît Monin
2026-11-06 9:30 ` [PATCH 21/25] mmc: sdhci-of-dwcmshc: add MT2824 tuning and HS400 support Benoît Monin
2026-11-06 9:30 ` [PATCH 22/25] phy: metanoia: add USB2 PHY driver Benoît Monin
2026-11-06 9:56 ` Philipp Zabel
2026-11-06 9:30 ` [PATCH 23/25] usb: dwc2: add support for Metanoia MT2824 Benoît Monin
2026-11-06 11:52 ` Krzysztof Kozlowski
2026-11-06 11:52 ` Krzysztof Kozlowski
2026-11-06 9:30 ` [PATCH 24/25] riscv: add Metanoia MT2824 SoC and MT5824 EVB support Benoît Monin
2026-11-06 10:04 ` Philipp Zabel
2026-11-06 11:21 ` Krzysztof Kozlowski
2026-11-06 18:30 ` Conor Dooley
2026-11-06 9:30 ` [PATCH 25/25] MAINTAINERS: add RISC-V Metanoia SoC support Benoît Monin
2026-11-06 11:22 ` Krzysztof Kozlowski
2026-11-06 18:19 ` Conor Dooley
2026-11-06 11:15 ` [PATCH 00/25] riscv: add support for the Metanoia MT2824 SoC and MT5824 EVB Mark Brown
2026-11-06 18:46 ` Conor Dooley
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=20261106-mt2824-v1-17-86087eaf5af4@bootlin.com \
--to=benoit.monin@bootlin.com \
--cc=adrian.hunter@intel.com \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=ben717@andestech.com \
--cc=broonie@kernel.org \
--cc=cl634@andestech.com \
--cc=conor+dt@kernel.org \
--cc=conor@kernel.org \
--cc=daniel.lezcano@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=hminas@synopsys.com \
--cc=jic23@kernel.org \
--cc=jszhang@kernel.org \
--cc=jun.chang@metanoia-comm.com \
--cc=krzk+dt@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=linux-phy@lists.infradead.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-spi@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=linux-watchdog@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=mani@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=p.zabel@pengutronix.de \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=pjw@kernel.org \
--cc=prabhakar.mahadev-lad.rj@bp.renesas.com \
--cc=radu@rendec.net \
--cc=randolph@andestech.com \
--cc=robh@kernel.org \
--cc=samuel.holland@sifive.com \
--cc=sre@kernel.org \
--cc=tglx@kernel.org \
--cc=thomas.petazzoni@bootlin.com \
--cc=ulfh@kernel.org \
--cc=vkoul@kernel.org \
--cc=wim@linux-watchdog.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
all inboxes | Powered by JetHome®