1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * vsp1_entity.c -- R-Car VSP1 Base Entity 4 * 5 * Copyright (C) 2013-2014 Renesas Electronics Corporation 6 * 7 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) 8 */ 9 10 #include <linux/device.h> 11 #include <linux/gfp.h> 12 13 #include <media/media-entity.h> 14 #include <media/v4l2-ctrls.h> 15 #include <media/v4l2-subdev.h> 16 17 #include "vsp1.h" 18 #include "vsp1_dl.h" 19 #include "vsp1_entity.h" 20 #include "vsp1_pipe.h" 21 #include "vsp1_rwpf.h" 22 23 void vsp1_entity_route_setup(struct vsp1_entity *entity, 24 struct vsp1_pipeline *pipe, 25 struct vsp1_dl_body *dlb) 26 { 27 struct vsp1_entity *source; 28 u32 route; 29 30 if (entity->type == VSP1_ENTITY_HGO) { 31 u32 smppt; 32 33 /* 34 * The HGO is a special case, its routing is configured on the 35 * sink pad. 36 */ 37 source = entity->sources[0]; 38 smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT) 39 | (source->route->output << VI6_DPR_SMPPT_PT_SHIFT); 40 41 vsp1_dl_body_write(dlb, VI6_DPR_HGO_SMPPT, smppt); 42 return; 43 } else if (entity->type == VSP1_ENTITY_HGT) { 44 u32 smppt; 45 46 /* 47 * The HGT is a special case, its routing is configured on the 48 * sink pad. 49 */ 50 source = entity->sources[0]; 51 smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT) 52 | (source->route->output << VI6_DPR_SMPPT_PT_SHIFT); 53 54 vsp1_dl_body_write(dlb, VI6_DPR_HGT_SMPPT, smppt); 55 return; 56 } 57 58 source = entity; 59 if (source->route->reg == 0) 60 return; 61 62 route = source->sink->route->inputs[source->sink_pad]; 63 /* 64 * The ILV and BRS share the same data path route. The extra BRSSEL bit 65 * selects between the ILV and BRS. 66 */ 67 if (source->type == VSP1_ENTITY_BRS) 68 route |= VI6_DPR_ROUTE_BRSSEL; 69 vsp1_dl_body_write(dlb, source->route->reg, route); 70 } 71 72 void vsp1_entity_configure_stream(struct vsp1_entity *entity, 73 struct vsp1_pipeline *pipe, 74 struct vsp1_dl_list *dl, 75 struct vsp1_dl_body *dlb) 76 { 77 if (entity->ops->configure_stream) 78 entity->ops->configure_stream(entity, pipe, dl, dlb); 79 } 80 81 void vsp1_entity_configure_frame(struct vsp1_entity *entity, 82 struct vsp1_pipeline *pipe, 83 struct vsp1_dl_list *dl, 84 struct vsp1_dl_body *dlb) 85 { 86 if (entity->ops->configure_frame) 87 entity->ops->configure_frame(entity, pipe, dl, dlb); 88 } 89 90 void vsp1_entity_configure_partition(struct vsp1_entity *entity, 91 struct vsp1_pipeline *pipe, 92 struct vsp1_dl_list *dl, 93 struct vsp1_dl_body *dlb) 94 { 95 if (entity->ops->configure_partition) 96 entity->ops->configure_partition(entity, pipe, dl, dlb); 97 } 98 99 /* ----------------------------------------------------------------------------- 100 * V4L2 Subdevice Operations 101 */ 102 103 /** 104 * vsp1_entity_get_state - Get the subdev state for an entity 105 * @entity: the entity 106 * @sd_state: the TRY state 107 * @which: state selector (ACTIVE or TRY) 108 * 109 * When called with which set to V4L2_SUBDEV_FORMAT_ACTIVE the caller must hold 110 * the entity lock to access the returned configuration. 111 * 112 * Return the subdev state requested by the which argument. The TRY state is 113 * passed explicitly to the function through the sd_state argument and simply 114 * returned when requested. The ACTIVE state comes from the entity structure. 115 */ 116 struct v4l2_subdev_state * 117 vsp1_entity_get_state(struct vsp1_entity *entity, 118 struct v4l2_subdev_state *sd_state, 119 enum v4l2_subdev_format_whence which) 120 { 121 switch (which) { 122 case V4L2_SUBDEV_FORMAT_ACTIVE: 123 return entity->state; 124 case V4L2_SUBDEV_FORMAT_TRY: 125 default: 126 return sd_state; 127 } 128 } 129 130 /** 131 * vsp1_entity_get_pad_format - Get a pad format from storage for an entity 132 * @entity: the entity 133 * @sd_state: the state storage 134 * @pad: the pad number 135 * 136 * Return the format stored in the given configuration for an entity's pad. The 137 * configuration can be an ACTIVE or TRY configuration. 138 */ 139 struct v4l2_mbus_framefmt * 140 vsp1_entity_get_pad_format(struct vsp1_entity *entity, 141 struct v4l2_subdev_state *sd_state, 142 unsigned int pad) 143 { 144 return v4l2_subdev_state_get_format(sd_state, pad); 145 } 146 147 /** 148 * vsp1_entity_get_pad_selection - Get a pad selection from storage for entity 149 * @entity: the entity 150 * @sd_state: the state storage 151 * @pad: the pad number 152 * @target: the selection target 153 * 154 * Return the selection rectangle stored in the given configuration for an 155 * entity's pad. The configuration can be an ACTIVE or TRY configuration. The 156 * selection target can be COMPOSE or CROP. 157 */ 158 struct v4l2_rect * 159 vsp1_entity_get_pad_selection(struct vsp1_entity *entity, 160 struct v4l2_subdev_state *sd_state, 161 unsigned int pad, unsigned int target) 162 { 163 switch (target) { 164 case V4L2_SEL_TGT_COMPOSE: 165 return v4l2_subdev_state_get_compose(sd_state, pad); 166 case V4L2_SEL_TGT_CROP: 167 return v4l2_subdev_state_get_crop(sd_state, pad); 168 default: 169 return NULL; 170 } 171 } 172 173 /* 174 * vsp1_subdev_get_pad_format - Subdev pad get_fmt handler 175 * @subdev: V4L2 subdevice 176 * @sd_state: V4L2 subdev state 177 * @fmt: V4L2 subdev format 178 * 179 * This function implements the subdev get_fmt pad operation. It can be used as 180 * a direct drop-in for the operation handler. 181 */ 182 int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev, 183 struct v4l2_subdev_state *sd_state, 184 struct v4l2_subdev_format *fmt) 185 { 186 struct vsp1_entity *entity = to_vsp1_entity(subdev); 187 struct v4l2_subdev_state *state; 188 189 state = vsp1_entity_get_state(entity, sd_state, fmt->which); 190 if (!state) 191 return -EINVAL; 192 193 mutex_lock(&entity->lock); 194 fmt->format = *vsp1_entity_get_pad_format(entity, state, fmt->pad); 195 mutex_unlock(&entity->lock); 196 197 return 0; 198 } 199 200 /* 201 * vsp1_subdev_enum_mbus_code - Subdev pad enum_mbus_code handler 202 * @subdev: V4L2 subdevice 203 * @sd_state: V4L2 subdev state 204 * @code: Media bus code enumeration 205 * @codes: Array of supported media bus codes 206 * @ncodes: Number of supported media bus codes 207 * 208 * This function implements the subdev enum_mbus_code pad operation for entities 209 * that do not support format conversion. It enumerates the given supported 210 * media bus codes on the sink pad and reports a source pad format identical to 211 * the sink pad. 212 */ 213 int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev, 214 struct v4l2_subdev_state *sd_state, 215 struct v4l2_subdev_mbus_code_enum *code, 216 const unsigned int *codes, unsigned int ncodes) 217 { 218 struct vsp1_entity *entity = to_vsp1_entity(subdev); 219 220 if (code->pad == 0) { 221 if (code->index >= ncodes) 222 return -EINVAL; 223 224 code->code = codes[code->index]; 225 } else { 226 struct v4l2_subdev_state *state; 227 struct v4l2_mbus_framefmt *format; 228 229 /* 230 * The entity can't perform format conversion, the sink format 231 * is always identical to the source format. 232 */ 233 if (code->index) 234 return -EINVAL; 235 236 state = vsp1_entity_get_state(entity, sd_state, code->which); 237 if (!state) 238 return -EINVAL; 239 240 mutex_lock(&entity->lock); 241 format = vsp1_entity_get_pad_format(entity, state, 0); 242 code->code = format->code; 243 mutex_unlock(&entity->lock); 244 } 245 246 return 0; 247 } 248 249 /* 250 * vsp1_subdev_enum_frame_size - Subdev pad enum_frame_size handler 251 * @subdev: V4L2 subdevice 252 * @sd_state: V4L2 subdev state 253 * @fse: Frame size enumeration 254 * @min_width: Minimum image width 255 * @min_height: Minimum image height 256 * @max_width: Maximum image width 257 * @max_height: Maximum image height 258 * 259 * This function implements the subdev enum_frame_size pad operation for 260 * entities that do not support scaling or cropping. It reports the given 261 * minimum and maximum frame width and height on the sink pad, and a fixed 262 * source pad size identical to the sink pad. 263 */ 264 int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev, 265 struct v4l2_subdev_state *sd_state, 266 struct v4l2_subdev_frame_size_enum *fse, 267 unsigned int min_width, unsigned int min_height, 268 unsigned int max_width, unsigned int max_height) 269 { 270 struct vsp1_entity *entity = to_vsp1_entity(subdev); 271 struct v4l2_subdev_state *state; 272 struct v4l2_mbus_framefmt *format; 273 int ret = 0; 274 275 state = vsp1_entity_get_state(entity, sd_state, fse->which); 276 if (!state) 277 return -EINVAL; 278 279 format = vsp1_entity_get_pad_format(entity, state, fse->pad); 280 281 mutex_lock(&entity->lock); 282 283 if (fse->index || fse->code != format->code) { 284 ret = -EINVAL; 285 goto done; 286 } 287 288 if (fse->pad == 0) { 289 fse->min_width = min_width; 290 fse->max_width = max_width; 291 fse->min_height = min_height; 292 fse->max_height = max_height; 293 } else { 294 /* 295 * The size on the source pad are fixed and always identical to 296 * the size on the sink pad. 297 */ 298 fse->min_width = format->width; 299 fse->max_width = format->width; 300 fse->min_height = format->height; 301 fse->max_height = format->height; 302 } 303 304 done: 305 mutex_unlock(&entity->lock); 306 return ret; 307 } 308 309 /* 310 * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler 311 * @subdev: V4L2 subdevice 312 * @sd_state: V4L2 subdev state 313 * @fmt: V4L2 subdev format 314 * @codes: Array of supported media bus codes 315 * @ncodes: Number of supported media bus codes 316 * @min_width: Minimum image width 317 * @min_height: Minimum image height 318 * @max_width: Maximum image width 319 * @max_height: Maximum image height 320 * 321 * This function implements the subdev set_fmt pad operation for entities that 322 * do not support scaling or cropping. It defaults to the first supplied media 323 * bus code if the requested code isn't supported, clamps the size to the 324 * supplied minimum and maximum, and propagates the sink pad format to the 325 * source pad. 326 */ 327 int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev, 328 struct v4l2_subdev_state *sd_state, 329 struct v4l2_subdev_format *fmt, 330 const unsigned int *codes, unsigned int ncodes, 331 unsigned int min_width, unsigned int min_height, 332 unsigned int max_width, unsigned int max_height) 333 { 334 struct vsp1_entity *entity = to_vsp1_entity(subdev); 335 struct v4l2_subdev_state *state; 336 struct v4l2_mbus_framefmt *format; 337 struct v4l2_rect *selection; 338 unsigned int i; 339 int ret = 0; 340 341 mutex_lock(&entity->lock); 342 343 state = vsp1_entity_get_state(entity, sd_state, fmt->which); 344 if (!state) { 345 ret = -EINVAL; 346 goto done; 347 } 348 349 format = vsp1_entity_get_pad_format(entity, state, fmt->pad); 350 351 if (fmt->pad == entity->source_pad) { 352 /* The output format can't be modified. */ 353 fmt->format = *format; 354 goto done; 355 } 356 357 /* 358 * Default to the first media bus code if the requested format is not 359 * supported. 360 */ 361 for (i = 0; i < ncodes; ++i) { 362 if (fmt->format.code == codes[i]) 363 break; 364 } 365 366 format->code = i < ncodes ? codes[i] : codes[0]; 367 format->width = clamp_t(unsigned int, fmt->format.width, 368 min_width, max_width); 369 format->height = clamp_t(unsigned int, fmt->format.height, 370 min_height, max_height); 371 format->field = V4L2_FIELD_NONE; 372 format->colorspace = V4L2_COLORSPACE_SRGB; 373 374 fmt->format = *format; 375 376 /* Propagate the format to the source pad. */ 377 format = vsp1_entity_get_pad_format(entity, state, entity->source_pad); 378 *format = fmt->format; 379 380 /* Reset the crop and compose rectangles. */ 381 selection = vsp1_entity_get_pad_selection(entity, state, fmt->pad, 382 V4L2_SEL_TGT_CROP); 383 selection->left = 0; 384 selection->top = 0; 385 selection->width = format->width; 386 selection->height = format->height; 387 388 selection = vsp1_entity_get_pad_selection(entity, state, fmt->pad, 389 V4L2_SEL_TGT_COMPOSE); 390 selection->left = 0; 391 selection->top = 0; 392 selection->width = format->width; 393 selection->height = format->height; 394 395 done: 396 mutex_unlock(&entity->lock); 397 return ret; 398 } 399 400 static int vsp1_entity_init_state(struct v4l2_subdev *subdev, 401 struct v4l2_subdev_state *sd_state) 402 { 403 unsigned int pad; 404 405 /* Initialize all pad formats with default values. */ 406 for (pad = 0; pad < subdev->entity.num_pads - 1; ++pad) { 407 struct v4l2_subdev_format format = { 408 .pad = pad, 409 .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY 410 : V4L2_SUBDEV_FORMAT_ACTIVE, 411 }; 412 413 v4l2_subdev_call(subdev, pad, set_fmt, sd_state, &format); 414 } 415 416 return 0; 417 } 418 419 static const struct v4l2_subdev_internal_ops vsp1_entity_internal_ops = { 420 .init_state = vsp1_entity_init_state, 421 }; 422 423 /* ----------------------------------------------------------------------------- 424 * Media Operations 425 */ 426 427 static inline struct vsp1_entity * 428 media_entity_to_vsp1_entity(struct media_entity *entity) 429 { 430 return container_of(entity, struct vsp1_entity, subdev.entity); 431 } 432 433 static int vsp1_entity_link_setup_source(const struct media_pad *source_pad, 434 const struct media_pad *sink_pad, 435 u32 flags) 436 { 437 struct vsp1_entity *source; 438 439 source = media_entity_to_vsp1_entity(source_pad->entity); 440 441 if (!source->route) 442 return 0; 443 444 if (flags & MEDIA_LNK_FL_ENABLED) { 445 struct vsp1_entity *sink 446 = media_entity_to_vsp1_entity(sink_pad->entity); 447 448 /* 449 * Fan-out is limited to one for the normal data path plus 450 * optional HGO and HGT. We ignore the HGO and HGT here. 451 */ 452 if (sink->type != VSP1_ENTITY_HGO && 453 sink->type != VSP1_ENTITY_HGT) { 454 if (source->sink) 455 return -EBUSY; 456 source->sink = sink; 457 source->sink_pad = sink_pad->index; 458 } 459 } else { 460 source->sink = NULL; 461 source->sink_pad = 0; 462 } 463 464 return 0; 465 } 466 467 static int vsp1_entity_link_setup_sink(const struct media_pad *source_pad, 468 const struct media_pad *sink_pad, 469 u32 flags) 470 { 471 struct vsp1_entity *sink; 472 struct vsp1_entity *source; 473 474 sink = media_entity_to_vsp1_entity(sink_pad->entity); 475 source = media_entity_to_vsp1_entity(source_pad->entity); 476 477 if (flags & MEDIA_LNK_FL_ENABLED) { 478 /* Fan-in is limited to one. */ 479 if (sink->sources[sink_pad->index]) 480 return -EBUSY; 481 482 sink->sources[sink_pad->index] = source; 483 } else { 484 sink->sources[sink_pad->index] = NULL; 485 } 486 487 return 0; 488 } 489 490 int vsp1_entity_link_setup(struct media_entity *entity, 491 const struct media_pad *local, 492 const struct media_pad *remote, u32 flags) 493 { 494 if (local->flags & MEDIA_PAD_FL_SOURCE) 495 return vsp1_entity_link_setup_source(local, remote, flags); 496 else 497 return vsp1_entity_link_setup_sink(remote, local, flags); 498 } 499 500 /** 501 * vsp1_entity_remote_pad - Find the pad at the remote end of a link 502 * @pad: Pad at the local end of the link 503 * 504 * Search for a remote pad connected to the given pad by iterating over all 505 * links originating or terminating at that pad until an enabled link is found. 506 * 507 * Our link setup implementation guarantees that the output fan-out will not be 508 * higher than one for the data pipelines, except for the links to the HGO and 509 * HGT that can be enabled in addition to a regular data link. When traversing 510 * outgoing links this function ignores HGO and HGT entities and should thus be 511 * used in place of the generic media_pad_remote_pad_first() function to 512 * traverse data pipelines. 513 * 514 * Return a pointer to the pad at the remote end of the first found enabled 515 * link, or NULL if no enabled link has been found. 516 */ 517 struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad) 518 { 519 struct media_link *link; 520 521 list_for_each_entry(link, &pad->entity->links, list) { 522 struct vsp1_entity *entity; 523 524 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) 525 continue; 526 527 /* If we're the sink the source will never be an HGO or HGT. */ 528 if (link->sink == pad) 529 return link->source; 530 531 if (link->source != pad) 532 continue; 533 534 /* If the sink isn't a subdevice it can't be an HGO or HGT. */ 535 if (!is_media_entity_v4l2_subdev(link->sink->entity)) 536 return link->sink; 537 538 entity = media_entity_to_vsp1_entity(link->sink->entity); 539 if (entity->type != VSP1_ENTITY_HGO && 540 entity->type != VSP1_ENTITY_HGT) 541 return link->sink; 542 } 543 544 return NULL; 545 546 } 547 548 /* ----------------------------------------------------------------------------- 549 * Initialization 550 */ 551 552 #define VSP1_ENTITY_ROUTE(ent) \ 553 { VSP1_ENTITY_##ent, 0, VI6_DPR_##ent##_ROUTE, \ 554 { VI6_DPR_NODE_##ent }, VI6_DPR_NODE_##ent } 555 556 #define VSP1_ENTITY_ROUTE_RPF(idx) \ 557 { VSP1_ENTITY_RPF, idx, VI6_DPR_RPF_ROUTE(idx), \ 558 { 0, }, VI6_DPR_NODE_RPF(idx) } 559 560 #define VSP1_ENTITY_ROUTE_UDS(idx) \ 561 { VSP1_ENTITY_UDS, idx, VI6_DPR_UDS_ROUTE(idx), \ 562 { VI6_DPR_NODE_UDS(idx) }, VI6_DPR_NODE_UDS(idx) } 563 564 #define VSP1_ENTITY_ROUTE_UIF(idx) \ 565 { VSP1_ENTITY_UIF, idx, VI6_DPR_UIF_ROUTE(idx), \ 566 { VI6_DPR_NODE_UIF(idx) }, VI6_DPR_NODE_UIF(idx) } 567 568 #define VSP1_ENTITY_ROUTE_WPF(idx) \ 569 { VSP1_ENTITY_WPF, idx, 0, \ 570 { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) } 571 572 static const struct vsp1_route vsp1_routes[] = { 573 { VSP1_ENTITY_BRS, 0, VI6_DPR_ILV_BRS_ROUTE, 574 { VI6_DPR_NODE_BRS_IN(0), VI6_DPR_NODE_BRS_IN(1) }, 0 }, 575 { VSP1_ENTITY_BRU, 0, VI6_DPR_BRU_ROUTE, 576 { VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1), 577 VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3), 578 VI6_DPR_NODE_BRU_IN(4) }, VI6_DPR_NODE_BRU_OUT }, 579 VSP1_ENTITY_ROUTE(CLU), 580 { VSP1_ENTITY_HGO, 0, 0, { 0, }, 0 }, 581 { VSP1_ENTITY_HGT, 0, 0, { 0, }, 0 }, 582 VSP1_ENTITY_ROUTE(HSI), 583 VSP1_ENTITY_ROUTE(HST), 584 { VSP1_ENTITY_LIF, 0, 0, { 0, }, 0 }, 585 { VSP1_ENTITY_LIF, 1, 0, { 0, }, 0 }, 586 VSP1_ENTITY_ROUTE(LUT), 587 VSP1_ENTITY_ROUTE_RPF(0), 588 VSP1_ENTITY_ROUTE_RPF(1), 589 VSP1_ENTITY_ROUTE_RPF(2), 590 VSP1_ENTITY_ROUTE_RPF(3), 591 VSP1_ENTITY_ROUTE_RPF(4), 592 VSP1_ENTITY_ROUTE(SRU), 593 VSP1_ENTITY_ROUTE_UDS(0), 594 VSP1_ENTITY_ROUTE_UDS(1), 595 VSP1_ENTITY_ROUTE_UDS(2), 596 VSP1_ENTITY_ROUTE_UIF(0), /* Named UIF4 in the documentation */ 597 VSP1_ENTITY_ROUTE_UIF(1), /* Named UIF5 in the documentation */ 598 VSP1_ENTITY_ROUTE_WPF(0), 599 VSP1_ENTITY_ROUTE_WPF(1), 600 VSP1_ENTITY_ROUTE_WPF(2), 601 VSP1_ENTITY_ROUTE_WPF(3), 602 }; 603 604 int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, 605 const char *name, unsigned int num_pads, 606 const struct v4l2_subdev_ops *ops, u32 function) 607 { 608 static struct lock_class_key key; 609 struct v4l2_subdev *subdev; 610 unsigned int i; 611 int ret; 612 613 for (i = 0; i < ARRAY_SIZE(vsp1_routes); ++i) { 614 if (vsp1_routes[i].type == entity->type && 615 vsp1_routes[i].index == entity->index) { 616 entity->route = &vsp1_routes[i]; 617 break; 618 } 619 } 620 621 if (i == ARRAY_SIZE(vsp1_routes)) 622 return -EINVAL; 623 624 mutex_init(&entity->lock); 625 626 entity->vsp1 = vsp1; 627 entity->source_pad = num_pads - 1; 628 629 /* Allocate and initialize pads. */ 630 entity->pads = devm_kcalloc(vsp1->dev, 631 num_pads, sizeof(*entity->pads), 632 GFP_KERNEL); 633 if (entity->pads == NULL) 634 return -ENOMEM; 635 636 for (i = 0; i < num_pads - 1; ++i) 637 entity->pads[i].flags = MEDIA_PAD_FL_SINK; 638 639 entity->sources = devm_kcalloc(vsp1->dev, max(num_pads - 1, 1U), 640 sizeof(*entity->sources), GFP_KERNEL); 641 if (entity->sources == NULL) 642 return -ENOMEM; 643 644 /* Single-pad entities only have a sink. */ 645 entity->pads[num_pads - 1].flags = num_pads > 1 ? MEDIA_PAD_FL_SOURCE 646 : MEDIA_PAD_FL_SINK; 647 648 /* Initialize the media entity. */ 649 ret = media_entity_pads_init(&entity->subdev.entity, num_pads, 650 entity->pads); 651 if (ret < 0) 652 return ret; 653 654 /* Initialize the V4L2 subdev. */ 655 subdev = &entity->subdev; 656 v4l2_subdev_init(subdev, ops); 657 subdev->internal_ops = &vsp1_entity_internal_ops; 658 659 subdev->entity.function = function; 660 subdev->entity.ops = &vsp1->media_ops; 661 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 662 663 snprintf(subdev->name, sizeof(subdev->name), "%s %s", 664 dev_name(vsp1->dev), name); 665 666 vsp1_entity_init_state(subdev, NULL); 667 668 /* 669 * Allocate the subdev state to store formats and selection 670 * rectangles. 671 */ 672 /* 673 * FIXME: Drop this call, drivers are not supposed to use 674 * __v4l2_subdev_state_alloc(). 675 */ 676 entity->state = __v4l2_subdev_state_alloc(&entity->subdev, 677 "vsp1:state->lock", &key); 678 if (IS_ERR(entity->state)) { 679 media_entity_cleanup(&entity->subdev.entity); 680 return PTR_ERR(entity->state); 681 } 682 683 return 0; 684 } 685 686 void vsp1_entity_destroy(struct vsp1_entity *entity) 687 { 688 if (entity->ops && entity->ops->destroy) 689 entity->ops->destroy(entity); 690 if (entity->subdev.ctrl_handler) 691 v4l2_ctrl_handler_free(entity->subdev.ctrl_handler); 692 __v4l2_subdev_state_free(entity->state); 693 media_entity_cleanup(&entity->subdev.entity); 694 } 695