diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index b98e602..997be15 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -50,6 +50,9 @@ static LIST_HEAD(hosts);
 static LIST_HEAD(devices);
 static DEFINE_MUTEX(list_lock);		/* Protects the list of hosts */
 
+static int soc_camera_video_start(struct soc_camera_device *icd);
+static int video_dev_create(struct soc_camera_device *icd);
+
 static struct soc_camera_device *soc_camera_device_find(struct soc_camera_link *icl)
 {
 	struct soc_camera_device *icd;
@@ -1110,15 +1113,168 @@ static void scan_add_host(struct soc_camera_host *ici)
 	mutex_unlock(&ici->host_lock);
 }
 
+/*
+ * FIXME: with internally created (I2C) clients the whole host scanning process
+ * is happening synchronously, i.e. we return from the scanning routine and
+ * complete host probing only after all clients have been enumerated. This
+ * allows us to lock the ->host_lock for the whole scan duration and thus
+ * prevent the user-space from interfering with the probing between single
+ * clients. This locking is necessary, because otherwise on a host with multiple
+ * clients, after a video device node has been registered for one of them, a
+ * user-space process, triggered by hotplug can try to access the first client
+ * and thereby occupy the host, which will disturb probing of further clients.
+ * With externally registered clients (host_wait == true) we use (I2C) bus
+ * notifications to complete client probing. Those notifications are called
+ * asynchronously after the host probing routine has returned. Besides, it can
+ * happen, that the notification is called much later or never at all. In this
+ * case we cannot keep the host locked until all client notifications have been
+ * called.
+ */
+static int soc_camera_probe_finish(struct soc_camera_device *icd)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	struct v4l2_subdev *sd;
+	struct v4l2_mbus_framefmt mf;
+	int ret;
+
+	sd = soc_camera_to_subdev(icd);
+	sd->grp_id = soc_camera_grp_id(icd);
+	v4l2_set_subdev_hostdata(sd, icd);
+
+	ret = v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler);
+	if (ret < 0)
+		return ret;
+
+	/* At this point client .probe() should have run already */
+	ret = soc_camera_init_user_formats(icd);
+	if (ret < 0)
+		return ret;
+
+	icd->field = V4L2_FIELD_ANY;
+
+	/*
+	 * ..._video_start() will create a device node, video_register_device()
+	 * itself is protected against concurrent open() calls, but we also have
+	 * to protect our data.
+	 */
+	mutex_lock(&icd->video_lock);
+
+	ret = soc_camera_video_start(icd);
+	if (ret < 0)
+		goto evidstart;
+
+	/* Try to improve our guess of a reasonable window format */
+	ret = ici->ops->add(icd);
+	if (ret < 0)
+		goto eadd;
+	if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
+		icd->user_width		= mf.width;
+		icd->user_height	= mf.height;
+		icd->colorspace		= mf.colorspace;
+		icd->field		= mf.field;
+	}
+
+	ici->ops->remove(icd);
+
+	mutex_unlock(&icd->video_lock);
+
+	return 0;
+
+eadd:
+	video_unregister_device(icd->vdev);
+	icd->vdev = NULL;
+evidstart:
+	mutex_unlock(&icd->video_lock);
+	soc_camera_free_user_formats(icd);
+
+	return ret;
+}
+
 #ifdef CONFIG_I2C_BOARDINFO
