All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/15] omap3isp driver DT support
@ 2015-03-25 22:57 Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 01/15] omap3isp: Fix error handling in probe Sakari Ailus
                   ` (14 more replies)
  0 siblings, 15 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

Hi folks,

Here's an update to the omap3isp DT support patchset. v1 can be found here:

<URL:http://www.spinics.net/lists/linux-media/msg87733.html>

Changes since v1:

patch 10:

- Add Kconfig dependency to MFD_SYSCON

patch 12:

- Rename "lane-polarity" property as "lane-polarities"

patch 13:

- Add node name to warning print when there are too few lane polarities.

patch 14:

- Fix comment about sub-device node registration in isp_register_entities().

- Add endpoint name to a debug print in isp_of_parse_node().

- Rework isp_of_parse_nodes(). Fixed issue with putting the acquired nodes,
  and correctly register multiple async sub-devices.

- Rename rval as ret.

- Obtain syscon register index from DT.

Patch 15:

- Fix the number of users.

-- 
Kind regards,
Sakari


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v2 01/15] omap3isp: Fix error handling in probe
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 02/15] omap3isp: Avoid a BUG_ON() in media_entity_create_link() Sakari Ailus
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

The mutex was not destroyed correctly if dma_coerce_mask_and_coherent()
failed for some reason.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 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 deca809..fb193b6 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2252,7 +2252,7 @@ static int isp_probe(struct platform_device *pdev)
 
 	ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32));
 	if (ret)
-		return ret;
+		goto error;
 
 	platform_set_drvdata(pdev, isp);
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 02/15] omap3isp: Avoid a BUG_ON() in media_entity_create_link()
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 01/15] omap3isp: Fix error handling in probe Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 03/15] omap3isp: Separate external link creation from platform data parsing Sakari Ailus
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

If an uninitialised v4l2_subdev struct was passed to
media_entity_create_link(), one of the BUG_ON()'s in the function will be
hit since media_entity.num_pads will be zero. Avoid this by checking whether
the num_pads field is non-zero for the interface.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/platform/omap3isp/isp.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index fb193b6..4ab674d 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1946,6 +1946,19 @@ static int isp_register_entities(struct isp_device *isp)
 			goto done;
 		}
 
+		/*
+		 * Not all interfaces are available on all revisions
+		 * of the ISP. The sub-devices of those interfaces
+		 * aren't initialised in such a case. Check this by
+		 * ensuring the num_pads is non-zero.
+		 */
+		if (!input->num_pads) {
+			dev_err(isp->dev, "%s: invalid input %u\n",
+				entity->name, subdevs->interface);
+			ret = -EINVAL;
+			goto done;
+		}
+
 		for (i = 0; i < sensor->entity.num_pads; i++) {
 			if (sensor->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
 				break;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 03/15] omap3isp: Separate external link creation from platform data parsing
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 01/15] omap3isp: Fix error handling in probe Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 02/15] omap3isp: Avoid a BUG_ON() in media_entity_create_link() Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 04/15] omap3isp: DT support for clocks Sakari Ailus
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

Move the code which connects the external entity to an ISP entity into a
separate function. This disconnects it from parsing the platform data.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/platform/omap3isp/isp.c |  143 +++++++++++++++++----------------
 1 file changed, 72 insertions(+), 71 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 4ab674d..f694615 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1832,6 +1832,77 @@ isp_register_subdev_group(struct isp_device *isp,
 	return sensor;
 }
 
+static int isp_link_entity(
+	struct isp_device *isp, struct media_entity *entity,
+	enum isp_interface_type interface)
+{
+	struct media_entity *input;
+	unsigned int flags;
+	unsigned int pad;
+	unsigned int i;
+
+	/* Connect the sensor to the correct interface module.
+	 * Parallel sensors are connected directly to the CCDC, while
+	 * serial sensors are connected to the CSI2a, CCP2b or CSI2c
+	 * receiver through CSIPHY1 or CSIPHY2.
+	 */
+	switch (interface) {
+	case ISP_INTERFACE_PARALLEL:
+		input = &isp->isp_ccdc.subdev.entity;
+		pad = CCDC_PAD_SINK;
+		flags = 0;
+		break;
+
+	case ISP_INTERFACE_CSI2A_PHY2:
+		input = &isp->isp_csi2a.subdev.entity;
+		pad = CSI2_PAD_SINK;
+		flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
+		break;
+
+	case ISP_INTERFACE_CCP2B_PHY1:
+	case ISP_INTERFACE_CCP2B_PHY2:
+		input = &isp->isp_ccp2.subdev.entity;
+		pad = CCP2_PAD_SINK;
+		flags = 0;
+		break;
+
+	case ISP_INTERFACE_CSI2C_PHY1:
+		input = &isp->isp_csi2c.subdev.entity;
+		pad = CSI2_PAD_SINK;
+		flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
+		break;
+
+	default:
+		dev_err(isp->dev, "%s: invalid interface type %u\n", __func__,
+			interface);
+		return -EINVAL;
+	}
+
+	/*
+	 * Not all interfaces are available on all revisions of the
+	 * ISP. The sub-devices of those interfaces aren't initialised
+	 * in such a case. Check this by ensuring the num_pads is
+	 * non-zero.
+	 */
+	if (!input->num_pads) {
+		dev_err(isp->dev, "%s: invalid input %u\n", entity->name,
+			interface);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < entity->num_pads; i++) {
+		if (entity->pads[i].flags & MEDIA_PAD_FL_SOURCE)
+			break;
+	}
+	if (i == entity->num_pads) {
+		dev_err(isp->dev, "%s: no source pad in external entity\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	return media_entity_create_link(entity, i, input, pad, flags);
+}
+
 static int isp_register_entities(struct isp_device *isp)
 {
 	struct isp_platform_data *pdata = isp->pdata;
@@ -1895,10 +1966,6 @@ static int isp_register_entities(struct isp_device *isp)
 	/* Register external entities */
 	for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
 		struct v4l2_subdev *sensor;
-		struct media_entity *input;
-		unsigned int flags;
-		unsigned int pad;
-		unsigned int i;
 
 		sensor = isp_register_subdev_group(isp, subdevs->subdevs);
 		if (sensor == NULL)
@@ -1906,73 +1973,7 @@ static int isp_register_entities(struct isp_device *isp)
 
 		sensor->host_priv = subdevs;
 
-		/* Connect the sensor to the correct interface module. Parallel
-		 * sensors are connected directly to the CCDC, while serial
-		 * sensors are connected to the CSI2a, CCP2b or CSI2c receiver
-		 * through CSIPHY1 or CSIPHY2.
-		 */
-		switch (subdevs->interface) {
-		case ISP_INTERFACE_PARALLEL:
-			input = &isp->isp_ccdc.subdev.entity;
-			pad = CCDC_PAD_SINK;
-			flags = 0;
-			break;
-
-		case ISP_INTERFACE_CSI2A_PHY2:
-			input = &isp->isp_csi2a.subdev.entity;
-			pad = CSI2_PAD_SINK;
-			flags = MEDIA_LNK_FL_IMMUTABLE
-			      | MEDIA_LNK_FL_ENABLED;
-			break;
-
-		case ISP_INTERFACE_CCP2B_PHY1:
-		case ISP_INTERFACE_CCP2B_PHY2:
-			input = &isp->isp_ccp2.subdev.entity;
-			pad = CCP2_PAD_SINK;
-			flags = 0;
-			break;
-
-		case ISP_INTERFACE_CSI2C_PHY1:
-			input = &isp->isp_csi2c.subdev.entity;
-			pad = CSI2_PAD_SINK;
-			flags = MEDIA_LNK_FL_IMMUTABLE
-			      | MEDIA_LNK_FL_ENABLED;
-			break;
-
-		default:
-			dev_err(isp->dev, "%s: invalid interface type %u\n",
-				__func__, subdevs->interface);
-			ret = -EINVAL;
-			goto done;
-		}
-
-		/*
-		 * Not all interfaces are available on all revisions
-		 * of the ISP. The sub-devices of those interfaces
-		 * aren't initialised in such a case. Check this by
-		 * ensuring the num_pads is non-zero.
-		 */
-		if (!input->num_pads) {
-			dev_err(isp->dev, "%s: invalid input %u\n",
-				entity->name, subdevs->interface);
-			ret = -EINVAL;
-			goto done;
-		}
-
-		for (i = 0; i < sensor->entity.num_pads; i++) {
-			if (sensor->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
-				break;
-		}
-		if (i == sensor->entity.num_pads) {
-			dev_err(isp->dev,
-				"%s: no source pad in external entity\n",
-				__func__);
-			ret = -EINVAL;
-			goto done;
-		}
-
-		ret = media_entity_create_link(&sensor->entity, i, input, pad,
-					       flags);
+		ret = isp_link_entity(isp, &sensor->entity, subdevs->interface);
 		if (ret < 0)
 			goto done;
 	}
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 04/15] omap3isp: DT support for clocks
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (2 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 03/15] omap3isp: Separate external link creation from platform data parsing Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 05/15] omap3isp: Platform data could be NULL Sakari Ailus
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/platform/omap3isp/isp.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index f694615..82499cd 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -279,9 +279,21 @@ static const struct clk_init_data isp_xclk_init_data = {
 	.num_parents = 1,
 };
 
+static struct clk *isp_xclk_src_get(struct of_phandle_args *clkspec, void *data)
+{
+	unsigned int idx = clkspec->args[0];
+	struct isp_device *isp = data;
+
+	if (idx >= ARRAY_SIZE(isp->xclks))
+		return ERR_PTR(-ENOENT);
+
+	return isp->xclks[idx].clk;
+}
+
 static int isp_xclk_init(struct isp_device *isp)
 {
 	struct isp_platform_data *pdata = isp->pdata;
+	struct device_node *np = isp->dev->of_node;
 	struct clk_init_data init;
 	unsigned int i;
 
@@ -312,6 +324,12 @@ static int isp_xclk_init(struct isp_device *isp)
 		if (IS_ERR(xclk->clk))
 			return PTR_ERR(xclk->clk);
 
+		/* When instantiated from DT we don't need to register clock
+		 * aliases.
+		 */
+		if (np)
+			continue;
+
 		if (pdata->xclks[i].con_id == NULL &&
 		    pdata->xclks[i].dev_id == NULL)
 			continue;
@@ -327,13 +345,20 @@ static int isp_xclk_init(struct isp_device *isp)
 		clkdev_add(xclk->lookup);
 	}
 
+	if (np)
+		of_clk_add_provider(np, isp_xclk_src_get, isp);
+
 	return 0;
 }
 
 static void isp_xclk_cleanup(struct isp_device *isp)
 {
+	struct device_node *np = isp->dev->of_node;
 	unsigned int i;
 
+	if (np)
+		of_clk_del_provider(np);
+
 	for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) {
 		struct isp_xclk *xclk = &isp->xclks[i];
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 05/15] omap3isp: Platform data could be NULL
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (3 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 04/15] omap3isp: DT support for clocks Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 06/15] omap3isp: Refactor device configuration structs for Device Tree Sakari Ailus
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

Only check for call platform data callback functions if there's platform
data. Also take care of a few other cases where the NULL pdata pointer could
have been accessed, and remove the check for NULL dev->platform_data
pointer.

Removing the check for NULL dev->platform_data isn't strictly needed by the
DT support but there's no harm from that either: the device now can be used
without sensors, for instance.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/platform/omap3isp/isp.c      |   10 ++++------
 drivers/media/platform/omap3isp/ispvideo.c |    6 +++---
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 82499cd..537377b 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -330,8 +330,8 @@ static int isp_xclk_init(struct isp_device *isp)
 		if (np)
 			continue;
 
-		if (pdata->xclks[i].con_id == NULL &&
-		    pdata->xclks[i].dev_id == NULL)
+		if (!pdata || (pdata->xclks[i].con_id == NULL &&
+			       pdata->xclks[i].dev_id == NULL))
 			continue;
 
 		xclk->lookup = kzalloc(sizeof(*xclk->lookup), GFP_KERNEL);
@@ -1989,7 +1989,8 @@ static int isp_register_entities(struct isp_device *isp)
 		goto done;
 
 	/* Register external entities */
-	for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
+	for (subdevs = pdata ? pdata->subdevs : NULL;
+	     subdevs && subdevs->subdevs; ++subdevs) {
 		struct v4l2_subdev *sensor;
 
 		sensor = isp_register_subdev_group(isp, subdevs->subdevs);
@@ -2271,9 +2272,6 @@ static int isp_probe(struct platform_device *pdev)
 	int ret;
 	int i, m;
 
-	if (pdata == NULL)
-		return -EINVAL;
-
 	isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL);
 	if (!isp) {
 		dev_err(&pdev->dev, "could not allocate memory\n");
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 0b5967e..d285af1 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -1018,7 +1018,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 
 	pipe->entities = 0;
 
-	if (video->isp->pdata->set_constraints)
+	if (video->isp->pdata && video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, true);
 	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
 	pipe->max_rate = pipe->l3_ick;
@@ -1100,7 +1100,7 @@ err_set_stream:
 err_check_format:
 	media_entity_pipeline_stop(&video->video.entity);
 err_pipeline_start:
-	if (video->isp->pdata->set_constraints)
+	if (video->isp->pdata && video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, false);
 	/* The DMA queue must be emptied here, otherwise CCDC interrupts that
 	 * will get triggered the next time the CCDC is powered up will try to
@@ -1161,7 +1161,7 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
 	video->queue = NULL;
 	video->error = false;
 
-	if (video->isp->pdata->set_constraints)
+	if (video->isp->pdata && video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, false);
 	media_entity_pipeline_stop(&video->video.entity);
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 06/15] omap3isp: Refactor device configuration structs for Device Tree
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (4 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 05/15] omap3isp: Platform data could be NULL Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 23:21   ` Tony Lindgren
  2015-03-25 22:57 ` [PATCH v2 07/15] omap3isp: Rename regulators to better suit the " Sakari Ailus
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media
  Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart, Igor Grinberg

Make omap3isp configuration data structures more suitable for consumption by
the DT by separating the I2C bus information of all the sub-devices in a
group and the ISP bus information from each other. The ISP bus information
is made a pointer instead of being directly embedded in the struct.

In the case of the DT only the sensor specific information on the ISP bus
configuration is retained. The structs are renamed to reflect that.

After this change the structs needed to describe device configuration can be
allocated and accessed separately without those needed only in the case of
platform data. The platform data related structs can be later removed once
the support for platform data can be removed.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Igor Grinberg <grinberg@compulab.co.il>
Acked-by: Igor Grinberg <grinberg@compulab.co.il> (for cm-t35)
---
 arch/arm/mach-omap2/board-cm-t35.c          |   57 +++++++-----------
 drivers/media/platform/omap3isp/isp.c       |   86 +++++++++++++--------------
 drivers/media/platform/omap3isp/isp.h       |    2 +-
 drivers/media/platform/omap3isp/ispccdc.c   |   26 ++++----
 drivers/media/platform/omap3isp/ispccp2.c   |   22 +++----
 drivers/media/platform/omap3isp/ispcsi2.c   |    8 +--
 drivers/media/platform/omap3isp/ispcsiphy.c |   21 ++++---
 include/media/omap3isp.h                    |   34 +++++------
 8 files changed, 119 insertions(+), 137 deletions(-)

diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 91738a1..b5dfbc1 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -492,51 +492,36 @@ static struct twl4030_platform_data cm_t35_twldata = {
 #include <media/omap3isp.h>
 #include "devices.h"
 
-static struct i2c_board_info cm_t35_isp_i2c_boardinfo[] = {
+static struct isp_platform_subdev cm_t35_isp_subdevs[] = {
 	{
-		I2C_BOARD_INFO("mt9t001", 0x5d),
-	},
-	{
-		I2C_BOARD_INFO("tvp5150", 0x5c),
-	},
-};
-
-static struct isp_subdev_i2c_board_info cm_t35_isp_primary_subdevs[] = {
-	{
-		.board_info = &cm_t35_isp_i2c_boardinfo[0],
-		.i2c_adapter_id = 3,
-	},
-	{ NULL, 0, },
-};
-
-static struct isp_subdev_i2c_board_info cm_t35_isp_secondary_subdevs[] = {
-	{
-		.board_info = &cm_t35_isp_i2c_boardinfo[1],
+		.board_info = &(struct i2c_board_info){
+			I2C_BOARD_INFO("mt9t001", 0x5d)
+		},
 		.i2c_adapter_id = 3,
-	},
-	{ NULL, 0, },
-};
-
-static struct isp_v4l2_subdevs_group cm_t35_isp_subdevs[] = {
-	{
-		.subdevs = cm_t35_isp_primary_subdevs,
-		.interface = ISP_INTERFACE_PARALLEL,
-		.bus = {
-			.parallel = {
-				.clk_pol = 1,
+		.bus = &(struct isp_bus_cfg){
+			.interface = ISP_INTERFACE_PARALLEL,
+			.bus = {
+				.parallel = {
+					.clk_pol = 1,
+				},
 			},
 		},
 	},
 	{
-		.subdevs = cm_t35_isp_secondary_subdevs,
-		.interface = ISP_INTERFACE_PARALLEL,
-		.bus = {
-			.parallel = {
-				.clk_pol = 0,
+		.board_info = &(struct i2c_board_info){
+			I2C_BOARD_INFO("tvp5150", 0x5c),
+		},
+		.i2c_adapter_id = 3,
+		.bus = &(struct isp_bus_cfg){
+			.interface = ISP_INTERFACE_PARALLEL,
+			.bus = {
+				.parallel = {
+					.clk_pol = 0,
+				},
 			},
 		},
 	},
-	{ NULL, 0, },
+	{ 0 },
 };
 
 static struct isp_platform_data cm_t35_isp_pdata = {
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 537377b..1b5c6df 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -447,7 +447,7 @@ static void isp_core_init(struct isp_device *isp, int idle)
  */
 void omap3isp_configure_bridge(struct isp_device *isp,
 			       enum ccdc_input_entity input,
-			       const struct isp_parallel_platform_data *pdata,
+			       const struct isp_parallel_cfg *parcfg,
 			       unsigned int shift, unsigned int bridge)
 {
 	u32 ispctrl_val;
@@ -462,8 +462,8 @@ void omap3isp_configure_bridge(struct isp_device *isp,
 	switch (input) {
 	case CCDC_INPUT_PARALLEL:
 		ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
-		ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
-		shift += pdata->data_lane_shift * 2;
+		ispctrl_val |= parcfg->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
+		shift += parcfg->data_lane_shift * 2;
 		break;
 
 	case CCDC_INPUT_CSI2A:
@@ -1809,52 +1809,44 @@ static void isp_unregister_entities(struct isp_device *isp)
 }
 
 /*
- * isp_register_subdev_group - Register a group of subdevices
+ * isp_register_subdev - Register a sub-device
  * @isp: OMAP3 ISP device
- * @board_info: I2C subdevs board information array
+ * @isp_subdev: platform data related to a sub-device
  *
- * Register all I2C subdevices in the board_info array. The array must be
- * terminated by a NULL entry, and the first entry must be the sensor.
+ * Register an I2C sub-device which has not been registered by other
+ * means (such as the Device Tree).
  *
- * Return a pointer to the sensor media entity if it has been successfully
+ * Return a pointer to the sub-device if it has been successfully
  * registered, or NULL otherwise.
  */
 static struct v4l2_subdev *
-isp_register_subdev_group(struct isp_device *isp,
-		     struct isp_subdev_i2c_board_info *board_info)
+isp_register_subdev(struct isp_device *isp,
+		    struct isp_platform_subdev *isp_subdev)
 {
-	struct v4l2_subdev *sensor = NULL;
-	unsigned int first;
+	struct i2c_adapter *adapter;
+	struct v4l2_subdev *sd;
 
-	if (board_info->board_info == NULL)
+	if (isp_subdev->board_info == NULL)
 		return NULL;
 
-	for (first = 1; board_info->board_info; ++board_info, first = 0) {
-		struct v4l2_subdev *subdev;
-		struct i2c_adapter *adapter;
-
-		adapter = i2c_get_adapter(board_info->i2c_adapter_id);
-		if (adapter == NULL) {
-			dev_err(isp->dev, "%s: Unable to get I2C adapter %d for "
-				"device %s\n", __func__,
-				board_info->i2c_adapter_id,
-				board_info->board_info->type);
-			continue;
-		}
-
-		subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
-				board_info->board_info, NULL);
-		if (subdev == NULL) {
-			dev_err(isp->dev, "%s: Unable to register subdev %s\n",
-				__func__, board_info->board_info->type);
-			continue;
-		}
+	adapter = i2c_get_adapter(isp_subdev->i2c_adapter_id);
+	if (adapter == NULL) {
+		dev_err(isp->dev,
+			"%s: Unable to get I2C adapter %d for device %s\n",
+			__func__, isp_subdev->i2c_adapter_id,
+			isp_subdev->board_info->type);
+		return NULL;
+	}
 
-		if (first)
-			sensor = subdev;
+	sd = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
+				       isp_subdev->board_info, NULL);
+	if (sd == NULL) {
+		dev_err(isp->dev, "%s: Unable to register subdev %s\n",
+			__func__, isp_subdev->board_info->type);
+		return NULL;
 	}
 
-	return sensor;
+	return sd;
 }
 
 static int isp_link_entity(
@@ -1931,7 +1923,7 @@ static int isp_link_entity(
 static int isp_register_entities(struct isp_device *isp)
 {
 	struct isp_platform_data *pdata = isp->pdata;
-	struct isp_v4l2_subdevs_group *subdevs;
+	struct isp_platform_subdev *isp_subdev;
 	int ret;
 
 	isp->media_dev.dev = isp->dev;
@@ -1989,17 +1981,23 @@ static int isp_register_entities(struct isp_device *isp)
 		goto done;
 
 	/* Register external entities */
-	for (subdevs = pdata ? pdata->subdevs : NULL;
-	     subdevs && subdevs->subdevs; ++subdevs) {
-		struct v4l2_subdev *sensor;
+	for (isp_subdev = pdata ? pdata->subdevs : NULL;
+	     isp_subdev && isp_subdev->board_info; isp_subdev++) {
+		struct v4l2_subdev *sd;
 
-		sensor = isp_register_subdev_group(isp, subdevs->subdevs);
-		if (sensor == NULL)
+		sd = isp_register_subdev(isp, isp_subdev);
+
+		/*
+		 * No bus information --- this is either a flash or a
+		 * lens subdev.
+		 */
+		if (!sd || !isp_subdev->bus)
 			continue;
 
-		sensor->host_priv = subdevs;
+		sd->host_priv = isp_subdev->bus;
 
-		ret = isp_link_entity(isp, &sensor->entity, subdevs->interface);
+		ret = isp_link_entity(isp, &sd->entity,
+				      isp_subdev->bus->interface);
 		if (ret < 0)
 			goto done;
 	}
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index cfdfc87..b932a6f 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -229,7 +229,7 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
 void omap3isp_pipeline_cancel_stream(struct isp_pipeline *pipe);
 void omap3isp_configure_bridge(struct isp_device *isp,
 			       enum ccdc_input_entity input,
-			       const struct isp_parallel_platform_data *pdata,
+			       const struct isp_parallel_cfg *buscfg,
 			       unsigned int shift, unsigned int bridge);
 
 struct isp_device *omap3isp_get(struct isp_device *isp);
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 587489a..388f971 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -958,11 +958,11 @@ void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
 /*
  * ccdc_config_sync_if - Set CCDC sync interface configuration
  * @ccdc: Pointer to ISP CCDC device.
- * @pdata: Parallel interface platform data (may be NULL)
+ * @parcfg: Parallel interface platform data (may be NULL)
  * @data_size: Data size
  */
 static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
-				struct isp_parallel_platform_data *pdata,
+				struct isp_parallel_cfg *parcfg,
 				unsigned int data_size)
 {
 	struct isp_device *isp = to_isp_device(ccdc);
@@ -1000,19 +1000,19 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
 		break;
 	}
 
-	if (pdata && pdata->data_pol)
+	if (parcfg && parcfg->data_pol)
 		syn_mode |= ISPCCDC_SYN_MODE_DATAPOL;
 
-	if (pdata && pdata->hs_pol)
+	if (parcfg && parcfg->hs_pol)
 		syn_mode |= ISPCCDC_SYN_MODE_HDPOL;
 
 	/* The polarity of the vertical sync signal output by the BT.656
 	 * decoder is not documented and seems to be active low.
 	 */
-	if ((pdata && pdata->vs_pol) || ccdc->bt656)
+	if ((parcfg && parcfg->vs_pol) || ccdc->bt656)
 		syn_mode |= ISPCCDC_SYN_MODE_VDPOL;
 
-	if (pdata && pdata->fld_pol)
+	if (parcfg && parcfg->fld_pol)
 		syn_mode |= ISPCCDC_SYN_MODE_FLDPOL;
 
 	isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
@@ -1115,7 +1115,7 @@ static const u32 ccdc_sgbrg_pattern =
 static void ccdc_configure(struct isp_ccdc_device *ccdc)
 {
 	struct isp_device *isp = to_isp_device(ccdc);
-	struct isp_parallel_platform_data *pdata = NULL;
+	struct isp_parallel_cfg *parcfg = NULL;
 	struct v4l2_subdev *sensor;
 	struct v4l2_mbus_framefmt *format;
 	const struct v4l2_rect *crop;
@@ -1145,7 +1145,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
 		if (!ret)
 			ccdc->bt656 = cfg.type == V4L2_MBUS_BT656;
 
-		pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
+		parcfg = &((struct isp_bus_cfg *)sensor->host_priv)
 			->bus.parallel;
 	}
 
@@ -1175,10 +1175,10 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
 	else
 		bridge = ISPCTRL_PAR_BRIDGE_DISABLE;
 
-	omap3isp_configure_bridge(isp, ccdc->input, pdata, shift, bridge);
+	omap3isp_configure_bridge(isp, ccdc->input, parcfg, shift, bridge);
 
 	/* Configure the sync interface. */
-	ccdc_config_sync_if(ccdc, pdata, depth_out);
+	ccdc_config_sync_if(ccdc, parcfg, depth_out);
 
 	syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
 
@@ -2417,11 +2417,11 @@ static int ccdc_link_validate(struct v4l2_subdev *sd,
 
 	/* We've got a parallel sensor here. */
 	if (ccdc->input == CCDC_INPUT_PARALLEL) {
-		struct isp_parallel_platform_data *pdata =
-			&((struct isp_v4l2_subdevs_group *)
+		struct isp_parallel_cfg *parcfg =
+			&((struct isp_bus_cfg *)
 			  media_entity_to_v4l2_subdev(link->source->entity)
 			  ->host_priv)->bus.parallel;
-		parallel_shift = pdata->data_lane_shift * 2;
+		parallel_shift = parcfg->data_lane_shift * 2;
 	} else {
 		parallel_shift = 0;
 	}
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index f4aedb3..374a1f4 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -201,14 +201,14 @@ static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable)
 /*
  * ccp2_phyif_config - Initialize CCP2 phy interface config
  * @ccp2: Pointer to ISP CCP2 device
- * @pdata: CCP2 platform data
+ * @buscfg: CCP2 platform data
  *
  * Configure the CCP2 physical interface module from platform data.
  *
  * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success.
  */
 static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
-			     const struct isp_ccp2_platform_data *pdata)
+			     const struct isp_ccp2_cfg *buscfg)
 {
 	struct isp_device *isp = to_isp_device(ccp2);
 	u32 val;
@@ -218,16 +218,16 @@ static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
 			    ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE;
 	/* Data/strobe physical layer */
 	BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK,
-		pdata->phy_layer);
+		buscfg->phy_layer);
 	BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK,
-		pdata->strobe_clk_pol);
+		buscfg->strobe_clk_pol);
 	isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
 
 	val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
 	if (!(val & ISPCCP2_CTRL_MODE)) {
-		if (pdata->ccp2_mode == ISP_CCP2_MODE_CCP2)
+		if (buscfg->ccp2_mode == ISP_CCP2_MODE_CCP2)
 			dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n");
-		if (pdata->phy_layer == ISP_CCP2_PHY_DATA_STROBE)
+		if (buscfg->phy_layer == ISP_CCP2_PHY_DATA_STROBE)
 			/* Strobe mode requires CCP2 */
 			return -EIO;
 	}
@@ -347,7 +347,7 @@ static void ccp2_lcx_config(struct isp_ccp2_device *ccp2,
  */
 static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
 {
-	const struct isp_v4l2_subdevs_group *pdata;
+	const struct isp_bus_cfg *buscfg;
 	struct v4l2_mbus_framefmt *format;
 	struct media_pad *pad;
 	struct v4l2_subdev *sensor;
@@ -358,20 +358,20 @@ static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
 
 	pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]);
 	sensor = media_entity_to_v4l2_subdev(pad->entity);
-	pdata = sensor->host_priv;
+	buscfg = sensor->host_priv;
 
-	ret = ccp2_phyif_config(ccp2, &pdata->bus.ccp2);
+	ret = ccp2_phyif_config(ccp2, &buscfg->bus.ccp2);
 	if (ret < 0)
 		return ret;
 
-	ccp2_vp_config(ccp2, pdata->bus.ccp2.vpclk_div + 1);
+	ccp2_vp_config(ccp2, buscfg->bus.ccp2.vpclk_div + 1);
 
 	v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines);
 
 	format = &ccp2->formats[CCP2_PAD_SINK];
 
 	ccp2->if_cfg.data_start = lines;
-	ccp2->if_cfg.crc = pdata->bus.ccp2.crc;
+	ccp2->if_cfg.crc = buscfg->bus.ccp2.crc;
 	ccp2->if_cfg.format = format->code;
 	ccp2->if_cfg.data_size = format->height;
 
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 09c686d..14d279d 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -548,7 +548,7 @@ int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
 
 static int csi2_configure(struct isp_csi2_device *csi2)
 {
-	const struct isp_v4l2_subdevs_group *pdata;
+	const struct isp_bus_cfg *buscfg;
 	struct isp_device *isp = csi2->isp;
 	struct isp_csi2_timing_cfg *timing = &csi2->timing[0];
 	struct v4l2_subdev *sensor;
@@ -565,14 +565,14 @@ static int csi2_configure(struct isp_csi2_device *csi2)
 
 	pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]);
 	sensor = media_entity_to_v4l2_subdev(pad->entity);
-	pdata = sensor->host_priv;
+	buscfg = sensor->host_priv;
 
 	csi2->frame_skip = 0;
 	v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
 
-	csi2->ctrl.vp_out_ctrl = pdata->bus.csi2.vpclk_div;
+	csi2->ctrl.vp_out_ctrl = buscfg->bus.csi2.vpclk_div;
 	csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE;
-	csi2->ctrl.ecc_enable = pdata->bus.csi2.crc;
+	csi2->ctrl.ecc_enable = buscfg->bus.csi2.crc;
 
 	timing->ionum = 1;
 	timing->force_rx_mode = 1;
diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c
index e033f22..4486e9f 100644
--- a/drivers/media/platform/omap3isp/ispcsiphy.c
+++ b/drivers/media/platform/omap3isp/ispcsiphy.c
@@ -168,18 +168,18 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy)
 {
 	struct isp_csi2_device *csi2 = phy->csi2;
 	struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
-	struct isp_v4l2_subdevs_group *subdevs = pipe->external->host_priv;
+	struct isp_bus_cfg *buscfg = pipe->external->host_priv;
 	struct isp_csiphy_lanes_cfg *lanes;
 	int csi2_ddrclk_khz;
 	unsigned int used_lanes = 0;
 	unsigned int i;
 	u32 reg;
 
-	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1
-	    || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2)
-		lanes = &subdevs->bus.ccp2.lanecfg;
+	if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1
+	    || buscfg->interface == ISP_INTERFACE_CCP2B_PHY2)
+		lanes = &buscfg->bus.ccp2.lanecfg;
 	else
-		lanes = &subdevs->bus.csi2.lanecfg;
+		lanes = &buscfg->bus.csi2.lanecfg;
 
 	/* Clock and data lanes verification */
 	for (i = 0; i < phy->num_data_lanes; i++) {
@@ -203,8 +203,8 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy)
 	 * issue since the MPU power domain is forced on whilst the
 	 * ISP is in use.
 	 */
-	csiphy_routing_cfg(phy, subdevs->interface, true,
-			   subdevs->bus.ccp2.phy_layer);
+	csiphy_routing_cfg(phy, buscfg->interface, true,
+			   buscfg->bus.ccp2.phy_layer);
 
 	/* DPHY timing configuration */
 	/* CSI-2 is DDR and we only count used lanes. */
@@ -302,11 +302,10 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy)
 		struct isp_csi2_device *csi2 = phy->csi2;
 		struct isp_pipeline *pipe =
 			to_isp_pipeline(&csi2->subdev.entity);
-		struct isp_v4l2_subdevs_group *subdevs =
-			pipe->external->host_priv;
+		struct isp_bus_cfg *buscfg = pipe->external->host_priv;
 
-		csiphy_routing_cfg(phy, subdevs->interface, false,
-				   subdevs->bus.ccp2.phy_layer);
+		csiphy_routing_cfg(phy, buscfg->interface, false,
+				   buscfg->bus.ccp2.phy_layer);
 		csiphy_power_autoswitch_enable(phy, false);
 		csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF);
 		regulator_disable(phy->vdd);
diff --git a/include/media/omap3isp.h b/include/media/omap3isp.h
index 398279d..39e0748 100644
--- a/include/media/omap3isp.h
+++ b/include/media/omap3isp.h
@@ -45,7 +45,7 @@ enum {
 };
 
 /**
- * struct isp_parallel_platform_data - Parallel interface platform data
+ * struct isp_parallel_cfg - Parallel interface configuration
  * @data_lane_shift: Data lane shifter
  *		ISP_LANE_SHIFT_0 - CAMEXT[13:0] -> CAM[13:0]
  *		ISP_LANE_SHIFT_2 - CAMEXT[13:2] -> CAM[11:0]
@@ -62,7 +62,7 @@ enum {
  * @data_pol: Data polarity
  *		0 - Normal, 1 - One's complement
  */
-struct isp_parallel_platform_data {
+struct isp_parallel_cfg {
 	unsigned int data_lane_shift:2;
 	unsigned int clk_pol:1;
 	unsigned int hs_pol:1;
@@ -105,7 +105,7 @@ struct isp_csiphy_lanes_cfg {
 };
 
 /**
- * struct isp_ccp2_platform_data - CCP2 interface platform data
+ * struct isp_ccp2_cfg - CCP2 interface configuration
  * @strobe_clk_pol: Strobe/clock polarity
  *		0 - Non Inverted, 1 - Inverted
  * @crc: Enable the cyclic redundancy check
@@ -117,7 +117,7 @@ struct isp_csiphy_lanes_cfg {
  *		ISP_CCP2_PHY_DATA_STROBE - Data/strobe physical layer
  * @vpclk_div: Video port output clock control
  */
-struct isp_ccp2_platform_data {
+struct isp_ccp2_cfg {
 	unsigned int strobe_clk_pol:1;
 	unsigned int crc:1;
 	unsigned int ccp2_mode:1;
@@ -127,31 +127,31 @@ struct isp_ccp2_platform_data {
 };
 
 /**
- * struct isp_csi2_platform_data - CSI2 interface platform data
+ * struct isp_csi2_cfg - CSI2 interface configuration
  * @crc: Enable the cyclic redundancy check
  * @vpclk_div: Video port output clock control
  */
-struct isp_csi2_platform_data {
+struct isp_csi2_cfg {
 	unsigned crc:1;
 	unsigned vpclk_div:2;
 	struct isp_csiphy_lanes_cfg lanecfg;
 };
 
-struct isp_subdev_i2c_board_info {
-	struct i2c_board_info *board_info;
-	int i2c_adapter_id;
-};
-
-struct isp_v4l2_subdevs_group {
-	struct isp_subdev_i2c_board_info *subdevs;
+struct isp_bus_cfg {
 	enum isp_interface_type interface;
 	union {
-		struct isp_parallel_platform_data parallel;
-		struct isp_ccp2_platform_data ccp2;
-		struct isp_csi2_platform_data csi2;
+		struct isp_parallel_cfg parallel;
+		struct isp_ccp2_cfg ccp2;
+		struct isp_csi2_cfg csi2;
 	} bus; /* gcc < 4.6.0 chokes on anonymous union initializers */
 };
 
+struct isp_platform_subdev {
+	struct i2c_board_info *board_info;
+	int i2c_adapter_id;
+	struct isp_bus_cfg *bus;
+};
+
 struct isp_platform_xclk {
 	const char *dev_id;
 	const char *con_id;
@@ -159,7 +159,7 @@ struct isp_platform_xclk {
 
 struct isp_platform_data {
 	struct isp_platform_xclk xclks[2];
-	struct isp_v4l2_subdevs_group *subdevs;
+	struct isp_platform_subdev *subdevs;
 	void (*set_constraints)(struct isp_device *isp, bool enable);
 };
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 07/15] omap3isp: Rename regulators to better suit the Device Tree
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (5 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 06/15] omap3isp: Refactor device configuration structs for Device Tree Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 08/15] omap3isp: Calculate vpclk_div for CSI-2 Sakari Ailus
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

Rename VDD_CSIPHY1 as vdd-csiphy1 and VDD_CSIPHY2 as vdd-csiphy2.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/platform/omap3isp/isp.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 1b5c6df..c045318 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2292,8 +2292,8 @@ static int isp_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, isp);
 
 	/* Regulators */
-	isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "VDD_CSIPHY1");
-	isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "VDD_CSIPHY2");
+	isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy1");
+	isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy2");
 
 	/* Clocks
 	 *
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 08/15] omap3isp: Calculate vpclk_div for CSI-2
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (6 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 07/15] omap3isp: Rename regulators to better suit the " Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 09/15] omap3isp: Replace mmio_base_phys array with the histogram block base Sakari Ailus
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

The video port clock is l3_ick divided by vpclk_div. This clock must be high
enough for the external pixel rate. The video port requires two clock cycles
to process a pixel.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/platform/omap3isp/ispcsi2.c |    8 +++++++-
 include/media/omap3isp.h                  |    2 --
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 14d279d..97cdfeb 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -548,6 +548,7 @@ int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
 
 static int csi2_configure(struct isp_csi2_device *csi2)
 {
+	struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
 	const struct isp_bus_cfg *buscfg;
 	struct isp_device *isp = csi2->isp;
 	struct isp_csi2_timing_cfg *timing = &csi2->timing[0];
@@ -570,7 +571,12 @@ static int csi2_configure(struct isp_csi2_device *csi2)
 	csi2->frame_skip = 0;
 	v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
 
-	csi2->ctrl.vp_out_ctrl = buscfg->bus.csi2.vpclk_div;
+	csi2->ctrl.vp_out_ctrl =
+		clamp_t(unsigned int, pipe->l3_ick / pipe->external_rate - 1,
+			1, 3);
+	dev_dbg(isp->dev, "%s: l3_ick %lu, external_rate %u, vp_out_ctrl %u\n",
+		__func__, pipe->l3_ick,  pipe->external_rate,
+		csi2->ctrl.vp_out_ctrl);
 	csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE;
 	csi2->ctrl.ecc_enable = buscfg->bus.csi2.crc;
 
diff --git a/include/media/omap3isp.h b/include/media/omap3isp.h
index 39e0748..0f0c08b 100644
--- a/include/media/omap3isp.h
+++ b/include/media/omap3isp.h
@@ -129,11 +129,9 @@ struct isp_ccp2_cfg {
 /**
  * struct isp_csi2_cfg - CSI2 interface configuration
  * @crc: Enable the cyclic redundancy check
- * @vpclk_div: Video port output clock control
  */
 struct isp_csi2_cfg {
 	unsigned crc:1;
-	unsigned vpclk_div:2;
 	struct isp_csiphy_lanes_cfg lanecfg;
 };
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 09/15] omap3isp: Replace mmio_base_phys array with the histogram block base
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (7 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 08/15] omap3isp: Calculate vpclk_div for CSI-2 Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 10/15] omap3isp: Move the syscon register out of the ISP register maps Sakari Ailus
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

Only the histogram sub-block driver uses the physical address. Do not store
it for other sub-blocks.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/platform/omap3isp/isp.c     |    3 ++-
 drivers/media/platform/omap3isp/isp.h     |    6 +++---
 drivers/media/platform/omap3isp/isphist.c |    3 +--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index c045318..68d7edfc 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2247,7 +2247,8 @@ static int isp_map_mem_resource(struct platform_device *pdev,
 	if (IS_ERR(isp->mmio_base[res]))
 		return PTR_ERR(isp->mmio_base[res]);
 
-	isp->mmio_base_phys[res] = mem->start;
+	if (res == OMAP3_ISP_IOMEM_HIST)
+		isp->mmio_hist_base_phys = mem->start;
 
 	return 0;
 }
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index b932a6f..9535524 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -138,8 +138,8 @@ struct isp_xclk {
  * @irq_num: Currently used IRQ number.
  * @mmio_base: Array with kernel base addresses for ioremapped ISP register
  *             regions.
- * @mmio_base_phys: Array with physical L4 bus addresses for ISP register
- *                  regions.
+ * @mmio_hist_base_phys: Physical L4 bus address for ISP hist block register
+ *			 region.
  * @mapping: IOMMU mapping
  * @stat_lock: Spinlock for handling statistics
  * @isp_mutex: Mutex for serializing requests to ISP.
@@ -175,7 +175,7 @@ struct isp_device {
 	unsigned int irq_num;
 
 	void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST];
-	unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST];
+	unsigned long mmio_hist_base_phys;
 
 	struct dma_iommu_mapping *mapping;
 
diff --git a/drivers/media/platform/omap3isp/isphist.c b/drivers/media/platform/omap3isp/isphist.c
index 738b946..7138b04 100644
--- a/drivers/media/platform/omap3isp/isphist.c
+++ b/drivers/media/platform/omap3isp/isphist.c
@@ -193,8 +193,7 @@ static int hist_buf_dma(struct ispstat *hist)
 	omap3isp_flush(hist->isp);
 
 	memset(&cfg, 0, sizeof(cfg));
-	cfg.src_addr = hist->isp->mmio_base_phys[OMAP3_ISP_IOMEM_HIST]
-		     + ISPHIST_DATA;
+	cfg.src_addr = hist->isp->mmio_hist_base_phys + ISPHIST_DATA;
 	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 	cfg.src_maxburst = hist->buf_size / 4;
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 10/15] omap3isp: Move the syscon register out of the ISP register maps
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (8 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 09/15] omap3isp: Replace mmio_base_phys array with the histogram block base Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 11/15] omap3isp: Replace many MMIO regions by two Sakari Ailus
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

The syscon register isn't part of the ISP, use it through the syscom driver
regmap instead. The syscom block is considered to be from 343x on ISP
revision 2.0 whereas 15.0 is assumed to have 3630 syscon.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/devices.c               |   10 ----------
 drivers/media/platform/Kconfig              |    1 +
 drivers/media/platform/omap3isp/isp.c       |   20 ++++++++++++++++----
 drivers/media/platform/omap3isp/isp.h       |   19 +++++++++++++++++--
 drivers/media/platform/omap3isp/ispcsiphy.c |   20 +++++++++-----------
 5 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 1afb50d..e945957 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -143,16 +143,6 @@ static struct resource omap3isp_resources[] = {
 		.flags		= IORESOURCE_MEM,
 	},
 	{
-		.start		= OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE,
-		.end		= OMAP343X_CTRL_BASE + OMAP343X_CONTROL_CSIRXFE + 3,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL,
-		.end		= OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL + 3,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
 		.start		= 24 + OMAP_INTC_START,
 		.flags		= IORESOURCE_IRQ,
 	}
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 2e30be5..272dc8c 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -90,6 +90,7 @@ config VIDEO_OMAP3
 	select ARM_DMA_USE_IOMMU
 	select OMAP_IOMMU
 	select VIDEOBUF2_DMA_CONTIG
+	select MFD_SYSCON
 	---help---
 	  Driver for an OMAP 3 camera controller.
 
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 68d7edfc..83b4368 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -51,6 +51,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/omap-iommu.h>
 #include <linux/platform_device.h>
@@ -94,8 +95,9 @@ static const struct isp_res_mapping isp_res_maps[] = {
 		       1 << OMAP3_ISP_IOMEM_RESZ |
 		       1 << OMAP3_ISP_IOMEM_SBL |
 		       1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
-		       1 << OMAP3_ISP_IOMEM_CSIPHY2 |
-		       1 << OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE,
+		       1 << OMAP3_ISP_IOMEM_CSIPHY2,
+		.syscon_offset = 0xdc,
+		.phy_type = ISP_PHY_TYPE_3430,
 	},
 	{
 		.isp_rev = ISP_REVISION_15_0,
@@ -112,8 +114,9 @@ static const struct isp_res_mapping isp_res_maps[] = {
 		       1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 |
 		       1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 |
 		       1 << OMAP3_ISP_IOMEM_CSIPHY1 |
-		       1 << OMAP3_ISP_IOMEM_CSI2C_REGS2 |
-		       1 << OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL,
+		       1 << OMAP3_ISP_IOMEM_CSI2C_REGS2,
+		.syscon_offset = 0x2f0,
+		.phy_type = ISP_PHY_TYPE_3630,
 	},
 };
 
@@ -2352,6 +2355,15 @@ static int isp_probe(struct platform_device *pdev)
 		}
 	}
 
+	isp->syscon = syscon_regmap_lookup_by_pdevname("syscon.0");
+	if (IS_ERR(isp->syscon)) {
+		ret = PTR_ERR(isp->syscon);
+		goto error_isp;
+	}
+
+	isp->syscon_offset = isp_res_maps[m].syscon_offset;
+	isp->phy_type = isp_res_maps[m].phy_type;
+
 	/* IOMMU */
 	ret = isp_attach_iommu(isp);
 	if (ret < 0) {
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index 9535524..03d2129 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -59,8 +59,6 @@ enum isp_mem_resources {
 	OMAP3_ISP_IOMEM_CSI2C_REGS1,
 	OMAP3_ISP_IOMEM_CSIPHY1,
 	OMAP3_ISP_IOMEM_CSI2C_REGS2,
-	OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE,
-	OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL,
 	OMAP3_ISP_IOMEM_LAST
 };
 
@@ -93,14 +91,25 @@ enum isp_subclk_resource {
 /* ISP2P: OMAP 36xx */
 #define ISP_REVISION_15_0		0xF0
 
+#define ISP_PHY_TYPE_3430		0
+#define ISP_PHY_TYPE_3630		1
+
+struct regmap;
+
 /*
  * struct isp_res_mapping - Map ISP io resources to ISP revision.
  * @isp_rev: ISP_REVISION_x_x
  * @map: bitmap for enum isp_mem_resources
+ * @syscon_offset: offset of the syscon register for 343x / 3630
+ *	    (CONTROL_CSIRXFE / CONTROL_CAMERA_PHY_CTRL, respectively)
+ *	    from the syscon base address
+ * @phy_type: ISP_PHY_TYPE_{3430,3630}
  */
 struct isp_res_mapping {
 	u32 isp_rev;
 	u32 map;
+	u32 syscon_offset;
+	u32 phy_type;
 };
 
 /*
@@ -140,6 +149,9 @@ struct isp_xclk {
  *             regions.
  * @mmio_hist_base_phys: Physical L4 bus address for ISP hist block register
  *			 region.
+ * @syscon: Regmap for the syscon register space
+ * @syscon_offset: Offset of the CSIPHY control register in syscon
+ * @phy_type: ISP_PHY_TYPE_{3430,3630}
  * @mapping: IOMMU mapping
  * @stat_lock: Spinlock for handling statistics
  * @isp_mutex: Mutex for serializing requests to ISP.
@@ -176,6 +188,9 @@ struct isp_device {
 
 	void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST];
 	unsigned long mmio_hist_base_phys;
+	struct regmap *syscon;
+	u32 syscon_offset;
+	u32 phy_type;
 
 	struct dma_iommu_mapping *mapping;
 
diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c
index 4486e9f..d91dde1 100644
--- a/drivers/media/platform/omap3isp/ispcsiphy.c
+++ b/drivers/media/platform/omap3isp/ispcsiphy.c
@@ -16,6 +16,7 @@
 
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 
 #include "isp.h"
@@ -26,10 +27,11 @@ static void csiphy_routing_cfg_3630(struct isp_csiphy *phy,
 				    enum isp_interface_type iface,
 				    bool ccp2_strobe)
 {
-	u32 reg = isp_reg_readl(
-		phy->isp, OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 0);
+	u32 reg;
 	u32 shift, mode;
 
+	regmap_read(phy->isp->syscon, phy->isp->syscon_offset, &reg);
+
 	switch (iface) {
 	default:
 	/* Should not happen in practice, but let's keep the compiler happy. */
@@ -63,8 +65,7 @@ static void csiphy_routing_cfg_3630(struct isp_csiphy *phy,
 	reg &= ~(OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK << shift);
 	reg |= mode << shift;
 
-	isp_reg_writel(phy->isp, reg,
-		       OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 0);
+	regmap_write(phy->isp->syscon, phy->isp->syscon_offset, reg);
 }
 
 static void csiphy_routing_cfg_3430(struct isp_csiphy *phy, u32 iface, bool on,
@@ -78,16 +79,14 @@ static void csiphy_routing_cfg_3430(struct isp_csiphy *phy, u32 iface, bool on,
 		return;
 
 	if (!on) {
-		isp_reg_writel(phy->isp, 0,
-			       OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 0);
+		regmap_write(phy->isp->syscon, phy->isp->syscon_offset, 0);
 		return;
 	}
 
 	if (ccp2_strobe)
 		csirxfe |= OMAP343X_CONTROL_CSIRXFE_SELFORM;
 
-	isp_reg_writel(phy->isp, csirxfe,
-		       OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 0);
+	regmap_write(phy->isp->syscon, phy->isp->syscon_offset, csirxfe);
 }
 
 /*
@@ -106,10 +105,9 @@ static void csiphy_routing_cfg(struct isp_csiphy *phy,
 			       enum isp_interface_type iface, bool on,
 			       bool ccp2_strobe)
 {
-	if (phy->isp->mmio_base[OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL]
-	    && on)
+	if (phy->isp->phy_type == ISP_PHY_TYPE_3630 && on)
 		return csiphy_routing_cfg_3630(phy, iface, ccp2_strobe);
-	if (phy->isp->mmio_base[OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE])
+	if (phy->isp->phy_type == ISP_PHY_TYPE_3430)
 		return csiphy_routing_cfg_3430(phy, iface, on, ccp2_strobe);
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 11/15] omap3isp: Replace many MMIO regions by two
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (9 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 10/15] omap3isp: Move the syscon register out of the ISP register maps Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 12/15] dt: bindings: Add lane-polarity property to endpoint nodes Sakari Ailus
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

The omap3isp MMIO register block is contiguous in the MMIO register space
apart from the fact that the ISP IOMMU register block is in the middle of
the area. Ioremap it at two occasions, and keep the rest of the layout of
the register space internal to the omap3isp driver.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/devices.c         |   66 +------------------
 arch/arm/mach-omap2/omap34xx.h        |   36 +----------
 drivers/media/platform/omap3isp/isp.c |  113 +++++++++++++++++----------------
 drivers/media/platform/omap3isp/isp.h |    4 +-
 4 files changed, 66 insertions(+), 153 deletions(-)

diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index e945957..990338f 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -74,72 +74,12 @@ omap_postcore_initcall(omap3_l3_init);
 static struct resource omap3isp_resources[] = {
 	{
 		.start		= OMAP3430_ISP_BASE,
-		.end		= OMAP3430_ISP_END,
+		.end		= OMAP3430_ISP_BASE + 0x12fc,
 		.flags		= IORESOURCE_MEM,
 	},
 	{
-		.start		= OMAP3430_ISP_CCP2_BASE,
-		.end		= OMAP3430_ISP_CCP2_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_CCDC_BASE,
-		.end		= OMAP3430_ISP_CCDC_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_HIST_BASE,
-		.end		= OMAP3430_ISP_HIST_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_H3A_BASE,
-		.end		= OMAP3430_ISP_H3A_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_PREV_BASE,
-		.end		= OMAP3430_ISP_PREV_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_RESZ_BASE,
-		.end		= OMAP3430_ISP_RESZ_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_SBL_BASE,
-		.end		= OMAP3430_ISP_SBL_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_CSI2A_REGS1_BASE,
-		.end		= OMAP3430_ISP_CSI2A_REGS1_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3430_ISP_CSIPHY2_BASE,
-		.end		= OMAP3430_ISP_CSIPHY2_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3630_ISP_CSI2A_REGS2_BASE,
-		.end		= OMAP3630_ISP_CSI2A_REGS2_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3630_ISP_CSI2C_REGS1_BASE,
-		.end		= OMAP3630_ISP_CSI2C_REGS1_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3630_ISP_CSIPHY1_BASE,
-		.end		= OMAP3630_ISP_CSIPHY1_END,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= OMAP3630_ISP_CSI2C_REGS2_BASE,
-		.end		= OMAP3630_ISP_CSI2C_REGS2_END,
+		.start		= OMAP3430_ISP_BASE2,
+		.end		= OMAP3430_ISP_BASE2 + 0x0600,
 		.flags		= IORESOURCE_MEM,
 	},
 	{
diff --git a/arch/arm/mach-omap2/omap34xx.h b/arch/arm/mach-omap2/omap34xx.h
index c0d1b4b..ed0024d 100644
--- a/arch/arm/mach-omap2/omap34xx.h
+++ b/arch/arm/mach-omap2/omap34xx.h
@@ -46,39 +46,9 @@
 
 #define OMAP34XX_IC_BASE	0x48200000
 
-#define OMAP3430_ISP_BASE		(L4_34XX_BASE + 0xBC000)
-#define OMAP3430_ISP_CBUFF_BASE		(OMAP3430_ISP_BASE + 0x0100)
-#define OMAP3430_ISP_CCP2_BASE		(OMAP3430_ISP_BASE + 0x0400)
-#define OMAP3430_ISP_CCDC_BASE		(OMAP3430_ISP_BASE + 0x0600)
-#define OMAP3430_ISP_HIST_BASE		(OMAP3430_ISP_BASE + 0x0A00)
-#define OMAP3430_ISP_H3A_BASE		(OMAP3430_ISP_BASE + 0x0C00)
-#define OMAP3430_ISP_PREV_BASE		(OMAP3430_ISP_BASE + 0x0E00)
-#define OMAP3430_ISP_RESZ_BASE		(OMAP3430_ISP_BASE + 0x1000)
-#define OMAP3430_ISP_SBL_BASE		(OMAP3430_ISP_BASE + 0x1200)
-#define OMAP3430_ISP_MMU_BASE		(OMAP3430_ISP_BASE + 0x1400)
-#define OMAP3430_ISP_CSI2A_REGS1_BASE	(OMAP3430_ISP_BASE + 0x1800)
-#define OMAP3430_ISP_CSIPHY2_BASE	(OMAP3430_ISP_BASE + 0x1970)
-#define OMAP3630_ISP_CSI2A_REGS2_BASE	(OMAP3430_ISP_BASE + 0x19C0)
-#define OMAP3630_ISP_CSI2C_REGS1_BASE	(OMAP3430_ISP_BASE + 0x1C00)
-#define OMAP3630_ISP_CSIPHY1_BASE	(OMAP3430_ISP_BASE + 0x1D70)
-#define OMAP3630_ISP_CSI2C_REGS2_BASE	(OMAP3430_ISP_BASE + 0x1DC0)
-
-#define OMAP3430_ISP_END		(OMAP3430_ISP_BASE         + 0x06F)
-#define OMAP3430_ISP_CBUFF_END		(OMAP3430_ISP_CBUFF_BASE   + 0x077)
-#define OMAP3430_ISP_CCP2_END		(OMAP3430_ISP_CCP2_BASE    + 0x1EF)
-#define OMAP3430_ISP_CCDC_END		(OMAP3430_ISP_CCDC_BASE    + 0x0A7)
-#define OMAP3430_ISP_HIST_END		(OMAP3430_ISP_HIST_BASE    + 0x047)
-#define OMAP3430_ISP_H3A_END		(OMAP3430_ISP_H3A_BASE     + 0x05F)
-#define OMAP3430_ISP_PREV_END		(OMAP3430_ISP_PREV_BASE    + 0x09F)
-#define OMAP3430_ISP_RESZ_END		(OMAP3430_ISP_RESZ_BASE    + 0x0AB)
-#define OMAP3430_ISP_SBL_END		(OMAP3430_ISP_SBL_BASE     + 0x0FB)
-#define OMAP3430_ISP_MMU_END		(OMAP3430_ISP_MMU_BASE     + 0x06F)
-#define OMAP3430_ISP_CSI2A_REGS1_END	(OMAP3430_ISP_CSI2A_REGS1_BASE + 0x16F)
-#define OMAP3430_ISP_CSIPHY2_END	(OMAP3430_ISP_CSIPHY2_BASE + 0x00B)
-#define OMAP3630_ISP_CSI2A_REGS2_END	(OMAP3630_ISP_CSI2A_REGS2_BASE + 0x3F)
-#define OMAP3630_ISP_CSI2C_REGS1_END	(OMAP3630_ISP_CSI2C_REGS1_BASE + 0x16F)
-#define OMAP3630_ISP_CSIPHY1_END	(OMAP3630_ISP_CSIPHY1_BASE + 0x00B)
-#define OMAP3630_ISP_CSI2C_REGS2_END	(OMAP3630_ISP_CSI2C_REGS2_BASE + 0x3F)
+#define OMAP3430_ISP_BASE	(L4_34XX_BASE + 0xBC000)
+#define OMAP3430_ISP_MMU_BASE	(OMAP3430_ISP_BASE + 0x1400)
+#define OMAP3430_ISP_BASE2	(OMAP3430_ISP_BASE + 0x1800)
 
 #define OMAP34XX_HSUSB_OTG_BASE	(L4_34XX_BASE + 0xAB000)
 #define OMAP34XX_USBTLL_BASE	(L4_34XX_BASE + 0x62000)
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 83b4368..992e74c 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -86,35 +86,43 @@ static void isp_restore_ctx(struct isp_device *isp);
 static const struct isp_res_mapping isp_res_maps[] = {
 	{
 		.isp_rev = ISP_REVISION_2_0,
-		.map = 1 << OMAP3_ISP_IOMEM_MAIN |
-		       1 << OMAP3_ISP_IOMEM_CCP2 |
-		       1 << OMAP3_ISP_IOMEM_CCDC |
-		       1 << OMAP3_ISP_IOMEM_HIST |
-		       1 << OMAP3_ISP_IOMEM_H3A |
-		       1 << OMAP3_ISP_IOMEM_PREV |
-		       1 << OMAP3_ISP_IOMEM_RESZ |
-		       1 << OMAP3_ISP_IOMEM_SBL |
-		       1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
-		       1 << OMAP3_ISP_IOMEM_CSIPHY2,
+		.offset = {
+			/* first MMIO area */
+			0x0000, /* base, len 0x0070 */
+			0x0400, /* ccp2, len 0x01f0 */
+			0x0600, /* ccdc, len 0x00a8 */
+			0x0a00, /* hist, len 0x0048 */
+			0x0c00, /* h3a, len 0x0060 */
+			0x0e00, /* preview, len 0x00a0 */
+			0x1000, /* resizer, len 0x00ac */
+			0x1200, /* sbl, len 0x00fc */
+			/* second MMIO area */
+			0x0000, /* csi2a, len 0x0170 */
+			0x0170, /* csiphy2, len 0x000c */
+		},
 		.syscon_offset = 0xdc,
 		.phy_type = ISP_PHY_TYPE_3430,
 	},
 	{
 		.isp_rev = ISP_REVISION_15_0,
-		.map = 1 << OMAP3_ISP_IOMEM_MAIN |
-		       1 << OMAP3_ISP_IOMEM_CCP2 |
-		       1 << OMAP3_ISP_IOMEM_CCDC |
-		       1 << OMAP3_ISP_IOMEM_HIST |
-		       1 << OMAP3_ISP_IOMEM_H3A |
-		       1 << OMAP3_ISP_IOMEM_PREV |
-		       1 << OMAP3_ISP_IOMEM_RESZ |
-		       1 << OMAP3_ISP_IOMEM_SBL |
-		       1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
-		       1 << OMAP3_ISP_IOMEM_CSIPHY2 |
-		       1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 |
-		       1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 |
-		       1 << OMAP3_ISP_IOMEM_CSIPHY1 |
-		       1 << OMAP3_ISP_IOMEM_CSI2C_REGS2,
+		.offset = {
+			/* first MMIO area */
+			0x0000, /* base, len 0x0070 */
+			0x0400, /* ccp2, len 0x01f0 */
+			0x0600, /* ccdc, len 0x00a8 */
+			0x0a00, /* hist, len 0x0048 */
+			0x0c00, /* h3a, len 0x0060 */
+			0x0e00, /* preview, len 0x00a0 */
+			0x1000, /* resizer, len 0x00ac */
+			0x1200, /* sbl, len 0x00fc */
+			/* second MMIO area */
+			0x0000, /* csi2a, len 0x0170 (1st area) */
+			0x0170, /* csiphy2, len 0x000c */
+			0x01c0, /* csi2a, len 0x0040 (2nd area) */
+			0x0400, /* csi2c, len 0x0170 (1st area) */
+			0x0570, /* csiphy1, len 0x000c */
+			0x05c0, /* csi2c, len 0x0040 (2nd area) */
+		},
 		.syscon_offset = 0x2f0,
 		.phy_type = ISP_PHY_TYPE_3630,
 	},
@@ -2235,27 +2243,6 @@ static int isp_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static int isp_map_mem_resource(struct platform_device *pdev,
-				struct isp_device *isp,
-				enum isp_mem_resources res)
-{
-	struct resource *mem;
-
-	/* request the mem region for the camera registers */
-
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
-
-	/* map the region */
-	isp->mmio_base[res] = devm_ioremap_resource(isp->dev, mem);
-	if (IS_ERR(isp->mmio_base[res]))
-		return PTR_ERR(isp->mmio_base[res]);
-
-	if (res == OMAP3_ISP_IOMEM_HIST)
-		isp->mmio_hist_base_phys = mem->start;
-
-	return 0;
-}
-
 /*
  * isp_probe - Probe ISP platform device
  * @pdev: Pointer to ISP platform device
@@ -2271,6 +2258,7 @@ static int isp_probe(struct platform_device *pdev)
 {
 	struct isp_platform_data *pdata = pdev->dev.platform_data;
 	struct isp_device *isp;
+	struct resource *mem;
 	int ret;
 	int i, m;
 
@@ -2303,10 +2291,21 @@ static int isp_probe(struct platform_device *pdev)
 	 *
 	 * The ISP clock tree is revision-dependent. We thus need to enable ICLK
 	 * manually to read the revision before calling __omap3isp_get().
+	 *
+	 * Start by mapping the ISP MMIO area, which is in two pieces.
+	 * The ISP IOMMU is in between. Map both now, and fill in the
+	 * ISP revision specific portions a little later in the
+	 * function.
 	 */
-	ret = isp_map_mem_resource(pdev, isp, OMAP3_ISP_IOMEM_MAIN);
-	if (ret < 0)
-		goto error;
+	for (i = 0; i < 2; i++) {
+		unsigned int map_idx = i ? OMAP3_ISP_IOMEM_CSI2A_REGS1 : 0;
+
+		mem = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		isp->mmio_base[map_idx] =
+			devm_ioremap_resource(isp->dev, mem);
+		if (IS_ERR(isp->mmio_base[map_idx]))
+			return PTR_ERR(isp->mmio_base[map_idx]);
+	}
 
 	ret = isp_get_clocks(isp);
 	if (ret < 0)
@@ -2347,13 +2346,17 @@ static int isp_probe(struct platform_device *pdev)
 		goto error_isp;
 	}
 
-	for (i = 1; i < OMAP3_ISP_IOMEM_LAST; i++) {
-		if (isp_res_maps[m].map & 1 << i) {
-			ret = isp_map_mem_resource(pdev, isp, i);
-			if (ret)
-				goto error_isp;
-		}
-	}
+	for (i = 1; i < OMAP3_ISP_IOMEM_CSI2A_REGS1; i++)
+		isp->mmio_base[i] =
+			isp->mmio_base[0] + isp_res_maps[m].offset[i];
+
+	for (i = OMAP3_ISP_IOMEM_CSIPHY2; i < OMAP3_ISP_IOMEM_LAST; i++)
+		isp->mmio_base[i] =
+			isp->mmio_base[OMAP3_ISP_IOMEM_CSI2A_REGS1]
+			+ isp_res_maps[m].offset[i];
+
+	isp->mmio_hist_base_phys =
+		mem->start + isp_res_maps[m].offset[OMAP3_ISP_IOMEM_HIST];
 
 	isp->syscon = syscon_regmap_lookup_by_pdevname("syscon.0");
 	if (IS_ERR(isp->syscon)) {
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index 03d2129..dcb7d20 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -99,7 +99,7 @@ struct regmap;
 /*
  * struct isp_res_mapping - Map ISP io resources to ISP revision.
  * @isp_rev: ISP_REVISION_x_x
- * @map: bitmap for enum isp_mem_resources
+ * @offset: register offsets of various ISP sub-blocks
  * @syscon_offset: offset of the syscon register for 343x / 3630
  *	    (CONTROL_CSIRXFE / CONTROL_CAMERA_PHY_CTRL, respectively)
  *	    from the syscon base address
@@ -107,7 +107,7 @@ struct regmap;
  */
 struct isp_res_mapping {
 	u32 isp_rev;
-	u32 map;
+	u32 offset[OMAP3_ISP_IOMEM_LAST];
 	u32 syscon_offset;
 	u32 phy_type;
 };
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 12/15] dt: bindings: Add lane-polarity property to endpoint nodes
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (10 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 11/15] omap3isp: Replace many MMIO regions by two Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-04-24 19:41     ` Benoit Parrot
  2015-03-25 22:57 ` [PATCH v2 13/15] v4l: of: Read lane-polarities endpoint property Sakari Ailus
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

Add lane-polarity property to endpoint nodes. This essentially tells that
the order of the differential signal wires is inverted.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 Documentation/devicetree/bindings/media/video-interfaces.txt |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt
index 571b4c6..9cd2a36 100644
--- a/Documentation/devicetree/bindings/media/video-interfaces.txt
+++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
@@ -106,6 +106,12 @@ Optional endpoint properties
 - link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for
   instance, this is the actual frequency of the bus, not bits per clock per
   lane value. An array of 64-bit unsigned integers.
+- lane-polarities: an array of polarities of the lanes starting from the clock
+  lane and followed by the data lanes in the same order as in data-lanes.
+  Valid values are 0 (normal) and 1 (inverted). The length of the array
+  should be the combined length of data-lanes and clock-lanes properties.
+  If the lane-polarities property is omitted, the value must be interpreted
+  as 0 (normal). This property is valid for serial busses only.
 
 
 Example
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 13/15] v4l: of: Read lane-polarities endpoint property
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (11 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 12/15] dt: bindings: Add lane-polarity property to endpoint nodes Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 14/15] omap3isp: Add support for the Device Tree Sakari Ailus
  2015-03-25 22:57 ` [PATCH v2 15/15] omap3isp: Deprecate platform data support Sakari Ailus
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

