From c7d0f258fb4d9ccb0e26bde0036abeda02575ad6 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 17 Nov 2014 08:08:40 -0600 Subject: [PATCH] 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 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/operation.c | 14 +++++++++++--- drivers/staging/greybus/operation.h | 8 +++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index bc68a5f9be66..2b33d336bfad 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 f30b162f78b7..dc15c2f61e30 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); -- 2.30.2