Re: v4l subdevs without big device was Re: drivers/media/i2c/adp1653.c: does not show as /dev/video* or v4l-subdev*

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

 



Hi!

> > Warning: I'm no DT expert, so this is just a first attempt.
> > 
> > Platform drivers (omap3isp) will have to add these controller devices to the list
> > of subdevs to load asynchronously.
> 
> I seem to have patches I haven't had time to push back then:
> 
> <URL:http://salottisipuli.retiisi.org.uk/cgi-bin/gitweb.cgi?p=~sailus/linux.git;a=shortlog;h=refs/heads/leds-as3645a>
> 
> This seems to be mostly in line with what has been discussed in the meeting,
> except that the patches add a device specific property. Please ignore the
> led patches in that tree for now (i.e. four patches on the top are the
> relevant ones here).

Ok, I attempted to forward-port the patches to v4.6. Not sure if I was successful.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
>From fad952ee3d1e888401b047c9657f04afeaf40fc5 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@xxxxxx>
Date: Sat, 16 May 2015 23:34:34 +0300
Subject: [PATCH 1/5] omap3isp: Fix async notifier registration order

The async notifier was registered before the v4l2_device was registered and
before the notifier callbacks were set. This could lead to missing the
bound() and complete() callbacks and to attempting to spin_lock() and
uninitialised spin lock.

Also fix unregistering the async notifier in the case of an error --- the
function may not fail anymore after the notifier is registered.

Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxx>

Conflicts:
	drivers/media/platform/omap3isp/isp.c
---
 arch/arm/boot/dts/omap3-n900.dts      | 24 ++++++++++++++++++++++++
 drivers/media/i2c/ad5820.c            |  2 +-
 drivers/media/i2c/adp1653.c           |  9 ++++++++-
 drivers/media/platform/omap3isp/isp.c | 12 ++++++++++++
 4 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 640d409..0729c69 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -186,6 +186,7 @@
 		module {
 			model = "TCM8341MD";
 			sensor = <&cam1>;
+			focus = <&autofocus>;			
 		};
 	};
 
@@ -198,6 +199,11 @@
 		};
 	};
 
+	autofocus: dac-camera-autofocus {
+		compatible = "dac-camera-autofocus";
+		io-channels = <&ad5820>;
+	};
+
 	video-bus-switch {
 		compatible = "video-bus-switch";
 
@@ -255,6 +261,11 @@
 				crc = <0>;
 			};
 		};
+		port@99 {
+			adp1653_link: endpoint {
+				      remote-endpoint = <&adp1653_ep>;
+			};
+		};
 	};
 };
 
@@ -696,6 +707,11 @@
 		indicator {
 			led-max-microamp = <17500>;
 		};
+		port {
+			adp1653_ep: endpoint {
+				   remote-endpoint = <&adp1653_link>;
+ 			};
+ 		};
 	};
 
 	lp5523: lp5523@32 {
@@ -879,6 +895,14 @@
 			};
 		};
 	};
