Commit 347d761c authored by Laurent Pinchart's avatar Laurent Pinchart

drm: rcar-du: Don't fail probe in case of partial encoder init error

If an encoder fails to initialize the device can still be used without
the failed encoder. Don't propagate the error out of the probe function
but just skip the failed encoder.

As a special case a deferred probe request from the encoder is still
propagated out of the probe function in order not to break the deferred
probing mechanism.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
parent 3b2b36e5
...@@ -193,32 +193,46 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, ...@@ -193,32 +193,46 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
if (renc->lvds) { if (renc->lvds) {
dev_err(rcdu->dev, dev_err(rcdu->dev,
"Chaining LVDS and HDMI encoders not supported\n"); "Chaining LVDS and HDMI encoders not supported\n");
return -EINVAL; ret = -EINVAL;
goto done;
} }
ret = rcar_du_hdmienc_init(rcdu, renc, enc_node); ret = rcar_du_hdmienc_init(rcdu, renc, enc_node);
if (ret < 0) if (ret < 0)
return ret; goto done;
} else { } else {
ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs, ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
encoder_type); encoder_type);
if (ret < 0) if (ret < 0)
return ret; goto done;
drm_encoder_helper_add(encoder, &encoder_helper_funcs); drm_encoder_helper_add(encoder, &encoder_helper_funcs);
} }
switch (encoder_type) { switch (encoder_type) {
case DRM_MODE_ENCODER_LVDS: case DRM_MODE_ENCODER_LVDS:
return rcar_du_lvds_connector_init(rcdu, renc, con_node); ret = rcar_du_lvds_connector_init(rcdu, renc, con_node);
break;
case DRM_MODE_ENCODER_DAC: case DRM_MODE_ENCODER_DAC:
return rcar_du_vga_connector_init(rcdu, renc); ret = rcar_du_vga_connector_init(rcdu, renc);
break;
case DRM_MODE_ENCODER_TMDS: case DRM_MODE_ENCODER_TMDS:
return rcar_du_hdmi_connector_init(rcdu, renc); ret = rcar_du_hdmi_connector_init(rcdu, renc);
break;
default: default:
return -EINVAL; ret = -EINVAL;
break;
} }
done:
if (ret < 0) {
if (encoder->name)
encoder->funcs->destroy(encoder);
devm_kfree(rcdu->dev, renc);
}
return ret;
} }
...@@ -346,8 +346,14 @@ static int rcar_du_encoders_init(struct rcar_du_device *rcdu) ...@@ -346,8 +346,14 @@ static int rcar_du_encoders_init(struct rcar_du_device *rcdu)
/* Process the output pipeline. */ /* Process the output pipeline. */
ret = rcar_du_encoders_init_one(rcdu, output, &ep); ret = rcar_du_encoders_init_one(rcdu, output, &ep);
if (ret < 0) { if (ret < 0) {
of_node_put(ep_node); if (ret == -EPROBE_DEFER) {
return ret; of_node_put(ep_node);
return ret;
}
dev_info(rcdu->dev,
"encoder initialization failed, skipping\n");
continue;
} }
num_encoders += ret; num_encoders += ret;
...@@ -413,6 +419,11 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) ...@@ -413,6 +419,11 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ret == 0) {
dev_err(rcdu->dev, "error: no encoder could be initialized\n");
return -EINVAL;
}
num_encoders = ret; num_encoders = ret;
/* Set the possible CRTCs and possible clones. There's always at least /* Set the possible CRTCs and possible clones. There's always at least
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment