diff mbox

[V2,3/4] exynos4-is: Remove requirement for "simple-bus" compatible

Message ID 1399570583-29824-1-git-send-email-s.nawrocki@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

This patch makes the driver instantiating its child devices itself,
rather than relying on an OS to instantiate devices as children
of "simple-bus". This removes an incorrect usage of "simple-bus"
compatible.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
---
This patch addresses Mark's review comments:
https://patchwork.linuxtv.org/patch/23008/
---
 .../devicetree/bindings/media/samsung-fimc.txt     |    6 +++---
 drivers/media/platform/exynos4-is/fimc-is.c        |   16 +++++++++++++--
 drivers/media/platform/exynos4-is/media-dev.c      |   21 ++++++++++++++++----
 3 files changed, 34 insertions(+), 9 deletions(-)
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt
index 922d6f8..8ce5984 100644
--- a/Documentation/devicetree/bindings/media/samsung-fimc.txt
+++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt
@@ -15,9 +15,9 @@  Common 'camera' node
 
 Required properties:
 
-- compatible: must be "samsung,fimc", "simple-bus"
+- compatible: should be "samsung,fimc",
 - clocks: list of clock specifiers, corresponding to entries in
-  the clock-names property;
+  the clock-names property,
 - clock-names : must contain "sclk_cam0", "sclk_cam1", "pxl_async0",
   "pxl_async1" entries, matching entries in the clocks property.
 
@@ -157,7 +157,7 @@  Example:
 	};
 
 	camera {
-		compatible = "samsung,fimc", "simple-bus";
+		compatible = "samsung,fimc";
 		clocks = <&clock 132>, <&clock 133>, <&clock 351>,
 			 <&clock 352>;
 		clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0",
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
index 6bbb6ca..4be3dd8 100644
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ b/drivers/media/platform/exynos4-is/fimc-is.c
@@ -24,6 +24,7 @@ 
 #include <linux/i2c.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/of_graph.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
@@ -221,10 +222,9 @@  static int fimc_is_register_subdevs(struct fimc_is *is)
 	return 0;
 }
 
-static int fimc_is_unregister_subdevs(struct fimc_is *is)
+static void fimc_is_unregister_subdevs(struct fimc_is *is)
 {
 	fimc_isp_subdev_destroy(&is->isp);
-	return 0;
 }
 
 static int fimc_is_load_setfile(struct fimc_is *is, char *file_name)
@@ -774,6 +774,8 @@  static int fimc_is_runtime_suspend(struct device *dev);
 static int fimc_is_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	bool create_children = !of_device_is_compatible(dev->of_node,
+						       "simple-bus");
 	struct fimc_is *is;
 	struct resource res;
 	struct device_node *node;
@@ -801,6 +803,12 @@  static int fimc_is_probe(struct platform_device *pdev)
 	if (!node)
 		return -ENODEV;
 
+	if (create_children) {
+		ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+		if (ret < 0)
+			return ret;
+	}
+
 	is->pmu_regs = of_iomap(node, 0);
 	if (!is->pmu_regs)
 		return -ENOMEM;
@@ -868,6 +876,9 @@  err_irq:
 	free_irq(is->irq, is);
 err_clk:
 	fimc_is_put_clocks(is);
+	if (create_children)
+		of_device_destroy_children(dev);
+
 	return ret;
 }
 
@@ -928,6 +939,7 @@  static int fimc_is_remove(struct platform_device *pdev)
 		release_firmware(is->fw.f_w);
 	fimc_is_free_cpu_memory(is);
 
+	of_device_destroy_children(dev);
 	return 0;
 }
 
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 344718d..f6d89ac 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -622,13 +622,13 @@  dev_unlock:
 }
 
 /* Register FIMC, FIMC-LITE and CSIS media entities */
-static int fimc_md_register_platform_entities(struct fimc_md *fmd,
-					      struct device_node *parent)
+static int fimc_md_register_platform_entities(struct fimc_md *fmd)
 {
+	struct device *parent = &fmd->pdev->dev;
 	struct device_node *node;
 	int ret = 0;
 
-	for_each_available_child_of_node(parent, node) {
+	for_each_available_child_of_node(parent->of_node, node) {
 		struct platform_device *pdev;
 		int plat_entity = -1;
 
@@ -651,6 +651,7 @@  static int fimc_md_register_platform_entities(struct fimc_md *fmd,
 			ret = fimc_md_register_platform_entity(fmd, pdev,
 							plat_entity);
 		put_device(&pdev->dev);
+
 		if (ret < 0)
 			break;
 	}
@@ -1318,6 +1319,8 @@  unlock:
 static int fimc_md_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	bool create_children = !of_device_is_compatible(dev->of_node,
+						       "simple-bus");
 	struct v4l2_device *v4l2_dev;
 	struct fimc_md *fmd;
 	int ret;
@@ -1343,6 +1346,14 @@  static int fimc_md_probe(struct platform_device *pdev)
 	fmd->use_isp = fimc_md_is_isp_available(dev->of_node);
 	fmd->user_subdev_api = true;
 
+	if (create_children) {
+		ret = of_platform_populate(dev->of_node,
+					   of_default_bus_match_table,
+					   NULL, dev);
+		if (ret < 0)
+			return ret;
+	}
+
 	ret = v4l2_device_register(dev, &fmd->v4l2_dev);
 	if (ret < 0) {
 		v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
@@ -1371,7 +1382,7 @@  static int fimc_md_probe(struct platform_device *pdev)
 	/* Protect the media graph while we're registering entities */
 	mutex_lock(&fmd->media_dev.graph_mutex);
 
-	ret = fimc_md_register_platform_entities(fmd, dev->of_node);
+	ret = fimc_md_register_platform_entities(fmd);
 	if (ret) {
 		mutex_unlock(&fmd->media_dev.graph_mutex);
 		goto err_clk;
@@ -1426,6 +1437,8 @@  err_md:
 	media_device_unregister(&fmd->media_dev);
 err_v4l2_dev:
 	v4l2_device_unregister(&fmd->v4l2_dev);
+	if (create_children)
+		of_device_destroy_children(dev);
 	return ret;
 }