disp: msm: make kms a DRM client for lastclose logic

Since some APIs previously used during lastclose are no longer
exposed to drivers (__drm_atomic_helper_disable_plane, and
__drm_atomic_helper_set_config), make kms a DRM client and use
the drm_client_modeset_commit_force API to do lastclose cleanup.

Change-Id: I543392fe79558a3996e326a0f222793c56d71e4f
Signed-off-by: Steve Cohen <cohens@codeaurora.org>
This commit is contained in:
Steve Cohen
2019-11-19 13:55:37 -05:00
förälder d1d9ae8b19
incheckning ff5365a1e0
3 ändrade filer med 59 tillägg och 138 borttagningar

Visa fil

@@ -813,6 +813,18 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
priv->fbdev = msm_fbdev_init(ddev);
#endif
/* create drm client only when fbdev is not supported */
if (!priv->fbdev) {
ret = drm_client_init(ddev, &kms->client, "kms_client", NULL);
if (ret) {
DRM_ERROR("failed to init kms_client: %d\n", ret);
kms->client.dev = NULL;
goto fail;
}
drm_client_register(&kms->client);
}
priv->debug_root = debugfs_create_dir("debug",
ddev->primary->debugfs_root);
if (IS_ERR_OR_NULL(priv->debug_root)) {
@@ -928,101 +940,10 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file)
context_close(ctx);
}
static int msm_disable_all_modes_commit(
struct drm_device *dev,
struct drm_atomic_state *state)
{
struct drm_plane *plane;
struct drm_crtc *crtc;
unsigned int plane_mask;
int ret;
plane_mask = 0;
drm_for_each_plane(plane, dev) {
struct drm_plane_state *plane_state;
plane_state = drm_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state)) {
ret = PTR_ERR(plane_state);
goto fail;
}
plane_state->rotation = 0;
plane->old_fb = plane->fb;
plane_mask |= 1 << drm_plane_index(plane);
/* disable non-primary: */
if (plane->type == DRM_PLANE_TYPE_PRIMARY)
continue;
DRM_DEBUG("disabling plane %d\n", plane->base.id);
ret = __drm_atomic_helper_disable_plane(plane, plane_state);
if (ret != 0)
DRM_ERROR("error %d disabling plane %d\n", ret,
plane->base.id);
}
drm_for_each_crtc(crtc, dev) {
struct drm_mode_set mode_set;
memset(&mode_set, 0, sizeof(struct drm_mode_set));
mode_set.crtc = crtc;
DRM_DEBUG("disabling crtc %d\n", crtc->base.id);
ret = __drm_atomic_helper_set_config(&mode_set, state);
if (ret != 0)
DRM_ERROR("error %d disabling crtc %d\n", ret,
crtc->base.id);
}
DRM_DEBUG("committing disables\n");
ret = drm_atomic_commit(state);
fail:
DRM_DEBUG("disables result %d\n", ret);
return ret;
}
/**
* msm_clear_all_modes - disables all planes and crtcs via an atomic commit
* based on restore_fbdev_mode_atomic in drm_fb_helper.c
* @dev: device pointer
* @Return: 0 on success, otherwise -error
*/
static int msm_disable_all_modes(
struct drm_device *dev,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_atomic_state *state;
int ret, i;
state = drm_atomic_state_alloc(dev);
if (!state)
return -ENOMEM;
state->acquire_ctx = ctx;
for (i = 0; i < TEARDOWN_DEADLOCK_RETRY_MAX; i++) {
ret = msm_disable_all_modes_commit(dev, state);
if (ret != -EDEADLK || ret != -ERESTARTSYS)
break;
drm_atomic_state_clear(state);
drm_modeset_backoff(ctx);
}
drm_atomic_state_put(state);
return ret;
}
static void msm_lastclose(struct drm_device *dev)
{
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
struct drm_modeset_acquire_ctx ctx;
int i, rc;
/* check for splash status before triggering cleanup
@@ -1048,32 +969,17 @@ static void msm_lastclose(struct drm_device *dev)
flush_workqueue(priv->wq);
if (priv->fbdev) {
drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
return;
rc = drm_fb_helper_restore_fbdev_mode_unlocked(priv->fbdev);
if (rc)
DRM_ERROR("restore FBDEV mode failed: %d\n", rc);
} else if (kms->client.dev) {
rc = drm_client_modeset_commit_force(&kms->client);
if (rc)
DRM_ERROR("client modeset commit failed: %d\n", rc);
}
drm_modeset_acquire_init(&ctx, 0);
retry:
rc = drm_modeset_lock_all_ctx(dev, &ctx);
if (rc)
goto fail;
rc = msm_disable_all_modes(dev, &ctx);
if (rc)
goto fail;
if (kms && kms->funcs && kms->funcs->lastclose)
kms->funcs->lastclose(kms, &ctx);
fail:
if (rc == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry;
} else if (rc) {
pr_err("last close failed: %d\n", rc);
}
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
kms->funcs->lastclose(kms);
}
static irqreturn_t msm_irq(int irq, void *arg)