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

From: Sylwester Nawrocki
Date: Thu May 08 2014 - 13:36:53 EST


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@xxxxxxxxxxx>
Acked-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
---
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 --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;
}

--
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/