aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core/v4l2-async.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-async.c')
-rw-r--r--drivers/media/v4l2-core/v4l2-async.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 85a6a34128a8..5bada202b2d3 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -22,10 +22,10 @@
22#include <media/v4l2-device.h> 22#include <media/v4l2-device.h>
23#include <media/v4l2-subdev.h> 23#include <media/v4l2-subdev.h>
24 24
25static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd) 25static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
26{ 26{
27#if IS_ENABLED(CONFIG_I2C) 27#if IS_ENABLED(CONFIG_I2C)
28 struct i2c_client *client = i2c_verify_client(dev); 28 struct i2c_client *client = i2c_verify_client(sd->dev);
29 return client && 29 return client &&
30 asd->match.i2c.adapter_id == client->adapter->nr && 30 asd->match.i2c.adapter_id == client->adapter->nr &&
31 asd->match.i2c.address == client->addr; 31 asd->match.i2c.address == client->addr;
@@ -34,14 +34,24 @@ static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
34#endif 34#endif
35} 35}
36 36
37static bool match_devname(struct device *dev, struct v4l2_async_subdev *asd) 37static bool match_devname(struct v4l2_subdev *sd,
38 struct v4l2_async_subdev *asd)
38{ 39{
39 return !strcmp(asd->match.device_name.name, dev_name(dev)); 40 return !strcmp(asd->match.device_name.name, dev_name(sd->dev));
40} 41}
41 42
42static bool match_of(struct device *dev, struct v4l2_async_subdev *asd) 43static bool match_of(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
43{ 44{
44 return dev->of_node == asd->match.of.node; 45 return sd->of_node == asd->match.of.node;
46}
47
48static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
49{
50 if (!asd->match.custom.match)
51 /* Match always */
52 return true;
53
54 return asd->match.custom.match(sd->dev, asd);
45} 55}
46 56
47static LIST_HEAD(subdev_list); 57static LIST_HEAD(subdev_list);
@@ -51,17 +61,14 @@ static DEFINE_MUTEX(list_lock);
51static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier, 61static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier,
52 struct v4l2_subdev *sd) 62 struct v4l2_subdev *sd)
53{ 63{
64 bool (*match)(struct v4l2_subdev *, struct v4l2_async_subdev *);
54 struct v4l2_async_subdev *asd; 65 struct v4l2_async_subdev *asd;
55 bool (*match)(struct device *, struct v4l2_async_subdev *);
56 66
57 list_for_each_entry(asd, &notifier->waiting, list) { 67 list_for_each_entry(asd, &notifier->waiting, list) {
58 /* bus_type has been verified valid before */ 68 /* bus_type has been verified valid before */
59 switch (asd->match_type) { 69 switch (asd->match_type) {
60 case V4L2_ASYNC_MATCH_CUSTOM: 70 case V4L2_ASYNC_MATCH_CUSTOM:
61 match = asd->match.custom.match; 71 match = match_custom;
62 if (!match)
63 /* Match always */
64 return asd;
65 break; 72 break;
66 case V4L2_ASYNC_MATCH_DEVNAME: 73 case V4L2_ASYNC_MATCH_DEVNAME:
67 match = match_devname; 74 match = match_devname;
@@ -79,7 +86,7 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *
79 } 86 }
80 87
81 /* match cannot be NULL here */ 88 /* match cannot be NULL here */
82 if (match(sd->dev, asd)) 89 if (match(sd, asd))
83 return asd; 90 return asd;
84 } 91 }
85 92
@@ -266,6 +273,14 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd)
266{ 273{
267 struct v4l2_async_notifier *notifier; 274 struct v4l2_async_notifier *notifier;
268 275
276 /*
277 * No reference taken. The reference is held by the device
278 * (struct v4l2_subdev.dev), and async sub-device does not
279 * exist independently of the device at any point of time.
280 */
281 if (!sd->of_node && sd->dev)
282 sd->of_node = sd->dev->of_node;
283
269 mutex_lock(&list_lock); 284 mutex_lock(&list_lock);
270 285
271 INIT_LIST_HEAD(&sd->async_list); 286 INIT_LIST_HEAD(&sd->async_list);