aboutsummaryrefslogtreecommitdiffstats
path: root/include/media
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2013-01-08 05:06:31 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-06-21 15:30:00 -0400
commite9e310491bdbc8c0f33ea0e2ce65eff345a01f71 (patch)
treec1ada792f3d31542ff8038d140de3232035d41a6 /include/media
parent668773b84604926519e2baf444f382f88d799d41 (diff)
[media] V4L2: support asynchronous subdevice registration
Currently bridge device drivers register devices for all subdevices synchronously, typically, during their probing. E.g. if an I2C CMOS sensor is attached to a video bridge device, the bridge driver will create an I2C device and wait for the respective I2C driver to probe. This makes linking of devices straight forward, but this approach cannot be used with intrinsically asynchronous and unordered device registration systems like the Flattened Device Tree. To support such systems this patch adds an asynchronous subdevice registration framework to V4L2. To use it respective (e.g. I2C) subdevice drivers must register themselves with the framework. A bridge driver on the other hand must register notification callbacks, that will be called upon various related events. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Lad, Prabhakar <prabhakar.csengg@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'include/media')
-rw-r--r--include/media/v4l2-async.h105
-rw-r--r--include/media/v4l2-subdev.h8
2 files changed, 113 insertions, 0 deletions
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
new file mode 100644
index 000000000000..c3ec6ac75f7e
--- /dev/null
+++ b/include/media/v4l2-async.h
@@ -0,0 +1,105 @@
1/*
2 * V4L2 asynchronous subdevice registration API
3 *
4 * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef V4L2_ASYNC_H
12#define V4L2_ASYNC_H
13
14#include <linux/list.h>
15#include <linux/mutex.h>
16
17struct device;
18struct v4l2_device;
19struct v4l2_subdev;
20struct v4l2_async_notifier;
21
22/* A random max subdevice number, used to allocate an array on stack */
23#define V4L2_MAX_SUBDEVS 128U
24
25enum v4l2_async_bus_type {
26 V4L2_ASYNC_BUS_CUSTOM,
27 V4L2_ASYNC_BUS_PLATFORM,
28 V4L2_ASYNC_BUS_I2C,
29};
30
31/**
32 * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge
33 * @bus_type: subdevice bus type to select the appropriate matching method
34 * @match: union of per-bus type matching data sets
35 * @list: used to link struct v4l2_async_subdev objects, waiting to be
36 * probed, to a notifier->waiting list
37 */
38struct v4l2_async_subdev {
39 enum v4l2_async_bus_type bus_type;
40 union {
41 struct {
42 const char *name;
43 } platform;
44 struct {
45 int adapter_id;
46 unsigned short address;
47 } i2c;
48 struct {
49 bool (*match)(struct device *,
50 struct v4l2_async_subdev *);
51 void *priv;
52 } custom;
53 } match;
54
55 /* v4l2-async core private: not to be used by drivers */
56 struct list_head list;
57};
58
59/**
60 * v4l2_async_subdev_list - provided by subdevices
61 * @list: links struct v4l2_async_subdev_list objects to a global list
62 * before probing, and onto notifier->done after probing
63 * @asd: pointer to respective struct v4l2_async_subdev
64 * @notifier: pointer to managing notifier
65 */
66struct v4l2_async_subdev_list {
67 struct list_head list;
68 struct v4l2_async_subdev *asd;
69 struct v4l2_async_notifier *notifier;
70};
71
72/**
73 * v4l2_async_notifier - v4l2_device notifier data
74 * @num_subdevs:number of subdevices
75 * @subdev: array of pointers to subdevice descriptors
76 * @v4l2_dev: pointer to struct v4l2_device
77 * @waiting: list of struct v4l2_async_subdev, waiting for their drivers
78 * @done: list of struct v4l2_async_subdev_list, already probed
79 * @list: member in a global list of notifiers
80 * @bound: a subdevice driver has successfully probed one of subdevices
81 * @complete: all subdevices have been probed successfully
82 * @unbind: a subdevice is leaving
83 */
84struct v4l2_async_notifier {
85 unsigned int num_subdevs;
86 struct v4l2_async_subdev **subdev;
87 struct v4l2_device *v4l2_dev;
88 struct list_head waiting;
89 struct list_head done;
90 struct list_head list;
91 int (*bound)(struct v4l2_async_notifier *notifier,
92 struct v4l2_subdev *subdev,
93 struct v4l2_async_subdev *asd);
94 int (*complete)(struct v4l2_async_notifier *notifier);
95 void (*unbind)(struct v4l2_async_notifier *notifier,
96 struct v4l2_subdev *subdev,
97 struct v4l2_async_subdev *asd);
98};
99
100int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
101 struct v4l2_async_notifier *notifier);
102void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
103int v4l2_async_register_subdev(struct v4l2_subdev *sd);
104void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
105#endif
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 5fbb266405f9..3250cc5e7925 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -24,6 +24,7 @@
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/v4l2-subdev.h> 25#include <linux/v4l2-subdev.h>
26#include <media/media-entity.h> 26#include <media/media-entity.h>
27#include <media/v4l2-async.h>
27#include <media/v4l2-common.h> 28#include <media/v4l2-common.h>
28#include <media/v4l2-dev.h> 29#include <media/v4l2-dev.h>
29#include <media/v4l2-fh.h> 30#include <media/v4l2-fh.h>
@@ -585,8 +586,15 @@ struct v4l2_subdev {
585 struct video_device *devnode; 586 struct video_device *devnode;
586 /* pointer to the physical device, if any */ 587 /* pointer to the physical device, if any */
587 struct device *dev; 588 struct device *dev;
589 struct v4l2_async_subdev_list asdl;
588}; 590};
589 591
592static inline struct v4l2_subdev *v4l2_async_to_subdev(
593 struct v4l2_async_subdev_list *asdl)
594{
595 return container_of(asdl, struct v4l2_subdev, asdl);
596}
597
590#define media_entity_to_v4l2_subdev(ent) \ 598#define media_entity_to_v4l2_subdev(ent) \
591 container_of(ent, struct v4l2_subdev, entity) 599 container_of(ent, struct v4l2_subdev, entity)
592#define vdev_to_v4l2_subdev(vdev) \ 600#define vdev_to_v4l2_subdev(vdev) \