Commit 2ba552b2 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'mediatek-drm-fixes-5.3' of...

Merge tag 'mediatek-drm-fixes-5.3' of https://github.com/ckhu-mediatek/linux.git-tags into drm-fixes

Mediatek memory leak drm fix for Linux 5.3
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: CK Hu <ck.hu@mediatek.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1566264270.30493.4.camel@mtksdaap41
parents 14673e15 165d42c0
...@@ -213,6 +213,7 @@ static int mtk_drm_kms_init(struct drm_device *drm) ...@@ -213,6 +213,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
struct mtk_drm_private *private = drm->dev_private; struct mtk_drm_private *private = drm->dev_private;
struct platform_device *pdev; struct platform_device *pdev;
struct device_node *np; struct device_node *np;
struct device *dma_dev;
int ret; int ret;
if (!iommu_present(&platform_bus_type)) if (!iommu_present(&platform_bus_type))
...@@ -275,7 +276,29 @@ static int mtk_drm_kms_init(struct drm_device *drm) ...@@ -275,7 +276,29 @@ static int mtk_drm_kms_init(struct drm_device *drm)
goto err_component_unbind; goto err_component_unbind;
} }
private->dma_dev = &pdev->dev; dma_dev = &pdev->dev;
private->dma_dev = dma_dev;
/*
* Configure the DMA segment size to make sure we get contiguous IOVA
* when importing PRIME buffers.
*/
if (!dma_dev->dma_parms) {
private->dma_parms_allocated = true;
dma_dev->dma_parms =
devm_kzalloc(drm->dev, sizeof(*dma_dev->dma_parms),
GFP_KERNEL);
}
if (!dma_dev->dma_parms) {
ret = -ENOMEM;
goto err_component_unbind;
}
ret = dma_set_max_seg_size(dma_dev, (unsigned int)DMA_BIT_MASK(32));
if (ret) {
dev_err(dma_dev, "Failed to set DMA segment size\n");
goto err_unset_dma_parms;
}
/* /*
* We don't use the drm_irq_install() helpers provided by the DRM * We don't use the drm_irq_install() helpers provided by the DRM
...@@ -285,13 +308,16 @@ static int mtk_drm_kms_init(struct drm_device *drm) ...@@ -285,13 +308,16 @@ static int mtk_drm_kms_init(struct drm_device *drm)
drm->irq_enabled = true; drm->irq_enabled = true;
ret = drm_vblank_init(drm, MAX_CRTC); ret = drm_vblank_init(drm, MAX_CRTC);
if (ret < 0) if (ret < 0)
goto err_component_unbind; goto err_unset_dma_parms;
drm_kms_helper_poll_init(drm); drm_kms_helper_poll_init(drm);
drm_mode_config_reset(drm); drm_mode_config_reset(drm);
return 0; return 0;
err_unset_dma_parms:
if (private->dma_parms_allocated)
dma_dev->dma_parms = NULL;
err_component_unbind: err_component_unbind:
component_unbind_all(drm->dev, drm); component_unbind_all(drm->dev, drm);
err_config_cleanup: err_config_cleanup:
...@@ -302,9 +328,14 @@ static int mtk_drm_kms_init(struct drm_device *drm) ...@@ -302,9 +328,14 @@ static int mtk_drm_kms_init(struct drm_device *drm)
static void mtk_drm_kms_deinit(struct drm_device *drm) static void mtk_drm_kms_deinit(struct drm_device *drm)
{ {
struct mtk_drm_private *private = drm->dev_private;
drm_kms_helper_poll_fini(drm); drm_kms_helper_poll_fini(drm);
drm_atomic_helper_shutdown(drm); drm_atomic_helper_shutdown(drm);
if (private->dma_parms_allocated)
private->dma_dev->dma_parms = NULL;
component_unbind_all(drm->dev, drm); component_unbind_all(drm->dev, drm);
drm_mode_config_cleanup(drm); drm_mode_config_cleanup(drm);
} }
...@@ -320,6 +351,18 @@ static const struct file_operations mtk_drm_fops = { ...@@ -320,6 +351,18 @@ static const struct file_operations mtk_drm_fops = {
.compat_ioctl = drm_compat_ioctl, .compat_ioctl = drm_compat_ioctl,
}; };
/*
* We need to override this because the device used to import the memory is
* not dev->dev, as drm_gem_prime_import() expects.
*/
struct drm_gem_object *mtk_drm_gem_prime_import(struct drm_device *dev,
struct dma_buf *dma_buf)
{
struct mtk_drm_private *private = dev->dev_private;
return drm_gem_prime_import_dev(dev, dma_buf, private->dma_dev);
}
static struct drm_driver mtk_drm_driver = { static struct drm_driver mtk_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
DRIVER_ATOMIC, DRIVER_ATOMIC,
...@@ -331,7 +374,7 @@ static struct drm_driver mtk_drm_driver = { ...@@ -331,7 +374,7 @@ static struct drm_driver mtk_drm_driver = {
.prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle, .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = drm_gem_prime_export, .gem_prime_export = drm_gem_prime_export,
.gem_prime_import = drm_gem_prime_import, .gem_prime_import = mtk_drm_gem_prime_import,
.gem_prime_get_sg_table = mtk_gem_prime_get_sg_table, .gem_prime_get_sg_table = mtk_gem_prime_get_sg_table,
.gem_prime_import_sg_table = mtk_gem_prime_import_sg_table, .gem_prime_import_sg_table = mtk_gem_prime_import_sg_table,
.gem_prime_mmap = mtk_drm_gem_mmap_buf, .gem_prime_mmap = mtk_drm_gem_mmap_buf,
...@@ -524,12 +567,15 @@ static int mtk_drm_probe(struct platform_device *pdev) ...@@ -524,12 +567,15 @@ static int mtk_drm_probe(struct platform_device *pdev)
comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL); comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
if (!comp) { if (!comp) {
ret = -ENOMEM; ret = -ENOMEM;
of_node_put(node);
goto err_node; goto err_node;
} }
ret = mtk_ddp_comp_init(dev, node, comp, comp_id, NULL); ret = mtk_ddp_comp_init(dev, node, comp, comp_id, NULL);
if (ret) if (ret) {
of_node_put(node);
goto err_node; goto err_node;
}
private->ddp_comp[comp_id] = comp; private->ddp_comp[comp_id] = comp;
} }
......
...@@ -51,6 +51,8 @@ struct mtk_drm_private { ...@@ -51,6 +51,8 @@ struct mtk_drm_private {
} commit; } commit;
struct drm_atomic_state *suspend_state; struct drm_atomic_state *suspend_state;
bool dma_parms_allocated;
}; };
extern struct platform_driver mtk_ddp_driver; extern struct platform_driver mtk_ddp_driver;
......
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