From: vkoul@infradead.org (Vinod Koul)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] Improve slave/cyclic DMA engine documentation (was: [PATCH V4 04/14] DMA: PL330: Add DMA_CYCLIC capability)
Date: Tue, 26 Jul 2011 15:05:33 +0530 [thread overview]
Message-ID: <1311672933.24316.1.camel@vkoul-mobl4> (raw)
In-Reply-To: <20110726075720.GL9653@n2100.arm.linux.org.uk>
On Tue, 2011-07-26 at 08:57 +0100, Russell King - ARM Linux wrote:
> Here's an updated patch.
>
> 8<----------
> From: Russell King <rmk+kernel@arm.linux.org.uk>
> DMAEngine: Improve slave/cyclic documentation
>
> Improve the documentation for the slave and cyclic DMA engine support
> reformatting it for easier reading, adding further APIs, splitting it
> into five steps, and including references to the documentation in
> dmaengine.h.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
> Documentation/dmaengine.txt | 211 ++++++++++++++++++++++++++++++-------------
> 1 files changed, 146 insertions(+), 65 deletions(-)
>
> diff --git a/Documentation/dmaengine.txt b/Documentation/dmaengine.txt
> index 5a0cb1e..8c2e888 100644
> --- a/Documentation/dmaengine.txt
> +++ b/Documentation/dmaengine.txt
> @@ -10,87 +10,168 @@
> Below is a guide to device driver writers on how to use the Slave-DMA API of the
> DMA Engine. This is applicable only for slave DMA usage only.
>
> -The slave DMA usage consists of following steps
> +The slave DMA usage consists of following steps:
> 1. Allocate a DMA slave channel
> 2. Set slave and controller specific parameters
> 3. Get a descriptor for transaction
> 4. Submit the transaction and wait for callback notification
> +5. Issue pending requests
Thanks Russell,
Applied with change to 4 above. Moved "and wait for callback
notification" to 5.
>
> 1. Allocate a DMA slave channel
> -Channel allocation is slightly different in the slave DMA context, client
> -drivers typically need a channel from a particular DMA controller only and even
> -in some cases a specific channel is desired. To request a channel
> -dma_request_channel() API is used.
> -
> -Interface:
> -struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
> - dma_filter_fn filter_fn,
> - void *filter_param);
> -where dma_filter_fn is defined as:
> -typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
> -
> -When the optional 'filter_fn' parameter is set to NULL dma_request_channel
> -simply returns the first channel that satisfies the capability mask. Otherwise,
> -when the mask parameter is insufficient for specifying the necessary channel,
> -the filter_fn routine can be used to disposition the available channels in the
> -system. The filter_fn routine is called once for each free channel in the
> -system. Upon seeing a suitable channel filter_fn returns DMA_ACK which flags
> -that channel to be the return value from dma_request_channel. A channel
> -allocated via this interface is exclusive to the caller, until
> -dma_release_channel() is called.
> +
> + Channel allocation is slightly different in the slave DMA context,
> + client drivers typically need a channel from a particular DMA
> + controller only and even in some cases a specific channel is desired.
> + To request a channel dma_request_channel() API is used.
> +
> + Interface:
> + struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
> + dma_filter_fn filter_fn,
> + void *filter_param);
> + where dma_filter_fn is defined as:
> + typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
> +
> + The 'filter_fn' parameter is optional, but highly recommended for
> + slave and cyclic channels as they typically need to obtain a specific
> + DMA channel.
> +
> + When the optional 'filter_fn' parameter is NULL, dma_request_channel()
> + simply returns the first channel that satisfies the capability mask.
> +
> + Otherwise, the 'filter_fn' routine will be called once for each free
> + channel which has a capability in 'mask'. 'filter_fn' is expected to
> + return 'true' when the desired DMA channel is found.
> +
> + A channel allocated via this interface is exclusive to the caller,
> + until dma_release_channel() is called.
>
> 2. Set slave and controller specific parameters
> -Next step is always to pass some specific information to the DMA driver. Most of
> -the generic information which a slave DMA can use is in struct dma_slave_config.
> -It allows the clients to specify DMA direction, DMA addresses, bus widths, DMA
> -burst lengths etc. If some DMA controllers have more parameters to be sent then
> -they should try to embed struct dma_slave_config in their controller specific
> -structure. That gives flexibility to client to pass more parameters, if
> -required.
> -
> -Interface:
> -int dmaengine_slave_config(struct dma_chan *chan,
> - struct dma_slave_config *config)
> +
> + Next step is always to pass some specific information to the DMA
> + driver. Most of the generic information which a slave DMA can use
> + is in struct dma_slave_config. This allows the clients to specify
> + DMA direction, DMA addresses, bus widths, DMA burst lengths etc
> + for the peripheral.
> +
> + If some DMA controllers have more parameters to be sent then they
> + should try to embed struct dma_slave_config in their controller
> + specific structure. That gives flexibility to client to pass more
> + parameters, if required.
> +
> + Interface:
> + int dmaengine_slave_config(struct dma_chan *chan,
> + struct dma_slave_config *config)
> +
> + Please see the dma_slave_config structure definition in dmaengine.h
> + for a detailed explaination of the struct members. Please note
> + that the 'direction' member will be going away as it duplicates the
> + direction given in the prepare call.
>
> 3. Get a descriptor for transaction
> -For slave usage the various modes of slave transfers supported by the
> -DMA-engine are:
> -slave_sg - DMA a list of scatter gather buffers from/to a peripheral
> -dma_cyclic - Perform a cyclic DMA operation from/to a peripheral till the
> +
> + For slave usage the various modes of slave transfers supported by the
> + DMA-engine are:
> +
> + slave_sg - DMA a list of scatter gather buffers from/to a peripheral
> + dma_cyclic - Perform a cyclic DMA operation from/to a peripheral till the
> operation is explicitly stopped.
> -The non NULL return of this transfer API represents a "descriptor" for the given
> -transaction.
>
> -Interface:
> -struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_sg)(
> + A non-NULL return of this transfer API represents a "descriptor" for
> + the given transaction.
> +
> + Interface:
> + struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_sg)(
> struct dma_chan *chan,
> struct scatterlist *dst_sg, unsigned int dst_nents,
> struct scatterlist *src_sg, unsigned int src_nents,
> unsigned long flags);
> -struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)(
> +
> + struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)(
> struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
> size_t period_len, enum dma_data_direction direction);
>
> -4. Submit the transaction and wait for callback notification
> -To schedule the transaction to be scheduled by dma device, the "descriptor"
> -returned in above (3) needs to be submitted.
> -To tell the dma driver that a transaction is ready to be serviced, the
> -descriptor->submit() callback needs to be invoked. This chains the descriptor to
> -the pending queue.
> -The transactions in the pending queue can be activated by calling the
> -issue_pending API. If channel is idle then the first transaction in queue is
> -started and subsequent ones queued up.
> -On completion of the DMA operation the next in queue is submitted and a tasklet
> -triggered. The tasklet would then call the client driver completion callback
> -routine for notification, if set.
> -Interface:
> -void dma_async_issue_pending(struct dma_chan *chan);
> -
> -==============================================================================
> -
> -Additional usage notes for dma driver writers
> -1/ Although DMA engine specifies that completion callback routines cannot submit
> -any new operations, but typically for slave DMA subsequent transaction may not
> -be available for submit prior to callback routine being called. This requirement
> -is not a requirement for DMA-slave devices. But they should take care to drop
> -the spin-lock they might be holding before calling the callback routine
> + Once a descriptor has been obtained, the callback information can be
> + added and must then be submitted. Some DMA engine drivers may hold a
> + spinlock between a successful preparation and submission so it is
> + important that these two operations are closely paired.
> +
> + Note:
> + Although the async_tx API specifies that completion callback
> + routines cannot submit any new operations, this is not the
> + case for slave/cyclic DMA.
> +
> + For slave DMA, the subsequent transaction may not be available
> + for submission prior to callback function being invoked, so
> + slave DMA callbacks are permitted to prepare and submit a new
> + transaction.
> +
> + For cyclic DMA, a callback function may wish to terminate the
> + DMA via dmaengine_terminate_all().
> +
> + Therefore, it is important that DMA engine drivers drop any
> + locks before calling the callback function which may cause a
> + deadlock.
> +
> + Note that callbacks will always be invoked from the DMA
> + engines tasklet, never from interrupt context.
> +
> +4. Submit the transaction
> +
> + Once the descriptor has been prepared and the callback information
> + added, it must be placed on the DMA engine drivers pending queue.
> +
> + Interface:
> + dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc)
> +
> + This returns a cookie can be used to check the progress of DMA engine
> + activity via other DMA engine calls not covered in this document.
> +
> + dmaengine_submit() will not start the DMA operation, it merely adds
> + it to the pending queue. For this, see step 5, dma_async_issue_pending.
> +
> +5. Issue pending DMA requests and wait for callback notification
> +
> + The transactions in the pending queue can be activated by calling the
> + issue_pending API. If channel is idle then the first transaction in
> + queue is started and subsequent ones queued up.
> +
> + On completion of each DMA operation, the next in queue is started and
> + a tasklet triggered. The tasklet will then call the client driver
> + completion callback routine for notification, if set.
> +
> + Interface:
> + void dma_async_issue_pending(struct dma_chan *chan);
> +
> +Further APIs:
> +
> +1. int dmaengine_terminate_all(struct dma_chan *chan)
> +
> + This causes all activity for the DMA channel to be stopped, and may
> + discard data in the DMA FIFO which hasn't been fully transferred.
> + No callback functions will be called for any incomplete transfers.
> +
> +2. int dmaengine_pause(struct dma_chan *chan)
> +
> + This pauses activity on the DMA channel without data loss.
> +
> +3. int dmaengine_resume(struct dma_chan *chan)
> +
> + Resume a previously paused DMA channel. It is invalid to resume a
> + channel which is not currently paused.
> +
> +4. enum dma_status dma_async_is_tx_complete(struct dma_chan *chan,
> + dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used)
> +
> + This can be used to check the status of the channel. Please see
> + the documentation in include/linux/dmaengine.h for a more complete
> + description of this API.
> +
> + This can be used in conjunction with dma_async_is_complete() and
> + the cookie returned from 'descriptor->submit()' to check for
> + completion of a specific DMA transaction.
> +
> + Note:
> + Not all DMA engine drivers can return reliable information for
> + a running DMA channel. It is recommended that DMA engine users
> + pause or stop (via dmaengine_terminate_all) the channel before
> + using this API.
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
~Vinod Koul
Intel Corp.
next prev parent reply other threads:[~2011-07-26 9:35 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-25 1:28 [RESEND] [PATCH V4 0/14] To use DMA generic APIs for Samsung DMA Boojin Kim
2011-07-25 1:28 ` [PATCH V4 01/14] DMA: PL330: Add support runtime PM for PL330 DMAC Boojin Kim
2011-07-26 6:03 ` Chanwoo Choi
2011-07-25 1:28 ` [PATCH V4 02/14] DMA: PL330: Update PL330 DMA API driver Boojin Kim
2011-07-25 8:57 ` Jassi Brar
2011-07-25 9:48 ` Boojin Kim
2011-07-25 1:28 ` [PATCH V4 03/14] DMA: PL330: Support DMA_SLAVE_CONFIG command Boojin Kim
2011-07-25 10:26 ` Vinod Koul
2011-07-25 12:51 ` Boojin Kim
2011-07-25 13:48 ` Vinod Koul
2011-07-26 13:04 ` Boojin Kim
2011-07-26 13:12 ` Russell King - ARM Linux
2011-07-25 1:28 ` [PATCH V4 04/14] DMA: PL330: Add DMA_CYCLIC capability Boojin Kim
2011-07-25 9:27 ` Russell King - ARM Linux
2011-07-25 10:31 ` Boojin Kim
2011-07-25 10:36 ` Russell King - ARM Linux
2011-07-25 10:48 ` Vinod Koul
2011-07-25 10:57 ` Russell King - ARM Linux
2011-07-25 11:01 ` Vinod Koul
2011-07-25 11:39 ` Russell King - ARM Linux
2011-07-25 12:01 ` Vinod Koul
2011-07-26 7:57 ` [PATCH] Improve slave/cyclic DMA engine documentation (was: [PATCH V4 04/14] DMA: PL330: Add DMA_CYCLIC capability) Russell King - ARM Linux
2011-07-26 9:35 ` Vinod Koul [this message]
2011-07-26 14:37 ` Jassi Brar
2011-07-26 17:20 ` Russell King - ARM Linux
2011-07-26 17:55 ` Jassi Brar
2011-07-26 18:03 ` Grant Likely
2011-07-26 18:16 ` Russell King - ARM Linux
2011-07-27 2:38 ` Vinod Koul
2011-07-27 9:01 ` Russell King - ARM Linux
2011-07-27 9:06 ` Koul, Vinod
2011-07-26 13:25 ` Russell King - ARM Linux
2011-07-25 12:36 ` [PATCH V4 04/14] DMA: PL330: Add DMA_CYCLIC capability Boojin Kim
2011-07-25 12:34 ` Boojin Kim
2011-07-25 11:24 ` Jassi Brar
2011-07-26 12:28 ` Boojin Kim
2011-07-25 1:28 ` [PATCH V4 05/14] ARM: SAMSUNG: Update to use PL330-DMA driver Boojin Kim
2011-07-25 10:52 ` Vinod Koul
2011-07-25 11:31 ` Jassi Brar
2011-07-25 1:28 ` [PATCH V4 06/14] ARM: SAMSUNG: Add common DMA operations Boojin Kim
2011-07-25 9:36 ` Russell King - ARM Linux
2011-07-25 9:57 ` Boojin Kim
2011-07-25 11:51 ` Jassi Brar
2011-07-26 8:02 ` Russell King - ARM Linux
2011-07-26 17:43 ` Jassi Brar
2011-07-26 18:14 ` Russell King - ARM Linux
2011-07-26 19:54 ` Jassi Brar
2011-07-26 9:35 ` Boojin Kim
2011-07-27 1:33 ` Jassi Brar
2011-07-27 5:17 ` Boojin Kim
2011-07-27 7:57 ` Jassi Brar
2011-07-28 0:38 ` Boojin Kim
2011-07-25 1:28 ` [PATCH V4 07/14] ARM: EXYNOS4: Use generic DMA PL330 driver Boojin Kim
2011-07-25 11:59 ` Jassi Brar
2011-07-25 12:59 ` Boojin Kim
2011-07-25 1:28 ` [PATCH V4 08/14] ARM: S5PV210: " Boojin Kim
2011-07-25 1:28 ` [PATCH V4 09/14] ARM: S5PC100: " Boojin Kim
2011-07-25 1:28 ` [PATCH V4 10/14] ARM: S5P64X0: " Boojin Kim
2011-07-25 1:28 ` [PATCH V4 11/14] ARM: SAMSUNG: Remove S3C-PL330-DMA driver Boojin Kim
2011-07-25 1:28 ` [PATCH V4 12/14] spi/s3c64xx: Add support DMA engine API Boojin Kim
2011-07-25 9:40 ` Russell King - ARM Linux
2011-07-25 10:34 ` Boojin Kim
2011-07-25 11:17 ` Vinod Koul
2011-07-26 9:31 ` Boojin Kim
2011-07-26 10:14 ` Vinod Koul
2011-07-27 5:05 ` Boojin Kim
2011-07-25 1:28 ` [PATCH V4 13/14] ASoC: Samsung: Update DMA interface Boojin Kim
2011-07-25 1:28 ` [PATCH V4 14/14] ARM: SAMSUNG: Remove Samsung specific enum type for dma direction Boojin Kim
2011-07-25 12:08 ` Jassi Brar
2011-07-25 21:15 ` Grant Likely
2011-07-28 1:23 ` Boojin Kim
2011-07-25 10:17 ` [RESEND] [PATCH V4 0/14] To use DMA generic APIs for Samsung DMA Vinod Koul
2011-07-25 11:09 ` Vinod Koul
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1311672933.24316.1.camel@vkoul-mobl4 \
--to=vkoul@infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox