From fdf73c00c8872f6f59730955d54b2cdc963e2485 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Fri, 15 Jul 2016 11:03:42 +0200 Subject: [PATCH] greybus: camera: Add wrapper for sync operation with flags The greybus operation core synchronous operation call doesn't support operation flags. Create a new synchronous operation wrapper with flags, and modify the capabilities operation implementation to use it. The code could be later moved to the greybus core if other drivers have a similar need. Signed-off-by: Jacopo Mondi Signed-off-by: Laurent Pinchart Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/camera.c | 60 ++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c index 7835ed78570a..9d9746f434e4 100644 --- a/drivers/staging/greybus/camera.c +++ b/drivers/staging/greybus/camera.c @@ -173,6 +173,41 @@ static const struct gb_camera_fmt_info gb_fmt_info[] = { #define gcam_info(gcam, format...) dev_info(&gcam->bundle->dev, format) #define gcam_err(gcam, format...) dev_err(&gcam->bundle->dev, format) +static int gb_camera_operation_sync_flags(struct gb_connection *connection, + int type, unsigned int flags, + void *request, size_t request_size, + void *response, size_t *response_size) +{ + struct gb_operation *operation; + int ret; + + operation = gb_operation_create_flags(connection, type, request_size, + *response_size, flags, + GFP_KERNEL); + if (!operation) + return -ENOMEM; + + if (request_size) + memcpy(operation->request->payload, request, request_size); + + ret = gb_operation_request_send_sync(operation); + if (ret) { + dev_err(&connection->hd->dev, + "%s: synchronous operation of type 0x%02x failed: %d\n", + connection->name, type, ret); + } else { + *response_size = operation->response->payload_size; + + if (operation->response->payload_size) + memcpy(response, operation->response->payload, + operation->response->payload_size); + } + + gb_operation_put(operation); + + return ret; +} + /* ----------------------------------------------------------------------------- * Hardware Configuration */ @@ -347,7 +382,6 @@ static void gb_camera_teardown_data_connection(struct gb_camera *gcam) static int gb_camera_capabilities(struct gb_camera *gcam, u8 *capabilities, size_t *size) { - struct gb_operation *op = NULL; int ret; ret = gb_pm_runtime_get_sync(gcam->bundle); @@ -361,28 +395,16 @@ static int gb_camera_capabilities(struct gb_camera *gcam, goto done; } - op = gb_operation_create_flags(gcam->connection, - GB_CAMERA_TYPE_CAPABILITIES, 0, *size, - GB_OPERATION_FLAG_SHORT_RESPONSE, - GFP_KERNEL); - if (!op) { - ret = -ENOMEM; - goto done; - } - - ret = gb_operation_request_send_sync(op); - if (ret) { + ret = gb_camera_operation_sync_flags(gcam->connection, + GB_CAMERA_TYPE_CAPABILITIES, + GB_OPERATION_FLAG_SHORT_RESPONSE, + NULL, 0, + (void *)capabilities, size); + if (ret) gcam_err(gcam, "failed to retrieve capabilities: %d\n", ret); - goto done; - } - - memcpy(capabilities, op->response->payload, op->response->payload_size); - *size = op->response->payload_size; done: mutex_unlock(&gcam->mutex); - if (op) - gb_operation_put(op); gb_pm_runtime_put_autosuspend(gcam->bundle); -- 2.39.5