drm/bridge: add lt9611 in the component system

Make sure the external bridge device is probed ahead
of the DRM device using the component system, because
KMS driver depends on bridge's presence to initialize
its other components.

Change-Id: Ida7310f6133b1b0d1c6c316e6dfaaa891f9653db
CRs-Fixed: 2186423
Signed-off-by: Ray Zhang <rayz@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/display/msm/sde.txt b/Documentation/devicetree/bindings/display/msm/sde.txt
index 4b4c274..0589165 100644
--- a/Documentation/devicetree/bindings/display/msm/sde.txt
+++ b/Documentation/devicetree/bindings/display/msm/sde.txt
@@ -78,6 +78,8 @@
 Optional properties:
 - clock-rate:		List of clock rates in Hz.
 - clock-max-rate:	List of maximum clock rate in Hz that this device supports.
+- connectors:		Specifies the connector components.
+- bridges:		Specifies the bridge components.
 - qcom,platform-supply-entries:	A node that lists the elements of the supply. There
 				can be more than one instance of this binding,
 				in which case the entry would be appended with
diff --git a/drivers/gpu/drm/bridge/lt9611.c b/drivers/gpu/drm/bridge/lt9611.c
index 887dd6f..1a12b0b 100644
--- a/drivers/gpu/drm/bridge/lt9611.c
+++ b/drivers/gpu/drm/bridge/lt9611.c
@@ -24,6 +24,7 @@
 #include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/interrupt.h>
+#include <linux/component.h>
 #include <linux/of_gpio.h>
 #include <linux/of_graph.h>
 #include <linux/of_irq.h>
@@ -1997,6 +1998,20 @@
 	sysfs_remove_group(&dev->kobj, &lt9611_sysfs_attr_grp);
 }
 
+static int lt9611_bind(struct device *dev, struct device *master, void *data)
+{
+	return 0;
+}
+
+static void lt9611_unbind(struct device *dev, struct device *master, void *data)
+{
+}
+
+static const struct component_ops lt9611_comp_ops = {
+	.bind = lt9611_bind,
+	.unbind = lt9611_unbind,
+};
+
 static int lt9611_probe(struct i2c_client *client,
 	 const struct i2c_device_id *id)
 {
@@ -2078,6 +2093,10 @@
 
 	drm_bridge_add(&pdata->bridge);
 
+	ret = component_add(&client->dev, &lt9611_comp_ops);
+	if (ret)
+		pr_err("component add failed, rc=%d\n", ret);
+
 	return ret;
 
 err_sysfs_init:
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index d5437d0..15fff53 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1806,6 +1806,27 @@
 	return ret;
 }
 
+static int add_bridge_components(struct device *dev,
+				  struct component_match **matchptr)
+{
+	struct device_node *node;
+
+	if (of_device_is_compatible(dev->of_node, "qcom,sde-kms")) {
+		struct device_node *np = dev->of_node;
+		unsigned int i;
+
+		for (i = 0; ; i++) {
+			node = of_parse_phandle(np, "bridges", i);
+			if (!node)
+				break;
+
+			component_match_add(dev, matchptr, compare_of, node);
+		}
+	}
+
+	return 0;
+}
+
 struct msm_gem_address_space *
 msm_gem_smmu_address_space_get(struct drm_device *dev,
 		unsigned int domain)
@@ -1897,6 +1918,10 @@
 	if (ret)
 		return ret;
 
+	ret = add_bridge_components(&pdev->dev, &match);
+	if (ret)
+		return ret;
+
 	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 	return component_master_add_with_match(&pdev->dev, &msm_drm_ops, match);
 }