greybus: camera: Improve module registration mechanism
authorGjorgji Rosikopulos <grosikopulos@mm-sol.com>
Mon, 14 Mar 2016 16:44:53 +0000 (18:44 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Thu, 17 Mar 2016 22:17:59 +0000 (15:17 -0700)
Registering more then one module at same time was not
possible with previous implementation. Also unregistering
of the module was missing leading to many instability issues
when camera module is ejected when camera is still active.

Signed-off-by: Gjorgji Rosikopulos <grosikopulos@mm-sol.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/camera.c
drivers/staging/greybus/gb-camera.h

index e862659a5ccc05c54f3db857dd6b5e91b9d7e806..722f2b4fe54d3e0bf323964ef22e37dfeabc5f5b 100644 (file)
@@ -38,6 +38,7 @@ struct gb_camera_debugfs_buffer {
  * @connection: the greybus connection for camera control
  * @data_connected: whether the data connection has been established
  * @debugfs: debugfs entries for camera protocol operations testing
+ * @module: Greybus camera module registered to HOST processor.
  */
 struct gb_camera {
        struct gb_connection *connection;
@@ -47,6 +48,8 @@ struct gb_camera {
                struct dentry *root;
                struct gb_camera_debugfs_buffer *buffers;
        } debugfs;
+
+       struct gb_camera_module module;
 };
 
 struct gb_camera_stream_config {
@@ -504,16 +507,20 @@ static int gb_camera_op_flush(void *priv, u32 *request_id)
        return gb_camera_flush(priv, request_id);
 }
 
-struct gb_camera_ops gb_cam_ops = {
-       .capabilities = gb_camera_op_capabilities,
-       .configure_streams = gb_camera_op_configure_streams,
-       .capture = gb_camera_op_capture,
-       .flush = gb_camera_op_flush,
-};
-
 static int gb_camera_register_intf_ops(struct gb_camera *gcam)
 {
-       return gb_camera_register(&gb_cam_ops, gcam);
+       gcam->module.priv = gcam;
+       gcam->module.ops.capabilities = gb_camera_op_capabilities;
+       gcam->module.ops.configure_streams = gb_camera_op_configure_streams;
+       gcam->module.ops.capture = gb_camera_op_capture;
+       gcam->module.ops.flush = gb_camera_op_flush;
+
+       return gb_camera_register(&gcam->module);
+}
+
+static int gb_camera_unregister_intf_ops(struct gb_camera *gcam)
+{
+       return gb_camera_unregister(&gcam->module);
 }
 
 /* -----------------------------------------------------------------------------
@@ -931,6 +938,8 @@ static void gb_camera_connection_exit(struct gb_connection *connection)
 {
        struct gb_camera *gcam = connection->private;
 
+       gb_camera_unregister_intf_ops(gcam);
+
        gb_camera_cleanup(gcam);
 }
 
index 50af0573737b08b2a4628b86e39affb56fe3e7e4..0a48a16b675ea6881a62d527482d86566354beb5 100644 (file)
@@ -34,9 +34,18 @@ struct gb_camera_ops {
        int (*flush)(void *priv, u32 *request_id);
 };
 
-#define gb_camera_call(f, p, op, args...)             \
-       (((f)->op) ? (f)->op(p, ##args) : -ENOIOCTLCMD)
+struct gb_camera_module {
+       void *priv;
+       struct gb_camera_ops ops;
 
-int gb_camera_register(struct gb_camera_ops *ops, void *priv);
+       struct list_head list; /* Global list */
+};
+
+#define gb_camera_call(f, op, args...)      \
+       ((!(f) ? -ENODEV : ((f)->ops.op) ?  \
+       (f)->ops.op((f)->priv, ##args) : -ENOIOCTLCMD))
+
+int gb_camera_register(struct gb_camera_module *module);
+int gb_camera_unregister(struct gb_camera_module *module);
 
 #endif /* __GB_CAMERA_H */