From 29f020290d8897e3ed6ed8a8f8938c0b8545bbcd Mon Sep 17 00:00:00 2001
From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Date: Mon, 14 Sep 2015 10:48:40 +0100
Subject: [PATCH] greybus: loopback: hold a coarse lock while init/exit run

This patch holds gb_dev.mutex for the duration of init and exit to reduce
complexity while ensuring that init and exit run atomically with respect
to slave threads @ gb_loopback_fn().

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
---
 drivers/staging/greybus/loopback.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c
index 33c21cf22687..7e1f527e3aef 100644
--- a/drivers/staging/greybus/loopback.c
+++ b/drivers/staging/greybus/loopback.c
@@ -864,21 +864,18 @@ static int gb_loopback_connection_init(struct gb_connection *connection)
 				    gb_dev.root, &gb_dev,
 				    &gb_loopback_debugfs_dev_latency_ops);
 		retval = sysfs_create_groups(kobj, loopback_dev_groups);
-		if (retval) {
-			mutex_unlock(&gb_dev.mutex);
+		if (retval)
 			goto out_sysfs;
-		}
+
 		/* Calculate maximum payload */
 		gb_dev.size_max = gb_operation_get_payload_size_max(connection);
 		if (gb_dev.size_max <=
 			sizeof(struct gb_loopback_transfer_request)) {
 			retval = -EINVAL;
-			mutex_unlock(&gb_dev.mutex);
 			goto out_sysfs;
 		}
 		gb_dev.size_max -= sizeof(struct gb_loopback_transfer_request);
 	}
-	mutex_unlock(&gb_dev.mutex);
 
 	/* Create per-connection sysfs and debugfs data-points */
 	snprintf(name, sizeof(name), "raw_latency_endo0:%d:%d:%d:%d",
@@ -916,10 +913,9 @@ static int gb_loopback_connection_init(struct gb_connection *connection)
 		goto out_kfifo1;
 	}
 
-	mutex_lock(&gb_dev.mutex);
 	list_add_tail(&gb->entry, &gb_dev.list);
-	mutex_unlock(&gb_dev.mutex);
 	gb_dev.count++;
+	mutex_unlock(&gb_dev.mutex);
 	return 0;
 
 out_kfifo1:
@@ -934,6 +930,7 @@ out_sysfs_dev:
 	debugfs_remove(gb->file);
 	connection->private = NULL;
 out_sysfs:
+	mutex_unlock(&gb_dev.mutex);
 	kfree(gb);
 
 	return retval;
-- 
2.30.2