[PATCH] drm/i915: Return -EPROBE_DEFER if we cannot get GPIO or PWM in dsi_init

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

 



On devices that have MIPI DSI panel control and PWM control comming from
CRC PMIC, we need the gpio and pwm exported from the intel_soc_pmic
driver. Defer probing for later in case we fail to get these devices.

v2: Rebased on latest drm-intel-nightly
    Added failure check for pwm_get which got missed out

Signed-off-by: Shobhit Kumar <shobhit.kumar@xxxxxxxxx>
---
 drivers/gpu/drm/i915/i915_drv.c      |  4 ++++
 drivers/gpu/drm/i915/i915_drv.h      |  2 +-
 drivers/gpu/drm/i915/intel_display.c | 25 +++++++++++++++++++------
 drivers/gpu/drm/i915/intel_drv.h     |  2 +-
 drivers/gpu/drm/i915/intel_dsi.c     | 24 +++++++++++++++++-------
 5 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index b9a8117..9bfe0c8 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -648,6 +648,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
 	/* Important: The output setup functions called by modeset_init need
 	 * working irqs for e.g. gmbus and dp aux transfers. */
 	intel_modeset_init(dev);
+	ret = intel_modeset_init(dev);
+	if (ret == -EPROBE_DEFER)
+		goto cleanup_deffered_probe;
 
 	intel_guc_init(dev);
 
@@ -675,6 +678,7 @@ cleanup_gem:
 	i915_gem_fini(dev);
 cleanup_irq:
 	intel_guc_fini(dev);
+cleanup_deffered_probe:
 	drm_irq_uninstall(dev);
 	intel_teardown_gmbus(dev);
 cleanup_csr:
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 03e1bfa..a9eed22 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3778,7 +3778,7 @@ void intel_device_info_dump(struct drm_i915_private *dev_priv);
 
 /* modesetting */
 extern void intel_modeset_init_hw(struct drm_device *dev);
-extern void intel_modeset_init(struct drm_device *dev);
+extern int intel_modeset_init(struct drm_device *dev);
 extern void intel_modeset_gem_init(struct drm_device *dev);
 extern void intel_modeset_cleanup(struct drm_device *dev);
 extern int intel_connector_register(struct drm_connector *);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index be3b2ca..b1250f2 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -14612,11 +14612,12 @@ static bool intel_crt_present(struct drm_device *dev)
 	return true;
 }
 
-static void intel_setup_outputs(struct drm_device *dev)
+static int intel_setup_outputs(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_encoder *encoder;
 	bool dpd_is_edp = false;
+	int ret = 0;
 
 	/*
 	 * intel_edp_init_connector() depends on this completing first, to
@@ -14638,7 +14639,9 @@ static void intel_setup_outputs(struct drm_device *dev)
 		intel_ddi_init(dev, PORT_B);
 		intel_ddi_init(dev, PORT_C);
 
-		intel_dsi_init(dev);
+		ret = intel_dsi_init(dev);
+		if (ret == -EPROBE_DEFER)
+			return ret;
 	} else if (HAS_DDI(dev)) {
 		int found;
 
@@ -14742,7 +14745,9 @@ static void intel_setup_outputs(struct drm_device *dev)
 				intel_hdmi_init(dev, CHV_HDMID, PORT_D);
 		}
 
-		intel_dsi_init(dev);
+		ret = intel_dsi_init(dev);
+		if (ret == -EPROBE_DEFER)
+			return ret;
 	} else if (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) {
 		bool found = false;
 
@@ -14795,6 +14800,8 @@ static void intel_setup_outputs(struct drm_device *dev)
 	intel_init_pch_refclk(dev);
 
 	drm_helper_move_panel_connectors_to_head(dev);
+
+	return 0;
 }
 
 static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
@@ -15539,7 +15546,7 @@ fail:
 	drm_modeset_acquire_fini(&ctx);
 }
 
-void intel_modeset_init(struct drm_device *dev)
+int intel_modeset_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct i915_ggtt *ggtt = &dev_priv->ggtt;
@@ -15564,7 +15571,7 @@ void intel_modeset_init(struct drm_device *dev)
 	intel_init_pm(dev);
 
 	if (INTEL_INFO(dev)->num_pipes == 0)
-		return;
+		return 0;
 
 	/*
 	 * There may be no VBT; and if the BIOS enabled SSC we can
@@ -15632,7 +15639,11 @@ void intel_modeset_init(struct drm_device *dev)
 
 	/* Just disable it once at startup */
 	i915_disable_vga(dev);
-	intel_setup_outputs(dev);
+
+	/* Check if we encountered -EPROBE_DEFER while initializing DSI */
+	ret = intel_setup_outputs(dev);
+	if (ret)
+		return ret;
 
 	drm_modeset_lock_all(dev);
 	intel_modeset_setup_hw_state(dev);
@@ -15667,6 +15678,8 @@ void intel_modeset_init(struct drm_device *dev)
 	 * since the watermark calculation done here will use pstate->fb.
 	 */
 	sanitize_watermarks(dev);
+
+	return 0;
 }
 
 static void intel_enable_pipe_a(struct drm_device *dev)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 55aeaf0..4f05b7c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1418,7 +1418,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector);
 int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_id);
 void intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port);
 /* intel_dsi.c */
-void intel_dsi_init(struct drm_device *dev);
+int intel_dsi_init(struct drm_device *dev);
 
 /* intel_dsi_dcs_backlight.c */
 int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector);
diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c
index de8e9fb..5c02a3f 100644
--- a/drivers/gpu/drm/i915/intel_dsi.c
+++ b/drivers/gpu/drm/i915/intel_dsi.c
@@ -1422,7 +1422,7 @@ static void intel_dsi_add_properties(struct intel_connector *connector)
 	}
 }
 
-void intel_dsi_init(struct drm_device *dev)
+int intel_dsi_init(struct drm_device *dev)
 {
 	struct intel_dsi *intel_dsi;
 	struct intel_encoder *intel_encoder;
@@ -1433,12 +1433,13 @@ void intel_dsi_init(struct drm_device *dev)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	enum port port;
 	unsigned int i;
+	int ret = 0;
 
 	DRM_DEBUG_KMS("\n");
 
 	/* There is no detection method for MIPI so rely on VBT */
 	if (!intel_bios_is_dsi_present(dev_priv, &port))
-		return;
+		return 0;
 
 	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
 		dev_priv->mipi_mmio_base = VLV_MIPI_BASE;
@@ -1446,17 +1447,17 @@ void intel_dsi_init(struct drm_device *dev)
 		dev_priv->mipi_mmio_base = BXT_MIPI_BASE;
 	} else {
 		DRM_ERROR("Unsupported Mipi device to reg base");
-		return;
+		return 0;
 	}
 
 	intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL);
 	if (!intel_dsi)
-		return;
+		return -ENOMEM;
 
 	intel_connector = intel_connector_alloc();
 	if (!intel_connector) {
 		kfree(intel_dsi);
-		return;
+		return -ENOMEM;
 	}
 
 	intel_encoder = &intel_dsi->base;
@@ -1560,6 +1561,9 @@ void intel_dsi_init(struct drm_device *dev)
 		if (IS_ERR(intel_dsi->gpio_panel)) {
 			DRM_ERROR("Failed to own gpio for panel control\n");
 			intel_dsi->gpio_panel = NULL;
+
+			ret = -EPROBE_DEFER;
+			goto err;
 		}
 	}
 
@@ -1597,14 +1601,20 @@ void intel_dsi_init(struct drm_device *dev)
 	connector->display_info.height_mm = fixed_mode->height_mm;
 
 	intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
-	intel_panel_setup_backlight(connector, INVALID_PIPE);
+	ret = intel_panel_setup_backlight(connector, INVALID_PIPE);
+	if (ret == -ENODEV) {
+		ret = -EPROBE_DEFER;
+		goto err;
+	}
 
 	intel_dsi_add_properties(intel_connector);
 
-	return;
+	return 0;
 
 err:
 	drm_encoder_cleanup(&intel_encoder->base);
 	kfree(intel_dsi);
 	kfree(intel_connector);
+
+	return ret;
 }
-- 
2.5.5

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux