forked from mirrors/linux
		
	media: v4l: fwnode: Add a convenience function for registering sensors
Add a convenience function for parsing firmware for information on related devices using v4l2_async_notifier_parse_fwnode_sensor_common() registering the notifier and finally the async sub-device itself. This should be useful for sensor drivers that do not have device specific requirements related to firmware information parsing or the async framework. Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se> Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
		
							parent
							
								
									7a9ec808ad
								
							
						
					
					
						commit
						aef69d5475
					
				
					 4 changed files with 81 additions and 4 deletions
				
			
		|  | @ -474,19 +474,25 @@ int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd, | |||
| } | ||||
| EXPORT_SYMBOL(v4l2_async_subdev_notifier_register); | ||||
| 
 | ||||
| void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) | ||||
| static void __v4l2_async_notifier_unregister( | ||||
| 	struct v4l2_async_notifier *notifier) | ||||
| { | ||||
| 	if (!notifier->v4l2_dev && !notifier->sd) | ||||
| 	if (!notifier || (!notifier->v4l2_dev && !notifier->sd)) | ||||
| 		return; | ||||
| 
 | ||||
| 	mutex_lock(&list_lock); | ||||
| 
 | ||||
| 	v4l2_async_notifier_unbind_all_subdevs(notifier); | ||||
| 
 | ||||
| 	notifier->sd = NULL; | ||||
| 	notifier->v4l2_dev = NULL; | ||||
| 
 | ||||
| 	list_del(¬ifier->list); | ||||
| } | ||||
| 
 | ||||
| void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) | ||||
| { | ||||
| 	mutex_lock(&list_lock); | ||||
| 
 | ||||
| 	__v4l2_async_notifier_unregister(notifier); | ||||
| 
 | ||||
| 	mutex_unlock(&list_lock); | ||||
| } | ||||
|  | @ -596,6 +602,11 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) | |||
| { | ||||
| 	mutex_lock(&list_lock); | ||||
| 
 | ||||
| 	__v4l2_async_notifier_unregister(sd->subdev_notifier); | ||||
| 	v4l2_async_notifier_cleanup(sd->subdev_notifier); | ||||
| 	kfree(sd->subdev_notifier); | ||||
| 	sd->subdev_notifier = NULL; | ||||
| 
 | ||||
| 	if (sd->asd) { | ||||
| 		struct v4l2_async_notifier *notifier = sd->notifier; | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ | |||
| 
 | ||||
| #include <media/v4l2-async.h> | ||||
| #include <media/v4l2-fwnode.h> | ||||
| #include <media/v4l2-subdev.h> | ||||
| 
 | ||||
| enum v4l2_fwnode_bus_type { | ||||
| 	V4L2_FWNODE_BUS_TYPE_GUESS = 0, | ||||
|  | @ -900,6 +901,46 @@ int v4l2_async_notifier_parse_fwnode_sensor_common( | |||
| } | ||||
| EXPORT_SYMBOL_GPL(v4l2_async_notifier_parse_fwnode_sensor_common); | ||||
| 
 | ||||
| int v4l2_async_register_subdev_sensor_common(struct v4l2_subdev *sd) | ||||
| { | ||||
| 	struct v4l2_async_notifier *notifier; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (WARN_ON(!sd->dev)) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	notifier = kzalloc(sizeof(*notifier), GFP_KERNEL); | ||||
| 	if (!notifier) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	ret = v4l2_async_notifier_parse_fwnode_sensor_common(sd->dev, | ||||
| 							     notifier); | ||||
| 	if (ret < 0) | ||||
| 		goto out_cleanup; | ||||
| 
 | ||||
| 	ret = v4l2_async_subdev_notifier_register(sd, notifier); | ||||
| 	if (ret < 0) | ||||
| 		goto out_cleanup; | ||||
| 
 | ||||
| 	ret = v4l2_async_register_subdev(sd); | ||||
| 	if (ret < 0) | ||||
| 		goto out_unregister; | ||||
| 
 | ||||
| 	sd->subdev_notifier = notifier; | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| out_unregister: | ||||
| 	v4l2_async_notifier_unregister(notifier); | ||||
| 
 | ||||
| out_cleanup: | ||||
| 	v4l2_async_notifier_cleanup(notifier); | ||||
| 	kfree(notifier); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(v4l2_async_register_subdev_sensor_common); | ||||
| 
 | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>"); | ||||
| MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>"); | ||||
|  |  | |||
|  | @ -173,6 +173,28 @@ void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier); | |||
|  */ | ||||
| int v4l2_async_register_subdev(struct v4l2_subdev *sd); | ||||
| 
 | ||||
| /**
 | ||||
|  * v4l2_async_register_subdev_sensor_common - registers a sensor sub-device to | ||||
|  *					      the asynchronous sub-device | ||||
|  *					      framework and parse set up common | ||||
|  *					      sensor related devices | ||||
|  * | ||||
|  * @sd: pointer to struct &v4l2_subdev | ||||
|  * | ||||
|  * This function is just like v4l2_async_register_subdev() with the exception | ||||
|  * that calling it will also parse firmware interfaces for remote references | ||||
|  * using v4l2_async_notifier_parse_fwnode_sensor_common() and registers the | ||||
|  * async sub-devices. The sub-device is similarly unregistered by calling | ||||
|  * v4l2_async_unregister_subdev(). | ||||
|  * | ||||
|  * While registered, the subdev module is marked as in-use. | ||||
|  * | ||||
|  * 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); | ||||
| 
 | ||||
| /**
 | ||||
|  * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous | ||||
|  * 	subdevice framework | ||||
|  |  | |||
|  | @ -793,6 +793,8 @@ struct v4l2_subdev_platform_data { | |||
|  *	list. | ||||
|  * @asd: Pointer to respective &struct v4l2_async_subdev. | ||||
|  * @notifier: Pointer to the managing notifier. | ||||
|  * @subdev_notifier: A sub-device notifier implicitly registered for the sub- | ||||
|  *		     device using v4l2_device_register_sensor_subdev(). | ||||
|  * @pdata: common part of subdevice platform data | ||||
|  * | ||||
|  * Each instance of a subdev driver should create this struct, either | ||||
|  | @ -823,6 +825,7 @@ struct v4l2_subdev { | |||
| 	struct list_head async_list; | ||||
| 	struct v4l2_async_subdev *asd; | ||||
| 	struct v4l2_async_notifier *notifier; | ||||
| 	struct v4l2_async_notifier *subdev_notifier; | ||||
| 	struct v4l2_subdev_platform_data *pdata; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Sakari Ailus
						Sakari Ailus