| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Xilinx Video IP Composite Device |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Contacts: Hyun Kwon <hyun.kwon@xilinx.com> |
|---|
| 8 | 9 | * Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 11 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 12 | | - * published by the Free Software Foundation. |
|---|
| 13 | 10 | */ |
|---|
| 14 | 11 | |
|---|
| 15 | 12 | #include <linux/list.h> |
|---|
| .. | .. |
|---|
| 32 | 29 | |
|---|
| 33 | 30 | /** |
|---|
| 34 | 31 | * struct xvip_graph_entity - Entity in the video graph |
|---|
| 35 | | - * @list: list entry in a graph entities list |
|---|
| 36 | | - * @node: the entity's DT node |
|---|
| 37 | | - * @entity: media entity, from the corresponding V4L2 subdev |
|---|
| 38 | 32 | * @asd: subdev asynchronous registration information |
|---|
| 33 | + * @entity: media entity, from the corresponding V4L2 subdev |
|---|
| 39 | 34 | * @subdev: V4L2 subdev |
|---|
| 40 | 35 | */ |
|---|
| 41 | 36 | struct xvip_graph_entity { |
|---|
| 42 | | - struct list_head list; |
|---|
| 43 | | - struct device_node *node; |
|---|
| 37 | + struct v4l2_async_subdev asd; /* must be first */ |
|---|
| 44 | 38 | struct media_entity *entity; |
|---|
| 45 | | - |
|---|
| 46 | | - struct v4l2_async_subdev asd; |
|---|
| 47 | 39 | struct v4l2_subdev *subdev; |
|---|
| 48 | 40 | }; |
|---|
| 41 | + |
|---|
| 42 | +static inline struct xvip_graph_entity * |
|---|
| 43 | +to_xvip_entity(struct v4l2_async_subdev *asd) |
|---|
| 44 | +{ |
|---|
| 45 | + return container_of(asd, struct xvip_graph_entity, asd); |
|---|
| 46 | +} |
|---|
| 49 | 47 | |
|---|
| 50 | 48 | /* ----------------------------------------------------------------------------- |
|---|
| 51 | 49 | * Graph Management |
|---|
| .. | .. |
|---|
| 53 | 51 | |
|---|
| 54 | 52 | static struct xvip_graph_entity * |
|---|
| 55 | 53 | xvip_graph_find_entity(struct xvip_composite_device *xdev, |
|---|
| 56 | | - const struct device_node *node) |
|---|
| 54 | + const struct fwnode_handle *fwnode) |
|---|
| 57 | 55 | { |
|---|
| 58 | 56 | struct xvip_graph_entity *entity; |
|---|
| 57 | + struct v4l2_async_subdev *asd; |
|---|
| 59 | 58 | |
|---|
| 60 | | - list_for_each_entry(entity, &xdev->entities, list) { |
|---|
| 61 | | - if (entity->node == node) |
|---|
| 59 | + list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { |
|---|
| 60 | + entity = to_xvip_entity(asd); |
|---|
| 61 | + if (entity->asd.match.fwnode == fwnode) |
|---|
| 62 | 62 | return entity; |
|---|
| 63 | 63 | } |
|---|
| 64 | 64 | |
|---|
| .. | .. |
|---|
| 75 | 75 | struct media_pad *remote_pad; |
|---|
| 76 | 76 | struct xvip_graph_entity *ent; |
|---|
| 77 | 77 | struct v4l2_fwnode_link link; |
|---|
| 78 | | - struct device_node *ep = NULL; |
|---|
| 78 | + struct fwnode_handle *ep = NULL; |
|---|
| 79 | 79 | int ret = 0; |
|---|
| 80 | 80 | |
|---|
| 81 | 81 | dev_dbg(xdev->dev, "creating links for entity %s\n", local->name); |
|---|
| 82 | 82 | |
|---|
| 83 | 83 | while (1) { |
|---|
| 84 | 84 | /* Get the next endpoint and parse its link. */ |
|---|
| 85 | | - ep = of_graph_get_next_endpoint(entity->node, ep); |
|---|
| 85 | + ep = fwnode_graph_get_next_endpoint(entity->asd.match.fwnode, |
|---|
| 86 | + ep); |
|---|
| 86 | 87 | if (ep == NULL) |
|---|
| 87 | 88 | break; |
|---|
| 88 | 89 | |
|---|
| 89 | | - dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep); |
|---|
| 90 | + dev_dbg(xdev->dev, "processing endpoint %p\n", ep); |
|---|
| 90 | 91 | |
|---|
| 91 | | - ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link); |
|---|
| 92 | + ret = v4l2_fwnode_parse_link(ep, &link); |
|---|
| 92 | 93 | if (ret < 0) { |
|---|
| 93 | | - dev_err(xdev->dev, "failed to parse link for %pOF\n", |
|---|
| 94 | + dev_err(xdev->dev, "failed to parse link for %p\n", |
|---|
| 94 | 95 | ep); |
|---|
| 95 | 96 | continue; |
|---|
| 96 | 97 | } |
|---|
| .. | .. |
|---|
| 99 | 100 | * the link. |
|---|
| 100 | 101 | */ |
|---|
| 101 | 102 | if (link.local_port >= local->num_pads) { |
|---|
| 102 | | - dev_err(xdev->dev, "invalid port number %u for %pOF\n", |
|---|
| 103 | | - link.local_port, |
|---|
| 104 | | - to_of_node(link.local_node)); |
|---|
| 103 | + dev_err(xdev->dev, "invalid port number %u for %p\n", |
|---|
| 104 | + link.local_port, link.local_node); |
|---|
| 105 | 105 | v4l2_fwnode_put_link(&link); |
|---|
| 106 | 106 | ret = -EINVAL; |
|---|
| 107 | 107 | break; |
|---|
| .. | .. |
|---|
| 110 | 110 | local_pad = &local->pads[link.local_port]; |
|---|
| 111 | 111 | |
|---|
| 112 | 112 | if (local_pad->flags & MEDIA_PAD_FL_SINK) { |
|---|
| 113 | | - dev_dbg(xdev->dev, "skipping sink port %pOF:%u\n", |
|---|
| 114 | | - to_of_node(link.local_node), |
|---|
| 115 | | - link.local_port); |
|---|
| 113 | + dev_dbg(xdev->dev, "skipping sink port %p:%u\n", |
|---|
| 114 | + link.local_node, link.local_port); |
|---|
| 116 | 115 | v4l2_fwnode_put_link(&link); |
|---|
| 117 | 116 | continue; |
|---|
| 118 | 117 | } |
|---|
| 119 | 118 | |
|---|
| 120 | 119 | /* Skip DMA engines, they will be processed separately. */ |
|---|
| 121 | 120 | if (link.remote_node == of_fwnode_handle(xdev->dev->of_node)) { |
|---|
| 122 | | - dev_dbg(xdev->dev, "skipping DMA port %pOF:%u\n", |
|---|
| 123 | | - to_of_node(link.local_node), |
|---|
| 124 | | - link.local_port); |
|---|
| 121 | + dev_dbg(xdev->dev, "skipping DMA port %p:%u\n", |
|---|
| 122 | + link.local_node, link.local_port); |
|---|
| 125 | 123 | v4l2_fwnode_put_link(&link); |
|---|
| 126 | 124 | continue; |
|---|
| 127 | 125 | } |
|---|
| 128 | 126 | |
|---|
| 129 | 127 | /* Find the remote entity. */ |
|---|
| 130 | | - ent = xvip_graph_find_entity(xdev, |
|---|
| 131 | | - to_of_node(link.remote_node)); |
|---|
| 128 | + ent = xvip_graph_find_entity(xdev, link.remote_node); |
|---|
| 132 | 129 | if (ent == NULL) { |
|---|
| 133 | | - dev_err(xdev->dev, "no entity found for %pOF\n", |
|---|
| 134 | | - to_of_node(link.remote_node)); |
|---|
| 130 | + dev_err(xdev->dev, "no entity found for %p\n", |
|---|
| 131 | + link.remote_node); |
|---|
| 135 | 132 | v4l2_fwnode_put_link(&link); |
|---|
| 136 | 133 | ret = -ENODEV; |
|---|
| 137 | 134 | break; |
|---|
| .. | .. |
|---|
| 140 | 137 | remote = ent->entity; |
|---|
| 141 | 138 | |
|---|
| 142 | 139 | if (link.remote_port >= remote->num_pads) { |
|---|
| 143 | | - dev_err(xdev->dev, "invalid port number %u on %pOF\n", |
|---|
| 144 | | - link.remote_port, to_of_node(link.remote_node)); |
|---|
| 140 | + dev_err(xdev->dev, "invalid port number %u on %p\n", |
|---|
| 141 | + link.remote_port, link.remote_node); |
|---|
| 145 | 142 | v4l2_fwnode_put_link(&link); |
|---|
| 146 | 143 | ret = -EINVAL; |
|---|
| 147 | 144 | break; |
|---|
| .. | .. |
|---|
| 168 | 165 | } |
|---|
| 169 | 166 | } |
|---|
| 170 | 167 | |
|---|
| 171 | | - of_node_put(ep); |
|---|
| 168 | + fwnode_handle_put(ep); |
|---|
| 172 | 169 | return ret; |
|---|
| 173 | 170 | } |
|---|
| 174 | 171 | |
|---|
| .. | .. |
|---|
| 230 | 227 | dma->video.name); |
|---|
| 231 | 228 | |
|---|
| 232 | 229 | /* Find the remote entity. */ |
|---|
| 233 | | - ent = xvip_graph_find_entity(xdev, |
|---|
| 234 | | - to_of_node(link.remote_node)); |
|---|
| 230 | + ent = xvip_graph_find_entity(xdev, link.remote_node); |
|---|
| 235 | 231 | if (ent == NULL) { |
|---|
| 236 | 232 | dev_err(xdev->dev, "no entity found for %pOF\n", |
|---|
| 237 | 233 | to_of_node(link.remote_node)); |
|---|
| .. | .. |
|---|
| 289 | 285 | struct xvip_composite_device *xdev = |
|---|
| 290 | 286 | container_of(notifier, struct xvip_composite_device, notifier); |
|---|
| 291 | 287 | struct xvip_graph_entity *entity; |
|---|
| 288 | + struct v4l2_async_subdev *asd; |
|---|
| 292 | 289 | int ret; |
|---|
| 293 | 290 | |
|---|
| 294 | 291 | dev_dbg(xdev->dev, "notify complete, all subdevs registered\n"); |
|---|
| 295 | 292 | |
|---|
| 296 | 293 | /* Create links for every entity. */ |
|---|
| 297 | | - list_for_each_entry(entity, &xdev->entities, list) { |
|---|
| 294 | + list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { |
|---|
| 295 | + entity = to_xvip_entity(asd); |
|---|
| 298 | 296 | ret = xvip_graph_build_one(xdev, entity); |
|---|
| 299 | 297 | if (ret < 0) |
|---|
| 300 | 298 | return ret; |
|---|
| .. | .. |
|---|
| 314 | 312 | |
|---|
| 315 | 313 | static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier, |
|---|
| 316 | 314 | struct v4l2_subdev *subdev, |
|---|
| 317 | | - struct v4l2_async_subdev *asd) |
|---|
| 315 | + struct v4l2_async_subdev *unused) |
|---|
| 318 | 316 | { |
|---|
| 319 | 317 | struct xvip_composite_device *xdev = |
|---|
| 320 | 318 | container_of(notifier, struct xvip_composite_device, notifier); |
|---|
| 321 | 319 | struct xvip_graph_entity *entity; |
|---|
| 320 | + struct v4l2_async_subdev *asd; |
|---|
| 322 | 321 | |
|---|
| 323 | 322 | /* Locate the entity corresponding to the bound subdev and store the |
|---|
| 324 | 323 | * subdev pointer. |
|---|
| 325 | 324 | */ |
|---|
| 326 | | - list_for_each_entry(entity, &xdev->entities, list) { |
|---|
| 327 | | - if (entity->node != subdev->dev->of_node) |
|---|
| 325 | + list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { |
|---|
| 326 | + entity = to_xvip_entity(asd); |
|---|
| 327 | + |
|---|
| 328 | + if (entity->asd.match.fwnode != subdev->fwnode) |
|---|
| 328 | 329 | continue; |
|---|
| 329 | 330 | |
|---|
| 330 | 331 | if (entity->subdev) { |
|---|
| 331 | | - dev_err(xdev->dev, "duplicate subdev for node %pOF\n", |
|---|
| 332 | | - entity->node); |
|---|
| 332 | + dev_err(xdev->dev, "duplicate subdev for node %p\n", |
|---|
| 333 | + entity->asd.match.fwnode); |
|---|
| 333 | 334 | return -EINVAL; |
|---|
| 334 | 335 | } |
|---|
| 335 | 336 | |
|---|
| .. | .. |
|---|
| 349 | 350 | }; |
|---|
| 350 | 351 | |
|---|
| 351 | 352 | static int xvip_graph_parse_one(struct xvip_composite_device *xdev, |
|---|
| 352 | | - struct device_node *node) |
|---|
| 353 | + struct fwnode_handle *fwnode) |
|---|
| 353 | 354 | { |
|---|
| 354 | | - struct xvip_graph_entity *entity; |
|---|
| 355 | | - struct device_node *remote; |
|---|
| 356 | | - struct device_node *ep = NULL; |
|---|
| 355 | + struct fwnode_handle *remote; |
|---|
| 356 | + struct fwnode_handle *ep = NULL; |
|---|
| 357 | 357 | int ret = 0; |
|---|
| 358 | 358 | |
|---|
| 359 | | - dev_dbg(xdev->dev, "parsing node %pOF\n", node); |
|---|
| 359 | + dev_dbg(xdev->dev, "parsing node %p\n", fwnode); |
|---|
| 360 | 360 | |
|---|
| 361 | 361 | while (1) { |
|---|
| 362 | | - ep = of_graph_get_next_endpoint(node, ep); |
|---|
| 362 | + struct v4l2_async_subdev *asd; |
|---|
| 363 | + |
|---|
| 364 | + ep = fwnode_graph_get_next_endpoint(fwnode, ep); |
|---|
| 363 | 365 | if (ep == NULL) |
|---|
| 364 | 366 | break; |
|---|
| 365 | 367 | |
|---|
| 366 | | - dev_dbg(xdev->dev, "handling endpoint %pOF\n", ep); |
|---|
| 368 | + dev_dbg(xdev->dev, "handling endpoint %p\n", ep); |
|---|
| 367 | 369 | |
|---|
| 368 | | - remote = of_graph_get_remote_port_parent(ep); |
|---|
| 370 | + remote = fwnode_graph_get_remote_port_parent(ep); |
|---|
| 369 | 371 | if (remote == NULL) { |
|---|
| 370 | 372 | ret = -EINVAL; |
|---|
| 371 | | - break; |
|---|
| 373 | + goto err_notifier_cleanup; |
|---|
| 372 | 374 | } |
|---|
| 373 | 375 | |
|---|
| 376 | + fwnode_handle_put(ep); |
|---|
| 377 | + |
|---|
| 374 | 378 | /* Skip entities that we have already processed. */ |
|---|
| 375 | | - if (remote == xdev->dev->of_node || |
|---|
| 379 | + if (remote == of_fwnode_handle(xdev->dev->of_node) || |
|---|
| 376 | 380 | xvip_graph_find_entity(xdev, remote)) { |
|---|
| 377 | | - of_node_put(remote); |
|---|
| 381 | + fwnode_handle_put(remote); |
|---|
| 378 | 382 | continue; |
|---|
| 379 | 383 | } |
|---|
| 380 | 384 | |
|---|
| 381 | | - entity = devm_kzalloc(xdev->dev, sizeof(*entity), GFP_KERNEL); |
|---|
| 382 | | - if (entity == NULL) { |
|---|
| 383 | | - of_node_put(remote); |
|---|
| 384 | | - ret = -ENOMEM; |
|---|
| 385 | | - break; |
|---|
| 385 | + asd = v4l2_async_notifier_add_fwnode_subdev( |
|---|
| 386 | + &xdev->notifier, remote, |
|---|
| 387 | + sizeof(struct xvip_graph_entity)); |
|---|
| 388 | + fwnode_handle_put(remote); |
|---|
| 389 | + if (IS_ERR(asd)) { |
|---|
| 390 | + ret = PTR_ERR(asd); |
|---|
| 391 | + goto err_notifier_cleanup; |
|---|
| 386 | 392 | } |
|---|
| 387 | | - |
|---|
| 388 | | - entity->node = remote; |
|---|
| 389 | | - entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; |
|---|
| 390 | | - entity->asd.match.fwnode = of_fwnode_handle(remote); |
|---|
| 391 | | - list_add_tail(&entity->list, &xdev->entities); |
|---|
| 392 | | - xdev->num_subdevs++; |
|---|
| 393 | 393 | } |
|---|
| 394 | 394 | |
|---|
| 395 | | - of_node_put(ep); |
|---|
| 395 | + return 0; |
|---|
| 396 | + |
|---|
| 397 | +err_notifier_cleanup: |
|---|
| 398 | + v4l2_async_notifier_cleanup(&xdev->notifier); |
|---|
| 399 | + fwnode_handle_put(ep); |
|---|
| 396 | 400 | return ret; |
|---|
| 397 | 401 | } |
|---|
| 398 | 402 | |
|---|
| 399 | 403 | static int xvip_graph_parse(struct xvip_composite_device *xdev) |
|---|
| 400 | 404 | { |
|---|
| 401 | 405 | struct xvip_graph_entity *entity; |
|---|
| 406 | + struct v4l2_async_subdev *asd; |
|---|
| 402 | 407 | int ret; |
|---|
| 403 | 408 | |
|---|
| 404 | 409 | /* |
|---|
| .. | .. |
|---|
| 407 | 412 | * loop will handle entities added at the end of the list while walking |
|---|
| 408 | 413 | * the links. |
|---|
| 409 | 414 | */ |
|---|
| 410 | | - ret = xvip_graph_parse_one(xdev, xdev->dev->of_node); |
|---|
| 415 | + ret = xvip_graph_parse_one(xdev, of_fwnode_handle(xdev->dev->of_node)); |
|---|
| 411 | 416 | if (ret < 0) |
|---|
| 412 | 417 | return 0; |
|---|
| 413 | 418 | |
|---|
| 414 | | - list_for_each_entry(entity, &xdev->entities, list) { |
|---|
| 415 | | - ret = xvip_graph_parse_one(xdev, entity->node); |
|---|
| 416 | | - if (ret < 0) |
|---|
| 419 | + list_for_each_entry(asd, &xdev->notifier.asd_list, asd_list) { |
|---|
| 420 | + entity = to_xvip_entity(asd); |
|---|
| 421 | + ret = xvip_graph_parse_one(xdev, entity->asd.match.fwnode); |
|---|
| 422 | + if (ret < 0) { |
|---|
| 423 | + v4l2_async_notifier_cleanup(&xdev->notifier); |
|---|
| 417 | 424 | break; |
|---|
| 425 | + } |
|---|
| 418 | 426 | } |
|---|
| 419 | 427 | |
|---|
| 420 | 428 | return ret; |
|---|
| .. | .. |
|---|
| 464 | 472 | { |
|---|
| 465 | 473 | struct device_node *ports; |
|---|
| 466 | 474 | struct device_node *port; |
|---|
| 467 | | - int ret; |
|---|
| 475 | + int ret = 0; |
|---|
| 468 | 476 | |
|---|
| 469 | 477 | ports = of_get_child_by_name(xdev->dev->of_node, "ports"); |
|---|
| 470 | 478 | if (ports == NULL) { |
|---|
| .. | .. |
|---|
| 474 | 482 | |
|---|
| 475 | 483 | for_each_child_of_node(ports, port) { |
|---|
| 476 | 484 | ret = xvip_graph_dma_init_one(xdev, port); |
|---|
| 477 | | - if (ret < 0) { |
|---|
| 485 | + if (ret) { |
|---|
| 478 | 486 | of_node_put(port); |
|---|
| 479 | | - return ret; |
|---|
| 487 | + break; |
|---|
| 480 | 488 | } |
|---|
| 481 | 489 | } |
|---|
| 482 | 490 | |
|---|
| 483 | | - return 0; |
|---|
| 491 | + of_node_put(ports); |
|---|
| 492 | + return ret; |
|---|
| 484 | 493 | } |
|---|
| 485 | 494 | |
|---|
| 486 | 495 | static void xvip_graph_cleanup(struct xvip_composite_device *xdev) |
|---|
| 487 | 496 | { |
|---|
| 488 | | - struct xvip_graph_entity *entityp; |
|---|
| 489 | | - struct xvip_graph_entity *entity; |
|---|
| 490 | 497 | struct xvip_dma *dmap; |
|---|
| 491 | 498 | struct xvip_dma *dma; |
|---|
| 492 | 499 | |
|---|
| 493 | 500 | v4l2_async_notifier_unregister(&xdev->notifier); |
|---|
| 494 | | - |
|---|
| 495 | | - list_for_each_entry_safe(entity, entityp, &xdev->entities, list) { |
|---|
| 496 | | - of_node_put(entity->node); |
|---|
| 497 | | - list_del(&entity->list); |
|---|
| 498 | | - } |
|---|
| 501 | + v4l2_async_notifier_cleanup(&xdev->notifier); |
|---|
| 499 | 502 | |
|---|
| 500 | 503 | list_for_each_entry_safe(dma, dmap, &xdev->dmas, list) { |
|---|
| 501 | 504 | xvip_dma_cleanup(dma); |
|---|
| .. | .. |
|---|
| 505 | 508 | |
|---|
| 506 | 509 | static int xvip_graph_init(struct xvip_composite_device *xdev) |
|---|
| 507 | 510 | { |
|---|
| 508 | | - struct xvip_graph_entity *entity; |
|---|
| 509 | | - struct v4l2_async_subdev **subdevs = NULL; |
|---|
| 510 | | - unsigned int num_subdevs; |
|---|
| 511 | | - unsigned int i; |
|---|
| 512 | 511 | int ret; |
|---|
| 513 | 512 | |
|---|
| 514 | 513 | /* Init the DMA channels. */ |
|---|
| .. | .. |
|---|
| 525 | 524 | goto done; |
|---|
| 526 | 525 | } |
|---|
| 527 | 526 | |
|---|
| 528 | | - if (!xdev->num_subdevs) { |
|---|
| 527 | + if (list_empty(&xdev->notifier.asd_list)) { |
|---|
| 529 | 528 | dev_err(xdev->dev, "no subdev found in graph\n"); |
|---|
| 530 | 529 | goto done; |
|---|
| 531 | 530 | } |
|---|
| 532 | 531 | |
|---|
| 533 | 532 | /* Register the subdevices notifier. */ |
|---|
| 534 | | - num_subdevs = xdev->num_subdevs; |
|---|
| 535 | | - subdevs = devm_kcalloc(xdev->dev, num_subdevs, sizeof(*subdevs), |
|---|
| 536 | | - GFP_KERNEL); |
|---|
| 537 | | - if (subdevs == NULL) { |
|---|
| 538 | | - ret = -ENOMEM; |
|---|
| 539 | | - goto done; |
|---|
| 540 | | - } |
|---|
| 541 | | - |
|---|
| 542 | | - i = 0; |
|---|
| 543 | | - list_for_each_entry(entity, &xdev->entities, list) |
|---|
| 544 | | - subdevs[i++] = &entity->asd; |
|---|
| 545 | | - |
|---|
| 546 | | - xdev->notifier.subdevs = subdevs; |
|---|
| 547 | | - xdev->notifier.num_subdevs = num_subdevs; |
|---|
| 548 | 533 | xdev->notifier.ops = &xvip_graph_notify_ops; |
|---|
| 549 | 534 | |
|---|
| 550 | 535 | ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier); |
|---|
| .. | .. |
|---|
| 578 | 563 | int ret; |
|---|
| 579 | 564 | |
|---|
| 580 | 565 | xdev->media_dev.dev = xdev->dev; |
|---|
| 581 | | - strlcpy(xdev->media_dev.model, "Xilinx Video Composite Device", |
|---|
| 566 | + strscpy(xdev->media_dev.model, "Xilinx Video Composite Device", |
|---|
| 582 | 567 | sizeof(xdev->media_dev.model)); |
|---|
| 583 | 568 | xdev->media_dev.hw_revision = 0; |
|---|
| 584 | 569 | |
|---|
| .. | .. |
|---|
| 610 | 595 | return -ENOMEM; |
|---|
| 611 | 596 | |
|---|
| 612 | 597 | xdev->dev = &pdev->dev; |
|---|
| 613 | | - INIT_LIST_HEAD(&xdev->entities); |
|---|
| 614 | 598 | INIT_LIST_HEAD(&xdev->dmas); |
|---|
| 599 | + v4l2_async_notifier_init(&xdev->notifier); |
|---|
| 615 | 600 | |
|---|
| 616 | 601 | ret = xvip_composite_v4l2_init(xdev); |
|---|
| 617 | 602 | if (ret < 0) |
|---|