162306a36Sopenharmony_ci====================
262306a36Sopenharmony_ciDMA Engine API Guide
362306a36Sopenharmony_ci====================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciVinod Koul <vinod dot koul at intel.com>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci.. note:: For DMA Engine usage in async_tx please see:
862306a36Sopenharmony_ci          ``Documentation/crypto/async-tx-api.rst``
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciBelow is a guide to device driver writers on how to use the Slave-DMA API of the
1262306a36Sopenharmony_ciDMA Engine. This is applicable only for slave DMA usage only.
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ciDMA usage
1562306a36Sopenharmony_ci=========
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ciThe slave DMA usage consists of following steps:
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci- Allocate a DMA slave channel
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci- Set slave and controller specific parameters
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci- Get a descriptor for transaction
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci- Submit the transaction
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci- Issue pending requests and wait for callback notification
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ciThe details of these operations are:
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci1. Allocate a DMA slave channel
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci   Channel allocation is slightly different in the slave DMA context,
3462306a36Sopenharmony_ci   client drivers typically need a channel from a particular DMA
3562306a36Sopenharmony_ci   controller only and even in some cases a specific channel is desired.
3662306a36Sopenharmony_ci   To request a channel dma_request_chan() API is used.
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci   Interface:
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci   .. code-block:: c
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci      struct dma_chan *dma_request_chan(struct device *dev, const char *name);
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci   Which will find and return the ``name`` DMA channel associated with the 'dev'
4562306a36Sopenharmony_ci   device. The association is done via DT, ACPI or board file based
4662306a36Sopenharmony_ci   dma_slave_map matching table.
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci   A channel allocated via this interface is exclusive to the caller,
4962306a36Sopenharmony_ci   until dma_release_channel() is called.
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci2. Set slave and controller specific parameters
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci   Next step is always to pass some specific information to the DMA
5462306a36Sopenharmony_ci   driver. Most of the generic information which a slave DMA can use
5562306a36Sopenharmony_ci   is in struct dma_slave_config. This allows the clients to specify
5662306a36Sopenharmony_ci   DMA direction, DMA addresses, bus widths, DMA burst lengths etc
5762306a36Sopenharmony_ci   for the peripheral.
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci   If some DMA controllers have more parameters to be sent then they
6062306a36Sopenharmony_ci   should try to embed struct dma_slave_config in their controller
6162306a36Sopenharmony_ci   specific structure. That gives flexibility to client to pass more
6262306a36Sopenharmony_ci   parameters, if required.
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci   Interface:
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci   .. code-block:: c
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci      int dmaengine_slave_config(struct dma_chan *chan,
6962306a36Sopenharmony_ci			struct dma_slave_config *config)
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci   Please see the dma_slave_config structure definition in dmaengine.h
7262306a36Sopenharmony_ci   for a detailed explanation of the struct members. Please note
7362306a36Sopenharmony_ci   that the 'direction' member will be going away as it duplicates the
7462306a36Sopenharmony_ci   direction given in the prepare call.
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci3. Get a descriptor for transaction
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci  For slave usage the various modes of slave transfers supported by the
7962306a36Sopenharmony_ci  DMA-engine are:
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci  - slave_sg: DMA a list of scatter gather buffers from/to a peripheral
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci  - dma_cyclic: Perform a cyclic DMA operation from/to a peripheral till the
8462306a36Sopenharmony_ci    operation is explicitly stopped.
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci  - interleaved_dma: This is common to Slave as well as M2M clients. For slave
8762306a36Sopenharmony_ci    address of devices' fifo could be already known to the driver.
8862306a36Sopenharmony_ci    Various types of operations could be expressed by setting
8962306a36Sopenharmony_ci    appropriate values to the 'dma_interleaved_template' members. Cyclic
9062306a36Sopenharmony_ci    interleaved DMA transfers are also possible if supported by the channel by
9162306a36Sopenharmony_ci    setting the DMA_PREP_REPEAT transfer flag.
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci  A non-NULL return of this transfer API represents a "descriptor" for
9462306a36Sopenharmony_ci  the given transaction.
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci  Interface:
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci  .. code-block:: c
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci     struct dma_async_tx_descriptor *dmaengine_prep_slave_sg(
10162306a36Sopenharmony_ci		struct dma_chan *chan, struct scatterlist *sgl,
10262306a36Sopenharmony_ci		unsigned int sg_len, enum dma_data_direction direction,
10362306a36Sopenharmony_ci		unsigned long flags);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci     struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic(
10662306a36Sopenharmony_ci		struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
10762306a36Sopenharmony_ci		size_t period_len, enum dma_data_direction direction);
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci     struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma(
11062306a36Sopenharmony_ci		struct dma_chan *chan, struct dma_interleaved_template *xt,
11162306a36Sopenharmony_ci		unsigned long flags);
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci  The peripheral driver is expected to have mapped the scatterlist for
11462306a36Sopenharmony_ci  the DMA operation prior to calling dmaengine_prep_slave_sg(), and must
11562306a36Sopenharmony_ci  keep the scatterlist mapped until the DMA operation has completed.
11662306a36Sopenharmony_ci  The scatterlist must be mapped using the DMA struct device.
11762306a36Sopenharmony_ci  If a mapping needs to be synchronized later, dma_sync_*_for_*() must be
11862306a36Sopenharmony_ci  called using the DMA struct device, too.
11962306a36Sopenharmony_ci  So, normal setup should look like this:
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci  .. code-block:: c
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci     struct device *dma_dev = dmaengine_get_dma_device(chan);
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci     nr_sg = dma_map_sg(dma_dev, sgl, sg_len);
12662306a36Sopenharmony_ci	if (nr_sg == 0)
12762306a36Sopenharmony_ci		/* error */
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	desc = dmaengine_prep_slave_sg(chan, sgl, nr_sg, direction, flags);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci  Once a descriptor has been obtained, the callback information can be
13262306a36Sopenharmony_ci  added and the descriptor must then be submitted. Some DMA engine
13362306a36Sopenharmony_ci  drivers may hold a spinlock between a successful preparation and
13462306a36Sopenharmony_ci  submission so it is important that these two operations are closely
13562306a36Sopenharmony_ci  paired.
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci  .. note::
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci     Although the async_tx API specifies that completion callback
14062306a36Sopenharmony_ci     routines cannot submit any new operations, this is not the
14162306a36Sopenharmony_ci     case for slave/cyclic DMA.
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci     For slave DMA, the subsequent transaction may not be available
14462306a36Sopenharmony_ci     for submission prior to callback function being invoked, so
14562306a36Sopenharmony_ci     slave DMA callbacks are permitted to prepare and submit a new
14662306a36Sopenharmony_ci     transaction.
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci     For cyclic DMA, a callback function may wish to terminate the
14962306a36Sopenharmony_ci     DMA via dmaengine_terminate_async().
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci     Therefore, it is important that DMA engine drivers drop any
15262306a36Sopenharmony_ci     locks before calling the callback function which may cause a
15362306a36Sopenharmony_ci     deadlock.
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci     Note that callbacks will always be invoked from the DMA
15662306a36Sopenharmony_ci     engines tasklet, never from interrupt context.
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci  **Optional: per descriptor metadata**
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci  DMAengine provides two ways for metadata support.
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci  DESC_METADATA_CLIENT
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci    The metadata buffer is allocated/provided by the client driver and it is
16562306a36Sopenharmony_ci    attached to the descriptor.
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci  .. code-block:: c
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci     int dmaengine_desc_attach_metadata(struct dma_async_tx_descriptor *desc,
17062306a36Sopenharmony_ci				   void *data, size_t len);
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci  DESC_METADATA_ENGINE
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci    The metadata buffer is allocated/managed by the DMA driver. The client
17562306a36Sopenharmony_ci    driver can ask for the pointer, maximum size and the currently used size of
17662306a36Sopenharmony_ci    the metadata and can directly update or read it.
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci    Because the DMA driver manages the memory area containing the metadata,
17962306a36Sopenharmony_ci    clients must make sure that they do not try to access or get the pointer
18062306a36Sopenharmony_ci    after their transfer completion callback has run for the descriptor.
18162306a36Sopenharmony_ci    If no completion callback has been defined for the transfer, then the
18262306a36Sopenharmony_ci    metadata must not be accessed after issue_pending.
18362306a36Sopenharmony_ci    In other words: if the aim is to read back metadata after the transfer is
18462306a36Sopenharmony_ci    completed, then the client must use completion callback.
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci  .. code-block:: c
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci     void *dmaengine_desc_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
18962306a36Sopenharmony_ci		size_t *payload_len, size_t *max_len);
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci     int dmaengine_desc_set_metadata_len(struct dma_async_tx_descriptor *desc,
19262306a36Sopenharmony_ci		size_t payload_len);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci  Client drivers can query if a given mode is supported with:
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci  .. code-block:: c
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci     bool dmaengine_is_metadata_mode_supported(struct dma_chan *chan,
19962306a36Sopenharmony_ci		enum dma_desc_metadata_mode mode);
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci  Depending on the used mode client drivers must follow different flow.
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci  DESC_METADATA_CLIENT
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci    - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci      1. prepare the descriptor (dmaengine_prep_*)
20862306a36Sopenharmony_ci         construct the metadata in the client's buffer
20962306a36Sopenharmony_ci      2. use dmaengine_desc_attach_metadata() to attach the buffer to the
21062306a36Sopenharmony_ci         descriptor
21162306a36Sopenharmony_ci      3. submit the transfer
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci    - DMA_DEV_TO_MEM:
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci      1. prepare the descriptor (dmaengine_prep_*)
21662306a36Sopenharmony_ci      2. use dmaengine_desc_attach_metadata() to attach the buffer to the
21762306a36Sopenharmony_ci         descriptor
21862306a36Sopenharmony_ci      3. submit the transfer
21962306a36Sopenharmony_ci      4. when the transfer is completed, the metadata should be available in the
22062306a36Sopenharmony_ci         attached buffer
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci  DESC_METADATA_ENGINE
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci    - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci      1. prepare the descriptor (dmaengine_prep_*)
22762306a36Sopenharmony_ci      2. use dmaengine_desc_get_metadata_ptr() to get the pointer to the
22862306a36Sopenharmony_ci         engine's metadata area
22962306a36Sopenharmony_ci      3. update the metadata at the pointer
23062306a36Sopenharmony_ci      4. use dmaengine_desc_set_metadata_len()  to tell the DMA engine the
23162306a36Sopenharmony_ci         amount of data the client has placed into the metadata buffer
23262306a36Sopenharmony_ci      5. submit the transfer
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci    - DMA_DEV_TO_MEM:
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci      1. prepare the descriptor (dmaengine_prep_*)
23762306a36Sopenharmony_ci      2. submit the transfer
23862306a36Sopenharmony_ci      3. on transfer completion, use dmaengine_desc_get_metadata_ptr() to get
23962306a36Sopenharmony_ci         the pointer to the engine's metadata area
24062306a36Sopenharmony_ci      4. read out the metadata from the pointer
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci  .. note::
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci     When DESC_METADATA_ENGINE mode is used the metadata area for the descriptor
24562306a36Sopenharmony_ci     is no longer valid after the transfer has been completed (valid up to the
24662306a36Sopenharmony_ci     point when the completion callback returns if used).
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci     Mixed use of DESC_METADATA_CLIENT / DESC_METADATA_ENGINE is not allowed,
24962306a36Sopenharmony_ci     client drivers must use either of the modes per descriptor.
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci4. Submit the transaction
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci   Once the descriptor has been prepared and the callback information
25462306a36Sopenharmony_ci   added, it must be placed on the DMA engine drivers pending queue.
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci   Interface:
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci   .. code-block:: c
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci      dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc)
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci   This returns a cookie can be used to check the progress of DMA engine
26362306a36Sopenharmony_ci   activity via other DMA engine calls not covered in this document.
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci   dmaengine_submit() will not start the DMA operation, it merely adds
26662306a36Sopenharmony_ci   it to the pending queue. For this, see step 5, dma_async_issue_pending.
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci   .. note::
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci      After calling ``dmaengine_submit()`` the submitted transfer descriptor
27162306a36Sopenharmony_ci      (``struct dma_async_tx_descriptor``) belongs to the DMA engine.
27262306a36Sopenharmony_ci      Consequently, the client must consider invalid the pointer to that
27362306a36Sopenharmony_ci      descriptor.
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci5. Issue pending DMA requests and wait for callback notification
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci   The transactions in the pending queue can be activated by calling the
27862306a36Sopenharmony_ci   issue_pending API. If channel is idle then the first transaction in
27962306a36Sopenharmony_ci   queue is started and subsequent ones queued up.
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci   On completion of each DMA operation, the next in queue is started and
28262306a36Sopenharmony_ci   a tasklet triggered. The tasklet will then call the client driver
28362306a36Sopenharmony_ci   completion callback routine for notification, if set.
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci   Interface:
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci   .. code-block:: c
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci      void dma_async_issue_pending(struct dma_chan *chan);
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ciFurther APIs
29262306a36Sopenharmony_ci------------
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci1. Terminate APIs
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci   .. code-block:: c
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci      int dmaengine_terminate_sync(struct dma_chan *chan)
29962306a36Sopenharmony_ci      int dmaengine_terminate_async(struct dma_chan *chan)
30062306a36Sopenharmony_ci      int dmaengine_terminate_all(struct dma_chan *chan) /* DEPRECATED */
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci   This causes all activity for the DMA channel to be stopped, and may
30362306a36Sopenharmony_ci   discard data in the DMA FIFO which hasn't been fully transferred.
30462306a36Sopenharmony_ci   No callback functions will be called for any incomplete transfers.
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci   Two variants of this function are available.
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci   dmaengine_terminate_async() might not wait until the DMA has been fully
30962306a36Sopenharmony_ci   stopped or until any running complete callbacks have finished. But it is
31062306a36Sopenharmony_ci   possible to call dmaengine_terminate_async() from atomic context or from
31162306a36Sopenharmony_ci   within a complete callback. dmaengine_synchronize() must be called before it
31262306a36Sopenharmony_ci   is safe to free the memory accessed by the DMA transfer or free resources
31362306a36Sopenharmony_ci   accessed from within the complete callback.
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci   dmaengine_terminate_sync() will wait for the transfer and any running
31662306a36Sopenharmony_ci   complete callbacks to finish before it returns. But the function must not be
31762306a36Sopenharmony_ci   called from atomic context or from within a complete callback.
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci   dmaengine_terminate_all() is deprecated and should not be used in new code.
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci2. Pause API
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci   .. code-block:: c
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci      int dmaengine_pause(struct dma_chan *chan)
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci   This pauses activity on the DMA channel without data loss.
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci3. Resume API
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci   .. code-block:: c
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci       int dmaengine_resume(struct dma_chan *chan)
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci   Resume a previously paused DMA channel. It is invalid to resume a
33662306a36Sopenharmony_ci   channel which is not currently paused.
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci4. Check Txn complete
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci   .. code-block:: c
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci      enum dma_status dma_async_is_tx_complete(struct dma_chan *chan,
34362306a36Sopenharmony_ci		dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used)
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci   This can be used to check the status of the channel. Please see
34662306a36Sopenharmony_ci   the documentation in include/linux/dmaengine.h for a more complete
34762306a36Sopenharmony_ci   description of this API.
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci   This can be used in conjunction with dma_async_is_complete() and
35062306a36Sopenharmony_ci   the cookie returned from dmaengine_submit() to check for
35162306a36Sopenharmony_ci   completion of a specific DMA transaction.
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci   .. note::
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci      Not all DMA engine drivers can return reliable information for
35662306a36Sopenharmony_ci      a running DMA channel. It is recommended that DMA engine users
35762306a36Sopenharmony_ci      pause or stop (via dmaengine_terminate_all()) the channel before
35862306a36Sopenharmony_ci      using this API.
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci5. Synchronize termination API
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci   .. code-block:: c
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci      void dmaengine_synchronize(struct dma_chan *chan)
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci   Synchronize the termination of the DMA channel to the current context.
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci   This function should be used after dmaengine_terminate_async() to synchronize
36962306a36Sopenharmony_ci   the termination of the DMA channel to the current context. The function will
37062306a36Sopenharmony_ci   wait for the transfer and any running complete callbacks to finish before it
37162306a36Sopenharmony_ci   returns.
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci   If dmaengine_terminate_async() is used to stop the DMA channel this function
37462306a36Sopenharmony_ci   must be called before it is safe to free memory accessed by previously
37562306a36Sopenharmony_ci   submitted descriptors or to free any resources accessed within the complete
37662306a36Sopenharmony_ci   callback of previously submitted descriptors.
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci   The behavior of this function is undefined if dma_async_issue_pending() has
37962306a36Sopenharmony_ci   been called between dmaengine_terminate_async() and this function.
380