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 eb1d8641cf5..2b8661b54ea 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,  	return error_count;  } -static void dmatest_callback(void *completion) +/* poor man's completion - we want to use wait_event_freezable() on it */ +struct dmatest_done { +	bool			done; +	wait_queue_head_t	*wait; +}; + +static void dmatest_callback(void *arg)  { -	complete(completion); +	struct dmatest_done *done = arg; + +	done->done = true; +	wake_up_all(done->wait);  }  /* @@ -235,7 +244,9 @@ static void dmatest_callback(void *completion)   */  static int dmatest_func(void *data)  { +	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_wait);  	struct dmatest_thread	*thread = data; +	struct dmatest_done	done = { .wait = &done_wait };  	struct dma_chan		*chan;  	const char		*thread_name;  	unsigned int		src_off, dst_off, len; @@ -252,7 +263,7 @@ static int dmatest_func(void *data)  	int			i;  	thread_name = current->comm; -	set_freezable_with_signal(); +	set_freezable();  	ret = -ENOMEM; @@ -306,9 +317,6 @@ static int dmatest_func(void *data)  		struct dma_async_tx_descriptor *tx = NULL;  		dma_addr_t dma_srcs[src_cnt];  		dma_addr_t dma_dsts[dst_cnt]; -		struct completion cmp; -		unsigned long start, tmo, end = 0 /* compiler... */; -		bool reload = true;  		u8 align = 0;  		total_tests++; @@ -391,9 +399,9 @@ static int dmatest_func(void *data)  			continue;  		} -		init_completion(&cmp); +		done.done = false;  		tx->callback = dmatest_callback; -		tx->callback_param = &cmp; +		tx->callback_param = &done;  		cookie = tx->tx_submit(tx);  		if (dma_submit_error(cookie)) { @@ -407,20 +415,20 @@ static int dmatest_func(void *data)  		}  		dma_async_issue_pending(chan); -		do { -			start = jiffies; -			if (reload) -				end = start + msecs_to_jiffies(timeout); -			else if (end <= start) -				end = start + 1; -			tmo = wait_for_completion_interruptible_timeout(&cmp, -								end - start); -			reload = try_to_freeze(); -		} while (tmo == -ERESTARTSYS); +		wait_event_freezable_timeout(done_wait, done.done, +					     msecs_to_jiffies(timeout));  		status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); -		if (tmo == 0) { +		if (!done.done) { +			/* +			 * We're leaving the timed out dma operation with +			 * dangling pointer to done_wait.  To make this +			 * correct, we'll need to allocate wait_done for +			 * each test iteration and perform "who's gonna +			 * free it this time?" dancing.  For now, just +			 * leave it dangling. +			 */  			pr_warning("%s: #%u: test timed out\n",  				   thread_name, total_tests - 1);  			failed_tests++;  |