Add lane_polarities field to struct v4l2_of_bus_mipi_csi2 and write the
contents of the lane-polarities property to it. The field tells the polarity
of the physical lanes starting from the first one. Any unused lanes are
ignored, i.e. only the polarity of the used lanes is specified.

Also rework reading the "data-lanes" property a little.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/v4l2-core/v4l2-of.c |   41 +++++++++++++++++++++++++++++--------
 include/media/v4l2-of.h           |    3 +++
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/v4l2-of.c b/drivers/media/v4l2-core/v4l2-of.c
index b4ed9a9..58e401f 100644
--- a/drivers/media/v4l2-core/v4l2-of.c
+++ b/drivers/media/v4l2-core/v4l2-of.c
@@ -19,11 +19,10 @@
 
 #include <media/v4l2-of.h>
 
-static void v4l2_of_parse_csi_bus(const struct device_node *node,
-				  struct v4l2_of_endpoint *endpoint)
+static int v4l2_of_parse_csi_bus(const struct device_node *node,
+				 struct v4l2_of_endpoint *endpoint)
 {
 	struct v4l2_of_bus_mipi_csi2 *bus = &endpoint->bus.mipi_csi2;
-	u32 data_lanes[ARRAY_SIZE(bus->data_lanes)];
 	struct property *prop;
 	bool have_clk_lane = false;
 	unsigned int flags = 0;
@@ -32,16 +31,34 @@ static void v4l2_of_parse_csi_bus(const struct device_node *node,
 	prop = of_find_property(node, "data-lanes", NULL);
 	if (prop) {
 		const __be32 *lane = NULL;
-		int i;
+		unsigned int i;
 
-		for (i = 0; i < ARRAY_SIZE(data_lanes); i++) {
-			lane = of_prop_next_u32(prop, lane, &data_lanes[i]);
+		for (i = 0; i < ARRAY_SIZE(bus->data_lanes); i++) {
+			lane = of_prop_next_u32(prop, lane, &v);
 			if (!lane)
 				break;
+			bus->data_lanes[i] = v;
 		}
 		bus->num_data_lanes = i;
-		while (i--)
-			bus->data_lanes[i] = data_lanes[i];
+	}
+
+	prop = of_find_property(node, "lane-polarities", NULL);
+	if (prop) {
+		const __be32 *polarity = NULL;
+		unsigned int i;
+
+		for (i = 0; i < ARRAY_SIZE(bus->lane_polarities); i++) {
+			polarity = of_prop_next_u32(prop, polarity, &v);
+			if (!polarity)
+				break;
+			bus->lane_polarities[i] = v;
+		}
+
+		if (i < 1 + bus->num_data_lanes /* clock + data */) {
+			pr_warn("%s: too few lane-polarities entries (need %u, got %u)\n",
+				node->full_name, 1 + bus->num_data_lanes, i);
+			return -EINVAL;
+		}
 	}
 
 	if (!of_property_read_u32(node, "clock-lanes", &v)) {
@@ -56,6 +73,8 @@ static void v4l2_of_parse_csi_bus(const struct device_node *node,
 
 	bus->flags = flags;
 	endpoint->bus_type = V4L2_MBUS_CSI2;
+
+	return 0;
 }
 
 static void v4l2_of_parse_parallel_bus(const struct device_node *node,
@@ -127,11 +146,15 @@ static void v4l2_of_parse_parallel_bus(const struct device_node *node,
 int v4l2_of_parse_endpoint(const struct device_node *node,
 			   struct v4l2_of_endpoint *endpoint)
 {
+	int rval;
+
 	of_graph_parse_endpoint(node, &endpoint->base);
 	endpoint->bus_type = 0;
 	memset(&endpoint->bus, 0, sizeof(endpoint->bus));
 
-	v4l2_of_parse_csi_bus(node, endpoint);
+	rval = v4l2_of_parse_csi_bus(node, endpoint);
+	if (rval)
+		return rval;
 	/*
 	 * Parse the parallel video bus properties only if none
 	 * of the MIPI CSI-2 specific properties were found.
diff --git a/include/media/v4l2-of.h b/include/media/v4l2-of.h
index 70fa7b7..2de42c5 100644
--- a/include/media/v4l2-of.h
+++ b/include/media/v4l2-of.h
@@ -29,12 +29,15 @@ struct device_node;
  * @data_lanes: an array of physical data lane indexes
  * @clock_lane: physical lane index of the clock lane
  * @num_data_lanes: number of data lanes
+ * @lane_polarities: polarity of the lanes. The order is the same of
+ *		   the physical lanes.
  */
 struct v4l2_of_bus_mipi_csi2 {
 	unsigned int flags;
 	unsigned char data_lanes[4];
 	unsigned char clock_lane;
 	unsigned short num_data_lanes;
+	bool lane_polarities[5];
 };
 
 /**
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 14/15] omap3isp: Add support for the Device Tree
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (12 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 13/15] v4l: of: Read lane-polarities endpoint property Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  2015-03-30 17:41   ` Sebastian Reichel
  2015-03-25 22:57 ` [PATCH v2 15/15] omap3isp: Deprecate platform data support Sakari Ailus
  14 siblings, 1 reply; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

Add the ISP device to omap3 DT include file and add support to the driver to
use it.

Also obtain information on the external entities and the ISP configuration
related to them through the Device Tree in addition to the platform data.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
---
 drivers/media/platform/omap3isp/isp.c       |  218 +++++++++++++++++++++++++--
 drivers/media/platform/omap3isp/isp.h       |   11 ++
 drivers/media/platform/omap3isp/ispcsiphy.c |    7 +
 3 files changed, 224 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 992e74c..e12484e 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -64,6 +64,7 @@
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
+#include <media/v4l2-of.h>
 
 #include "isp.h"
 #include "ispreg.h"
@@ -1991,6 +1992,13 @@ static int isp_register_entities(struct isp_device *isp)
 	if (ret < 0)
 		goto done;
 
+	/*
+	 * Device Tree --- the external sub-devices will be registered
+	 * later. The same goes for the sub-device node registration.
+	 */
+	if (isp->dev->of_node)
+		return 0;
+
 	/* Register external entities */
 	for (isp_subdev = pdata ? pdata->subdevs : NULL;
 	     isp_subdev && isp_subdev->board_info; isp_subdev++) {
@@ -2016,8 +2024,10 @@ static int isp_register_entities(struct isp_device *isp)
 	ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
 
 done:
-	if (ret < 0)
+	if (ret < 0) {
 		isp_unregister_entities(isp);
+		v4l2_async_notifier_unregister(&isp->notifier);
+	}
 
 	return ret;
 }
@@ -2232,6 +2242,7 @@ static int isp_remove(struct platform_device *pdev)
 {
 	struct isp_device *isp = platform_get_drvdata(pdev);
 
+	v4l2_async_notifier_unregister(&isp->notifier);
 	isp_unregister_entities(isp);
 	isp_cleanup_modules(isp);
 	isp_xclk_cleanup(isp);
@@ -2243,6 +2254,156 @@ static int isp_remove(struct platform_device *pdev)
 	return 0;
 }
 
+enum isp_of_phy {
+	ISP_OF_PHY_PARALLEL = 0,
+	ISP_OF_PHY_CSIPHY1,
+	ISP_OF_PHY_CSIPHY2,
+};
+
+static int isp_of_parse_node(struct device *dev, struct device_node *node,
+			     struct isp_async_subdev *isd)
+{
+	struct isp_bus_cfg *buscfg = &isd->bus;
+	struct v4l2_of_endpoint vep;
+	unsigned int i;
+
+	v4l2_of_parse_endpoint(node, &vep);
+
+	dev_dbg(dev, "parsing endpoint %s, interface %u\n", node->full_name,
+		vep.base.port);
+
+	switch (vep.base.port) {
+	case ISP_OF_PHY_PARALLEL:
+		buscfg->interface = ISP_INTERFACE_PARALLEL;
+		buscfg->bus.parallel.data_lane_shift =
+			vep.bus.parallel.data_shift;
+		buscfg->bus.parallel.clk_pol =
+			!!(vep.bus.parallel.flags
+			   & V4L2_MBUS_PCLK_SAMPLE_FALLING);
+		buscfg->bus.parallel.hs_pol =
+			!!(vep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
+		buscfg->bus.parallel.vs_pol =
+			!!(vep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
+		buscfg->bus.parallel.fld_pol =
+			!!(vep.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
+		buscfg->bus.parallel.data_pol =
+			!!(vep.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
+		break;
+
+	case ISP_OF_PHY_CSIPHY1:
+	case ISP_OF_PHY_CSIPHY2:
+		/* FIXME: always assume CSI-2 for now. */
+		switch (vep.base.port) {
+		case ISP_OF_PHY_CSIPHY1:
+			buscfg->interface = ISP_INTERFACE_CSI2C_PHY1;
+			break;
+		case ISP_OF_PHY_CSIPHY2:
+			buscfg->interface = ISP_INTERFACE_CSI2A_PHY2;
+			break;
+		}
+		buscfg->bus.csi2.lanecfg.clk.pos = vep.bus.mipi_csi2.clock_lane;
+		buscfg->bus.csi2.lanecfg.clk.pol =
+			vep.bus.mipi_csi2.lane_polarities[0];
+		dev_dbg(dev, "clock lane polarity %u, pos %u\n",
+			buscfg->bus.csi2.lanecfg.clk.pol,
+			buscfg->bus.csi2.lanecfg.clk.pos);
+
+		for (i = 0; i < ISP_CSIPHY2_NUM_DATA_LANES; i++) {
+			buscfg->bus.csi2.lanecfg.data[i].pos =
+				vep.bus.mipi_csi2.data_lanes[i];
+			buscfg->bus.csi2.lanecfg.data[i].pol =
+				vep.bus.mipi_csi2.lane_polarities[i + 1];
+			dev_dbg(dev, "data lane %u polarity %u, pos %u\n", i,
+				buscfg->bus.csi2.lanecfg.data[i].pol,
+				buscfg->bus.csi2.lanecfg.data[i].pos);
+		}
+
+		/*
+		 * FIXME: now we assume the CRC is always there.
+		 * Implement a way to obtain this information from the
+		 * sensor. Frame descriptors, perhaps?
+		 */
+		buscfg->bus.csi2.crc = 1;
+		break;
+
+	default:
+		dev_warn(dev, "%s: invalid interface %u\n", node->full_name,
+			 vep.base.port);
+		break;
+	}
+
+	return 0;
+}
+
+static int isp_of_parse_nodes(struct device *dev,
+			      struct v4l2_async_notifier *notifier)
+{
+	struct device_node *node;
+
+	notifier->subdevs = devm_kcalloc(
+		dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL);
+	if (!notifier->subdevs)
+		return -ENOMEM;
+
+	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;
+		}
+
+		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");
+			return -EINVAL;
+		}
+
+		isd->asd.match_type = V4L2_ASYNC_MATCH_OF;
+		notifier->num_subdevs++;
+	}
+
+	return notifier->num_subdevs;
+}
+
+static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,
+				     struct v4l2_subdev *subdev,
+				     struct v4l2_async_subdev *asd)
+{
+	struct isp_device *isp = container_of(async, struct isp_device,
+					      notifier);
+	struct isp_async_subdev *isd =
+		container_of(asd, struct isp_async_subdev, asd);
+	int ret;
+
+	ret = isp_link_entity(isp, &subdev->entity, isd->bus.interface);
+	if (ret < 0)
+		return ret;
+
+	isd->sd = subdev;
+	isd->sd->host_priv = &isd->bus;
+
+	return ret;
+}
+
+static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
+{
+	struct isp_device *isp = container_of(async, struct isp_device,
+					      notifier);
+
+	return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
+}
+
 /*
  * isp_probe - Probe ISP platform device
  * @pdev: Pointer to ISP platform device
@@ -2256,7 +2417,6 @@ static int isp_remove(struct platform_device *pdev)
  */
 static int isp_probe(struct platform_device *pdev)
 {
-	struct isp_platform_data *pdata = pdev->dev.platform_data;
 	struct isp_device *isp;
 	struct resource *mem;
 	int ret;
@@ -2268,13 +2428,42 @@ static int isp_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		ret = of_property_read_u32(pdev->dev.of_node, "ti,phy-type",
+					   &isp->phy_type);
+		if (ret)
+			return ret;
+
+		isp->syscon = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+							      "syscon");
+		if (IS_ERR(isp->syscon))
+			return PTR_ERR(isp->syscon);
+
+		ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1,
+						 &isp->syscon_offset);
+		if (ret)
+			return ret;
+
+		ret = isp_of_parse_nodes(&pdev->dev, &isp->notifier);
+		if (ret < 0)
+			return ret;
+		ret = v4l2_async_notifier_register(&isp->v4l2_dev,
+						   &isp->notifier);
+		if (ret)
+			return ret;
+	} else {
+		isp->pdata = pdev->dev.platform_data;
+		isp->syscon = syscon_regmap_lookup_by_pdevname("syscon.0");
+		if (IS_ERR(isp->syscon))
+			return PTR_ERR(isp->syscon);
+	}
+
 	isp->autoidle = autoidle;
 
 	mutex_init(&isp->isp_mutex);
 	spin_lock_init(&isp->stat_lock);
 
 	isp->dev = &pdev->dev;
-	isp->pdata = pdata;
 	isp->ref_count = 0;
 
 	ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32));
@@ -2346,6 +2535,11 @@ static int isp_probe(struct platform_device *pdev)
 		goto error_isp;
 	}
 
+	if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node) {
+		isp->syscon_offset = isp_res_maps[m].syscon_offset;
+		isp->phy_type = isp_res_maps[m].phy_type;
+	}
+
 	for (i = 1; i < OMAP3_ISP_IOMEM_CSI2A_REGS1; i++)
 		isp->mmio_base[i] =
 			isp->mmio_base[0] + isp_res_maps[m].offset[i];
@@ -2358,15 +2552,6 @@ static int isp_probe(struct platform_device *pdev)
 	isp->mmio_hist_base_phys =
 		mem->start + isp_res_maps[m].offset[OMAP3_ISP_IOMEM_HIST];
 
-	isp->syscon = syscon_regmap_lookup_by_pdevname("syscon.0");
-	if (IS_ERR(isp->syscon)) {
-		ret = PTR_ERR(isp->syscon);
-		goto error_isp;
-	}
-
-	isp->syscon_offset = isp_res_maps[m].syscon_offset;
-	isp->phy_type = isp_res_maps[m].phy_type;
-
 	/* IOMMU */
 	ret = isp_attach_iommu(isp);
 	if (ret < 0) {
@@ -2394,6 +2579,9 @@ static int isp_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto error_iommu;
 
+	isp->notifier.bound = isp_subdev_notifier_bound;
+	isp->notifier.complete = isp_subdev_notifier_complete;
+
 	ret = isp_register_entities(isp);
 	if (ret < 0)
 		goto error_modules;
@@ -2429,6 +2617,11 @@ static struct platform_device_id omap3isp_id_table[] = {
 };
 MODULE_DEVICE_TABLE(platform, omap3isp_id_table);
 
+static const struct of_device_id omap3isp_of_table[] = {
+	{ .compatible = "ti,omap3-isp" },
+	{ },
+};
+
 static struct platform_driver omap3isp_driver = {
 	.probe = isp_probe,
 	.remove = isp_remove,
@@ -2436,6 +2629,7 @@ static struct platform_driver omap3isp_driver = {
 	.driver = {
 		.name = "omap3isp",
 		.pm	= &omap3isp_pm_ops,
+		.of_match_table = omap3isp_of_table,
 	},
 };
 
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index dcb7d20..431224e 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -18,6 +18,7 @@
 #define OMAP3_ISP_CORE_H
 
 #include <media/omap3isp.h>
+#include <media/v4l2-async.h>
 #include <media/v4l2-device.h>
 #include <linux/clk-provider.h>
 #include <linux/device.h>
@@ -178,6 +179,7 @@ struct isp_xclk {
  */
 struct isp_device {
 	struct v4l2_device v4l2_dev;
+	struct v4l2_async_notifier notifier;
 	struct media_device media_dev;
 	struct device *dev;
 	u32 revision;
@@ -224,6 +226,15 @@ struct isp_device {
 
 	unsigned int sbl_resources;
 	unsigned int subclk_resources;
+
+#define ISP_MAX_SUBDEVS		8
+	struct v4l2_subdev *subdevs[ISP_MAX_SUBDEVS];
+};
+
+struct isp_async_subdev {
+	struct v4l2_subdev *sd;
+	struct isp_bus_cfg bus;
+	struct v4l2_async_subdev asd;
 };
 
 #define v4l2_dev_to_isp_device(dev) \
diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c
index d91dde1..495447d 100644
--- a/drivers/media/platform/omap3isp/ispcsiphy.c
+++ b/drivers/media/platform/omap3isp/ispcsiphy.c
@@ -173,6 +173,13 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy)
 	unsigned int i;
 	u32 reg;
 
+	if (!buscfg) {
+		struct isp_async_subdev *isd =
+			container_of(pipe->external->asd,
+				     struct isp_async_subdev, asd);
+		buscfg = &isd->bus;
+	}
+
 	if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1
 	    || buscfg->interface == ISP_INTERFACE_CCP2B_PHY2)
 		lanes = &buscfg->bus.ccp2.lanecfg;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v2 15/15] omap3isp: Deprecate platform data support
  2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
                   ` (13 preceding siblings ...)
  2015-03-25 22:57 ` [PATCH v2 14/15] omap3isp: Add support for the Device Tree Sakari Ailus
@ 2015-03-25 22:57 ` Sakari Ailus
  14 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-25 22:57 UTC (permalink / raw)
  To: linux-media; +Cc: linux-omap, tony, sre, pali.rohar, laurent.pinchart

Print a warning when the driver is used with platform data. Existing
platform data users should move to DT now.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 drivers/media/platform/omap3isp/isp.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index e12484e..ff8f633 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2456,6 +2456,8 @@ static int isp_probe(struct platform_device *pdev)
 		isp->syscon = syscon_regmap_lookup_by_pdevname("syscon.0");
 		if (IS_ERR(isp->syscon))
 			return PTR_ERR(isp->syscon);
+		dev_warn(&pdev->dev,
+			 "Platform data support is deprecated! Please move to DT now!\n");
 	}
 
 	isp->autoidle = autoidle;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 06/15] omap3isp: Refactor device configuration structs for Device Tree
  2015-03-25 22:57 ` [PATCH v2 06/15] omap3isp: Refactor device configuration structs for Device Tree Sakari Ailus
@ 2015-03-25 23:21   ` Tony Lindgren
  0 siblings, 0 replies; 27+ messages in thread
From: Tony Lindgren @ 2015-03-25 23:21 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, linux-omap, sre, pali.rohar, laurent.pinchart,
	Igor Grinberg

* Sakari Ailus <sakari.ailus@iki.fi> [150325 16:00]:
> Make omap3isp configuration data structures more suitable for consumption by
> the DT by separating the I2C bus information of all the sub-devices in a
> group and the ISP bus information from each other. The ISP bus information
> is made a pointer instead of being directly embedded in the struct.
> 
> In the case of the DT only the sensor specific information on the ISP bus
> configuration is retained. The structs are renamed to reflect that.
> 
> After this change the structs needed to describe device configuration can be
> allocated and accessed separately without those needed only in the case of
> platform data. The platform data related structs can be later removed once
> the support for platform data can be removed.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Igor Grinberg <grinberg@compulab.co.il>
> Acked-by: Igor Grinberg <grinberg@compulab.co.il> (for cm-t35)

There arch/arm/mach-omap2 changes here are OK to merge along with
the driver changes:

Acked-by: Tony Lindgren <tony@atomide.com>

> ---
>  arch/arm/mach-omap2/board-cm-t35.c          |   57 +++++++-----------
>  drivers/media/platform/omap3isp/isp.c       |   86 +++++++++++++--------------
>  drivers/media/platform/omap3isp/isp.h       |    2 +-
>  drivers/media/platform/omap3isp/ispccdc.c   |   26 ++++----
>  drivers/media/platform/omap3isp/ispccp2.c   |   22 +++----
>  drivers/media/platform/omap3isp/ispcsi2.c   |    8 +--
>  drivers/media/platform/omap3isp/ispcsiphy.c |   21 ++++---
>  include/media/omap3isp.h                    |   34 +++++------
>  8 files changed, 119 insertions(+), 137 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
> index 91738a1..b5dfbc1 100644
> --- a/arch/arm/mach-omap2/board-cm-t35.c
> +++ b/arch/arm/mach-omap2/board-cm-t35.c
> @@ -492,51 +492,36 @@ static struct twl4030_platform_data cm_t35_twldata = {
>  #include <media/omap3isp.h>
>  #include "devices.h"
>  
> -static struct i2c_board_info cm_t35_isp_i2c_boardinfo[] = {
> +static struct isp_platform_subdev cm_t35_isp_subdevs[] = {
>  	{
> -		I2C_BOARD_INFO("mt9t001", 0x5d),
> -	},
> -	{
> -		I2C_BOARD_INFO("tvp5150", 0x5c),
> -	},
> -};
> -
> -static struct isp_subdev_i2c_board_info cm_t35_isp_primary_subdevs[] = {
> -	{
> -		.board_info = &cm_t35_isp_i2c_boardinfo[0],
> -		.i2c_adapter_id = 3,
> -	},
> -	{ NULL, 0, },
> -};
> -
> -static struct isp_subdev_i2c_board_info cm_t35_isp_secondary_subdevs[] = {
> -	{
> -		.board_info = &cm_t35_isp_i2c_boardinfo[1],
> +		.board_info = &(struct i2c_board_info){
> +			I2C_BOARD_INFO("mt9t001", 0x5d)
> +		},
>  		.i2c_adapter_id = 3,
> -	},
> -	{ NULL, 0, },
> -};
> -
> -static struct isp_v4l2_subdevs_group cm_t35_isp_subdevs[] = {
> -	{
> -		.subdevs = cm_t35_isp_primary_subdevs,
> -		.interface = ISP_INTERFACE_PARALLEL,
> -		.bus = {
> -			.parallel = {
> -				.clk_pol = 1,
> +		.bus = &(struct isp_bus_cfg){
> +			.interface = ISP_INTERFACE_PARALLEL,
> +			.bus = {
> +				.parallel = {
> +					.clk_pol = 1,
> +				},
>  			},
>  		},
>  	},
>  	{
> -		.subdevs = cm_t35_isp_secondary_subdevs,
> -		.interface = ISP_INTERFACE_PARALLEL,
> -		.bus = {
> -			.parallel = {
> -				.clk_pol = 0,
> +		.board_info = &(struct i2c_board_info){
> +			I2C_BOARD_INFO("tvp5150", 0x5c),
> +		},
> +		.i2c_adapter_id = 3,
> +		.bus = &(struct isp_bus_cfg){
> +			.interface = ISP_INTERFACE_PARALLEL,
> +			.bus = {
> +				.parallel = {
> +					.clk_pol = 0,
> +				},
>  			},
>  		},
>  	},
> -	{ NULL, 0, },
> +	{ 0 },
>  };
>  
>  static struct isp_platform_data cm_t35_isp_pdata = {
> diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
> index 537377b..1b5c6df 100644
> --- a/drivers/media/platform/omap3isp/isp.c
> +++ b/drivers/media/platform/omap3isp/isp.c
> @@ -447,7 +447,7 @@ static void isp_core_init(struct isp_device *isp, int idle)
>   */
>  void omap3isp_configure_bridge(struct isp_device *isp,
>  			       enum ccdc_input_entity input,
> -			       const struct isp_parallel_platform_data *pdata,
> +			       const struct isp_parallel_cfg *parcfg,
>  			       unsigned int shift, unsigned int bridge)
>  {
>  	u32 ispctrl_val;
> @@ -462,8 +462,8 @@ void omap3isp_configure_bridge(struct isp_device *isp,
>  	switch (input) {
>  	case CCDC_INPUT_PARALLEL:
>  		ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
> -		ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
> -		shift += pdata->data_lane_shift * 2;
> +		ispctrl_val |= parcfg->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
> +		shift += parcfg->data_lane_shift * 2;
>  		break;
>  
>  	case CCDC_INPUT_CSI2A:
> @@ -1809,52 +1809,44 @@ static void isp_unregister_entities(struct isp_device *isp)
>  }
>  
>  /*
> - * isp_register_subdev_group - Register a group of subdevices
> + * isp_register_subdev - Register a sub-device
>   * @isp: OMAP3 ISP device
> - * @board_info: I2C subdevs board information array
> + * @isp_subdev: platform data related to a sub-device
>   *
> - * Register all I2C subdevices in the board_info array. The array must be
> - * terminated by a NULL entry, and the first entry must be the sensor.
> + * Register an I2C sub-device which has not been registered by other
> + * means (such as the Device Tree).
>   *
> - * Return a pointer to the sensor media entity if it has been successfully
> + * Return a pointer to the sub-device if it has been successfully
>   * registered, or NULL otherwise.
>   */
>  static struct v4l2_subdev *
> -isp_register_subdev_group(struct isp_device *isp,
> -		     struct isp_subdev_i2c_board_info *board_info)
> +isp_register_subdev(struct isp_device *isp,
> +		    struct isp_platform_subdev *isp_subdev)
>  {
> -	struct v4l2_subdev *sensor = NULL;
> -	unsigned int first;
> +	struct i2c_adapter *adapter;
> +	struct v4l2_subdev *sd;
>  
> -	if (board_info->board_info == NULL)
> +	if (isp_subdev->board_info == NULL)
>  		return NULL;
>  
> -	for (first = 1; board_info->board_info; ++board_info, first = 0) {
> -		struct v4l2_subdev *subdev;
> -		struct i2c_adapter *adapter;
> -
> -		adapter = i2c_get_adapter(board_info->i2c_adapter_id);
> -		if (adapter == NULL) {
> -			dev_err(isp->dev, "%s: Unable to get I2C adapter %d for "
> -				"device %s\n", __func__,
> -				board_info->i2c_adapter_id,
> -				board_info->board_info->type);
> -			continue;
> -		}
> -
> -		subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
> -				board_info->board_info, NULL);
> -		if (subdev == NULL) {
> -			dev_err(isp->dev, "%s: Unable to register subdev %s\n",
> -				__func__, board_info->board_info->type);
> -			continue;
> -		}
> +	adapter = i2c_get_adapter(isp_subdev->i2c_adapter_id);
> +	if (adapter == NULL) {
> +		dev_err(isp->dev,
> +			"%s: Unable to get I2C adapter %d for device %s\n",
> +			__func__, isp_subdev->i2c_adapter_id,
> +			isp_subdev->board_info->type);
> +		return NULL;
> +	}
>  
> -		if (first)
> -			sensor = subdev;
> +	sd = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
> +				       isp_subdev->board_info, NULL);
> +	if (sd == NULL) {
> +		dev_err(isp->dev, "%s: Unable to register subdev %s\n",
> +			__func__, isp_subdev->board_info->type);
> +		return NULL;
>  	}
>  
> -	return sensor;
> +	return sd;
>  }
>  
>  static int isp_link_entity(
> @@ -1931,7 +1923,7 @@ static int isp_link_entity(
>  static int isp_register_entities(struct isp_device *isp)
>  {
>  	struct isp_platform_data *pdata = isp->pdata;
> -	struct isp_v4l2_subdevs_group *subdevs;
> +	struct isp_platform_subdev *isp_subdev;
>  	int ret;
>  
>  	isp->media_dev.dev = isp->dev;
> @@ -1989,17 +1981,23 @@ static int isp_register_entities(struct isp_device *isp)
>  		goto done;
>  
>  	/* Register external entities */
> -	for (subdevs = pdata ? pdata->subdevs : NULL;
> -	     subdevs && subdevs->subdevs; ++subdevs) {
> -		struct v4l2_subdev *sensor;
> +	for (isp_subdev = pdata ? pdata->subdevs : NULL;
> +	     isp_subdev && isp_subdev->board_info; isp_subdev++) {
> +		struct v4l2_subdev *sd;
>  
> -		sensor = isp_register_subdev_group(isp, subdevs->subdevs);
> -		if (sensor == NULL)
> +		sd = isp_register_subdev(isp, isp_subdev);
> +
> +		/*
> +		 * No bus information --- this is either a flash or a
> +		 * lens subdev.
> +		 */
> +		if (!sd || !isp_subdev->bus)
>  			continue;
>  
> -		sensor->host_priv = subdevs;
> +		sd->host_priv = isp_subdev->bus;
>  
> -		ret = isp_link_entity(isp, &sensor->entity, subdevs->interface);
> +		ret = isp_link_entity(isp, &sd->entity,
> +				      isp_subdev->bus->interface);
>  		if (ret < 0)
>  			goto done;
>  	}
> diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
> index cfdfc87..b932a6f 100644
> --- a/drivers/media/platform/omap3isp/isp.h
> +++ b/drivers/media/platform/omap3isp/isp.h
> @@ -229,7 +229,7 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
>  void omap3isp_pipeline_cancel_stream(struct isp_pipeline *pipe);
>  void omap3isp_configure_bridge(struct isp_device *isp,
>  			       enum ccdc_input_entity input,
> -			       const struct isp_parallel_platform_data *pdata,
> +			       const struct isp_parallel_cfg *buscfg,
>  			       unsigned int shift, unsigned int bridge);
>  
>  struct isp_device *omap3isp_get(struct isp_device *isp);
> diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
> index 587489a..388f971 100644
> --- a/drivers/media/platform/omap3isp/ispccdc.c
> +++ b/drivers/media/platform/omap3isp/ispccdc.c
> @@ -958,11 +958,11 @@ void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
>  /*
>   * ccdc_config_sync_if - Set CCDC sync interface configuration
>   * @ccdc: Pointer to ISP CCDC device.
> - * @pdata: Parallel interface platform data (may be NULL)
> + * @parcfg: Parallel interface platform data (may be NULL)
>   * @data_size: Data size
>   */
>  static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
> -				struct isp_parallel_platform_data *pdata,
> +				struct isp_parallel_cfg *parcfg,
>  				unsigned int data_size)
>  {
>  	struct isp_device *isp = to_isp_device(ccdc);
> @@ -1000,19 +1000,19 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
>  		break;
>  	}
>  
> -	if (pdata && pdata->data_pol)
> +	if (parcfg && parcfg->data_pol)
>  		syn_mode |= ISPCCDC_SYN_MODE_DATAPOL;
>  
> -	if (pdata && pdata->hs_pol)
> +	if (parcfg && parcfg->hs_pol)
>  		syn_mode |= ISPCCDC_SYN_MODE_HDPOL;
>  
>  	/* The polarity of the vertical sync signal output by the BT.656
>  	 * decoder is not documented and seems to be active low.
>  	 */
> -	if ((pdata && pdata->vs_pol) || ccdc->bt656)
> +	if ((parcfg && parcfg->vs_pol) || ccdc->bt656)
>  		syn_mode |= ISPCCDC_SYN_MODE_VDPOL;
>  
> -	if (pdata && pdata->fld_pol)
> +	if (parcfg && parcfg->fld_pol)
>  		syn_mode |= ISPCCDC_SYN_MODE_FLDPOL;
>  
>  	isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
> @@ -1115,7 +1115,7 @@ static const u32 ccdc_sgbrg_pattern =
>  static void ccdc_configure(struct isp_ccdc_device *ccdc)
>  {
>  	struct isp_device *isp = to_isp_device(ccdc);
> -	struct isp_parallel_platform_data *pdata = NULL;
> +	struct isp_parallel_cfg *parcfg = NULL;
>  	struct v4l2_subdev *sensor;
>  	struct v4l2_mbus_framefmt *format;
>  	const struct v4l2_rect *crop;
> @@ -1145,7 +1145,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
>  		if (!ret)
>  			ccdc->bt656 = cfg.type == V4L2_MBUS_BT656;
>  
> -		pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
> +		parcfg = &((struct isp_bus_cfg *)sensor->host_priv)
>  			->bus.parallel;
>  	}
>  
> @@ -1175,10 +1175,10 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
>  	else
>  		bridge = ISPCTRL_PAR_BRIDGE_DISABLE;
>  
> -	omap3isp_configure_bridge(isp, ccdc->input, pdata, shift, bridge);
> +	omap3isp_configure_bridge(isp, ccdc->input, parcfg, shift, bridge);
>  
>  	/* Configure the sync interface. */
> -	ccdc_config_sync_if(ccdc, pdata, depth_out);
> +	ccdc_config_sync_if(ccdc, parcfg, depth_out);
>  
>  	syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
>  
> @@ -2417,11 +2417,11 @@ static int ccdc_link_validate(struct v4l2_subdev *sd,
>  
>  	/* We've got a parallel sensor here. */
>  	if (ccdc->input == CCDC_INPUT_PARALLEL) {
> -		struct isp_parallel_platform_data *pdata =
> -			&((struct isp_v4l2_subdevs_group *)
> +		struct isp_parallel_cfg *parcfg =
> +			&((struct isp_bus_cfg *)
>  			  media_entity_to_v4l2_subdev(link->source->entity)
>  			  ->host_priv)->bus.parallel;
> -		parallel_shift = pdata->data_lane_shift * 2;
> +		parallel_shift = parcfg->data_lane_shift * 2;
>  	} else {
>  		parallel_shift = 0;
>  	}
> diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
> index f4aedb3..374a1f4 100644
> --- a/drivers/media/platform/omap3isp/ispccp2.c
> +++ b/drivers/media/platform/omap3isp/ispccp2.c
> @@ -201,14 +201,14 @@ static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable)
>  /*
>   * ccp2_phyif_config - Initialize CCP2 phy interface config
>   * @ccp2: Pointer to ISP CCP2 device
> - * @pdata: CCP2 platform data
> + * @buscfg: CCP2 platform data
>   *
>   * Configure the CCP2 physical interface module from platform data.
>   *
>   * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success.
>   */
>  static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
> -			     const struct isp_ccp2_platform_data *pdata)
> +			     const struct isp_ccp2_cfg *buscfg)
>  {
>  	struct isp_device *isp = to_isp_device(ccp2);
>  	u32 val;
> @@ -218,16 +218,16 @@ static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
>  			    ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE;
>  	/* Data/strobe physical layer */
>  	BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK,
> -		pdata->phy_layer);
> +		buscfg->phy_layer);
>  	BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK,
> -		pdata->strobe_clk_pol);
> +		buscfg->strobe_clk_pol);
>  	isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
>  
>  	val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
>  	if (!(val & ISPCCP2_CTRL_MODE)) {
> -		if (pdata->ccp2_mode == ISP_CCP2_MODE_CCP2)
> +		if (buscfg->ccp2_mode == ISP_CCP2_MODE_CCP2)
>  			dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n");
> -		if (pdata->phy_layer == ISP_CCP2_PHY_DATA_STROBE)
> +		if (buscfg->phy_layer == ISP_CCP2_PHY_DATA_STROBE)
>  			/* Strobe mode requires CCP2 */
>  			return -EIO;
>  	}
> @@ -347,7 +347,7 @@ static void ccp2_lcx_config(struct isp_ccp2_device *ccp2,
>   */
>  static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
>  {
> -	const struct isp_v4l2_subdevs_group *pdata;
> +	const struct isp_bus_cfg *buscfg;
>  	struct v4l2_mbus_framefmt *format;
>  	struct media_pad *pad;
>  	struct v4l2_subdev *sensor;
> @@ -358,20 +358,20 @@ static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
>  
>  	pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]);
>  	sensor = media_entity_to_v4l2_subdev(pad->entity);
> -	pdata = sensor->host_priv;
> +	buscfg = sensor->host_priv;
>  
> -	ret = ccp2_phyif_config(ccp2, &pdata->bus.ccp2);
> +	ret = ccp2_phyif_config(ccp2, &buscfg->bus.ccp2);
>  	if (ret < 0)
>  		return ret;
>  
> -	ccp2_vp_config(ccp2, pdata->bus.ccp2.vpclk_div + 1);
> +	ccp2_vp_config(ccp2, buscfg->bus.ccp2.vpclk_div + 1);
>  
>  	v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines);
>  
>  	format = &ccp2->formats[CCP2_PAD_SINK];
>  
>  	ccp2->if_cfg.data_start = lines;
> -	ccp2->if_cfg.crc = pdata->bus.ccp2.crc;
> +	ccp2->if_cfg.crc = buscfg->bus.ccp2.crc;
>  	ccp2->if_cfg.format = format->code;
>  	ccp2->if_cfg.data_size = format->height;
>  
> diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
> index 09c686d..14d279d 100644
> --- a/drivers/media/platform/omap3isp/ispcsi2.c
> +++ b/drivers/media/platform/omap3isp/ispcsi2.c
> @@ -548,7 +548,7 @@ int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
>  
>  static int csi2_configure(struct isp_csi2_device *csi2)
>  {
> -	const struct isp_v4l2_subdevs_group *pdata;
> +	const struct isp_bus_cfg *buscfg;
>  	struct isp_device *isp = csi2->isp;
>  	struct isp_csi2_timing_cfg *timing = &csi2->timing[0];
>  	struct v4l2_subdev *sensor;
> @@ -565,14 +565,14 @@ static int csi2_configure(struct isp_csi2_device *csi2)
>  
>  	pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]);
>  	sensor = media_entity_to_v4l2_subdev(pad->entity);
> -	pdata = sensor->host_priv;
> +	buscfg = sensor->host_priv;
>  
>  	csi2->frame_skip = 0;
>  	v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
>  
> -	csi2->ctrl.vp_out_ctrl = pdata->bus.csi2.vpclk_div;
> +	csi2->ctrl.vp_out_ctrl = buscfg->bus.csi2.vpclk_div;
>  	csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE;
> -	csi2->ctrl.ecc_enable = pdata->bus.csi2.crc;
> +	csi2->ctrl.ecc_enable = buscfg->bus.csi2.crc;
>  
>  	timing->ionum = 1;
>  	timing->force_rx_mode = 1;
> diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c
> index e033f22..4486e9f 100644
> --- a/drivers/media/platform/omap3isp/ispcsiphy.c
> +++ b/drivers/media/platform/omap3isp/ispcsiphy.c
> @@ -168,18 +168,18 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy)
>  {
>  	struct isp_csi2_device *csi2 = phy->csi2;
>  	struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
> -	struct isp_v4l2_subdevs_group *subdevs = pipe->external->host_priv;
> +	struct isp_bus_cfg *buscfg = pipe->external->host_priv;
>  	struct isp_csiphy_lanes_cfg *lanes;
>  	int csi2_ddrclk_khz;
>  	unsigned int used_lanes = 0;
>  	unsigned int i;
>  	u32 reg;
>  
> -	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1
> -	    || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2)
> -		lanes = &subdevs->bus.ccp2.lanecfg;
> +	if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1
> +	    || buscfg->interface == ISP_INTERFACE_CCP2B_PHY2)
> +		lanes = &buscfg->bus.ccp2.lanecfg;
>  	else
> -		lanes = &subdevs->bus.csi2.lanecfg;
> +		lanes = &buscfg->bus.csi2.lanecfg;
>  
>  	/* Clock and data lanes verification */
>  	for (i = 0; i < phy->num_data_lanes; i++) {
> @@ -203,8 +203,8 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy)
>  	 * issue since the MPU power domain is forced on whilst the
>  	 * ISP is in use.
>  	 */
> -	csiphy_routing_cfg(phy, subdevs->interface, true,
> -			   subdevs->bus.ccp2.phy_layer);
> +	csiphy_routing_cfg(phy, buscfg->interface, true,
> +			   buscfg->bus.ccp2.phy_layer);
>  
>  	/* DPHY timing configuration */
>  	/* CSI-2 is DDR and we only count used lanes. */
> @@ -302,11 +302,10 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy)
>  		struct isp_csi2_device *csi2 = phy->csi2;
>  		struct isp_pipeline *pipe =
>  			to_isp_pipeline(&csi2->subdev.entity);
> -		struct isp_v4l2_subdevs_group *subdevs =
> -			pipe->external->host_priv;
> +		struct isp_bus_cfg *buscfg = pipe->external->host_priv;
>  
> -		csiphy_routing_cfg(phy, subdevs->interface, false,
> -				   subdevs->bus.ccp2.phy_layer);
> +		csiphy_routing_cfg(phy, buscfg->interface, false,
> +				   buscfg->bus.ccp2.phy_layer);
>  		csiphy_power_autoswitch_enable(phy, false);
>  		csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF);
>  		regulator_disable(phy->vdd);
> diff --git a/include/media/omap3isp.h b/include/media/omap3isp.h
> index 398279d..39e0748 100644
> --- a/include/media/omap3isp.h
> +++ b/include/media/omap3isp.h
> @@ -45,7 +45,7 @@ enum {
>  };
>  
>  /**
> - * struct isp_parallel_platform_data - Parallel interface platform data
> + * struct isp_parallel_cfg - Parallel interface configuration
>   * @data_lane_shift: Data lane shifter
>   *		ISP_LANE_SHIFT_0 - CAMEXT[13:0] -> CAM[13:0]
>   *		ISP_LANE_SHIFT_2 - CAMEXT[13:2] -> CAM[11:0]
> @@ -62,7 +62,7 @@ enum {
>   * @data_pol: Data polarity
>   *		0 - Normal, 1 - One's complement
>   */
> -struct isp_parallel_platform_data {
> +struct isp_parallel_cfg {
>  	unsigned int data_lane_shift:2;
>  	unsigned int clk_pol:1;
>  	unsigned int hs_pol:1;
> @@ -105,7 +105,7 @@ struct isp_csiphy_lanes_cfg {
>  };
>  
>  /**
> - * struct isp_ccp2_platform_data - CCP2 interface platform data
> + * struct isp_ccp2_cfg - CCP2 interface configuration
>   * @strobe_clk_pol: Strobe/clock polarity
>   *		0 - Non Inverted, 1 - Inverted
>   * @crc: Enable the cyclic redundancy check
> @@ -117,7 +117,7 @@ struct isp_csiphy_lanes_cfg {
>   *		ISP_CCP2_PHY_DATA_STROBE - Data/strobe physical layer
>   * @vpclk_div: Video port output clock control
>   */
> -struct isp_ccp2_platform_data {
> +struct isp_ccp2_cfg {
>  	unsigned int strobe_clk_pol:1;
>  	unsigned int crc:1;
>  	unsigned int ccp2_mode:1;
> @@ -127,31 +127,31 @@ struct isp_ccp2_platform_data {
>  };
>  
>  /**
> - * struct isp_csi2_platform_data - CSI2 interface platform data
> + * struct isp_csi2_cfg - CSI2 interface configuration
>   * @crc: Enable the cyclic redundancy check
>   * @vpclk_div: Video port output clock control
>   */
> -struct isp_csi2_platform_data {
> +struct isp_csi2_cfg {
>  	unsigned crc:1;
>  	unsigned vpclk_div:2;
>  	struct isp_csiphy_lanes_cfg lanecfg;
>  };
>  
> -struct isp_subdev_i2c_board_info {
> -	struct i2c_board_info *board_info;
> -	int i2c_adapter_id;
> -};
> -
> -struct isp_v4l2_subdevs_group {
> -	struct isp_subdev_i2c_board_info *subdevs;
> +struct isp_bus_cfg {
>  	enum isp_interface_type interface;
>  	union {
> -		struct isp_parallel_platform_data parallel;
> -		struct isp_ccp2_platform_data ccp2;
> -		struct isp_csi2_platform_data csi2;
> +		struct isp_parallel_cfg parallel;
> +		struct isp_ccp2_cfg ccp2;
> +		struct isp_csi2_cfg csi2;
>  	} bus; /* gcc < 4.6.0 chokes on anonymous union initializers */
>  };
>  
> +struct isp_platform_subdev {
> +	struct i2c_board_info *board_info;
> +	int i2c_adapter_id;
> +	struct isp_bus_cfg *bus;
> +};
> +
>  struct isp_platform_xclk {
>  	const char *dev_id;
>  	const char *con_id;
> @@ -159,7 +159,7 @@ struct isp_platform_xclk {
>  
>  struct isp_platform_data {
>  	struct isp_platform_xclk xclks[2];
> -	struct isp_v4l2_subdevs_group *subdevs;
> +	struct isp_platform_subdev *subdevs;
>  	void (*set_constraints)(struct isp_device *isp, bool enable);
>  };
>  
> -- 
> 1.7.10.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 14/15] omap3isp: Add support for the Device Tree
  2015-03-25 22:57 ` [PATCH v2 14/15] omap3isp: Add support for the Device Tree Sakari Ailus
@ 2015-03-30 17:41   ` Sebastian Reichel
  2015-03-30 21:17     ` Sakari Ailus
  2015-03-30 23:13     ` [PATCH 1/1] omap3isp: Don't pass uninitialised arguments to of_graph_get_next_endpoint() Sakari Ailus
  0 siblings, 2 replies; 27+ messages in thread
From: Sebastian Reichel @ 2015-03-30 17:41 UTC (permalink / raw)
  To: Sakari Ailus; +Cc: linux-media, linux-omap, tony, pali.rohar, laurent.pinchart

[-- Attachment #1: Type: text/plain, Size: 543 bytes --]

Hi,

The code crashed for me on Nokia N900. I found the following
problem:

On Thu, Mar 26, 2015 at 12:57:38AM +0200, Sakari Ailus wrote:
> [...]
> +static int isp_of_parse_nodes(struct device *dev,
> +			      struct v4l2_async_notifier *notifier)
> +{
> +	struct device_node *node;

struct device_node *node = NULL;

to avoid feeding a random pointer into of_graph_get_next_endpoint():

> [...]
> +	while (notifier->num_subdevs < ISP_MAX_SUBDEVS &&
> +	       (node = of_graph_get_next_endpoint(dev->of_node, node))) {
> [...]

-- Sebastian

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 14/15] omap3isp: Add support for the Device Tree
  2015-03-30 17:41   ` Sebastian Reichel
@ 2015-03-30 21:17     ` Sakari Ailus
  2015-03-30 23:13     ` [PATCH 1/1] omap3isp: Don't pass uninitialised arguments to of_graph_get_next_endpoint() Sakari Ailus
  1 sibling, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-03-30 21:17 UTC (permalink / raw)
  To: Sebastian Reichel, laurent.pinchart
  Cc: linux-media, linux-omap, tony, pali.rohar

Hi Sebastian,

On Mon, Mar 30, 2015 at 07:41:23PM +0200, Sebastian Reichel wrote:
> Hi,
> 
> The code crashed for me on Nokia N900. I found the following
> problem:
> 
> On Thu, Mar 26, 2015 at 12:57:38AM +0200, Sakari Ailus wrote:
> > [...]
> > +static int isp_of_parse_nodes(struct device *dev,
> > +			      struct v4l2_async_notifier *notifier)
> > +{
> > +	struct device_node *node;
> 
> struct device_node *node = NULL;
> 
> to avoid feeding a random pointer into of_graph_get_next_endpoint():

Good catch!

Laurent, could you use a new version of this patch, and send a new pull
request, or would you prefer an additional patch to fix this?

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 1/1] omap3isp: Don't pass uninitialised arguments to of_graph_get_next_endpoint()
  2015-03-30 17:41   ` Sebastian Reichel
  2015-03-30 21:17     ` Sakari Ailus
@ 2015-03-30 23:13     ` Sakari Ailus
  2015-03-31  1:37       ` Sebastian Reichel
  1 sibling, 1 reply; 27+ messages in thread
From: Sakari Ailus @ 2015-03-30 23:13 UTC (permalink / raw)
  To: linux-media, sre; +Cc: linux-omap, laurent.pinchart, pali.rohar, tony

isp_of_parse_nodes() passed an uninitialised prev argument to
of_graph_get_next_endpoint(). This is bad, fix it by assigning NULL to it in
the initialisation.

Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
Reported-by: Sebastian Reichel <sre@kernel.org>
---
 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 ff8f633..ff51c4f 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2338,7 +2338,7 @@ static int isp_of_parse_node(struct device *dev, struct device_node *node,
 static int isp_of_parse_nodes(struct device *dev,
 			      struct v4l2_async_notifier *notifier)
 {
-	struct device_node *node;
+	struct device_node *node = NULL;
 
 	notifier->subdevs = devm_kcalloc(
 		dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/1] omap3isp: Don't pass uninitialised arguments to of_graph_get_next_endpoint()
  2015-03-30 23:13     ` [PATCH 1/1] omap3isp: Don't pass uninitialised arguments to of_graph_get_next_endpoint() Sakari Ailus
@ 2015-03-31  1:37       ` Sebastian Reichel
  2015-04-01 22:41         ` Sakari Ailus
  0 siblings, 1 reply; 27+ messages in thread
From: Sebastian Reichel @ 2015-03-31  1:37 UTC (permalink / raw)
  To: Sakari Ailus; +Cc: linux-media, linux-omap, laurent.pinchart, pali.rohar, tony

[-- Attachment #1: Type: text/plain, Size: 5677 bytes --]

Hi,

On Tue, Mar 31, 2015 at 02:13:28AM +0300, Sakari Ailus wrote:
> isp_of_parse_nodes() passed an uninitialised prev argument to
> of_graph_get_next_endpoint(). This is bad, fix it by assigning NULL to it in
> the initialisation.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
> Reported-by: Sebastian Reichel <sre@kernel.org>
> ---
>  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 ff8f633..ff51c4f 100644
> --- a/drivers/media/platform/omap3isp/isp.c
> +++ b/drivers/media/platform/omap3isp/isp.c
> @@ -2338,7 +2338,7 @@ static int isp_of_parse_node(struct device *dev, struct device_node *node,
>  static int isp_of_parse_nodes(struct device *dev,
>  			      struct v4l2_async_notifier *notifier)
>  {
> -	struct device_node *node;
> +	struct device_node *node = NULL;
>  
>  	notifier->subdevs = devm_kcalloc(
>  		dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL);

Acked-By: Sebastian Reichel <sre@kernel.org>

Note, that this actually triggered the following stacktrace for me,
so you may want to add a Fixes: <commitid> and the stacktrace to the
commit message if its not merged with the original commit (relevant
for people doing git bisect).

[    1.587951] pgd = c0004000
[    1.590820] [fffffe17] *pgd=8fef6821, *pte=00000000, *ppte=00000000
[    1.597503] Internal error: Oops: 17 [#1] SMP ARM
[    1.602478] Modules linked in:
[    1.605743] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.0.0-rc1-00019-g258ac6a-dirty #293
[    1.614379] Hardware name: Nokia RX-51 board
[    1.618896] task: ce0aab80 ti: ce0ac000 task.ti: ce0ac000
[    1.624603] PC is at of_get_parent+0x18/0x34
[    1.629150] LR is at _raw_spin_lock_irqsave+0x48/0x54
[    1.634490] pc : [<c05c6034>]    lr : [<c07d5e20>]    psr: 60000193
[    1.634490] sp : ce0addc8  ip : c0c0b5a0  fp : c0b91b90
[    1.646636] r10: c0b2e598  r9 : ce3804d0  r8 : 00000000
[    1.652160] r7 : fffffdfb  r6 : cfc84c44  r5 : fffffdfb  r4 : fffffdfb
[    1.659057] r3 : 60000193  r2 : 00000000  r1 : 95d695d5  r0 : a0000113
[    1.665954] Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
[    1.673767] Control: 10c5387d  Table: 80004019  DAC: 00000015
[    1.679870] Process swapper/0 (pid: 1, stack limit = 0xce0ac218)
[    1.686218] Stack: (0xce0addc8 to 0xce0ae000)
[    1.690826] ddc0:                   ce380010 c05c662c ce545810 c041d9e0 ce380010 ce1f4010
[    1.699462] dde0: ce1f4000 c056b024 c07d4254 ce0aab80 00000001 c142199c c0a547f0 c0085dcc
[    1.708129] de00: c0bfeee8 60000113 c0bfef0c c07d4254 00000002 00000000 ce546c90 ce1f6270
[    1.716766] de20: ce1f6270 c01bced0 ce1f6270 c0a547f0 ce1f6270 ce546d50 00000000 00000001
[    1.725433] de40: ce1f6270 c0a547f0 ce546c90 c1457f98 ce1f4010 c0c304d4 fffffdfb 00000000
[    1.734069] de60: 00000000 c0b2e598 c0b91b90 c041c6c8 c041c684 c1457f98 ce1f4010 00000000
[    1.742736] de80: c0c304d4 c041ade4 00000000 ce1f4010 c0c304d4 ce1f4044 c0c18730 00000000
[    1.751373] dea0: c0b91b98 c041aff4 00000000 c0c304d4 c041af60 c041936c ce0d7ca4 ce1f7e90
[    1.760040] dec0: c0c304d4 ce526740 00000000 c041a608 c09f8b88 c0c304d4 c0bb3eb0 c0c304d4
[    1.768676] dee0: c0bb3eb0 ce5458c0 c0b71550 c041b74c 00000000 c0bb3eb0 c0bb3eb0 c0008b64
[    1.777343] df00: cfeff246 cfeff241 c082416c c0aed820 00000100 c0aede00 00000000 0000005e
[    1.785980] df20: cfeff241 ce0adf38 00000072 00000000 cfeff292 c005b040 c0a6bfb8 cfeff294
[    1.794647] df40: 00000006 00000006 00000000 c0ba7c74 c0ba7fa8 00000006 c0c61700 00000114
[    1.803283] df60: c0c61700 c0b2e598 c0b91b90 c0b2eea0 00000006 00000006 c0b2e598 ffffffff
[    1.811920] df80: fffbfdff 00000000 c07ca054 00000000 00000000 00000000 00000000 00000000
[    1.820587] dfa0: 00000000 c07ca05c 00000000 c000e8f0 00000000 00000000 00000000 00000000
[    1.829223] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    1.837890] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffffffff ffffffff
[    1.846557] [<c05c6034>] (of_get_parent) from [<c05c662c>] (of_graph_get_next_endpoint+0x24/0x118)
[    1.856018] [<c05c662c>] (of_graph_get_next_endpoint) from [<c056b024>] (isp_probe+0x118/0xf58)
[    1.865234] [<c056b024>] (isp_probe) from [<c041c6c8>] (platform_drv_probe+0x44/0xa4)
[    1.873535] [<c041c6c8>] (platform_drv_probe) from [<c041ade4>] (driver_probe_device+0x104/0x23c)
[    1.882934] [<c041ade4>] (driver_probe_device) from [<c041aff4>] (__driver_attach+0x94/0x98)
[    1.891876] [<c041aff4>] (__driver_attach) from [<c041936c>] (bus_for_each_dev+0x6c/0xa0)
[    1.900512] [<c041936c>] (bus_for_each_dev) from [<c041a608>] (bus_add_driver+0x144/0x1f0)
[    1.909271] [<c041a608>] (bus_add_driver) from [<c041b74c>] (driver_register+0x78/0xf8)
[    1.917755] [<c041b74c>] (driver_register) from [<c0008b64>] (do_one_initcall+0x80/0x1dc)
[    1.926391] [<c0008b64>] (do_one_initcall) from [<c0b2eea0>] (kernel_init_freeable+0x204/0x2d0)
[    1.935607] [<c0b2eea0>] (kernel_init_freeable) from [<c07ca05c>] (kernel_init+0x8/0xec)
[    1.944183] [<c07ca05c>] (kernel_init) from [<c000e8f0>] (ret_from_fork+0x14/0x24)
[    1.952209] Code: e1a04000 0a000005 e59f0018 eb083f68 (e594401c) 
[    1.958709] ---[ end trace 5d64830d502ea2d7 ]---
[    1.965698] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[    1.965698] 
[    1.975402] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[    1.975402] 

-- Sebastian

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/1] omap3isp: Don't pass uninitialised arguments to of_graph_get_next_endpoint()
  2015-03-31  1:37       ` Sebastian Reichel
@ 2015-04-01 22:41         ` Sakari Ailus
  0 siblings, 0 replies; 27+ messages in thread
From: Sakari Ailus @ 2015-04-01 22:41 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: linux-media, linux-omap, laurent.pinchart, pali.rohar, tony

Hi Sebastian,

On Tue, Mar 31, 2015 at 03:37:20AM +0200, Sebastian Reichel wrote:
> Hi,
> 
> On Tue, Mar 31, 2015 at 02:13:28AM +0300, Sakari Ailus wrote:
> > isp_of_parse_nodes() passed an uninitialised prev argument to
> > of_graph_get_next_endpoint(). This is bad, fix it by assigning NULL to it in
> > the initialisation.
> > 
> > Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
> > Reported-by: Sebastian Reichel <sre@kernel.org>
> > ---
> >  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 ff8f633..ff51c4f 100644
> > --- a/drivers/media/platform/omap3isp/isp.c
> > +++ b/drivers/media/platform/omap3isp/isp.c
> > @@ -2338,7 +2338,7 @@ static int isp_of_parse_node(struct device *dev, struct device_node *node,
> >  static int isp_of_parse_nodes(struct device *dev,
> >  			      struct v4l2_async_notifier *notifier)
> >  {
> > -	struct device_node *node;
> > +	struct device_node *node = NULL;
> >  
> >  	notifier->subdevs = devm_kcalloc(
> >  		dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL);
> 
> Acked-By: Sebastian Reichel <sre@kernel.org>
> 
> Note, that this actually triggered the following stacktrace for me,
> so you may want to add a Fixes: <commitid> and the stacktrace to the
> commit message if its not merged with the original commit (relevant
> for people doing git bisect).

Thanks.

Laurent merged the patch with the original one, and will send a new pull
request.

-- 
Regards,

Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 12/15] dt: bindings: Add lane-polarity property to endpoint nodes
  2015-03-25 22:57 ` [PATCH v2 12/15] dt: bindings: Add lane-polarity property to endpoint nodes Sakari Ailus
@ 2015-04-24 19:41     ` Benoit Parrot
  0 siblings, 0 replies; 27+ messages in thread
From: Benoit Parrot @ 2015-04-24 19:41 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, linux-omap, tony, sre, pali.rohar, laurent.pinchart

Sakari Ailus <sakari.ailus@iki.fi> wrote on Thu [2015-Mar-26 00:57:36 +0200]:
> Add lane-polarity property to endpoint nodes. This essentially tells that
> the order of the differential signal wires is inverted.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  Documentation/devicetree/bindings/media/video-interfaces.txt |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt
> index 571b4c6..9cd2a36 100644
> --- a/Documentation/devicetree/bindings/media/video-interfaces.txt
> +++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
> @@ -106,6 +106,12 @@ Optional endpoint properties
>  - link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for
>    instance, this is the actual frequency of the bus, not bits per clock per
>    lane value. An array of 64-bit unsigned integers.
> +- lane-polarities: an array of polarities of the lanes starting from the clock
> +  lane and followed by the data lanes in the same order as in data-lanes.
> +  Valid values are 0 (normal) and 1 (inverted). The length of the array
> +  should be the combined length of data-lanes and clock-lanes properties.
> +  If the lane-polarities property is omitted, the value must be interpreted
> +  as 0 (normal). This property is valid for serial busses only.
>  

I am interested in this functionality.
But I do have the following question.
If the lane-polarities property is not specified, shouldn't the
relevant struct member (bus->lane_polarities[i]) be set to 0?

Regards,
Benoit
>  
>  Example
> -- 
> 1.7.10.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 12/15] dt: bindings: Add lane-polarity property to endpoint nodes
@ 2015-04-24 19:41     ` Benoit Parrot
  0 siblings, 0 replies; 27+ messages in thread
From: Benoit Parrot @ 2015-04-24 19:41 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, linux-omap, tony, sre, pali.rohar, laurent.pinchart

Sakari Ailus <sakari.ailus@iki.fi> wrote on Thu [2015-Mar-26 00:57:36 +0200]:
> Add lane-polarity property to endpoint nodes. This essentially tells that
> the order of the differential signal wires is inverted.
> 
> Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  Documentation/devicetree/bindings/media/video-interfaces.txt |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt
> index 571b4c6..9cd2a36 100644
> --- a/Documentation/devicetree/bindings/media/video-interfaces.txt
> +++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
> @@ -106,6 +106,12 @@ Optional endpoint properties
>  - link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for
>    instance, this is the actual frequency of the bus, not bits per clock per
>    lane value. An array of 64-bit unsigned integers.
> +- lane-polarities: an array of polarities of the lanes starting from the clock
> +  lane and followed by the data lanes in the same order as in data-lanes.
> +  Valid values are 0 (normal) and 1 (inverted). The length of the array
> +  should be the combined length of data-lanes and clock-lanes properties.
> +  If the lane-polarities property is omitted, the value must be interpreted
> +  as 0 (normal). This property is valid for serial busses only.
>  

I am interested in this functionality.
But I do have the following question.
If the lane-polarities property is not specified, shouldn't the
relevant struct member (bus->lane_polarities[i]) be set to 0?

Regards,
Benoit
>  
>  Example
> -- 
> 1.7.10.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 12/15] dt: bindings: Add lane-polarity property to endpoint nodes
  2015-04-24 19:41     ` Benoit Parrot
  (?)
@ 2015-04-24 19:49     ` Sakari Ailus
  2015-04-24 19:53         ` Benoit Parrot
  -1 siblings, 1 reply; 27+ messages in thread
From: Sakari Ailus @ 2015-04-24 19:49 UTC (permalink / raw)
  To: Benoit Parrot
  Cc: linux-media, linux-omap, tony, sre, pali.rohar, laurent.pinchart

Hi Benoit,

On Fri, Apr 24, 2015 at 02:41:00PM -0500, Benoit Parrot wrote:
> Sakari Ailus <sakari.ailus@iki.fi> wrote on Thu [2015-Mar-26 00:57:36 +0200]:
> > Add lane-polarity property to endpoint nodes. This essentially tells that
> > the order of the differential signal wires is inverted.
> > 
> > Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
> > Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> >  Documentation/devicetree/bindings/media/video-interfaces.txt |    6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt
> > index 571b4c6..9cd2a36 100644
> > --- a/Documentation/devicetree/bindings/media/video-interfaces.txt
> > +++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
> > @@ -106,6 +106,12 @@ Optional endpoint properties
> >  - link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for
> >    instance, this is the actual frequency of the bus, not bits per clock per
> >    lane value. An array of 64-bit unsigned integers.
> > +- lane-polarities: an array of polarities of the lanes starting from the clock
> > +  lane and followed by the data lanes in the same order as in data-lanes.
> > +  Valid values are 0 (normal) and 1 (inverted). The length of the array
> > +  should be the combined length of data-lanes and clock-lanes properties.
> > +  If the lane-polarities property is omitted, the value must be interpreted
> > +  as 0 (normal). This property is valid for serial busses only.
> >  
> 
> I am interested in this functionality.
> But I do have the following question.
> If the lane-polarities property is not specified, shouldn't the
> relevant struct member (bus->lane_polarities[i]) be set to 0?

This is done in the caller function; endpoint->bus is zeroed in
v4l2_of_parse_endpoint(). I believe reading rest of the properties relies on
the same.

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 12/15] dt: bindings: Add lane-polarity property to endpoint nodes
  2015-04-24 19:49     ` Sakari Ailus
@ 2015-04-24 19:53         ` Benoit Parrot
  0 siblings, 0 replies; 27+ messages in thread
From: Benoit Parrot @ 2015-04-24 19:53 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, linux-omap, tony, sre, pali.rohar, laurent.pinchart

Sakari Ailus <sakari.ailus@iki.fi> wrote on Fri [2015-Apr-24 22:49:33 +0300]:
> Hi Benoit,
> 
> On Fri, Apr 24, 2015 at 02:41:00PM -0500, Benoit Parrot wrote:
> > Sakari Ailus <sakari.ailus@iki.fi> wrote on Thu [2015-Mar-26 00:57:36 +0200]:
> > > Add lane-polarity property to endpoint nodes. This essentially tells that
> > > the order of the differential signal wires is inverted.
> > > 
> > > Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
> > > Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > ---
> > >  Documentation/devicetree/bindings/media/video-interfaces.txt |    6 ++++++
> > >  1 file changed, 6 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt
> > > index 571b4c6..9cd2a36 100644
> > > --- a/Documentation/devicetree/bindings/media/video-interfaces.txt
> > > +++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
> > > @@ -106,6 +106,12 @@ Optional endpoint properties
> > >  - link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for
> > >    instance, this is the actual frequency of the bus, not bits per clock per
> > >    lane value. An array of 64-bit unsigned integers.
> > > +- lane-polarities: an array of polarities of the lanes starting from the clock
> > > +  lane and followed by the data lanes in the same order as in data-lanes.
> > > +  Valid values are 0 (normal) and 1 (inverted). The length of the array
> > > +  should be the combined length of data-lanes and clock-lanes properties.
> > > +  If the lane-polarities property is omitted, the value must be interpreted
> > > +  as 0 (normal). This property is valid for serial busses only.
> > >  
> > 
> > I am interested in this functionality.
> > But I do have the following question.
> > If the lane-polarities property is not specified, shouldn't the
> > relevant struct member (bus->lane_polarities[i]) be set to 0?
> 
> This is done in the caller function; endpoint->bus is zeroed in
> v4l2_of_parse_endpoint(). I believe reading rest of the properties relies on
> the same.

Dang, missed that.
Sorry for the noise.

> 
> -- 
> Kind regards,
> 
> Sakari Ailus
> e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v2 12/15] dt: bindings: Add lane-polarity property to endpoint nodes
@ 2015-04-24 19:53         ` Benoit Parrot
  0 siblings, 0 replies; 27+ messages in thread
From: Benoit Parrot @ 2015-04-24 19:53 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, linux-omap, tony, sre, pali.rohar, laurent.pinchart

Sakari Ailus <sakari.ailus@iki.fi> wrote on Fri [2015-Apr-24 22:49:33 +0300]:
> Hi Benoit,
> 
> On Fri, Apr 24, 2015 at 02:41:00PM -0500, Benoit Parrot wrote:
> > Sakari Ailus <sakari.ailus@iki.fi> wrote on Thu [2015-Mar-26 00:57:36 +0200]:
> > > Add lane-polarity property to endpoint nodes. This essentially tells that
> > > the order of the differential signal wires is inverted.
> > > 
> > > Signed-off-by: Sakari Ailus <sakari.ailus@iki.fi>
> > > Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > ---
> > >  Documentation/devicetree/bindings/media/video-interfaces.txt |    6 ++++++
> > >  1 file changed, 6 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/media/video-interfaces.txt b/Documentation/devicetree/bindings/media/video-interfaces.txt
> > > index 571b4c6..9cd2a36 100644
> > > --- a/Documentation/devicetree/bindings/media/video-interfaces.txt
> > > +++ b/Documentation/devicetree/bindings/media/video-interfaces.txt
> > > @@ -106,6 +106,12 @@ Optional endpoint properties
> > >  - link-frequencies: Allowed data bus frequencies. For MIPI CSI-2, for
> > >    instance, this is the actual frequency of the bus, not bits per clock per
> > >    lane value. An array of 64-bit unsigned integers.
> > > +- lane-polarities: an array of polarities of the lanes starting from the clock
> > > +  lane and followed by the data lanes in the same order as in data-lanes.
> > > +  Valid values are 0 (normal) and 1 (inverted). The length of the array
> > > +  should be the combined length of data-lanes and clock-lanes properties.
> > > +  If the lane-polarities property is omitted, the value must be interpreted
> > > +  as 0 (normal). This property is valid for serial busses only.
> > >  
> > 
> > I am interested in this functionality.
> > But I do have the following question.
> > If the lane-polarities property is not specified, shouldn't the
> > relevant struct member (bus->lane_polarities[i]) be set to 0?
> 
> This is done in the caller function; endpoint->bus is zeroed in
> v4l2_of_parse_endpoint(). I believe reading rest of the properties relies on
> the same.

Dang, missed that.
Sorry for the noise.

> 
> -- 
> Kind regards,
> 
> Sakari Ailus
> e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2015-04-24 19:53 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-25 22:57 [PATCH v2 00/15] omap3isp driver DT support Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 01/15] omap3isp: Fix error handling in probe Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 02/15] omap3isp: Avoid a BUG_ON() in media_entity_create_link() Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 03/15] omap3isp: Separate external link creation from platform data parsing Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 04/15] omap3isp: DT support for clocks Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 05/15] omap3isp: Platform data could be NULL Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 06/15] omap3isp: Refactor device configuration structs for Device Tree Sakari Ailus
2015-03-25 23:21   ` Tony Lindgren
2015-03-25 22:57 ` [PATCH v2 07/15] omap3isp: Rename regulators to better suit the " Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 08/15] omap3isp: Calculate vpclk_div for CSI-2 Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 09/15] omap3isp: Replace mmio_base_phys array with the histogram block base Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 10/15] omap3isp: Move the syscon register out of the ISP register maps Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 11/15] omap3isp: Replace many MMIO regions by two Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 12/15] dt: bindings: Add lane-polarity property to endpoint nodes Sakari Ailus
2015-04-24 19:41   ` Benoit Parrot
2015-04-24 19:41     ` Benoit Parrot
2015-04-24 19:49     ` Sakari Ailus
2015-04-24 19:53       ` Benoit Parrot
2015-04-24 19:53         ` Benoit Parrot
2015-03-25 22:57 ` [PATCH v2 13/15] v4l: of: Read lane-polarities endpoint property Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 14/15] omap3isp: Add support for the Device Tree Sakari Ailus
2015-03-30 17:41   ` Sebastian Reichel
2015-03-30 21:17     ` Sakari Ailus
2015-03-30 23:13     ` [PATCH 1/1] omap3isp: Don't pass uninitialised arguments to of_graph_get_next_endpoint() Sakari Ailus
2015-03-31  1:37       ` Sebastian Reichel
2015-04-01 22:41         ` Sakari Ailus
2015-03-25 22:57 ` [PATCH v2 15/15] omap3isp: Deprecate platform data support Sakari Ailus

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.