All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Yu-Chun Lin" <eleanor.lin@realtek.com>
Cc: robh@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v5 2/2] spi: spi-mem: Add Realtek SPI NOR flash controller driver
Date: Wed, 30 Sep 2026 07:11:25 +0000	[thread overview]
Message-ID: <20260930071125.529791F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260930065945.88008-3-eleanor.lin@realtek.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] spi: rtk-nor: missing error handling for pm_runtime_resume_and_get() in remove path
- [High] spi: rtk-nor: rtk_spi_supports_op() returns true for unsupported commands due to bool coercion
- [High] spi: rtk-nor: rtk_spi_do_write_and_cmds() silently truncates multi-byte writes
- [High] spi: rtk-nor: stateful 4-byte mode tracking breaks dirmap memory-mapped accesses
- [High] spi: rtk-nor: missing DUAL_MODE_EN for write operations and exec_op reads causes data corruption
--

commit 3bdf61831cde1ea53f0bf3d584243f565bbd2cc7
Author: Jyan Chou <jyanchou@realtek.com>

spi: spi-mem: Add Realtek SPI NOR flash controller driver

Add a spi-mem driver for the SPI NOR Flash Controller (SFC) found on
Realtek DHC SoC. The controller supports single and dual I/O transfers
and offloads the payload to an integrated DMA engine.

> diff --git a/drivers/spi/spi-rtk-nor.c b/drivers/spi/spi-rtk-nor.c
> --- /dev/null
> +++ b/drivers/spi/spi-rtk-nor.c
[ ... ]
> +static void rtk_spi_read_mode(struct rtk_spi_host *host, const struct spi_mem_op *op)
> +{
> +	u32 opcode = op->cmd.opcode;
> +	u32 dummy_cycles, val;
> +
> +	if (op->data.buswidth == 2)
> +		opcode |= DUAL_MODE_EN;
> +
> +	writel(opcode, host->regbase + SFC_OPCODE);
> +
> +	val = readl(host->regbase + SFC_CTL);
> +	val |= RW_DATAEN | ADDR_EN;

[Severity: High]
If a stateless 3-byte command (like Read SFDP) is issued via
rtk_spi_exec_op() while the flash is in 4-byte mode, host->is_4byte is
set to false and the hardware register is updated.

If a subsequent dirmap read bypasses rtk_spi_exec_op() and calls
rtk_spi_read_mode() here, it appears the 4-byte enable register
(SFC_ADR_FOUR_BYTE_EN) is not updated from the dirmap template.

Could this cause the controller to send a 3-byte address for a 4-byte
dirmap operation, resulting in garbage data reads?

[ ... ]
> +static void rtk_spi_write_mode(struct rtk_spi_host *host,
> +			       const struct spi_mem_op *op)
> +{
> +	u32 opcode = op->cmd.opcode;
> +	u32 val;
> +
> +	writel(opcode, host->regbase + SFC_OPCODE);

[Severity: High]
rtk_spi_supports_op() accepts buswidth == 2 for all data operations, and
rtk_spi_read_mode() above properly sets the DUAL_MODE_EN bit for dirmap
reads.

Is DUAL_MODE_EN missing here in rtk_spi_write_mode()?

If the SPI NOR core initiates a dual I/O Page Program, will the controller
execute it in standard 1-1-1 mode and potentially misconfigure the hardware?

[ ... ]
> +static int rtk_spi_command_read(struct rtk_spi_host *host, const struct spi_mem_op *op)
> +{
> +	size_t len = op->data.nbytes;
> +	loff_t offset = op->addr.val;
> +	u8 opcode = op->cmd.opcode;
> +	u32 dummy_cycles, val;
> +
> +	writel(opcode, host->regbase + SFC_OPCODE);

[Severity: High]
Similarly, does this code also miss setting DUAL_MODE_EN for exec_op reads
when dual I/O is requested?

[ ... ]
> +static int rtk_spi_do_write_and_cmds(struct rtk_spi_host *host, const struct spi_mem_op *op)
> +{
> +	u8 opcode = op->cmd.opcode;
> +	u32 ctl_val = 0;
> +
> +	writel(opcode, host->regbase + SFC_OPCODE);
> +
> +	if (op->data.nbytes > 0)
> +		ctl_val |= RW_DATAEN;
> +
> +	if (op->addr.nbytes > 0)
> +		ctl_val |= ADDR_EN;
> +
> +	writel(ctl_val, host->regbase + SFC_CTL);
> +
> +	if (op->data.nbytes > 0) {
> +		const u8 *buf = op->data.buf.out;
> +
> +		if (op->addr.val + op->data.nbytes > host->dirmap_size)
> +			return -EINVAL;
> +
> +		writeb(*buf, host->iobase + op->addr.val);
> +	} else {

[Severity: High]
When exec_op is used for multi-byte writes (where op->data.nbytes > 1),
this executes a single writeb() without a loop and returns success.

Does this silently discard the rest of the payload in op->data.buf.out?
If the SPI NOR core falls back to exec_op for multi-byte register writes,
it appears only the first byte is written.

[ ... ]
> +static bool rtk_spi_supports_op(struct spi_mem *mem,
> +				const struct spi_mem_op *op)
> +{
[ ... ]
> +	/*
> +	 * The data window is access-triggered: each CPU access to host->iobase
> +	 * generates one complete SPI transaction. Consecutive byte accesses
> +	 * therefore cannot be merged into a single transaction, so
> +	 * multi-byte stateless commands are not supported by this controller.
> +	 */
> +	if (!op->addr.nbytes && op->data.nbytes > 1)
> +		return -EOPNOTSUPP;

[Severity: High]
Since rtk_spi_supports_op() returns a bool, won't returning -EOPNOTSUPP
evaluate to true?

Does this cause the driver to erroneously advertise support for multi-byte
stateless commands instead of rejecting them?

[ ... ]
> +static void rtk_spi_remove(struct platform_device *pdev)
> +{
> +	struct spi_controller *ctrl = platform_get_drvdata(pdev);
> +	struct rtk_spi_host *host = spi_controller_get_devdata(ctrl);
> +	struct device *dev = &pdev->dev;
> +
> +	spi_unregister_controller(ctrl);
> +
> +	if (pm_runtime_resume_and_get(dev) < 0)
> +		dev_warn(dev, "Failed to resume device during remove\n");
> +
> +	pm_runtime_put_noidle(dev);
> +	pm_runtime_disable(dev);
> +	pm_runtime_set_suspended(dev);
> +	pm_runtime_dont_use_autosuspend(dev);
> +	reset_control_assert(host->rstc);
> +	clk_disable_unprepare(host->clk);
> +}

[Severity: High]
If pm_runtime_resume_and_get(dev) fails (returns < 0), it does not increment
the device's PM usage counter.

Since the execution unconditionally proceeds to call
pm_runtime_put_noidle(dev) and clk_disable_unprepare(host->clk), will
this result in a PM usage counter underflow (double put) and a clock
enable counter underflow?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260930065945.88008-1-eleanor.lin@realtek.com?part=2

  reply	other threads:[~2026-09-30  7:11 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-30  6:59 [PATCH v5 0/2] spi: realtek: Add support for RTD1625 SPI NOR Flash Controller Yu-Chun Lin
2026-09-30  6:59 ` [PATCH v5 1/2] dt-bindings: spi: Add Realtek RTD1625 SPI NOR support Yu-Chun Lin
2026-09-30  6:59 ` [PATCH v5 2/2] spi: spi-mem: Add Realtek SPI NOR flash controller driver Yu-Chun Lin
2026-10-02 11:12   ` Dan Carpenter
2026-09-30  7:11   ` sashiko-bot [this message]
2026-10-02 12:40   ` Mark Brown
2026-10-02 13:20     ` Dan Carpenter
2026-09-30 15:26 ` [PATCH v5 0/2] spi: realtek: Add support for RTD1625 SPI NOR Flash Controller Mark Brown

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=20260930071125.529791F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=eleanor.lin@realtek.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.