Merge tag 'for-5.1-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[sfrench/cifs-2.6.git] / include / media / v4l2-async.h
index 1592d323c577d7125c1cf851b668a170112f753d..1497bda66c3b65d62e3a5b8dd74a4b805b9d56f7 100644 (file)
@@ -20,9 +20,6 @@ struct v4l2_device;
 struct v4l2_subdev;
 struct v4l2_async_notifier;
 
-/* A random max subdevice number, used to allocate an array on stack */
-#define V4L2_MAX_SUBDEVS 128U
-
 /**
  * enum v4l2_async_match_type - type of asynchronous subdevice logic to be used
  *     in order to identify a match
@@ -73,6 +70,8 @@ enum v4l2_async_match_type {
  * @match.custom.priv:
  *             Driver-specific private struct with match parameters
  *             to be used if %V4L2_ASYNC_MATCH_CUSTOM.
+ * @asd_list:  used to add struct v4l2_async_subdev objects to the
+ *             master notifier @asd_list
  * @list:      used to link struct v4l2_async_subdev objects, waiting to be
  *             probed, to a notifier->waiting list
  *
@@ -90,14 +89,15 @@ struct v4l2_async_subdev {
                        unsigned short address;
                } i2c;
                struct {
-                       bool (*match)(struct device *,
-                                     struct v4l2_async_subdev *);
+                       bool (*match)(struct device *dev,
+                                     struct v4l2_async_subdev *sd);
                        void *priv;
                } custom;
        } match;
 
        /* v4l2-async core private: not to be used by drivers */
        struct list_head list;
+       struct list_head asd_list;
 };
 
 /**
@@ -121,29 +121,107 @@ struct v4l2_async_notifier_operations {
  * struct v4l2_async_notifier - v4l2_device notifier data
  *
  * @ops:       notifier operations
- * @num_subdevs: number of subdevices used in the subdevs array
- * @max_subdevs: number of subdevices allocated in the subdevs array
- * @subdevs:   array of pointers to subdevice descriptors
  * @v4l2_dev:  v4l2_device of the root notifier, NULL otherwise
  * @sd:                sub-device that registered the notifier, NULL otherwise
  * @parent:    parent notifier
+ * @asd_list:  master list of struct v4l2_async_subdev
  * @waiting:   list of struct v4l2_async_subdev, waiting for their drivers
  * @done:      list of struct v4l2_subdev, already probed
  * @list:      member in a global list of notifiers
  */
 struct v4l2_async_notifier {
        const struct v4l2_async_notifier_operations *ops;
-       unsigned int num_subdevs;
-       unsigned int max_subdevs;
-       struct v4l2_async_subdev **subdevs;
        struct v4l2_device *v4l2_dev;
        struct v4l2_subdev *sd;
        struct v4l2_async_notifier *parent;
+       struct list_head asd_list;
        struct list_head waiting;
        struct list_head done;
        struct list_head list;
 };
 
+/**
+ * v4l2_async_notifier_init - Initialize a notifier.
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ *
+ * This function initializes the notifier @asd_list. It must be called
+ * before the first call to @v4l2_async_notifier_add_subdev.
+ */
+void v4l2_async_notifier_init(struct v4l2_async_notifier *notifier);
+
+/**
+ * v4l2_async_notifier_add_subdev - Add an async subdev to the
+ *                             notifier's master asd list.
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ * @asd: pointer to &struct v4l2_async_subdev
+ *
+ * Call this function before registering a notifier to link the
+ * provided asd to the notifiers master @asd_list.
+ */
+int v4l2_async_notifier_add_subdev(struct v4l2_async_notifier *notifier,
+                                  struct v4l2_async_subdev *asd);
+
+/**
+ * v4l2_async_notifier_add_fwnode_subdev - Allocate and add a fwnode async
+ *                             subdev to the notifier's master asd_list.
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ * @fwnode: fwnode handle of the sub-device to be matched
+ * @asd_struct_size: size of the driver's async sub-device struct, including
+ *                  sizeof(struct v4l2_async_subdev). The &struct
+ *                  v4l2_async_subdev shall be the first member of
+ *                  the driver's async sub-device struct, i.e. both
+ *                  begin at the same memory address.
+ *
+ * Allocate a fwnode-matched asd of size asd_struct_size, and add it
+ * to the notifiers @asd_list.
+ */
+struct v4l2_async_subdev *
+v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier,
+                                     struct fwnode_handle *fwnode,
+                                     unsigned int asd_struct_size);
+
+/**
+ * v4l2_async_notifier_add_i2c_subdev - Allocate and add an i2c async
+ *                             subdev to the notifier's master asd_list.
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ * @adapter_id: I2C adapter ID to be matched
+ * @address: I2C address of sub-device to be matched
+ * @asd_struct_size: size of the driver's async sub-device struct, including
+ *                  sizeof(struct v4l2_async_subdev). The &struct
+ *                  v4l2_async_subdev shall be the first member of
+ *                  the driver's async sub-device struct, i.e. both
+ *                  begin at the same memory address.
+ *
+ * Same as above but for I2C matched sub-devices.
+ */
+struct v4l2_async_subdev *
+v4l2_async_notifier_add_i2c_subdev(struct v4l2_async_notifier *notifier,
+                                  int adapter_id, unsigned short address,
+                                  unsigned int asd_struct_size);
+
+/**
+ * v4l2_async_notifier_add_devname_subdev - Allocate and add a device-name
+ *                             async subdev to the notifier's master asd_list.
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ * @device_name: device name string to be matched
+ * @asd_struct_size: size of the driver's async sub-device struct, including
+ *                  sizeof(struct v4l2_async_subdev). The &struct
+ *                  v4l2_async_subdev shall be the first member of
+ *                  the driver's async sub-device struct, i.e. both
+ *                  begin at the same memory address.
+ *
+ * Same as above but for device-name matched sub-devices.
+ */
+struct v4l2_async_subdev *
+v4l2_async_notifier_add_devname_subdev(struct v4l2_async_notifier *notifier,
+                                      const char *device_name,
+                                      unsigned int asd_struct_size);
+
 /**
  * v4l2_async_notifier_register - registers a subdevice asynchronous notifier
  *
@@ -164,7 +242,8 @@ int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
                                        struct v4l2_async_notifier *notifier);
 
 /**
- * v4l2_async_notifier_unregister - unregisters a subdevice asynchronous notifier
+ * v4l2_async_notifier_unregister - unregisters a subdevice
+ *     asynchronous notifier
  *
  * @notifier: pointer to &struct v4l2_async_notifier
  */
@@ -177,7 +256,9 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
  * Release memory resources related to a notifier, including the async
  * sub-devices allocated for the purposes of the notifier but not the notifier
  * itself. The user is responsible for calling this function to clean up the
- * notifier after calling @v4l2_async_notifier_parse_fwnode_endpoints or
+ * notifier after calling
+ * @v4l2_async_notifier_add_subdev,
+ * @v4l2_async_notifier_parse_fwnode_endpoints or
  * @v4l2_fwnode_reference_parse_sensor_common.
  *
  * There is no harm from calling v4l2_async_notifier_cleanup in other
@@ -213,8 +294,8 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd);
  * An error is returned if the module is no longer loaded on any attempts
  * to register it.
  */
-int __must_check v4l2_async_register_subdev_sensor_common(
-       struct v4l2_subdev *sd);
+int __must_check
+v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd);
 
 /**
  * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous