Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -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)
			    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 *
		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,
		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,
+5 −0
Original line number Original line Diff line number Diff line
@@ -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 {
	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 {
		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;
+3 −0
Original line number Original line Diff line number Diff line
@@ -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 {
	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;