From: Alex Elder <elder@linaro.org>
Date: Mon, 17 Nov 2014 14:08:40 +0000 (-0600)
Subject: greybus: reference count operations
X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=c7d0f258fb4d9ccb0e26bde0036abeda02575ad6;p=linux.git

greybus: reference count operations

Add a reference counter to the operations structure.  We'll
need this when operations are actually allowed to complete
asynchronously.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
---

diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c
index bc68a5f9be667..2b33d336bfad9 100644
--- a/drivers/staging/greybus/operation.c
+++ b/drivers/staging/greybus/operation.c
@@ -274,6 +274,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
 	operation->callback = NULL;	/* set at submit time */
 	init_completion(&operation->completion);
 	INIT_DELAYED_WORK(&operation->timeout_work, operation_timeout);
+	kref_init(&operation->kref);
 
 	spin_lock_irq(&gb_operations_lock);
 	list_add_tail(&operation->links, &connection->operations);
@@ -292,10 +293,11 @@ err_cache:
 /*
  * Destroy a previously created operation.
  */
-void gb_operation_destroy(struct gb_operation *operation)
+static void _gb_operation_destroy(struct kref *kref)
 {
-	if (WARN_ON(!operation))
-		return;
+	struct gb_operation *operation;
+
+	operation = container_of(kref, struct gb_operation, kref);
 
 	/* XXX Make sure it's not in flight */
 	spin_lock_irq(&gb_operations_lock);
@@ -308,6 +310,12 @@ void gb_operation_destroy(struct gb_operation *operation)
 	kmem_cache_free(gb_operation_cache, operation);
 }
 
+void gb_operation_put(struct gb_operation *operation)
+{
+	if (!WARN_ON(!operation))
+		kref_put(&operation->kref, _gb_operation_destroy);
+}
+
 /*
  * Send an operation request message.  The caller has filled in
  * any payload so the request message is ready to go.  If non-null,
diff --git a/drivers/staging/greybus/operation.h b/drivers/staging/greybus/operation.h
index f30b162f78b77..dc15c2f61e30a 100644
--- a/drivers/staging/greybus/operation.h
+++ b/drivers/staging/greybus/operation.h
@@ -65,6 +65,7 @@ struct gb_operation {
 	struct completion	completion;	/* Used if no callback */
 	struct delayed_work	timeout_work;
 
+	struct kref		kref;
 	struct list_head	links;	/* connection->{operations,pending} */
 
 	/* These are what's used by caller */
@@ -78,7 +79,12 @@ void gb_connection_operation_recv(struct gb_connection *connection,
 struct gb_operation *gb_operation_create(struct gb_connection *connection,
 					u8 type, size_t request_size,
 					size_t response_size);
-void gb_operation_destroy(struct gb_operation *operation);
+struct gb_operation *gb_operation_get(struct gb_operation *operation);
+void gb_operation_put(struct gb_operation *operation);
+static inline void gb_operation_destroy(struct gb_operation *operation)
+{
+	gb_operation_put(operation);
+}
 
 int gb_operation_request_send(struct gb_operation *operation,
 				gb_operation_callback callback);