| .. | .. |
|---|
| 185 | 185 | /* OF graph endpoint's V4L2 async data */ |
|---|
| 186 | 186 | struct rcar_drif_graph_ep { |
|---|
| 187 | 187 | struct v4l2_subdev *subdev; /* Async matched subdev */ |
|---|
| 188 | | - struct v4l2_async_subdev asd; /* Async sub-device descriptor */ |
|---|
| 189 | 188 | }; |
|---|
| 190 | 189 | |
|---|
| 191 | 190 | /* DMA buffer */ |
|---|
| .. | .. |
|---|
| 275 | 274 | for_each_rcar_drif_channel(i, &sdr->cur_ch_mask) { |
|---|
| 276 | 275 | struct rcar_drif *ch = sdr->ch[i]; |
|---|
| 277 | 276 | |
|---|
| 278 | | - ch->dmach = dma_request_slave_channel(&ch->pdev->dev, "rx"); |
|---|
| 279 | | - if (!ch->dmach) { |
|---|
| 280 | | - rdrif_err(sdr, "ch%u: dma channel req failed\n", i); |
|---|
| 281 | | - ret = -ENODEV; |
|---|
| 277 | + ch->dmach = dma_request_chan(&ch->pdev->dev, "rx"); |
|---|
| 278 | + if (IS_ERR(ch->dmach)) { |
|---|
| 279 | + ret = PTR_ERR(ch->dmach); |
|---|
| 280 | + if (ret != -EPROBE_DEFER) |
|---|
| 281 | + rdrif_err(sdr, |
|---|
| 282 | + "ch%u: dma channel req failed: %pe\n", |
|---|
| 283 | + i, ch->dmach); |
|---|
| 284 | + ch->dmach = NULL; |
|---|
| 282 | 285 | goto dmach_error; |
|---|
| 283 | 286 | } |
|---|
| 284 | 287 | |
|---|
| .. | .. |
|---|
| 870 | 873 | { |
|---|
| 871 | 874 | struct rcar_drif_sdr *sdr = video_drvdata(file); |
|---|
| 872 | 875 | |
|---|
| 873 | | - strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); |
|---|
| 874 | | - strlcpy(cap->card, sdr->vdev->name, sizeof(cap->card)); |
|---|
| 876 | + strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); |
|---|
| 877 | + strscpy(cap->card, sdr->vdev->name, sizeof(cap->card)); |
|---|
| 875 | 878 | snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", |
|---|
| 876 | 879 | sdr->vdev->name); |
|---|
| 877 | 880 | |
|---|
| .. | .. |
|---|
| 1104 | 1107 | struct rcar_drif_sdr *sdr = |
|---|
| 1105 | 1108 | container_of(notifier, struct rcar_drif_sdr, notifier); |
|---|
| 1106 | 1109 | |
|---|
| 1107 | | - if (sdr->ep.asd.match.fwnode != |
|---|
| 1108 | | - of_fwnode_handle(subdev->dev->of_node)) { |
|---|
| 1109 | | - rdrif_err(sdr, "subdev %s cannot bind\n", subdev->name); |
|---|
| 1110 | | - return -EINVAL; |
|---|
| 1111 | | - } |
|---|
| 1112 | | - |
|---|
| 1113 | 1110 | v4l2_set_subdev_hostdata(subdev, sdr); |
|---|
| 1114 | 1111 | sdr->ep.subdev = subdev; |
|---|
| 1115 | 1112 | rdrif_dbg(sdr, "bound asd %s\n", subdev->name); |
|---|
| .. | .. |
|---|
| 1164 | 1161 | } |
|---|
| 1165 | 1162 | |
|---|
| 1166 | 1163 | ret = v4l2_ctrl_add_handler(&sdr->ctrl_hdl, |
|---|
| 1167 | | - sdr->ep.subdev->ctrl_handler, NULL); |
|---|
| 1164 | + sdr->ep.subdev->ctrl_handler, NULL, true); |
|---|
| 1168 | 1165 | if (ret) { |
|---|
| 1169 | 1166 | rdrif_err(sdr, "failed: ctrl add hdlr ret %d\n", ret); |
|---|
| 1170 | 1167 | goto error; |
|---|
| .. | .. |
|---|
| 1213 | 1210 | { |
|---|
| 1214 | 1211 | struct v4l2_async_notifier *notifier = &sdr->notifier; |
|---|
| 1215 | 1212 | struct fwnode_handle *fwnode, *ep; |
|---|
| 1213 | + struct v4l2_async_subdev *asd; |
|---|
| 1216 | 1214 | |
|---|
| 1217 | | - notifier->subdevs = devm_kzalloc(sdr->dev, sizeof(*notifier->subdevs), |
|---|
| 1218 | | - GFP_KERNEL); |
|---|
| 1219 | | - if (!notifier->subdevs) |
|---|
| 1220 | | - return -ENOMEM; |
|---|
| 1215 | + v4l2_async_notifier_init(notifier); |
|---|
| 1221 | 1216 | |
|---|
| 1222 | 1217 | ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(sdr->dev->of_node), |
|---|
| 1223 | 1218 | NULL); |
|---|
| 1224 | 1219 | if (!ep) |
|---|
| 1225 | 1220 | return 0; |
|---|
| 1226 | 1221 | |
|---|
| 1227 | | - notifier->subdevs[notifier->num_subdevs] = &sdr->ep.asd; |
|---|
| 1228 | | - fwnode = fwnode_graph_get_remote_port_parent(ep); |
|---|
| 1229 | | - if (!fwnode) { |
|---|
| 1230 | | - dev_warn(sdr->dev, "bad remote port parent\n"); |
|---|
| 1231 | | - fwnode_handle_put(ep); |
|---|
| 1232 | | - return -EINVAL; |
|---|
| 1233 | | - } |
|---|
| 1234 | | - |
|---|
| 1235 | | - sdr->ep.asd.match.fwnode = fwnode; |
|---|
| 1236 | | - sdr->ep.asd.match_type = V4L2_ASYNC_MATCH_FWNODE; |
|---|
| 1237 | | - notifier->num_subdevs++; |
|---|
| 1238 | | - |
|---|
| 1239 | 1222 | /* Get the endpoint properties */ |
|---|
| 1240 | 1223 | rcar_drif_get_ep_properties(sdr, ep); |
|---|
| 1241 | 1224 | |
|---|
| 1242 | | - fwnode_handle_put(fwnode); |
|---|
| 1225 | + fwnode = fwnode_graph_get_remote_port_parent(ep); |
|---|
| 1243 | 1226 | fwnode_handle_put(ep); |
|---|
| 1227 | + if (!fwnode) { |
|---|
| 1228 | + dev_warn(sdr->dev, "bad remote port parent\n"); |
|---|
| 1229 | + return -EINVAL; |
|---|
| 1230 | + } |
|---|
| 1231 | + |
|---|
| 1232 | + asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, |
|---|
| 1233 | + sizeof(*asd)); |
|---|
| 1234 | + fwnode_handle_put(fwnode); |
|---|
| 1235 | + if (IS_ERR(asd)) |
|---|
| 1236 | + return PTR_ERR(asd); |
|---|
| 1244 | 1237 | |
|---|
| 1245 | 1238 | return 0; |
|---|
| 1246 | 1239 | } |
|---|
| .. | .. |
|---|
| 1356 | 1349 | ret = v4l2_async_notifier_register(&sdr->v4l2_dev, &sdr->notifier); |
|---|
| 1357 | 1350 | if (ret < 0) { |
|---|
| 1358 | 1351 | dev_err(sdr->dev, "failed: notifier register ret %d\n", ret); |
|---|
| 1359 | | - goto error; |
|---|
| 1352 | + goto cleanup; |
|---|
| 1360 | 1353 | } |
|---|
| 1361 | 1354 | |
|---|
| 1362 | 1355 | return ret; |
|---|
| 1363 | 1356 | |
|---|
| 1357 | +cleanup: |
|---|
| 1358 | + v4l2_async_notifier_cleanup(&sdr->notifier); |
|---|
| 1364 | 1359 | error: |
|---|
| 1365 | 1360 | v4l2_device_unregister(&sdr->v4l2_dev); |
|---|
| 1366 | 1361 | |
|---|
| .. | .. |
|---|
| 1371 | 1366 | static void rcar_drif_sdr_remove(struct rcar_drif_sdr *sdr) |
|---|
| 1372 | 1367 | { |
|---|
| 1373 | 1368 | v4l2_async_notifier_unregister(&sdr->notifier); |
|---|
| 1369 | + v4l2_async_notifier_cleanup(&sdr->notifier); |
|---|
| 1374 | 1370 | v4l2_device_unregister(&sdr->v4l2_dev); |
|---|
| 1375 | 1371 | } |
|---|
| 1376 | 1372 | |
|---|
| .. | .. |
|---|
| 1401 | 1397 | /* Register map */ |
|---|
| 1402 | 1398 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 1403 | 1399 | ch->base = devm_ioremap_resource(&pdev->dev, res); |
|---|
| 1404 | | - if (IS_ERR(ch->base)) { |
|---|
| 1405 | | - ret = PTR_ERR(ch->base); |
|---|
| 1406 | | - dev_err(&pdev->dev, "ioremap failed (%d)\n", ret); |
|---|
| 1407 | | - return ret; |
|---|
| 1408 | | - } |
|---|
| 1400 | + if (IS_ERR(ch->base)) |
|---|
| 1401 | + return PTR_ERR(ch->base); |
|---|
| 1402 | + |
|---|
| 1409 | 1403 | ch->start = res->start; |
|---|
| 1410 | 1404 | platform_set_drvdata(pdev, ch); |
|---|
| 1411 | 1405 | |
|---|