1 /* 2 * V4L2 sub-device 3 * 4 * Copyright (C) 2010 Nokia Corporation 5 * 6 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 7 * Sakari Ailus <sakari.ailus@iki.fi> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19 #include <linux/ioctl.h> 20 #include <linux/mm.h> 21 #include <linux/slab.h> 22 #include <linux/types.h> 23 #include <linux/videodev2.h> 24 #include <linux/export.h> 25 26 #include <media/v4l2-ctrls.h> 27 #include <media/v4l2-device.h> 28 #include <media/v4l2-ioctl.h> 29 #include <media/v4l2-fh.h> 30 #include <media/v4l2-event.h> 31 32 static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) 33 { 34 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 35 if (sd->entity.num_pads) { 36 fh->pad = v4l2_subdev_alloc_pad_config(sd); 37 if (fh->pad == NULL) 38 return -ENOMEM; 39 } 40 #endif 41 return 0; 42 } 43 44 static void subdev_fh_free(struct v4l2_subdev_fh *fh) 45 { 46 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 47 v4l2_subdev_free_pad_config(fh->pad); 48 fh->pad = NULL; 49 #endif 50 } 51 52 static int subdev_open(struct file *file) 53 { 54 struct video_device *vdev = video_devdata(file); 55 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); 56 struct v4l2_subdev_fh *subdev_fh; 57 #if defined(CONFIG_MEDIA_CONTROLLER) 58 struct media_entity *entity = NULL; 59 #endif 60 int ret; 61 62 subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL); 63 if (subdev_fh == NULL) 64 return -ENOMEM; 65 66 ret = subdev_fh_init(subdev_fh, sd); 67 if (ret) { 68 kfree(subdev_fh); 69 return ret; 70 } 71 72 v4l2_fh_init(&subdev_fh->vfh, vdev); 73 v4l2_fh_add(&subdev_fh->vfh); 74 file->private_data = &subdev_fh->vfh; 75 #if defined(CONFIG_MEDIA_CONTROLLER) 76 if (sd->v4l2_dev->mdev) { 77 entity = media_entity_get(&sd->entity); 78 if (!entity) { 79 ret = -EBUSY; 80 goto err; 81 } 82 } 83 #endif 84 85 if (sd->internal_ops && sd->internal_ops->open) { 86 ret = sd->internal_ops->open(sd, subdev_fh); 87 if (ret < 0) 88 goto err; 89 } 90 91 return 0; 92 93 err: 94 #if defined(CONFIG_MEDIA_CONTROLLER) 95 media_entity_put(entity); 96 #endif 97 v4l2_fh_del(&subdev_fh->vfh); 98 v4l2_fh_exit(&subdev_fh->vfh); 99 subdev_fh_free(subdev_fh); 100 kfree(subdev_fh); 101 102 return ret; 103 } 104 105 static int subdev_close(struct file *file) 106 { 107 struct video_device *vdev = video_devdata(file); 108 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); 109 struct v4l2_fh *vfh = file->private_data; 110 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); 111 112 if (sd->internal_ops && sd->internal_ops->close) 113 sd->internal_ops->close(sd, subdev_fh); 114 #if defined(CONFIG_MEDIA_CONTROLLER) 115 if (sd->v4l2_dev->mdev) 116 media_entity_put(&sd->entity); 117 #endif 118 v4l2_fh_del(vfh); 119 v4l2_fh_exit(vfh); 120 subdev_fh_free(subdev_fh); 121 kfree(subdev_fh); 122 file->private_data = NULL; 123 124 return 0; 125 } 126 127 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 128 static int check_format(struct v4l2_subdev *sd, 129 struct v4l2_subdev_format *format) 130 { 131 if (format->which != V4L2_SUBDEV_FORMAT_TRY && 132 format->which != V4L2_SUBDEV_FORMAT_ACTIVE) 133 return -EINVAL; 134 135 if (format->pad >= sd->entity.num_pads) 136 return -EINVAL; 137 138 return 0; 139 } 140 141 static int check_crop(struct v4l2_subdev *sd, struct v4l2_subdev_crop *crop) 142 { 143 if (crop->which != V4L2_SUBDEV_FORMAT_TRY && 144 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) 145 return -EINVAL; 146 147 if (crop->pad >= sd->entity.num_pads) 148 return -EINVAL; 149 150 return 0; 151 } 152 153 static int check_selection(struct v4l2_subdev *sd, 154 struct v4l2_subdev_selection *sel) 155 { 156 if (sel->which != V4L2_SUBDEV_FORMAT_TRY && 157 sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 158 return -EINVAL; 159 160 if (sel->pad >= sd->entity.num_pads) 161 return -EINVAL; 162 163 return 0; 164 } 165 166 static int check_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid) 167 { 168 if (edid->pad >= sd->entity.num_pads) 169 return -EINVAL; 170 171 if (edid->blocks && edid->edid == NULL) 172 return -EINVAL; 173 174 return 0; 175 } 176 #endif 177 178 static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) 179 { 180 struct video_device *vdev = video_devdata(file); 181 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); 182 struct v4l2_fh *vfh = file->private_data; 183 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 184 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); 185 int rval; 186 #endif 187 188 switch (cmd) { 189 case VIDIOC_QUERYCTRL: 190 /* 191 * TODO: this really should be folded into v4l2_queryctrl (this 192 * currently returns -EINVAL for NULL control handlers). 193 * However, v4l2_queryctrl() is still called directly by 194 * drivers as well and until that has been addressed I believe 195 * it is safer to do the check here. The same is true for the 196 * other control ioctls below. 197 */ 198 if (!vfh->ctrl_handler) 199 return -ENOTTY; 200 return v4l2_queryctrl(vfh->ctrl_handler, arg); 201 202 case VIDIOC_QUERY_EXT_CTRL: 203 if (!vfh->ctrl_handler) 204 return -ENOTTY; 205 return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg); 206 207 case VIDIOC_QUERYMENU: 208 if (!vfh->ctrl_handler) 209 return -ENOTTY; 210 return v4l2_querymenu(vfh->ctrl_handler, arg); 211 212 case VIDIOC_G_CTRL: 213 if (!vfh->ctrl_handler) 214 return -ENOTTY; 215 return v4l2_g_ctrl(vfh->ctrl_handler, arg); 216 217 case VIDIOC_S_CTRL: 218 if (!vfh->ctrl_handler) 219 return -ENOTTY; 220 return v4l2_s_ctrl(vfh, vfh->ctrl_handler, arg); 221 222 case VIDIOC_G_EXT_CTRLS: 223 if (!vfh->ctrl_handler) 224 return -ENOTTY; 225 return v4l2_g_ext_ctrls(vfh->ctrl_handler, 226 sd->v4l2_dev->mdev, arg); 227 228 case VIDIOC_S_EXT_CTRLS: 229 if (!vfh->ctrl_handler) 230 return -ENOTTY; 231 return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, 232 sd->v4l2_dev->mdev, arg); 233 234 case VIDIOC_TRY_EXT_CTRLS: 235 if (!vfh->ctrl_handler) 236 return -ENOTTY; 237 return v4l2_try_ext_ctrls(vfh->ctrl_handler, 238 sd->v4l2_dev->mdev, arg); 239 240 case VIDIOC_DQEVENT: 241 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) 242 return -ENOIOCTLCMD; 243 244 return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); 245 246 case VIDIOC_SUBSCRIBE_EVENT: 247 return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); 248 249 case VIDIOC_UNSUBSCRIBE_EVENT: 250 return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg); 251 252 #ifdef CONFIG_VIDEO_ADV_DEBUG 253 case VIDIOC_DBG_G_REGISTER: 254 { 255 struct v4l2_dbg_register *p = arg; 256 257 if (!capable(CAP_SYS_ADMIN)) 258 return -EPERM; 259 return v4l2_subdev_call(sd, core, g_register, p); 260 } 261 case VIDIOC_DBG_S_REGISTER: 262 { 263 struct v4l2_dbg_register *p = arg; 264 265 if (!capable(CAP_SYS_ADMIN)) 266 return -EPERM; 267 return v4l2_subdev_call(sd, core, s_register, p); 268 } 269 case VIDIOC_DBG_G_CHIP_INFO: 270 { 271 struct v4l2_dbg_chip_info *p = arg; 272 273 if (p->match.type != V4L2_CHIP_MATCH_SUBDEV || p->match.addr) 274 return -EINVAL; 275 if (sd->ops->core && sd->ops->core->s_register) 276 p->flags |= V4L2_CHIP_FL_WRITABLE; 277 if (sd->ops->core && sd->ops->core->g_register) 278 p->flags |= V4L2_CHIP_FL_READABLE; 279 strscpy(p->name, sd->name, sizeof(p->name)); 280 return 0; 281 } 282 #endif 283 284 case VIDIOC_LOG_STATUS: { 285 int ret; 286 287 pr_info("%s: ================= START STATUS =================\n", 288 sd->name); 289 ret = v4l2_subdev_call(sd, core, log_status); 290 pr_info("%s: ================== END STATUS ==================\n", 291 sd->name); 292 return ret; 293 } 294 295 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 296 case VIDIOC_SUBDEV_G_FMT: { 297 struct v4l2_subdev_format *format = arg; 298 299 rval = check_format(sd, format); 300 if (rval) 301 return rval; 302 303 memset(format->reserved, 0, sizeof(format->reserved)); 304 memset(format->format.reserved, 0, sizeof(format->format.reserved)); 305 return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh->pad, format); 306 } 307 308 case VIDIOC_SUBDEV_S_FMT: { 309 struct v4l2_subdev_format *format = arg; 310 311 rval = check_format(sd, format); 312 if (rval) 313 return rval; 314 315 memset(format->reserved, 0, sizeof(format->reserved)); 316 memset(format->format.reserved, 0, sizeof(format->format.reserved)); 317 return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->pad, format); 318 } 319 320 case VIDIOC_SUBDEV_G_CROP: { 321 struct v4l2_subdev_crop *crop = arg; 322 struct v4l2_subdev_selection sel; 323 324 rval = check_crop(sd, crop); 325 if (rval) 326 return rval; 327 328 memset(crop->reserved, 0, sizeof(crop->reserved)); 329 memset(&sel, 0, sizeof(sel)); 330 sel.which = crop->which; 331 sel.pad = crop->pad; 332 sel.target = V4L2_SEL_TGT_CROP; 333 334 rval = v4l2_subdev_call( 335 sd, pad, get_selection, subdev_fh->pad, &sel); 336 337 crop->rect = sel.r; 338 339 return rval; 340 } 341 342 case VIDIOC_SUBDEV_S_CROP: { 343 struct v4l2_subdev_crop *crop = arg; 344 struct v4l2_subdev_selection sel; 345 346 memset(crop->reserved, 0, sizeof(crop->reserved)); 347 rval = check_crop(sd, crop); 348 if (rval) 349 return rval; 350 351 memset(&sel, 0, sizeof(sel)); 352 sel.which = crop->which; 353 sel.pad = crop->pad; 354 sel.target = V4L2_SEL_TGT_CROP; 355 sel.r = crop->rect; 356 357 rval = v4l2_subdev_call( 358 sd, pad, set_selection, subdev_fh->pad, &sel); 359 360 crop->rect = sel.r; 361 362 return rval; 363 } 364 365 case VIDIOC_SUBDEV_ENUM_MBUS_CODE: { 366 struct v4l2_subdev_mbus_code_enum *code = arg; 367 368 if (code->which != V4L2_SUBDEV_FORMAT_TRY && 369 code->which != V4L2_SUBDEV_FORMAT_ACTIVE) 370 return -EINVAL; 371 372 if (code->pad >= sd->entity.num_pads) 373 return -EINVAL; 374 375 memset(code->reserved, 0, sizeof(code->reserved)); 376 return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh->pad, 377 code); 378 } 379 380 case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: { 381 struct v4l2_subdev_frame_size_enum *fse = arg; 382 383 if (fse->which != V4L2_SUBDEV_FORMAT_TRY && 384 fse->which != V4L2_SUBDEV_FORMAT_ACTIVE) 385 return -EINVAL; 386 387 if (fse->pad >= sd->entity.num_pads) 388 return -EINVAL; 389 390 memset(fse->reserved, 0, sizeof(fse->reserved)); 391 return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh->pad, 392 fse); 393 } 394 395 case VIDIOC_SUBDEV_G_FRAME_INTERVAL: { 396 struct v4l2_subdev_frame_interval *fi = arg; 397 398 if (fi->pad >= sd->entity.num_pads) 399 return -EINVAL; 400 401 memset(fi->reserved, 0, sizeof(fi->reserved)); 402 return v4l2_subdev_call(sd, video, g_frame_interval, arg); 403 } 404 405 case VIDIOC_SUBDEV_S_FRAME_INTERVAL: { 406 struct v4l2_subdev_frame_interval *fi = arg; 407 408 if (fi->pad >= sd->entity.num_pads) 409 return -EINVAL; 410 411 memset(fi->reserved, 0, sizeof(fi->reserved)); 412 return v4l2_subdev_call(sd, video, s_frame_interval, arg); 413 } 414 415 case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: { 416 struct v4l2_subdev_frame_interval_enum *fie = arg; 417 418 if (fie->which != V4L2_SUBDEV_FORMAT_TRY && 419 fie->which != V4L2_SUBDEV_FORMAT_ACTIVE) 420 return -EINVAL; 421 422 if (fie->pad >= sd->entity.num_pads) 423 return -EINVAL; 424 425 memset(fie->reserved, 0, sizeof(fie->reserved)); 426 return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh->pad, 427 fie); 428 } 429 430 case VIDIOC_SUBDEV_G_SELECTION: { 431 struct v4l2_subdev_selection *sel = arg; 432 433 rval = check_selection(sd, sel); 434 if (rval) 435 return rval; 436 437 memset(sel->reserved, 0, sizeof(sel->reserved)); 438 return v4l2_subdev_call( 439 sd, pad, get_selection, subdev_fh->pad, sel); 440 } 441 442 case VIDIOC_SUBDEV_S_SELECTION: { 443 struct v4l2_subdev_selection *sel = arg; 444 445 rval = check_selection(sd, sel); 446 if (rval) 447 return rval; 448 449 memset(sel->reserved, 0, sizeof(sel->reserved)); 450 return v4l2_subdev_call( 451 sd, pad, set_selection, subdev_fh->pad, sel); 452 } 453 454 case VIDIOC_G_EDID: { 455 struct v4l2_subdev_edid *edid = arg; 456 457 rval = check_edid(sd, edid); 458 if (rval) 459 return rval; 460 461 return v4l2_subdev_call(sd, pad, get_edid, edid); 462 } 463 464 case VIDIOC_S_EDID: { 465 struct v4l2_subdev_edid *edid = arg; 466 467 rval = check_edid(sd, edid); 468 if (rval) 469 return rval; 470 471 return v4l2_subdev_call(sd, pad, set_edid, edid); 472 } 473 474 case VIDIOC_SUBDEV_DV_TIMINGS_CAP: { 475 struct v4l2_dv_timings_cap *cap = arg; 476 477 if (cap->pad >= sd->entity.num_pads) 478 return -EINVAL; 479 480 return v4l2_subdev_call(sd, pad, dv_timings_cap, cap); 481 } 482 483 case VIDIOC_SUBDEV_ENUM_DV_TIMINGS: { 484 struct v4l2_enum_dv_timings *dvt = arg; 485 486 if (dvt->pad >= sd->entity.num_pads) 487 return -EINVAL; 488 489 return v4l2_subdev_call(sd, pad, enum_dv_timings, dvt); 490 } 491 492 case VIDIOC_SUBDEV_QUERY_DV_TIMINGS: 493 return v4l2_subdev_call(sd, video, query_dv_timings, arg); 494 495 case VIDIOC_SUBDEV_G_DV_TIMINGS: 496 return v4l2_subdev_call(sd, video, g_dv_timings, arg); 497 498 case VIDIOC_SUBDEV_S_DV_TIMINGS: 499 return v4l2_subdev_call(sd, video, s_dv_timings, arg); 500 501 case VIDIOC_SUBDEV_G_STD: 502 return v4l2_subdev_call(sd, video, g_std, arg); 503 504 case VIDIOC_SUBDEV_S_STD: { 505 v4l2_std_id *std = arg; 506 507 return v4l2_subdev_call(sd, video, s_std, *std); 508 } 509 510 case VIDIOC_SUBDEV_ENUMSTD: { 511 struct v4l2_standard *p = arg; 512 v4l2_std_id id; 513 514 if (v4l2_subdev_call(sd, video, g_tvnorms, &id)) 515 return -EINVAL; 516 517 return v4l_video_std_enumstd(p, id); 518 } 519 520 case VIDIOC_SUBDEV_QUERYSTD: 521 return v4l2_subdev_call(sd, video, querystd, arg); 522 #endif 523 default: 524 return v4l2_subdev_call(sd, core, ioctl, cmd, arg); 525 } 526 527 return 0; 528 } 529 530 static long subdev_do_ioctl_lock(struct file *file, unsigned int cmd, void *arg) 531 { 532 struct video_device *vdev = video_devdata(file); 533 struct mutex *lock = vdev->lock; 534 long ret = -ENODEV; 535 536 if (lock && mutex_lock_interruptible(lock)) 537 return -ERESTARTSYS; 538 if (video_is_registered(vdev)) 539 ret = subdev_do_ioctl(file, cmd, arg); 540 if (lock) 541 mutex_unlock(lock); 542 return ret; 543 } 544 545 static long subdev_ioctl(struct file *file, unsigned int cmd, 546 unsigned long arg) 547 { 548 return video_usercopy(file, cmd, arg, subdev_do_ioctl_lock); 549 } 550 551 #ifdef CONFIG_COMPAT 552 static long subdev_compat_ioctl32(struct file *file, unsigned int cmd, 553 unsigned long arg) 554 { 555 struct video_device *vdev = video_devdata(file); 556 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); 557 558 return v4l2_subdev_call(sd, core, compat_ioctl32, cmd, arg); 559 } 560 #endif 561 562 static __poll_t subdev_poll(struct file *file, poll_table *wait) 563 { 564 struct video_device *vdev = video_devdata(file); 565 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); 566 struct v4l2_fh *fh = file->private_data; 567 568 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) 569 return EPOLLERR; 570 571 poll_wait(file, &fh->wait, wait); 572 573 if (v4l2_event_pending(fh)) 574 return EPOLLPRI; 575 576 return 0; 577 } 578 579 const struct v4l2_file_operations v4l2_subdev_fops = { 580 .owner = THIS_MODULE, 581 .open = subdev_open, 582 .unlocked_ioctl = subdev_ioctl, 583 #ifdef CONFIG_COMPAT 584 .compat_ioctl32 = subdev_compat_ioctl32, 585 #endif 586 .release = subdev_close, 587 .poll = subdev_poll, 588 }; 589 590 #ifdef CONFIG_MEDIA_CONTROLLER 591 int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd, 592 struct media_link *link, 593 struct v4l2_subdev_format *source_fmt, 594 struct v4l2_subdev_format *sink_fmt) 595 { 596 /* The width, height and code must match. */ 597 if (source_fmt->format.width != sink_fmt->format.width 598 || source_fmt->format.height != sink_fmt->format.height 599 || source_fmt->format.code != sink_fmt->format.code) 600 return -EPIPE; 601 602 /* The field order must match, or the sink field order must be NONE 603 * to support interlaced hardware connected to bridges that support 604 * progressive formats only. 605 */ 606 if (source_fmt->format.field != sink_fmt->format.field && 607 sink_fmt->format.field != V4L2_FIELD_NONE) 608 return -EPIPE; 609 610 return 0; 611 } 612 EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default); 613 614 static int 615 v4l2_subdev_link_validate_get_format(struct media_pad *pad, 616 struct v4l2_subdev_format *fmt) 617 { 618 if (is_media_entity_v4l2_subdev(pad->entity)) { 619 struct v4l2_subdev *sd = 620 media_entity_to_v4l2_subdev(pad->entity); 621 622 fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE; 623 fmt->pad = pad->index; 624 return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt); 625 } 626 627 WARN(pad->entity->function != MEDIA_ENT_F_IO_V4L, 628 "Driver bug! Wrong media entity type 0x%08x, entity %s\n", 629 pad->entity->function, pad->entity->name); 630 631 return -EINVAL; 632 } 633 634 int v4l2_subdev_link_validate(struct media_link *link) 635 { 636 struct v4l2_subdev *sink; 637 struct v4l2_subdev_format sink_fmt, source_fmt; 638 int rval; 639 640 rval = v4l2_subdev_link_validate_get_format( 641 link->source, &source_fmt); 642 if (rval < 0) 643 return 0; 644 645 rval = v4l2_subdev_link_validate_get_format( 646 link->sink, &sink_fmt); 647 if (rval < 0) 648 return 0; 649 650 sink = media_entity_to_v4l2_subdev(link->sink->entity); 651 652 rval = v4l2_subdev_call(sink, pad, link_validate, link, 653 &source_fmt, &sink_fmt); 654 if (rval != -ENOIOCTLCMD) 655 return rval; 656 657 return v4l2_subdev_link_validate_default( 658 sink, link, &source_fmt, &sink_fmt); 659 } 660 EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate); 661 662 struct v4l2_subdev_pad_config * 663 v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd) 664 { 665 struct v4l2_subdev_pad_config *cfg; 666 int ret; 667 668 if (!sd->entity.num_pads) 669 return NULL; 670 671 cfg = kvmalloc_array(sd->entity.num_pads, sizeof(*cfg), 672 GFP_KERNEL | __GFP_ZERO); 673 if (!cfg) 674 return NULL; 675 676 ret = v4l2_subdev_call(sd, pad, init_cfg, cfg); 677 if (ret < 0 && ret != -ENOIOCTLCMD) { 678 kvfree(cfg); 679 return NULL; 680 } 681 682 return cfg; 683 } 684 EXPORT_SYMBOL_GPL(v4l2_subdev_alloc_pad_config); 685 686 void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg) 687 { 688 kvfree(cfg); 689 } 690 EXPORT_SYMBOL_GPL(v4l2_subdev_free_pad_config); 691 #endif /* CONFIG_MEDIA_CONTROLLER */ 692 693 void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) 694 { 695 INIT_LIST_HEAD(&sd->list); 696 BUG_ON(!ops); 697 sd->ops = ops; 698 sd->v4l2_dev = NULL; 699 sd->flags = 0; 700 sd->name[0] = '\0'; 701 sd->grp_id = 0; 702 sd->dev_priv = NULL; 703 sd->host_priv = NULL; 704 #if defined(CONFIG_MEDIA_CONTROLLER) 705 sd->entity.name = sd->name; 706 sd->entity.obj_type = MEDIA_ENTITY_TYPE_V4L2_SUBDEV; 707 sd->entity.function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; 708 #endif 709 } 710 EXPORT_SYMBOL(v4l2_subdev_init); 711 712 void v4l2_subdev_notify_event(struct v4l2_subdev *sd, 713 const struct v4l2_event *ev) 714 { 715 v4l2_event_queue(sd->devnode, ev); 716 v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT, (void *)ev); 717 } 718 EXPORT_SYMBOL_GPL(v4l2_subdev_notify_event); 719