aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/camera.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2016-06-14 15:59:24 +0300
committerGreg Kroah-Hartman <gregkh@google.com>2016-06-15 05:05:47 -0700
commit3b8ebfeb32daf13ef5fccb7ec3d163783e6a01a2 (patch)
treefc7d8046588cb78629f502d1afb380414299b502 /drivers/staging/greybus/camera.c
parentgreybus: camera: Clean up on stream configuration failure (diff)
downloadlinux-dev-3b8ebfeb32daf13ef5fccb7ec3d163783e6a01a2.tar.xz
linux-dev-3b8ebfeb32daf13ef5fccb7ec3d163783e6a01a2.zip
greybus: camera: Fix data connection setup
When the module is in the configured state, an attempt to change the configuration must first tear down the data connection to update its parameters, as the APB1 bridge doesn't support modifying the CSI transmitter configuration when it is already started. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Gjorgji Rosikopulos <grosikopulos@mm-sol.com> Tested-by: Gjorgji Rosikopulos <grosikopulos@mm-sol.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/camera.c')
-rw-r--r--drivers/staging/greybus/camera.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c
index bbf54d7f52a1..db7cdcee1c53 100644
--- a/drivers/staging/greybus/camera.c
+++ b/drivers/staging/greybus/camera.c
@@ -33,11 +33,17 @@ struct gb_camera_debugfs_buffer {
size_t length;
};
+enum gb_camera_state {
+ GB_CAMERA_STATE_UNCONFIGURED,
+ GB_CAMERA_STATE_CONFIGURED,
+};
+
/**
* struct gb_camera - A Greybus Camera Device
* @connection: the greybus connection for camera management
* @data_connection: the greybus connection for camera data
- * @mutex: protects the connection field
+ * @mutex: protects the connection and state fields
+ * @state: the current module state
* @debugfs: debugfs entries for camera protocol operations testing
* @module: Greybus camera module registered to HOST processor.
*/
@@ -45,7 +51,9 @@ struct gb_camera {
struct gb_bundle *bundle;
struct gb_connection *connection;
struct gb_connection *data_connection;
+
struct mutex mutex;
+ enum gb_camera_state state;
struct {
struct dentry *root;
@@ -300,7 +308,6 @@ static int gb_camera_configure_streams(struct gb_camera *gcam,
{
struct gb_camera_configure_streams_request *req;
struct gb_camera_configure_streams_response *resp;
-
unsigned int nstreams = *num_streams;
unsigned int i;
size_t req_size;
@@ -385,6 +392,11 @@ static int gb_camera_configure_streams(struct gb_camera *gcam,
goto done;
}
+ if (gcam->state == GB_CAMERA_STATE_CONFIGURED) {
+ gb_camera_teardown_data_connection(gcam);
+ gcam->state = GB_CAMERA_STATE_UNCONFIGURED;
+ }
+
if (resp->num_streams) {
ret = gb_camera_setup_data_connection(gcam, resp, csi_params);
if (ret < 0) {
@@ -394,8 +406,8 @@ static int gb_camera_configure_streams(struct gb_camera *gcam,
req, req_size, resp, resp_size);
goto done;
}
- } else {
- gb_camera_teardown_data_connection(gcam);
+
+ gcam->state = GB_CAMERA_STATE_CONFIGURED;
}
*flags = resp->flags;
@@ -1039,9 +1051,11 @@ static int gb_camera_probe(struct gb_bundle *bundle,
if (!gcam)
return -ENOMEM;
- gcam->bundle = bundle;
mutex_init(&gcam->mutex);
+ gcam->bundle = bundle;
+ gcam->state = GB_CAMERA_STATE_UNCONFIGURED;
+
conn = gb_connection_create(bundle, mgmt_cport_id,
gb_camera_request_handler);
if (IS_ERR(conn)) {