summaryrefslogtreecommitdiffstats
path: root/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0447-media-soc_camera-rcar_vin-Fix-crash-when-the-module-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0447-media-soc_camera-rcar_vin-Fix-crash-when-the-module-.patch')
-rw-r--r--bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0447-media-soc_camera-rcar_vin-Fix-crash-when-the-module-.patch75
1 files changed, 75 insertions, 0 deletions
diff --git a/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0447-media-soc_camera-rcar_vin-Fix-crash-when-the-module-.patch b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0447-media-soc_camera-rcar_vin-Fix-crash-when-the-module-.patch
new file mode 100644
index 00000000..c6b384e8
--- /dev/null
+++ b/bsp/meta-rcar/meta-rcar-gen3-adas/recipes-kernel/linux/linux-renesas/0447-media-soc_camera-rcar_vin-Fix-crash-when-the-module-.patch
@@ -0,0 +1,75 @@
+From b7b603c33d7cc369f1165773a0f3fa14f7f71baf Mon Sep 17 00:00:00 2001
+From: Valentine Barshak <valentine.barshak@cogentembedded.com>
+Date: Sun, 8 Dec 2019 01:30:38 +0300
+Subject: [PATCH] media: soc_camera: rcar_vin: Fix crash when the module is
+ removed
+
+The kernel may crash when removing rcar_csi2 or re-inserting
+rcar_vin module after having removed it. This happens when
+multiple ports are used. Multiple async clients are created
+in this case. Each client registers a notifier which is added
+to the notifier_list. However, only the last one, referenced
+by the async_client pointer, is removed form the notifier_list
+later when the rcar_vin module is removed.
+
+Fix this issue by using a linked list and removing all the
+async clients in the list when removing rcar_vin device.
+
+Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com>
+---
+ drivers/media/platform/soc_camera/rcar_vin.c | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
+index 501598c..e13a046 100644
+--- a/drivers/media/platform/soc_camera/rcar_vin.c
++++ b/drivers/media/platform/soc_camera/rcar_vin.c
+@@ -922,7 +922,7 @@ struct rcar_vin_priv {
+ bool deser_sync;
+ int lut_updated;
+
+- struct rcar_vin_async_client *async_client;
++ struct list_head async_client;
+ /* Asynchronous CSI2 linking */
+ struct v4l2_subdev *csi2_sd;
+ /* Asynchronous Deserializer linking */
+@@ -3032,7 +3032,7 @@ static int rcar_vin_soc_of_bind(struct rcar_vin_priv *priv,
+ sasc->notifier.num_subdevs = 1;
+ sasc->notifier.ops = &rcar_vin_sensor_ops;
+
+- priv->async_client = sasc;
++ list_add(&sasc->list, &priv->async_client);
+
+ client = of_find_i2c_device_by_node(remote);
+
+@@ -3368,6 +3368,7 @@ static int rcar_vin_probe(struct platform_device *pdev)
+
+ spin_lock_init(&priv->lock);
+ INIT_LIST_HEAD(&priv->capture);
++ INIT_LIST_HEAD(&priv->async_client);
+
+ priv->state = STOPPED;
+
+@@ -3417,11 +3418,16 @@ static int rcar_vin_remove(struct platform_device *pdev)
+ struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
+ struct rcar_vin_priv *priv = container_of(soc_host,
+ struct rcar_vin_priv, ici);
++ struct rcar_vin_async_client *sasc, *tmp;
+
+- platform_device_del(priv->async_client->pdev);
+- platform_device_put(priv->async_client->pdev);
++ list_for_each_entry_safe(sasc, tmp, &priv->async_client, list) {
++ v4l2_async_notifier_unregister(&sasc->notifier);
++ v4l2_async_notifier_cleanup(&sasc->notifier);
++ list_del(&sasc->list);
+
+- v4l2_async_notifier_unregister(&priv->async_client->notifier);
++ platform_device_del(sasc->pdev);
++ platform_device_put(sasc->pdev);
++ }
+
+ soc_camera_host_unregister(soc_host);
+ pm_runtime_disable(&pdev->dev);
+--
+2.7.4
+