summaryrefslogtreecommitdiffstats
path: root/drivers/staging/media
diff options
context:
space:
mode:
authorSteve Longerbeam2019-02-21 00:53:32 +0100
committerMauro Carvalho Chehab2019-03-19 18:42:52 +0100
commitdee747f88167124884a918855c1f438e2f7f39e2 (patch)
treef57997c6b36119ebbdb8bc5a4c9d44626a1f9fb1 /drivers/staging/media
parentmedia: imx: Rename functions that add IPU-internal subdevs (diff)
downloadkernel-qcow2-linux-dee747f88167124884a918855c1f438e2f7f39e2.tar.gz
kernel-qcow2-linux-dee747f88167124884a918855c1f438e2f7f39e2.tar.xz
kernel-qcow2-linux-dee747f88167124884a918855c1f438e2f7f39e2.zip
media: imx: Don't register IPU subdevs/links if CSI port missing
The second IPU internal sub-devices were being registered and links to them created even when the second IPU is not present. This is wrong for i.MX6 S/DL and i.MX53 which have only a single IPU. Fixes: e130291212df5 ("[media] media: Add i.MX media core driver") Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Cc: stable@vger.kernel.org Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/staging/media')
-rw-r--r--drivers/staging/media/imx/imx-media-dev.c7
-rw-r--r--drivers/staging/media/imx/imx-media-internal-sd.c22
-rw-r--r--drivers/staging/media/imx/imx-media-of.c58
-rw-r--r--drivers/staging/media/imx/imx-media.h3
-rw-r--r--drivers/staging/media/imx/imx7-media-csi.c2
5 files changed, 46 insertions, 46 deletions
diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
index fc35508d9396..10a63a4fa90b 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -477,13 +477,6 @@ static int imx_media_probe(struct platform_device *pdev)
goto cleanup;
}
- ret = imx_media_add_ipu_internal_subdevs(imxmd);
- if (ret) {
- v4l2_err(&imxmd->v4l2_dev,
- "add_ipu_internal_subdevs failed with %d\n", ret);
- goto cleanup;
- }
-
ret = imx_media_dev_notifier_register(imxmd);
if (ret)
goto del_int;
diff --git a/drivers/staging/media/imx/imx-media-internal-sd.c b/drivers/staging/media/imx/imx-media-internal-sd.c
index e620f4adb755..dc510dcfe160 100644
--- a/drivers/staging/media/imx/imx-media-internal-sd.c
+++ b/drivers/staging/media/imx/imx-media-internal-sd.c
@@ -298,13 +298,14 @@ static int add_internal_subdev(struct imx_media_dev *imxmd,
}
/* adds the internal subdevs in one ipu */
-static int add_ipu_internal_subdevs(struct imx_media_dev *imxmd, int ipu_id)
+int imx_media_add_ipu_internal_subdevs(struct imx_media_dev *imxmd,
+ int ipu_id)
{
enum isd_enum i;
+ int ret;
for (i = 0; i < num_isd; i++) {
const struct internal_subdev *isd = &int_subdev[i];
- int ret;
/*
* the CSIs are represented in the device-tree, so those
@@ -322,25 +323,10 @@ static int add_ipu_internal_subdevs(struct imx_media_dev *imxmd, int ipu_id)
}
if (ret)
- return ret;
+ goto remove;
}
return 0;
-}
-
-int imx_media_add_ipu_internal_subdevs(struct imx_media_dev *imxmd)
-{
- int ret;
-
- ret = add_ipu_internal_subdevs(imxmd, 0);
- if (ret)
- goto remove;
-
- ret = add_ipu_internal_subdevs(imxmd, 1);
- if (ret)
- goto remove;
-
- return 0;
remove:
imx_media_remove_ipu_internal_subdevs(imxmd);
diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
index a26bdeb1af34..12383f4785ad 100644
--- a/drivers/staging/media/imx/imx-media-of.c
+++ b/drivers/staging/media/imx/imx-media-of.c
@@ -23,36 +23,25 @@
int imx_media_of_add_csi(struct imx_media_dev *imxmd,
struct device_node *csi_np)
{
- int ret;
-
if (!of_device_is_available(csi_np)) {
dev_dbg(imxmd->md.dev, "%s: %pOFn not enabled\n", __func__,
csi_np);
- /* unavailable is not an error */
- return 0;
+ return -ENODEV;
}
/* add CSI fwnode to async notifier */
- ret = imx_media_add_async_subdev(imxmd, of_fwnode_handle(csi_np), NULL);
- if (ret) {
- if (ret == -EEXIST) {
- /* already added, everything is fine */
- return 0;
- }
-
- /* other error, can't continue */
- return ret;
- }
-
- return 0;
+ return imx_media_add_async_subdev(imxmd, of_fwnode_handle(csi_np),
+ NULL);
}
EXPORT_SYMBOL_GPL(imx_media_of_add_csi);
int imx_media_add_of_subdevs(struct imx_media_dev *imxmd,
struct device_node *np)
{
+ bool ipu_found[2] = {false, false};
struct device_node *csi_np;
int i, ret;
+ u32 ipu_id;
for (i = 0; ; i++) {
csi_np = of_parse_phandle(np, "ports", i);
@@ -60,12 +49,43 @@ int imx_media_add_of_subdevs(struct imx_media_dev *imxmd,
break;
ret = imx_media_of_add_csi(imxmd, csi_np);
- of_node_put(csi_np);
- if (ret)
- return ret;
+ if (ret) {
+ /* unavailable or already added is not an error */
+ if (ret == -ENODEV || ret == -EEXIST) {
+ of_node_put(csi_np);
+ continue;
+ }
+
+ /* other error, can't continue */
+ goto err_out;
+ }
+
+ ret = of_alias_get_id(csi_np->parent, "ipu");
+ if (ret < 0)
+ goto err_out;
+ if (ret > 1) {
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ ipu_id = ret;
+
+ if (!ipu_found[ipu_id]) {
+ ret = imx_media_add_ipu_internal_subdevs(imxmd,
+ ipu_id);
+ if (ret)
+ goto err_out;
+ }
+
+ ipu_found[ipu_id] = true;
}
return 0;
+
+err_out:
+ imx_media_remove_ipu_internal_subdevs(imxmd);
+ of_node_put(csi_np);
+ return ret;
}
/*
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index ccbfc4438c85..dd603a6b3a70 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -252,7 +252,8 @@ struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd);
void imx_media_fim_free(struct imx_media_fim *fim);
/* imx-media-internal-sd.c */
-int imx_media_add_ipu_internal_subdevs(struct imx_media_dev *imxmd);
+int imx_media_add_ipu_internal_subdevs(struct imx_media_dev *imxmd,
+ int ipu_id);
int imx_media_create_ipu_internal_links(struct imx_media_dev *imxmd,
struct v4l2_subdev *sd);
void imx_media_remove_ipu_internal_subdevs(struct imx_media_dev *imxmd);
diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c
index 3fba7c27c0ec..1ba62fcdcae8 100644
--- a/drivers/staging/media/imx/imx7-media-csi.c
+++ b/drivers/staging/media/imx/imx7-media-csi.c
@@ -1271,7 +1271,7 @@ static int imx7_csi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &csi->sd);
ret = imx_media_of_add_csi(imxmd, node);
- if (ret < 0)
+ if (ret < 0 && ret != -ENODEV && ret != -EEXIST)
goto cleanup;
ret = imx_media_dev_notifier_register(imxmd);