This patch series adds support for the Andes ATCDMAC300 DMA controller,
a memory-to-memory and peripheral DMA controller that provides
scatter-gather, cyclic, and slave transfer capabilities.
The ATCDMAC300 IP is embedded in AndesCore-based platforms or SoCs
such as AE350 and Qilai.
v7 drew eight findings from sashiko-bot, and Frank Li asked for each to
be fixed or explained. Five are fixed here. The other three are
answered in the reply to v7 rather than changed:
- Terminal count and error arriving together:
The data sheet defines the terminal count status as being set only
when a transfer finishes without an error or abort event, and only
one transfer is in flight on a channel at a time, so the two cannot
both describe the same transfer.
- Descriptors a client prepares and never submits:
The desc_free half does not apply, as the driver does not set
descriptor_reuse and so that callback is unreachable; for the rest
the API offers no unprepare a driver could hook. No in-tree client
of this driver prepares a transfer it does not submit.
- Endianness conversions:
The driver depends on ARCH_ANDES and Linux has no big-endian RISC-V,
so the conversions would be no-ops everywhere this can be built, and
struct atcdmac_regs is both the linked list node the controller reads
and the staging copy fed to regmap_write(), so the fields would be
converted on the way in and converted straight back on the way out.
v7: https://lore.kernel.org/r/[email protected]
Changes in v8:
- Fold in fourteen further correctness fixes; no interface or binding
change. Five of them answer the v7 findings above; the remaining
nine come from a review of the whole driver.
- Descriptor lifetime:
- Track cyclic mode on the descriptor rather than on the channel;
a cyclic and a non-cyclic transfer on one channel could leave the
flag set for the wrong descriptor and dereference a NULL callback
- Drop the num_sg field, which was written but never read
- Suspend and resume:
- Restore stop_mask when suspend times out, instead of leaving
every channel stopped for good
- Start transfers that were queued while suspended
- Driver model:
- Do not offer the controller for unbinding; a client holding a
channel across an unbind would run against devres memory that
remove() has already released
- Register encoding:
- Reject a DMA request line the request-select field cannot hold,
rather than truncating it silently
- Keep the burst field out of its reserved range, which the
controller reports as an error exception
- Refuse a transfer width the width field cannot encode
- Slave configuration:
- Clear the stored configuration when a channel is allocated, so a
client cannot inherit the previous one's device address
- Accept a configuration that describes only the direction it uses
- Reject a length that is not a whole number of device-width units,
which either transfers fewer bytes than asked for or programs a
zero transfer size
- Probe:
- Use struct_size() for the channel array, which is already
declared with __counted_by()
- Check the configuration register read, and refuse a channel count
of zero rather than registering a controller with no channels
- Cleanups:
- Return a bool from the channel-enabled helper rather than a value
that is negative on a failed register read; pass a register value
rather than a bool to regmap_update_bits(); use
dma_cookie_status() directly
Changes in v7:
- Rebase onto the current dmaengine/next
- Fold in twelve correctness fixes found by review and confirmed on an
FPGA; no interface or binding change
- Interrupt path:
- Acknowledge only the status bits that were actually read
- Key the acknowledge on channel ownership instead of on in-flight
state the handler itself clears, which could leave a completion
unacknowledged until the core disabled the line
- Use raw spinlocks for the state shared with the hard IRQ handler
- Termination and descriptor lifetime:
- Do not run the callback twice, or recycle a descriptor, when a
transfer is terminated while its completion is in flight
- Initialise desc_node when a descriptor is allocated
- Wait for the channel to stop without holding the channel lock;
the poll could spin 100 ms with interrupts disabled
- Suspend and resume:
- Move the PM callbacks to the late phase so clients terminate their
transfers first, and name the channels that fail to idle
- Drain in-flight completions across suspend and resume
- Do not restart an idle cyclic channel on resume
- Probe:
- Register the DMA device only after the interrupt and cache
coherency setup, closing a window in which a client could obtain a
channel through dma_request_channel() on an unready controller
- Do not read-modify-write write-only registers
- Name the device in the probe-time reset error
Changes in v6:
- Rebase onto dmaengine/next; no functional changes from v5
- Fold the MAINTAINERS entry into the driver patch instead of carrying
it as a separate patch (series is now 2 patches)
Changes in v5:
- Update copyright year to 2026
- Remove redundant headers (init.h, iopoll.h, mod_devicetable.h)
- Move atcdmac_init_iocp() before of_dma_controller_register() in probe
- Change builtin_platform_driver() to module_platform_driver()
- Implement .remove callback to support safe module unloading
- Update Kconfig entry from bool to tristate
- Add MODULE_AUTHOR, MODULE_DESCRIPTION, MODULE_LICENSE macros
Changes in v4:
- Use items list format with descriptions for reg property in DT binding
as suggested by Conor Dooley
- Re-add Acked-by from Conor Dooley for DT binding patch
Changes in v3:
- Rename DT binding file from andestech,qilai-dma.yaml to
andestech,ae350-dma.yaml
- Deprecate IP-core-based compatible usage and align with
SoC/platform-based strings
- Dropped Acked-by from Conor Dooley due to the above binding change
- Remove "andestech,atcdmac300" from of_device_id table
- Replace deprecated tasklet with threaded IRQ using
devm_request_threaded_irq() and IRQF_ONESHOT
- Update locking from spin_lock_bh() to spin_lock_irqsave()
- Use builtin_platform_driver() instead of module_platform_driver()
- Remove "select DMATEST" from Kconfig
- Add separate MAINTAINERS patch (patch 3/3)
Please kindly review.
CL Wang (2):
dt-bindings: dmaengine: Add support for ATCDMAC300 DMA engine
dmaengine: atcdmac300: Add driver for Andes ATCDMAC300 DMA controller
.../bindings/dma/andestech,ae350-dma.yaml | 67 +
MAINTAINERS | 6 +
drivers/dma/Kconfig | 11 +
drivers/dma/Makefile | 1 +
drivers/dma/atcdmac300.c | 1759 +++++++++++++++++
drivers/dma/atcdmac300.h | 298 +++
6 files changed, 2142 insertions(+)
create mode 100644
Documentation/devicetree/bindings/dma/andestech,ae350-dma.yaml
create mode 100644 drivers/dma/atcdmac300.c
create mode 100644 drivers/dma/atcdmac300.h
base-commit: 0a8dda0a15d3926422d286567f945a05328a4ac6
--
2.34.1