* [PATCH AUTOSEL 6.19-6.1] spi-geni-qcom: initialize mode related registers to 0
[not found] <20260214010245.3671907-1-sashal@kernel.org>
@ 2026-02-14 0:58 ` Sasha Levin
2026-02-14 0:58 ` [PATCH AUTOSEL 6.19-6.6] spi-geni-qcom: use xfer->bits_per_word for can_dma() Sasha Levin
2026-02-14 0:59 ` [PATCH AUTOSEL 6.19-6.12] spi: geni-qcom: Fix abort sequence execution for serial engine errors Sasha Levin
2 siblings, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2026-02-14 0:58 UTC (permalink / raw)
To: patches, stable
Cc: Jonathan Marek, Mark Brown, Sasha Levin, linux-arm-msm, linux-spi
From: Jonathan Marek <jonathan@marek.ca>
[ Upstream commit 739062a9f1e9a77a9687c8fd30f8e5dd12ec70be ]
setup_fifo_params assumes these will be zero, it won't write these
registers if the initial mode is zero.
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Link: https://patch.msgid.link/20251120211204.24078-4-jonathan@marek.ca
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I have a complete understanding of the bug and the fix. Let me
compile the analysis.
---
## Detailed Analysis
### 1. COMMIT MESSAGE ANALYSIS
The commit subject "spi-geni-qcom: initialize mode related registers to
0" is straightforward. The commit body explains: "`setup_fifo_params`
assumes these will be zero, it won't write these registers if the
initial mode is zero." This is a clear description of a latent
initialization bug.
### 2. CODE CHANGE ANALYSIS - The Bug Mechanism
The bug centers on the interaction between two functions in `spi-geni-
qcom.c`:
**`spi_geni_init()`** (called once during probe at line 1147)
initializes the GENI SPI controller. In the `case 0:` (FIFO mode) branch
at lines 724-728, it sets the transfer mode but does NOT initialize the
SPI mode registers.
**`setup_fifo_params()`** (called for each SPI message at line 593 via
`spi_geni_prepare_message`) has an optimization at line 405:
```397:431:drivers/spi/spi-geni-qcom.c
static int setup_fifo_params(struct spi_device *spi_slv,
struct spi_controller *spi)
{
struct spi_geni_master *mas = spi_controller_get_devdata(spi);
struct geni_se *se = &mas->se;
u32 loopback_cfg = 0, cpol = 0, cpha = 0, demux_output_inv = 0;
u32 demux_sel;
if (mas->last_mode != spi_slv->mode) {
// ... only writes registers when mode changes ...
writel(loopback_cfg, se->base + SE_SPI_LOOPBACK);
writel(demux_sel, se->base + SE_SPI_DEMUX_SEL);
writel(cpha, se->base + SE_SPI_CPHA);
writel(cpol, se->base + SE_SPI_CPOL);
writel(demux_output_inv, se->base +
SE_SPI_DEMUX_OUTPUT_INV);
mas->last_mode = spi_slv->mode;
}
// ...
}
```
**The critical chain of assumptions:**
1. `spi_geni_master` is allocated with `kzalloc` (confirmed in
`__spi_alloc_controller` at spi.c line 3056), so `mas->last_mode`
starts at **0**.
2. `SPI_MODE_0` = `(0|0)` = **0** (from `include/uapi/linux/spi/spi.h`
line 10). This is the most common SPI mode.
3. When the first SPI device uses mode 0, `spi_slv->mode` is 0, so
`mas->last_mode != spi_slv->mode` is **false** (0 != 0 → false).
4. **The register writes are skipped entirely** for the first SPI
transaction.
5. This assumes the hardware registers already contain 0.
**When the assumption breaks:**
- **Bootloader contamination**: If the bootloader used SPI (very common
on Qualcomm SoCs for reading from SPI flash/NOR), it may have
configured these registers with non-zero values (e.g., CPOL=1, CPHA=1
for SPI mode 3, or specific chip select muxing).
- **Firmware loading path**: The `geni_load_se_firmware()` path (line
674-679) loads QUP firmware when `proto == GENI_SE_INVALID_PROTO`.
After firmware loading, register state may be undefined.
**The consequence:**
If hardware registers retain stale non-zero values from the bootloader
and the first SPI device uses mode 0:
- **SE_SPI_CPOL** could be set to `BIT(2)` → wrong clock polarity
- **SE_SPI_CPHA** could be set to `BIT(0)` → wrong clock phase
- **SE_SPI_LOOPBACK** could be enabled → data loops back instead of
going to device
- **SE_SPI_DEMUX_SEL** could select wrong chip → wrong device addressed
- **SE_SPI_DEMUX_OUTPUT_INV** could invert CS → chip select logic
inverted
Any of these would cause **SPI communication failure or data
corruption**.
### 3. THE FIX
The fix is 5 `writel(0, ...)` calls added to the FIFO mode
initialization path in `spi_geni_init()`:
```c
writel(0, se->base + SE_SPI_LOOPBACK);
writel(0, se->base + SE_SPI_DEMUX_SEL);
writel(0, se->base + SE_SPI_CPHA);
writel(0, se->base + SE_SPI_CPOL);
writel(0, se->base + SE_SPI_DEMUX_OUTPUT_INV);
```
This ensures the hardware state matches the software assumption
(`last_mode = 0`), making `setup_fifo_params()`'s optimization correct.
### 4. CLASSIFICATION
- **Type**: Initialization bug fix (uninitialized hardware register
state)
- **NOT a feature**: No new functionality, just ensuring correct
initialization
- **Category**: Data corruption / device communication failure fix
### 5. SCOPE AND RISK ASSESSMENT
- **Lines changed**: 6 (5 writel + 1 comment)
- **Files touched**: 1 (`drivers/spi/spi-geni-qcom.c`)
- **Complexity**: Extremely low - simple register zeroing
- **Risk of regression**: Near zero. In the common case where registers
are already 0, the writel calls are a harmless no-op. In the bug case,
they fix incorrect register values.
- **Self-contained**: Yes - all register defines (`SE_SPI_LOOPBACK`,
etc.) and the `spi_geni_init()` function exist in all stable trees
that have this driver.
### 6. USER IMPACT
- **Qualcomm GENI SPI** is used on many Qualcomm SoCs (SDM845, SM8150,
SM8250, SC7180, SC7280, SM8350, SM8450, X1E80100, etc.)
- These SoCs power phones, laptops (Qualcomm-based Chromebooks, Windows
on ARM devices), IoT, and embedded systems
- SPI is used for touchscreen controllers, sensor hubs, TPM modules, and
other critical peripherals
- If SPI communication fails, the affected device simply doesn't work
### 7. DEPENDENCY CHECK
The patch is **entirely self-contained**. It uses:
- `se->base` - available since the driver was created
- `SE_SPI_LOOPBACK`, `SE_SPI_DEMUX_SEL`, `SE_SPI_CPHA`, `SE_SPI_CPOL`,
`SE_SPI_DEMUX_OUTPUT_INV` - all defined in the same file since
original driver creation
- `writel()` - standard kernel API
The patch was "4/N" in a series (from the Link URL), but this specific
change is independent. It does not depend on any prior patch in the
series - it simply adds register zeroing to an existing function.
### 8. STABILITY INDICATORS
- Merged by Mark Brown (SPI subsystem maintainer) with `Signed-off-by`
- The fix is logically obvious and defensive
- The pattern (writing 0 to ensure known state during init) is standard
practice throughout the kernel
### CONCLUSION
This commit fixes a real initialization bug where SPI mode-related
hardware registers may retain stale non-zero values from
bootloader/firmware, causing the driver's `setup_fifo_params()`
optimization to incorrectly skip the first register write when the SPI
device uses mode 0 (the most common mode). The consequence is SPI
communication failure or data corruption. The fix is a trivial 5-line
addition of register zeroing during init, with essentially zero
regression risk, affecting a widely-deployed Qualcomm SPI driver. It is
self-contained with no dependencies and applies cleanly to stable trees.
**YES**
drivers/spi/spi-geni-qcom.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index a0d8d3425c6c6..9e9953469b3a0 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -724,6 +724,12 @@ static int spi_geni_init(struct spi_geni_master *mas)
case 0:
mas->cur_xfer_mode = GENI_SE_FIFO;
geni_se_select_mode(se, GENI_SE_FIFO);
+ /* setup_fifo_params assumes that these registers start with a zero value */
+ writel(0, se->base + SE_SPI_LOOPBACK);
+ writel(0, se->base + SE_SPI_DEMUX_SEL);
+ writel(0, se->base + SE_SPI_CPHA);
+ writel(0, se->base + SE_SPI_CPOL);
+ writel(0, se->base + SE_SPI_DEMUX_OUTPUT_INV);
ret = 0;
break;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH AUTOSEL 6.19-6.6] spi-geni-qcom: use xfer->bits_per_word for can_dma()
[not found] <20260214010245.3671907-1-sashal@kernel.org>
2026-02-14 0:58 ` [PATCH AUTOSEL 6.19-6.1] spi-geni-qcom: initialize mode related registers to 0 Sasha Levin
@ 2026-02-14 0:58 ` Sasha Levin
2026-02-14 0:59 ` [PATCH AUTOSEL 6.19-6.12] spi: geni-qcom: Fix abort sequence execution for serial engine errors Sasha Levin
2 siblings, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2026-02-14 0:58 UTC (permalink / raw)
To: patches, stable
Cc: Jonathan Marek, Mark Brown, Sasha Levin, linux-arm-msm, linux-spi
From: Jonathan Marek <jonathan@marek.ca>
[ Upstream commit fb2bbe3838728f572485706677590e4fc41eec5c ]
mas->cur_bits_per_word may not reflect the value of xfer->bits_per_word
when can_dma() is called. Use the right value instead.
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Link: https://patch.msgid.link/20251120211204.24078-3-jonathan@marek.ca
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Here is my complete analysis:
---
## Commit Analysis: spi-geni-qcom: use xfer->bits_per_word for can_dma()
### 1. Problem Description
The `geni_can_dma()` function and its helper `get_xfer_len_in_words()`
use `mas->cur_bits_per_word` (a cached state variable on the driver
struct) to compute the transfer length in SPI words and the effective
FIFO size. However, **`mas->cur_bits_per_word` may not reflect the
actual `bits_per_word` of the current transfer** when `can_dma()` is
called by the SPI core.
### 2. Root Cause - Call Order Mismatch
The SPI core's `__spi_pump_transfer_message()` calls operations in this
order:
```1726:1825:drivers/spi/spi.c
// Step 1: prepare_message
if (ctlr->prepare_message) {
ret = ctlr->prepare_message(ctlr, msg);
// ...
}
// Step 2: spi_map_msg → calls can_dma() for EACH transfer
ret = spi_map_msg(ctlr, msg);
// Step 3: transfer_one_message → calls transfer_one per-xfer
ret = ctlr->transfer_one_message(ctlr, msg);
```
Looking at Step 1, `spi_geni_prepare_message` calls `setup_fifo_params`,
which sets:
```419:419:drivers/spi/spi-geni-qcom.c
mas->cur_bits_per_word = spi_slv->bits_per_word;
```
But **only if mode changed** (`mas->last_mode != spi_slv->mode` at line
405). If the mode hasn't changed between messages,
`mas->cur_bits_per_word` retains whatever value was set during the
**last transfer** of the **previous message**.
In Step 2, `spi_map_msg` → `__spi_map_msg` iterates over **all
transfers** in the message and calls `can_dma()` for each:
```1246:1251:drivers/spi/spi.c
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
unsigned long attrs = DMA_ATTR_SKIP_CPU_SYNC;
if (!ctlr->can_dma(ctlr, msg->spi, xfer))
continue;
```
At this point, `mas->cur_bits_per_word` could be **wrong** for any
transfer whose `bits_per_word` differs from the stale cached value.
Step 3 is where `setup_se_xfer()` (line 863-865) finally updates
`mas->cur_bits_per_word = xfer->bits_per_word` — but this is **too
late** for the `can_dma()` decision, which already happened in Step 2.
### 3. Bug Impact
The buggy `geni_can_dma()` function uses the wrong `bits_per_word` in
two calculations:
**a) Transfer length in words (`get_xfer_len_in_words`):**
```551:554:drivers/spi/spi-geni-qcom.c
if (!(mas->cur_bits_per_word % MIN_WORD_LEN))
len = xfer->len * BITS_PER_BYTE / mas->cur_bits_per_word;
else
len = xfer->len / (mas->cur_bits_per_word / BITS_PER_BYTE + 1);
```
**b) FIFO size calculation:**
```574:574:drivers/spi/spi-geni-qcom.c
fifo_size = mas->tx_fifo_depth * mas->fifo_width_bits /
mas->cur_bits_per_word;
```
If `mas->cur_bits_per_word` is wrong, both `len` and `fifo_size` are
incorrect. This causes the wrong DMA vs FIFO mode selection:
- If the stale value is **smaller** than actual, `fifo_size` is inflated
and `len` deflated → **FIFO chosen when DMA should be used** →
potential FIFO overflow for large transfers
- If the stale value is **larger** than actual, the opposite happens →
**unnecessary DMA for small transfers**
### 4. Fix Analysis
The fix is trivially correct: replace `mas->cur_bits_per_word` with
`xfer->bits_per_word` in both `get_xfer_len_in_words()` and
`geni_can_dma()`. The `xfer` parameter is already available, and the SPI
core guarantees `xfer->bits_per_word` is always populated via
`__spi_validate()`:
```4079:4080:drivers/spi/spi.c
if (!xfer->bits_per_word)
xfer->bits_per_word = spi->bits_per_word;
```
This validation runs in the `spi_async()` path, well before `can_dma()`
is called.
The fix is also correct for the other caller of
`get_xfer_len_in_words()` — `setup_se_xfer()` at line 876. In that
context, `mas->cur_bits_per_word` was already set to
`xfer->bits_per_word` (line 865), so using `xfer->bits_per_word`
directly is equivalent and always correct.
### 5. Scope and Risk
- **Size**: Only 4 lines changed across 2 functions in a single file
- **Risk**: Very low — the change replaces a potentially-stale cached
value with the authoritative source of truth that was always available
- **No behavioral change** for the common case where all transfers use
the same `bits_per_word`
- **Fixes the bug** for devices using per-transfer `bits_per_word`
overrides
### 6. Series Dependency
The message-id (`24078-3-jonathan@marek.ca`) indicates this is patch 3
of a series. However, this change is entirely **self-contained** — it
only swaps `mas->cur_bits_per_word` for `xfer->bits_per_word` in
functions that already receive the `xfer` parameter. No dependency on
other patches.
### 7. Affected Stable Versions
- `geni_can_dma` was introduced in commit b59c122484ecb ("spi: spi-geni-
qcom: Add support for GPI dma") — around v5.16
- `get_xfer_len_in_words` was introduced in commit 3a76c7ca9e772 ("spi:
spi-geni-qcom: Do not do DMA map/unmap inside driver, use framework
instead") — v6.5-rc1
- The bug in `geni_can_dma` (using `mas->cur_bits_per_word` for
fifo_size) has existed since `geni_can_dma` was added, but
`get_xfer_len_in_words` was refactored in v6.5
### 8. Conclusion
This is a clear bug fix. The commit:
- Fixes a real bug: wrong value used for DMA/FIFO mode selection,
potentially causing incorrect SPI transfers
- Is small and surgical: 4 line changes, self-contained
- Has very low regression risk: uses the correct data source that was
always available
- Applies to stable trees v6.5+ (where `get_xfer_len_in_words` exists),
with a simpler variant applicable to v5.16+
- Does not introduce new features or APIs
**YES**
drivers/spi/spi-geni-qcom.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 9e9953469b3a0..5ab20d7955121 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -548,10 +548,10 @@ static u32 get_xfer_len_in_words(struct spi_transfer *xfer,
{
u32 len;
- if (!(mas->cur_bits_per_word % MIN_WORD_LEN))
- len = xfer->len * BITS_PER_BYTE / mas->cur_bits_per_word;
+ if (!(xfer->bits_per_word % MIN_WORD_LEN))
+ len = xfer->len * BITS_PER_BYTE / xfer->bits_per_word;
else
- len = xfer->len / (mas->cur_bits_per_word / BITS_PER_BYTE + 1);
+ len = xfer->len / (xfer->bits_per_word / BITS_PER_BYTE + 1);
len &= TRANS_LEN_MSK;
return len;
@@ -571,7 +571,7 @@ static bool geni_can_dma(struct spi_controller *ctlr,
return true;
len = get_xfer_len_in_words(xfer, mas);
- fifo_size = mas->tx_fifo_depth * mas->fifo_width_bits / mas->cur_bits_per_word;
+ fifo_size = mas->tx_fifo_depth * mas->fifo_width_bits / xfer->bits_per_word;
if (len > fifo_size)
return true;
--
2.51.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH AUTOSEL 6.19-6.12] spi: geni-qcom: Fix abort sequence execution for serial engine errors
[not found] <20260214010245.3671907-1-sashal@kernel.org>
2026-02-14 0:58 ` [PATCH AUTOSEL 6.19-6.1] spi-geni-qcom: initialize mode related registers to 0 Sasha Levin
2026-02-14 0:58 ` [PATCH AUTOSEL 6.19-6.6] spi-geni-qcom: use xfer->bits_per_word for can_dma() Sasha Levin
@ 2026-02-14 0:59 ` Sasha Levin
2 siblings, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2026-02-14 0:59 UTC (permalink / raw)
To: patches, stable
Cc: Praveen Talari, Konrad Dybcio, Mark Brown, Sasha Levin,
linux-arm-msm, linux-spi
From: Praveen Talari <praveen.talari@oss.qualcomm.com>
[ Upstream commit 96e041647bb0f9d92f95df1d69cb7442d7408b79 ]
The driver currently skips the abort sequence for target mode when serial
engine errors occur. This leads to improper error recovery as the serial
engine may remain in an undefined state without proper cleanup, potentially
causing subsequent operations to fail or behave unpredictably.
Fix this by ensuring the abort sequence and DMA reset always execute during
error recovery, as both are required for proper serial engine error
handling.
Co-developed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://patch.msgid.link/20260204162854.1206323-3-praveen.talari@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Now I can see the **current code** (before the patch). The issue is
clear:
**Before the fix (buggy code):**
- When `spi->target` is true, the code does `goto reset_if_dma`, which
**skips both**:
1. The cancel command (correct - target mode doesn't support cancel)
2. The abort command (INCORRECT - abort is still needed for proper
error recovery)
**After the fix:**
- When `spi->target` is true, only the cancel command is skipped
- The abort command (`geni_se_abort_m_cmd()`) and subsequent DMA reset
**always execute** regardless of target/controller mode
The logic restructuring:
- The old code: `if (spi->target) { goto reset_if_dma; }` - skips
everything (cancel AND abort)
- The new code: `if (!spi->target) { do cancel; if cancel succeeded,
goto reset_if_dma; }` then **always** falls through to the abort
sequence
This is a critical error recovery path fix. Without the abort, the
serial engine can remain stuck in an error state.
### 3. CLASSIFICATION
This is clearly a **bug fix** for improper error recovery in the SPI
GENI Qualcomm driver:
- Fixes a functional bug where the abort sequence is incorrectly skipped
- The serial engine can get stuck in an undefined state
- Subsequent SPI transactions can fail
### 4. SCOPE AND RISK ASSESSMENT
- **Lines changed:** Small - approximately 10-15 lines of logic
restructuring within a single function
- **Files touched:** 1 file (`drivers/spi/spi-geni-qcom.c`)
- **Subsystem:** SPI driver, specifically Qualcomm GENI SPI
- **Risk:** LOW - The change is well-contained within
`handle_se_timeout()`, only affects error recovery logic, and the
abort command is the standard recovery mechanism for the serial
engine. The cancel path for controller mode is preserved unchanged.
- **The change is purely a control flow fix** - no new functions, no new
variables, no new APIs
### 5. USER IMPACT
- **Who is affected:** Users of Qualcomm platforms (Snapdragon-based
devices, many ARM boards/phones) using SPI in target mode
- **Severity:** When the bug triggers, the SPI bus can become stuck,
requiring a reboot or causing cascading failures for SPI peripherals
- **Real-world impact:** This affects error recovery - when things go
wrong (timeouts, SE errors), the system can't recover properly. This
is a significant reliability issue.
### 6. STABILITY INDICATORS
- **Reviewed-by:** Konrad Dybcio (Qualcomm maintainer)
- **Signed-off-by:** Mark Brown (SPI subsystem maintainer)
- The commit is clearly described and the logic is straightforward
### 7. DEPENDENCY CHECK
The fix is self-contained - it restructures control flow within a single
function using existing APIs (`geni_se_abort_m_cmd`,
`geni_se_cancel_m_cmd`). No dependencies on other commits. The affected
code has been in the kernel for a while (the `spi->target` check and the
abort/cancel framework).
### Summary
This is a clear, small, well-reviewed bug fix that corrects an error
recovery path in the Qualcomm GENI SPI driver. Without this fix, when
serial engine errors occur in target mode, the abort sequence is
skipped, leaving the hardware in an undefined state. The fix is surgical
(single function, single file), low risk, and addresses a real
reliability problem on Qualcomm platforms. It meets all stable kernel
criteria.
**YES**
drivers/spi/spi-geni-qcom.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 5ab20d7955121..acfcf870efd84 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -160,24 +160,20 @@ static void handle_se_timeout(struct spi_controller *spi,
xfer = mas->cur_xfer;
mas->cur_xfer = NULL;
- if (spi->target) {
- /*
- * skip CMD Cancel sequnece since spi target
- * doesn`t support CMD Cancel sequnece
- */
+ /* The controller doesn't support the Cancel commnand in target mode */
+ if (!spi->target) {
+ reinit_completion(&mas->cancel_done);
+ geni_se_cancel_m_cmd(se);
+
spin_unlock_irq(&mas->lock);
- goto reset_if_dma;
- }
- reinit_completion(&mas->cancel_done);
- geni_se_cancel_m_cmd(se);
- spin_unlock_irq(&mas->lock);
+ time_left = wait_for_completion_timeout(&mas->cancel_done, HZ);
+ if (time_left)
+ goto reset_if_dma;
- time_left = wait_for_completion_timeout(&mas->cancel_done, HZ);
- if (time_left)
- goto reset_if_dma;
+ spin_lock_irq(&mas->lock);
+ }
- spin_lock_irq(&mas->lock);
reinit_completion(&mas->abort_done);
geni_se_abort_m_cmd(se);
spin_unlock_irq(&mas->lock);
--
2.51.0
^ permalink raw reply related [flat|nested] 3+ messages in thread