mm: update get_user_pages_longterm to migrate pages allocated from CMA region
[linux-2.6-block.git] / drivers / dma / dmatest.c
CommitLineData
4a776f0a
HS
1/*
2 * DMA Engine test module
3 *
4 * Copyright (C) 2007 Atmel Corporation
851b7e16 5 * Copyright (C) 2013 Intel Corporation
4a776f0a
HS
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
872f05c6
DW
11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12
4a776f0a 13#include <linux/delay.h>
b7f080cf 14#include <linux/dma-mapping.h>
4a776f0a 15#include <linux/dmaengine.h>
981ed70d 16#include <linux/freezer.h>
4a776f0a
HS
17#include <linux/init.h>
18#include <linux/kthread.h>
0881e7bd 19#include <linux/sched/task.h>
4a776f0a
HS
20#include <linux/module.h>
21#include <linux/moduleparam.h>
22#include <linux/random.h>
5a0e3ad6 23#include <linux/slab.h>
4a776f0a
HS
24#include <linux/wait.h>
25
26static unsigned int test_buf_size = 16384;
a6c268d0 27module_param(test_buf_size, uint, S_IRUGO | S_IWUSR);
4a776f0a
HS
28MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer");
29
a85159fe 30static char test_device[32];
a6c268d0
AS
31module_param_string(device, test_device, sizeof(test_device),
32 S_IRUGO | S_IWUSR);
4a776f0a
HS
33MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)");
34
35static unsigned int threads_per_chan = 1;
a6c268d0 36module_param(threads_per_chan, uint, S_IRUGO | S_IWUSR);
4a776f0a
HS
37MODULE_PARM_DESC(threads_per_chan,
38 "Number of threads to start per channel (default: 1)");
39
40static unsigned int max_channels;
a6c268d0 41module_param(max_channels, uint, S_IRUGO | S_IWUSR);
33df8ca0 42MODULE_PARM_DESC(max_channels,
4a776f0a
HS
43 "Maximum number of channels to use (default: all)");
44
0a2ff57d 45static unsigned int iterations;
a6c268d0 46module_param(iterations, uint, S_IRUGO | S_IWUSR);
0a2ff57d
NF
47MODULE_PARM_DESC(iterations,
48 "Iterations before stopping test (default: infinite)");
49
d8646724 50static unsigned int dmatest;
a0d4cb44
KA
51module_param(dmatest, uint, S_IRUGO | S_IWUSR);
52MODULE_PARM_DESC(dmatest,
c678fa66 53 "dmatest 0-memcpy 1-memset (default: 0)");
a0d4cb44 54
b54d5cb9 55static unsigned int xor_sources = 3;
a6c268d0 56module_param(xor_sources, uint, S_IRUGO | S_IWUSR);
b54d5cb9
DW
57MODULE_PARM_DESC(xor_sources,
58 "Number of xor source buffers (default: 3)");
59
58691d64 60static unsigned int pq_sources = 3;
a6c268d0 61module_param(pq_sources, uint, S_IRUGO | S_IWUSR);
58691d64
DW
62MODULE_PARM_DESC(pq_sources,
63 "Number of p+q source buffers (default: 3)");
64
d42efe6b 65static int timeout = 3000;
a6c268d0 66module_param(timeout, uint, S_IRUGO | S_IWUSR);
85ee7a1d
JP
67MODULE_PARM_DESC(timeout, "Transfer Timeout in msec (default: 3000), "
68 "Pass -1 for infinite timeout");
d42efe6b 69
e3b9c347
DW
70static bool noverify;
71module_param(noverify, bool, S_IRUGO | S_IWUSR);
2e67a087
YS
72MODULE_PARM_DESC(noverify, "Disable data verification (default: verify)");
73
74static bool norandom;
75module_param(norandom, bool, 0644);
76MODULE_PARM_DESC(norandom, "Disable random offset setup (default: random)");
4a776f0a 77
50137a7d
DW
78static bool verbose;
79module_param(verbose, bool, S_IRUGO | S_IWUSR);
80MODULE_PARM_DESC(verbose, "Enable \"success\" result messages (default: off)");
4a776f0a 81
a875abfa
SA
82static int alignment = -1;
83module_param(alignment, int, 0644);
84MODULE_PARM_DESC(alignment, "Custom data address alignment taken as 2^(alignment) (default: not used (-1))");
85
13396a13
SA
86static unsigned int transfer_size;
87module_param(transfer_size, uint, 0644);
88MODULE_PARM_DESC(transfer_size, "Optional custom transfer size in bytes (default: not used (0))");
89
e03e93a9 90/**
15b8a8ea 91 * struct dmatest_params - test parameters.
e03e93a9
AS
92 * @buf_size: size of the memcpy test buffer
93 * @channel: bus ID of the channel to test
94 * @device: bus ID of the DMA Engine to test
95 * @threads_per_chan: number of threads to start per channel
96 * @max_channels: maximum number of channels to use
97 * @iterations: iterations before stopping test
98 * @xor_sources: number of xor source buffers
99 * @pq_sources: number of p+q source buffers
100 * @timeout: transfer timeout in msec, -1 for infinite timeout
101 */
15b8a8ea 102struct dmatest_params {
e03e93a9
AS
103 unsigned int buf_size;
104 char channel[20];
a85159fe 105 char device[32];
e03e93a9
AS
106 unsigned int threads_per_chan;
107 unsigned int max_channels;
108 unsigned int iterations;
109 unsigned int xor_sources;
110 unsigned int pq_sources;
111 int timeout;
e3b9c347 112 bool noverify;
2e67a087 113 bool norandom;
a875abfa 114 int alignment;
13396a13 115 unsigned int transfer_size;
15b8a8ea
AS
116};
117
118/**
119 * struct dmatest_info - test information.
120 * @params: test parameters
851b7e16 121 * @lock: access protection to the fields of this structure
15b8a8ea 122 */
a310d037 123static struct dmatest_info {
15b8a8ea
AS
124 /* Test parameters */
125 struct dmatest_params params;
838cc704
AS
126
127 /* Internal state */
128 struct list_head channels;
129 unsigned int nr_channels;
851b7e16 130 struct mutex lock;
a310d037
DW
131 bool did_init;
132} test_info = {
133 .channels = LIST_HEAD_INIT(test_info.channels),
134 .lock = __MUTEX_INITIALIZER(test_info.lock),
135};
851b7e16 136
a310d037
DW
137static int dmatest_run_set(const char *val, const struct kernel_param *kp);
138static int dmatest_run_get(char *val, const struct kernel_param *kp);
9c27847d 139static const struct kernel_param_ops run_ops = {
a310d037
DW
140 .set = dmatest_run_set,
141 .get = dmatest_run_get,
e03e93a9 142};
a310d037
DW
143static bool dmatest_run;
144module_param_cb(run, &run_ops, &dmatest_run, S_IRUGO | S_IWUSR);
145MODULE_PARM_DESC(run, "Run the test (default: false)");
e03e93a9 146
d53513d5
SA
147static int dmatest_chan_set(const char *val, const struct kernel_param *kp);
148static int dmatest_chan_get(char *val, const struct kernel_param *kp);
149static const struct kernel_param_ops multi_chan_ops = {
150 .set = dmatest_chan_set,
151 .get = dmatest_chan_get,
152};
153
154static char test_channel[20];
155static struct kparam_string newchan_kps = {
156 .string = test_channel,
157 .maxlen = 20,
158};
159module_param_cb(channel, &multi_chan_ops, &newchan_kps, 0644);
160MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)");
161
162static int dmatest_test_list_get(char *val, const struct kernel_param *kp);
163static const struct kernel_param_ops test_list_ops = {
164 .get = dmatest_test_list_get,
165};
166module_param_cb(test_list, &test_list_ops, NULL, 0444);
167MODULE_PARM_DESC(test_list, "Print current test list");
168
a310d037
DW
169/* Maximum amount of mismatched bytes in buffer to print */
170#define MAX_ERROR_COUNT 32
171
172/*
173 * Initialization patterns. All bytes in the source buffer has bit 7
174 * set, all bytes in the destination buffer has bit 7 cleared.
175 *
176 * Bit 6 is set for all bytes which are to be copied by the DMA
177 * engine. Bit 5 is set for all bytes which are to be overwritten by
178 * the DMA engine.
179 *
180 * The remaining bits are the inverse of a counter which increments by
181 * one for each byte address.
182 */
183#define PATTERN_SRC 0x80
184#define PATTERN_DST 0x00
185#define PATTERN_COPY 0x40
186#define PATTERN_OVERWRITE 0x20
187#define PATTERN_COUNT_MASK 0x1f
61b5f54d 188#define PATTERN_MEMSET_IDX 0x01
851b7e16 189
6138f967
SA
190/* Fixed point arithmetic ops */
191#define FIXPT_SHIFT 8
192#define FIXPNT_MASK 0xFF
193#define FIXPT_TO_INT(a) ((a) >> FIXPT_SHIFT)
194#define INT_TO_FIXPT(a) ((a) << FIXPT_SHIFT)
195#define FIXPT_GET_FRAC(a) ((((a) & FIXPNT_MASK) * 100) >> FIXPT_SHIFT)
196
6f6a23a2
AW
197/* poor man's completion - we want to use wait_event_freezable() on it */
198struct dmatest_done {
199 bool done;
200 wait_queue_head_t *wait;
201};
202
a310d037
DW
203struct dmatest_thread {
204 struct list_head node;
205 struct dmatest_info *info;
206 struct task_struct *task;
207 struct dma_chan *chan;
208 u8 **srcs;
d6481608 209 u8 **usrcs;
a310d037 210 u8 **dsts;
d6481608 211 u8 **udsts;
a310d037 212 enum dma_transaction_type type;
6f6a23a2
AW
213 wait_queue_head_t done_wait;
214 struct dmatest_done test_done;
a310d037 215 bool done;
d53513d5 216 bool pending;
a310d037 217};
95019c8c 218
a310d037
DW
219struct dmatest_chan {
220 struct list_head node;
221 struct dma_chan *chan;
222 struct list_head threads;
e03e93a9
AS
223};
224
2d88ce76
DW
225static DECLARE_WAIT_QUEUE_HEAD(thread_wait);
226static bool wait;
227
228static bool is_threaded_test_run(struct dmatest_info *info)
229{
230 struct dmatest_chan *dtc;
231
232 list_for_each_entry(dtc, &info->channels, node) {
233 struct dmatest_thread *thread;
234
235 list_for_each_entry(thread, &dtc->threads, node) {
236 if (!thread->done)
237 return true;
238 }
239 }
240
241 return false;
242}
243
d53513d5
SA
244static bool is_threaded_test_pending(struct dmatest_info *info)
245{
246 struct dmatest_chan *dtc;
247
248 list_for_each_entry(dtc, &info->channels, node) {
249 struct dmatest_thread *thread;
250
251 list_for_each_entry(thread, &dtc->threads, node) {
252 if (thread->pending)
253 return true;
254 }
255 }
256
257 return false;
258}
259
2d88ce76
DW
260static int dmatest_wait_get(char *val, const struct kernel_param *kp)
261{
262 struct dmatest_info *info = &test_info;
263 struct dmatest_params *params = &info->params;
264
265 if (params->iterations)
266 wait_event(thread_wait, !is_threaded_test_run(info));
267 wait = true;
268 return param_get_bool(val, kp);
269}
270
9c27847d 271static const struct kernel_param_ops wait_ops = {
2d88ce76
DW
272 .get = dmatest_wait_get,
273 .set = param_set_bool,
274};
275module_param_cb(wait, &wait_ops, &wait, S_IRUGO);
276MODULE_PARM_DESC(wait, "Wait for tests to complete (default: false)");
e03e93a9 277
15b8a8ea 278static bool dmatest_match_channel(struct dmatest_params *params,
e03e93a9 279 struct dma_chan *chan)
4a776f0a 280{
15b8a8ea 281 if (params->channel[0] == '\0')
4a776f0a 282 return true;
15b8a8ea 283 return strcmp(dma_chan_name(chan), params->channel) == 0;
4a776f0a
HS
284}
285
15b8a8ea 286static bool dmatest_match_device(struct dmatest_params *params,
e03e93a9 287 struct dma_device *device)
4a776f0a 288{
15b8a8ea 289 if (params->device[0] == '\0')
4a776f0a 290 return true;
15b8a8ea 291 return strcmp(dev_name(device->dev), params->device) == 0;
4a776f0a
HS
292}
293
294static unsigned long dmatest_random(void)
295{
296 unsigned long buf;
297
be9fa5a4 298 prandom_bytes(&buf, sizeof(buf));
4a776f0a
HS
299 return buf;
300}
301
61b5f54d
SK
302static inline u8 gen_inv_idx(u8 index, bool is_memset)
303{
304 u8 val = is_memset ? PATTERN_MEMSET_IDX : index;
305
306 return ~val & PATTERN_COUNT_MASK;
307}
308
309static inline u8 gen_src_value(u8 index, bool is_memset)
310{
311 return PATTERN_SRC | gen_inv_idx(index, is_memset);
312}
313
314static inline u8 gen_dst_value(u8 index, bool is_memset)
315{
316 return PATTERN_DST | gen_inv_idx(index, is_memset);
317}
318
e03e93a9 319static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len,
61b5f54d 320 unsigned int buf_size, bool is_memset)
4a776f0a
HS
321{
322 unsigned int i;
b54d5cb9
DW
323 u8 *buf;
324
325 for (; (buf = *bufs); bufs++) {
326 for (i = 0; i < start; i++)
61b5f54d 327 buf[i] = gen_src_value(i, is_memset);
b54d5cb9 328 for ( ; i < start + len; i++)
61b5f54d 329 buf[i] = gen_src_value(i, is_memset) | PATTERN_COPY;
e03e93a9 330 for ( ; i < buf_size; i++)
61b5f54d 331 buf[i] = gen_src_value(i, is_memset);
b54d5cb9
DW
332 buf++;
333 }
4a776f0a
HS
334}
335
e03e93a9 336static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len,
61b5f54d 337 unsigned int buf_size, bool is_memset)
4a776f0a
HS
338{
339 unsigned int i;
b54d5cb9
DW
340 u8 *buf;
341
342 for (; (buf = *bufs); bufs++) {
343 for (i = 0; i < start; i++)
61b5f54d 344 buf[i] = gen_dst_value(i, is_memset);
b54d5cb9 345 for ( ; i < start + len; i++)
61b5f54d
SK
346 buf[i] = gen_dst_value(i, is_memset) |
347 PATTERN_OVERWRITE;
e03e93a9 348 for ( ; i < buf_size; i++)
61b5f54d 349 buf[i] = gen_dst_value(i, is_memset);
b54d5cb9 350 }
4a776f0a
HS
351}
352
7b610178 353static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
61b5f54d 354 unsigned int counter, bool is_srcbuf, bool is_memset)
7b610178
DW
355{
356 u8 diff = actual ^ pattern;
61b5f54d 357 u8 expected = pattern | gen_inv_idx(counter, is_memset);
7b610178
DW
358 const char *thread_name = current->comm;
359
360 if (is_srcbuf)
361 pr_warn("%s: srcbuf[0x%x] overwritten! Expected %02x, got %02x\n",
362 thread_name, index, expected, actual);
363 else if ((pattern & PATTERN_COPY)
364 && (diff & (PATTERN_COPY | PATTERN_OVERWRITE)))
365 pr_warn("%s: dstbuf[0x%x] not copied! Expected %02x, got %02x\n",
366 thread_name, index, expected, actual);
367 else if (diff & PATTERN_SRC)
368 pr_warn("%s: dstbuf[0x%x] was copied! Expected %02x, got %02x\n",
369 thread_name, index, expected, actual);
370 else
371 pr_warn("%s: dstbuf[0x%x] mismatch! Expected %02x, got %02x\n",
372 thread_name, index, expected, actual);
373}
374
375static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
376 unsigned int end, unsigned int counter, u8 pattern,
61b5f54d 377 bool is_srcbuf, bool is_memset)
4a776f0a
HS
378{
379 unsigned int i;
380 unsigned int error_count = 0;
381 u8 actual;
b54d5cb9
DW
382 u8 expected;
383 u8 *buf;
384 unsigned int counter_orig = counter;
385
386 for (; (buf = *bufs); bufs++) {
387 counter = counter_orig;
388 for (i = start; i < end; i++) {
389 actual = buf[i];
61b5f54d 390 expected = pattern | gen_inv_idx(counter, is_memset);
b54d5cb9 391 if (actual != expected) {
7b610178
DW
392 if (error_count < MAX_ERROR_COUNT)
393 dmatest_mismatch(actual, pattern, i,
61b5f54d
SK
394 counter, is_srcbuf,
395 is_memset);
b54d5cb9
DW
396 error_count++;
397 }
398 counter++;
4a776f0a 399 }
4a776f0a
HS
400 }
401
74b5c07a 402 if (error_count > MAX_ERROR_COUNT)
7b610178 403 pr_warn("%s: %u errors suppressed\n",
74b5c07a 404 current->comm, error_count - MAX_ERROR_COUNT);
4a776f0a
HS
405
406 return error_count;
407}
408
adfa543e
TH
409
410static void dmatest_callback(void *arg)
e44e0aa3 411{
adfa543e 412 struct dmatest_done *done = arg;
6f6a23a2 413 struct dmatest_thread *thread =
66b3bd23 414 container_of(done, struct dmatest_thread, test_done);
6f6a23a2
AW
415 if (!thread->done) {
416 done->done = true;
417 wake_up_all(done->wait);
418 } else {
419 /*
420 * If thread->done, it means that this callback occurred
421 * after the parent thread has cleaned up. This can
422 * happen in the case that driver doesn't implement
423 * the terminate_all() functionality and a dma operation
424 * did not occur within the timeout period
425 */
426 WARN(1, "dmatest: Kernel memory may be corrupted!!\n");
427 }
e44e0aa3
DW
428}
429
8be9e32b
AM
430static unsigned int min_odd(unsigned int x, unsigned int y)
431{
432 unsigned int val = min(x, y);
433
434 return val % 2 ? val : val - 1;
435}
436
872f05c6
DW
437static void result(const char *err, unsigned int n, unsigned int src_off,
438 unsigned int dst_off, unsigned int len, unsigned long data)
d86b2f29 439{
2acec150 440 pr_info("%s: result #%u: '%s' with src_off=0x%x dst_off=0x%x len=0x%x (%lu)\n",
872f05c6 441 current->comm, n, err, src_off, dst_off, len, data);
d86b2f29
AS
442}
443
872f05c6
DW
444static void dbg_result(const char *err, unsigned int n, unsigned int src_off,
445 unsigned int dst_off, unsigned int len,
446 unsigned long data)
95019c8c 447{
2acec150 448 pr_debug("%s: result #%u: '%s' with src_off=0x%x dst_off=0x%x len=0x%x (%lu)\n",
a835bb85 449 current->comm, n, err, src_off, dst_off, len, data);
95019c8c
AS
450}
451
a835bb85
AS
452#define verbose_result(err, n, src_off, dst_off, len, data) ({ \
453 if (verbose) \
454 result(err, n, src_off, dst_off, len, data); \
455 else \
456 dbg_result(err, n, src_off, dst_off, len, data);\
50137a7d 457})
95019c8c 458
86727443 459static unsigned long long dmatest_persec(s64 runtime, unsigned int val)
d86b2f29 460{
86727443 461 unsigned long long per_sec = 1000000;
d86b2f29 462
86727443
DW
463 if (runtime <= 0)
464 return 0;
95019c8c 465
86727443
DW
466 /* drop precision until runtime is 32-bits */
467 while (runtime > UINT_MAX) {
468 runtime >>= 1;
469 per_sec <<= 1;
95019c8c
AS
470 }
471
86727443 472 per_sec *= val;
6138f967 473 per_sec = INT_TO_FIXPT(per_sec);
86727443 474 do_div(per_sec, runtime);
6138f967 475
86727443 476 return per_sec;
95019c8c
AS
477}
478
86727443 479static unsigned long long dmatest_KBs(s64 runtime, unsigned long long len)
95019c8c 480{
6138f967 481 return FIXPT_TO_INT(dmatest_persec(runtime, len >> 10));
95019c8c
AS
482}
483
4a776f0a
HS
484/*
485 * This function repeatedly tests DMA transfers of various lengths and
b54d5cb9
DW
486 * offsets for a given operation type until it is told to exit by
487 * kthread_stop(). There may be multiple threads running this function
488 * in parallel for a single channel, and there may be multiple channels
489 * being tested in parallel.
4a776f0a
HS
490 *
491 * Before each test, the source and destination buffer is initialized
492 * with a known pattern. This pattern is different depending on
493 * whether it's in an area which is supposed to be copied or
494 * overwritten, and different in the source and destination buffers.
495 * So if the DMA engine doesn't copy exactly what we tell it to copy,
496 * we'll notice.
497 */
498static int dmatest_func(void *data)
499{
500 struct dmatest_thread *thread = data;
6f6a23a2 501 struct dmatest_done *done = &thread->test_done;
e03e93a9 502 struct dmatest_info *info;
15b8a8ea 503 struct dmatest_params *params;
4a776f0a 504 struct dma_chan *chan;
8be9e32b 505 struct dma_device *dev;
4a776f0a
HS
506 unsigned int error_count;
507 unsigned int failed_tests = 0;
508 unsigned int total_tests = 0;
509 dma_cookie_t cookie;
510 enum dma_status status;
b54d5cb9 511 enum dma_ctrl_flags flags;
945b5af3 512 u8 *pq_coefs = NULL;
4a776f0a 513 int ret;
b54d5cb9
DW
514 int src_cnt;
515 int dst_cnt;
516 int i;
e9405ef0 517 ktime_t ktime, start, diff;
8b0e1953
TG
518 ktime_t filltime = 0;
519 ktime_t comparetime = 0;
86727443
DW
520 s64 runtime = 0;
521 unsigned long long total_len = 0;
6138f967 522 unsigned long long iops = 0;
d6481608 523 u8 align = 0;
61b5f54d 524 bool is_memset = false;
72ef08bf
LA
525 dma_addr_t *srcs;
526 dma_addr_t *dma_pq;
4a776f0a 527
adfa543e 528 set_freezable();
4a776f0a
HS
529
530 ret = -ENOMEM;
4a776f0a
HS
531
532 smp_rmb();
d53513d5 533 thread->pending = false;
e03e93a9 534 info = thread->info;
15b8a8ea 535 params = &info->params;
4a776f0a 536 chan = thread->chan;
8be9e32b 537 dev = chan->device;
d6481608 538 if (thread->type == DMA_MEMCPY) {
a875abfa
SA
539 align = params->alignment < 0 ? dev->copy_align :
540 params->alignment;
b54d5cb9 541 src_cnt = dst_cnt = 1;
61b5f54d 542 } else if (thread->type == DMA_MEMSET) {
a875abfa
SA
543 align = params->alignment < 0 ? dev->fill_align :
544 params->alignment;
61b5f54d
SK
545 src_cnt = dst_cnt = 1;
546 is_memset = true;
d6481608 547 } else if (thread->type == DMA_XOR) {
8be9e32b 548 /* force odd to ensure dst = src */
15b8a8ea 549 src_cnt = min_odd(params->xor_sources | 1, dev->max_xor);
b54d5cb9 550 dst_cnt = 1;
a875abfa
SA
551 align = params->alignment < 0 ? dev->xor_align :
552 params->alignment;
58691d64 553 } else if (thread->type == DMA_PQ) {
8be9e32b 554 /* force odd to ensure dst = src */
15b8a8ea 555 src_cnt = min_odd(params->pq_sources | 1, dma_maxpq(dev, 0));
58691d64 556 dst_cnt = 2;
a875abfa
SA
557 align = params->alignment < 0 ? dev->pq_align :
558 params->alignment;
945b5af3 559
31d18257 560 pq_coefs = kmalloc(params->pq_sources + 1, GFP_KERNEL);
945b5af3
AS
561 if (!pq_coefs)
562 goto err_thread_type;
563
94de648d 564 for (i = 0; i < src_cnt; i++)
58691d64 565 pq_coefs[i] = 1;
b54d5cb9 566 } else
945b5af3 567 goto err_thread_type;
b54d5cb9 568
787d3083
AA
569 /* Check if buffer count fits into map count variable (u8) */
570 if ((src_cnt + dst_cnt) >= 255) {
571 pr_err("too many buffers (%d of 255 supported)\n",
572 src_cnt + dst_cnt);
3f3c7554 573 goto err_free_coefs;
787d3083
AA
574 }
575
576 if (1 << align > params->buf_size) {
577 pr_err("%u-byte buffer too small for %d-byte alignment\n",
578 params->buf_size, 1 << align);
3f3c7554 579 goto err_free_coefs;
787d3083
AA
580 }
581
31d18257 582 thread->srcs = kcalloc(src_cnt + 1, sizeof(u8 *), GFP_KERNEL);
b54d5cb9 583 if (!thread->srcs)
3f3c7554 584 goto err_free_coefs;
d6481608
DJ
585
586 thread->usrcs = kcalloc(src_cnt + 1, sizeof(u8 *), GFP_KERNEL);
587 if (!thread->usrcs)
588 goto err_usrcs;
589
b54d5cb9 590 for (i = 0; i < src_cnt; i++) {
d6481608
DJ
591 thread->usrcs[i] = kmalloc(params->buf_size + align,
592 GFP_KERNEL);
593 if (!thread->usrcs[i])
b54d5cb9 594 goto err_srcbuf;
d6481608
DJ
595
596 /* align srcs to alignment restriction */
597 if (align)
598 thread->srcs[i] = PTR_ALIGN(thread->usrcs[i], align);
599 else
600 thread->srcs[i] = thread->usrcs[i];
b54d5cb9
DW
601 }
602 thread->srcs[i] = NULL;
603
31d18257 604 thread->dsts = kcalloc(dst_cnt + 1, sizeof(u8 *), GFP_KERNEL);
b54d5cb9
DW
605 if (!thread->dsts)
606 goto err_dsts;
d6481608
DJ
607
608 thread->udsts = kcalloc(dst_cnt + 1, sizeof(u8 *), GFP_KERNEL);
609 if (!thread->udsts)
610 goto err_udsts;
611
b54d5cb9 612 for (i = 0; i < dst_cnt; i++) {
d6481608
DJ
613 thread->udsts[i] = kmalloc(params->buf_size + align,
614 GFP_KERNEL);
615 if (!thread->udsts[i])
b54d5cb9 616 goto err_dstbuf;
d6481608
DJ
617
618 /* align dsts to alignment restriction */
619 if (align)
620 thread->dsts[i] = PTR_ALIGN(thread->udsts[i], align);
621 else
622 thread->dsts[i] = thread->udsts[i];
b54d5cb9
DW
623 }
624 thread->dsts[i] = NULL;
625
e44e0aa3
DW
626 set_user_nice(current, 10);
627
72ef08bf
LA
628 srcs = kcalloc(src_cnt, sizeof(dma_addr_t), GFP_KERNEL);
629 if (!srcs)
630 goto err_dstbuf;
631
632 dma_pq = kcalloc(dst_cnt, sizeof(dma_addr_t), GFP_KERNEL);
633 if (!dma_pq)
634 goto err_srcs_array;
635
b203bd3f 636 /*
d1cab34c 637 * src and dst buffers are freed by ourselves below
b203bd3f 638 */
0776ae7b 639 flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
4a776f0a 640
86727443 641 ktime = ktime_get();
0a2ff57d 642 while (!kthread_should_stop()
15b8a8ea 643 && !(params->iterations && total_tests >= params->iterations)) {
b54d5cb9 644 struct dma_async_tx_descriptor *tx = NULL;
4076e755 645 struct dmaengine_unmap_data *um;
4076e755 646 dma_addr_t *dsts;
ede23a58 647 unsigned int src_off, dst_off, len;
d86be86e 648
4a776f0a
HS
649 total_tests++;
650
13396a13
SA
651 if (params->transfer_size) {
652 if (params->transfer_size >= params->buf_size) {
653 pr_err("%u-byte transfer size must be lower than %u-buffer size\n",
654 params->transfer_size, params->buf_size);
655 break;
656 }
657 len = params->transfer_size;
658 } else if (params->norandom) {
e3b9c347 659 len = params->buf_size;
13396a13 660 } else {
ede23a58 661 len = dmatest_random() % params->buf_size + 1;
13396a13 662 }
ede23a58 663
13396a13
SA
664 /* Do not alter transfer size explicitly defined by user */
665 if (!params->transfer_size) {
666 len = (len >> align) << align;
667 if (!len)
668 len = 1 << align;
669 }
ede23a58
AS
670 total_len += len;
671
2e67a087 672 if (params->norandom) {
e3b9c347
DW
673 src_off = 0;
674 dst_off = 0;
675 } else {
e3b9c347
DW
676 src_off = dmatest_random() % (params->buf_size - len + 1);
677 dst_off = dmatest_random() % (params->buf_size - len + 1);
678
679 src_off = (src_off >> align) << align;
680 dst_off = (dst_off >> align) << align;
2e67a087 681 }
e3b9c347 682
2e67a087
YS
683 if (!params->noverify) {
684 start = ktime_get();
e3b9c347 685 dmatest_init_srcs(thread->srcs, src_off, len,
61b5f54d 686 params->buf_size, is_memset);
e3b9c347 687 dmatest_init_dsts(thread->dsts, dst_off, len,
61b5f54d 688 params->buf_size, is_memset);
e9405ef0
SK
689
690 diff = ktime_sub(ktime_get(), start);
691 filltime = ktime_add(filltime, diff);
e3b9c347
DW
692 }
693
31d18257 694 um = dmaengine_get_unmap_data(dev->dev, src_cnt + dst_cnt,
4076e755
DW
695 GFP_KERNEL);
696 if (!um) {
697 failed_tests++;
698 result("unmap data NULL", total_tests,
699 src_off, dst_off, len, ret);
700 continue;
701 }
4a776f0a 702
4076e755 703 um->len = params->buf_size;
b54d5cb9 704 for (i = 0; i < src_cnt; i++) {
745c00da 705 void *buf = thread->srcs[i];
4076e755 706 struct page *pg = virt_to_page(buf);
f62e5f61 707 unsigned long pg_off = offset_in_page(buf);
4076e755
DW
708
709 um->addr[i] = dma_map_page(dev->dev, pg, pg_off,
710 um->len, DMA_TO_DEVICE);
711 srcs[i] = um->addr[i] + src_off;
712 ret = dma_mapping_error(dev->dev, um->addr[i]);
afde3be1 713 if (ret) {
872f05c6
DW
714 result("src mapping error", total_tests,
715 src_off, dst_off, len, ret);
6454368a 716 goto error_unmap_continue;
afde3be1 717 }
4076e755 718 um->to_cnt++;
b54d5cb9 719 }
d86be86e 720 /* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
4076e755 721 dsts = &um->addr[src_cnt];
b54d5cb9 722 for (i = 0; i < dst_cnt; i++) {
745c00da 723 void *buf = thread->dsts[i];
4076e755 724 struct page *pg = virt_to_page(buf);
f62e5f61 725 unsigned long pg_off = offset_in_page(buf);
4076e755
DW
726
727 dsts[i] = dma_map_page(dev->dev, pg, pg_off, um->len,
728 DMA_BIDIRECTIONAL);
729 ret = dma_mapping_error(dev->dev, dsts[i]);
afde3be1 730 if (ret) {
872f05c6
DW
731 result("dst mapping error", total_tests,
732 src_off, dst_off, len, ret);
6454368a 733 goto error_unmap_continue;
afde3be1 734 }
4076e755 735 um->bidi_cnt++;
b54d5cb9
DW
736 }
737
738 if (thread->type == DMA_MEMCPY)
739 tx = dev->device_prep_dma_memcpy(chan,
4076e755
DW
740 dsts[0] + dst_off,
741 srcs[0], len, flags);
61b5f54d
SK
742 else if (thread->type == DMA_MEMSET)
743 tx = dev->device_prep_dma_memset(chan,
744 dsts[0] + dst_off,
745 *(thread->srcs[0] + src_off),
746 len, flags);
b54d5cb9
DW
747 else if (thread->type == DMA_XOR)
748 tx = dev->device_prep_dma_xor(chan,
4076e755
DW
749 dsts[0] + dst_off,
750 srcs, src_cnt,
b54d5cb9 751 len, flags);
58691d64 752 else if (thread->type == DMA_PQ) {
58691d64 753 for (i = 0; i < dst_cnt; i++)
4076e755
DW
754 dma_pq[i] = dsts[i] + dst_off;
755 tx = dev->device_prep_dma_pq(chan, dma_pq, srcs,
94de648d 756 src_cnt, pq_coefs,
58691d64
DW
757 len, flags);
758 }
d86be86e 759
d86be86e 760 if (!tx) {
872f05c6
DW
761 result("prep error", total_tests, src_off,
762 dst_off, len, ret);
d86be86e 763 msleep(100);
6454368a 764 goto error_unmap_continue;
d86be86e 765 }
e44e0aa3 766
6f6a23a2 767 done->done = false;
e44e0aa3 768 tx->callback = dmatest_callback;
6f6a23a2 769 tx->callback_param = done;
d86be86e
AN
770 cookie = tx->tx_submit(tx);
771
4a776f0a 772 if (dma_submit_error(cookie)) {
872f05c6
DW
773 result("submit error", total_tests, src_off,
774 dst_off, len, ret);
4a776f0a 775 msleep(100);
6454368a 776 goto error_unmap_continue;
4a776f0a 777 }
b54d5cb9 778 dma_async_issue_pending(chan);
4a776f0a 779
6f6a23a2 780 wait_event_freezable_timeout(thread->done_wait, done->done,
15b8a8ea 781 msecs_to_jiffies(params->timeout));
981ed70d 782
e44e0aa3 783 status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
4a776f0a 784
6f6a23a2 785 if (!done->done) {
872f05c6
DW
786 result("test timed out", total_tests, src_off, dst_off,
787 len, 0);
6454368a 788 goto error_unmap_continue;
19e9f99f 789 } else if (status != DMA_COMPLETE) {
872f05c6
DW
790 result(status == DMA_ERROR ?
791 "completion error status" :
792 "completion busy status", total_tests, src_off,
793 dst_off, len, ret);
6454368a 794 goto error_unmap_continue;
4a776f0a 795 }
e44e0aa3 796
6454368a
AS
797 dmaengine_unmap_put(um);
798
e3b9c347 799 if (params->noverify) {
50137a7d
DW
800 verbose_result("test passed", total_tests, src_off,
801 dst_off, len, 0);
e3b9c347
DW
802 continue;
803 }
4a776f0a 804
e9405ef0 805 start = ktime_get();
872f05c6 806 pr_debug("%s: verifying source buffer...\n", current->comm);
e3b9c347 807 error_count = dmatest_verify(thread->srcs, 0, src_off,
61b5f54d 808 0, PATTERN_SRC, true, is_memset);
7b610178
DW
809 error_count += dmatest_verify(thread->srcs, src_off,
810 src_off + len, src_off,
61b5f54d 811 PATTERN_SRC | PATTERN_COPY, true, is_memset);
7b610178
DW
812 error_count += dmatest_verify(thread->srcs, src_off + len,
813 params->buf_size, src_off + len,
61b5f54d 814 PATTERN_SRC, true, is_memset);
7b610178 815
872f05c6 816 pr_debug("%s: verifying dest buffer...\n", current->comm);
7b610178 817 error_count += dmatest_verify(thread->dsts, 0, dst_off,
61b5f54d
SK
818 0, PATTERN_DST, false, is_memset);
819
7b610178
DW
820 error_count += dmatest_verify(thread->dsts, dst_off,
821 dst_off + len, src_off,
61b5f54d
SK
822 PATTERN_SRC | PATTERN_COPY, false, is_memset);
823
7b610178
DW
824 error_count += dmatest_verify(thread->dsts, dst_off + len,
825 params->buf_size, dst_off + len,
61b5f54d 826 PATTERN_DST, false, is_memset);
4a776f0a 827
e9405ef0
SK
828 diff = ktime_sub(ktime_get(), start);
829 comparetime = ktime_add(comparetime, diff);
830
4a776f0a 831 if (error_count) {
872f05c6
DW
832 result("data error", total_tests, src_off, dst_off,
833 len, error_count);
4a776f0a
HS
834 failed_tests++;
835 } else {
50137a7d
DW
836 verbose_result("test passed", total_tests, src_off,
837 dst_off, len, 0);
4a776f0a 838 }
6454368a
AS
839
840 continue;
841
842error_unmap_continue:
843 dmaengine_unmap_put(um);
844 failed_tests++;
4a776f0a 845 }
e9405ef0
SK
846 ktime = ktime_sub(ktime_get(), ktime);
847 ktime = ktime_sub(ktime, comparetime);
848 ktime = ktime_sub(ktime, filltime);
849 runtime = ktime_to_us(ktime);
4a776f0a
HS
850
851 ret = 0;
72ef08bf
LA
852 kfree(dma_pq);
853err_srcs_array:
854 kfree(srcs);
8e1f50d7 855err_dstbuf:
d6481608
DJ
856 for (i = 0; thread->udsts[i]; i++)
857 kfree(thread->udsts[i]);
858 kfree(thread->udsts);
859err_udsts:
b54d5cb9
DW
860 kfree(thread->dsts);
861err_dsts:
8e1f50d7 862err_srcbuf:
d6481608
DJ
863 for (i = 0; thread->usrcs[i]; i++)
864 kfree(thread->usrcs[i]);
865 kfree(thread->usrcs);
866err_usrcs:
b54d5cb9 867 kfree(thread->srcs);
3f3c7554 868err_free_coefs:
945b5af3
AS
869 kfree(pq_coefs);
870err_thread_type:
6138f967
SA
871 iops = dmatest_persec(runtime, total_tests);
872 pr_info("%s: summary %u tests, %u failures %llu.%02llu iops %llu KB/s (%d)\n",
86727443 873 current->comm, total_tests, failed_tests,
6138f967 874 FIXPT_TO_INT(iops), FIXPT_GET_FRAC(iops),
86727443 875 dmatest_KBs(runtime, total_len), ret);
0a2ff57d 876
9704efaa 877 /* terminate all transfers on specified channels */
6f6a23a2 878 if (ret || failed_tests)
fbffb6b4 879 dmaengine_terminate_sync(chan);
5e034f7b 880
3e5ccd86 881 thread->done = true;
2d88ce76 882 wake_up(&thread_wait);
0a2ff57d 883
4a776f0a
HS
884 return ret;
885}
886
887static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
888{
889 struct dmatest_thread *thread;
890 struct dmatest_thread *_thread;
891 int ret;
892
893 list_for_each_entry_safe(thread, _thread, &dtc->threads, node) {
894 ret = kthread_stop(thread->task);
0adff800
DW
895 pr_debug("thread %s exited with status %d\n",
896 thread->task->comm, ret);
4a776f0a 897 list_del(&thread->node);
2d88ce76 898 put_task_struct(thread->task);
4a776f0a
HS
899 kfree(thread);
900 }
9704efaa
VK
901
902 /* terminate all transfers on specified channels */
fbffb6b4 903 dmaengine_terminate_sync(dtc->chan);
9704efaa 904
4a776f0a
HS
905 kfree(dtc);
906}
907
e03e93a9
AS
908static int dmatest_add_threads(struct dmatest_info *info,
909 struct dmatest_chan *dtc, enum dma_transaction_type type)
4a776f0a 910{
15b8a8ea 911 struct dmatest_params *params = &info->params;
b54d5cb9
DW
912 struct dmatest_thread *thread;
913 struct dma_chan *chan = dtc->chan;
914 char *op;
915 unsigned int i;
4a776f0a 916
b54d5cb9
DW
917 if (type == DMA_MEMCPY)
918 op = "copy";
61b5f54d
SK
919 else if (type == DMA_MEMSET)
920 op = "set";
b54d5cb9
DW
921 else if (type == DMA_XOR)
922 op = "xor";
58691d64
DW
923 else if (type == DMA_PQ)
924 op = "pq";
b54d5cb9
DW
925 else
926 return -EINVAL;
4a776f0a 927
15b8a8ea 928 for (i = 0; i < params->threads_per_chan; i++) {
4a776f0a
HS
929 thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL);
930 if (!thread) {
0adff800
DW
931 pr_warn("No memory for %s-%s%u\n",
932 dma_chan_name(chan), op, i);
4a776f0a
HS
933 break;
934 }
e03e93a9 935 thread->info = info;
4a776f0a 936 thread->chan = dtc->chan;
b54d5cb9 937 thread->type = type;
6f6a23a2
AW
938 thread->test_done.wait = &thread->done_wait;
939 init_waitqueue_head(&thread->done_wait);
4a776f0a 940 smp_wmb();
2d88ce76 941 thread->task = kthread_create(dmatest_func, thread, "%s-%s%u",
b54d5cb9 942 dma_chan_name(chan), op, i);
4a776f0a 943 if (IS_ERR(thread->task)) {
2d88ce76 944 pr_warn("Failed to create thread %s-%s%u\n",
0adff800 945 dma_chan_name(chan), op, i);
4a776f0a
HS
946 kfree(thread);
947 break;
948 }
949
950 /* srcbuf and dstbuf are allocated by the thread itself */
2d88ce76 951 get_task_struct(thread->task);
4a776f0a 952 list_add_tail(&thread->node, &dtc->threads);
d53513d5 953 thread->pending = true;
4a776f0a
HS
954 }
955
b54d5cb9
DW
956 return i;
957}
958
e03e93a9
AS
959static int dmatest_add_channel(struct dmatest_info *info,
960 struct dma_chan *chan)
b54d5cb9
DW
961{
962 struct dmatest_chan *dtc;
963 struct dma_device *dma_dev = chan->device;
964 unsigned int thread_count = 0;
b9033e68 965 int cnt;
b54d5cb9
DW
966
967 dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
968 if (!dtc) {
0adff800 969 pr_warn("No memory for %s\n", dma_chan_name(chan));
b54d5cb9
DW
970 return -ENOMEM;
971 }
972
973 dtc->chan = chan;
974 INIT_LIST_HEAD(&dtc->threads);
975
976 if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
a0d4cb44
KA
977 if (dmatest == 0) {
978 cnt = dmatest_add_threads(info, dtc, DMA_MEMCPY);
979 thread_count += cnt > 0 ? cnt : 0;
980 }
b54d5cb9 981 }
a0d4cb44 982
61b5f54d 983 if (dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)) {
a0d4cb44 984 if (dmatest == 1) {
c678fa66 985 cnt = dmatest_add_threads(info, dtc, DMA_MEMSET);
a0d4cb44
KA
986 thread_count += cnt > 0 ? cnt : 0;
987 }
988 }
989
b54d5cb9 990 if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
e03e93a9 991 cnt = dmatest_add_threads(info, dtc, DMA_XOR);
f1aef8b6 992 thread_count += cnt > 0 ? cnt : 0;
b54d5cb9 993 }
58691d64 994 if (dma_has_cap(DMA_PQ, dma_dev->cap_mask)) {
e03e93a9 995 cnt = dmatest_add_threads(info, dtc, DMA_PQ);
d07a74a5 996 thread_count += cnt > 0 ? cnt : 0;
58691d64 997 }
b54d5cb9 998
d53513d5 999 pr_info("Added %u threads using %s\n",
b54d5cb9 1000 thread_count, dma_chan_name(chan));
4a776f0a 1001
838cc704
AS
1002 list_add_tail(&dtc->node, &info->channels);
1003 info->nr_channels++;
4a776f0a 1004
33df8ca0 1005 return 0;
4a776f0a
HS
1006}
1007
7dd60251 1008static bool filter(struct dma_chan *chan, void *param)
4a776f0a 1009{
15b8a8ea 1010 struct dmatest_params *params = param;
e03e93a9 1011
15b8a8ea
AS
1012 if (!dmatest_match_channel(params, chan) ||
1013 !dmatest_match_device(params, chan->device))
7dd60251 1014 return false;
33df8ca0 1015 else
7dd60251 1016 return true;
4a776f0a
HS
1017}
1018
a9e55495
DW
1019static void request_channels(struct dmatest_info *info,
1020 enum dma_transaction_type type)
4a776f0a 1021{
33df8ca0 1022 dma_cap_mask_t mask;
33df8ca0
DW
1023
1024 dma_cap_zero(mask);
a9e55495 1025 dma_cap_set(type, mask);
33df8ca0 1026 for (;;) {
a9e55495
DW
1027 struct dmatest_params *params = &info->params;
1028 struct dma_chan *chan;
1029
15b8a8ea 1030 chan = dma_request_channel(mask, filter, params);
33df8ca0 1031 if (chan) {
a9e55495 1032 if (dmatest_add_channel(info, chan)) {
33df8ca0
DW
1033 dma_release_channel(chan);
1034 break; /* add_channel failed, punt */
1035 }
1036 } else
1037 break; /* no more channels available */
15b8a8ea
AS
1038 if (params->max_channels &&
1039 info->nr_channels >= params->max_channels)
33df8ca0
DW
1040 break; /* we have all we need */
1041 }
4a776f0a 1042}
4a776f0a 1043
d53513d5 1044static void add_threaded_test(struct dmatest_info *info)
851b7e16 1045{
a9e55495 1046 struct dmatest_params *params = &info->params;
851b7e16 1047
a9e55495
DW
1048 /* Copy test parameters */
1049 params->buf_size = test_buf_size;
1050 strlcpy(params->channel, strim(test_channel), sizeof(params->channel));
1051 strlcpy(params->device, strim(test_device), sizeof(params->device));
1052 params->threads_per_chan = threads_per_chan;
1053 params->max_channels = max_channels;
1054 params->iterations = iterations;
1055 params->xor_sources = xor_sources;
1056 params->pq_sources = pq_sources;
1057 params->timeout = timeout;
e3b9c347 1058 params->noverify = noverify;
2e67a087 1059 params->norandom = norandom;
a875abfa 1060 params->alignment = alignment;
13396a13 1061 params->transfer_size = transfer_size;
a9e55495
DW
1062
1063 request_channels(info, DMA_MEMCPY);
61b5f54d 1064 request_channels(info, DMA_MEMSET);
a9e55495
DW
1065 request_channels(info, DMA_XOR);
1066 request_channels(info, DMA_PQ);
851b7e16 1067}
851b7e16 1068
d53513d5
SA
1069static void run_pending_tests(struct dmatest_info *info)
1070{
1071 struct dmatest_chan *dtc;
1072 unsigned int thread_count = 0;
1073
1074 list_for_each_entry(dtc, &info->channels, node) {
1075 struct dmatest_thread *thread;
1076
1077 thread_count = 0;
1078 list_for_each_entry(thread, &dtc->threads, node) {
1079 wake_up_process(thread->task);
1080 thread_count++;
1081 }
1082 pr_info("Started %u threads using %s\n",
1083 thread_count, dma_chan_name(dtc->chan));
1084 }
1085}
1086
a310d037 1087static void stop_threaded_test(struct dmatest_info *info)
4a776f0a 1088{
33df8ca0 1089 struct dmatest_chan *dtc, *_dtc;
7cbd4877 1090 struct dma_chan *chan;
33df8ca0 1091
838cc704 1092 list_for_each_entry_safe(dtc, _dtc, &info->channels, node) {
33df8ca0 1093 list_del(&dtc->node);
7cbd4877 1094 chan = dtc->chan;
33df8ca0 1095 dmatest_cleanup_channel(dtc);
0adff800 1096 pr_debug("dropped channel %s\n", dma_chan_name(chan));
7cbd4877 1097 dma_release_channel(chan);
33df8ca0 1098 }
838cc704
AS
1099
1100 info->nr_channels = 0;
4a776f0a 1101}
e03e93a9 1102
d53513d5 1103static void start_threaded_tests(struct dmatest_info *info)
851b7e16 1104{
a310d037
DW
1105 /* we might be called early to set run=, defer running until all
1106 * parameters have been evaluated
1107 */
1108 if (!info->did_init)
a9e55495 1109 return;
851b7e16 1110
d53513d5 1111 run_pending_tests(info);
851b7e16
AS
1112}
1113
a310d037 1114static int dmatest_run_get(char *val, const struct kernel_param *kp)
851b7e16 1115{
a310d037 1116 struct dmatest_info *info = &test_info;
851b7e16
AS
1117
1118 mutex_lock(&info->lock);
a310d037
DW
1119 if (is_threaded_test_run(info)) {
1120 dmatest_run = true;
3e5ccd86 1121 } else {
d53513d5
SA
1122 if (!is_threaded_test_pending(info))
1123 stop_threaded_test(info);
a310d037 1124 dmatest_run = false;
3e5ccd86 1125 }
851b7e16 1126 mutex_unlock(&info->lock);
851b7e16 1127
a310d037 1128 return param_get_bool(val, kp);
851b7e16
AS
1129}
1130
a310d037 1131static int dmatest_run_set(const char *val, const struct kernel_param *kp)
95019c8c 1132{
a310d037
DW
1133 struct dmatest_info *info = &test_info;
1134 int ret;
95019c8c 1135
a310d037
DW
1136 mutex_lock(&info->lock);
1137 ret = param_set_bool(val, kp);
1138 if (ret) {
851b7e16 1139 mutex_unlock(&info->lock);
a310d037 1140 return ret;
d53513d5
SA
1141 } else if (dmatest_run) {
1142 if (is_threaded_test_pending(info))
1143 start_threaded_tests(info);
1144 else
1145 pr_info("Could not start test, no channels configured\n");
1146 } else {
1147 stop_threaded_test(info);
1148 }
1149
1150 mutex_unlock(&info->lock);
1151
1152 return ret;
1153}
1154
1155static int dmatest_chan_set(const char *val, const struct kernel_param *kp)
1156{
1157 struct dmatest_info *info = &test_info;
1158 struct dmatest_chan *dtc;
1159 char chan_reset_val[20];
1160 int ret = 0;
1161
1162 mutex_lock(&info->lock);
1163 ret = param_set_copystring(val, kp);
1164 if (ret) {
1165 mutex_unlock(&info->lock);
1166 return ret;
1167 }
1168 /*Clear any previously run threads */
1169 if (!is_threaded_test_run(info) && !is_threaded_test_pending(info))
1170 stop_threaded_test(info);
1171 /* Reject channels that are already registered */
1172 if (is_threaded_test_pending(info)) {
1173 list_for_each_entry(dtc, &info->channels, node) {
1174 if (strcmp(dma_chan_name(dtc->chan),
1175 strim(test_channel)) == 0) {
1176 dtc = list_last_entry(&info->channels,
1177 struct dmatest_chan,
1178 node);
1179 strlcpy(chan_reset_val,
1180 dma_chan_name(dtc->chan),
1181 sizeof(chan_reset_val));
1182 ret = -EBUSY;
1183 goto add_chan_err;
1184 }
1185 }
95019c8c
AS
1186 }
1187
d53513d5
SA
1188 add_threaded_test(info);
1189
1190 /* Check if channel was added successfully */
1191 dtc = list_last_entry(&info->channels, struct dmatest_chan, node);
1192
1193 if (dtc->chan) {
1194 /*
1195 * if new channel was not successfully added, revert the
1196 * "test_channel" string to the name of the last successfully
1197 * added channel. exception for when users issues empty string
1198 * to channel parameter.
1199 */
1200 if ((strcmp(dma_chan_name(dtc->chan), strim(test_channel)) != 0)
1201 && (strcmp("", strim(test_channel)) != 0)) {
1202 ret = -EINVAL;
1203 strlcpy(chan_reset_val, dma_chan_name(dtc->chan),
1204 sizeof(chan_reset_val));
1205 goto add_chan_err;
1206 }
1207
1208 } else {
1209 /* Clear test_channel if no channels were added successfully */
1210 strlcpy(chan_reset_val, "", sizeof(chan_reset_val));
a310d037 1211 ret = -EBUSY;
d53513d5
SA
1212 goto add_chan_err;
1213 }
1214
1215 mutex_unlock(&info->lock);
1216
1217 return ret;
851b7e16 1218
d53513d5
SA
1219add_chan_err:
1220 param_set_copystring(chan_reset_val, kp);
a310d037 1221 mutex_unlock(&info->lock);
851b7e16 1222
a310d037 1223 return ret;
851b7e16
AS
1224}
1225
d53513d5
SA
1226static int dmatest_chan_get(char *val, const struct kernel_param *kp)
1227{
1228 struct dmatest_info *info = &test_info;
1229
1230 mutex_lock(&info->lock);
1231 if (!is_threaded_test_run(info) && !is_threaded_test_pending(info)) {
1232 stop_threaded_test(info);
1233 strlcpy(test_channel, "", sizeof(test_channel));
1234 }
1235 mutex_unlock(&info->lock);
1236
1237 return param_get_string(val, kp);
1238}
1239
1240static int dmatest_test_list_get(char *val, const struct kernel_param *kp)
1241{
1242 struct dmatest_info *info = &test_info;
1243 struct dmatest_chan *dtc;
1244 unsigned int thread_count = 0;
1245
1246 list_for_each_entry(dtc, &info->channels, node) {
1247 struct dmatest_thread *thread;
1248
1249 thread_count = 0;
1250 list_for_each_entry(thread, &dtc->threads, node) {
1251 thread_count++;
1252 }
1253 pr_info("%u threads using %s\n",
1254 thread_count, dma_chan_name(dtc->chan));
1255 }
1256
1257 return 0;
1258}
1259
e03e93a9
AS
1260static int __init dmatest_init(void)
1261{
1262 struct dmatest_info *info = &test_info;
2d88ce76 1263 struct dmatest_params *params = &info->params;
e03e93a9 1264
a310d037
DW
1265 if (dmatest_run) {
1266 mutex_lock(&info->lock);
d53513d5
SA
1267 add_threaded_test(info);
1268 run_pending_tests(info);
a310d037
DW
1269 mutex_unlock(&info->lock);
1270 }
838cc704 1271
2d88ce76
DW
1272 if (params->iterations && wait)
1273 wait_event(thread_wait, !is_threaded_test_run(info));
95019c8c 1274
a310d037
DW
1275 /* module parameters are stable, inittime tests are started,
1276 * let userspace take over 'run' control
1277 */
1278 info->did_init = true;
851b7e16 1279
851b7e16 1280 return 0;
e03e93a9
AS
1281}
1282/* when compiled-in wait for drivers to load first */
1283late_initcall(dmatest_init);
1284
1285static void __exit dmatest_exit(void)
1286{
1287 struct dmatest_info *info = &test_info;
1288
a310d037 1289 mutex_lock(&info->lock);
e03e93a9 1290 stop_threaded_test(info);
a310d037 1291 mutex_unlock(&info->lock);
e03e93a9 1292}
4a776f0a
HS
1293module_exit(dmatest_exit);
1294
e05503ef 1295MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
4a776f0a 1296MODULE_LICENSE("GPL v2");