Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5cc8d536 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau: wake up the card if necessary during gem callbacks



The failure paths if we fail to wake the card are less than desirable,
but there's not really a graceful way to handle this case currently.

I'll keep this situation in mind when I get to fixing other vm-related
issues.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 8d5e3af1
Loading
Loading
Loading
Loading
+30 −5
Original line number Original line Diff line number Diff line
@@ -36,7 +36,14 @@ void
nouveau_gem_object_del(struct drm_gem_object *gem)
nouveau_gem_object_del(struct drm_gem_object *gem)
{
{
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
	struct ttm_buffer_object *bo = &nvbo->bo;
	struct ttm_buffer_object *bo = &nvbo->bo;
	struct device *dev = drm->dev->dev;
	int ret;

	ret = pm_runtime_get_sync(dev);
	if (WARN_ON(ret < 0 && ret != -EACCES))
		return;


	if (gem->import_attach)
	if (gem->import_attach)
		drm_prime_gem_destroy(gem, nvbo->bo.sg);
		drm_prime_gem_destroy(gem, nvbo->bo.sg);
@@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem)
	/* reset filp so nouveau_bo_del_ttm() can test for it */
	/* reset filp so nouveau_bo_del_ttm() can test for it */
	gem->filp = NULL;
	gem->filp = NULL;
	ttm_bo_unref(&bo);
	ttm_bo_unref(&bo);

	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);
}
}


int
int
@@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
{
{
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
	struct nouveau_vma *vma;
	struct nouveau_vma *vma;
	struct device *dev = drm->dev->dev;
	int ret;
	int ret;


	if (!cli->vm)
	if (!cli->vm)
@@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
			goto out;
			goto out;
		}
		}


		ret = pm_runtime_get_sync(dev);
		if (ret < 0 && ret != -EACCES)
			goto out;

		ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
		ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
		if (ret) {
		if (ret)
			kfree(vma);
			kfree(vma);
			goto out;

		}
		pm_runtime_mark_last_busy(dev);
		pm_runtime_put_autosuspend(dev);
	} else {
	} else {
		vma->refcount++;
		vma->refcount++;
	}
	}
@@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
{
{
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
	struct device *dev = drm->dev->dev;
	struct nouveau_vma *vma;
	struct nouveau_vma *vma;
	int ret;
	int ret;


@@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)


	vma = nouveau_bo_vma_find(nvbo, cli->vm);
	vma = nouveau_bo_vma_find(nvbo, cli->vm);
	if (vma) {
	if (vma) {
		if (--vma->refcount == 0)
		if (--vma->refcount == 0) {
			ret = pm_runtime_get_sync(dev);
			if (!WARN_ON(ret < 0 && ret != -EACCES)) {
				nouveau_gem_object_unmap(nvbo, vma);
				nouveau_gem_object_unmap(nvbo, vma);
				pm_runtime_mark_last_busy(dev);
				pm_runtime_put_autosuspend(dev);
			}
		}
	}
	}
	ttm_bo_unreserve(&nvbo->bo);
	ttm_bo_unreserve(&nvbo->bo);
}
}