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 <jacopo.mondi@linaro.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Jacopo Mondi 2016-07-15 11:03:42 +02:00 committed by Greg Kroah-Hartman
parent 6cc270483c
commit fdf73c00c8

View file

@ -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);