-static int soc_camera_init_i2c(struct soc_camera_device *icd,
+static int soc_camera_i2c_notify(struct notifier_block *nb,
+				 unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct soc_camera_device *icd = container_of(nb, struct soc_camera_device, notifier);
+	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
+	struct i2c_adapter *adap = NULL;
+	struct v4l2_subdev *subdev;
+	int ret;
+
+	if (client->addr != icl->board_info->addr ||
+	    client->adapter->nr != icl->i2c_adapter_id)
+		return NOTIFY_DONE;
+
+	switch (action) {
+	case BUS_NOTIFY_BIND_DRIVER:
+		client->dev.platform_data = icl;
+
+		return NOTIFY_OK;
+	case BUS_NOTIFY_BOUND_DRIVER:
+		adap = i2c_get_adapter(icl->i2c_adapter_id);
+		if (!adap)
+			break;
+
+		if (!try_module_get(dev->driver->owner))
+			/* clean up */
+			break;
+
+		subdev = i2c_get_clientdata(client);
+
+		if (v4l2_device_register_subdev(&ici->v4l2_dev, subdev))
+			subdev = NULL;
+
+		module_put(client->driver->driver.owner);
+
+		if (!subdev)
+			break;
+		client = v4l2_get_subdevdata(subdev);
+		icd->control = &client->dev;
+		mutex_lock(&ici->host_lock);
+		ret = soc_camera_probe_finish(icd);
+		mutex_unlock(&ici->host_lock);
+		if (ret < 0)
+			break;
+
+		return NOTIFY_OK;
+	default:
+		return NOTIFY_DONE;
+	}
+
+	if (adap)
+		i2c_put_adapter(adap);
+	if (icd->vdev) {
+		video_device_release(icd->vdev);
+		icd->vdev = NULL;
+	}
+	regulator_bulk_free(icl->num_regulators, icl->regulators);
+	v4l2_ctrl_handler_free(&icd->ctrl_handler);
+
+	return NOTIFY_DONE;
+}
+
+static int soc_camera_i2c_init(struct soc_camera_device *icd,
 			       struct soc_camera_link *icl)
 {
 	struct i2c_client *client;
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
-	struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
+	struct soc_camera_host *ici;
+	struct i2c_adapter *adap;
 	struct v4l2_subdev *subdev;
 
+	if (icl->host_wait) {
+		int ret;
+		icd->notifier.notifier_call = soc_camera_i2c_notify;
+		ret = bus_register_notifier(&i2c_bus_type, &icd->notifier);
+		if (!ret)
+			return -EPROBE_DEFER;
+		return ret;
+	}
+
+	ici = to_soc_camera_host(icd->parent);
+	adap = i2c_get_adapter(icl->i2c_adapter_id);
+
 	if (!adap) {
 		dev_err(icd->pdev, "Cannot get I2C adapter #%d. No driver?\n",
 			icl->i2c_adapter_id);
@@ -1144,7 +1300,7 @@ ei2cga:
 	return -ENODEV;
 }
 
-static void soc_camera_free_i2c(struct soc_camera_device *icd)
+static void soc_camera_i2c_free(struct soc_camera_device *icd)
 {
 	struct i2c_client *client =
 		to_i2c_client(to_soc_camera_control(icd));
@@ -1155,21 +1311,38 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd)
 	i2c_unregister_device(client);
 	i2c_put_adapter(adap);
 }
+
+static void soc_camera_i2c_reprobe(struct soc_camera_device *icd)
+{
+	struct i2c_client *client =
+		to_i2c_client(to_soc_camera_control(icd));
+	struct i2c_adapter *adap;
+
+	if (icd->notifier.notifier_call == soc_camera_i2c_notify)
+		bus_unregister_notifier(&i2c_bus_type, &icd->notifier);
+
+	if (!icd->control)
+		return;
+
+	adap = client->adapter;
+
+	icd->control = NULL;
+	v4l2_device_unregister_subdev(i2c_get_clientdata(client));
+	/* Put device back in deferred-probing state */
+	i2c_unregister_device(client);
+	i2c_new_device(adap, icd->link->board_info);
+}
 #else
-#define soc_camera_init_i2c(icd, icl)	(-ENODEV)
-#define soc_camera_free_i2c(icd)	do {} while (0)
+#define soc_camera_i2c_init(icd, icl)	(-ENODEV)
+#define soc_camera_i2c_free(icd)	do {} while (0)
+#define soc_camera_i2c_reprobe(icd)	do {} while (0)
 #endif
 
-static int soc_camera_video_start(struct soc_camera_device *icd);
-static int video_dev_create(struct soc_camera_device *icd);
 /* Called during host-driver probe */
 static int soc_camera_probe(struct soc_camera_device *icd)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
 	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	struct device *control = NULL;
-	struct v4l2_subdev *sd;
-	struct v4l2_mbus_framefmt mf;
 	int ret;
 
 	dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev));
@@ -1201,7 +1374,9 @@ static int soc_camera_probe(struct soc_camera_device *icd)
 
 	/* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
 	if (icl->board_info) {
-		ret = soc_camera_init_i2c(icd, icl);
+		ret = soc_camera_i2c_init(icd, icl);
+		if (ret == -EPROBE_DEFER)
+			return 0;
 		if (ret < 0)
 			goto eadddev;
 	} else if (!icl->add_device || !icl->del_device) {
@@ -1228,58 +1403,15 @@ static int soc_camera_probe(struct soc_camera_device *icd)
 		}
 	}
 
-	sd = soc_camera_to_subdev(icd);
-	sd->grp_id = soc_camera_grp_id(icd);
-	v4l2_set_subdev_hostdata(sd, icd);
-
-	if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler))
-		goto ectrl;
-
-	/* At this point client .probe() should have run already */
-	ret = soc_camera_init_user_formats(icd);
-	if (ret < 0)
-		goto eiufmt;
-
-	icd->field = V4L2_FIELD_ANY;
-
-	/*
-	 * ..._video_start() will create a device node, video_register_device()
-	 * itself is protected against concurrent open() calls, but we also have
-	 * to protect our data.
-	 */
-	mutex_lock(&icd->video_lock);
-
-	ret = soc_camera_video_start(icd);
-	if (ret < 0)
-		goto evidstart;
-
-	/* Try to improve our guess of a reasonable window format */
-	ret = ici->ops->add(icd);
+	ret = soc_camera_probe_finish(icd);
 	if (ret < 0)
-		goto eadd;
-	if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
-		icd->user_width		= mf.width;
-		icd->user_height	= mf.height;
-		icd->colorspace		= mf.colorspace;
-		icd->field		= mf.field;
-	}
-
-	ici->ops->remove(icd);
-
-	mutex_unlock(&icd->video_lock);
+		goto efinish;
 
 	return 0;
 
-eadd:
-	video_unregister_device(icd->vdev);
-	icd->vdev = NULL;
-evidstart:
-	mutex_unlock(&icd->video_lock);
-	soc_camera_free_user_formats(icd);
-eiufmt:
-ectrl:
+efinish:
 	if (icl->board_info) {
-		soc_camera_free_i2c(icd);
+		soc_camera_i2c_free(icd);
 	} else {
 		icl->del_device(icd);
 		module_put(control->driver->owner);
@@ -1315,7 +1447,10 @@ static int soc_camera_remove(struct soc_camera_device *icd)
 	}
 
 	if (icl->board_info) {
-		soc_camera_free_i2c(icd);
+		if (icl->host_wait)
+			soc_camera_i2c_reprobe(icd);
+		else
+			soc_camera_i2c_free(icd);
 	} else {
 		struct device_driver *drv = to_soc_camera_control(icd)->driver;
 		if (drv) {
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 72342fe..1d4e3c5 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -50,6 +50,7 @@ struct soc_camera_device {
 	int use_count;
 	struct mutex video_lock;	/* Protects device data */
 	struct file *streamer;		/* stream owner */
+	struct notifier_block notifier;	/* Bus-event notifier */
 	union {
 		struct videobuf_queue vb_vidq;
 		struct vb2_queue vb2_vidq;
@@ -125,6 +126,7 @@ struct soc_camera_link {
 	int i2c_adapter_id;
 	struct i2c_board_info *board_info;
 	const char *module_name;
+	bool host_wait;
 	void *priv;
 
 	/* Optional regulators that have to be managed on power on/off events */
