aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/dmaengine/client.txt38
-rw-r--r--Documentation/dmaengine/provider.txt20
-rw-r--r--drivers/dma/dmaengine.c5
-rw-r--r--include/linux/dmaengine.h90
4 files changed, 148 insertions, 5 deletions
diff --git a/Documentation/dmaengine/client.txt b/Documentation/dmaengine/client.txt
index 11fb87ff6cd0..d9f9f461102a 100644
--- a/Documentation/dmaengine/client.txt
+++ b/Documentation/dmaengine/client.txt
@@ -128,7 +128,7 @@ The slave DMA usage consists of following steps:
128 transaction. 128 transaction.
129 129
130 For cyclic DMA, a callback function may wish to terminate the 130 For cyclic DMA, a callback function may wish to terminate the
131 DMA via dmaengine_terminate_all(). 131 DMA via dmaengine_terminate_async().
132 132
133 Therefore, it is important that DMA engine drivers drop any 133 Therefore, it is important that DMA engine drivers drop any
134 locks before calling the callback function which may cause a 134 locks before calling the callback function which may cause a
@@ -166,12 +166,29 @@ The slave DMA usage consists of following steps:
166 166
167Further APIs: 167Further APIs:
168 168
1691. int dmaengine_terminate_all(struct dma_chan *chan) 1691. int dmaengine_terminate_sync(struct dma_chan *chan)
170 int dmaengine_terminate_async(struct dma_chan *chan)
171 int dmaengine_terminate_all(struct dma_chan *chan) /* DEPRECATED */
170 172
171 This causes all activity for the DMA channel to be stopped, and may 173 This causes all activity for the DMA channel to be stopped, and may
172 discard data in the DMA FIFO which hasn't been fully transferred. 174 discard data in the DMA FIFO which hasn't been fully transferred.
173 No callback functions will be called for any incomplete transfers. 175 No callback functions will be called for any incomplete transfers.
174 176
177 Two variants of this function are available.
178
179 dmaengine_terminate_async() might not wait until the DMA has been fully
180 stopped or until any running complete callbacks have finished. But it is
181 possible to call dmaengine_terminate_async() from atomic context or from
182 within a complete callback. dmaengine_synchronize() must be called before it
183 is safe to free the memory accessed by the DMA transfer or free resources
184 accessed from within the complete callback.
185
186 dmaengine_terminate_sync() will wait for the transfer and any running
187 complete callbacks to finish before it returns. But the function must not be
188 called from atomic context or from within a complete callback.
189
190 dmaengine_terminate_all() is deprecated and should not be used in new code.
191
1752. int dmaengine_pause(struct dma_chan *chan) 1922. int dmaengine_pause(struct dma_chan *chan)
176 193
177 This pauses activity on the DMA channel without data loss. 194 This pauses activity on the DMA channel without data loss.
@@ -197,3 +214,20 @@ Further APIs:
197 a running DMA channel. It is recommended that DMA engine users 214 a running DMA channel. It is recommended that DMA engine users
198 pause or stop (via dmaengine_terminate_all()) the channel before 215 pause or stop (via dmaengine_terminate_all()) the channel before
199 using this API. 216 using this API.
217
2185. void dmaengine_synchronize(struct dma_chan *chan)
219
220 Synchronize the termination of the DMA channel to the current context.
221
222 This function should be used after dmaengine_terminate_async() to synchronize
223 the termination of the DMA channel to the current context. The function will
224 wait for the transfer and any running complete callbacks to finish before it
225 returns.
226
227 If dmaengine_terminate_async() is used to stop the DMA channel this function
228 must be called before it is safe to free memory accessed by previously
229 submitted descriptors or to free any resources accessed within the complete
230 callback of previously submitted descriptors.
231
232 The behavior of this function is undefined if dma_async_issue_pending() has
233 been called between dmaengine_terminate_async() and this function.
diff --git a/Documentation/dmaengine/provider.txt b/Documentation/dmaengine/provider.txt
index 67d4ce4df109..122b7f4876bb 100644
--- a/Documentation/dmaengine/provider.txt
+++ b/Documentation/dmaengine/provider.txt
@@ -327,8 +327,24 @@ supported.
327 327
328 * device_terminate_all 328 * device_terminate_all
329 - Aborts all the pending and ongoing transfers on the channel 329 - Aborts all the pending and ongoing transfers on the channel
330 - This command should operate synchronously on the channel, 330 - For aborted transfers the complete callback should not be called
331 terminating right away all the channels 331 - Can be called from atomic context or from within a complete
332 callback of a descriptor. Must not sleep. Drivers must be able
333 to handle this correctly.
334 - Termination may be asynchronous. The driver does not have to
335 wait until the currently active transfer has completely stopped.
336 See device_synchronize.
337
338 * device_synchronize
339 - Must synchronize the termination of a channel to the current
340 context.
341 - Must make sure that memory for previously submitted
342 descriptors is no longer accessed by the DMA controller.
343 - Must make sure that all complete callbacks for previously
344 submitted descriptors have finished running and none are
345 scheduled to run.
346 - May sleep.
347
332 348
333Misc notes (stuff that should be documented, but don't really know 349Misc notes (stuff that should be documented, but don't really know
334where to put them) 350where to put them)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 3ecec1445adf..d6fc82e3986f 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -265,8 +265,11 @@ static void dma_chan_put(struct dma_chan *chan)
265 module_put(dma_chan_to_owner(chan)); 265 module_put(dma_chan_to_owner(chan));
266 266
267 /* This channel is not in use anymore, free it */ 267 /* This channel is not in use anymore, free it */
268 if (!chan->client_count && chan->device->device_free_chan_resources) 268 if (!chan->client_count && chan->device->device_free_chan_resources) {
269 /* Make sure all operations have completed */
270 dmaengine_synchronize(chan);
269 chan->device->device_free_chan_resources(chan); 271 chan->device->device_free_chan_resources(chan);
272 }
270 273
271 /* If the channel is used via a DMA request router, free the mapping */ 274 /* If the channel is used via a DMA request router, free the mapping */
272 if (chan->router && chan->router->route_free) { 275 if (chan->router && chan->router->route_free) {
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index c47c68e535e8..4662d9aa6d5a 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -654,6 +654,8 @@ enum dmaengine_alignment {
654 * paused. Returns 0 or an error code 654 * paused. Returns 0 or an error code
655 * @device_terminate_all: Aborts all transfers on a channel. Returns 0 655 * @device_terminate_all: Aborts all transfers on a channel. Returns 0
656 * or an error code 656 * or an error code
657 * @device_synchronize: Synchronizes the termination of a transfers to the
658 * current context.
657 * @device_tx_status: poll for transaction completion, the optional 659 * @device_tx_status: poll for transaction completion, the optional
658 * txstate parameter can be supplied with a pointer to get a 660 * txstate parameter can be supplied with a pointer to get a
659 * struct with auxiliary transfer status information, otherwise the call 661 * struct with auxiliary transfer status information, otherwise the call
@@ -737,6 +739,7 @@ struct dma_device {
737 int (*device_pause)(struct dma_chan *chan); 739 int (*device_pause)(struct dma_chan *chan);
738 int (*device_resume)(struct dma_chan *chan); 740 int (*device_resume)(struct dma_chan *chan);
739 int (*device_terminate_all)(struct dma_chan *chan); 741 int (*device_terminate_all)(struct dma_chan *chan);
742 void (*device_synchronize)(struct dma_chan *chan);
740 743
741 enum dma_status (*device_tx_status)(struct dma_chan *chan, 744 enum dma_status (*device_tx_status)(struct dma_chan *chan,
742 dma_cookie_t cookie, 745 dma_cookie_t cookie,
@@ -828,6 +831,13 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg(
828 src_sg, src_nents, flags); 831 src_sg, src_nents, flags);
829} 832}
830 833
834/**
835 * dmaengine_terminate_all() - Terminate all active DMA transfers
836 * @chan: The channel for which to terminate the transfers
837 *
838 * This function is DEPRECATED use either dmaengine_terminate_sync() or
839 * dmaengine_terminate_async() instead.
840 */
831static inline int dmaengine_terminate_all(struct dma_chan *chan) 841static inline int dmaengine_terminate_all(struct dma_chan *chan)
832{ 842{
833 if (chan->device->device_terminate_all) 843 if (chan->device->device_terminate_all)
@@ -836,6 +846,86 @@ static inline int dmaengine_terminate_all(struct dma_chan *chan)
836 return -ENOSYS; 846 return -ENOSYS;
837} 847}
838 848
849/**
850 * dmaengine_terminate_async() - Terminate all active DMA transfers
851 * @chan: The channel for which to terminate the transfers
852 *
853 * Calling this function will terminate all active and pending descriptors
854 * that have previously been submitted to the channel. It is not guaranteed
855 * though that the transfer for the active descriptor has stopped when the
856 * function returns. Furthermore it is possible the complete callback of a
857 * submitted transfer is still running when this function returns.
858 *
859 * dmaengine_synchronize() needs to be called before it is safe to free
860 * any memory that is accessed by previously submitted descriptors or before
861 * freeing any resources accessed from within the completion callback of any
862 * perviously submitted descriptors.
863 *
864 * This function can be called from atomic context as well as from within a
865 * complete callback of a descriptor submitted on the same channel.
866 *
867 * If none of the two conditions above apply consider using
868 * dmaengine_terminate_sync() instead.
869 */
870static inline int dmaengine_terminate_async(struct dma_chan *chan)
871{
872 if (chan->device->device_terminate_all)
873 return chan->device->device_terminate_all(chan);
874
875 return -EINVAL;
876}
877
878/**
879 * dmaengine_synchronize() - Synchronize DMA channel termination
880 * @chan: The channel to synchronize
881 *
882 * Synchronizes to the DMA channel termination to the current context. When this
883 * function returns it is guaranteed that all transfers for previously issued
884 * descriptors have stopped and and it is safe to free the memory assoicated
885 * with them. Furthermore it is guaranteed that all complete callback functions
886 * for a previously submitted descriptor have finished running and it is safe to
887 * free resources accessed from within the complete callbacks.
888 *
889 * The behavior of this function is undefined if dma_async_issue_pending() has
890 * been called between dmaengine_terminate_async() and this function.
891 *
892 * This function must only be called from non-atomic context and must not be
893 * called from within a complete callback of a descriptor submitted on the same
894 * channel.
895 */
896static inline void dmaengine_synchronize(struct dma_chan *chan)
897{
898 if (chan->device->device_synchronize)
899 chan->device->device_synchronize(chan);
900}
901
902/**
903 * dmaengine_terminate_sync() - Terminate all active DMA transfers
904 * @chan: The channel for which to terminate the transfers
905 *
906 * Calling this function will terminate all active and pending transfers
907 * that have previously been submitted to the channel. It is similar to
908 * dmaengine_terminate_async() but guarantees that the DMA transfer has actually
909 * stopped and that all complete callbacks have finished running when the
910 * function returns.
911 *
912 * This function must only be called from non-atomic context and must not be
913 * called from within a complete callback of a descriptor submitted on the same
914 * channel.
915 */
916static inline int dmaengine_terminate_sync(struct dma_chan *chan)
917{
918 int ret;
919
920 ret = dmaengine_terminate_async(chan);
921 if (ret)
922 return ret;
923
924 dmaengine_synchronize(chan);
925
926 return 0;
927}
928
839static inline int dmaengine_pause(struct dma_chan *chan) 929static inline int dmaengine_pause(struct dma_chan *chan)
840{ 930{
841 if (chan->device->device_pause) 931 if (chan->device->device_pause)