Merge tag 'late-dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / dma / dmatest.c
index 64b048d..a2c8904 100644 (file)
@@ -242,6 +242,13 @@ static inline void unmap_dst(struct device *dev, dma_addr_t *addr, size_t len,
                dma_unmap_single(dev, addr[count], len, DMA_BIDIRECTIONAL);
 }
 
+static unsigned int min_odd(unsigned int x, unsigned int y)
+{
+       unsigned int val = min(x, y);
+
+       return val % 2 ? val : val - 1;
+}
+
 /*
  * This function repeatedly tests DMA transfers of various lengths and
  * offsets for a given operation type until it is told to exit by
@@ -262,6 +269,7 @@ static int dmatest_func(void *data)
        struct dmatest_thread   *thread = data;
        struct dmatest_done     done = { .wait = &done_wait };
        struct dma_chan         *chan;
+       struct dma_device       *dev;
        const char              *thread_name;
        unsigned int            src_off, dst_off, len;
        unsigned int            error_count;
@@ -283,13 +291,16 @@ static int dmatest_func(void *data)
 
        smp_rmb();
        chan = thread->chan;
+       dev = chan->device;
        if (thread->type == DMA_MEMCPY)
                src_cnt = dst_cnt = 1;
        else if (thread->type == DMA_XOR) {
-               src_cnt = xor_sources | 1; /* force odd to ensure dst = src */
+               /* force odd to ensure dst = src */
+               src_cnt = min_odd(xor_sources | 1, dev->max_xor);
                dst_cnt = 1;
        } else if (thread->type == DMA_PQ) {
-               src_cnt = pq_sources | 1; /* force odd to ensure dst = src */
+               /* force odd to ensure dst = src */
+               src_cnt = min_odd(pq_sources | 1, dma_maxpq(dev, 0));
                dst_cnt = 2;
                for (i = 0; i < src_cnt; i++)
                        pq_coefs[i] = 1;
@@ -327,7 +338,6 @@ static int dmatest_func(void *data)
 
        while (!kthread_should_stop()
               && !(iterations && total_tests >= iterations)) {
-               struct dma_device *dev = chan->device;
                struct dma_async_tx_descriptor *tx = NULL;
                dma_addr_t dma_srcs[src_cnt];
                dma_addr_t dma_dsts[dst_cnt];
@@ -526,7 +536,9 @@ err_srcs:
                        thread_name, total_tests, failed_tests, ret);
 
        /* terminate all transfers on specified channels */
-       chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+       if (ret)
+               dmaengine_terminate_all(chan);
+
        if (iterations > 0)
                while (!kthread_should_stop()) {
                        DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit);
@@ -551,7 +563,7 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
        }
 
        /* terminate all transfers on specified channels */
-       dtc->chan->device->device_control(dtc->chan, DMA_TERMINATE_ALL, 0);
+       dmaengine_terminate_all(dtc->chan);
 
        kfree(dtc);
 }