Commit d6701f13 authored by Ezequiel Garcia's avatar Ezequiel Garcia Committed by Mauro Carvalho Chehab
Browse files

media: atmel: Use v4l2_async_notifier_add_fwnode_remote_subdev



The use of v4l2_async_notifier_add_subdev will be discouraged.
Drivers are instead encouraged to use a helper such as
v4l2_async_notifier_add_fwnode_remote_subdev.

This fixes a misuse of the API, as v4l2_async_notifier_add_subdev
should get a kmalloc'ed struct v4l2_async_subdev,
removing some boilerplate code while at it.

Signed-off-by: default avatarEzequiel Garcia <ezequiel@collabora.com>
Reviewed-by: default avatarJacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: default avatarHelen Koike <helen.koike@collabora.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent c1cf3d89
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ struct isc_buffer {
struct isc_subdev_entity {
	struct v4l2_subdev		*sd;
	struct v4l2_async_subdev	*asd;
	struct device_node		*epn;
	struct v4l2_async_notifier      notifier;

	u32 pfe_cfg0;
+13 −33
Original line number Diff line number Diff line
@@ -70,7 +70,6 @@ struct frame_buffer {
struct isi_graph_entity {
	struct device_node *node;

	struct v4l2_async_subdev asd;
	struct v4l2_subdev *subdev;
};

@@ -1136,45 +1135,26 @@ static const struct v4l2_async_notifier_operations isi_graph_notify_ops = {
	.complete = isi_graph_notify_complete,
};

static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
{
	struct device_node *ep = NULL;
	struct device_node *remote;

	ep = of_graph_get_next_endpoint(node, ep);
	if (!ep)
		return -EINVAL;

	remote = of_graph_get_remote_port_parent(ep);
	of_node_put(ep);
	if (!remote)
		return -EINVAL;

	/* Remote node to connect */
	isi->entity.node = remote;
	isi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
	isi->entity.asd.match.fwnode = of_fwnode_handle(remote);
	return 0;
}

static int isi_graph_init(struct atmel_isi *isi)
{
	struct v4l2_async_subdev *asd;
	struct device_node *ep;
	int ret;

	/* Parse the graph to extract a list of subdevice DT nodes. */
	ret = isi_graph_parse(isi, isi->dev->of_node);
	if (ret < 0) {
		dev_err(isi->dev, "Graph parsing failed\n");
		return ret;
	}
	ep = of_graph_get_next_endpoint(isi->dev->of_node, NULL);
	if (!ep)
		return -EINVAL;

	v4l2_async_notifier_init(&isi->notifier);

	ret = v4l2_async_notifier_add_subdev(&isi->notifier, &isi->entity.asd);
	if (ret) {
		of_node_put(isi->entity.node);
		return ret;
	}
	asd = v4l2_async_notifier_add_fwnode_remote_subdev(
						&isi->notifier,
						of_fwnode_handle(ep),
						sizeof(*asd));
	of_node_put(ep);

	if (IS_ERR(asd))
		return PTR_ERR(asd);

	isi->notifier.ops = &isi_graph_notify_ops;

+15 −29
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@
static int isc_parse_dt(struct device *dev, struct isc_device *isc)
{
	struct device_node *np = dev->of_node;
	struct device_node *epn = NULL, *rem;
	struct device_node *epn = NULL;
	struct isc_subdev_entity *subdev_entity;
	unsigned int flags;
	int ret;
@@ -71,17 +71,9 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
		if (!epn)
			return 0;

		rem = of_graph_get_remote_port_parent(epn);
		if (!rem) {
			dev_notice(dev, "Remote device at %pOF not found\n",
				   epn);
			continue;
		}

		ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn),
						 &v4l2_epn);
		if (ret) {
			of_node_put(rem);
			ret = -EINVAL;
			dev_err(dev, "Could not parse the endpoint\n");
			break;
@@ -90,21 +82,10 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
		subdev_entity = devm_kzalloc(dev, sizeof(*subdev_entity),
					     GFP_KERNEL);
		if (!subdev_entity) {
			of_node_put(rem);
			ret = -ENOMEM;
			break;
		}

		/* asd will be freed by the subsystem once it's added to the
		 * notifier list
		 */
		subdev_entity->asd = kzalloc(sizeof(*subdev_entity->asd),
					     GFP_KERNEL);
		if (!subdev_entity->asd) {
			of_node_put(rem);
			ret = -ENOMEM;
			break;
		}
		subdev_entity->epn = epn;

		flags = v4l2_epn.bus.parallel.flags;

@@ -121,12 +102,10 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
			subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_CCIR_CRC |
					ISC_PFE_CFG0_CCIR656;

		subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
		subdev_entity->asd->match.fwnode = of_fwnode_handle(rem);
		list_add_tail(&subdev_entity->list, &isc->subdev_entities);
	}

	of_node_put(epn);

	return ret;
}

@@ -228,13 +207,20 @@ static int atmel_isc_probe(struct platform_device *pdev)
	}

	list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
		struct v4l2_async_subdev *asd;

		v4l2_async_notifier_init(&subdev_entity->notifier);

		ret = v4l2_async_notifier_add_subdev(&subdev_entity->notifier,
						     subdev_entity->asd);
		if (ret) {
			fwnode_handle_put(subdev_entity->asd->match.fwnode);
			kfree(subdev_entity->asd);
		asd = v4l2_async_notifier_add_fwnode_remote_subdev(
					&subdev_entity->notifier,
					of_fwnode_handle(subdev_entity->epn),
					sizeof(*asd));

		of_node_put(subdev_entity->epn);
		subdev_entity->epn = NULL;

		if (IS_ERR(asd)) {
			ret = PTR_ERR(asd);
			goto cleanup_subdev;
		}