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)
struct mtk_drm_private *private = drm->dev_private;
struct platform_device *pdev;
struct device_node *np;
struct device *dma_dev;
int ret;
if (!iommu_present(&platform_bus_type))
......@@ -275,7 +276,29 @@ static int mtk_drm_kms_init(struct drm_device *drm)
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
......@@ -285,13 +308,16 @@ static int mtk_drm_kms_init(struct drm_device *drm)
drm->irq_enabled = true;
ret = drm_vblank_init(drm, MAX_CRTC);
if (ret < 0)
goto err_component_unbind;
goto err_unset_dma_parms;
drm_kms_helper_poll_init(drm);
drm_mode_config_reset(drm);
return 0;
err_unset_dma_parms:
if (private->dma_parms_allocated)
dma_dev->dma_parms = NULL;
err_component_unbind:
component_unbind_all(drm->dev, drm);
err_config_cleanup:
......@@ -302,9 +328,14 @@ static int mtk_drm_kms_init(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_atomic_helper_shutdown(drm);
if (private->dma_parms_allocated)
private->dma_dev->dma_parms = NULL;
component_unbind_all(drm->dev, drm);
drm_mode_config_cleanup(drm);
}
......@@ -320,6 +351,18 @@ static const struct file_operations mtk_drm_fops = {
.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 = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME |
DRIVER_ATOMIC,
......@@ -331,7 +374,7 @@ static struct drm_driver mtk_drm_driver = {
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.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_import_sg_table = mtk_gem_prime_import_sg_table,
.gem_prime_mmap = mtk_drm_gem_mmap_buf,
......@@ -524,12 +567,15 @@ static int mtk_drm_probe(struct platform_device *pdev)
comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL);
if (!comp) {
ret = -ENOMEM;
of_node_put(node);
goto err_node;
}
ret = mtk_ddp_comp_init(dev, node, comp, comp_id, NULL);
if (ret)
if (ret) {
of_node_put(node);
goto err_node;
}
private->ddp_comp[comp_id] = comp;
}
......
......@@ -51,6 +51,8 @@ struct mtk_drm_private {
} commit;
struct drm_atomic_state *suspend_state;
bool dma_parms_allocated;
};
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