[PATCH v2 7/8] drm/panel: raspberrypi-touchscreen: Use the attach hook

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

 



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 <maxime@xxxxxxxxxx>
---
 .../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




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux