Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / drivers / media / media-device.c
1 /*
2  * Media device
3  *
4  * Copyright (C) 2010 Nokia Corporation
5  *
6  * Contacts: 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  * 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
21  */
22
23 /* We need to access legacy defines from linux/media.h */
24 #define __NEED_MEDIA_LEGACY_API
25
26 #include <linux/compat.h>
27 #include <linux/export.h>
28 #include <linux/idr.h>
29 #include <linux/ioctl.h>
30 #include <linux/media.h>
31 #include <linux/slab.h>
32 #include <linux/types.h>
33 #include <linux/pci.h>
34 #include <linux/usb.h>
35
36 #include <media/media-device.h>
37 #include <media/media-devnode.h>
38 #include <media/media-entity.h>
39
40 #ifdef CONFIG_MEDIA_CONTROLLER
41
42 /* -----------------------------------------------------------------------------
43  * Userspace API
44  */
45
46 static inline void __user *media_get_uptr(__u64 arg)
47 {
48         return (void __user *)(uintptr_t)arg;
49 }
50
51 static int media_device_open(struct file *filp)
52 {
53         return 0;
54 }
55
56 static int media_device_close(struct file *filp)
57 {
58         return 0;
59 }
60
61 static int media_device_get_info(struct media_device *dev,
62                                  struct media_device_info *info)
63 {
64         memset(info, 0, sizeof(*info));
65
66         if (dev->driver_name[0])
67                 strlcpy(info->driver, dev->driver_name, sizeof(info->driver));
68         else
69                 strlcpy(info->driver, dev->dev->driver->name,
70                         sizeof(info->driver));
71
72         strlcpy(info->model, dev->model, sizeof(info->model));
73         strlcpy(info->serial, dev->serial, sizeof(info->serial));
74         strlcpy(info->bus_info, dev->bus_info, sizeof(info->bus_info));
75
76         info->media_version = MEDIA_API_VERSION;
77         info->hw_revision = dev->hw_revision;
78         info->driver_version = dev->driver_version;
79
80         return 0;
81 }
82
83 static struct media_entity *find_entity(struct media_device *mdev, u32 id)
84 {
85         struct media_entity *entity;
86         int next = id & MEDIA_ENT_ID_FLAG_NEXT;
87
88         id &= ~MEDIA_ENT_ID_FLAG_NEXT;
89
90         media_device_for_each_entity(entity, mdev) {
91                 if (((media_entity_id(entity) == id) && !next) ||
92                     ((media_entity_id(entity) > id) && next)) {
93                         return entity;
94                 }
95         }
96
97         return NULL;
98 }
99
100 static long media_device_enum_entities(struct media_device *mdev,
101                                        struct media_entity_desc *entd)
102 {
103         struct media_entity *ent;
104
105         ent = find_entity(mdev, entd->id);
106         if (ent == NULL)
107                 return -EINVAL;
108
109         memset(entd, 0, sizeof(*entd));
110
111         entd->id = media_entity_id(ent);
112         if (ent->name)
113                 strlcpy(entd->name, ent->name, sizeof(entd->name));
114         entd->type = ent->function;
115         entd->revision = 0;             /* Unused */
116         entd->flags = ent->flags;
117         entd->group_id = 0;             /* Unused */
118         entd->pads = ent->num_pads;
119         entd->links = ent->num_links - ent->num_backlinks;
120
121         /*
122          * Workaround for a bug at media-ctl <= v1.10 that makes it to
123          * do the wrong thing if the entity function doesn't belong to
124          * either MEDIA_ENT_F_OLD_BASE or MEDIA_ENT_F_OLD_SUBDEV_BASE
125          * Ranges.
126          *
127          * Non-subdevices are expected to be at the MEDIA_ENT_F_OLD_BASE,
128          * or, otherwise, will be silently ignored by media-ctl when
129          * printing the graphviz diagram. So, map them into the devnode
130          * old range.
131          */
132         if (ent->function < MEDIA_ENT_F_OLD_BASE ||
133             ent->function > MEDIA_ENT_T_DEVNODE_UNKNOWN) {
134                 if (is_media_entity_v4l2_subdev(ent))
135                         entd->type = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
136                 else if (ent->function != MEDIA_ENT_F_IO_V4L)
137                         entd->type = MEDIA_ENT_T_DEVNODE_UNKNOWN;
138         }
139
140         memcpy(&entd->raw, &ent->info, sizeof(ent->info));
141
142         return 0;
143 }
144
145 static void media_device_kpad_to_upad(const struct media_pad *kpad,
146                                       struct media_pad_desc *upad)
147 {
148         upad->entity = media_entity_id(kpad->entity);
149         upad->index = kpad->index;
150         upad->flags = kpad->flags;
151 }
152
153 static long media_device_enum_links(struct media_device *mdev,
154                                     struct media_links_enum *links)
155 {
156         struct media_entity *entity;
157
158         entity = find_entity(mdev, links->entity);
159         if (entity == NULL)
160                 return -EINVAL;
161
162         if (links->pads) {
163                 unsigned int p;
164
165                 for (p = 0; p < entity->num_pads; p++) {
166                         struct media_pad_desc pad;
167
168                         memset(&pad, 0, sizeof(pad));
169                         media_device_kpad_to_upad(&entity->pads[p], &pad);
170                         if (copy_to_user(&links->pads[p], &pad, sizeof(pad)))
171                                 return -EFAULT;
172                 }
173         }
174
175         if (links->links) {
176                 struct media_link *link;
177                 struct media_link_desc __user *ulink_desc = links->links;
178
179                 list_for_each_entry(link, &entity->links, list) {
180                         struct media_link_desc klink_desc;
181
182                         /* Ignore backlinks. */
183                         if (link->source->entity != entity)
184                                 continue;
185                         memset(&klink_desc, 0, sizeof(klink_desc));
186                         media_device_kpad_to_upad(link->source,
187                                                   &klink_desc.source);
188                         media_device_kpad_to_upad(link->sink,
189                                                   &klink_desc.sink);
190                         klink_desc.flags = link->flags;
191                         if (copy_to_user(ulink_desc, &klink_desc,
192                                          sizeof(*ulink_desc)))
193                                 return -EFAULT;
194                         ulink_desc++;
195                 }
196         }
197
198         return 0;
199 }
200
201 static long media_device_setup_link(struct media_device *mdev,
202                                     struct media_link_desc *linkd)
203 {
204         struct media_link *link = NULL;
205         struct media_entity *source;
206         struct media_entity *sink;
207
208         /* Find the source and sink entities and link.
209          */
210         source = find_entity(mdev, linkd->source.entity);
211         sink = find_entity(mdev, linkd->sink.entity);
212
213         if (source == NULL || sink == NULL)
214                 return -EINVAL;
215
216         if (linkd->source.index >= source->num_pads ||
217             linkd->sink.index >= sink->num_pads)
218                 return -EINVAL;
219
220         link = media_entity_find_link(&source->pads[linkd->source.index],
221                                       &sink->pads[linkd->sink.index]);
222         if (link == NULL)
223                 return -EINVAL;
224
225         /* Setup the link on both entities. */
226         return __media_entity_setup_link(link, linkd->flags);
227 }
228
229 static long media_device_get_topology(struct media_device *mdev,
230                                       struct media_v2_topology *topo)
231 {
232         struct media_entity *entity;
233         struct media_interface *intf;
234         struct media_pad *pad;
235         struct media_link *link;
236         struct media_v2_entity kentity, __user *uentity;
237         struct media_v2_interface kintf, __user *uintf;
238         struct media_v2_pad kpad, __user *upad;
239         struct media_v2_link klink, __user *ulink;
240         unsigned int i;
241         int ret = 0;
242
243         topo->topology_version = mdev->topology_version;
244
245         /* Get entities and number of entities */
246         i = 0;
247         uentity = media_get_uptr(topo->ptr_entities);
248         media_device_for_each_entity(entity, mdev) {
249                 i++;
250                 if (ret || !uentity)
251                         continue;
252
253                 if (i > topo->num_entities) {
254                         ret = -ENOSPC;
255                         continue;
256                 }
257
258                 /* Copy fields to userspace struct if not error */
259                 memset(&kentity, 0, sizeof(kentity));
260                 kentity.id = entity->graph_obj.id;
261                 kentity.function = entity->function;
262                 strncpy(kentity.name, entity->name,
263                         sizeof(kentity.name));
264
265                 if (copy_to_user(uentity, &kentity, sizeof(kentity)))
266                         ret = -EFAULT;
267                 uentity++;
268         }
269         topo->num_entities = i;
270
271         /* Get interfaces and number of interfaces */
272         i = 0;
273         uintf = media_get_uptr(topo->ptr_interfaces);
274         media_device_for_each_intf(intf, mdev) {
275                 i++;
276                 if (ret || !uintf)
277                         continue;
278
279                 if (i > topo->num_interfaces) {
280                         ret = -ENOSPC;
281                         continue;
282                 }
283
284                 memset(&kintf, 0, sizeof(kintf));
285
286                 /* Copy intf fields to userspace struct */
287                 kintf.id = intf->graph_obj.id;
288                 kintf.intf_type = intf->type;
289                 kintf.flags = intf->flags;
290
291                 if (media_type(&intf->graph_obj) == MEDIA_GRAPH_INTF_DEVNODE) {
292                         struct media_intf_devnode *devnode;
293
294                         devnode = intf_to_devnode(intf);
295
296                         kintf.devnode.major = devnode->major;
297                         kintf.devnode.minor = devnode->minor;
298                 }
299
300                 if (copy_to_user(uintf, &kintf, sizeof(kintf)))
301                         ret = -EFAULT;
302                 uintf++;
303         }
304         topo->num_interfaces = i;
305
306         /* Get pads and number of pads */
307         i = 0;
308         upad = media_get_uptr(topo->ptr_pads);
309         media_device_for_each_pad(pad, mdev) {
310                 i++;
311                 if (ret || !upad)
312                         continue;
313
314                 if (i > topo->num_pads) {
315                         ret = -ENOSPC;
316                         continue;
317                 }
318
319                 memset(&kpad, 0, sizeof(kpad));
320
321                 /* Copy pad fields to userspace struct */
322                 kpad.id = pad->graph_obj.id;
323                 kpad.entity_id = pad->entity->graph_obj.id;
324                 kpad.flags = pad->flags;
325
326                 if (copy_to_user(upad, &kpad, sizeof(kpad)))
327                         ret = -EFAULT;
328                 upad++;
329         }
330         topo->num_pads = i;
331
332         /* Get links and number of links */
333         i = 0;
334         ulink = media_get_uptr(topo->ptr_links);
335         media_device_for_each_link(link, mdev) {
336                 if (link->is_backlink)
337                         continue;
338
339                 i++;
340
341                 if (ret || !ulink)
342                         continue;
343
344                 if (i > topo->num_links) {
345                         ret = -ENOSPC;
346                         continue;
347                 }
348
349                 memset(&klink, 0, sizeof(klink));
350
351                 /* Copy link fields to userspace struct */
352                 klink.id = link->graph_obj.id;
353                 klink.source_id = link->gobj0->id;
354                 klink.sink_id = link->gobj1->id;
355                 klink.flags = link->flags;
356
357                 if (copy_to_user(ulink, &klink, sizeof(klink)))
358                         ret = -EFAULT;
359                 ulink++;
360         }
361         topo->num_links = i;
362
363         return ret;
364 }
365
366 static long copy_arg_from_user(void *karg, void __user *uarg, unsigned int cmd)
367 {
368         /* All media IOCTLs are _IOWR() */
369         if (copy_from_user(karg, uarg, _IOC_SIZE(cmd)))
370                 return -EFAULT;
371
372         return 0;
373 }
374
375 static long copy_arg_to_user(void __user *uarg, void *karg, unsigned int cmd)
376 {
377         /* All media IOCTLs are _IOWR() */
378         if (copy_to_user(uarg, karg, _IOC_SIZE(cmd)))
379                 return -EFAULT;
380
381         return 0;
382 }
383
384 /* Do acquire the graph mutex */
385 #define MEDIA_IOC_FL_GRAPH_MUTEX        BIT(0)
386
387 #define MEDIA_IOC_ARG(__cmd, func, fl, from_user, to_user)              \
388         [_IOC_NR(MEDIA_IOC_##__cmd)] = {                                \
389                 .cmd = MEDIA_IOC_##__cmd,                               \
390                 .fn = (long (*)(struct media_device *, void *))func,    \
391                 .flags = fl,                                            \
392                 .arg_from_user = from_user,                             \
393                 .arg_to_user = to_user,                                 \
394         }
395
396 #define MEDIA_IOC(__cmd, func, fl)                                      \
397         MEDIA_IOC_ARG(__cmd, func, fl, copy_arg_from_user, copy_arg_to_user)
398
399 /* the table is indexed by _IOC_NR(cmd) */
400 struct media_ioctl_info {
401         unsigned int cmd;
402         unsigned short flags;
403         long (*fn)(struct media_device *dev, void *arg);
404         long (*arg_from_user)(void *karg, void __user *uarg, unsigned int cmd);
405         long (*arg_to_user)(void __user *uarg, void *karg, unsigned int cmd);
406 };
407
408 static const struct media_ioctl_info ioctl_info[] = {
409         MEDIA_IOC(DEVICE_INFO, media_device_get_info, MEDIA_IOC_FL_GRAPH_MUTEX),
410         MEDIA_IOC(ENUM_ENTITIES, media_device_enum_entities, MEDIA_IOC_FL_GRAPH_MUTEX),
411         MEDIA_IOC(ENUM_LINKS, media_device_enum_links, MEDIA_IOC_FL_GRAPH_MUTEX),
412         MEDIA_IOC(SETUP_LINK, media_device_setup_link, MEDIA_IOC_FL_GRAPH_MUTEX),
413         MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, MEDIA_IOC_FL_GRAPH_MUTEX),
414 };
415
416 static long media_device_ioctl(struct file *filp, unsigned int cmd,
417                                unsigned long __arg)
418 {
419         struct media_devnode *devnode = media_devnode_data(filp);
420         struct media_device *dev = devnode->media_dev;
421         const struct media_ioctl_info *info;
422         void __user *arg = (void __user *)__arg;
423         char __karg[256], *karg = __karg;
424         long ret;
425
426         if (_IOC_NR(cmd) >= ARRAY_SIZE(ioctl_info)
427             || ioctl_info[_IOC_NR(cmd)].cmd != cmd)
428                 return -ENOIOCTLCMD;
429
430         info = &ioctl_info[_IOC_NR(cmd)];
431
432         if (_IOC_SIZE(info->cmd) > sizeof(__karg)) {
433                 karg = kmalloc(_IOC_SIZE(info->cmd), GFP_KERNEL);
434                 if (!karg)
435                         return -ENOMEM;
436         }
437
438         if (info->arg_from_user) {
439                 ret = info->arg_from_user(karg, arg, cmd);
440                 if (ret)
441                         goto out_free;
442         }
443
444         if (info->flags & MEDIA_IOC_FL_GRAPH_MUTEX)
445                 mutex_lock(&dev->graph_mutex);
446
447         ret = info->fn(dev, karg);
448
449         if (info->flags & MEDIA_IOC_FL_GRAPH_MUTEX)
450                 mutex_unlock(&dev->graph_mutex);
451
452         if (!ret && info->arg_to_user)
453                 ret = info->arg_to_user(arg, karg, cmd);
454
455 out_free:
456         if (karg != __karg)
457                 kfree(karg);
458
459         return ret;
460 }
461
462 #ifdef CONFIG_COMPAT
463
464 struct media_links_enum32 {
465         __u32 entity;
466         compat_uptr_t pads; /* struct media_pad_desc * */
467         compat_uptr_t links; /* struct media_link_desc * */
468         __u32 reserved[4];
469 };
470
471 static long media_device_enum_links32(struct media_device *mdev,
472                                       struct media_links_enum32 __user *ulinks)
473 {
474         struct media_links_enum links;
475         compat_uptr_t pads_ptr, links_ptr;
476
477         memset(&links, 0, sizeof(links));
478
479         if (get_user(links.entity, &ulinks->entity)
480             || get_user(pads_ptr, &ulinks->pads)
481             || get_user(links_ptr, &ulinks->links))
482                 return -EFAULT;
483
484         links.pads = compat_ptr(pads_ptr);
485         links.links = compat_ptr(links_ptr);
486
487         return media_device_enum_links(mdev, &links);
488 }
489
490 #define MEDIA_IOC_ENUM_LINKS32          _IOWR('|', 0x02, struct media_links_enum32)
491
492 static long media_device_compat_ioctl(struct file *filp, unsigned int cmd,
493                                       unsigned long arg)
494 {
495         struct media_devnode *devnode = media_devnode_data(filp);
496         struct media_device *dev = devnode->media_dev;
497         long ret;
498
499         switch (cmd) {
500         case MEDIA_IOC_ENUM_LINKS32:
501                 mutex_lock(&dev->graph_mutex);
502                 ret = media_device_enum_links32(dev,
503                                 (struct media_links_enum32 __user *)arg);
504                 mutex_unlock(&dev->graph_mutex);
505                 break;
506
507         default:
508                 return media_device_ioctl(filp, cmd, arg);
509         }
510
511         return ret;
512 }
513 #endif /* CONFIG_COMPAT */
514
515 static const struct media_file_operations media_device_fops = {
516         .owner = THIS_MODULE,
517         .open = media_device_open,
518         .ioctl = media_device_ioctl,
519 #ifdef CONFIG_COMPAT
520         .compat_ioctl = media_device_compat_ioctl,
521 #endif /* CONFIG_COMPAT */
522         .release = media_device_close,
523 };
524
525 /* -----------------------------------------------------------------------------
526  * sysfs
527  */
528
529 static ssize_t show_model(struct device *cd,
530                           struct device_attribute *attr, char *buf)
531 {
532         struct media_devnode *devnode = to_media_devnode(cd);
533         struct media_device *mdev = devnode->media_dev;
534
535         return sprintf(buf, "%.*s\n", (int)sizeof(mdev->model), mdev->model);
536 }
537
538 static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
539
540 /* -----------------------------------------------------------------------------
541  * Registration/unregistration
542  */
543
544 static void media_device_release(struct media_devnode *mdev)
545 {
546         dev_dbg(mdev->parent, "Media device released\n");
547 }
548
549 /**
550  * media_device_register_entity - Register an entity with a media device
551  * @mdev:       The media device
552  * @entity:     The entity
553  */
554 int __must_check media_device_register_entity(struct media_device *mdev,
555                                               struct media_entity *entity)
556 {
557         struct media_entity_notify *notify, *next;
558         unsigned int i;
559         int ret;
560
561         if (entity->function == MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN ||
562             entity->function == MEDIA_ENT_F_UNKNOWN)
563                 dev_warn(mdev->dev,
564                          "Entity type for entity %s was not initialized!\n",
565                          entity->name);
566
567         /* Warn if we apparently re-register an entity */
568         WARN_ON(entity->graph_obj.mdev != NULL);
569         entity->graph_obj.mdev = mdev;
570         INIT_LIST_HEAD(&entity->links);
571         entity->num_links = 0;
572         entity->num_backlinks = 0;
573
574         if (!ida_pre_get(&mdev->entity_internal_idx, GFP_KERNEL))
575                 return -ENOMEM;
576
577         mutex_lock(&mdev->graph_mutex);
578
579         ret = ida_get_new_above(&mdev->entity_internal_idx, 1,
580                                 &entity->internal_idx);
581         if (ret < 0) {
582                 mutex_unlock(&mdev->graph_mutex);
583                 return ret;
584         }
585
586         mdev->entity_internal_idx_max =
587                 max(mdev->entity_internal_idx_max, entity->internal_idx);
588
589         /* Initialize media_gobj embedded at the entity */
590         media_gobj_create(mdev, MEDIA_GRAPH_ENTITY, &entity->graph_obj);
591
592         /* Initialize objects at the pads */
593         for (i = 0; i < entity->num_pads; i++)
594                 media_gobj_create(mdev, MEDIA_GRAPH_PAD,
595                                &entity->pads[i].graph_obj);
596
597         /* invoke entity_notify callbacks */
598         list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
599                 (notify)->notify(entity, notify->notify_data);
600         }
601
602         if (mdev->entity_internal_idx_max
603             >= mdev->pm_count_walk.ent_enum.idx_max) {
604                 struct media_entity_graph new = { .top = 0 };
605
606                 /*
607                  * Initialise the new graph walk before cleaning up
608                  * the old one in order not to spoil the graph walk
609                  * object of the media device if graph walk init fails.
610                  */
611                 ret = media_entity_graph_walk_init(&new, mdev);
612                 if (ret) {
613                         mutex_unlock(&mdev->graph_mutex);
614                         return ret;
615                 }
616                 media_entity_graph_walk_cleanup(&mdev->pm_count_walk);
617                 mdev->pm_count_walk = new;
618         }
619         mutex_unlock(&mdev->graph_mutex);
620
621         return 0;
622 }
623 EXPORT_SYMBOL_GPL(media_device_register_entity);
624
625 static void __media_device_unregister_entity(struct media_entity *entity)
626 {
627         struct media_device *mdev = entity->graph_obj.mdev;
628         struct media_link *link, *tmp;
629         struct media_interface *intf;
630         unsigned int i;
631
632         ida_simple_remove(&mdev->entity_internal_idx, entity->internal_idx);
633
634         /* Remove all interface links pointing to this entity */
635         list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) {
636                 list_for_each_entry_safe(link, tmp, &intf->links, list) {
637                         if (link->entity == entity)
638                                 __media_remove_intf_link(link);
639                 }
640         }
641
642         /* Remove all data links that belong to this entity */
643         __media_entity_remove_links(entity);
644
645         /* Remove all pads that belong to this entity */
646         for (i = 0; i < entity->num_pads; i++)
647                 media_gobj_destroy(&entity->pads[i].graph_obj);
648
649         /* Remove the entity */
650         media_gobj_destroy(&entity->graph_obj);
651
652         /* invoke entity_notify callbacks to handle entity removal?? */
653
654         entity->graph_obj.mdev = NULL;
655 }
656
657 void media_device_unregister_entity(struct media_entity *entity)
658 {
659         struct media_device *mdev = entity->graph_obj.mdev;
660
661         if (mdev == NULL)
662                 return;
663
664         mutex_lock(&mdev->graph_mutex);
665         __media_device_unregister_entity(entity);
666         mutex_unlock(&mdev->graph_mutex);
667 }
668 EXPORT_SYMBOL_GPL(media_device_unregister_entity);
669
670 /**
671  * media_device_init() - initialize a media device
672  * @mdev:       The media device
673  *
674  * The caller is responsible for initializing the media device before
675  * registration. The following fields must be set:
676  *
677  * - dev must point to the parent device
678  * - model must be filled with the device model name
679  */
680 void media_device_init(struct media_device *mdev)
681 {
682         INIT_LIST_HEAD(&mdev->entities);
683         INIT_LIST_HEAD(&mdev->interfaces);
684         INIT_LIST_HEAD(&mdev->pads);
685         INIT_LIST_HEAD(&mdev->links);
686         INIT_LIST_HEAD(&mdev->entity_notify);
687         mutex_init(&mdev->graph_mutex);
688         ida_init(&mdev->entity_internal_idx);
689
690         dev_dbg(mdev->dev, "Media device initialized\n");
691 }
692 EXPORT_SYMBOL_GPL(media_device_init);
693
694 void media_device_cleanup(struct media_device *mdev)
695 {
696         ida_destroy(&mdev->entity_internal_idx);
697         mdev->entity_internal_idx_max = 0;
698         media_entity_graph_walk_cleanup(&mdev->pm_count_walk);
699         mutex_destroy(&mdev->graph_mutex);
700 }
701 EXPORT_SYMBOL_GPL(media_device_cleanup);
702
703 int __must_check __media_device_register(struct media_device *mdev,
704                                          struct module *owner)
705 {
706         struct media_devnode *devnode;
707         int ret;
708
709         devnode = kzalloc(sizeof(*devnode), GFP_KERNEL);
710         if (!devnode)
711                 return -ENOMEM;
712
713         /* Register the device node. */
714         mdev->devnode = devnode;
715         devnode->fops = &media_device_fops;
716         devnode->parent = mdev->dev;
717         devnode->release = media_device_release;
718
719         /* Set version 0 to indicate user-space that the graph is static */
720         mdev->topology_version = 0;
721
722         ret = media_devnode_register(mdev, devnode, owner);
723         if (ret < 0) {
724                 /* devnode free is handled in media_devnode_*() */
725                 mdev->devnode = NULL;
726                 return ret;
727         }
728
729         ret = device_create_file(&devnode->dev, &dev_attr_model);
730         if (ret < 0) {
731                 /* devnode free is handled in media_devnode_*() */
732                 mdev->devnode = NULL;
733                 media_devnode_unregister_prepare(devnode);
734                 media_devnode_unregister(devnode);
735                 return ret;
736         }
737
738         dev_dbg(mdev->dev, "Media device registered\n");
739
740         return 0;
741 }
742 EXPORT_SYMBOL_GPL(__media_device_register);
743
744 int __must_check media_device_register_entity_notify(struct media_device *mdev,
745                                         struct media_entity_notify *nptr)
746 {
747         mutex_lock(&mdev->graph_mutex);
748         list_add_tail(&nptr->list, &mdev->entity_notify);
749         mutex_unlock(&mdev->graph_mutex);
750         return 0;
751 }
752 EXPORT_SYMBOL_GPL(media_device_register_entity_notify);
753
754 /*
755  * Note: Should be called with mdev->lock held.
756  */
757 static void __media_device_unregister_entity_notify(struct media_device *mdev,
758                                         struct media_entity_notify *nptr)
759 {
760         list_del(&nptr->list);
761 }
762
763 void media_device_unregister_entity_notify(struct media_device *mdev,
764                                         struct media_entity_notify *nptr)
765 {
766         mutex_lock(&mdev->graph_mutex);
767         __media_device_unregister_entity_notify(mdev, nptr);
768         mutex_unlock(&mdev->graph_mutex);
769 }
770 EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify);
771
772 void media_device_unregister(struct media_device *mdev)
773 {
774         struct media_entity *entity;
775         struct media_entity *next;
776         struct media_interface *intf, *tmp_intf;
777         struct media_entity_notify *notify, *nextp;
778
779         if (mdev == NULL)
780                 return;
781
782         mutex_lock(&mdev->graph_mutex);
783
784         /* Check if mdev was ever registered at all */
785         if (!media_devnode_is_registered(mdev->devnode)) {
786                 mutex_unlock(&mdev->graph_mutex);
787                 return;
788         }
789
790         /* Clear the devnode register bit to avoid races with media dev open */
791         media_devnode_unregister_prepare(mdev->devnode);
792
793         /* Remove all entities from the media device */
794         list_for_each_entry_safe(entity, next, &mdev->entities, graph_obj.list)
795                 __media_device_unregister_entity(entity);
796
797         /* Remove all entity_notify callbacks from the media device */
798         list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list)
799                 __media_device_unregister_entity_notify(mdev, notify);
800
801         /* Remove all interfaces from the media device */
802         list_for_each_entry_safe(intf, tmp_intf, &mdev->interfaces,
803                                  graph_obj.list) {
804                 __media_remove_intf_links(intf);
805                 media_gobj_destroy(&intf->graph_obj);
806                 kfree(intf);
807         }
808
809         mutex_unlock(&mdev->graph_mutex);
810
811         dev_dbg(mdev->dev, "Media device unregistered\n");
812
813         device_remove_file(&mdev->devnode->dev, &dev_attr_model);
814         media_devnode_unregister(mdev->devnode);
815         /* devnode free is handled in media_devnode_*() */
816         mdev->devnode = NULL;
817 }
818 EXPORT_SYMBOL_GPL(media_device_unregister);
819
820 static void media_device_release_devres(struct device *dev, void *res)
821 {
822 }
823
824 struct media_device *media_device_get_devres(struct device *dev)
825 {
826         struct media_device *mdev;
827
828         mdev = devres_find(dev, media_device_release_devres, NULL, NULL);
829         if (mdev)
830                 return mdev;
831
832         mdev = devres_alloc(media_device_release_devres,
833                                 sizeof(struct media_device), GFP_KERNEL);
834         if (!mdev)
835                 return NULL;
836         return devres_get(dev, mdev, NULL, NULL);
837 }
838 EXPORT_SYMBOL_GPL(media_device_get_devres);
839
840 struct media_device *media_device_find_devres(struct device *dev)
841 {
842         return devres_find(dev, media_device_release_devres, NULL, NULL);
843 }
844 EXPORT_SYMBOL_GPL(media_device_find_devres);
845
846 #if IS_ENABLED(CONFIG_PCI)
847 void media_device_pci_init(struct media_device *mdev,
848                            struct pci_dev *pci_dev,
849                            const char *name)
850 {
851         mdev->dev = &pci_dev->dev;
852
853         if (name)
854                 strlcpy(mdev->model, name, sizeof(mdev->model));
855         else
856                 strlcpy(mdev->model, pci_name(pci_dev), sizeof(mdev->model));
857
858         sprintf(mdev->bus_info, "PCI:%s", pci_name(pci_dev));
859
860         mdev->hw_revision = (pci_dev->subsystem_vendor << 16)
861                             | pci_dev->subsystem_device;
862
863         mdev->driver_version = LINUX_VERSION_CODE;
864
865         media_device_init(mdev);
866 }
867 EXPORT_SYMBOL_GPL(media_device_pci_init);
868 #endif
869
870 #if IS_ENABLED(CONFIG_USB)
871 void __media_device_usb_init(struct media_device *mdev,
872                              struct usb_device *udev,
873                              const char *board_name,
874                              const char *driver_name)
875 {
876         mdev->dev = &udev->dev;
877
878         if (driver_name)
879                 strlcpy(mdev->driver_name, driver_name,
880                         sizeof(mdev->driver_name));
881
882         if (board_name)
883                 strlcpy(mdev->model, board_name, sizeof(mdev->model));
884         else if (udev->product)
885                 strlcpy(mdev->model, udev->product, sizeof(mdev->model));
886         else
887                 strlcpy(mdev->model, "unknown model", sizeof(mdev->model));
888         if (udev->serial)
889                 strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial));
890         usb_make_path(udev, mdev->bus_info, sizeof(mdev->bus_info));
891         mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
892         mdev->driver_version = LINUX_VERSION_CODE;
893
894         media_device_init(mdev);
895 }
896 EXPORT_SYMBOL_GPL(__media_device_usb_init);
897 #endif
898
899
900 #endif /* CONFIG_MEDIA_CONTROLLER */