diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c index bd4f3fe0e309..b6f93c1db3d2 100644 --- a/drivers/media/i2c/adv748x/adv748x-csi2.c +++ b/drivers/media/i2c/adv748x/adv748x-csi2.c @@ -296,13 +296,12 @@ int adv748x_csi2_init(struct adv748x_state *state, struct adv748x_csi2 *tx) if (!is_tx_enabled(tx)) return 0; + /* FIXME: Do endpoint matching again! */ + adv748x_subdev_init(&tx->sd, state, &adv748x_csi2_ops, MEDIA_ENT_F_VID_IF_BRIDGE, is_txa(tx) ? "txa" : "txb"); - /* Ensure that matching is based upon the endpoint fwnodes */ - tx->sd.fwnode = of_fwnode_handle(state->endpoints[tx->port]); - /* Register internal ops for incremental subdev registration */ tx->sd.internal_ops = &adv748x_csi2_internal_ops; diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c index 8dcd5e8b56f1..a1f86dbc9e1a 100644 --- a/drivers/media/i2c/max9286.c +++ b/drivers/media/i2c/max9286.c @@ -1051,7 +1051,6 @@ static const struct v4l2_ctrl_ops max9286_ctrl_ops = { static int max9286_v4l2_register(struct max9286_priv *priv) { struct device *dev = &priv->client->dev; - struct fwnode_handle *ep; int ret; int i; @@ -1093,25 +1092,14 @@ static int max9286_v4l2_register(struct max9286_priv *priv) if (ret) goto err_async; - ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), MAX9286_SRC_PAD, - 0, 0); - if (!ep) { - dev_err(dev, "Unable to retrieve endpoint on \"port@4\"\n"); - ret = -ENOENT; - goto err_async; - } - priv->sd.fwnode = ep; - ret = v4l2_async_register_subdev(&priv->sd); if (ret < 0) { dev_err(dev, "Unable to register subdevice\n"); - goto err_put_node; + goto err_async; } return 0; -err_put_node: - fwnode_handle_put(ep); err_async: v4l2_ctrl_handler_free(&priv->ctrls); max9286_v4l2_notifier_unregister(priv); diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index 01a2596282f0..f4e2e2f3972a 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -567,7 +567,6 @@ again: static int rdacm20_probe(struct i2c_client *client) { struct rdacm20_device *dev; - struct fwnode_handle *ep; int ret; dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); @@ -616,24 +615,12 @@ static int rdacm20_probe(struct i2c_client *client) if (ret < 0) goto error_free_ctrls; - ep = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL); - if (!ep) { - dev_err(&client->dev, - "Unable to get endpoint in node %pOF\n", - client->dev.of_node); - ret = -ENOENT; - goto error_free_ctrls; - } - dev->sd.fwnode = ep; - ret = v4l2_async_register_subdev(&dev->sd); if (ret) - goto error_put_node; + goto error_free_ctrls; return 0; -error_put_node: - fwnode_handle_put(ep); error_free_ctrls: v4l2_ctrl_handler_free(&dev->ctrls); error: @@ -650,7 +637,6 @@ static void rdacm20_remove(struct i2c_client *client) { struct rdacm20_device *dev = i2c_to_rdacm20(client); - fwnode_handle_put(dev->sd.fwnode); v4l2_async_unregister_subdev(&dev->sd); v4l2_ctrl_handler_free(&dev->ctrls); media_entity_cleanup(&dev->sd.entity); diff --git a/drivers/media/i2c/rdacm21.c b/drivers/media/i2c/rdacm21.c index 043fec778a5e..3454f7d73121 100644 --- a/drivers/media/i2c/rdacm21.c +++ b/drivers/media/i2c/rdacm21.c @@ -543,7 +543,6 @@ static int rdacm21_initialize(struct rdacm21_device *dev) static int rdacm21_probe(struct i2c_client *client) { struct rdacm21_device *dev; - struct fwnode_handle *ep; int ret; dev = devm_kzalloc(&client->dev, sizeof(*dev), GFP_KERNEL); @@ -588,24 +587,12 @@ static int rdacm21_probe(struct i2c_client *client) if (ret < 0) goto error_free_ctrls; - ep = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev), NULL); - if (!ep) { - dev_err(&client->dev, - "Unable to get endpoint in node %pOF\n", - client->dev.of_node); - ret = -ENOENT; - goto error_free_ctrls; - } - dev->sd.fwnode = ep; - ret = v4l2_async_register_subdev(&dev->sd); if (ret) - goto error_put_node; + goto error_free_ctrls; return 0; -error_put_node: - fwnode_handle_put(dev->sd.fwnode); error_free_ctrls: v4l2_ctrl_handler_free(&dev->ctrls); error: diff --git a/drivers/media/i2c/tc358746.c b/drivers/media/i2c/tc358746.c index 3f7e147ef594..f37373c257c6 100644 --- a/drivers/media/i2c/tc358746.c +++ b/drivers/media/i2c/tc358746.c @@ -1476,9 +1476,6 @@ static int tc358746_async_register(struct tc358746 *tc358746) if (err) goto err_cleanup; - tc358746->sd.fwnode = fwnode_graph_get_endpoint_by_id( - dev_fwnode(tc358746->sd.dev), TC358746_SOURCE, 0, 0); - err = v4l2_async_register_subdev(&tc358746->sd); if (err) goto err_unregister; @@ -1486,7 +1483,6 @@ static int tc358746_async_register(struct tc358746 *tc358746) return 0; err_unregister: - fwnode_handle_put(tc358746->sd.fwnode); v4l2_async_nf_unregister(&tc358746->notifier); err_cleanup: v4l2_async_nf_cleanup(&tc358746->notifier); @@ -1605,7 +1601,6 @@ static void tc358746_remove(struct i2c_client *client) v4l2_fwnode_endpoint_free(&tc358746->csi_vep); v4l2_async_nf_unregister(&tc358746->notifier); v4l2_async_nf_cleanup(&tc358746->notifier); - fwnode_handle_put(sd->fwnode); v4l2_async_unregister_subdev(sd); media_entity_cleanup(&sd->entity); diff --git a/drivers/media/platform/nxp/imx-mipi-csis.c b/drivers/media/platform/nxp/imx-mipi-csis.c index 3c08d101d947..8483ce576975 100644 --- a/drivers/media/platform/nxp/imx-mipi-csis.c +++ b/drivers/media/platform/nxp/imx-mipi-csis.c @@ -1364,13 +1364,6 @@ static int mipi_csis_subdev_init(struct mipi_csis_device *csis) sd->dev = csis->dev; - sd->fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(csis->dev), - 1, 0, 0); - if (!sd->fwnode) { - dev_err(csis->dev, "Unable to retrieve endpoint for port@1\n"); - return -ENOENT; - } - csis->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; csis->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 04ea6f9a8ed3..11d336e783bd 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -94,89 +94,36 @@ match_fwnode_one(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, struct fwnode_handle *sd_fwnode, struct v4l2_async_match_desc *match) { - struct fwnode_handle *other_fwnode; - struct fwnode_handle *dev_fwnode; - bool asd_fwnode_is_ep; - bool sd_fwnode_is_ep; - struct device *dev; + struct fwnode_handle *asd_dev_fwnode; + bool ret; dev_dbg(notifier_dev(notifier), "v4l2-async: fwnode match: need %pfw, trying %pfw\n", sd_fwnode, match->fwnode); - /* - * Both the subdev and the async subdev can provide either an endpoint - * fwnode or a device fwnode. Start with the simple case of direct - * fwnode matching. - */ if (sd_fwnode == match->fwnode) { dev_dbg(notifier_dev(notifier), "v4l2-async: direct match found\n"); return true; } - /* - * Otherwise, check if the sd fwnode and the asd fwnode refer to an - * endpoint or a device. If they're of the same type, there's no match. - * Technically speaking this checks if the nodes refer to a connected - * endpoint, which is the simplest check that works for both OF and - * ACPI. This won't make a difference, as drivers should not try to - * match unconnected endpoints. - */ - sd_fwnode_is_ep = fwnode_graph_is_endpoint(sd_fwnode); - asd_fwnode_is_ep = fwnode_graph_is_endpoint(match->fwnode); - - if (sd_fwnode_is_ep == asd_fwnode_is_ep) { + if (!fwnode_graph_is_endpoint(match->fwnode)) { dev_dbg(notifier_dev(notifier), "v4l2-async: direct match not found\n"); return false; } - /* - * The sd and asd fwnodes are of different types. Get the device fwnode - * parent of the endpoint fwnode, and compare it with the other fwnode. - */ - if (sd_fwnode_is_ep) { - dev_fwnode = fwnode_graph_get_port_parent(sd_fwnode); - other_fwnode = match->fwnode; - } else { - dev_fwnode = fwnode_graph_get_port_parent(match->fwnode); - other_fwnode = sd_fwnode; - } + asd_dev_fwnode = fwnode_graph_get_port_parent(match->fwnode); + + ret = sd_fwnode == asd_dev_fwnode; + + fwnode_handle_put(asd_dev_fwnode); dev_dbg(notifier_dev(notifier), - "v4l2-async: fwnode compat match: need %pfw, trying %pfw\n", - dev_fwnode, other_fwnode); + "v4l2-async: device--endpoint match %sfound\n", + ret ? "" : "not "); - fwnode_handle_put(dev_fwnode); - - if (dev_fwnode != other_fwnode) { - dev_dbg(notifier_dev(notifier), - "v4l2-async: compat match not found\n"); - return false; - } - - /* - * We have a heterogeneous match. Retrieve the struct device of the side - * that matched on a device fwnode to print its driver name. - */ - if (sd_fwnode_is_ep) - dev = notifier->v4l2_dev ? notifier->v4l2_dev->dev - : notifier->sd->dev; - else - dev = sd->dev; - - if (dev && dev->driver) { - if (sd_fwnode_is_ep) - dev_warn(dev, "Driver %s uses device fwnode, incorrect match may occur\n", - dev->driver->name); - dev_notice(dev, "Consider updating driver %s to match on endpoints\n", - dev->driver->name); - } - - dev_dbg(notifier_dev(notifier), "v4l2-async: compat match found\n"); - - return true; + return ret; } static bool match_fwnode(struct v4l2_async_notifier *notifier, @@ -816,12 +763,19 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) int ret; /* - * No reference taken. The reference is held by the device - * (struct v4l2_subdev.dev), and async sub-device does not - * exist independently of the device at any point of time. + * No reference taken. The reference is held by the device (struct + * v4l2_subdev.dev), and async sub-device does not exist independently + * of the device at any point of time. + * + * The async sub-device shall always be registered for its device node, + * not the endpoint node. */ - if (!sd->fwnode && sd->dev) + if (!sd->fwnode && sd->dev) { sd->fwnode = dev_fwnode(sd->dev); + } else if (fwnode_graph_is_endpoint(sd->fwnode)) { + dev_warn(sd->dev, "sub-device fwnode is an endpoint!\n"); + return -EINVAL; + } mutex_lock(&list_lock);