Skip to content

Commit dee747f

Browse files
slongerbeammchehab
authored andcommitted
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: e130291 ("[media] media: Add i.MX media core driver") Signed-off-by: Steve Longerbeam <[email protected]> Reviewed-by: Philipp Zabel <[email protected]> Cc: [email protected] Signed-off-by: Hans Verkuil <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 085b26d commit dee747f

File tree

5 files changed

+46
-46
lines changed

5 files changed

+46
-46
lines changed

drivers/staging/media/imx/imx-media-dev.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -477,13 +477,6 @@ static int imx_media_probe(struct platform_device *pdev)
477477
goto cleanup;
478478
}
479479

480-
ret = imx_media_add_ipu_internal_subdevs(imxmd);
481-
if (ret) {
482-
v4l2_err(&imxmd->v4l2_dev,
483-
"add_ipu_internal_subdevs failed with %d\n", ret);
484-
goto cleanup;
485-
}
486-
487480
ret = imx_media_dev_notifier_register(imxmd);
488481
if (ret)
489482
goto del_int;

drivers/staging/media/imx/imx-media-internal-sd.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -298,13 +298,14 @@ static int add_internal_subdev(struct imx_media_dev *imxmd,
298298
}
299299

300300
/* adds the internal subdevs in one ipu */
301-
static int add_ipu_internal_subdevs(struct imx_media_dev *imxmd, int ipu_id)
301+
int imx_media_add_ipu_internal_subdevs(struct imx_media_dev *imxmd,
302+
int ipu_id)
302303
{
303304
enum isd_enum i;
305+
int ret;
304306

305307
for (i = 0; i < num_isd; i++) {
306308
const struct internal_subdev *isd = &int_subdev[i];
307-
int ret;
308309

309310
/*
310311
* 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)
322323
}
323324

324325
if (ret)
325-
return ret;
326+
goto remove;
326327
}
327328

328329
return 0;
329-
}
330-
331-
int imx_media_add_ipu_internal_subdevs(struct imx_media_dev *imxmd)
332-
{
333-
int ret;
334-
335-
ret = add_ipu_internal_subdevs(imxmd, 0);
336-
if (ret)
337-
goto remove;
338-
339-
ret = add_ipu_internal_subdevs(imxmd, 1);
340-
if (ret)
341-
goto remove;
342-
343-
return 0;
344330

345331
remove:
346332
imx_media_remove_ipu_internal_subdevs(imxmd);

drivers/staging/media/imx/imx-media-of.c

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,49 +23,69 @@
2323
int imx_media_of_add_csi(struct imx_media_dev *imxmd,
2424
struct device_node *csi_np)
2525
{
26-
int ret;
27-
2826
if (!of_device_is_available(csi_np)) {
2927
dev_dbg(imxmd->md.dev, "%s: %pOFn not enabled\n", __func__,
3028
csi_np);
31-
/* unavailable is not an error */
32-
return 0;
29+
return -ENODEV;
3330
}
3431

3532
/* add CSI fwnode to async notifier */
36-
ret = imx_media_add_async_subdev(imxmd, of_fwnode_handle(csi_np), NULL);
37-
if (ret) {
38-
if (ret == -EEXIST) {
39-
/* already added, everything is fine */
40-
return 0;
41-
}
42-
43-
/* other error, can't continue */
44-
return ret;
45-
}
46-
47-
return 0;
33+
return imx_media_add_async_subdev(imxmd, of_fwnode_handle(csi_np),
34+
NULL);
4835
}
4936
EXPORT_SYMBOL_GPL(imx_media_of_add_csi);
5037

5138
int imx_media_add_of_subdevs(struct imx_media_dev *imxmd,
5239
struct device_node *np)
5340
{
41+
bool ipu_found[2] = {false, false};
5442
struct device_node *csi_np;
5543
int i, ret;
44+
u32 ipu_id;
5645

5746
for (i = 0; ; i++) {
5847
csi_np = of_parse_phandle(np, "ports", i);
5948
if (!csi_np)
6049
break;
6150

6251
ret = imx_media_of_add_csi(imxmd, csi_np);
63-
of_node_put(csi_np);
64-
if (ret)
65-
return ret;
52+
if (ret) {
53+
/* unavailable or already added is not an error */
54+
if (ret == -ENODEV || ret == -EEXIST) {
55+
of_node_put(csi_np);
56+
continue;
57+
}
58+
59+
/* other error, can't continue */
60+
goto err_out;
61+
}
62+
63+
ret = of_alias_get_id(csi_np->parent, "ipu");
64+
if (ret < 0)
65+
goto err_out;
66+
if (ret > 1) {
67+
ret = -EINVAL;
68+
goto err_out;
69+
}
70+
71+
ipu_id = ret;
72+
73+
if (!ipu_found[ipu_id]) {
74+
ret = imx_media_add_ipu_internal_subdevs(imxmd,
75+
ipu_id);
76+
if (ret)
77+
goto err_out;
78+
}
79+
80+
ipu_found[ipu_id] = true;
6681
}
6782

6883
return 0;
84+
85+
err_out:
86+
imx_media_remove_ipu_internal_subdevs(imxmd);
87+
of_node_put(csi_np);
88+
return ret;
6989
}
7090

7191
/*

drivers/staging/media/imx/imx-media.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd);
252252
void imx_media_fim_free(struct imx_media_fim *fim);
253253

254254
/* imx-media-internal-sd.c */
255-
int imx_media_add_ipu_internal_subdevs(struct imx_media_dev *imxmd);
255+
int imx_media_add_ipu_internal_subdevs(struct imx_media_dev *imxmd,
256+
int ipu_id);
256257
int imx_media_create_ipu_internal_links(struct imx_media_dev *imxmd,
257258
struct v4l2_subdev *sd);
258259
void imx_media_remove_ipu_internal_subdevs(struct imx_media_dev *imxmd);

drivers/staging/media/imx/imx7-media-csi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1271,7 +1271,7 @@ static int imx7_csi_probe(struct platform_device *pdev)
12711271
platform_set_drvdata(pdev, &csi->sd);
12721272

12731273
ret = imx_media_of_add_csi(imxmd, node);
1274-
if (ret < 0)
1274+
if (ret < 0 && ret != -ENODEV && ret != -EEXIST)
12751275
goto cleanup;
12761276

12771277
ret = imx_media_dev_notifier_register(imxmd);

0 commit comments

Comments
 (0)