return dp->encoder;
}
+static int analogix_dp_loader_protect(struct drm_connector *connector, bool on)
+{
+ struct analogix_dp_device *dp = to_dp(connector);
+
+ if (on == connector->loader_protect)
+ return 0;
+
+ if (on) {
+ pm_runtime_get_sync(dp->dev);
+
+ connector->loader_protect = true;
+ } else {
+ pm_runtime_put(dp->dev);
+
+ connector->loader_protect = false;
+ }
+
+ return 0;
+}
+
static const struct drm_connector_helper_funcs analogix_dp_connector_helper_funcs = {
+ .loader_protect = analogix_dp_loader_protect,
.get_modes = analogix_dp_get_modes,
.best_encoder = analogix_dp_best_encoder,
};
dp->plat_data->power_off(dp->plat_data);
pm_runtime_put_sync(dp->dev);
+ if (dp->connector.loader_protect) {
+ pm_runtime_put_sync(dp->dev);
+ dp->connector.loader_protect = false;
+ }
dp->dpms_mode = DRM_MODE_DPMS_OFF;
}
funcs = connector->helper_private;
conn_state->best_encoder = funcs->best_encoder(connector);
+ if (funcs->loader_protect)
+ funcs->loader_protect(connector, true);
num_modes = connector->funcs->fill_modes(connector, 4096, 4096);
if (!num_modes) {
dev_err(drm_dev->dev, "connector[%s] can't found any modes\n",
connector->name);
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
list_for_each_entry(mode, &connector->modes, head) {
head);
if (!mode) {
pr_err("failed to find available modes\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto error;
}
}
}
set->mode = mode;
crtc_state = drm_atomic_get_crtc_state(state, crtc);
- if (IS_ERR(crtc_state))
- return PTR_ERR(crtc_state);
+ if (IS_ERR(crtc_state)) {
+ ret = PTR_ERR(crtc_state);
+ goto error;
+ }
drm_mode_copy(&crtc_state->adjusted_mode, mode);
if (!match || !is_crtc_enabled) {
} else {
ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
if (ret)
- return ret;
+ goto error;
ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
if (ret)
- return ret;
+ goto error;
crtc_state->active = true;
}
- if (!set->fb)
- return 0;
+ if (!set->fb) {
+ ret = 0;
+ goto error;
+ }
primary_state = drm_atomic_get_plane_state(state, crtc->primary);
- if (IS_ERR(primary_state))
- return PTR_ERR(primary_state);
+ if (IS_ERR(primary_state)) {
+ ret = PTR_ERR(primary_state);
+ goto error;
+ }
hdisplay = mode->hdisplay;
vdisplay = mode->vdisplay;
}
return 0;
+
+error:
+ if (funcs->loader_protect)
+ funcs->loader_protect(connector, false);
+ return ret;
}
static int update_state(struct drm_device *drm_dev,
/**
* struct drm_connector_helper_funcs - helper operations for connectors
+ * @loader_protect: protect loader logo connector's power
* @get_modes: get mode list for this connector
* @mode_valid: is this mode valid on the given connector? (optional)
* @best_encoder: return the preferred encoder for this connector
* The helper operations are called by the mid-layer CRTC helper.
*/
struct drm_connector_helper_funcs {
+ int (*loader_protect)(struct drm_connector *connector, bool on);
int (*get_modes)(struct drm_connector *connector);
enum drm_mode_status (*mode_valid)(struct drm_connector *connector,
struct drm_display_mode *mode);