From 3c2ade017a7e10470aa8112f8a4bfdb2ee30f97f Mon Sep 17 00:00:00 2001
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
Date: Fri, 19 Jul 2013 12:08:08 -0300
Subject: [media] V4L: Drop bus_type check in v4l2-async match functions

These match_* functions are internal callbacks and are always
invoked only after checking asd->bus_type. So drop redundant
checks in match_i2c() and match_platform() functions.
Acked-and-tested-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/v4l2-core/v4l2-async.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

(limited to 'drivers/media/v4l2-core/v4l2-async.c')

diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index aae241730ca..ff87c299f64 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -27,7 +27,6 @@ static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
 #if IS_ENABLED(CONFIG_I2C)
 	struct i2c_client *client = i2c_verify_client(dev);
 	return client &&
-		asd->bus_type == V4L2_ASYNC_BUS_I2C &&
 		asd->match.i2c.adapter_id == client->adapter->nr &&
 		asd->match.i2c.address == client->addr;
 #else
@@ -37,8 +36,7 @@ static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
 
 static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd)
 {
-	return asd->bus_type == V4L2_ASYNC_BUS_PLATFORM &&
-		!strcmp(asd->match.platform.name, dev_name(dev));
+	return !strcmp(asd->match.platform.name, dev_name(dev));
 }
 
 static LIST_HEAD(subdev_list);
-- 
cgit v1.2.3-70-g09d2


From cfca7644d7959e1f50cb132306d1557bf6c2da57 Mon Sep 17 00:00:00 2001
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
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 <prabhakar.csengg@gmail.com>

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 .../platform/soc_camera/sh_mobile_ceu_camera.c     |  6 ++---
 drivers/media/platform/soc_camera/soc_camera.c     |  2 +-
 drivers/media/v4l2-core/v4l2-async.c               | 26 +++++++++++-----------
 include/media/v4l2-async.h                         | 12 +++++-----
 4 files changed, 23 insertions(+), 23 deletions(-)

(limited to 'drivers/media/v4l2-core/v4l2-async.c')

diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index f2de0066089..dae9716e34b 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -1837,9 +1837,9 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
 		for (j = 0; pcdev->pdata->asd_sizes[j]; j++) {
 			for (i = 0; i < pcdev->pdata->asd_sizes[j]; i++, asd++) {
 				dev_dbg(&pdev->dev, "%s(): subdev #%d, type %u\n",
-					__func__, i, (*asd)->bus_type);
-				if ((*asd)->bus_type == V4L2_ASYNC_BUS_PLATFORM &&
-				    !strncmp(name, (*asd)->match.platform.name,
+					__func__, i, (*asd)->match_type);
+				if ((*asd)->match_type == V4L2_ASYNC_MATCH_DEVNAME &&
+				    !strncmp(name, (*asd)->match.device_name.name,
 					     sizeof(name) - 1)) {
 					pcdev->csi2_asd = *asd;
 					break;
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 2dd0e527294..8af572bcf03 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -1475,7 +1475,7 @@ static int scan_async_group(struct soc_camera_host *ici,
 			break;
 	}
 
-	if (i == size || asd[i]->bus_type != V4L2_ASYNC_BUS_I2C) {
+	if (i == size || asd[i]->match_type != V4L2_ASYNC_MATCH_I2C) {
 		/* All useless */
 		dev_err(ici->v4l2_dev.dev, "No I2C data source found!\n");
 		return -ENODEV;
diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index ff87c299f64..86934ca7335 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -34,9 +34,9 @@ static bool match_i2c(struct device *dev, struct v4l2_async_subdev *asd)
 #endif
 }
 
-static bool match_platform(struct device *dev, struct v4l2_async_subdev *asd)
+static bool match_devname(struct device *dev, struct v4l2_async_subdev *asd)
 {
-	return !strcmp(asd->match.platform.name, dev_name(dev));
+	return !strcmp(asd->match.device_name.name, dev_name(dev));
 }
 
 static LIST_HEAD(subdev_list);
@@ -53,17 +53,17 @@ static struct v4l2_async_subdev *v4l2_async_belongs(struct v4l2_async_notifier *
 
 	list_for_each_entry(asd, &notifier->waiting, list) {
 		/* bus_type has been verified valid before */
-		switch (asd->bus_type) {
-		case V4L2_ASYNC_BUS_CUSTOM:
+		switch (asd->match_type) {
+		case V4L2_ASYNC_MATCH_CUSTOM:
 			match = asd->match.custom.match;
 			if (!match)
 				/* Match always */
 				return asd;
 			break;
-		case V4L2_ASYNC_BUS_PLATFORM:
-			match = match_platform;
+		case V4L2_ASYNC_MATCH_DEVNAME:
+			match = match_devname;
 			break;
-		case V4L2_ASYNC_BUS_I2C:
+		case V4L2_ASYNC_MATCH_I2C:
 			match = match_i2c;
 			break;
 		default:
@@ -141,15 +141,15 @@ int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
 	for (i = 0; i < notifier->num_subdevs; i++) {
 		asd = notifier->subdev[i];
 
-		switch (asd->bus_type) {
-		case V4L2_ASYNC_BUS_CUSTOM:
-		case V4L2_ASYNC_BUS_PLATFORM:
-		case V4L2_ASYNC_BUS_I2C:
+		switch (asd->match_type) {
+		case V4L2_ASYNC_MATCH_CUSTOM:
+		case V4L2_ASYNC_MATCH_DEVNAME:
+		case V4L2_ASYNC_MATCH_I2C:
 			break;
 		default:
 			dev_err(notifier->v4l2_dev ? notifier->v4l2_dev->dev : NULL,
-				"Invalid bus-type %u on %p\n",
-				asd->bus_type, asd);
+				"Invalid match type %u on %p\n",
+				asd->match_type, asd);
 			return -EINVAL;
 		}
 		list_add_tail(&asd->list, &notifier->waiting);
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 <s.nawrocki@samsung.com>
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 <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/v4l2-core/v4l2-async.c | 9 +++++++++
 include/media/v4l2-async.h           | 5 +++++
 2 files changed, 14 insertions(+)

(limited to 'drivers/media/v4l2-core/v4l2-async.c')

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 <linux/mutex.h>
 
 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 <s.nawrocki@samsung.com>
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 <prabhakar.csengg@gmail.com>

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 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 'drivers/media/v4l2-core/v4l2-async.c')

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(&notifier->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 <s.nawrocki@samsung.com>
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 <prabhakar.csengg@gmail.com>

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 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 'drivers/media/v4l2-core/v4l2-async.c')

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, &notifier->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, &notifier->done);
+	list_move(&sd->async_list, &notifier->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(&notifier->list, &notifier_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(&notifier->list);
 
-	list_for_each_entry_safe(asdl, tmp, &notifier->done, list) {
-		struct v4l2_subdev *sd = v4l2_async_to_subdev(asdl);
-
+	list_for_each_entry_safe(sd, tmp, &notifier->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, &notifier_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, &notifier->waiting);
+	list_add(&sd->asd->list, &notifier->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


From 8e3fbfee23fffa2f50a36ef7b7d18092d0f57f6c Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Date: Wed, 3 Jul 2013 07:49:06 -0300
Subject: [media] v4l: async: Make it safe to unregister unregistered notifier

Calling v4l2_async_notifier_unregister() on a notifier that hasn't been
registered leads to a crash. To simplify drivers, make it safe to
unregister a notifier that has not been registered.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Tested-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/v4l2-core/v4l2-async.c | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'drivers/media/v4l2-core/v4l2-async.c')

diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index b350ab99652..10bb62cb8d7 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -192,6 +192,9 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
 	struct device *dev[n_subdev];
 	int i = 0;
 
+	if (!notifier->v4l2_dev)
+		return;
+
 	mutex_lock(&list_lock);
 
 	list_del(&notifier->list);
@@ -225,6 +228,9 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
 		}
 		put_device(d);
 	}
+
+	notifier->v4l2_dev = NULL;
+
 	/*
 	 * Don't care about the waiting list, it is initialised and populated
 	 * upon notifier registration.
-- 
cgit v1.2.3-70-g09d2


From ceedcc4ede04e069c5201748a34b2bdc044d3824 Mon Sep 17 00:00:00 2001
From: Sylwester Nawrocki <s.nawrocki@samsung.com>
Date: Wed, 31 Jul 2013 13:10:18 -0300
Subject: [media] v4l2-async: Use proper list head for iteration over
 registered subdevs

This fixes regression introduced in commit b426b3a660c85faf6e1ca1c92c6d
[media] V4L: Merge struct v4l2_async_subdev_list with struct v4l2_subdev

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
---
 drivers/media/v4l2-core/v4l2-async.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/media/v4l2-core/v4l2-async.c')

diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index 10bb62cb8d7..c85d69da35b 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -199,7 +199,7 @@ void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier)
 
 	list_del(&notifier->list);
 
-	list_for_each_entry_safe(sd, tmp, &notifier->done, list) {
+	list_for_each_entry_safe(sd, tmp, &notifier->done, async_list) {
 		dev[i] = get_device(sd->dev);
 
 		v4l2_async_cleanup(sd);
-- 
cgit v1.2.3-70-g09d2