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