summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAjay Singh Parmar <aparmar@codeaurora.org>2016-06-27 11:46:54 -0700
committerDhaval Patel <pdhaval@codeaurora.org>2016-08-01 11:58:14 -0700
commit3da3dc4d309defdefbf7649cd5e971146582b729 (patch)
tree48368144a5f952f5ba58068653eaba5422ebb515 /drivers/gpu
parent1de12c6e3dde44a9f96f7f405b77427e1a9ddba2 (diff)
drm/msm: defer drm driver probe if backlight isn't ready
DRM driver uses backlight driver's APIs. In case backlight driver isn't probed, defer probe for drm driver to make sure backlight functionalities are available for use when drm driver is probed. Change-Id: I52713ad3b096f557091bbbd64bae460d69b46ab1 Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/display_manager.c4
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c2
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/dsi_display.c5
-rw-r--r--drivers/gpu/drm/msm/dsi-staging/dsi_panel.c45
4 files changed, 45 insertions, 11 deletions
diff --git a/drivers/gpu/drm/msm/dsi-staging/display_manager.c b/drivers/gpu/drm/msm/dsi-staging/display_manager.c
index 45d1433dce93..3def7dcf8cb5 100644
--- a/drivers/gpu/drm/msm/dsi-staging/display_manager.c
+++ b/drivers/gpu/drm/msm/dsi-staging/display_manager.c
@@ -125,7 +125,9 @@ static int disp_manager_comp_ops_bind(struct device *dev,
rc = dsi_display_bind(dsi_display, drm);
if (rc) {
- pr_err("Failed to bind dsi display_%d, rc=%d\n", i, rc);
+ if (rc != -EPROBE_DEFER)
+ pr_err("Failed to bind dsi display_%d, rc=%d\n",
+ i, rc);
goto error_unbind_dsi;
}
}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 04a3a79f2f1d..2e857b84ea2a 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1197,7 +1197,7 @@ static int dsi_ctrl_drv_state_init(struct dsi_ctrl *dsi_ctrl)
return rc;
}
-static int dsi_ctrl_intr_deinit(struct dsi_ctrl *dsi_ctrl)
+int dsi_ctrl_intr_deinit(struct dsi_ctrl *dsi_ctrl)
{
struct dsi_ctrl_interrupts *ints = &dsi_ctrl->int_info;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 47fa70823bc3..e8eb000c08c1 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -1501,8 +1501,9 @@ int dsi_display_bind(struct dsi_display *display, struct drm_device *dev)
rc = dsi_panel_drv_init(display->panel, &display->host);
if (rc) {
- pr_err("[%s] Failed to initialize panel driver, rc=%d\n",
- display->name, rc);
+ if (rc != -EPROBE_DEFER)
+ pr_err("[%s] Failed to initialize panel driver, rc=%d\n",
+ display->name, rc);
goto error_host_deinit;
}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
index b44ead465e09..a1748f2c228e 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
@@ -111,7 +111,9 @@ static int dsi_panel_gpio_release(struct dsi_panel *panel)
if (gpio_is_valid(r_config->disp_en_gpio))
gpio_free(r_config->disp_en_gpio);
- /* TODO: backlight gpios */
+ if (gpio_is_valid(panel->bl_config.en_gpio))
+ gpio_free(panel->bl_config.en_gpio);
+
return rc;
}
@@ -302,6 +304,31 @@ static int dsi_panel_bl_register(struct dsi_panel *panel)
switch (bl->type) {
case DSI_BACKLIGHT_WLED:
led_trigger_register_simple("bkl-trigger", &bl->wled);
+
+ /* LED APIs don't tell us directly whether a classdev has yet
+ * been registered to service this trigger. Until classdev is
+ * registered, calling led_trigger has no effect, and doesn't
+ * fail. Classdevs are associated with any registered triggers
+ * when they do register, but that is too late for FBCon.
+ * Check the cdev list directly and defer if appropriate.
+ */
+ if (!bl->wled) {
+ pr_err("[%s] backlight registration failed\n",
+ panel->name);
+ rc = -EINVAL;
+ } else {
+ read_lock(&bl->wled->leddev_list_lock);
+ if (list_empty(&bl->wled->led_cdevs))
+ rc = -EPROBE_DEFER;
+ read_unlock(&bl->wled->leddev_list_lock);
+
+ if (rc) {
+ pr_info("[%s] backlight %s not ready, defer probe\n",
+ panel->name, bl->wled->name);
+ led_trigger_unregister_simple(bl->wled);
+ }
+ }
+
break;
default:
pr_err("Backlight type(%d) not supported\n", bl->type);
@@ -1503,7 +1530,7 @@ int dsi_panel_drv_init(struct dsi_panel *panel,
if (rc) {
pr_err("[%s] Failed to get panel regulators, rc=%d\n",
panel->name, rc);
- goto error;
+ goto exit;
}
rc = dsi_panel_pinctrl_init(panel);
@@ -1521,17 +1548,21 @@ int dsi_panel_drv_init(struct dsi_panel *panel,
rc = dsi_panel_bl_register(panel);
if (rc) {
- pr_err("[%s] failed to register backlight, rc=%d\n",
- panel->name, rc);
+ if (rc != -EPROBE_DEFER)
+ pr_err("[%s] failed to register backlight, rc=%d\n",
+ panel->name, rc);
+ goto error_gpio_release;
}
- rc = 0;
- goto error;
+
+ goto exit;
+
+error_gpio_release:
(void)dsi_panel_gpio_release(panel);
error_pinctrl_deinit:
(void)dsi_panel_pinctrl_deinit(panel);
error_vreg_put:
(void)dsi_panel_vreg_put(panel);
-error:
+exit:
mutex_unlock(&panel->panel_lock);
return rc;
}