+
+	/* D/A converter for auto-focus */
+	ad5820: dac@0c {
+		compatible = "adi,ad5820";
+		reg = <0x0c>;
+
+		#io-channel-cells = <0>;
+	};
 };
 
 &mmc1 {
diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c
index 58a44f1..400200c 100644
--- a/drivers/media/i2c/ad5820.c
+++ b/drivers/media/i2c/ad5820.c
@@ -421,7 +421,7 @@ static int ad5820_probe(struct i2c_client *client,
 	coil->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	coil->subdev.internal_ops = &ad5820_internal_ops;
 
-	ret = media_entity_init(&coil->subdev.entity, 0, NULL, 0);
+	ret = media_entity_pads_init(&coil->subdev.entity, 0, NULL);
 	if (ret < 0)
 		kfree(coil);
 
diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c
index b90e15b..6dd5d6a 100644
--- a/drivers/media/i2c/adp1653.c
+++ b/drivers/media/i2c/adp1653.c
@@ -515,6 +515,7 @@ static int adp1653_probe(struct i2c_client *client,
 	v4l2_i2c_subdev_init(&flash->subdev, client, &adp1653_ops);
 	flash->subdev.internal_ops = &adp1653_internal_ops;
 	flash->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	strcpy(flash->subdev.name, "adp1653 flash");
 
 	ret = adp1653_init_controls(flash);
 	if (ret)
@@ -524,7 +525,13 @@ static int adp1653_probe(struct i2c_client *client,
 	if (ret < 0)
 		goto free_and_quit;
 
-	dev_info(&client->dev, "adp1653 probe: should be ok\n");		
+	dev_info(&client->dev, "adp1653 probe: should be ok\n");
+
+	ret = v4l2_async_register_subdev(&flash->subdev);
+	if (ret < 0)
+		goto free_and_quit;
+
+	dev_info(&client->dev, "adp1653 probe: async register subdev ok\n");	
 
 	flash->subdev.entity.function = MEDIA_ENT_F_FLASH;
 
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 6361fde..9f51127 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2392,6 +2392,7 @@ static int isp_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto error_modules;
 
+<<<<<<< HEAD
 	ret = isp_create_links(isp);
 	if (ret < 0)
 		goto error_register_entities;
@@ -2402,6 +2403,17 @@ static int isp_probe(struct platform_device *pdev)
 	ret = v4l2_async_notifier_register(&isp->v4l2_dev, &isp->notifier);
 	if (ret)
 		goto error_register_entities;
+=======
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		isp->notifier.bound = isp_subdev_notifier_bound;
+		isp->notifier.complete = isp_subdev_notifier_complete;
+
+		ret = v4l2_async_notifier_register(&isp->v4l2_dev,
+						   &isp->notifier);
+		if (ret)
+			goto error_register_entities;
+	}
+>>>>>>> a035633... omap3isp: Fix async notifier registration order
 
 	isp_core_init(isp, 1);
 	omap3isp_put(isp);
-- 
2.1.4

>From 4f8286dfb13a14c1e166a61837ec20f5a096ed7b Mon Sep 17 00:00:00 2001
From: Pavel <pavel@xxxxxx>
Date: Fri, 29 Apr 2016 12:02:07 +0200
Subject: [PATCH 2/5] Solve conflict I missed.

---
 drivers/media/platform/omap3isp/isp.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 9f51127..7419404 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2392,18 +2392,14 @@ static int isp_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto error_modules;
 
-<<<<<<< HEAD
 	ret = isp_create_links(isp);
 	if (ret < 0)
 		goto error_register_entities;
 
-	isp->notifier.bound = isp_subdev_notifier_bound;
-	isp->notifier.complete = isp_subdev_notifier_complete;
-
 	ret = v4l2_async_notifier_register(&isp->v4l2_dev, &isp->notifier);
 	if (ret)
 		goto error_register_entities;
-=======
+
 	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
 		isp->notifier.bound = isp_subdev_notifier_bound;
 		isp->notifier.complete = isp_subdev_notifier_complete;
@@ -2413,7 +2409,6 @@ static int isp_probe(struct platform_device *pdev)
 		if (ret)
 			goto error_register_entities;
 	}
->>>>>>> a035633... omap3isp: Fix async notifier registration order
 
 	isp_core_init(isp, 1);
 	omap3isp_put(isp);
-- 
2.1.4

>From b402e5a19c46a9c264a311b7656c0e7e0d65322f Mon Sep 17 00:00:00 2001
From: Pavel <pavel@xxxxxx>
Date: Fri, 29 Apr 2016 12:06:32 +0200
Subject: [PATCH 3/5] Cherry-pick (manually)

commit b3691ff97a99bcf28790c4da906ffc17c822844a
Author: Sakari Ailus <sakari.ailus@xxxxxx>
Date:   Sat May 16 23:56:03 2015 +0300

    omap3isp: Support the ti,camera-flashes property

    Before this patch the omap3isp driver only supported external
    devices that
        are connected to it by a data bus. This patch adds support for
    flash
        devices, in form of an array of phandles to sensor and
    associated flash
        devices, respectively, in the "ti,camera-flashes" property.

    The non image source devices are recognised by empty bus field in
    struct
        isp_async_subdev, which is made a pointer by the patch.

    Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxx>
---
 drivers/media/platform/omap3isp/isp.c       | 90 +++++++++++++++++++++--------
 drivers/media/platform/omap3isp/isp.h       |  2 +-
 drivers/media/platform/omap3isp/ispcsiphy.c |  2 +-
 3 files changed, 67 insertions(+), 27 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 7419404..a1c3bdb 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2095,13 +2095,20 @@ static void isp_of_parse_node_csi2(struct device *dev,
 	buscfg->bus.csi2.crc = 1;
 }
 
-static int isp_of_parse_node(struct device *dev, struct device_node *node,
-			     struct isp_async_subdev *isd)
+static int isp_of_parse_node_endpoint(struct device *dev,
+				      struct device_node *node,
+				      struct isp_async_subdev *isd)
 {
-	struct isp_bus_cfg *buscfg = &isd->bus;
+	struct isp_bus_cfg *buscfg;
 	struct v4l2_of_endpoint vep;
 	int ret;
 
+	isd->bus = devm_kzalloc(dev, sizeof(*isd->bus), GFP_KERNEL);
+	if (!isd->bus)
+		return -ENOMEM;
+
+	buscfg = isd->bus;
+
 	ret = v4l2_of_parse_endpoint(node, &vep);
 	if (ret)
 		return ret;
@@ -2144,10 +2151,48 @@ static int isp_of_parse_node(struct device *dev, struct device_node *node,
 	return 0;
 }
 
+static int isp_of_parse_node(struct device *dev, struct device_node *node,
+			     struct v4l2_async_notifier *notifier, bool link)
+{
+	struct isp_async_subdev *isd;
+
+	isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL);
+	if (!isd) {
+		of_node_put(node);
+		return -ENOMEM;
+	}
+
+	notifier->subdevs[notifier->num_subdevs] = &isd->asd;
+
+	if (link) {
+		if (isp_of_parse_node_endpoint(dev, node, isd)) {
+			of_node_put(node);
+			return -EINVAL;
+		}
+
+		isd->asd.match.of.node = of_graph_get_remote_port_parent(node);
+		of_node_put(node);
+	} else {
+		isd->asd.match.of.node = node;
+	}
+
+	if (!isd->asd.match.of.node) {
+		dev_warn(dev, "bad remote port parent\n");
+		return -EINVAL;
+	}
+
+	isd->asd.match_type = V4L2_ASYNC_MATCH_OF;
+	notifier->num_subdevs++;
+
+	return 0;
+}
+
 static int isp_of_parse_nodes(struct device *dev,
 			      struct v4l2_async_notifier *notifier)
 {
 	struct device_node *node = NULL;
+	int ret;
+	unsigned int flash = 0;
 
 	notifier->subdevs = devm_kcalloc(
 		dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL);
@@ -2156,30 +2201,25 @@ static int isp_of_parse_nodes(struct device *dev,
 
 	while (notifier->num_subdevs < ISP_MAX_SUBDEVS &&
 	       (node = of_graph_get_next_endpoint(dev->of_node, node))) {
-		struct isp_async_subdev *isd;
-
-		isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL);
-		if (!isd) {
-			of_node_put(node);
-			return -ENOMEM;
-		}
-
-		notifier->subdevs[notifier->num_subdevs] = &isd->asd;
-
-		if (isp_of_parse_node(dev, node, isd)) {
-			of_node_put(node);
-			return -EINVAL;
-		}
+		ret = isp_of_parse_node(dev, node, notifier, true);
+		if (ret)
+			return ret;
+	}
 
-		isd->asd.match.of.node = of_graph_get_remote_port_parent(node);
-		of_node_put(node);
-		if (!isd->asd.match.of.node) {
-			dev_warn(dev, "bad remote port parent\n");
+	while (notifier->num_subdevs < ISP_MAX_SUBDEVS &&
+	       (node = of_parse_phandle(dev->of_node, "ti,camera-flashes",
+					flash++))) {
+		struct device_node *sensor_node =
+			of_parse_phandle(dev->of_node, "ti,camera-flashes",
+					 flash++);
+		unsigned int i;
+
+		if (!sensor_node)
 			return -EINVAL;
-		}
 
-		isd->asd.match_type = V4L2_ASYNC_MATCH_OF;
-		notifier->num_subdevs++;
+		ret = isp_of_parse_node(dev, node, notifier, false);
+		if (ret)
+			return ret;
 	}
 
 	return notifier->num_subdevs;
@@ -2193,7 +2233,7 @@ static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,
 		container_of(asd, struct isp_async_subdev, asd);
 
 	isd->sd = subdev;
-	isd->sd->host_priv = &isd->bus;
+	isd->sd->host_priv = isd->bus;
 
 	return 0;
 }
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index 7e6f663..c0b9d1d 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -228,7 +228,7 @@ struct isp_device {
 
 struct isp_async_subdev {
 	struct v4l2_subdev *sd;
-	struct isp_bus_cfg bus;
+	struct isp_bus_cfg *bus;
 	struct v4l2_async_subdev asd;
 };
 
diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c
index 495447d..750ce93 100644
--- a/drivers/media/platform/omap3isp/ispcsiphy.c
+++ b/drivers/media/platform/omap3isp/ispcsiphy.c
@@ -177,7 +177,7 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy)
 		struct isp_async_subdev *isd =
 			container_of(pipe->external->asd,
 				     struct isp_async_subdev, asd);
-		buscfg = &isd->bus;
+		buscfg = isd->bus;
 	}
 
 	if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1
-- 
2.1.4

>From 568ea9c5c8aa61ee44e30aa4134d2b59e55a5b45 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@xxxxxx>
Date: Sat, 23 May 2015 15:24:55 +0300
Subject: [PATCH 4/5] omap3isp: Assign a group ID for sensor and flash entities

Starting from zero, assign a group ID for each sensor. Look for the
associated flash device node and based on nodes found, assign the same group
ID for them.

Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxx>
---
 drivers/media/platform/omap3isp/isp.c | 42 ++++++++++++++++++++++++++++++++---
 drivers/media/platform/omap3isp/isp.h |  1 +
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index a1c3bdb..f89abea 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2152,7 +2152,8 @@ static int isp_of_parse_node_endpoint(struct device *dev,
 }
 
 static int isp_of_parse_node(struct device *dev, struct device_node *node,
-			     struct v4l2_async_notifier *notifier, bool link)
+			     struct v4l2_async_notifier *notifier,
+			     u32 group_id, bool link)
 {
 	struct isp_async_subdev *isd;
 
@@ -2182,6 +2183,7 @@ static int isp_of_parse_node(struct device *dev, struct device_node *node,
 	}
 
 	isd->asd.match_type = V4L2_ASYNC_MATCH_OF;
+	isd->group_id = group_id;
 	notifier->num_subdevs++;
 
 	return 0;
@@ -2193,6 +2195,7 @@ static int isp_of_parse_nodes(struct device *dev,
 	struct device_node *node = NULL;
 	int ret;
 	unsigned int flash = 0;
+	u32 group_id = 0;
 
 	notifier->subdevs = devm_kcalloc(
 		dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL);
@@ -2201,7 +2204,7 @@ static int isp_of_parse_nodes(struct device *dev,
 
 	while (notifier->num_subdevs < ISP_MAX_SUBDEVS &&
 	       (node = of_graph_get_next_endpoint(dev->of_node, node))) {
-		ret = isp_of_parse_node(dev, node, notifier, true);
+		ret = isp_of_parse_node(dev, node, notifier, group_id++, true);
 		if (ret)
 			return ret;
 	}
@@ -2213,11 +2216,43 @@ static int isp_of_parse_nodes(struct device *dev,
 			of_parse_phandle(dev->of_node, "ti,camera-flashes",
 					 flash++);
 		unsigned int i;
+		u32 flash_group_id;
 
 		if (!sensor_node)
 			return -EINVAL;
 
-		ret = isp_of_parse_node(dev, node, notifier, false);
+		for (i = 0; i < notifier->num_subdevs; i++) {
+			struct isp_async_subdev *isd = container_of(
+				notifier->subdevs[i], struct isp_async_subdev,
+				asd);
+
+			if (!isd->bus)
+				continue;
+
+			dev_dbg(dev, "match \"%s\", \"%s\"\n",sensor_node->name,
+				isd->asd.match.of.node->name);
+
+			if (sensor_node != isd->asd.match.of.node)
+				continue;
+
+			dev_dbg(dev, "found\n");
+
+			flash_group_id = isd->group_id;
+			break;
+		}
+
+		/*
+		 * No sensor was found --- complain and allocate a new
+		 * group ID.
+		 */
+		if (i == notifier->num_subdevs) {
+			dev_warn(dev, "no device node \"%s\" was found",
+				 sensor_node->name);
+			flash_group_id = group_id++;
+		}
+
+		ret = isp_of_parse_node(dev, node, notifier, flash_group_id,
+					false);
 		if (ret)
 			return ret;
 	}
@@ -2232,6 +2267,7 @@ static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,
 	struct isp_async_subdev *isd =
 		container_of(asd, struct isp_async_subdev, asd);
 
+	subdev->entity.group_id = isd->group_id;
 	isd->sd = subdev;
 	isd->sd->host_priv = isd->bus;
 
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index c0b9d1d..639b3ca 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -230,6 +230,7 @@ struct isp_async_subdev {
 	struct v4l2_subdev *sd;
 	struct isp_bus_cfg *bus;
 	struct v4l2_async_subdev asd;
+	u32 group_id;
 };
 
 #define v4l2_dev_to_isp_device(dev) \
-- 
2.1.4

>From 70e7eada67a5a4170f2a9e268d8134a7c773e225 Mon Sep 17 00:00:00 2001
From: Pavel <pavel@xxxxxx>
Date: Fri, 29 Apr 2016 12:13:24 +0200
Subject: [PATCH 5/5] Fix (work around?) compilation.

---
 drivers/media/platform/omap3isp/isp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index f89abea..dd96a4b 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2267,7 +2267,7 @@ static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,
 	struct isp_async_subdev *isd =
 		container_of(asd, struct isp_async_subdev, asd);
 
-	subdev->entity.group_id = isd->group_id;
+//	subdev->entity.group_id = isd->group_id;
 	isd->sd = subdev;
 	isd->sd->host_priv = isd->bus;
 
-- 
2.1.4


[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