[RFC PATCH V0 08/10] media: mtk-mdp3: remove illegal device node usage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch is used for review before send upstream patch.
>From Rob Herring's review comment: device node can't use same
register address as other nodes'.
Remove illegal device nodes in device tree.
MDP's sub component init need to do corresponding modification.

Signed-off-by: Moudy Ho <moudy.ho@xxxxxxxxxxxx>
---
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.c   | 224 +++++++++++++-----
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.h   |   2 +-
 2 files changed, 163 insertions(+), 63 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
index 157ef9408ed3..e89fd02bb556 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
@@ -1016,23 +1016,15 @@ static const struct of_device_id mdp_comp_dt_ids[] = {
 	{}
 };
 
-static int mdp_comp_get_id(struct device *dev, struct device_node *node,
-			   enum mdp_comp_type type)
+static int mdp_comp_get_id(enum mdp_comp_type type, u32 alias_id)
 {
-	u32 alias_id;
-	int i, ret;
-
-	ret = of_property_read_u32(node, "mediatek,mdp-id", &alias_id);
-	if (ret)
-		return ret;
+	int i;
 
 	for (i = 0; i < ARRAY_SIZE(mdp_comp_matches); i++)
 		if (mdp_comp_matches[i].type == type &&
 		    mdp_comp_matches[i].alias_id == alias_id)
 			return i;
-
-	dev_err(dev, "Failed to get id. type: %d, alias: %d\n", type, alias_id);
-	return -EINVAL;
+	return -ENODEV;
 }
 
 void mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp)
@@ -1143,33 +1135,10 @@ static void __mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
 	comp->reg_base = base;
 }
 
-static int mdp_mm_init(struct mdp_dev *mdp,
-		       struct mdp_comp *comp, const char *ref_name)
+static int mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
+			 struct mdp_comp *comp, enum mdp_comp_id id)
 {
-	struct device_node *node;
 	struct device *dev = &mdp->pdev->dev;
-
-	node = of_parse_phandle(dev->of_node, ref_name, 0);
-	if (!node) {
-		dev_err(dev, "Failed to parse dt %s\n", ref_name);
-		return -EINVAL;
-	}
-
-	__mdp_comp_init(mdp, node, comp);
-	mdp_get_subsys_id(dev, node, comp);
-	of_node_put(node);
-	if (!comp->reg_base) {
-		dev_err(dev, "Failed to init %s base\n", ref_name);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int mdp_comp_init(struct device *dev, struct mdp_dev *mdp,
-			 struct device_node *node, struct mdp_comp *comp,
-			 enum mdp_comp_id id)
-{
-	struct platform_device *pdev;
 	int i;
 
 	if (id < 0 || id >= MDP_MAX_COMP_COUNT) {
@@ -1191,32 +1160,140 @@ static int mdp_comp_init(struct device *dev, struct mdp_dev *mdp,
 
 	mdp_get_subsys_id(dev, node, comp);
 
-	/* Only DMA capable components need the pm control */
-	comp->comp_dev = NULL;
-	if (comp->type != MDP_COMP_TYPE_RDMA &&
-	    comp->type != MDP_COMP_TYPE_WROT &&
-		comp->type != MDP_COMP_TYPE_WDMA)
-		return 0;
+	return 0;
+}
 
-	pdev = of_find_device_by_node(node);
-	if (!pdev) {
-		dev_warn(dev, "can't find platform device of node:%s\n",
-			 node->name);
-		return -ENODEV;
+static struct mdp_comp *mdp_comp_create(struct mdp_dev *mdp,
+					struct device_node *node,
+					enum mdp_comp_id id)
+{
+	struct device *dev = &mdp->pdev->dev;
+	struct mdp_comp *comp;
+	int ret;
+
+	if (mdp->comp[id])
+		return ERR_PTR(-EEXIST);
+
+	comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
+	if (!comp)
+		return ERR_PTR(-ENOMEM);
+
+	ret = mdp_comp_init(mdp, node, comp, id);
+	if (ret) {
+		kfree(comp);
+		return ERR_PTR(ret);
 	}
+	mdp->comp[id] = comp;
+
+	dev_info(dev, "%s type:%d alias:%d id:%d base:%#x regs:%p\n",
+		dev->of_node->name, comp->type, comp->alias_id, id,
+		(u32)comp->reg_base, comp->regs);
+	return comp;
+}
 
-	comp->comp_dev = &pdev->dev;
-	pm_runtime_enable(comp->comp_dev);
+static int mdp_sub_comps_create(struct mdp_dev *mdp, struct device_node *node)
+{
+	struct device *dev = &mdp->pdev->dev;
+	struct property *prop;
+	const char *name;
+	int index = 0;
+
+	of_property_for_each_string(node, "mdp-comps", prop, name) {
+		const struct of_device_id *matches = mdp_comp_dt_ids;
+		enum mdp_comp_type type = MDP_COMP_NONE;
+		u32 alias_id;
+		int id, ret;
+		struct mdp_comp *comp;
 
+		for (; matches->compatible[0]; matches++) {
+			if (of_compat_cmp(name, matches->compatible,
+				strlen(matches->compatible)) == 0) {
+				type = (enum mdp_comp_type)matches->data;
+				break;
+			}
+		}
+
+		ret = of_property_read_u32_index(node, "mdp-comp-ids",
+			index, &alias_id);
+		if (ret) {
+			dev_warn(dev, "Skipping unknown component %s\n", name);
+			return ret;
+		}
+
+		id = mdp_comp_get_id(type, alias_id);
+		if (id < 0) {
+			dev_err(dev, "Failed to get component id: "
+				"%s type %d, alias %d\n", name, type, alias_id);
+			return -ENODEV;
+		}
+
+		comp = mdp_comp_create(mdp, node, id);
+		if (IS_ERR(comp))
+			return PTR_ERR(comp);
+
+		index++;
+	}
 	return 0;
 }
 
 static void mdp_comp_deinit(struct mdp_comp *comp)
 {
-	iounmap(comp->regs);
+	if (!comp)
+		return;
+
+	if (comp->regs)
+		iounmap(comp->regs);
 	/* of_node_put(comp->dev_node); */
 }
 
+static int mdp_imgi_init(struct mdp_dev *mdp, const char *ref_name)
+{
+	struct device_node *node;
+	struct device *dev = &mdp->pdev->dev;
+	int ret;
+
+	node = of_parse_phandle(dev->of_node, ref_name, 0);
+	if (!node) {
+		dev_err(dev, "Failed to parse dt %s\n", ref_name);
+		return -EINVAL;
+	}
+
+	ret = mdp_sub_comps_create(mdp, node);
+	of_node_put(node);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int mdp_mm_init(struct mdp_dev *mdp, struct mdp_comp *comp,
+		       const char *ref_name)
+{
+	struct device_node *node;
+	struct device *dev = &mdp->pdev->dev;
+	int ret;
+
+	node = of_parse_phandle(dev->of_node, ref_name, 0);
+	if (!node) {
+		dev_err(dev, "Failed to parse dt %s\n", ref_name);
+		return -EINVAL;
+	}
+
+	__mdp_comp_init(mdp, node, comp);
+	mdp_get_subsys_id(dev, node, comp);
+	if (!comp->reg_base) {
+		dev_err(dev, "Failed to init %s base\n", ref_name);
+		of_node_put(node);
+		return -EINVAL;
+	}
+
+	ret = mdp_sub_comps_create(mdp, node);
+	of_node_put(node);
+	if (ret)
+		return ret;
+	return 0;
+}
+
 void mdp_component_deinit(struct mdp_dev *mdp)
 {
 	int i;
@@ -1235,6 +1312,8 @@ int mdp_component_init(struct mdp_dev *mdp)
 {
 	struct device *dev = &mdp->pdev->dev;
 	struct device_node *node, *parent;
+	struct platform_device *pdev;
+	u32 alias_id;
 	int i, ret;
 
 	for (i = RDMA0_SOF; i < MDP_MAX_EVENT_COUNT; i++) {
@@ -1260,7 +1339,11 @@ int mdp_component_init(struct mdp_dev *mdp)
 
 	ret = mdp_mm_init(mdp, &mdp->mm_mutex, "mediatek,mm-mutex");
 	if (ret)
-		goto err_init_mm;
+		goto err_init_comps;
+
+	ret = mdp_imgi_init(mdp, "mediatek,imgsys");
+	if (ret)
+		goto err_init_comps;
 
 	parent = dev->of_node->parent;
 	/* Iterate over sibling MDP function blocks */
@@ -1281,27 +1364,44 @@ int mdp_component_init(struct mdp_dev *mdp)
 		}
 
 		type = (enum mdp_comp_type)of_id->data;
-		id = mdp_comp_get_id(dev, node, type);
-		if (id < 0) {
+		ret = of_property_read_u32(node, "mediatek,mdp-id", &alias_id);
+		if (ret) {
 			dev_warn(dev, "Skipping unknown component %pOF\n",
 				 node);
 			continue;
 		}
+		id = mdp_comp_get_id(type, alias_id);
+		if (id < 0) {
+			dev_err(dev,
+				"Fail to get component id: type %d alias %d\n",
+				type, alias_id);
+			continue;
+		}
 
-		comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
-		if (!comp) {
-			ret = -ENOMEM;
+		comp = mdp_comp_create(mdp, node, id);
+		if (IS_ERR(comp))
 			goto err_init_comps;
-		}
-		mdp->comp[id] = comp;
 
-		ret = mdp_comp_init(dev, mdp, node, comp, id);
+		ret = mdp_sub_comps_create(mdp, node);
 		if (ret)
 			goto err_init_comps;
 
-		dev_info(dev, "%s type:%d alias:%d id:%d base:%#x regs:%p\n",
-			 of_id->compatible, type, comp->alias_id, id,
-			(u32)comp->reg_base, comp->regs);
+		/* Only DMA capable components need the pm control */
+		comp->comp_dev = NULL;
+		if (comp->type != MDP_COMP_TYPE_RDMA &&
+		    comp->type != MDP_COMP_TYPE_WROT &&
+			comp->type != MDP_COMP_TYPE_WDMA)
+			continue;
+
+		pdev = of_find_device_by_node(node);
+		if (!pdev) {
+			dev_warn(dev, "can't find platform device of node:%s\n",
+				 node->name);
+			return -ENODEV;
+		}
+
+		comp->comp_dev = &pdev->dev;
+		pm_runtime_enable(comp->comp_dev);
 	}
 	return 0;
 
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
index f201bced3c06..f5d514a51236 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
@@ -112,7 +112,7 @@ struct mdp_comp {
 	void __iomem			*regs;
 	phys_addr_t			reg_base;
 	u8				subsys_id;
-	struct clk			*clks[2];
+	struct clk			*clks[4];
 	struct device			*comp_dev;
 	enum mdp_comp_type		type;
 	enum mdp_comp_id		id;
-- 
2.18.0





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux