All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Navid Ghahremani" <ghahramani.navid@gmail.com>
Cc: devicetree@vger.kernel.org, robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH 20/24] spi: Add ZTE ZX279128S SPI flash controller
Date: Sat, 10 Oct 2026 13:11:48 +0000	[thread overview]
Message-ID: <sashiko-outbox-166571@kernel.org> (raw)
In-Reply-To: <20261010130024.177503-21-ghahramani.navid@gmail.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] spi: zx279128s: Endianness corruption in FIFO byte stream access
- [Medium] spi: zx279128s: hardware register overwrite while controller is busy
--

commit 4810c7a0849d088839c80d7f592b0dcb4167dff5
Author: Navid Ghahremani <ghahramani.navid@gmail.com>

spi: Add ZTE ZX279128S SPI flash controller

This commit adds support for the SPI flash controller of the ZTE
zx279128s SoC, implementing the spi-mem interface for bounded SPI-memory
operations.

> diff --git a/drivers/spi/spi-zx279128s-spifc.c b/drivers/spi/spi-zx279128s-spifc.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/spi/spi-zx279128s-spifc.c

[ ... ]

> +static int zx_spifc_read_fifo(struct zx_spifc *spifc, u8 *buf,
> +			      unsigned int len)
> +{
> +	unsigned int i;
> +	u32 word;
> +	int ret;
> +
> +	for (i = 0; i < len; i += 4) {
> +		ret = zx_spifc_wait_fifo(spifc, SPIFC_FIFO_RX_AVAIL);
> +		if (ret)
> +			return ret;
> +		word = readl(spifc->base + SPIFC_FIFO_DATA);
> +		memcpy(buf + i, &word, min(4U, len - i));

[Severity: High]
Does this code cause byte-order corruption on big-endian architectures?

The readl() accessor implicitly performs CPU-to-little-endian byteswapping.
When used with memcpy() to handle a byte stream, this byteswapping reverses
the byte order within each 32-bit word on big-endian systems.

Could stream accessors like readsl() or ioread32_rep() be used here
instead to preserve memory byte order without endianness conversions?

> +	}
> +
> +	return 0;
> +}

[ ... ]

> +static int zx_spifc_write_fifo(struct zx_spifc *spifc, const u8 *buf,
> +			       unsigned int len)
> +{
> +	unsigned int i = 0;
> +	bool started = false;
> +	u32 word;
> +	int ret;
> +
> +	while (i < len) {
> +		if (!(readl(spifc->base + SPIFC_FIFO_STATUS) &
> +		      SPIFC_FIFO_TX_FREE)) {
> +			if (!started) {
> +				zx_spifc_start(spifc);
> +				started = true;
> +			}
> +			ret = zx_spifc_wait_fifo(spifc, SPIFC_FIFO_TX_FREE);
> +			if (ret)
> +				return ret;
> +		}
> +		word = 0;
> +		memcpy(&word, buf + i, min(4U, len - i));
> +		writel(word, spifc->base + SPIFC_FIFO_DATA);

[Severity: High]
Similarly, does this writel() call reverse the byte order of the outgoing
stream on big-endian systems?

Could writesl() or iowrite32_rep() be used to avoid unintended
byteswapping during flash writes?

> +		i += 4;
> +	}
> +
> +	if (!started)
> +		zx_spifc_start(spifc);
> +
> +	return 0;
> +}

[ ... ]

> +static int zx_spifc_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
> +{
> +	struct zx_spifc *spifc = spi_controller_get_devdata(mem->spi->controller);
> +	void __iomem *base = spifc->base;
> +	u32 fmt0 = 0, fmt1 = 0, val;
> +	int ret;
> +
> +	ret = zx_spifc_set_speed(spifc, op->max_freq ?: mem->spi->max_speed_hz);
> +	if (ret)
> +		return ret;
> +
> +	if (op->addr.nbytes) {
> +		fmt0 |= SPIFC_FMT0_ADDR;
> +		fmt1 |= FIELD_PREP(SPIFC_FMT1_ADDR_BYTES, op->addr.nbytes - 1);
> +	}
> +	if (op->dummy.nbytes) {
> +		fmt0 |= SPIFC_FMT0_DUMMY;
> +		fmt1 |= FIELD_PREP(SPIFC_FMT1_DUMMY_BYTES, op->dummy.nbytes);
> +	}
> +	if (op->data.nbytes) {
> +		fmt0 |= op->data.dir == SPI_MEM_DATA_IN ? SPIFC_FMT0_DATA_IN :
> +							  SPIFC_FMT0_DATA_OUT;
> +		fmt1 |= FIELD_PREP(SPIFC_FMT1_DATA_LINES,
> +				   zx_spifc_lines(op->data.buswidth));
> +	}
> +
> +	zx_spifc_ack(spifc);
> +	writel(op->cmd.opcode, base + SPIFC_OPCODE);
> +	writel(fmt0, base + SPIFC_FMT0);

[Severity: Medium]
Does this code overwrite active controller registers while the hardware is
still busy?

If a previous SPI operation times out, the hardware's busy flag might
still be active. When zx_spifc_ack() is called, it observes the busy state
and skips the acknowledge:

    static void zx_spifc_ack(struct zx_spifc *spifc)
    {
        u32 val = readl(spifc->base + SPIFC_ACK);
        if (!(val & SPIFC_ACK_BUSY))
            writel(val | SPIFC_ACK_DONE, spifc->base + SPIFC_ACK);
    }

However, execution immediately continues and unconditionally writes new
configuration to SPIFC_OPCODE and SPIFC_FMT0. Modifying active controller
registers while the hardware state machine is processing a previous
transaction could lead to undefined behavior or bus lockups.

Should the driver ensure the hardware is idle or properly reset before
starting a new operation here?

> +	writel(fmt1, base + SPIFC_FMT1);
> +	writel(op->data.nbytes ? op->data.nbytes - 1 : 0, base + SPIFC_LEN);
> +	writel(op->addr.nbytes ? op->addr.val : 0, base + SPIFC_ADDR);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261010130024.177503-1-ghahramani.navid@gmail.com?part=20

  reply	other threads:[~2026-10-10 13:11 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-10 12:59 [PATCH RFC 00/24] ARM: zte: Add support for Sanechips ZX279128S and ZTE ZXHN H3600 Navid Ghahremani
2026-10-10 12:59 ` [PATCH 01/24] dt-bindings: cache: l2c2x0: Describe ZTE device-read serialization Navid Ghahremani
2026-10-12  9:43   ` Krzysztof Kozlowski
2026-10-10 12:59 ` [PATCH 02/24] ARM: l2c: Serialize device reads with cache maintenance when requested Navid Ghahremani
2026-10-10 13:10   ` sashiko-bot
2026-10-10 14:28   ` Arnd Bergmann
2026-10-10 21:41     ` Navid Ghahremani
2026-10-11  1:02     ` Navid Ghahremani
2026-10-11 14:48       ` Arnd Bergmann
2026-10-10 12:59 ` [PATCH 03/24] wifi: mt76: Serialize MMIO reads with outer cache maintenance Navid Ghahremani
2026-10-10 12:59 ` [PATCH 04/24] dt-bindings: arm: Add ZTE ZX279128S platform descriptions Navid Ghahremani
2026-10-10 12:59 ` [PATCH 05/24] ARM: zte: Add ZX279128S platform and CPU hotplug support Navid Ghahremani
2026-10-10 14:13   ` Arnd Bergmann
2026-10-10 17:34     ` Stefan Dösinger
2026-10-10 21:26       ` Navid Ghahremani
2026-10-10 12:59 ` [PATCH 06/24] dt-bindings: clock: Add ZTE ZX279128S CRM clocks and resets Navid Ghahremani
2026-10-10 13:08   ` sashiko-bot
2026-10-11  9:13   ` Stefan Dösinger
2026-10-10 12:59 ` [PATCH 07/24] clk: zte: Add ZX279128S CRM clock and reset driver Navid Ghahremani
2026-10-10 13:15   ` sashiko-bot
2026-10-11 11:10   ` Stefan Dösinger
2026-10-10 12:59 ` [PATCH 08/24] dt-bindings: gpio: Add ZTE ZX279128S GPIO controller Navid Ghahremani
2026-10-10 12:59 ` [PATCH 09/24] gpio: Add ZTE ZX279128S GPIO driver Navid Ghahremani
2026-10-10 13:14   ` sashiko-bot
2026-10-11 11:19   ` Stefan Dösinger
2026-10-12 10:59   ` Uwe Kleine-König
2026-10-10 12:59 ` [PATCH 10/24] dt-bindings: pinctrl: pinctrl-single: Add ZTE ZX279128S pin mux Navid Ghahremani
2026-10-10 12:59 ` [PATCH 11/24] dt-bindings: mfd: syscon: Add ZX279128S system controller Navid Ghahremani
2026-10-10 13:08   ` sashiko-bot
2026-10-10 12:59 ` [PATCH 12/24] dt-bindings: PCI: Add ZTE ZX279128S host controller Navid Ghahremani
2026-10-10 13:12   ` sashiko-bot
2026-10-10 12:59 ` [PATCH 13/24] PCI: dwc: Add ZTE ZX279128S host controller driver Navid Ghahremani
2026-10-10 13:14   ` sashiko-bot
2026-10-11 13:03   ` Stefan Dösinger
2026-10-10 12:59 ` [PATCH 14/24] dt-bindings: net: Add ZTE ZX279128S MDIO controller Navid Ghahremani
2026-10-10 13:06   ` sashiko-bot
2026-10-10 12:59 ` [PATCH 15/24] net: mdio: " Navid Ghahremani
2026-10-10 13:11   ` sashiko-bot
2026-10-10 12:59 ` [PATCH 16/24] net: phy: Add Sanechips ZX5201 PHY support Navid Ghahremani
2026-10-10 12:59 ` [PATCH 17/24] dt-bindings: net: Add ZTE ZX279128S Ethernet switch Navid Ghahremani
2026-10-10 13:08   ` sashiko-bot
2026-10-10 12:59 ` [PATCH 18/24] net: ethernet: zte: Add ZX279128S Ethernet switch driver Navid Ghahremani
2026-10-10 13:19   ` sashiko-bot
2026-10-10 12:59 ` [PATCH 19/24] dt-bindings: spi: Add ZTE ZX279128S SPI flash controller Navid Ghahremani
2026-10-10 12:59 ` [PATCH 20/24] " Navid Ghahremani
2026-10-10 13:11   ` sashiko-bot [this message]
2026-10-11 16:32   ` Stefan Dösinger
2026-10-10 12:59 ` [PATCH 21/24] dt-bindings: usb: Add ZTE ZX279128S DWC3 controller Navid Ghahremani
2026-10-10 13:11   ` sashiko-bot
2026-10-10 13:00 ` [PATCH 22/24] usb: dwc3: generic-plat: Add ZTE ZX279128S Navid Ghahremani
2026-10-10 13:14   ` sashiko-bot
2026-10-10 13:00 ` [PATCH 23/24] ARM: dts: zte: Add ZX279128S SoC description Navid Ghahremani
2026-10-10 13:14   ` sashiko-bot
2026-10-10 13:00 ` [PATCH 24/24] ARM: dts: zte: Add ZTE ZXHN H3600 board Navid Ghahremani
2026-10-12 19:20 ` [PATCH RFC 00/24] ARM: zte: Add support for Sanechips ZX279128S and ZTE ZXHN H3600 Stefan Dösinger

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-166571@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=ghahramani.navid@gmail.com \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.