From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33A323D0BE1 for ; Tue, 13 Oct 2026 14:14:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791900877; cv=none; b=L3zIBSoIFzodbyTUcLL80oWQDgoccS8oaAdlQRqCX65W3v0fdNlI6JXyPXuc0pnXPf+z7lvL1IgWlXYGE/LEIxhqJbVD3H97gif2ec53y4NrfjR9OUitUbOKCoBHgU4Y7fMdliMRhzZ5TeI89YuLwmOAs4D25w5eoMbffmx9NR0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791900877; c=relaxed/simple; bh=nH6jYVOksBPD8uC4fP2Cgr0v+i667iKCmZZHX/50iwk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X/mWUTyNyz9PCZq5JtR8ib9ecKqgjPRgU4ZWTNmCdX8ZiZcUInYpqVdPcazC11kc5Z14irNo+KJHkcZ7+j5kYYQ4jydamV736xbK3XzWYlxsopg9oUD3zKQnckG11hXKfThwwFd65k1F2MK3SCBNecfdrXdMEPJTwp0H4Diw424= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=vPYtz7qV; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="vPYtz7qV" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id E43224E41209; Tue, 13 Oct 2026 14:14:34 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B8D4C60362; Tue, 13 Oct 2026 14:14:34 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id C5AA811D714ED; Tue, 13 Oct 2026 16:14:26 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1791900869; h=from:subject:date:message-id:to:cc:mime-version: content-transfer-encoding:in-reply-to:references; bh=OLsy6HHrd9OhlTf5ijFBqojW+83puKqwZQgSDTxalnY=; b=vPYtz7qVmDHNllXMQyumytOH7h1TmGBxMcPaIQ0IksGaa8t3qHFOHqCno5BCR50M/caxan lSMbKm3vXxJH+CqZDrz3g48zipOuZPGz24vFZtYK4O0saPXp6G6ZBLFW72zDvyzndcxnhT X7nKoIZRX/6IRmYBWFM7tLL4y7PaZF1oYMKAFQpSVPQ8B77XssAo3qfIr9BTYz5cZU2MVZ 2dn2jj2F8a6nUbR9iXmIqCDbW+w68Pl9O1ZVi1wElFd5GhTYKr0DCbQfcBd8C8zICVKArm 0ZC0ggq8tXrPnQrV4EU5n+Kx27M4ehRVG+ptQgdCtbh1fFTW07/W6e63nvq7SA== From: Paul Cercueil To: Pratyush Yadav , Michael Walle , Takahiro Kuwano , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Mark Brown , Thomas Petazzoni Cc: Kees Cook , Tony Luck , "Guilherme G . Piccoli" , linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, Bharat Bhushan , Sunil Kovvuri Goutham , Tanmay Jagdale , Paul Cercueil Subject: [PATCH v2 1/7] spi: spi-mem: Add support for panic mem writes Date: Tue, 13 Oct 2026 16:13:44 +0200 Message-ID: <20261013141350.189996-2-paul.cercueil@bootlin.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261013141350.189996-1-paul.cercueil@bootlin.com> References: <20261013141350.189996-1-paul.cercueil@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Last-TLS-Session-Version: TLSv1.3 From: Tanmay Jagdale Add a 'panic_write' flag to the controller's capabilities struct. When set, the SPI controller indicates that it will be able to send commands to a connected NOR or NAND memory in the context of a kernel panic, which means without sleeping and without relying on IRQs. Whether or not a given memory operation is a panic mem write is given by the spi_mem_op.panic_write flag. Signed-off-by: Tanmay Jagdale Co-developed-by: Paul Cercueil Signed-off-by: Paul Cercueil --- Notes: v2: - Don't call spi_mem_access_start/end on panic. We don't need to flush the SPI queue at that point, and we don't need to lock the mutexes. - Check that the SPI controller's PM status is active, and bail out otherwise. drivers/spi/spi-mem.c | 35 +++++++++++++++++++++++++++++++++-- include/linux/spi/spi-mem.h | 5 +++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index b94680b60af9..3b6fa44e4550 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -398,6 +398,31 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) u8 *tmpbuf; int ret; + if (op->panic_write) { + if (!spi_mem_controller_is_capable(ctlr, panic_write)) + return -EOPNOTSUPP; + + /* + * Only support panic writes if we'll go through .exec_op(). + * The regular SPI path (spi_sync(), etc.) explicitly mentions + * that it can only be used from a context that may sleep, which + * is not the case on a kernel panic. + * If this changes in the future, this could be reworked, but + * for now this will have to do. + */ + if (WARN_ON_ONCE(!ctlr->mem_ops || !ctlr->mem_ops->exec_op)) + return -EOPNOTSUPP; + + if (spi_get_csgpiod(mem->spi, 0)) + return -EPERM; + + /* On panic IRQs are disabled so we cannot wait on locks */ + if (mutex_is_locked(&ctlr->bus_lock_mutex) || + mutex_is_locked(&ctlr->io_mutex)) { + return -EPERM; + } + } + /* Make sure the operation frequency is correct before going futher */ spi_mem_adjust_op_freq(mem, (struct spi_mem_op *)op); @@ -420,7 +445,10 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) return -EOPNOTSUPP; if (ctlr->mem_ops && ctlr->mem_ops->exec_op && !spi_get_csgpiod(mem->spi, 0)) { - ret = spi_mem_access_start(mem); + if (!op->panic_write) + ret = spi_mem_access_start(mem); + else if (ctlr->auto_runtime_pm) + ret = pm_runtime_get_if_active(ctlr->dev.parent); if (ret) return ret; @@ -428,7 +456,10 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) ret = ctlr->mem_ops->exec_op(mem, op); trace_spi_mem_stop_op(mem, op); - spi_mem_access_end(mem); + if (!op->panic_write) + spi_mem_access_end(mem); + else if (ctlr->auto_runtime_pm) + pm_runtime_put_noidle(ctlr->dev.parent); /* * Some controllers only optimize specific paths (typically the diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h index 0cce6b57242a..2633307bfad5 100644 --- a/include/linux/spi/spi-mem.h +++ b/include/linux/spi/spi-mem.h @@ -169,6 +169,7 @@ enum spi_mem_data_dir { * operation does not involve transferring data * @data.buf.in: input buffer (must be DMA-able) * @data.buf.out: output buffer (must be DMA-able) + * @panic_write: The command is executed in the context of a kernel panic * @max_freq: frequency limitation wrt this operation. 0 means there is no * specific constraint and the highest achievable frequency can be * attempted. @@ -211,6 +212,7 @@ struct spi_mem_op { } buf; } data; + bool panic_write; unsigned int max_freq; }; @@ -392,6 +394,8 @@ struct spi_controller_mem_ops { * is a pause in the transfer (eg. internal bus contention or * DMA arbitration on an interconnect). Features such as NAND * continuous reads shall not be leveraged. + * @panic_write: Set to true if the controller driver supports writing to a + * connected NAND/NOR memory in a kernel panic context */ struct spi_controller_mem_caps { bool dtr; @@ -400,6 +404,7 @@ struct spi_controller_mem_caps { bool per_op_freq; bool secondary_op_tmpl; bool no_cs_assertion; + bool panic_write; }; #define spi_mem_controller_is_capable(ctlr, cap) \ -- 2.47.3