Modify the driver to invoke callbacks for the next bridge
in the bridge chain.
Also, remove the drm_connector implementation from ptn3460,
since the same is implemented using panel_binder.

Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
---
 drivers/gpu/drm/bridge/ptn3460.c        |  136 +++++--------------------------
 drivers/gpu/drm/exynos/exynos_dp_core.c |   16 ++--
 include/drm/bridge/ptn3460.h            |   15 ++--
 3 files changed, 39 insertions(+), 128 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c
index 98fd17a..21e9db8 100644
--- a/drivers/gpu/drm/bridge/ptn3460.c
+++ b/drivers/gpu/drm/bridge/ptn3460.c
@@ -34,37 +34,15 @@
 #define PTN3460_EDID_SRAM_LOAD_ADDR            0x85

 struct ptn3460_bridge {
-       struct drm_connector connector;
        struct i2c_client *client;
        struct drm_encoder *encoder;
        struct drm_bridge *bridge;
-       struct edid *edid;
        int gpio_pd_n;
        int gpio_rst_n;
        u32 edid_emulation;
        bool enabled;
 };

-static int ptn3460_read_bytes(struct ptn3460_bridge *ptn_bridge, char addr,
-               u8 *buf, int len)
-{
-       int ret;
-
-       ret = i2c_master_send(ptn_bridge->client, &addr, 1);
-       if (ret <= 0) {
-               DRM_ERROR("Failed to send i2c command, ret=%d\n", ret);
-               return ret;
-       }
-
-       ret = i2c_master_recv(ptn_bridge->client, buf, len);
-       if (ret <= 0) {
-               DRM_ERROR("Failed to recv i2c data, ret=%d\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
 static int ptn3460_write_byte(struct ptn3460_bridge *ptn_bridge, char addr,
                char val)
 {
@@ -126,6 +104,8 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge)
                gpio_set_value(ptn_bridge->gpio_rst_n, 1);
        }

+       drm_next_bridge_pre_enable(bridge);
+
        /*
         * There's a bug in the PTN chip where it falsely asserts hotplug before
         * it is fully functional. We're forced to wait for the maximum start up
@@ -142,6 +122,7 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge)

 static void ptn3460_enable(struct drm_bridge *bridge)
 {
+       drm_next_bridge_enable(bridge);
 }

 static void ptn3460_disable(struct drm_bridge *bridge)
@@ -153,6 +134,8 @@ static void ptn3460_disable(struct drm_bridge *bridge)

        ptn_bridge->enabled = false;

+       drm_next_bridge_disable(bridge);
+
        if (gpio_is_valid(ptn_bridge->gpio_rst_n))
                gpio_set_value(ptn_bridge->gpio_rst_n, 1);

@@ -162,6 +145,7 @@ static void ptn3460_disable(struct drm_bridge *bridge)

 static void ptn3460_post_disable(struct drm_bridge *bridge)
 {
+       drm_next_bridge_post_disable(bridge);
 }

 void ptn3460_bridge_destroy(struct drm_bridge *bridge)
@@ -173,6 +157,9 @@ void ptn3460_bridge_destroy(struct drm_bridge *bridge)
                gpio_free(ptn_bridge->gpio_pd_n);
        if (gpio_is_valid(ptn_bridge->gpio_rst_n))
                gpio_free(ptn_bridge->gpio_rst_n);
+
+       drm_next_bridge_destroy(bridge);
+
        /* Nothing else to free, we've got devm allocated memory */
 }

@@ -184,81 +171,10 @@ struct drm_bridge_funcs ptn3460_bridge_funcs = {
        .destroy = ptn3460_bridge_destroy,
 };

-int ptn3460_get_modes(struct drm_connector *connector)
-{
-       struct ptn3460_bridge *ptn_bridge;
-       u8 *edid;
-       int ret, num_modes;
-       bool power_off;
-
-       ptn_bridge = container_of(connector, struct ptn3460_bridge, connector);
-
-       if (ptn_bridge->edid)
-               return drm_add_edid_modes(connector, ptn_bridge->edid);
-
-       power_off = !ptn_bridge->enabled;
-       ptn3460_pre_enable(ptn_bridge->bridge);
-
-       edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
-       if (!edid) {
-               DRM_ERROR("Failed to allocate edid\n");
-               return 0;
-       }
-
-       ret = ptn3460_read_bytes(ptn_bridge, PTN3460_EDID_ADDR, edid,
-                       EDID_LENGTH);
-       if (ret) {
-               kfree(edid);
-               num_modes = 0;
-               goto out;
-       }
-
-       ptn_bridge->edid = (struct edid *)edid;
-       drm_mode_connector_update_edid_property(connector, ptn_bridge->edid);
-
-       num_modes = drm_add_edid_modes(connector, ptn_bridge->edid);
-
-out:
-       if (power_off)
-               ptn3460_disable(ptn_bridge->bridge);
-
-       return num_modes;
-}
-
-struct drm_encoder *ptn3460_best_encoder(struct drm_connector *connector)
-{
-       struct ptn3460_bridge *ptn_bridge;
-
-       ptn_bridge = container_of(connector, struct ptn3460_bridge, connector);
-
-       return ptn_bridge->encoder;
-}
-
-struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {
-       .get_modes = ptn3460_get_modes,
-       .best_encoder = ptn3460_best_encoder,
-};
-
-enum drm_connector_status ptn3460_detect(struct drm_connector *connector,
-               bool force)
-{
-       return connector_status_connected;
-}
-
-void ptn3460_connector_destroy(struct drm_connector *connector)
-{
-       drm_connector_cleanup(connector);
-}
-
-struct drm_connector_funcs ptn3460_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .detect = ptn3460_detect,
-       .destroy = ptn3460_connector_destroy,
-};
-
-int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
-               struct i2c_client *client, struct device_node *node)
+struct drm_bridge *ptn3460_init(struct drm_device *dev,
+                               struct drm_encoder *encoder,
+                               struct i2c_client *client,
+                               struct device_node *node)
 {
        int ret;
        struct drm_bridge *bridge;
@@ -267,13 +183,13 @@ int ptn3460_init(struct drm_device *dev, struct 
drm_encoder *encoder,
        bridge = devm_kzalloc(dev->dev, sizeof(*bridge), GFP_KERNEL);
        if (!bridge) {
                DRM_ERROR("Failed to allocate drm bridge\n");
-               return -ENOMEM;
+               return NULL;
        }

        ptn_bridge = devm_kzalloc(dev->dev, sizeof(*ptn_bridge), GFP_KERNEL);
        if (!ptn_bridge) {
                DRM_ERROR("Failed to allocate ptn bridge\n");
-               return -ENOMEM;
+               return NULL;
        }

        ptn_bridge->client = client;
@@ -285,7 +201,7 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder 
*encoder,
                                GPIOF_OUT_INIT_HIGH, "PTN3460_PD_N");
                if (ret) {
                        DRM_ERROR("Request powerdown-gpio failed (%d)\n", ret);
-                       return ret;
+                       return NULL;
                }
        }

@@ -300,7 +216,7 @@ int ptn3460_init(struct drm_device *dev, struct drm_encoder 
*encoder,
                if (ret) {
                        DRM_ERROR("Request reset-gpio failed (%d)\n", ret);
                        gpio_free(ptn_bridge->gpio_pd_n);
-                       return ret;
+                       return NULL;
                }
        }

@@ -318,26 +234,18 @@ int ptn3460_init(struct drm_device *dev, struct 
drm_encoder *encoder,
        }

        bridge->driver_private = ptn_bridge;
-       encoder->bridge = bridge;

-       ret = drm_connector_init(dev, &ptn_bridge->connector,
-                       &ptn3460_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
-       if (ret) {
-               DRM_ERROR("Failed to initialize connector with drm\n");
-               goto err;
-       }
-       drm_connector_helper_add(&ptn_bridge->connector,
-                       &ptn3460_connector_helper_funcs);
-       drm_sysfs_connector_add(&ptn_bridge->connector);
-       drm_mode_connector_attach_encoder(&ptn_bridge->connector, encoder);
+       if (!encoder->bridge)
+               /* First entry in the bridge chain */
+               encoder->bridge = bridge;

-       return 0;
+       return bridge;

 err:
        if (gpio_is_valid(ptn_bridge->gpio_pd_n))
                gpio_free(ptn_bridge->gpio_pd_n);
        if (gpio_is_valid(ptn_bridge->gpio_rst_n))
                gpio_free(ptn_bridge->gpio_rst_n);
-       return ret;
+       return NULL;
 }
 EXPORT_SYMBOL(ptn3460_init);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c 
b/drivers/gpu/drm/exynos/exynos_dp_core.c
index aca739d..d8546ea 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -988,19 +988,19 @@ static bool find_bridge(const char *compat, struct 
bridge_init *bridge)
        return true;
 }

-/* returns the number of bridges attached */
-static int exynos_drm_attach_lcd_bridge(struct drm_device *dev,
+static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
                struct drm_encoder *encoder)
 {
        struct bridge_init bridge;
-       int ret;
+       struct drm_bridge *bridge_chain = NULL;
+       bool connector_created = false;

        if (find_bridge("nxp,ptn3460", &bridge)) {
-               ret = ptn3460_init(dev, encoder, bridge.client, bridge.node);
-               if (!ret)
-                       return 1;
+               bridge_chain = ptn3460_init(dp->drm_dev, encoder, bridge.client,
+                                                               bridge.node);
        }
-       return 0;
+
+       return connector_created;
 }

 static int exynos_dp_create_connector(struct exynos_drm_display *display,
@@ -1013,7 +1013,7 @@ static int exynos_dp_create_connector(struct 
exynos_drm_display *display,
        dp->encoder = encoder;

        /* Pre-empt DP connector creation if there's a bridge */
-       ret = exynos_drm_attach_lcd_bridge(dp->drm_dev, encoder);
+       ret = exynos_drm_attach_lcd_bridge(dp, encoder);
        if (ret)
                return 0;

diff --git a/include/drm/bridge/ptn3460.h b/include/drm/bridge/ptn3460.h
index ff62344..f612b9b 100644
--- a/include/drm/bridge/ptn3460.h
+++ b/include/drm/bridge/ptn3460.h
@@ -21,15 +21,18 @@ struct device_node;

 #if defined(CONFIG_DRM_PTN3460) || defined(CONFIG_DRM_PTN3460_MODULE)

-int ptn3460_init(struct drm_device *dev, struct drm_encoder *encoder,
-               struct i2c_client *client, struct device_node *node);
+struct drm_bridge *ptn3460_init(struct drm_device *dev,
+                               struct drm_encoder *encoder,
+                               struct i2c_client *client,
+                               struct device_node *node);
 #else

-static inline int ptn3460_init(struct drm_device *dev,
-               struct drm_encoder *encoder, struct i2c_client *client,
-               struct device_node *node)
+static inline struct drm_bridge *ptn3460_init(struct drm_device *dev,
+                                               struct drm_encoder *encoder,
+                                               struct i2c_client *client,
+                                               struct device_node *node)
 {
-       return 0;
+       return NULL;
 }

 #endif
-- 
1.7.9.5

Reply via email to