From 255a3eb2b7f539944d9117873dd50dcc3da79033 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 25 Sep 2017 01:47:44 +0300 Subject: [PATCH] FROMLIST: v4l: async: 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 (cherry picked from commit dd202f9d5346cacd785a482952f54b205eafcc64) https://git.linuxtv.org/sailus/media_tree.git/log/?h=010f7f4393fd http://www.spinics.net/lists/linux-media/msg122688.html Signed-off-by: Marc Herbert Conflicts: include/media/v4l2-subdev.h (convert to older documentation style) BUG=b:64133998 TEST=media device topology shows subdevs registered successfully TEST=no camera regression Change-Id: Ia4af50d7204173d17d04faf9575f6605a1400e46 Reviewed-on: https://chromium-review.googlesource.com/693700 Commit-Ready: Tomasz Figa Tested-by: Hyungwoo Yang Reviewed-by: Tomasz Figa Signed-off-by: Jacob Chen --- drivers/media/v4l2-core/v4l2-async.c | 5 ++++ drivers/media/v4l2-core/v4l2-fwnode.c | 41 +++++++++++++++++++++++++++ include/media/v4l2-async.h | 22 ++++++++++++++ include/media/v4l2-subdev.h | 3 ++ 4 files changed, 71 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index b20e458c1f46..2f072aab3048 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -584,6 +584,11 @@ void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) { struct v4l2_async_notifier *notifier = sd->notifier; + if (sd->subdev_notifier) + v4l2_async_notifier_unregister(sd->subdev_notifier); + v4l2_async_notifier_cleanup(sd->subdev_notifier); + kfree(sd->subdev_notifier); + if (!sd->asd) { if (!list_empty(&sd->async_list)) v4l2_async_cleanup(sd); diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 0c4fd245ae06..e3e73d6bd27a 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -29,6 +29,7 @@ #include #include +#include static int v4l2_fwnode_endpoint_parse_csi_bus(struct fwnode_handle *fwnode, struct v4l2_fwnode_endpoint *vep) @@ -765,6 +766,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 "); MODULE_AUTHOR("Sylwester Nawrocki "); diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 479c317fab2f..74f2ea27d117 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -172,6 +172,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 diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 735069f81699..28318dd124c7 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -750,6 +750,9 @@ struct v4l2_subdev { /* Pointer to the managing notifier. */ struct v4l2_async_notifier *notifier; /* common part of subdevice platform data */ + struct v4l2_async_notifier *subdev_notifier; + /* A sub-device notifier implicitly registered for the sub-device + using v4l2_device_register_sensor_subdev(). */ struct v4l2_subdev_platform_data *pdata; };