Browse Source

Merge branch 'fixes' of git://git.infradead.org/users/vkoul/slave-dma

Pull slave-dmaengine fixes from Vinod Koul:
 "Fix from Andy is for dmatest regression reported by Will and Rabin has
  fixed runtime ref counting for st_dma40"

* 'fixes' of git://git.infradead.org/users/vkoul/slave-dma:
  dmatest: do not allow to interrupt ongoing tests
  dmaengine: ste_dma40: fix pm runtime ref counting
Linus Torvalds 12 years ago
parent
commit
d7a39e300d
3 changed files with 31 additions and 28 deletions
  1. 3 3
      Documentation/dmatest.txt
  2. 23 22
      drivers/dma/dmatest.c
  3. 5 3
      drivers/dma/ste_dma40.c

+ 3 - 3
Documentation/dmatest.txt

@@ -34,7 +34,7 @@ command:
 After a while you will start to get messages about current status or error like
 After a while you will start to get messages about current status or error like
 in the original code.
 in the original code.
 
 
-Note that running a new test will stop any in progress test.
+Note that running a new test will not stop any in progress test.
 
 
 The following command should return actual state of the test.
 The following command should return actual state of the test.
 	% cat /sys/kernel/debug/dmatest/run
 	% cat /sys/kernel/debug/dmatest/run
@@ -52,8 +52,8 @@ To wait for test done the user may perform a busy loop that checks the state.
 
 
 The module parameters that is supplied to the kernel command line will be used
 The module parameters that is supplied to the kernel command line will be used
 for the first performed test. After user gets a control, the test could be
 for the first performed test. After user gets a control, the test could be
-interrupted or re-run with same or different parameters. For the details see
-the above section "Part 2 - When dmatest is built as a module..."
+re-run with the same or different parameters. For the details see the above
+section "Part 2 - When dmatest is built as a module..."
 
 
 In both cases the module parameters are used as initial values for the test case.
 In both cases the module parameters are used as initial values for the test case.
 You always could check them at run-time by running
 You always could check them at run-time by running

+ 23 - 22
drivers/dma/dmatest.c

@@ -716,8 +716,7 @@ static int dmatest_func(void *data)
 		}
 		}
 		dma_async_issue_pending(chan);
 		dma_async_issue_pending(chan);
 
 
-		wait_event_freezable_timeout(done_wait,
-					     done.done || kthread_should_stop(),
+		wait_event_freezable_timeout(done_wait, done.done,
 					     msecs_to_jiffies(params->timeout));
 					     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);
@@ -997,7 +996,6 @@ static void stop_threaded_test(struct dmatest_info *info)
 static int __restart_threaded_test(struct dmatest_info *info, bool run)
 static int __restart_threaded_test(struct dmatest_info *info, bool run)
 {
 {
 	struct dmatest_params *params = &info->params;
 	struct dmatest_params *params = &info->params;
-	int ret;
 
 
 	/* Stop any running test first */
 	/* Stop any running test first */
 	__stop_threaded_test(info);
 	__stop_threaded_test(info);
@@ -1012,13 +1010,23 @@ static int __restart_threaded_test(struct dmatest_info *info, bool run)
 	memcpy(params, &info->dbgfs_params, sizeof(*params));
 	memcpy(params, &info->dbgfs_params, sizeof(*params));
 
 
 	/* Run test with new parameters */
 	/* Run test with new parameters */
-	ret = __run_threaded_test(info);
-	if (ret) {
-		__stop_threaded_test(info);
-		pr_err("dmatest: Can't run test\n");
+	return __run_threaded_test(info);
+}
+
+static bool __is_threaded_test_run(struct dmatest_info *info)
+{
+	struct dmatest_chan *dtc;
+
+	list_for_each_entry(dtc, &info->channels, node) {
+		struct dmatest_thread *thread;
+
+		list_for_each_entry(thread, &dtc->threads, node) {
+			if (!thread->done)
+				return true;
+		}
 	}
 	}
 
 
-	return ret;
+	return false;
 }
 }
 
 
 static ssize_t dtf_write_string(void *to, size_t available, loff_t *ppos,
 static ssize_t dtf_write_string(void *to, size_t available, loff_t *ppos,
@@ -1091,22 +1099,10 @@ static ssize_t dtf_read_run(struct file *file, char __user *user_buf,
 {
 {
 	struct dmatest_info *info = file->private_data;
 	struct dmatest_info *info = file->private_data;
 	char buf[3];
 	char buf[3];
-	struct dmatest_chan *dtc;
-	bool alive = false;
 
 
 	mutex_lock(&info->lock);
 	mutex_lock(&info->lock);
-	list_for_each_entry(dtc, &info->channels, node) {
-		struct dmatest_thread *thread;
-
-		list_for_each_entry(thread, &dtc->threads, node) {
-			if (!thread->done) {
-				alive = true;
-				break;
-			}
-		}
-	}
 
 
-	if (alive) {
+	if (__is_threaded_test_run(info)) {
 		buf[0] = 'Y';
 		buf[0] = 'Y';
 	} else {
 	} else {
 		__stop_threaded_test(info);
 		__stop_threaded_test(info);
@@ -1132,7 +1128,12 @@ static ssize_t dtf_write_run(struct file *file, const char __user *user_buf,
 
 
 	if (strtobool(buf, &bv) == 0) {
 	if (strtobool(buf, &bv) == 0) {
 		mutex_lock(&info->lock);
 		mutex_lock(&info->lock);
-		ret = __restart_threaded_test(info, bv);
+
+		if (__is_threaded_test_run(info))
+			ret = -EBUSY;
+		else
+			ret = __restart_threaded_test(info, bv);
+
 		mutex_unlock(&info->lock);
 		mutex_unlock(&info->lock);
 	}
 	}
 
 

+ 5 - 3
drivers/dma/ste_dma40.c

@@ -1566,10 +1566,12 @@ static void dma_tc_handle(struct d40_chan *d40c)
 			return;
 			return;
 		}
 		}
 
 
-		if (d40_queue_start(d40c) == NULL)
+		if (d40_queue_start(d40c) == NULL) {
 			d40c->busy = false;
 			d40c->busy = false;
-		pm_runtime_mark_last_busy(d40c->base->dev);
-		pm_runtime_put_autosuspend(d40c->base->dev);
+
+			pm_runtime_mark_last_busy(d40c->base->dev);
+			pm_runtime_put_autosuspend(d40c->base->dev);
+		}
 
 
 		d40_desc_remove(d40d);
 		d40_desc_remove(d40d);
 		d40_desc_done(d40c, d40d);
 		d40_desc_done(d40c, d40d);