From cfca7644d7959e1f50cb132306d1557bf6c2da57 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 19 Jul 2013 12:14:46 -0300 Subject: [media] V4L: Rename v4l2_async_bus_* to v4l2_async_match_* enum v4l2_async_bus_type also selects a method subdevs are matched in the notification handlers, rename it to v4l2_async_match_type so V4L2_ASYNC_MATCH_OF entry can be further added for matching by device tree node pointer. Acked-and-tested-by: Lad, Prabhakar Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-async.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/media/v4l2-async.h') diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index c3ec6ac75f7..33e3b2a30ec 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -22,10 +22,10 @@ struct v4l2_async_notifier; /* A random max subdevice number, used to allocate an array on stack */ #define V4L2_MAX_SUBDEVS 128U -enum v4l2_async_bus_type { - V4L2_ASYNC_BUS_CUSTOM, - V4L2_ASYNC_BUS_PLATFORM, - V4L2_ASYNC_BUS_I2C, +enum v4l2_async_match_type { + V4L2_ASYNC_MATCH_CUSTOM, + V4L2_ASYNC_MATCH_DEVNAME, + V4L2_ASYNC_MATCH_I2C, }; /** @@ -36,11 +36,11 @@ enum v4l2_async_bus_type { * probed, to a notifier->waiting list */ struct v4l2_async_subdev { - enum v4l2_async_bus_type bus_type; + enum v4l2_async_match_type match_type; union { struct { const char *name; - } platform; + } device_name; struct { int adapter_id; unsigned short address; -- cgit v1.2.3-70-g09d2 From e7359f8e660882fb2168609638163561eb2f50f0 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 19 Jul 2013 12:21:29 -0300 Subject: [media] V4L: Add V4L2_ASYNC_MATCH_OF subdev matching type Add support for matching by device_node pointer. This allows the notifier user to simply pass a list of device_node pointers corresponding to sub-devices. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Acked-by: Lad, Prabhakar Acked-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-async.c | 9 +++++++++ include/media/v4l2-async.h | 5 +++++ 2 files changed, 14 insertions(+) (limited to 'include/media/v4l2-async.h') diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 86934ca7335..9f91013a600 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -39,6 +39,11 @@ static bool match_devname(struct device *dev, struct v4l2_async_subdev *asd) return !strcmp(asd->match.device_name.name, dev_name(dev)); } +static bool match_of(struct device *dev, struct v4l2_async_subdev *asd) +{ + return dev->of_node == asd->match.of.node; +} + static LIST_HEAD(subdev_list); static LIST_HEAD(notifier_list); static DEFINE_MUTEX(list_lock); @@ -66,6 +71,9 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier * case V4L2_ASYNC_MATCH_I2C: match = match_i2c; break; + case V4L2_ASYNC_MATCH_OF: + match = match_of; + break; default: /* Cannot happen, unless someone breaks us */ WARN_ON(true); @@ -145,6 +153,7 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, case V4L2_ASYNC_MATCH_CUSTOM: case V4L2_ASYNC_MATCH_DEVNAME: case V4L2_ASYNC_MATCH_I2C: + case V4L2_ASYNC_MATCH_OF: break; default: dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL, diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 33e3b2a30ec..82b29813f8b 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -15,6 +15,7 @@ #include struct device; +struct device_node; struct v4l2_device; struct v4l2_subdev; struct v4l2_async_notifier; @@ -26,6 +27,7 @@ enum v4l2_async_match_type { V4L2_ASYNC_MATCH_CUSTOM, V4L2_ASYNC_MATCH_DEVNAME, V4L2_ASYNC_MATCH_I2C, + V4L2_ASYNC_MATCH_OF, }; /** @@ -38,6 +40,9 @@ enum v4l2_async_match_type { struct v4l2_async_subdev { enum v4l2_async_match_type match_type; union { + struct { + const struct device_node *node; + } of; struct { const char *name; } device_name; -- cgit v1.2.3-70-g09d2 From e8419d0890efaccb93f9f274d9ba0aae91210e8c Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 19 Jul 2013 12:31:10 -0300 Subject: [media] V4L: Rename subdev field of struct v4l2_async_notifier This is a purely cosmetic change. Since the 'subdev' member points to an array of subdevs make it more explicit by renaming to the plural form. Acked-and-tested-by: Lad, Prabhakar Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/davinci/vpif_capture.c | 2 +- drivers/media/platform/davinci/vpif_display.c | 2 +- drivers/media/platform/soc_camera/soc_camera.c | 2 +- drivers/media/v4l2-core/v4l2-async.c | 2 +- include/media/v4l2-async.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include/media/v4l2-async.h') diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index b11d7a74497..7fbde6d790b 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -2168,7 +2168,7 @@ static __init int vpif_probe(struct platform_device *pdev) } vpif_probe_complete(); } else { - vpif_obj.notifier.subdev = vpif_obj.config->asd; + vpif_obj.notifier.subdevs = vpif_obj.config->asd; vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0]; vpif_obj.notifier.bound = vpif_async_bound; vpif_obj.notifier.complete = vpif_async_complete; diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index c2ff06745fd..6336dfc8648 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -1832,7 +1832,7 @@ static __init int vpif_probe(struct platform_device *pdev) } vpif_probe_complete(); } else { - vpif_obj.notifier.subdev = vpif_obj.config->asd; + vpif_obj.notifier.subdevs = vpif_obj.config->asd; vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0]; vpif_obj.notifier.bound = vpif_async_bound; vpif_obj.notifier.complete = vpif_async_complete; diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 8af572bcf03..4b42572253e 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1501,7 +1501,7 @@ static int scan_async_group(struct soc_camera_host *ici, return -ENOMEM; } - sasc->notifier.subdev = asd; + sasc->notifier.subdevs = asd; sasc->notifier.num_subdevs = size; sasc->notifier.bound = soc_camera_async_bound; sasc->notifier.unbind = soc_camera_async_unbind; diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 9f91013a600..ed31a655b9b 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -147,7 +147,7 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, INIT_LIST_HEAD(¬ifier->done); for (i = 0; i < notifier->num_subdevs; i++) { - asd = notifier->subdev[i]; + asd = notifier->subdevs[i]; switch (asd->match_type) { case V4L2_ASYNC_MATCH_CUSTOM: diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 82b29813f8b..8fac8eaca51 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -77,7 +77,7 @@ struct v4l2_async_subdev_list { /** * v4l2_async_notifier - v4l2_device notifier data * @num_subdevs:number of subdevices - * @subdev: array of pointers to subdevice descriptors + * @subdevs: array of pointers to subdevice descriptors * @v4l2_dev: pointer to struct v4l2_device * @waiting: list of struct v4l2_async_subdev, waiting for their drivers * @done: list of struct v4l2_async_subdev_list, already probed @@ -88,7 +88,7 @@ struct v4l2_async_subdev_list { */ struct v4l2_async_notifier { unsigned int num_subdevs; - struct v4l2_async_subdev **subdev; + struct v4l2_async_subdev **subdevs; struct v4l2_device *v4l2_dev; struct list_head waiting; struct list_head done; -- cgit v1.2.3-70-g09d2 From b426b3a660c85faf6e1ca1c92c6d43577022aa3b Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 22 Jul 2013 08:01:33 -0300 Subject: [media] V4L: Merge struct v4l2_async_subdev_list with struct v4l2_subdev By integrating the v4l2-async API internals a bit more with the core overall the v4l2-async code becomes a bit simpler and easier to follow. Acked-and-tested-by: Lad, Prabhakar Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Acked-by: Laurent Pinchart Acked-by: Hans Verkuil Acked-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-async.c | 67 ++++++++++++++++-------------------- include/media/v4l2-async.h | 15 +------- include/media/v4l2-subdev.h | 13 ++++--- 3 files changed, 36 insertions(+), 59 deletions(-) (limited to 'include/media/v4l2-async.h') diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index ed31a655b9b..b350ab99652 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -49,12 +49,10 @@ static LIST_HEAD(notifier_list); static DEFINE_MUTEX(list_lock); static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *notifier, - struct v4l2_async_subdev_list *asdl) + struct v4l2_subdev *sd) { - struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl); struct v4l2_async_subdev *asd; - bool (*match)(struct device *, - struct v4l2_async_subdev *); + bool (*match)(struct device *, struct v4l2_async_subdev *); list_for_each_entry(asd, ¬ifier->waiting, list) { /* bus_type has been verified valid before */ @@ -89,16 +87,15 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier * } static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier, - struct v4l2_async_subdev_list *asdl, + struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) { - struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl); int ret; /* Remove from the waiting list */ list_del(&asd->list); - asdl->asd = asd; - asdl->notifier = notifier; + sd->asd = asd; + sd->notifier = notifier; if (notifier->bound) { ret = notifier->bound(notifier, sd, asd); @@ -106,7 +103,7 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier, return ret; } /* Move from the global subdevice list to notifier's done */ - list_move(&asdl->list, ¬ifier->done); + list_move(&sd->async_list, ¬ifier->done); ret = v4l2_device_register_subdev(notifier->v4l2_dev, sd); if (ret < 0) { @@ -121,21 +118,19 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier, return 0; } -static void v4l2_async_cleanup(struct v4l2_async_subdev_list *asdl) +static void v4l2_async_cleanup(struct v4l2_subdev *sd) { - struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl); - v4l2_device_unregister_subdev(sd); - /* Subdevice driver will reprobe and put asdl back onto the list */ - list_del_init(&asdl->list); - asdl->asd = NULL; + /* Subdevice driver will reprobe and put the subdev back onto the list */ + list_del_init(&sd->async_list); + sd->asd = NULL; sd->dev = NULL; } int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, struct v4l2_async_notifier *notifier) { - struct v4l2_async_subdev_list *asdl, *tmp; + struct v4l2_subdev *sd, *tmp; struct v4l2_async_subdev *asd; int i; @@ -169,14 +164,14 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, /* Keep also completed notifiers on the list */ list_add(¬ifier->list, ¬ifier_list); - list_for_each_entry_safe(asdl, tmp, &subdev_list, list) { + list_for_each_entry_safe(sd, tmp, &subdev_list, async_list) { int ret; - asd = v4l2_async_belongs(notifier, asdl); + asd = v4l2_async_belongs(notifier, sd); if (!asd) continue; - ret = v4l2_async_test_notify(notifier, asdl, asd); + ret = v4l2_async_test_notify(notifier, sd, asd); if (ret < 0) { mutex_unlock(&list_lock); return ret; @@ -191,7 +186,7 @@ EXPORT_SYMBOL(v4l2_async_notifier_register); void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) { - struct v4l2_async_subdev_list *asdl, *tmp; + struct v4l2_subdev *sd, *tmp; unsigned int notif_n_subdev = notifier->num_subdevs; unsigned int n_subdev = min(notif_n_subdev, V4L2_MAX_SUBDEVS); struct device *dev[n_subdev]; @@ -201,18 +196,16 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier) list_del(¬ifier->list); - list_for_each_entry_safe(asdl, tmp, ¬ifier->done, list) { - struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl); - + list_for_each_entry_safe(sd, tmp, ¬ifier->done, list) { dev[i] = get_device(sd->dev); - v4l2_async_cleanup(asdl); + v4l2_async_cleanup(sd); /* If we handled USB devices, we'd have to lock the parent too */ device_release_driver(dev[i++]); if (notifier->unbind) - notifier->unbind(notifier, sd, sd->asdl.asd); + notifier->unbind(notifier, sd, sd->asd); } mutex_unlock(&list_lock); @@ -241,24 +234,23 @@ EXPORT_SYMBOL(v4l2_async_notifier_unregister); int v4l2_async_register_subdev(struct v4l2_subdev *sd) { - struct v4l2_async_subdev_list *asdl = &sd->asdl; struct v4l2_async_notifier *notifier; mutex_lock(&list_lock); - INIT_LIST_HEAD(&asdl->list); + INIT_LIST_HEAD(&sd->async_list); list_for_each_entry(notifier, ¬ifier_list, list) { - struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, asdl); + struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, sd); if (asd) { - int ret = v4l2_async_test_notify(notifier, asdl, asd); + int ret = v4l2_async_test_notify(notifier, sd, asd); mutex_unlock(&list_lock); return ret; } } /* None matched, wait for hot-plugging */ - list_add(&asdl->list, &subdev_list); + list_add(&sd->async_list, &subdev_list); mutex_unlock(&list_lock); @@ -268,23 +260,22 @@ EXPORT_SYMBOL(v4l2_async_register_subdev); void v4l2_async_unregister_subdev(struct v4l2_subdev *sd) { - struct v4l2_async_subdev_list *asdl = &sd->asdl; - struct v4l2_async_notifier *notifier = asdl->notifier; + struct v4l2_async_notifier *notifier = sd->notifier; - if (!asdl->asd) { - if (!list_empty(&asdl->list)) - v4l2_async_cleanup(asdl); + if (!sd->asd) { + if (!list_empty(&sd->async_list)) + v4l2_async_cleanup(sd); return; } mutex_lock(&list_lock); - list_add(&asdl->asd->list, ¬ifier->waiting); + list_add(&sd->asd->list, ¬ifier->waiting); - v4l2_async_cleanup(asdl); + v4l2_async_cleanup(sd); if (notifier->unbind) - notifier->unbind(notifier, sd, sd->asdl.asd); + notifier->unbind(notifier, sd, sd->asd); mutex_unlock(&list_lock); } diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h index 8fac8eaca51..768356917be 100644 --- a/include/media/v4l2-async.h +++ b/include/media/v4l2-async.h @@ -61,26 +61,13 @@ struct v4l2_async_subdev { struct list_head list; }; -/** - * v4l2_async_subdev_list - provided by subdevices - * @list: links struct v4l2_async_subdev_list objects to a global list - * before probing, and onto notifier->done after probing - * @asd: pointer to respective struct v4l2_async_subdev - * @notifier: pointer to managing notifier - */ -struct v4l2_async_subdev_list { - struct list_head list; - struct v4l2_async_subdev *asd; - struct v4l2_async_notifier *notifier; -}; - /** * v4l2_async_notifier - v4l2_device notifier data * @num_subdevs:number of subdevices * @subdevs: array of pointers to subdevice descriptors * @v4l2_dev: pointer to struct v4l2_device * @waiting: list of struct v4l2_async_subdev, waiting for their drivers - * @done: list of struct v4l2_async_subdev_list, already probed + * @done: list of struct v4l2_subdev, already probed * @list: member in a global list of notifiers * @bound: a subdevice driver has successfully probed one of subdevices * @complete: all subdevices have been probed successfully diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 3250cc5e792..bfda0fe9aeb 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -586,15 +586,14 @@ struct v4l2_subdev { struct video_device *devnode; /* pointer to the physical device, if any */ struct device *dev; - struct v4l2_async_subdev_list asdl; + /* Links this subdev to a global subdev_list or @notifier->done list. */ + struct list_head async_list; + /* Pointer to respective struct v4l2_async_subdev. */ + struct v4l2_async_subdev *asd; + /* Pointer to the managing notifier. */ + struct v4l2_async_notifier *notifier; }; -static inline struct v4l2_subdev *v4l2_async_to_subdev( - struct v4l2_async_subdev_list *asdl) -{ - return container_of(asdl, struct v4l2_subdev, asdl); -} - #define media_entity_to_v4l2_subdev(ent) \ container_of(ent, struct v4l2_subdev, entity) #define vdev_to_v4l2_subdev(vdev) \ -- cgit v1.2.3-70-g09d2