From 6e03a97d1dc379478f1d4d097821ed48d3aeebbb Mon Sep 17 00:00:00 2001 From: Shobhit Kumar Date: Wed, 20 Jan 2016 15:23:21 +0530 Subject: [PATCH] drm/i915: Return -EPROBE_DEFER if we cannot get GPIO and PWM in dsi_init 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. Signed-off-by: Shobhit Kumar --- drivers/gpu/drm/i915/i915_dma.c | 5 ++++- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/intel_display.c | 21 ++++++++++++++++----- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_dsi.c | 18 ++++++++++++------ 5 files changed, 34 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a0f5659..2675a8c 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -410,7 +410,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_ucode_init(dev); @@ -456,6 +458,7 @@ cleanup_gem: mutex_unlock(&dev->struct_mutex); cleanup_irq: intel_guc_ucode_fini(dev); +cleanup_deffered_probe: drm_irq_uninstall(dev); intel_teardown_gmbus(dev); cleanup_gem_stolen: diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index af30148..b3d96bf 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3394,7 +3394,7 @@ static inline void intel_unregister_dsm_handler(void) { return; } /* 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 void intel_connector_unregister(struct intel_connector *); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a851cb7..effdc96 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -14518,11 +14518,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 = dev->dev_private; struct intel_encoder *encoder; bool dpd_is_edp = false; + int ret = 0; intel_lvds_init(dev); @@ -14629,7 +14630,9 @@ static void intel_setup_outputs(struct drm_device *dev) intel_dp_init(dev, CHV_DP_D, 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; @@ -14682,6 +14685,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) @@ -15402,7 +15407,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 = dev->dev_private; int sprite, ret; @@ -15426,7 +15431,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 @@ -15494,7 +15499,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); @@ -15529,6 +15538,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 059b46e..f73bace 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1312,7 +1312,7 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_ 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_dvo.c */ diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 91cef35..9929b01 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -1097,7 +1097,7 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = { .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, }; -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; @@ -1108,28 +1108,29 @@ void intel_dsi_init(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; 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 (!dev_priv->vbt.has_mipi) - return; + return 0; if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { dev_priv->mipi_mmio_base = VLV_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; @@ -1198,6 +1199,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; } } @@ -1236,10 +1240,12 @@ void intel_dsi_init(struct drm_device *dev) intel_panel_init(&intel_connector->panel, fixed_mode, NULL); intel_panel_setup_backlight(connector, INVALID_PIPE); - return; + return 0; err: drm_encoder_cleanup(&intel_encoder->base); kfree(intel_dsi); kfree(intel_connector); + + return ret; } -- 1.9.1