4 * Copyright (C) 2010 Nokia Corporation
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
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.
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.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/compat.h>
24 #include <linux/export.h>
25 #include <linux/idr.h>
26 #include <linux/ioctl.h>
27 #include <linux/media.h>
28 #include <linux/slab.h>
29 #include <linux/types.h>
31 #include <media/media-device.h>
32 #include <media/media-devnode.h>
33 #include <media/media-entity.h>
35 #ifdef CONFIG_MEDIA_CONTROLLER
37 /* -----------------------------------------------------------------------------
41 static int media_device_open(struct file
*filp
)
46 static int media_device_close(struct file
*filp
)
51 static int media_device_get_info(struct media_device
*dev
,
52 struct media_device_info __user
*__info
)
54 struct media_device_info info
;
56 memset(&info
, 0, sizeof(info
));
58 strlcpy(info
.driver
, dev
->dev
->driver
->name
, sizeof(info
.driver
));
59 strlcpy(info
.model
, dev
->model
, sizeof(info
.model
));
60 strlcpy(info
.serial
, dev
->serial
, sizeof(info
.serial
));
61 strlcpy(info
.bus_info
, dev
->bus_info
, sizeof(info
.bus_info
));
63 info
.media_version
= MEDIA_API_VERSION
;
64 info
.hw_revision
= dev
->hw_revision
;
65 info
.driver_version
= dev
->driver_version
;
67 if (copy_to_user(__info
, &info
, sizeof(*__info
)))
72 static struct media_entity
*find_entity(struct media_device
*mdev
, u32 id
)
74 struct media_entity
*entity
;
75 int next
= id
& MEDIA_ENT_ID_FLAG_NEXT
;
77 id
&= ~MEDIA_ENT_ID_FLAG_NEXT
;
79 spin_lock(&mdev
->lock
);
81 media_device_for_each_entity(entity
, mdev
) {
82 if (((media_entity_id(entity
) == id
) && !next
) ||
83 ((media_entity_id(entity
) > id
) && next
)) {
84 spin_unlock(&mdev
->lock
);
89 spin_unlock(&mdev
->lock
);
94 static long media_device_enum_entities(struct media_device
*mdev
,
95 struct media_entity_desc __user
*uent
)
97 struct media_entity
*ent
;
98 struct media_entity_desc u_ent
;
100 memset(&u_ent
, 0, sizeof(u_ent
));
101 if (copy_from_user(&u_ent
.id
, &uent
->id
, sizeof(u_ent
.id
)))
104 ent
= find_entity(mdev
, u_ent
.id
);
109 u_ent
.id
= media_entity_id(ent
);
111 strlcpy(u_ent
.name
, ent
->name
, sizeof(u_ent
.name
));
112 u_ent
.type
= ent
->function
;
113 u_ent
.revision
= 0; /* Unused */
114 u_ent
.flags
= ent
->flags
;
115 u_ent
.group_id
= 0; /* Unused */
116 u_ent
.pads
= ent
->num_pads
;
117 u_ent
.links
= ent
->num_links
- ent
->num_backlinks
;
118 memcpy(&u_ent
.raw
, &ent
->info
, sizeof(ent
->info
));
119 if (copy_to_user(uent
, &u_ent
, sizeof(u_ent
)))
124 static void media_device_kpad_to_upad(const struct media_pad
*kpad
,
125 struct media_pad_desc
*upad
)
127 upad
->entity
= media_entity_id(kpad
->entity
);
128 upad
->index
= kpad
->index
;
129 upad
->flags
= kpad
->flags
;
132 static long __media_device_enum_links(struct media_device
*mdev
,
133 struct media_links_enum
*links
)
135 struct media_entity
*entity
;
137 entity
= find_entity(mdev
, links
->entity
);
144 for (p
= 0; p
< entity
->num_pads
; p
++) {
145 struct media_pad_desc pad
;
147 memset(&pad
, 0, sizeof(pad
));
148 media_device_kpad_to_upad(&entity
->pads
[p
], &pad
);
149 if (copy_to_user(&links
->pads
[p
], &pad
, sizeof(pad
)))
155 struct media_link
*link
;
156 struct media_link_desc __user
*ulink_desc
= links
->links
;
158 list_for_each_entry(link
, &entity
->links
, list
) {
159 struct media_link_desc klink_desc
;
161 /* Ignore backlinks. */
162 if (link
->source
->entity
!= entity
)
164 memset(&klink_desc
, 0, sizeof(klink_desc
));
165 media_device_kpad_to_upad(link
->source
,
167 media_device_kpad_to_upad(link
->sink
,
169 klink_desc
.flags
= link
->flags
;
170 if (copy_to_user(ulink_desc
, &klink_desc
,
171 sizeof(*ulink_desc
)))
180 static long media_device_enum_links(struct media_device
*mdev
,
181 struct media_links_enum __user
*ulinks
)
183 struct media_links_enum links
;
186 if (copy_from_user(&links
, ulinks
, sizeof(links
)))
189 rval
= __media_device_enum_links(mdev
, &links
);
193 if (copy_to_user(ulinks
, &links
, sizeof(*ulinks
)))
199 static long media_device_setup_link(struct media_device
*mdev
,
200 struct media_link_desc __user
*_ulink
)
202 struct media_link
*link
= NULL
;
203 struct media_link_desc ulink
;
204 struct media_entity
*source
;
205 struct media_entity
*sink
;
208 if (copy_from_user(&ulink
, _ulink
, sizeof(ulink
)))
211 /* Find the source and sink entities and link.
213 source
= find_entity(mdev
, ulink
.source
.entity
);
214 sink
= find_entity(mdev
, ulink
.sink
.entity
);
216 if (source
== NULL
|| sink
== NULL
)
219 if (ulink
.source
.index
>= source
->num_pads
||
220 ulink
.sink
.index
>= sink
->num_pads
)
223 link
= media_entity_find_link(&source
->pads
[ulink
.source
.index
],
224 &sink
->pads
[ulink
.sink
.index
]);
228 /* Setup the link on both entities. */
229 ret
= __media_entity_setup_link(link
, ulink
.flags
);
231 if (copy_to_user(_ulink
, &ulink
, sizeof(ulink
)))
237 #if 0 /* Let's postpone it to Kernel 4.6 */
238 static long __media_device_get_topology(struct media_device
*mdev
,
239 struct media_v2_topology
*topo
)
241 struct media_entity
*entity
;
242 struct media_interface
*intf
;
243 struct media_pad
*pad
;
244 struct media_link
*link
;
245 struct media_v2_entity kentity
, *uentity
;
246 struct media_v2_interface kintf
, *uintf
;
247 struct media_v2_pad kpad
, *upad
;
248 struct media_v2_link klink
, *ulink
;
252 topo
->topology_version
= mdev
->topology_version
;
254 /* Get entities and number of entities */
256 uentity
= media_get_uptr(topo
->ptr_entities
);
257 media_device_for_each_entity(entity
, mdev
) {
262 if (i
> topo
->num_entities
) {
267 /* Copy fields to userspace struct if not error */
268 memset(&kentity
, 0, sizeof(kentity
));
269 kentity
.id
= entity
->graph_obj
.id
;
270 kentity
.function
= entity
->function
;
271 strncpy(kentity
.name
, entity
->name
,
272 sizeof(kentity
.name
));
274 if (copy_to_user(uentity
, &kentity
, sizeof(kentity
)))
278 topo
->num_entities
= i
;
280 /* Get interfaces and number of interfaces */
282 uintf
= media_get_uptr(topo
->ptr_interfaces
);
283 media_device_for_each_intf(intf
, mdev
) {
288 if (i
> topo
->num_interfaces
) {
293 memset(&kintf
, 0, sizeof(kintf
));
295 /* Copy intf fields to userspace struct */
296 kintf
.id
= intf
->graph_obj
.id
;
297 kintf
.intf_type
= intf
->type
;
298 kintf
.flags
= intf
->flags
;
300 if (media_type(&intf
->graph_obj
) == MEDIA_GRAPH_INTF_DEVNODE
) {
301 struct media_intf_devnode
*devnode
;
303 devnode
= intf_to_devnode(intf
);
305 kintf
.devnode
.major
= devnode
->major
;
306 kintf
.devnode
.minor
= devnode
->minor
;
309 if (copy_to_user(uintf
, &kintf
, sizeof(kintf
)))
313 topo
->num_interfaces
= i
;
315 /* Get pads and number of pads */
317 upad
= media_get_uptr(topo
->ptr_pads
);
318 media_device_for_each_pad(pad
, mdev
) {
323 if (i
> topo
->num_pads
) {
328 memset(&kpad
, 0, sizeof(kpad
));
330 /* Copy pad fields to userspace struct */
331 kpad
.id
= pad
->graph_obj
.id
;
332 kpad
.entity_id
= pad
->entity
->graph_obj
.id
;
333 kpad
.flags
= pad
->flags
;
335 if (copy_to_user(upad
, &kpad
, sizeof(kpad
)))
341 /* Get links and number of links */
343 ulink
= media_get_uptr(topo
->ptr_links
);
344 media_device_for_each_link(link
, mdev
) {
345 if (link
->is_backlink
)
353 if (i
> topo
->num_links
) {
358 memset(&klink
, 0, sizeof(klink
));
360 /* Copy link fields to userspace struct */
361 klink
.id
= link
->graph_obj
.id
;
362 klink
.source_id
= link
->gobj0
->id
;
363 klink
.sink_id
= link
->gobj1
->id
;
364 klink
.flags
= link
->flags
;
366 if (copy_to_user(ulink
, &klink
, sizeof(klink
)))
375 static long media_device_get_topology(struct media_device
*mdev
,
376 struct media_v2_topology __user
*utopo
)
378 struct media_v2_topology ktopo
;
381 if (copy_from_user(&ktopo
, utopo
, sizeof(ktopo
)))
384 ret
= __media_device_get_topology(mdev
, &ktopo
);
388 if (copy_to_user(utopo
, &ktopo
, sizeof(*utopo
)))
395 static long media_device_ioctl(struct file
*filp
, unsigned int cmd
,
398 struct media_devnode
*devnode
= media_devnode_data(filp
);
399 struct media_device
*dev
= to_media_device(devnode
);
403 case MEDIA_IOC_DEVICE_INFO
:
404 ret
= media_device_get_info(dev
,
405 (struct media_device_info __user
*)arg
);
408 case MEDIA_IOC_ENUM_ENTITIES
:
409 ret
= media_device_enum_entities(dev
,
410 (struct media_entity_desc __user
*)arg
);
413 case MEDIA_IOC_ENUM_LINKS
:
414 mutex_lock(&dev
->graph_mutex
);
415 ret
= media_device_enum_links(dev
,
416 (struct media_links_enum __user
*)arg
);
417 mutex_unlock(&dev
->graph_mutex
);
420 case MEDIA_IOC_SETUP_LINK
:
421 mutex_lock(&dev
->graph_mutex
);
422 ret
= media_device_setup_link(dev
,
423 (struct media_link_desc __user
*)arg
);
424 mutex_unlock(&dev
->graph_mutex
);
427 #if 0 /* Let's postpone it to Kernel 4.6 */
428 case MEDIA_IOC_G_TOPOLOGY
:
429 mutex_lock(&dev
->graph_mutex
);
430 ret
= media_device_get_topology(dev
,
431 (struct media_v2_topology __user
*)arg
);
432 mutex_unlock(&dev
->graph_mutex
);
444 struct media_links_enum32
{
446 compat_uptr_t pads
; /* struct media_pad_desc * */
447 compat_uptr_t links
; /* struct media_link_desc * */
451 static long media_device_enum_links32(struct media_device
*mdev
,
452 struct media_links_enum32 __user
*ulinks
)
454 struct media_links_enum links
;
455 compat_uptr_t pads_ptr
, links_ptr
;
457 memset(&links
, 0, sizeof(links
));
459 if (get_user(links
.entity
, &ulinks
->entity
)
460 || get_user(pads_ptr
, &ulinks
->pads
)
461 || get_user(links_ptr
, &ulinks
->links
))
464 links
.pads
= compat_ptr(pads_ptr
);
465 links
.links
= compat_ptr(links_ptr
);
467 return __media_device_enum_links(mdev
, &links
);
470 #define MEDIA_IOC_ENUM_LINKS32 _IOWR('|', 0x02, struct media_links_enum32)
472 static long media_device_compat_ioctl(struct file
*filp
, unsigned int cmd
,
475 struct media_devnode
*devnode
= media_devnode_data(filp
);
476 struct media_device
*dev
= to_media_device(devnode
);
480 case MEDIA_IOC_DEVICE_INFO
:
481 case MEDIA_IOC_ENUM_ENTITIES
:
482 case MEDIA_IOC_SETUP_LINK
:
483 #if 0 /* Let's postpone it to Kernel 4.6 */
484 case MEDIA_IOC_G_TOPOLOGY
:
486 return media_device_ioctl(filp
, cmd
, arg
);
488 case MEDIA_IOC_ENUM_LINKS32
:
489 mutex_lock(&dev
->graph_mutex
);
490 ret
= media_device_enum_links32(dev
,
491 (struct media_links_enum32 __user
*)arg
);
492 mutex_unlock(&dev
->graph_mutex
);
501 #endif /* CONFIG_COMPAT */
503 static const struct media_file_operations media_device_fops
= {
504 .owner
= THIS_MODULE
,
505 .open
= media_device_open
,
506 .ioctl
= media_device_ioctl
,
508 .compat_ioctl
= media_device_compat_ioctl
,
509 #endif /* CONFIG_COMPAT */
510 .release
= media_device_close
,
513 /* -----------------------------------------------------------------------------
517 static ssize_t
show_model(struct device
*cd
,
518 struct device_attribute
*attr
, char *buf
)
520 struct media_device
*mdev
= to_media_device(to_media_devnode(cd
));
522 return sprintf(buf
, "%.*s\n", (int)sizeof(mdev
->model
), mdev
->model
);
525 static DEVICE_ATTR(model
, S_IRUGO
, show_model
, NULL
);
527 /* -----------------------------------------------------------------------------
528 * Registration/unregistration
531 static void media_device_release(struct media_devnode
*mdev
)
533 dev_dbg(mdev
->parent
, "Media device released\n");
537 * media_device_register_entity - Register an entity with a media device
538 * @mdev: The media device
539 * @entity: The entity
541 int __must_check
media_device_register_entity(struct media_device
*mdev
,
542 struct media_entity
*entity
)
547 if (entity
->function
== MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN
||
548 entity
->function
== MEDIA_ENT_F_UNKNOWN
)
550 "Entity type for entity %s was not initialized!\n",
553 /* Warn if we apparently re-register an entity */
554 WARN_ON(entity
->graph_obj
.mdev
!= NULL
);
555 entity
->graph_obj
.mdev
= mdev
;
556 INIT_LIST_HEAD(&entity
->links
);
557 entity
->num_links
= 0;
558 entity
->num_backlinks
= 0;
560 if (!ida_pre_get(&mdev
->entity_internal_idx
, GFP_KERNEL
))
563 spin_lock(&mdev
->lock
);
565 ret
= ida_get_new_above(&mdev
->entity_internal_idx
, 1,
566 &entity
->internal_idx
);
568 spin_unlock(&mdev
->lock
);
572 mdev
->entity_internal_idx_max
=
573 max(mdev
->entity_internal_idx_max
, entity
->internal_idx
);
575 /* Initialize media_gobj embedded at the entity */
576 media_gobj_create(mdev
, MEDIA_GRAPH_ENTITY
, &entity
->graph_obj
);
578 /* Initialize objects at the pads */
579 for (i
= 0; i
< entity
->num_pads
; i
++)
580 media_gobj_create(mdev
, MEDIA_GRAPH_PAD
,
581 &entity
->pads
[i
].graph_obj
);
583 spin_unlock(&mdev
->lock
);
587 EXPORT_SYMBOL_GPL(media_device_register_entity
);
589 static void __media_device_unregister_entity(struct media_entity
*entity
)
591 struct media_device
*mdev
= entity
->graph_obj
.mdev
;
592 struct media_link
*link
, *tmp
;
593 struct media_interface
*intf
;
596 ida_simple_remove(&mdev
->entity_internal_idx
, entity
->internal_idx
);
598 /* Remove all interface links pointing to this entity */
599 list_for_each_entry(intf
, &mdev
->interfaces
, graph_obj
.list
) {
600 list_for_each_entry_safe(link
, tmp
, &intf
->links
, list
) {
601 if (link
->entity
== entity
)
602 __media_remove_intf_link(link
);
606 /* Remove all data links that belong to this entity */
607 __media_entity_remove_links(entity
);
609 /* Remove all pads that belong to this entity */
610 for (i
= 0; i
< entity
->num_pads
; i
++)
611 media_gobj_destroy(&entity
->pads
[i
].graph_obj
);
613 /* Remove the entity */
614 media_gobj_destroy(&entity
->graph_obj
);
616 entity
->graph_obj
.mdev
= NULL
;
619 void media_device_unregister_entity(struct media_entity
*entity
)
621 struct media_device
*mdev
= entity
->graph_obj
.mdev
;
626 spin_lock(&mdev
->lock
);
627 __media_device_unregister_entity(entity
);
628 spin_unlock(&mdev
->lock
);
630 EXPORT_SYMBOL_GPL(media_device_unregister_entity
);
633 * media_device_init() - initialize a media device
634 * @mdev: The media device
636 * The caller is responsible for initializing the media device before
637 * registration. The following fields must be set:
639 * - dev must point to the parent device
640 * - model must be filled with the device model name
642 void media_device_init(struct media_device
*mdev
)
644 INIT_LIST_HEAD(&mdev
->entities
);
645 INIT_LIST_HEAD(&mdev
->interfaces
);
646 INIT_LIST_HEAD(&mdev
->pads
);
647 INIT_LIST_HEAD(&mdev
->links
);
648 spin_lock_init(&mdev
->lock
);
649 mutex_init(&mdev
->graph_mutex
);
650 ida_init(&mdev
->entity_internal_idx
);
652 dev_dbg(mdev
->dev
, "Media device initialized\n");
654 EXPORT_SYMBOL_GPL(media_device_init
);
656 void media_device_cleanup(struct media_device
*mdev
)
658 ida_destroy(&mdev
->entity_internal_idx
);
659 mdev
->entity_internal_idx_max
= 0;
660 mutex_destroy(&mdev
->graph_mutex
);
662 EXPORT_SYMBOL_GPL(media_device_cleanup
);
664 int __must_check
__media_device_register(struct media_device
*mdev
,
665 struct module
*owner
)
669 /* Register the device node. */
670 mdev
->devnode
.fops
= &media_device_fops
;
671 mdev
->devnode
.parent
= mdev
->dev
;
672 mdev
->devnode
.release
= media_device_release
;
674 /* Set version 0 to indicate user-space that the graph is static */
675 mdev
->topology_version
= 0;
677 ret
= media_devnode_register(&mdev
->devnode
, owner
);
681 ret
= device_create_file(&mdev
->devnode
.dev
, &dev_attr_model
);
683 media_devnode_unregister(&mdev
->devnode
);
687 dev_dbg(mdev
->dev
, "Media device registered\n");
691 EXPORT_SYMBOL_GPL(__media_device_register
);
693 void media_device_unregister(struct media_device
*mdev
)
695 struct media_entity
*entity
;
696 struct media_entity
*next
;
697 struct media_interface
*intf
, *tmp_intf
;
702 spin_lock(&mdev
->lock
);
704 /* Check if mdev was ever registered at all */
705 if (!media_devnode_is_registered(&mdev
->devnode
)) {
706 spin_unlock(&mdev
->lock
);
710 /* Remove all entities from the media device */
711 list_for_each_entry_safe(entity
, next
, &mdev
->entities
, graph_obj
.list
)
712 __media_device_unregister_entity(entity
);
714 /* Remove all interfaces from the media device */
715 list_for_each_entry_safe(intf
, tmp_intf
, &mdev
->interfaces
,
717 __media_remove_intf_links(intf
);
718 media_gobj_destroy(&intf
->graph_obj
);
722 spin_unlock(&mdev
->lock
);
724 device_remove_file(&mdev
->devnode
.dev
, &dev_attr_model
);
725 media_devnode_unregister(&mdev
->devnode
);
727 dev_dbg(mdev
->dev
, "Media device unregistered\n");
729 EXPORT_SYMBOL_GPL(media_device_unregister
);
731 static void media_device_release_devres(struct device
*dev
, void *res
)
735 struct media_device
*media_device_get_devres(struct device
*dev
)
737 struct media_device
*mdev
;
739 mdev
= devres_find(dev
, media_device_release_devres
, NULL
, NULL
);
743 mdev
= devres_alloc(media_device_release_devres
,
744 sizeof(struct media_device
), GFP_KERNEL
);
747 return devres_get(dev
, mdev
, NULL
, NULL
);
749 EXPORT_SYMBOL_GPL(media_device_get_devres
);
751 struct media_device
*media_device_find_devres(struct device
*dev
)
753 return devres_find(dev
, media_device_release_devres
, NULL
, NULL
);
755 EXPORT_SYMBOL_GPL(media_device_find_devres
);
757 #endif /* CONFIG_MEDIA_CONTROLLER */