Now that we have an attach hook available for panels as well, let's use
it for the RaspberryPi 7" DSI panel.

This now mimics what all the other bridges in a similar situation are
doing, and we avoid our probe order issue entirely.

Signed-off-by: Maxime Ripard <max...@cerno.tech>
---
 .../drm/panel/panel-raspberrypi-touchscreen.c | 135 ++++++++++--------
 1 file changed, 77 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c 
b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
index 462faae0f446..995c5cafb970 100644
--- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
+++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c
@@ -346,7 +346,83 @@ static int rpi_touchscreen_get_modes(struct drm_panel 
*panel,
        return num;
 }
 
+static int rpi_touchscreen_attach(struct drm_panel *panel)
+{
+       struct rpi_touchscreen *ts = panel_to_ts(panel);
+       struct device *dev = &ts->i2c->dev;
+       struct device_node *endpoint, *dsi_host_node;
+       struct mipi_dsi_device *dsi;
+       struct mipi_dsi_host *host;
+       int ret;
+
+       struct mipi_dsi_device_info info = {
+               .type = RPI_DSI_DRIVER_NAME,
+               .channel = 0,
+               .node = NULL,
+       };
+
+       /* Look up the DSI host.  It needs to probe before we do. */
+       endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+       if (!endpoint)
+               return -ENODEV;
+
+       dsi_host_node = of_graph_get_remote_port_parent(endpoint);
+       if (!dsi_host_node) {
+               of_node_put(endpoint);
+               return -ENODEV;
+       }
+
+       host = of_find_mipi_dsi_host_by_node(dsi_host_node);
+       of_node_put(dsi_host_node);
+       if (!host) {
+               of_node_put(endpoint);
+               return -EPROBE_DEFER;
+       }
+
+       info.node = of_graph_get_remote_port(endpoint);
+       if (!info.node) {
+               of_node_put(endpoint);
+               return -ENODEV;
+       }
+
+       of_node_put(endpoint);
+
+       dsi = mipi_dsi_device_register_full(host, &info);
+       if (IS_ERR(dsi)) {
+               dev_err(dev, "DSI device registration failed: %ld\n",
+                       PTR_ERR(dsi));
+               return PTR_ERR(dsi);
+       }
+
+       ts->dsi = dsi;
+
+       dsi->mode_flags = (MIPI_DSI_MODE_VIDEO |
+                          MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+                          MIPI_DSI_MODE_LPM);
+       dsi->format = MIPI_DSI_FMT_RGB888;
+       dsi->lanes = 1;
+
+       ret = mipi_dsi_attach(dsi);
+       if (ret) {
+               dev_err(&dsi->dev, "failed to attach dsi to host: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static void rpi_touchscreen_detach(struct drm_panel *panel)
+{
+       struct rpi_touchscreen *ts = panel_to_ts(panel);
+
+       mipi_dsi_detach(ts->dsi);
+       mipi_dsi_device_unregister(ts->dsi);
+}
+
 static const struct drm_panel_funcs rpi_touchscreen_funcs = {
+       .attach = rpi_touchscreen_attach,
+       .detach = rpi_touchscreen_detach,
+
        .disable = rpi_touchscreen_disable,
        .unprepare = rpi_touchscreen_noop,
        .prepare = rpi_touchscreen_noop,
@@ -359,14 +435,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,
 {
        struct device *dev = &i2c->dev;
        struct rpi_touchscreen *ts;
-       struct device_node *endpoint, *dsi_host_node;
-       struct mipi_dsi_host *host;
        int ver;
-       struct mipi_dsi_device_info info = {
-               .type = RPI_DSI_DRIVER_NAME,
-               .channel = 0,
-               .node = NULL,
-       };
 
        ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
        if (!ts)
@@ -394,35 +463,6 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,
        /* /\* Turn off at boot, so we can cleanly sequence powering on. *\/ */
        /* rpi_touchscreen_i2c_write(ts, REG_POWERON, 0); */
 
-       /* Look up the DSI host.  It needs to probe before we do. */
-       endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
-       if (!endpoint)
-               return -ENODEV;
-
-       dsi_host_node = of_graph_get_remote_port_parent(endpoint);
-       if (!dsi_host_node)
-               goto error;
-
-       host = of_find_mipi_dsi_host_by_node(dsi_host_node);
-       of_node_put(dsi_host_node);
-       if (!host) {
-               of_node_put(endpoint);
-               return -EPROBE_DEFER;
-       }
-
-       info.node = of_graph_get_remote_port(endpoint);
-       if (!info.node)
-               goto error;
-
-       of_node_put(endpoint);
-
-       ts->dsi = mipi_dsi_device_register_full(host, &info);
-       if (IS_ERR(ts->dsi)) {
-               dev_err(dev, "DSI device registration failed: %ld\n",
-                       PTR_ERR(ts->dsi));
-               return PTR_ERR(ts->dsi);
-       }
-
        drm_panel_init(&ts->base, dev, &rpi_touchscreen_funcs,
                       DRM_MODE_CONNECTOR_DSI);
 
@@ -432,41 +472,20 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c,
        drm_panel_add(&ts->base);
 
        return 0;
-
-error:
-       of_node_put(endpoint);
-       return -ENODEV;
 }
 
 static int rpi_touchscreen_remove(struct i2c_client *i2c)
 {
        struct rpi_touchscreen *ts = i2c_get_clientdata(i2c);
 
-       mipi_dsi_detach(ts->dsi);
-
        drm_panel_remove(&ts->base);
 
-       mipi_dsi_device_unregister(ts->dsi);
-
        return 0;
 }
 
 static int rpi_touchscreen_dsi_probe(struct mipi_dsi_device *dsi)
 {
-       int ret;
-
-       dsi->mode_flags = (MIPI_DSI_MODE_VIDEO |
-                          MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
-                          MIPI_DSI_MODE_LPM);
-       dsi->format = MIPI_DSI_FMT_RGB888;
-       dsi->lanes = 1;
-
-       ret = mipi_dsi_attach(dsi);
-
-       if (ret)
-               dev_err(&dsi->dev, "failed to attach dsi to host: %d\n", ret);
-
-       return ret;
+       return 0;
 }
 
 static struct mipi_dsi_driver rpi_touchscreen_dsi_driver = {
-- 
2.31.1

Reply via email to