Commit ecdf0cfe authored by Sakari Ailus's avatar Sakari Ailus Committed by Mauro Carvalho Chehab

[media] v4l: async: Add fwnode match support

Add fwnode matching to complement OF node matching. And fwnode may also be
an OF node.

Do not enable fwnode matching yet. It will replace OF matching soon.
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Tested-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Tested-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent ca50c197
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -46,6 +47,16 @@ static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) ...@@ -46,6 +47,16 @@ static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
of_node_full_name(asd->match.of.node)); of_node_full_name(asd->match.of.node));
} }
static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
if (!is_of_node(sd->fwnode) || !is_of_node(asd->match.fwnode.fwnode))
return sd->fwnode == asd->match.fwnode.fwnode;
return !of_node_cmp(of_node_full_name(to_of_node(sd->fwnode)),
of_node_full_name(
to_of_node(asd->match.fwnode.fwnode)));
}
static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{ {
if (!asd->match.custom.match) if (!asd->match.custom.match)
...@@ -80,6 +91,9 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier * ...@@ -80,6 +91,9 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *
case V4L2_ASYNC_MATCH_OF: case V4L2_ASYNC_MATCH_OF:
match = match_of; match = match_of;
break; break;
case V4L2_ASYNC_MATCH_FWNODE:
match = match_fwnode;
break;
default: default:
/* Cannot happen, unless someone breaks us */ /* Cannot happen, unless someone breaks us */
WARN_ON(true); WARN_ON(true);
...@@ -158,6 +172,7 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, ...@@ -158,6 +172,7 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
case V4L2_ASYNC_MATCH_DEVNAME: case V4L2_ASYNC_MATCH_DEVNAME:
case V4L2_ASYNC_MATCH_I2C: case V4L2_ASYNC_MATCH_I2C:
case V4L2_ASYNC_MATCH_OF: case V4L2_ASYNC_MATCH_OF:
case V4L2_ASYNC_MATCH_FWNODE:
break; break;
default: default:
dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL, dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
......
...@@ -32,6 +32,7 @@ struct v4l2_async_notifier; ...@@ -32,6 +32,7 @@ struct v4l2_async_notifier;
* @V4L2_ASYNC_MATCH_DEVNAME: Match will use the device name * @V4L2_ASYNC_MATCH_DEVNAME: Match will use the device name
* @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address * @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address
* @V4L2_ASYNC_MATCH_OF: Match will use OF node * @V4L2_ASYNC_MATCH_OF: Match will use OF node
* @V4L2_ASYNC_MATCH_FWNODE: Match will use firmware node
* *
* This enum is used by the asyncrhronous sub-device logic to define the * This enum is used by the asyncrhronous sub-device logic to define the
* algorithm that will be used to match an asynchronous device. * algorithm that will be used to match an asynchronous device.
...@@ -41,6 +42,7 @@ enum v4l2_async_match_type { ...@@ -41,6 +42,7 @@ enum v4l2_async_match_type {
V4L2_ASYNC_MATCH_DEVNAME, V4L2_ASYNC_MATCH_DEVNAME,
V4L2_ASYNC_MATCH_I2C, V4L2_ASYNC_MATCH_I2C,
V4L2_ASYNC_MATCH_OF, V4L2_ASYNC_MATCH_OF,
V4L2_ASYNC_MATCH_FWNODE,
}; };
/** /**
...@@ -57,6 +59,9 @@ struct v4l2_async_subdev { ...@@ -57,6 +59,9 @@ struct v4l2_async_subdev {
struct { struct {
const struct device_node *node; const struct device_node *node;
} of; } of;
struct {
struct fwnode_handle *fwnode;
} fwnode;
struct { struct {
const char *name; const char *name;
} device_name; } device_name;
......
...@@ -788,6 +788,8 @@ struct v4l2_subdev_platform_data { ...@@ -788,6 +788,8 @@ struct v4l2_subdev_platform_data {
* @devnode: subdev device node * @devnode: subdev device node
* @dev: pointer to the physical device, if any * @dev: pointer to the physical device, if any
* @of_node: The device_node of the subdev, usually the same as dev->of_node. * @of_node: The device_node of the subdev, usually the same as dev->of_node.
* @fwnode: The fwnode_handle of the subdev, usually the same as
* either dev->of_node->fwnode or dev->fwnode (whichever is non-NULL).
* @async_list: Links this subdev to a global subdev_list or @notifier->done * @async_list: Links this subdev to a global subdev_list or @notifier->done
* list. * list.
* @asd: Pointer to respective &struct v4l2_async_subdev. * @asd: Pointer to respective &struct v4l2_async_subdev.
...@@ -819,6 +821,7 @@ struct v4l2_subdev { ...@@ -819,6 +821,7 @@ struct v4l2_subdev {
struct video_device *devnode; struct video_device *devnode;
struct device *dev; struct device *dev;
struct device_node *of_node; struct device_node *of_node;
struct fwnode_handle *fwnode;
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment