From: sashiko-bot@kernel.org
To: "Jyothi Kumar Seerapu" <jyothi.seerapu@oss.qualcomm.com>
Cc: dmaengine@vger.kernel.org, devicetree@vger.kernel.org,
robh@kernel.org, conor+dt@kernel.org, vkoul@kernel.org,
Frank.Li@kernel.org
Subject: Re: [PATCH 1/6] spi: spi-geni-qcom: Add transfer_one_message() support
Date: Fri, 06 Nov 2026 15:20:17 +0000 [thread overview]
Message-ID: <sashiko-outbox-201663@kernel.org> (raw)
In-Reply-To: <20261106-qspi_upstream_series-v1-1-21f43042dd60@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] spi: spi-geni-qcom: unreset started flag in
spi_geni_transfer_one_message()
- [Medium] spi: spi-geni-qcom: double handle_se_timeout() call on target
abort
It also noticed 1 related pre-existing issue this patch does not
introduce:
- [High] spi: geni-qcom: incorrect DMA timeout handling in
spi_geni_target_abort() [1]
--
commit 3683cd703233401c535fc67323251b79d0c02313
Author: Jyothi Kumar Seerapu <jyothi.seerapu@oss.qualcomm.com>
spi: spi-geni-qcom: Add transfer_one_message() support
This commit replaces the SPI core's default transfer_one_message() path in
the Qualcomm GENI SPI driver with a driver-specific implementation that
handles message sequencing, GPIO chip-select control, transfer delays, DMA
buffer synchronization, and error recovery.
> diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
> index 6c57f8309a3b2..25c03096ee23f 100644
> --- a/drivers/spi/spi-geni-qcom.c
> +++ b/drivers/spi/spi-geni-qcom.c
[ ... ]
> @@ -935,16 +940,206 @@ static int spi_geni_transfer_one(struct spi_controller *spi,
[ ... ]
> +static int spi_geni_transfer_one_message(struct spi_controller *spi,
> + struct spi_message *msg)
> +{
> + struct spi_geni_master *mas = spi_controller_get_devdata(spi);
> + struct spi_device *spi_slv = msg->spi;
> + struct spi_transfer *xfer, *next_xfer;
> + bool keep_cs = false;
> + bool dma_synced = false;
> + bool started = false;
> + int ret = 0;
> +
> + xfer = list_first_entry(&msg->transfers, struct spi_transfer, transfer_list);
> + spi_geni_set_cs(spi_slv, !xfer->cs_off);
> +
> + list_for_each_entry(xfer, &msg->transfers, transfer_list) {
> + if ((xfer->tx_buf || xfer->rx_buf) && xfer->len) {
> + reinit_completion(&mas->xfer_done);
> +
> + /* Synchronize buffers only for DMA; the SE FIFO path uses CPU access. */
> + dma_synced = mas->cur_xfer_mode == GENI_GPI_DMA ||
> + ((xfer->tx_sg.nents || xfer->rx_sg.nents) &&
> + xfer->tx_sg.nents <= 1 && xfer->rx_sg.nents <= 1);
> + if (dma_synced)
> + spi_geni_dma_sync(spi, xfer, true);
> +
> + ret = spi_geni_transfer_one(spi, spi_slv, xfer);
> + if (ret < 0) {
> + dev_err(mas->dev, "Transfer failed: %d\n", ret);
> + goto out_err;
> + }
> + started = true;
> +
> + ret = spi_geni_wait_for_xfer(spi, xfer);
> + if (ret)
> + goto out_err;
> +
> + /* DMA errors and target aborts are reported through msg->status. */
> + if (msg->status != -EINPROGRESS) {
> + ret = msg->status;
> + goto out_err;
> + }
> + if (dma_synced) {
> + spi_geni_dma_sync(spi, xfer, false);
> + dma_synced = false;
> + }
> + } else if (xfer->len) {
> + dev_err(&spi_slv->dev,
> + "Bufferless transfer has length %u\n", xfer->len);
> + ret = -EINVAL;
> + goto out_err;
> + }
> +
> + msg->actual_length += xfer->len;
> + ret = spi_transfer_delay_exec(xfer);
> + if (ret)
> + goto out_err;
[ ... ]
> +out_err:
> + if (!ret && msg->status != -EINPROGRESS)
> + ret = msg->status;
> +
> + if (ret && started)
> + spi_geni_handle_err(spi, msg);
[Severity: Medium]
Should started be reset to false after each transfer completes, just like
dma_synced?
In a multi-transfer message, if one transfer finishes normally and a
subsequent transfer fails before starting hardware (for example, failing
the bufferless transfer check or set_rate() in setup_se_xfer()), started
remains true from the earlier transfer. The out_err path then calls
spi_geni_handle_err() on an idle controller, where handle_se_timeout()
issues cancel and abort commands with no active transfer, waits up to two
seconds on completion timeouts, and sets mas->abort_failed = true, causing
later transfers to fail with -EBUSY.
[ ... ]
> @@ -1057,11 +1253,14 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
>
> static int spi_geni_target_abort(struct spi_controller *spi)
> {
> + struct spi_geni_master *mas = spi_controller_get_devdata(spi);
> +
> if (!spi->cur_msg)
> return 0;
>
> + spi->cur_msg->status = -ECANCELED;
> handle_se_timeout(spi);
[Severity: High]
This problem wasn't introduced by this patch, but spi_geni_target_abort()
unconditionally calls handle_se_timeout() regardless of mas->cur_xfer_mode
[1]. When operating in GENI_GPI_DMA mode, this skips
handle_gpi_timeout() and dmaengine_terminate_sync(), and instead writes SE
registers such as SE_GENI_TX_WATERMARK_REG while the GPI DMA engine is
still active, leaving the controller in an unrecoverable state. Should
this call spi_geni_handle_err() or dispatch on mas->cur_xfer_mode?
> - spi_finalize_current_transfer(spi);
> + complete(&mas->xfer_done);
>
> return 0;
> }
[Severity: Medium]
Does setting spi->cur_msg->status = -ECANCELED here cause
handle_se_timeout() to run twice on every target abort?
spi_geni_target_abort() calls handle_se_timeout() and then completes
mas->xfer_done. When spi_geni_transfer_one_message() wakes up, it sees
msg->status != -EINPROGRESS, sets ret = -ECANCELED, and jumps to out_err
with started == true, which calls spi_geni_handle_err() ->
handle_se_timeout() a second time on the already-aborted hardware. Because
mas->cur_xfer is already NULL on the second call, handle_se_timeout()
issues a redundant abort command that can time out after 1 second and set
mas->abort_failed = true.
In addition, if wait_for_completion_interruptible() in
spi_geni_wait_for_xfer() is interrupted by a signal at the same time as
spi_geni_target_abort(), both threads run handle_se_timeout() concurrently
without serialization on mas->abort_done, mas->tx_reset_done, and
mas->rx_reset_done.
[1] https://sashiko.dev/#/bug/linux-9f164df4-358b-4ab0-bbe7-3843965ed2e8
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261106-qspi_upstream_series-v1-0-21f43042dd60@oss.qualcomm.com?part=1
next prev parent reply other threads:[~2026-11-06 15:20 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 15:01 [PATCH 0/6] spi: qcom-geni: Add QSPI support over GPI DMA Jyothi Kumar Seerapu
2026-11-06 15:01 ` [PATCH 1/6] spi: spi-geni-qcom: Add transfer_one_message() support Jyothi Kumar Seerapu
2026-11-06 15:20 ` sashiko-bot [this message]
2026-11-06 15:01 ` [PATCH 2/6] dt-bindings: dma: qcom-gpi: Add QSPI protocol identifier Jyothi Kumar Seerapu
2026-11-09 13:42 ` Krzysztof Kozlowski
2026-11-09 14:33 ` Jyothi Kumar Seerapu
2026-11-11 12:37 ` Krzysztof Kozlowski
2026-11-06 15:01 ` [PATCH 3/6] dt-bindings: spi: qcom,spi-geni-qcom: Document QSPI support Jyothi Kumar Seerapu
2026-11-09 13:46 ` Krzysztof Kozlowski
2026-11-06 15:01 ` [PATCH 4/6] soc: qcom: geni-se: Define the QSPI firmware protocol Jyothi Kumar Seerapu
2026-11-09 13:44 ` Krzysztof Kozlowski
2026-11-09 14:43 ` Jyothi Kumar Seerapu
2026-11-11 12:40 ` Krzysztof Kozlowski
2026-11-09 14:47 ` Konrad Dybcio
2026-11-09 16:45 ` Jyothi Kumar Seerapu
2026-11-06 15:01 ` [PATCH 5/6] dmaengine: qcom: gpi: Add QSPI protocol support Jyothi Kumar Seerapu
2026-11-06 15:12 ` sashiko-bot
2026-11-06 15:01 ` [PATCH 6/6] spi: spi-geni-qcom: Add QSPI support over GPI DMA Jyothi Kumar Seerapu
2026-11-06 15:32 ` sashiko-bot
2026-11-08 15:18 ` [PATCH 0/6] spi: qcom-geni: " Mark Brown
2026-11-09 7:10 ` Jyothi Kumar Seerapu
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=sashiko-outbox-201663@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Frank.Li@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmaengine@vger.kernel.org \
--cc=jyothi.seerapu@oss.qualcomm.com \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vkoul@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox