dmaengine: dmatest: Add support for completion polling
authorPeter Ujfalusi <peter.ujfalusi@ti.com>
Wed, 31 Jul 2019 07:14:38 +0000 (10:14 +0300)
committerVinod Koul <vkoul@kernel.org>
Wed, 4 Sep 2019 04:44:22 +0000 (10:14 +0530)
With the polled parameter the DMA drivers can be tested if they can work
correctly when no completion is requested (no DMA_PREP_INTERRUPT and no
callback is provided).

If polled mode is selected then use dma_sync_wait() to execute the test
iteration instead of relying on the completion callback.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Link: https://lore.kernel.org/r/20190731071438.24075-1-peter.ujfalusi@ti.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/dma/dmatest.c

index 3d22ae8..a2cadfa 100644 (file)
@@ -72,6 +72,10 @@ static bool norandom;
 module_param(norandom, bool, 0644);
 MODULE_PARM_DESC(norandom, "Disable random offset setup (default: random)");
 
+static bool polled;
+module_param(polled, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(polled, "Use polling for completion instead of interrupts");
+
 static bool verbose;
 module_param(verbose, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(verbose, "Enable \"success\" result messages (default: off)");
@@ -110,6 +114,7 @@ struct dmatest_params {
        bool            norandom;
        int             alignment;
        unsigned int    transfer_size;
+       bool            polled;
 };
 
 /**
@@ -651,7 +656,10 @@ static int dmatest_func(void *data)
        /*
         * src and dst buffers are freed by ourselves below
         */
-       flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
+       if (params->polled)
+               flags = DMA_CTRL_ACK;
+       else
+               flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
 
        ktime = ktime_get();
        while (!kthread_should_stop()
@@ -780,8 +788,10 @@ static int dmatest_func(void *data)
                }
 
                done->done = false;
-               tx->callback = dmatest_callback;
-               tx->callback_param = done;
+               if (!params->polled) {
+                       tx->callback = dmatest_callback;
+                       tx->callback_param = done;
+               }
                cookie = tx->tx_submit(tx);
 
                if (dma_submit_error(cookie)) {
@@ -790,12 +800,22 @@ static int dmatest_func(void *data)
                        msleep(100);
                        goto error_unmap_continue;
                }
-               dma_async_issue_pending(chan);
 
-               wait_event_freezable_timeout(thread->done_wait, done->done,
-                                            msecs_to_jiffies(params->timeout));
+               if (params->polled) {
+                       status = dma_sync_wait(chan, cookie);
+                       dmaengine_terminate_sync(chan);
+                       if (status == DMA_COMPLETE)
+                               done->done = true;
+               } else {
+                       dma_async_issue_pending(chan);
+
+                       wait_event_freezable_timeout(thread->done_wait,
+                                       done->done,
+                                       msecs_to_jiffies(params->timeout));
 
-               status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
+                       status = dma_async_is_tx_complete(chan, cookie, NULL,
+                                                         NULL);
+               }
 
                if (!done->done) {
                        result("test timed out", total_tests, src->off, dst->off,
@@ -1065,6 +1085,7 @@ static void add_threaded_test(struct dmatest_info *info)
        params->norandom = norandom;
        params->alignment = alignment;
        params->transfer_size = transfer_size;
+       params->polled = polled;
 
        request_channels(info, DMA_MEMCPY);
        request_channels(info, DMA_MEMSET);