The controller per-cpu statistics is not allocated until after the
controller has been registered with driver core, which leaves a window
where accessing the sysfs attributes can trigger a NULL-pointer
dereference.
Fix this by moving the statistics allocation to controller allocation
while tying its lifetime to that of the controller (rather than using
implicit devres).
Fixes: 6598b91b5a ("spi: spi.c: Convert statistics to per-cpu u64_stats_t")
Cc: stable@vger.kernel.org # 6.0
Cc: David Jander <david@protonic.nl>
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260312151817.32100-3-johan@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
setup_fifo_params computes mode_changed from spi->mode flags but tests
it against SE_SPI_CPHA and SE_SPI_CPOL, which are register offsets,
not SPI mode bits. This causes CPHA and CPOL updates to be skipped
on mode switches, leaving the controller with stale clock phase
and polarity settings.
Fix this by using SPI_CPHA and SPI_CPOL to detect mode changes before
updating the corresponding registers.
Fixes: 781c3e71c9 ("spi: spi-geni-qcom: rework setup_fifo_params")
Signed-off-by: Maramaina Naresh <naresh.maramaina@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://patch.msgid.link/20260316-spi-geni-cpha-cpol-fix-v1-1-4cb44c176b79@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
ctlr is allocated using devm_spi_alloc_host(), which automatically
handles reference counting via the devm framework.
Calling spi_controller_put() manually in the probe error path is
redundant and results in a double-free.
Fixes: e75a6b00ad ("spi: axiado: Add driver for Axiado SPI DB controller")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Link: https://patch.msgid.link/20260302-axiado-v1-1-1132819f1cb7@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
In aml_spisg_probe(), ctlr is allocated by
spi_alloc_target()/spi_alloc_host(), but fails to call
spi_controller_put() in several error paths. This leads
to a memory leak whenever the driver fails to probe after
the initial allocation.
Convert to use devm_spi_alloc_host()/devm_spi_alloc_target()
to fix the memory leak.
Fixes: cef9991e04 ("spi: Add Amlogic SPISG driver")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Link: https://patch.msgid.link/20260308-spisg-v1-1-2cace5cafc24@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
The driver uses devm_clk_get_enabled() which enables the clock and
registers a callback to automatically disable it when the device
is unbound.
Remove the redundant aml_sfc_disable_clk() call in the error paths
and remove callback.
Fixes: 4670db6f32 ("spi: amlogic: add driver for Amlogic SPI Flash Controller")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Link: https://patch.msgid.link/20260308-spifc-a4-1-v1-1-77e286c26832@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
The kernel test robot reported a compile-time error regarding the
FIELD_PREP() value being too large for the TRANS_DUAL_QUAD field:
error: FIELD_PREP: value too large for the field
note: in expansion of macro 'TRANS_DUAL_QUAD'
tc |= TRANS_DUAL_QUAD(ffs(op->data.buswidth) - 1);
This occurs because TRANS_DUAL_QUAD is defined as a 2-bit field, and
GCC's static analysis cannot deduce that `ffs(op->data.buswidth) - 1`
will strictly fall within the 0~3 range. Although the SPI framework
guarantees that `op->data.buswidth` is valid at runtime (e.g., 1, 2,
4, 8), an explicit bounds check is necessary to satisfy the compiler.
To resolve the build warning, introduce a safe fallback mechanism.
If an unexpected buswidth is encountered, the driver will trigger
a WARN_ON_ONCE to leave a trace and fall back to width_code = 0
(standard 1-bit SPI mode). This approach guarantees predictable
hardware behavior.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202602140738.P7ZozxzI-lkp@intel.com/
Suggested-by: Pei Xiao <xiaopei01@kylinos.cn>
Signed-off-by: CL Wang <cl634@andestech.com>
Link: https://patch.msgid.link/20260303024737.1791196-1-cl634@andestech.com
Signed-off-by: Mark Brown <broonie@kernel.org>
The driver uses devm_spi_register_controller() for registration, which
automatically unregisters the controller via devm cleanup when the
device is removed. The manual call to spi_unregister_controller() in
the remove() callback can lead to a double-free.
And to make sure controller is unregistered before DMA buffer is
unmapped, switch to use spi_register_controller() in probe().
Fixes: 8011709906 ("spi: rockchip-sfc: Support pm ops")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Link: https://patch.msgid.link/20260310-sfc-v2-1-67fab04b097f@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
The driver uses devm_dma_request_chan() which registers automatic cleanup
via devm_add_action_or_reset(). Calling dma_release_channel() manually on
the RX channel when TX channel request fails causes a double-free when
the devm cleanup runs.
Remove the unnecessary manual cleanup and simplify the error handling
since devm will properly release channels on probe failure or driver
detach.
Fixes: 34e3815ea4 ("spi: atcspi200: Add ATCSPI200 SPI controller driver")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Link: https://patch.msgid.link/20260305-atcspi2000-v1-1-eafe08dcca60@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Fix three bugs in aml_sfc_dma_buffer_setup() error paths:
1. Unnecessary goto: When the first DMA mapping (sfc->daddr) fails,
nothing needs cleanup. Use direct return instead of goto.
2. Double-unmap bug: When info DMA mapping failed, the code would
unmap sfc->daddr inline, then fall through to out_map_data which
would unmap it again, causing a double-unmap.
3. Wrong unmap size: The out_map_info label used datalen instead of
infolen when unmapping sfc->iaddr, which could lead to incorrect
DMA sync behavior.
Fixes: 4670db6f32 ("spi: amlogic: add driver for Amlogic SPI Flash Controller")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Link: https://patch.msgid.link/20260306-spifc-a4-v1-1-f22c9965f64a@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This converts some of the visually simpler cases that have been split
over multiple lines. I only did the ones that are easy to verify the
resulting diff by having just that final GFP_KERNEL argument on the next
line.
Somebody should probably do a proper coccinelle script for this, but for
me the trivial script actually resulted in an assertion failure in the
middle of the script. I probably had made it a bit _too_ trivial.
So after fighting that far a while I decided to just do some of the
syntactically simpler cases with variations of the previous 'sed'
scripts.
The more syntactically complex multi-line cases would mostly really want
whitespace cleanup anyway.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This is the exact same thing as the 'alloc_obj()' version, only much
smaller because there are a lot fewer users of the *alloc_flex()
interface.
As with alloc_obj() version, this was done entirely with mindless brute
force, using the same script, except using 'flex' in the pattern rather
than 'objs*'.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This is the result of running the Coccinelle script from
scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to
avoid scalar types (which need careful case-by-case checking), and
instead replace kmalloc-family calls that allocate struct or union
object instances:
Single allocations: kmalloc(sizeof(TYPE), ...)
are replaced with: kmalloc_obj(TYPE, ...)
Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...)
are replaced with: kmalloc_objs(TYPE, COUNT, ...)
Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...)
are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...)
(where TYPE may also be *VAR)
The resulting allocations no longer return "void *", instead returning
"TYPE *".
Signed-off-by: Kees Cook <kees@kernel.org>
Pull spi fixes from Mark Brown:
"There's a relatively large but ultimately simple fix for spidev here
which addresses some ABBA races by simplifying down to just using a
single lock, it's not clear to me that there was ever any benefit in
having the two separate locks in the first place.
We also have simple missing error check fix in in the wpcm-fiu driver"
* tag 'spi-fix-v7.0-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
spi: spidev: fix lock inversion between spi_lock and buf_lock
spi: wpcm-fiu: Fix potential NULL pointer dereference in wpcm_fiu_probe()
Pull char/misc/IIO driver updates from Greg KH:
"Here is the big set of char/misc/iio and other smaller driver
subsystem changes for 7.0-rc1. Lots of little things in here,
including:
- Loads of iio driver changes and updates and additions
- gpib driver updates
- interconnect driver updates
- i3c driver updates
- hwtracing (coresight and intel) driver updates
- deletion of the obsolete mwave driver
- binder driver updates (rust and c versions)
- mhi driver updates (causing a merge conflict, see below)
- mei driver updates
- fsi driver updates
- eeprom driver updates
- lots of other small char and misc driver updates and cleanups
All of these have been in linux-next for a while, with no reported
issues"
* tag 'char-misc-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (297 commits)
mux: mmio: fix regmap leak on probe failure
rust_binder: return p from rust_binder_transaction_target_node()
drivers: android: binder: Update ARef imports from sync::aref
rust_binder: fix needless borrow in context.rs
iio: magn: mmc5633: Fix Kconfig for combination of I3C as module and driver builtin
iio: sca3000: Fix a resource leak in sca3000_probe()
iio: proximity: rfd77402: Add interrupt handling support
iio: proximity: rfd77402: Document device private data structure
iio: proximity: rfd77402: Use devm-managed mutex initialization
iio: proximity: rfd77402: Use kernel helper for result polling
iio: proximity: rfd77402: Align polling timeout with datasheet
iio: cros_ec: Allow enabling/disabling calibration mode
iio: frequency: ad9523: correct kernel-doc bad line warning
iio: buffer: buffer_impl.h: fix kernel-doc warnings
iio: gyro: itg3200: Fix unchecked return value in read_raw
MAINTAINERS: add entry for ADE9000 driver
iio: accel: sca3000: remove unused last_timestamp field
iio: accel: adxl372: remove unused int2_bitmask field
iio: adc: ad7766: Use iio_trigger_generic_data_rdy_poll()
iio: magnetometer: Remove IRQF_ONESHOT
...
The spidev driver previously used two mutexes, spi_lock and buf_lock,
but acquired them in different orders depending on the code path:
write()/read(): buf_lock -> spi_lock
ioctl(): spi_lock -> buf_lock
This AB-BA locking pattern triggers lockdep warnings and can
cause real deadlocks:
WARNING: possible circular locking dependency detected
spidev_ioctl() -> mutex_lock(&spidev->buf_lock)
spidev_sync_write() -> mutex_lock(&spidev->spi_lock)
*** DEADLOCK ***
The issue is reproducible with a simple userspace program that
performs write() and SPI_IOC_WR_MAX_SPEED_HZ ioctl() calls from
separate threads on the same spidev file descriptor.
Fix this by simplifying the locking model and removing the lock
inversion entirely. spidev_sync() no longer performs any locking,
and all callers serialize access using spi_lock.
buf_lock is removed since its functionality is fully covered by
spi_lock, eliminating the possibility of lock ordering issues.
This removes the lock inversion and prevents deadlocks without
changing userspace ABI or behaviour.
Signed-off-by: Fabian Godehardt <fg@emlix.com>
Link: https://patch.msgid.link/20260211072616.489522-1-fg@emlix.com
Signed-off-by: Mark Brown <broonie@kernel.org>
platform_get_resource_byname() can return NULL, which would cause a crash
when passed the pointer to resource_size().
Move the fiu->memory_size assignment after the error check for
devm_ioremap_resource() to prevent the potential NULL pointer dereference.
Fixes: 9838c18247 ("spi: wpcm-fiu: Add direct map support")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Reviewed-by: J. Neuschäfer <j.ne@posteo.net>
Link: https://patch.msgid.link/20260212-wpcm-v1-1-5b7c4f526aac@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Pull sound updates from Takashi Iwai:
"It's been relatively calm for a new era; majority of changes are for
ASoC, mostly device-specific changes, while there are a bit of
cleanups in core stuff. A few SPI API and regmap updates are included
to be used by sound drivers, too.
Core:
- A few trivial cleanups about __free() and runtime PM macros
- Convert to new snd_seq_bus binding
ASoC:
- Generic SDCA support for reporting jack events
- Continuing platform support, cleanup and feature improvements for
AMD, Intel, Qualcomm and SOF code
- Platform description improvements for the Cirrus drivers
- Support for NXP i.MX952, Realtek RT1320 and RT5575, and Sophogo
CV1800B
HD- and USB-audio:
- Many quirks as usual"
* tag 'sound-7.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (341 commits)
ALSA: usb-audio: Add DSD support for iBasso DC04U
ALSA: mixer: oss: Add card disconnect checkpoints
ASoC: SOF: ipc4-control: Set correct error code in refresh_bytes_control
ASoC: SOF: Intel: select CONFIG_SND_HDA_EXT_CORE from SND_SOC_SOF_HDA_COMMON
ALSA: usb-audio: Add iface reset and delay quirk for AB13X USB Audio
ASoC: amd: maintainer information
ALSA: ctxfi: Add quirk for SE-300PCIE variant (160b:0102)
ALSA: hda/generic: fix typos in comments
ALSA: hda/realtek - Enable mute LEDs on HP ENVY x360 15-es0xxx
ALSA: hda/conexant: Add quirk for HP ZBook Studio G4
ASoC: fsl_asrc_dma: allocate memory from dma device
ASoC: fsl_asrc: Add support for i.MX952 platform
ASoC: fsl_asrc_m2m: Add option to start ASRC before DMA device for M2M
ASoC: dt-bindings: fsl,imx-asrc: Add support for i.MX952 platform
ALSA: oss: delete self assignment
ASoC: rockchip: spdif: Convert to FIELD_PREP
ASoC: rockchip: spdif: Fill IEC958 CS info per params
ASoC: rockchip: spdif: Add support for format S32_LE
ASoC: rockchip: spdif: Add support for set mclk rate
ASoC: rockchip: spdif: Swap PCM and DAI component registration order
...
Pull spi updates from Mark Brown:
"The highlight here is that David Lechner has added support for
multi-lane SPI devices. Unlike the existing dual/quad SPI support this
is for devices (typically ADCs/DACs) which support multiple
independent data streams over multiple data lanes, instead of sending
one data stream N times as fast they simultaneously transfer N
different data streams.
This is very similar to the case where multiple devices are grouped
together but in this case it's a single device in a way that's visible
to software.
Otherwise there's been quite a bit of work on existing drivers, both
cleanup and feature improvement, and a reasonable collection of new
drivers.
- Support for multi-lane SPI devices
- Preparatory work for some memory mapped flash improvements that
will happen in the MTD subsystem
- Several conversions to fwnode APIs
- A bunch of cleanup and hardening work on the ST drivers
- Support for DMA mode on Renesas RZV2H and i.MX target mode
- Support for ATCSPI200, AXIADO AX300, NXP XPI and Renesas RZ/N1"
* tag 'spi-v6.20' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (108 commits)
spi: tools: Add include folder to .gitignore
spi: cadence-qspi: Add support for the Renesas RZ/N1 controller
spi: cadence-qspi: Kill cqspi_jh7110_clk_init
spi: dt-bindings: cdns,qspi-nor: Add Renesas RZ/N1D400 to the list
spi: geni-qcom: Add target abort support
spi: geni-qcom: Drop unused msg parameter from timeout handlers
spi: geni-qcom: Fix abort sequence execution for serial engine errors
spi: geni-qcom: Improve target mode allocation by using proper allocation functions
spi: xilinx: use device property accessors.
dt-bindings: spi: Add binding for Faraday FTSSP010
spi: axi-spi-engine: support SPI_MULTI_LANE_MODE_STRIPE
spi: dt-bindings: adi,axi-spi-engine: add multi-lane support
spi: Documentation: add page on multi-lane support
spi: add multi_lane_mode field to struct spi_transfer
spi: support controllers with multiple data lanes
spi: dt-bindings: add spi-{tx,rx}-lane-map properties
spi: dt-bindings: change spi-{rx,tx}-bus-width to arrays
spi: dw: Remove not-going-to-be-supported code for Baikal SoC
spi: cadence-qspi: Use a default value for cdns,fifo-width
spi: cadence-qspi: Make sure write protection is disabled
...
Merge series from "Miquel Raynal (Schneider Electric)" <miquel.raynal@bootlin.com>:
This series adds support for the QSPI controller available on Renesas
RZ/N1S and RZ/N1D SoC. It has been tested with a custom board (see last
SPI patch for details), but has been tested by Wolfram (thank you!) on
the DB board.
Link: https://lore.kernel.org/linux-devicetree/20260116114852.52948-2-wsa+renesas@sang-engineering.com/
Adding support for this SoC required a few adaptations to the Cadence
QSPI driver which have already been merged (except one regarding clocks
handling). This series contains the remaining patches, the ones actually
adding support for the RZ/N1 flavour.
The COMMAND1 register bits [29:28] set the SPI mode, which controls
the clock idle level. When a transfer ends, tegra_spi_transfer_end()
writes def_command1_reg back to restore the default state, but this
register value currently lacks the mode bits. This results in the
clock always being configured as idle low, breaking devices that
need it high.
Fix this by storing the mode bits in def_command1_reg during setup,
to prevent this field from always being cleared.
Fixes: f333a331ad ("spi/tegra114: add spi driver")
Signed-off-by: Vishwaroop A <va@nvidia.com>
Link: https://patch.msgid.link/20260204141212.1540382-1-va@nvidia.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Renesas RZ/N1 QSPI controllers embed a modified version of the Cadence
IP with the following settings:
- a limited bus clock range
- no DTR support
- no DMA
- no useful interrupt flag
- only direct accesses (no INDAC mode)
- write protection
The controller has been tested by running the SPI NOR check list with a
custom RZ/N1D400 based board mounted with a Spansion s25fl128s1 quad
SPI.
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Miquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com>
Link: https://patch.msgid.link/20260205-schneider-6-19-rc1-qspi-v5-3-843632b3c674@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This controller can be fed by either a main "ref" clock, or three clocks
("ref" again, "ahb", "apb"). In practice, it is likely that all
controllers have the same inputs, but a single clock feeds the three
interfaces (ref is used for controlling the external interface, ahb/apb
the internal ones). Handling these clocks is in no way SoC specific,
only the number of expected clocks may change. Plus, we will soon be
adding another controller requiring an AHB and an APB clock as well, so
it is time to align the whole clock handling.
Furthermore, the use of the cqspi_jh7110_clk_init() helper, which
specifically grabs and enables the "ahb" and "apb" clocks, is a bit
convoluted:
- only the JH7110 compatible provides the ->jh7110_clk_init() callback,
- in the probe, if the above callback is set in the driver data, the
driver does not call the callback (!) but instead calls the helper
directly (?),
- in the helper, the is_jh7110 boolean is set.
This logic does not make sense. Instead:
- in the probe, set the is_jh7110 boolean based on the compatible,
- collect all available clocks with the "bulk" helper,
- enable the extra clocks if they are available,
- kill the SoC specific cqspi_jh7110_clk_init() helper.
This also allows to group the clock handling instead of depending on the
driver data pointer, which further simplifies the error path and the
remove callback.
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Miquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com>
Link: https://patch.msgid.link/20260205-schneider-6-19-rc1-qspi-v5-2-843632b3c674@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>
The current implementation always allocates a host controller and sets the
target flag later when the "spi-slave" device tree property is present.
This approach is suboptimal as it doesn't utilize the dedicated allocation
functions designed for target mode.
Use devm_spi_alloc_target() when "spi-slave" device tree property is
present, otherwise use devm_spi_alloc_host(). This replaces the previous
approach of always allocating a host controller and setting target flag
later.
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-2-praveen.talari@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Merge series from David Lechner <dlechner@baylibre.com>:
This series is adding support for SPI controllers and peripherals that
have multiple SPI data lanes (data lanes being independent sets of
SDI/SDO lines, each with their own serializer/deserializer).
This series covers this specific use case:
+--------------+ +---------+
| SPI | | SPI |
| Controller | | ADC |
| | | |
| CS0 |--->| CS |
| SCLK |--->| SCLK |
| SDO |--->| SDI |
| SDI0 |<---| SDOA |
| SDI1 |<---| SDOB |
| SDI2 |<---| SDOC |
| SDI3 |<---| SDOD |
+--------------+ +--------+
The ADC is a simultaneous sampling ADC that can convert 4 samples at the
same time. It has 4 data output lines (SDOA-D) that each contain the
data of one of the 4 channels. So it requires a SPI controller with 4
separate deserializers in order to receive all of the information at the
same time.
This should also work for the use case in [1] as well. (Some of the
patches in this series were already submitted there). In that case the
SPI controller is used kind of like it is two separate SPI controllers,
each with its own chip select, clock, and data lines.
[1]: https://lore.kernel.org/linux-spi/20250616220054.3968946-1-sean.anderson@linux.dev/
The DT bindings are a fairly straight-forward mapping of which pins on
the peripheral are connected to which pins on the controller. The SPI
core code parses this and makes the information available to drivers.
When a peripheral driver sees that multiple data lanes are wired up, it
can chose to use them when sending messages.
The SPI message API is a bit higher-level than just specifying the
number of data lines for a SPI transfer though. I did some research on
other SPI controllers that have this feature. They tend to be the kind
meant for connecting to two flash memory chips at the same time but can
be used more generically as well. They generally have the option to
either use one lane at a time (Sean's use case), or can mirror the same
data on multiple lanes (no users of this yet) or can perform striping
of a single data FIFO/DMA stream to/from the two lanes (our use case).
For now, the API assumes that if you want to do mirror/striping, then
you want to use all available data lanes. Otherwise, it just uses the
first data lane for "normal" SPI transfers.
Add support for SPI controllers with multiple physical SPI data lanes.
(A data lane in this context means lines connected to a serializer, so a
controller with two data lanes would have two serializers in a single
controller).
This is common in the type of controller that can be used with parallel
flash memories, but can be used for general purpose SPI as well.
To indicate support, a controller just needs to set ctlr->num_data_lanes
to something greater than 1. Peripherals indicate which lane they are
connected to via device tree (ACPI support can be added if needed).
The spi-{tx,rx}-bus-width DT properties can now be arrays. The length of
the array indicates the number of data lanes, and each element indicates
the bus width of that lane. For now, we restrict all lanes to have the
same bus width to keep things simple. Support for an optional controller
lane mapping property is also implemented.
Signed-off-by: David Lechner <dlechner@baylibre.com>
Link: https://patch.msgid.link/20260123-spi-add-multi-bus-support-v6-3-12af183c06eb@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Now that all other accesses to curr_xfer are done under the lock,
protect the curr_xfer NULL check in tegra_qspi_isr_thread() with the
spinlock. Without this protection, the following race can occur:
CPU0 (ISR thread) CPU1 (timeout path)
---------------- -------------------
if (!tqspi->curr_xfer)
// sees non-NULL
spin_lock()
tqspi->curr_xfer = NULL
spin_unlock()
handle_*_xfer()
spin_lock()
t = tqspi->curr_xfer // NULL!
... t->len ... // NULL dereference!
With this patch, all curr_xfer accesses are now properly synchronized.
Although all accesses to curr_xfer are done under the lock, in
tegra_qspi_isr_thread() it checks for NULL, releases the lock and
reacquires it later in handle_cpu_based_xfer()/handle_dma_based_xfer().
There is a potential for an update in between, which could cause a NULL
pointer dereference.
To handle this, add a NULL check inside the handlers after acquiring
the lock. This ensures that if the timeout path has already cleared
curr_xfer, the handler will safely return without dereferencing the
NULL pointer.
Fixes: b4e002d8a7 ("spi: tegra210-quad: Fix timeout handling")
Signed-off-by: Breno Leitao <leitao@debian.org>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Link: https://patch.msgid.link/20260126-tegra_xfer-v2-6-6d2115e4f387@debian.org
Signed-off-by: Mark Brown <broonie@kernel.org>
The curr_xfer field is read by the IRQ handler without holding the lock
to check if a transfer is in progress. When clearing curr_xfer in the
combined sequence transfer loop, protect it with the spinlock to prevent
a race with the interrupt handler.
Protect the curr_xfer clearing at the exit path of
tegra_qspi_combined_seq_xfer() with the spinlock to prevent a race
with the interrupt handler that reads this field.
Without this protection, the IRQ handler could read a partially updated
curr_xfer value, leading to NULL pointer dereference or use-after-free.
Fixes: b4e002d8a7 ("spi: tegra210-quad: Fix timeout handling")
Signed-off-by: Breno Leitao <leitao@debian.org>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Link: https://patch.msgid.link/20260126-tegra_xfer-v2-4-6d2115e4f387@debian.org
Signed-off-by: Mark Brown <broonie@kernel.org>
When the timeout handler processes a completed transfer and signals
completion, the transfer thread can immediately set up the next transfer
and assign curr_xfer to point to it.
If a delayed ISR from the previous transfer then runs, it checks if
(!tqspi->curr_xfer) (currently without the lock also -- to be fixed
soon) to detect stale interrupts, but this check passes because
curr_xfer now points to the new transfer. The ISR then incorrectly
processes the new transfer's context.
Protect the curr_xfer assignment with the spinlock to ensure the ISR
either sees NULL (and bails out) or sees the new value only after the
assignment is complete.
Fixes: 921fc1838f ("spi: tegra210-quad: Add support for Tegra210 QSPI controller")
Signed-off-by: Breno Leitao <leitao@debian.org>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Link: https://patch.msgid.link/20260126-tegra_xfer-v2-3-6d2115e4f387@debian.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Move the assignment of the transfer pointer from curr_xfer inside the
spinlock critical section in both handle_cpu_based_xfer() and
handle_dma_based_xfer().
Previously, curr_xfer was read before acquiring the lock, creating a
window where the timeout path could clear curr_xfer between reading it
and using it. By moving the read inside the lock, the handlers are
guaranteed to see a consistent value that cannot be modified by the
timeout path.
Fixes: 921fc1838f ("spi: tegra210-quad: Add support for Tegra210 QSPI controller")
Signed-off-by: Breno Leitao <leitao@debian.org>
Acked-by: Thierry Reding <treding@nvidia.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Link: https://patch.msgid.link/20260126-tegra_xfer-v2-2-6d2115e4f387@debian.org
Signed-off-by: Mark Brown <broonie@kernel.org>
When the ISR thread wakes up late and finds that the timeout handler
has already processed the transfer (curr_xfer is NULL), return
IRQ_HANDLED instead of IRQ_NONE.
Use a similar approach to tegra_qspi_handle_timeout() by reading
QSPI_TRANS_STATUS and checking the QSPI_RDY bit to determine if the
hardware actually completed the transfer. If QSPI_RDY is set, the
interrupt was legitimate and triggered by real hardware activity.
The fact that the timeout path handled it first doesn't make it
spurious. Returning IRQ_NONE incorrectly suggests the interrupt
wasn't for this device, which can cause issues with shared interrupt
lines and interrupt accounting.
Fixes: b4e002d8a7 ("spi: tegra210-quad: Fix timeout handling")
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Usama Arif <usamaarif642@gmail.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Link: https://patch.msgid.link/20260126-tegra_xfer-v2-1-6d2115e4f387@debian.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Merge series from "Miquel Raynal (Schneider Electric)" <miquel.raynal@bootlin.com>:
This series adds support for the QSPI controller available on Renesas
RZ/N1S and RZ/N1D SoC. It has been tested with a custom board (see last
SPI patch for details), but has been tested by Wolfram (thank you!) on
the DB board.
Link: https://lore.kernel.org/linux-devicetree/20260116114852.52948-2-wsa+renesas@sang-engineering.com/
Adding support for this SoC required a few adaptations in the Cadence
QSPI driver. The bulk of the work is in the few last patches. Everything
else is just misc style fixes and improvements which bothered me while I
was wandering.
In order to support all constraints, I sometimes used a new quirk (for
the write protection feature and the "no indirect mode"), and sometimes
used the compatible directly. The ones I thought might not be RZ/N1
specific have been implemented under the form of a quirk, in order to
ease their reuse. The other adaptations, which I believe are more
Renesas specific, have been handled using the compatible. This is all
very arbitrary, and can be discussed.
Bindings expect 4 to be the default value for cdns,fifo-width. Said
otherwise, if the property (which is not mandatory) is not provided, the
OS, in order to comply with the bindings, should not error out and take
4 as default value.
Comply with the bindings. This would have slighlty simplyfied my testing
if it had been implemented correctly in the first place, but in practice
it should have no impact on the existing boards using this controller, as
they all set cdns,fifo-width to 4 explicitly in their upstream DTS.
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Miquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com>
Tested-by: Santhosh Kumar K <s-k6@ti.com>
Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-13-f9c21419a3e6@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Renesas RZ/N1 QSPI controllers embed the Cadence IP with some
modifications. For instance, they feature a write protection of the
direct mapping at the controller level, with this feature all data
writes to the AHB region are aborted.
Despite the fact that the flag setting write protection is disabled by
default, Bootloaders may (and actually do) set it, so mark this feature
as being available with a specific flag to, if applicable, make sure it
is disabled.
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Miquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com>
Tested-by: Santhosh Kumar K <s-k6@ti.com>
Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-12-f9c21419a3e6@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>