drm/bridge/synopsys: dsi: add ability to check dsi-device

A patch from »drm/rockchip: migrate to common dw-mipi-dsi bridge and dual-dsi« in state Mainline for linux-kernel

From: Heiko Stuebner <heiko@...> Date: Mon, 4 Jun 2018 11:11:35 +0200

Commit-Message

When the panel-driver is build as a module it currently fails hard as the panel cannot be probed directly: dw_mipi_dsi_bind() __dw_mipi_dsi_probe() creates dsi bus creates panel device triggers panel module load panel not probed (module not loaded or panel probe slow) drm_bridge_attach fails with -EINVAL due to empty panel_bridge Additionally the panel probing can run concurrently with dsi bringup making it possible that the panel can already be found but dsi-attach hasn't finished running. The newly added function provides the ability for glue drivers to check if a dsi device was actually attached and also protects the attach part to prevent concurrency issues from panel-assignment and drm_bridge_create. Using that check glue drivers are able to for example defer probe/bind in the case that the panel is not completely set up yet. Signed-off-by: Heiko Stuebner <heiko@...>

Patch-Comment

drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 25 +++++++++++++++++++ include/drm/bridge/dw_mipi_dsi.h | 1 + 2 files changed, 26 insertions(+)

Statistics

  • 26 lines added
  • 0 lines removed

Changes

---------------- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c -----------------
index bb4aeca5c0f9..88fed22ff3f6 100644
@@ -12,6 +12,7 @@
#include <linux/component.h>
#include <linux/iopoll.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
@@ -219,6 +220,7 @@ struct dw_mipi_dsi {
struct drm_bridge bridge;
struct mipi_dsi_host dsi_host;
struct drm_bridge *panel_bridge;
+ struct mutex panel_mutex;
struct device *dev;
void __iomem *base;
@@ -296,10 +298,14 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
return PTR_ERR(bridge);
}
+ mutex_lock(&dsi->panel_mutex);
+
dsi->panel_bridge = bridge;
drm_bridge_add(&dsi->bridge);
+ mutex_unlock(&dsi->panel_mutex);
+
return 0;
}
@@ -308,13 +314,30 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
{
struct dw_mipi_dsi *dsi = host_to_dsi(host);
+ mutex_lock(&dsi->panel_mutex);
+
+ dsi->panel_bridge = NULL;
drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
drm_bridge_remove(&dsi->bridge);
+ mutex_unlock(&dsi->panel_mutex);
+
return 0;
}
+bool dw_mipi_dsi_device_attached(struct dw_mipi_dsi *dsi)
+{
+ bool output;
+
+ mutex_lock(&dsi->panel_mutex);
+ output = !!dsi->panel_bridge;
+ mutex_unlock(&dsi->panel_mutex);
+
+ return output;
+}
+EXPORT_SYMBOL_GPL(dw_mipi_dsi_device_attached);
+
static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
const struct mipi_dsi_msg *msg)
{
@@ -867,6 +890,8 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
dsi->dev = dev;
dsi->plat_data = plat_data;
+ mutex_init(&dsi->panel_mutex);
+
if (!plat_data->phy_ops->init || !plat_data->phy_ops->get_lane_mbps) {
DRM_ERROR("Phy not properly configured\n");
return ERR_PTR(-ENODEV);
----------------------- include/drm/bridge/dw_mipi_dsi.h -----------------------
index 6d7f8eb5d9f2..131ff2569ed4 100644
@@ -31,6 +31,7 @@ struct dw_mipi_dsi_plat_data {
void *priv_data;
};
+bool dw_mipi_dsi_device_attached(struct dw_mipi_dsi *dsi);
struct dw_mipi_dsi *dw_mipi_dsi_probe(struct platform_device *pdev,
const struct dw_mipi_dsi_plat_data
*plat_data);
 
 

Recent Patches

About Us

Sed lacus. Donec lectus. Nullam pretium nibh ut turpis. Nam bibendum. In nulla tortor, elementum vel, tempor at, varius non, purus. Mauris vitae nisl nec metus placerat consectetuer.

Read More...