[PATCH v3 16/29] media: ov2680: Add endpoint matching support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add endpoint matching support and defer probe() until
the endpoint fwnode is available. This is necessary on ACPI
platforms where the bridge code creating the fwnodes may also e.g.
set the "clock-frequency" device property and add GPIO mappings.

Acked-by: Rui Miguel Silva <rmfrfs@xxxxxxxxx>
Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
---
 drivers/media/i2c/ov2680.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c
index d4ef34859914..52ae265612fa 100644
--- a/drivers/media/i2c/ov2680.c
+++ b/drivers/media/i2c/ov2680.c
@@ -103,6 +103,7 @@ struct ov2680_ctrls {
 
 struct ov2680_dev {
 	struct device			*dev;
+	struct fwnode_handle		*ep_fwnode;
 	struct regmap			*regmap;
 	struct v4l2_subdev		sd;
 
@@ -638,6 +639,7 @@ static int ov2680_v4l2_register(struct ov2680_dev *sensor)
 	sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	sensor->sd.fwnode = sensor->ep_fwnode;
 
 	ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
 	if (ret < 0)
@@ -799,29 +801,39 @@ static int ov2680_probe(struct i2c_client *client)
 	if (IS_ERR(sensor->regmap))
 		return PTR_ERR(sensor->regmap);
 
+	/*
+	 * Sometimes the fwnode graph is initialized by the bridge driver.
+	 * Bridge drivers doing this may also add GPIO mappings, wait for this.
+	 */
+	sensor->ep_fwnode = fwnode_graph_get_next_endpoint(dev_fwnode(dev),
+							   NULL);
+	if (!sensor->ep_fwnode)
+		return dev_err_probe(dev, -EPROBE_DEFER,
+				     "waiting for fwnode graph endpoint\n");
+
+	mutex_init(&sensor->lock);
+
 	ret = ov2680_parse_dt(sensor);
 	if (ret < 0)
-		return -EINVAL;
+		goto err_fwnode_put;
 
 	ret = ov2680_mode_init(sensor);
 	if (ret < 0)
-		return ret;
+		goto err_fwnode_put;
 
 	ret = ov2680_get_regulators(sensor);
 	if (ret < 0) {
 		dev_err(dev, "failed to get regulators\n");
-		return ret;
+		goto err_fwnode_put;
 	}
 
-	mutex_init(&sensor->lock);
-
 	/*
 	 * Power up and verify the chip now, so that if runtime pm is
 	 * disabled the chip is left on and streaming will work.
 	 */
 	ret = ov2680_power_on(sensor);
 	if (ret < 0)
-		goto lock_destroy;
+		goto err_fwnode_put;
 
 	ret = ov2680_check_id(sensor);
 	if (ret < 0)
@@ -848,9 +860,10 @@ static int ov2680_probe(struct i2c_client *client)
 	pm_runtime_put_noidle(&client->dev);
 err_powerdown:
 	ov2680_power_off(sensor);
-lock_destroy:
+err_fwnode_put:
 	dev_err(dev, "ov2680 init fail: %d\n", ret);
 	mutex_destroy(&sensor->lock);
+	fwnode_handle_put(sensor->ep_fwnode);
 
 	return ret;
 }
@@ -864,6 +877,7 @@ static void ov2680_remove(struct i2c_client *client)
 	mutex_destroy(&sensor->lock);
 	media_entity_cleanup(&sensor->sd.entity);
 	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
+	fwnode_handle_put(sensor->ep_fwnode);
 
 	/*
 	 * Disable runtime PM. In case runtime PM is disabled in the kernel,
-- 
2.41.0




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux