diff options
Diffstat (limited to 'drivers/dma/dmatest.c')
| -rw-r--r-- | drivers/dma/dmatest.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index eb1d8641cf5c..2b8661b54eaf 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c | |||
| @@ -214,9 +214,18 @@ static unsigned int dmatest_verify(u8 **bufs, unsigned int start, | |||
| 214 | return error_count; | 214 | return error_count; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | static void dmatest_callback(void *completion) | 217 | /* poor man's completion - we want to use wait_event_freezable() on it */ |
| 218 | struct dmatest_done { | ||
| 219 | bool done; | ||
| 220 | wait_queue_head_t *wait; | ||
| 221 | }; | ||
| 222 | |||
| 223 | static void dmatest_callback(void *arg) | ||
| 218 | { | 224 | { |
| 219 | complete(completion); | 225 | struct dmatest_done *done = arg; |
| 226 | |||
| 227 | done->done = true; | ||
| 228 | wake_up_all(done->wait); | ||
| 220 | } | 229 | } |
| 221 | 230 | ||
| 222 | /* | 231 | /* |
| @@ -235,7 +244,9 @@ static void dmatest_callback(void *completion) | |||
| 235 | */ | 244 | */ |
| 236 | static int dmatest_func(void *data) | 245 | static int dmatest_func(void *data) |
| 237 | { | 246 | { |
| 247 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_wait); | ||
| 238 | struct dmatest_thread *thread = data; | 248 | struct dmatest_thread *thread = data; |
| 249 | struct dmatest_done done = { .wait = &done_wait }; | ||
| 239 | struct dma_chan *chan; | 250 | struct dma_chan *chan; |
| 240 | const char *thread_name; | 251 | const char *thread_name; |
| 241 | unsigned int src_off, dst_off, len; | 252 | unsigned int src_off, dst_off, len; |
| @@ -252,7 +263,7 @@ static int dmatest_func(void *data) | |||
| 252 | int i; | 263 | int i; |
| 253 | 264 | ||
| 254 | thread_name = current->comm; | 265 | thread_name = current->comm; |
| 255 | set_freezable_with_signal(); | 266 | set_freezable(); |
| 256 | 267 | ||
| 257 | ret = -ENOMEM; | 268 | ret = -ENOMEM; |
| 258 | 269 | ||
| @@ -306,9 +317,6 @@ static int dmatest_func(void *data) | |||
| 306 | struct dma_async_tx_descriptor *tx = NULL; | 317 | struct dma_async_tx_descriptor *tx = NULL; |
| 307 | dma_addr_t dma_srcs[src_cnt]; | 318 | dma_addr_t dma_srcs[src_cnt]; |
| 308 | dma_addr_t dma_dsts[dst_cnt]; | 319 | dma_addr_t dma_dsts[dst_cnt]; |
| 309 | struct completion cmp; | ||
| 310 | unsigned long start, tmo, end = 0 /* compiler... */; | ||
| 311 | bool reload = true; | ||
| 312 | u8 align = 0; | 320 | u8 align = 0; |
| 313 | 321 | ||
| 314 | total_tests++; | 322 | total_tests++; |
| @@ -391,9 +399,9 @@ static int dmatest_func(void *data) | |||
| 391 | continue; | 399 | continue; |
| 392 | } | 400 | } |
| 393 | 401 | ||
| 394 | init_completion(&cmp); | 402 | done.done = false; |
| 395 | tx->callback = dmatest_callback; | 403 | tx->callback = dmatest_callback; |
| 396 | tx->callback_param = &cmp; | 404 | tx->callback_param = &done; |
| 397 | cookie = tx->tx_submit(tx); | 405 | cookie = tx->tx_submit(tx); |
| 398 | 406 | ||
| 399 | if (dma_submit_error(cookie)) { | 407 | if (dma_submit_error(cookie)) { |
| @@ -407,20 +415,20 @@ static int dmatest_func(void *data) | |||
| 407 | } | 415 | } |
| 408 | dma_async_issue_pending(chan); | 416 | dma_async_issue_pending(chan); |
| 409 | 417 | ||
| 410 | do { | 418 | wait_event_freezable_timeout(done_wait, done.done, |
| 411 | start = jiffies; | 419 | msecs_to_jiffies(timeout)); |
| 412 | if (reload) | ||
| 413 | end = start + msecs_to_jiffies(timeout); | ||
| 414 | else if (end <= start) | ||
| 415 | end = start + 1; | ||
| 416 | tmo = wait_for_completion_interruptible_timeout(&cmp, | ||
| 417 | end - start); | ||
| 418 | reload = try_to_freeze(); | ||
| 419 | } while (tmo == -ERESTARTSYS); | ||
| 420 | 420 | ||
| 421 | status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); | 421 | status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); |
| 422 | 422 | ||
| 423 | if (tmo == 0) { | 423 | if (!done.done) { |
| 424 | /* | ||
| 425 | * We're leaving the timed out dma operation with | ||
| 426 | * dangling pointer to done_wait. To make this | ||
| 427 | * correct, we'll need to allocate wait_done for | ||
| 428 | * each test iteration and perform "who's gonna | ||
| 429 | * free it this time?" dancing. For now, just | ||
| 430 | * leave it dangling. | ||
| 431 | */ | ||
| 424 | pr_warning("%s: #%u: test timed out\n", | 432 | pr_warning("%s: #%u: test timed out\n", |
| 425 | thread_name, total_tests - 1); | 433 | thread_name, total_tests - 1); |
| 426 | failed_tests++; | 434 | failed_tests++; |
