diff options
Diffstat (limited to 'drivers/gpu/drm/tegra/gem.c')
| -rw-r--r-- | drivers/gpu/drm/tegra/gem.c | 43 |
1 files changed, 19 insertions, 24 deletions
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index ace3e5a805cf..436394e04812 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -16,8 +16,8 @@ #include <linux/vmalloc.h> #include <drm/drm_drv.h> +#include <drm/drm_dumb_buffers.h> #include <drm/drm_prime.h> -#include <drm/tegra_drm.h> #include "drm.h" #include "gem.h" @@ -64,12 +64,12 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_ struct host1x_bo_mapping *map; int err; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) return ERR_PTR(-ENOMEM); kref_init(&map->ref); - map->bo = host1x_bo_get(bo); + map->bo = bo; map->direction = direction; map->dev = dev; @@ -103,7 +103,7 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_ * If we don't have a mapping for this buffer yet, return an SG table * so that host1x can do the mapping for us via the DMA API. */ - map->sgt = kzalloc(sizeof(*map->sgt), GFP_KERNEL); + map->sgt = kzalloc_obj(*map->sgt); if (!map->sgt) { err = -ENOMEM; goto free; @@ -170,7 +170,6 @@ static void tegra_bo_unpin(struct host1x_bo_mapping *map) kfree(map->sgt); } - host1x_bo_put(map->bo); kfree(map); } @@ -235,12 +234,13 @@ static const struct host1x_bo_ops tegra_bo_ops = { static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo) { int prot = IOMMU_READ | IOMMU_WRITE; + ssize_t size; int err; if (bo->mm) return -EBUSY; - bo->mm = kzalloc(sizeof(*bo->mm), GFP_KERNEL); + bo->mm = kzalloc_obj(*bo->mm); if (!bo->mm) return -ENOMEM; @@ -256,13 +256,15 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo) bo->iova = bo->mm->start; - bo->size = iommu_map_sgtable(tegra->domain, bo->iova, bo->sgt, prot); - if (!bo->size) { + size = iommu_map_sgtable(tegra->domain, bo->iova, bo->sgt, prot); + if (size < 0) { dev_err(tegra->drm->dev, "failed to map buffer\n"); - err = -ENOMEM; + err = size; goto remove; } + bo->size = size; + mutex_unlock(&tegra->mm_lock); return 0; @@ -302,7 +304,7 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm, struct tegra_bo *bo; int err; - bo = kzalloc(sizeof(*bo), GFP_KERNEL); + bo = kzalloc_obj(*bo); if (!bo) return ERR_PTR(-ENOMEM); @@ -509,22 +511,14 @@ free: void tegra_bo_free_object(struct drm_gem_object *gem) { struct tegra_drm *tegra = gem->dev->dev_private; - struct host1x_bo_mapping *mapping, *tmp; struct tegra_bo *bo = to_tegra_bo(gem); - /* remove all mappings of this buffer object from any caches */ - list_for_each_entry_safe(mapping, tmp, &bo->base.mappings, list) { - if (mapping->cache) - host1x_bo_unpin(mapping); - else - dev_err(gem->dev->dev, "mapping %p stale for device %s\n", mapping, - dev_name(mapping->dev)); - } + host1x_bo_clear_cached_mappings(&bo->base); if (tegra->domain) { tegra_bo_iommu_unmap(tegra, bo); - if (gem->import_attach) { + if (drm_gem_is_imported(gem)) { dma_buf_unmap_attachment_unlocked(gem->import_attach, bo->sgt, DMA_TO_DEVICE); dma_buf_detach(gem->import_attach->dmabuf, gem->import_attach); @@ -543,12 +537,13 @@ void tegra_bo_free_object(struct drm_gem_object *gem) int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm, struct drm_mode_create_dumb *args) { - unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); struct tegra_drm *tegra = drm->dev_private; struct tegra_bo *bo; + int ret; - args->pitch = round_up(min_pitch, tegra->pitch_align); - args->size = args->pitch * args->height; + ret = drm_mode_size_dumb(drm, args, tegra->pitch_align, 0); + if (ret) + return ret; bo = tegra_bo_create_with_handle(file, drm, args->size, 0, &args->handle); @@ -638,7 +633,7 @@ tegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, struct tegra_bo *bo = to_tegra_bo(gem); struct sg_table *sgt; - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) return NULL; |
