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.
19 #include <linux/compat.h>
20 #include <linux/export.h>
21 #include <linux/idr.h>
22 #include <linux/ioctl.h>
23 #include <linux/media.h>
24 #include <linux/slab.h>
25 #include <linux/types.h>
26 #include <linux/pci.h>
27 #include <linux/usb.h>
28 #include <linux/version.h>
30 #include <media/media-device.h>
31 #include <media/media-devnode.h>
32 #include <media/media-entity.h>
34 #ifdef CONFIG_MEDIA_CONTROLLER
37 * Legacy defines from linux/media.h. This is the only place we need this
38 * so we just define it here. The media.h header doesn't expose it to the
39 * kernel to prevent it from being used by drivers, but here (and only here!)
40 * we need it to handle the legacy behavior.
42 #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff
43 #define MEDIA_ENT_T_DEVNODE_UNKNOWN (MEDIA_ENT_F_OLD_BASE | \
44 MEDIA_ENT_SUBTYPE_MASK)
46 /* -----------------------------------------------------------------------------
50 static inline void __user
*media_get_uptr(__u64 arg
)
52 return (void __user
*)(uintptr_t)arg
;
55 static int media_device_open(struct file
*filp
)
60 static int media_device_close(struct file
*filp
)
65 static long media_device_get_info(struct media_device
*dev
, void *arg
)
67 struct media_device_info
*info
= arg
;
69 memset(info
, 0, sizeof(*info
));
71 if (dev
->driver_name
[0])
72 strlcpy(info
->driver
, dev
->driver_name
, sizeof(info
->driver
));
74 strlcpy(info
->driver
, dev
->dev
->driver
->name
,
75 sizeof(info
->driver
));
77 strlcpy(info
->model
, dev
->model
, sizeof(info
->model
));
78 strlcpy(info
->serial
, dev
->serial
, sizeof(info
->serial
));
79 strlcpy(info
->bus_info
, dev
->bus_info
, sizeof(info
->bus_info
));
81 info
->media_version
= LINUX_VERSION_CODE
;
82 info
->driver_version
= info
->media_version
;
83 info
->hw_revision
= dev
->hw_revision
;
88 static struct media_entity
*find_entity(struct media_device
*mdev
, u32 id
)
90 struct media_entity
*entity
;
91 int next
= id
& MEDIA_ENT_ID_FLAG_NEXT
;
93 id
&= ~MEDIA_ENT_ID_FLAG_NEXT
;
95 media_device_for_each_entity(entity
, mdev
) {
96 if (((media_entity_id(entity
) == id
) && !next
) ||
97 ((media_entity_id(entity
) > id
) && next
)) {
105 static long media_device_enum_entities(struct media_device
*mdev
, void *arg
)
107 struct media_entity_desc
*entd
= arg
;
108 struct media_entity
*ent
;
110 ent
= find_entity(mdev
, entd
->id
);
114 memset(entd
, 0, sizeof(*entd
));
116 entd
->id
= media_entity_id(ent
);
118 strlcpy(entd
->name
, ent
->name
, sizeof(entd
->name
));
119 entd
->type
= ent
->function
;
120 entd
->revision
= 0; /* Unused */
121 entd
->flags
= ent
->flags
;
122 entd
->group_id
= 0; /* Unused */
123 entd
->pads
= ent
->num_pads
;
124 entd
->links
= ent
->num_links
- ent
->num_backlinks
;
127 * Workaround for a bug at media-ctl <= v1.10 that makes it to
128 * do the wrong thing if the entity function doesn't belong to
129 * either MEDIA_ENT_F_OLD_BASE or MEDIA_ENT_F_OLD_SUBDEV_BASE
132 * Non-subdevices are expected to be at the MEDIA_ENT_F_OLD_BASE,
133 * or, otherwise, will be silently ignored by media-ctl when
134 * printing the graphviz diagram. So, map them into the devnode
137 if (ent
->function
< MEDIA_ENT_F_OLD_BASE
||
138 ent
->function
> MEDIA_ENT_F_TUNER
) {
139 if (is_media_entity_v4l2_subdev(ent
))
140 entd
->type
= MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN
;
141 else if (ent
->function
!= MEDIA_ENT_F_IO_V4L
)
142 entd
->type
= MEDIA_ENT_T_DEVNODE_UNKNOWN
;
145 memcpy(&entd
->raw
, &ent
->info
, sizeof(ent
->info
));
150 static void media_device_kpad_to_upad(const struct media_pad
*kpad
,
151 struct media_pad_desc
*upad
)
153 upad
->entity
= media_entity_id(kpad
->entity
);
154 upad
->index
= kpad
->index
;
155 upad
->flags
= kpad
->flags
;
158 static long media_device_enum_links(struct media_device
*mdev
, void *arg
)
160 struct media_links_enum
*links
= arg
;
161 struct media_entity
*entity
;
163 entity
= find_entity(mdev
, links
->entity
);
170 for (p
= 0; p
< entity
->num_pads
; p
++) {
171 struct media_pad_desc pad
;
173 memset(&pad
, 0, sizeof(pad
));
174 media_device_kpad_to_upad(&entity
->pads
[p
], &pad
);
175 if (copy_to_user(&links
->pads
[p
], &pad
, sizeof(pad
)))
181 struct media_link
*link
;
182 struct media_link_desc __user
*ulink_desc
= links
->links
;
184 list_for_each_entry(link
, &entity
->links
, list
) {
185 struct media_link_desc klink_desc
;
187 /* Ignore backlinks. */
188 if (link
->source
->entity
!= entity
)
190 memset(&klink_desc
, 0, sizeof(klink_desc
));
191 media_device_kpad_to_upad(link
->source
,
193 media_device_kpad_to_upad(link
->sink
,
195 klink_desc
.flags
= link
->flags
;
196 if (copy_to_user(ulink_desc
, &klink_desc
,
197 sizeof(*ulink_desc
)))
202 memset(links
->reserved
, 0, sizeof(links
->reserved
));
207 static long media_device_setup_link(struct media_device
*mdev
, void *arg
)
209 struct media_link_desc
*linkd
= arg
;
210 struct media_link
*link
= NULL
;
211 struct media_entity
*source
;
212 struct media_entity
*sink
;
214 /* Find the source and sink entities and link.
216 source
= find_entity(mdev
, linkd
->source
.entity
);
217 sink
= find_entity(mdev
, linkd
->sink
.entity
);
219 if (source
== NULL
|| sink
== NULL
)
222 if (linkd
->source
.index
>= source
->num_pads
||
223 linkd
->sink
.index
>= sink
->num_pads
)
226 link
= media_entity_find_link(&source
->pads
[linkd
->source
.index
],
227 &sink
->pads
[linkd
->sink
.index
]);
231 memset(linkd
->reserved
, 0, sizeof(linkd
->reserved
));
233 /* Setup the link on both entities. */
234 return __media_entity_setup_link(link
, linkd
->flags
);
237 static long media_device_get_topology(struct media_device
*mdev
, void *arg
)
239 struct media_v2_topology
*topo
= arg
;
240 struct media_entity
*entity
;
241 struct media_interface
*intf
;
242 struct media_pad
*pad
;
243 struct media_link
*link
;
244 struct media_v2_entity kentity
, __user
*uentity
;
245 struct media_v2_interface kintf
, __user
*uintf
;
246 struct media_v2_pad kpad
, __user
*upad
;
247 struct media_v2_link klink
, __user
*ulink
;
251 topo
->topology_version
= mdev
->topology_version
;
253 /* Get entities and number of entities */
255 uentity
= media_get_uptr(topo
->ptr_entities
);
256 media_device_for_each_entity(entity
, mdev
) {
261 if (i
> topo
->num_entities
) {
266 /* Copy fields to userspace struct if not error */
267 memset(&kentity
, 0, sizeof(kentity
));
268 kentity
.id
= entity
->graph_obj
.id
;
269 kentity
.function
= entity
->function
;
270 kentity
.flags
= entity
->flags
;
271 strlcpy(kentity
.name
, entity
->name
,
272 sizeof(kentity
.name
));
274 if (copy_to_user(uentity
, &kentity
, sizeof(kentity
)))
278 topo
->num_entities
= i
;
281 /* Get interfaces and number of interfaces */
283 uintf
= media_get_uptr(topo
->ptr_interfaces
);
284 media_device_for_each_intf(intf
, mdev
) {
289 if (i
> topo
->num_interfaces
) {
294 memset(&kintf
, 0, sizeof(kintf
));
296 /* Copy intf fields to userspace struct */
297 kintf
.id
= intf
->graph_obj
.id
;
298 kintf
.intf_type
= intf
->type
;
299 kintf
.flags
= intf
->flags
;
301 if (media_type(&intf
->graph_obj
) == MEDIA_GRAPH_INTF_DEVNODE
) {
302 struct media_intf_devnode
*devnode
;
304 devnode
= intf_to_devnode(intf
);
306 kintf
.devnode
.major
= devnode
->major
;
307 kintf
.devnode
.minor
= devnode
->minor
;
310 if (copy_to_user(uintf
, &kintf
, sizeof(kintf
)))
314 topo
->num_interfaces
= i
;
317 /* Get pads and number of pads */
319 upad
= media_get_uptr(topo
->ptr_pads
);
320 media_device_for_each_pad(pad
, mdev
) {
325 if (i
> topo
->num_pads
) {
330 memset(&kpad
, 0, sizeof(kpad
));
332 /* Copy pad fields to userspace struct */
333 kpad
.id
= pad
->graph_obj
.id
;
334 kpad
.entity_id
= pad
->entity
->graph_obj
.id
;
335 kpad
.flags
= pad
->flags
;
336 kpad
.index
= pad
->index
;
338 if (copy_to_user(upad
, &kpad
, sizeof(kpad
)))
345 /* Get links and number of links */
347 ulink
= media_get_uptr(topo
->ptr_links
);
348 media_device_for_each_link(link
, mdev
) {
349 if (link
->is_backlink
)
357 if (i
> topo
->num_links
) {
362 memset(&klink
, 0, sizeof(klink
));
364 /* Copy link fields to userspace struct */
365 klink
.id
= link
->graph_obj
.id
;
366 klink
.source_id
= link
->gobj0
->id
;
367 klink
.sink_id
= link
->gobj1
->id
;
368 klink
.flags
= link
->flags
;
370 if (copy_to_user(ulink
, &klink
, sizeof(klink
)))
380 static long copy_arg_from_user(void *karg
, void __user
*uarg
, unsigned int cmd
)
382 /* All media IOCTLs are _IOWR() */
383 if (copy_from_user(karg
, uarg
, _IOC_SIZE(cmd
)))
389 static long copy_arg_to_user(void __user
*uarg
, void *karg
, unsigned int cmd
)
391 /* All media IOCTLs are _IOWR() */
392 if (copy_to_user(uarg
, karg
, _IOC_SIZE(cmd
)))
398 /* Do acquire the graph mutex */
399 #define MEDIA_IOC_FL_GRAPH_MUTEX BIT(0)
401 #define MEDIA_IOC_ARG(__cmd, func, fl, from_user, to_user) \
402 [_IOC_NR(MEDIA_IOC_##__cmd)] = { \
403 .cmd = MEDIA_IOC_##__cmd, \
404 .fn = (long (*)(struct media_device *, void *))func, \
406 .arg_from_user = from_user, \
407 .arg_to_user = to_user, \
410 #define MEDIA_IOC(__cmd, func, fl) \
411 MEDIA_IOC_ARG(__cmd, func, fl, copy_arg_from_user, copy_arg_to_user)
413 /* the table is indexed by _IOC_NR(cmd) */
414 struct media_ioctl_info
{
416 unsigned short flags
;
417 long (*fn
)(struct media_device
*dev
, void *arg
);
418 long (*arg_from_user
)(void *karg
, void __user
*uarg
, unsigned int cmd
);
419 long (*arg_to_user
)(void __user
*uarg
, void *karg
, unsigned int cmd
);
422 static const struct media_ioctl_info ioctl_info
[] = {
423 MEDIA_IOC(DEVICE_INFO
, media_device_get_info
, MEDIA_IOC_FL_GRAPH_MUTEX
),
424 MEDIA_IOC(ENUM_ENTITIES
, media_device_enum_entities
, MEDIA_IOC_FL_GRAPH_MUTEX
),
425 MEDIA_IOC(ENUM_LINKS
, media_device_enum_links
, MEDIA_IOC_FL_GRAPH_MUTEX
),
426 MEDIA_IOC(SETUP_LINK
, media_device_setup_link
, MEDIA_IOC_FL_GRAPH_MUTEX
),
427 MEDIA_IOC(G_TOPOLOGY
, media_device_get_topology
, MEDIA_IOC_FL_GRAPH_MUTEX
),
430 static long media_device_ioctl(struct file
*filp
, unsigned int cmd
,
433 struct media_devnode
*devnode
= media_devnode_data(filp
);
434 struct media_device
*dev
= devnode
->media_dev
;
435 const struct media_ioctl_info
*info
;
436 void __user
*arg
= (void __user
*)__arg
;
437 char __karg
[256], *karg
= __karg
;
440 if (_IOC_NR(cmd
) >= ARRAY_SIZE(ioctl_info
)
441 || ioctl_info
[_IOC_NR(cmd
)].cmd
!= cmd
)
444 info
= &ioctl_info
[_IOC_NR(cmd
)];
446 if (_IOC_SIZE(info
->cmd
) > sizeof(__karg
)) {
447 karg
= kmalloc(_IOC_SIZE(info
->cmd
), GFP_KERNEL
);
452 if (info
->arg_from_user
) {
453 ret
= info
->arg_from_user(karg
, arg
, cmd
);
458 if (info
->flags
& MEDIA_IOC_FL_GRAPH_MUTEX
)
459 mutex_lock(&dev
->graph_mutex
);
461 ret
= info
->fn(dev
, karg
);
463 if (info
->flags
& MEDIA_IOC_FL_GRAPH_MUTEX
)
464 mutex_unlock(&dev
->graph_mutex
);
466 if (!ret
&& info
->arg_to_user
)
467 ret
= info
->arg_to_user(arg
, karg
, cmd
);
478 struct media_links_enum32
{
480 compat_uptr_t pads
; /* struct media_pad_desc * */
481 compat_uptr_t links
; /* struct media_link_desc * */
485 static long media_device_enum_links32(struct media_device
*mdev
,
486 struct media_links_enum32 __user
*ulinks
)
488 struct media_links_enum links
;
489 compat_uptr_t pads_ptr
, links_ptr
;
492 memset(&links
, 0, sizeof(links
));
494 if (get_user(links
.entity
, &ulinks
->entity
)
495 || get_user(pads_ptr
, &ulinks
->pads
)
496 || get_user(links_ptr
, &ulinks
->links
))
499 links
.pads
= compat_ptr(pads_ptr
);
500 links
.links
= compat_ptr(links_ptr
);
502 ret
= media_device_enum_links(mdev
, &links
);
506 if (copy_to_user(ulinks
->reserved
, links
.reserved
,
507 sizeof(ulinks
->reserved
)))
512 #define MEDIA_IOC_ENUM_LINKS32 _IOWR('|', 0x02, struct media_links_enum32)
514 static long media_device_compat_ioctl(struct file
*filp
, unsigned int cmd
,
517 struct media_devnode
*devnode
= media_devnode_data(filp
);
518 struct media_device
*dev
= devnode
->media_dev
;
522 case MEDIA_IOC_ENUM_LINKS32
:
523 mutex_lock(&dev
->graph_mutex
);
524 ret
= media_device_enum_links32(dev
,
525 (struct media_links_enum32 __user
*)arg
);
526 mutex_unlock(&dev
->graph_mutex
);
530 return media_device_ioctl(filp
, cmd
, arg
);
535 #endif /* CONFIG_COMPAT */
537 static const struct media_file_operations media_device_fops
= {
538 .owner
= THIS_MODULE
,
539 .open
= media_device_open
,
540 .ioctl
= media_device_ioctl
,
542 .compat_ioctl
= media_device_compat_ioctl
,
543 #endif /* CONFIG_COMPAT */
544 .release
= media_device_close
,
547 /* -----------------------------------------------------------------------------
551 static ssize_t
show_model(struct device
*cd
,
552 struct device_attribute
*attr
, char *buf
)
554 struct media_devnode
*devnode
= to_media_devnode(cd
);
555 struct media_device
*mdev
= devnode
->media_dev
;
557 return sprintf(buf
, "%.*s\n", (int)sizeof(mdev
->model
), mdev
->model
);
560 static DEVICE_ATTR(model
, S_IRUGO
, show_model
, NULL
);
562 /* -----------------------------------------------------------------------------
563 * Registration/unregistration
566 static void media_device_release(struct media_devnode
*devnode
)
568 dev_dbg(devnode
->parent
, "Media device released\n");
572 * media_device_register_entity - Register an entity with a media device
573 * @mdev: The media device
574 * @entity: The entity
576 int __must_check
media_device_register_entity(struct media_device
*mdev
,
577 struct media_entity
*entity
)
579 struct media_entity_notify
*notify
, *next
;
583 if (entity
->function
== MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN
||
584 entity
->function
== MEDIA_ENT_F_UNKNOWN
)
586 "Entity type for entity %s was not initialized!\n",
589 /* Warn if we apparently re-register an entity */
590 WARN_ON(entity
->graph_obj
.mdev
!= NULL
);
591 entity
->graph_obj
.mdev
= mdev
;
592 INIT_LIST_HEAD(&entity
->links
);
593 entity
->num_links
= 0;
594 entity
->num_backlinks
= 0;
596 ret
= ida_alloc_min(&mdev
->entity_internal_idx
, 1, GFP_KERNEL
);
599 entity
->internal_idx
= ret
;
601 mutex_lock(&mdev
->graph_mutex
);
602 mdev
->entity_internal_idx_max
=
603 max(mdev
->entity_internal_idx_max
, entity
->internal_idx
);
605 /* Initialize media_gobj embedded at the entity */
606 media_gobj_create(mdev
, MEDIA_GRAPH_ENTITY
, &entity
->graph_obj
);
608 /* Initialize objects at the pads */
609 for (i
= 0; i
< entity
->num_pads
; i
++)
610 media_gobj_create(mdev
, MEDIA_GRAPH_PAD
,
611 &entity
->pads
[i
].graph_obj
);
613 /* invoke entity_notify callbacks */
614 list_for_each_entry_safe(notify
, next
, &mdev
->entity_notify
, list
)
615 notify
->notify(entity
, notify
->notify_data
);
617 if (mdev
->entity_internal_idx_max
618 >= mdev
->pm_count_walk
.ent_enum
.idx_max
) {
619 struct media_graph
new = { .top
= 0 };
622 * Initialise the new graph walk before cleaning up
623 * the old one in order not to spoil the graph walk
624 * object of the media device if graph walk init fails.
626 ret
= media_graph_walk_init(&new, mdev
);
628 mutex_unlock(&mdev
->graph_mutex
);
631 media_graph_walk_cleanup(&mdev
->pm_count_walk
);
632 mdev
->pm_count_walk
= new;
634 mutex_unlock(&mdev
->graph_mutex
);
638 EXPORT_SYMBOL_GPL(media_device_register_entity
);
640 static void __media_device_unregister_entity(struct media_entity
*entity
)
642 struct media_device
*mdev
= entity
->graph_obj
.mdev
;
643 struct media_link
*link
, *tmp
;
644 struct media_interface
*intf
;
647 ida_free(&mdev
->entity_internal_idx
, entity
->internal_idx
);
649 /* Remove all interface links pointing to this entity */
650 list_for_each_entry(intf
, &mdev
->interfaces
, graph_obj
.list
) {
651 list_for_each_entry_safe(link
, tmp
, &intf
->links
, list
) {
652 if (link
->entity
== entity
)
653 __media_remove_intf_link(link
);
657 /* Remove all data links that belong to this entity */
658 __media_entity_remove_links(entity
);
660 /* Remove all pads that belong to this entity */
661 for (i
= 0; i
< entity
->num_pads
; i
++)
662 media_gobj_destroy(&entity
->pads
[i
].graph_obj
);
664 /* Remove the entity */
665 media_gobj_destroy(&entity
->graph_obj
);
667 /* invoke entity_notify callbacks to handle entity removal?? */
669 entity
->graph_obj
.mdev
= NULL
;
672 void media_device_unregister_entity(struct media_entity
*entity
)
674 struct media_device
*mdev
= entity
->graph_obj
.mdev
;
679 mutex_lock(&mdev
->graph_mutex
);
680 __media_device_unregister_entity(entity
);
681 mutex_unlock(&mdev
->graph_mutex
);
683 EXPORT_SYMBOL_GPL(media_device_unregister_entity
);
686 * media_device_init() - initialize a media device
687 * @mdev: The media device
689 * The caller is responsible for initializing the media device before
690 * registration. The following fields must be set:
692 * - dev must point to the parent device
693 * - model must be filled with the device model name
695 void media_device_init(struct media_device
*mdev
)
697 INIT_LIST_HEAD(&mdev
->entities
);
698 INIT_LIST_HEAD(&mdev
->interfaces
);
699 INIT_LIST_HEAD(&mdev
->pads
);
700 INIT_LIST_HEAD(&mdev
->links
);
701 INIT_LIST_HEAD(&mdev
->entity_notify
);
702 mutex_init(&mdev
->graph_mutex
);
703 ida_init(&mdev
->entity_internal_idx
);
705 dev_dbg(mdev
->dev
, "Media device initialized\n");
707 EXPORT_SYMBOL_GPL(media_device_init
);
709 void media_device_cleanup(struct media_device
*mdev
)
711 ida_destroy(&mdev
->entity_internal_idx
);
712 mdev
->entity_internal_idx_max
= 0;
713 media_graph_walk_cleanup(&mdev
->pm_count_walk
);
714 mutex_destroy(&mdev
->graph_mutex
);
716 EXPORT_SYMBOL_GPL(media_device_cleanup
);
718 int __must_check
__media_device_register(struct media_device
*mdev
,
719 struct module
*owner
)
721 struct media_devnode
*devnode
;
724 devnode
= kzalloc(sizeof(*devnode
), GFP_KERNEL
);
728 /* Register the device node. */
729 mdev
->devnode
= devnode
;
730 devnode
->fops
= &media_device_fops
;
731 devnode
->parent
= mdev
->dev
;
732 devnode
->release
= media_device_release
;
734 /* Set version 0 to indicate user-space that the graph is static */
735 mdev
->topology_version
= 0;
737 ret
= media_devnode_register(mdev
, devnode
, owner
);
739 /* devnode free is handled in media_devnode_*() */
740 mdev
->devnode
= NULL
;
744 ret
= device_create_file(&devnode
->dev
, &dev_attr_model
);
746 /* devnode free is handled in media_devnode_*() */
747 mdev
->devnode
= NULL
;
748 media_devnode_unregister_prepare(devnode
);
749 media_devnode_unregister(devnode
);
753 dev_dbg(mdev
->dev
, "Media device registered\n");
757 EXPORT_SYMBOL_GPL(__media_device_register
);
759 int __must_check
media_device_register_entity_notify(struct media_device
*mdev
,
760 struct media_entity_notify
*nptr
)
762 mutex_lock(&mdev
->graph_mutex
);
763 list_add_tail(&nptr
->list
, &mdev
->entity_notify
);
764 mutex_unlock(&mdev
->graph_mutex
);
767 EXPORT_SYMBOL_GPL(media_device_register_entity_notify
);
770 * Note: Should be called with mdev->lock held.
772 static void __media_device_unregister_entity_notify(struct media_device
*mdev
,
773 struct media_entity_notify
*nptr
)
775 list_del(&nptr
->list
);
778 void media_device_unregister_entity_notify(struct media_device
*mdev
,
779 struct media_entity_notify
*nptr
)
781 mutex_lock(&mdev
->graph_mutex
);
782 __media_device_unregister_entity_notify(mdev
, nptr
);
783 mutex_unlock(&mdev
->graph_mutex
);
785 EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify
);
787 void media_device_unregister(struct media_device
*mdev
)
789 struct media_entity
*entity
;
790 struct media_entity
*next
;
791 struct media_interface
*intf
, *tmp_intf
;
792 struct media_entity_notify
*notify
, *nextp
;
797 mutex_lock(&mdev
->graph_mutex
);
799 /* Check if mdev was ever registered at all */
800 if (!media_devnode_is_registered(mdev
->devnode
)) {
801 mutex_unlock(&mdev
->graph_mutex
);
805 /* Clear the devnode register bit to avoid races with media dev open */
806 media_devnode_unregister_prepare(mdev
->devnode
);
808 /* Remove all entities from the media device */
809 list_for_each_entry_safe(entity
, next
, &mdev
->entities
, graph_obj
.list
)
810 __media_device_unregister_entity(entity
);
812 /* Remove all entity_notify callbacks from the media device */
813 list_for_each_entry_safe(notify
, nextp
, &mdev
->entity_notify
, list
)
814 __media_device_unregister_entity_notify(mdev
, notify
);
816 /* Remove all interfaces from the media device */
817 list_for_each_entry_safe(intf
, tmp_intf
, &mdev
->interfaces
,
820 * Unlink the interface, but don't free it here; the
821 * module which created it is responsible for freeing
824 __media_remove_intf_links(intf
);
825 media_gobj_destroy(&intf
->graph_obj
);
828 mutex_unlock(&mdev
->graph_mutex
);
830 dev_dbg(mdev
->dev
, "Media device unregistered\n");
832 device_remove_file(&mdev
->devnode
->dev
, &dev_attr_model
);
833 media_devnode_unregister(mdev
->devnode
);
834 /* devnode free is handled in media_devnode_*() */
835 mdev
->devnode
= NULL
;
837 EXPORT_SYMBOL_GPL(media_device_unregister
);
839 #if IS_ENABLED(CONFIG_PCI)
840 void media_device_pci_init(struct media_device
*mdev
,
841 struct pci_dev
*pci_dev
,
844 mdev
->dev
= &pci_dev
->dev
;
847 strlcpy(mdev
->model
, name
, sizeof(mdev
->model
));
849 strlcpy(mdev
->model
, pci_name(pci_dev
), sizeof(mdev
->model
));
851 sprintf(mdev
->bus_info
, "PCI:%s", pci_name(pci_dev
));
853 mdev
->hw_revision
= (pci_dev
->subsystem_vendor
<< 16)
854 | pci_dev
->subsystem_device
;
856 media_device_init(mdev
);
858 EXPORT_SYMBOL_GPL(media_device_pci_init
);
861 #if IS_ENABLED(CONFIG_USB)
862 void __media_device_usb_init(struct media_device
*mdev
,
863 struct usb_device
*udev
,
864 const char *board_name
,
865 const char *driver_name
)
867 mdev
->dev
= &udev
->dev
;
870 strlcpy(mdev
->driver_name
, driver_name
,
871 sizeof(mdev
->driver_name
));
874 strlcpy(mdev
->model
, board_name
, sizeof(mdev
->model
));
875 else if (udev
->product
)
876 strlcpy(mdev
->model
, udev
->product
, sizeof(mdev
->model
));
878 strlcpy(mdev
->model
, "unknown model", sizeof(mdev
->model
));
880 strlcpy(mdev
->serial
, udev
->serial
, sizeof(mdev
->serial
));
881 usb_make_path(udev
, mdev
->bus_info
, sizeof(mdev
->bus_info
));
882 mdev
->hw_revision
= le16_to_cpu(udev
->descriptor
.bcdDevice
);
884 media_device_init(mdev
);
886 EXPORT_SYMBOL_GPL(__media_device_usb_init
);
890 #endif /* CONFIG_MEDIA_CONTROLLER */