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
|
@ -474,19 +474,25 @@ int v4l2_async_subdev_notifier_register(struct v4l2_subdev *sd,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(v4l2_async_subdev_notifier_register);
|
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;
|
return;
|
||||||
|
|
||||||
mutex_lock(&list_lock);
|
|
||||||
|
|
||||||
v4l2_async_notifier_unbind_all_subdevs(notifier);
|
v4l2_async_notifier_unbind_all_subdevs(notifier);
|
||||||
|
|
||||||
notifier->sd = NULL;
|
notifier->sd = NULL;
|
||||||
notifier->v4l2_dev = NULL;
|
notifier->v4l2_dev = NULL;
|
||||||
|
|
||||||
list_del(¬ifier->list);
|
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);
|
mutex_unlock(&list_lock);
|
||||||
}
|
}
|
||||||
|
@ -596,6 +602,11 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd)
|
||||||
{
|
{
|
||||||
mutex_lock(&list_lock);
|
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) {
|
if (sd->asd) {
|
||||||
struct v4l2_async_notifier *notifier = sd->notifier;
|
struct v4l2_async_notifier *notifier = sd->notifier;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include <media/v4l2-async.h>
|
#include <media/v4l2-async.h>
|
||||||
#include <media/v4l2-fwnode.h>
|
#include <media/v4l2-fwnode.h>
|
||||||
|
#include <media/v4l2-subdev.h>
|
||||||
|
|
||||||
enum v4l2_fwnode_bus_type {
|
enum v4l2_fwnode_bus_type {
|
||||||
V4L2_FWNODE_BUS_TYPE_GUESS = 0,
|
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);
|
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_LICENSE("GPL");
|
||||||
MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
|
MODULE_AUTHOR("Sakari Ailus <sakari.ailus@linux.intel.com>");
|
||||||
MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.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);
|
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
|
* v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous
|
||||||
* subdevice framework
|
* subdevice framework
|
||||||
|
|
|
@ -793,6 +793,8 @@ struct v4l2_subdev_platform_data {
|
||||||
* list.
|
* list.
|
||||||
* @asd: Pointer to respective &struct v4l2_async_subdev.
|
* @asd: Pointer to respective &struct v4l2_async_subdev.
|
||||||
* @notifier: Pointer to the managing notifier.
|
* @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
|
* @pdata: common part of subdevice platform data
|
||||||
*
|
*
|
||||||
* Each instance of a subdev driver should create this struct, either
|
* Each instance of a subdev driver should create this struct, either
|
||||||
|
@ -823,6 +825,7 @@ struct v4l2_subdev {
|
||||||
struct list_head async_list;
|
struct list_head async_list;
|
||||||
struct v4l2_async_subdev *asd;
|
struct v4l2_async_subdev *asd;
|
||||||
struct v4l2_async_notifier *notifier;
|
struct v4l2_async_notifier *notifier;
|
||||||
|
struct v4l2_async_notifier *subdev_notifier;
|
||||||
struct v4l2_subdev_platform_data *pdata;
|
struct v4l2_subdev_platform_data *pdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue