summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLloyd Atkinson <latkinso@codeaurora.org>2016-10-04 10:01:24 -0400
committerLloyd Atkinson <latkinso@codeaurora.org>2016-11-24 13:22:30 -0500
commit74502bdbd80be7f7df06b5733ecacc69df10b15d (patch)
tree5686e64b759d3756c4e3dadbbe755017c556c813 /drivers/gpu
parentaa82c5fad3573f9f36f392c4d4c03ac010f672a6 (diff)
drm/msm/sde: fix iounmap usage and init callflow
Fix iounmap usage to properly use devm_iounmap. Fix clearing of pointers in failure callflows of sde_kms init. Change-Id: Ib42134ee972c578070ac513c3e4da37faec7d0cd Signed-off-by: Lloyd Atkinson <latkinso@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c5
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h1
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.c99
3 files changed, 67 insertions, 38 deletions
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index dcfb6842df15..860f99a761b0 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -126,6 +126,11 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
return ptr;
}
+void msm_iounmap(struct platform_device *pdev, void __iomem *addr)
+{
+ devm_iounmap(&pdev->dev, addr);
+}
+
void msm_writel(u32 data, void __iomem *addr)
{
if (reglog)
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 9c824655a954..847a6e82fe33 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -481,6 +481,7 @@ static inline void msm_rd_dump_submit(struct msm_gem_submit *submit) {}
void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
const char *dbgname);
+void msm_iounmap(struct platform_device *dev, void __iomem *addr);
void msm_writel(u32 data, void __iomem *addr);
u32 msm_readl(const void __iomem *addr);
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index f4da57db6e21..c834f6dad83a 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -305,7 +305,7 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
SDE_EVT32(DRMID(crtc));
ret = sde_encoder_wait_for_commit_done(encoder);
if (ret && ret != -EWOULDBLOCK) {
- DRM_ERROR("wait for commit done returned %d\n", ret);
+ SDE_ERROR("wait for commit done returned %d\n", ret);
break;
}
}
@@ -754,7 +754,7 @@ static int _sde_kms_mmu_destroy(struct sde_kms *sde_kms)
int i;
for (i = ARRAY_SIZE(sde_kms->mmu_id) - 1; i >= 0; i--) {
- if (sde_kms->mmu_id[i] <= 0 || !sde_kms->mmu[i])
+ if (!sde_kms->mmu[i])
continue;
mmu = sde_kms->mmu[i];
@@ -778,14 +778,15 @@ static int _sde_kms_mmu_init(struct sde_kms *sde_kms)
mmu = msm_smmu_new(sde_kms->dev->dev, i);
if (IS_ERR(mmu)) {
ret = PTR_ERR(mmu);
- DRM_ERROR("failed to init iommu: %d\n", ret);
+ SDE_ERROR("failed to init iommu id %d: rc: %d\n", i,
+ ret);
goto fail;
}
ret = mmu->funcs->attach(mmu, (const char **)iommu_ports,
ARRAY_SIZE(iommu_ports));
if (ret) {
- DRM_ERROR("failed to attach iommu: %d\n", ret);
+ SDE_ERROR("failed to attach iommu %d: %d\n", i, ret);
mmu->funcs->destroy(mmu);
goto fail;
}
@@ -793,7 +794,8 @@ static int _sde_kms_mmu_init(struct sde_kms *sde_kms)
sde_kms->mmu_id[i] = msm_register_mmu(sde_kms->dev, mmu);
if (sde_kms->mmu_id[i] < 0) {
ret = sde_kms->mmu_id[i];
- DRM_ERROR("failed to register sde iommu: %d\n", ret);
+ SDE_ERROR("failed to register sde iommu %d: %d\n",
+ i, ret);
mmu->funcs->detach(mmu, (const char **)iommu_ports,
ARRAY_SIZE(iommu_ports));
goto fail;
@@ -820,16 +822,18 @@ static struct sde_kms *_sde_kms_hw_setup(struct platform_device *pdev)
sde_kms->mmio = msm_ioremap(pdev, "mdp_phys", "SDE");
if (IS_ERR(sde_kms->mmio)) {
- SDE_ERROR("mdp register memory map failed\n");
ret = PTR_ERR(sde_kms->mmio);
+ SDE_ERROR("mdp register memory map failed: %d\n", ret);
+ sde_kms->mmio = NULL;
goto err;
}
DRM_INFO("mapped mdp address space @%p\n", sde_kms->mmio);
sde_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif_phys", "VBIF");
if (IS_ERR(sde_kms->vbif[VBIF_RT])) {
- SDE_ERROR("vbif register memory map failed\n");
ret = PTR_ERR(sde_kms->vbif[VBIF_RT]);
+ SDE_ERROR("vbif register memory map failed: %d\n", ret);
+ sde_kms->vbif[VBIF_RT] = NULL;
goto vbif_map_err;
}
@@ -848,25 +852,31 @@ static struct sde_kms *_sde_kms_hw_setup(struct platform_device *pdev)
}
SDE_DEBUG("sde hw setup successful\n");
+
return sde_kms;
kms_init_err:
if (sde_kms->vbif[VBIF_NRT])
- iounmap(sde_kms->vbif[VBIF_NRT]);
- iounmap(sde_kms->vbif[VBIF_RT]);
+ msm_iounmap(pdev, sde_kms->vbif[VBIF_NRT]);
+ if (sde_kms->vbif[VBIF_RT])
+ msm_iounmap(pdev, sde_kms->vbif[VBIF_RT]);
vbif_map_err:
- iounmap(sde_kms->mmio);
+ if (sde_kms->mmio)
+ msm_iounmap(pdev, sde_kms->mmio);
err:
kfree(sde_kms);
return ERR_PTR(ret);
}
-static void _sde_kms_hw_destroy(struct sde_kms *sde_kms)
+static void _sde_kms_hw_destroy(struct sde_kms *sde_kms,
+ struct platform_device *pdev)
{
if (sde_kms->vbif[VBIF_NRT])
- iounmap(sde_kms->vbif[VBIF_NRT]);
- iounmap(sde_kms->vbif[VBIF_RT]);
- iounmap(sde_kms->mmio);
+ msm_iounmap(pdev, sde_kms->vbif[VBIF_NRT]);
+ if (sde_kms->vbif[VBIF_RT])
+ msm_iounmap(pdev, sde_kms->vbif[VBIF_RT]);
+ if (sde_kms->mmio)
+ msm_iounmap(pdev, sde_kms->mmio);
kfree(sde_kms);
}
@@ -886,8 +896,8 @@ struct msm_kms *sde_kms_init(struct drm_device *dev)
priv = dev->dev_private;
sde_kms = _sde_kms_hw_setup(dev->platformdev);
if (IS_ERR_OR_NULL(sde_kms)) {
- SDE_ERROR("sde hw setup failed\n");
rc = PTR_ERR(sde_kms);
+ SDE_ERROR("sde hw setup failed: %d\n", rc);
goto end;
}
@@ -896,16 +906,17 @@ struct msm_kms *sde_kms_init(struct drm_device *dev)
sde_kms->core_client = sde_power_client_create(&priv->phandle, "core");
if (IS_ERR_OR_NULL(sde_kms->core_client)) {
- SDE_ERROR("sde power client create failed\n");
- rc = -EINVAL;
+ rc = PTR_ERR(sde_kms->core_client);
+ SDE_ERROR("sde power client create failed: %d\n", rc);
+ sde_kms->core_client = NULL;
goto kms_destroy;
}
rc = sde_power_resource_enable(&priv->phandle, sde_kms->core_client,
true);
if (rc) {
- SDE_ERROR("resource enable failed\n");
- goto clk_rate_err;
+ SDE_ERROR("resource enable failed: %d\n", rc);
+ goto clk_enable_err;
}
_sde_kms_core_hw_rev_init(sde_kms);
@@ -914,15 +925,24 @@ struct msm_kms *sde_kms_init(struct drm_device *dev)
sde_kms->catalog = sde_hw_catalog_init(dev, sde_kms->core_rev);
if (IS_ERR_OR_NULL(sde_kms->catalog)) {
- SDE_ERROR("catalog init failed\n");
rc = PTR_ERR(sde_kms->catalog);
+ SDE_ERROR("catalog init failed: %d\n", rc);
+ sde_kms->catalog = NULL;
goto catalog_err;
}
rc = sde_rm_init(&sde_kms->rm, sde_kms->catalog, sde_kms->mmio,
sde_kms->dev);
if (rc)
- goto catalog_err;
+ goto rm_init_err;
+
+ sde_kms->hw_mdp = sde_rm_get_mdp(&sde_kms->rm);
+ if (IS_ERR_OR_NULL(sde_kms->hw_mdp)) {
+ rc = PTR_ERR(sde_kms->hw_mdp);
+ SDE_ERROR("failed to get hw_mdp: %d\n", rc);
+ sde_kms->hw_mdp = NULL;
+ goto mdp_top_init_err;
+ }
for (i = 0; i < sde_kms->catalog->vbif_count; i++) {
u32 vbif_idx = sde_kms->catalog->vbif[i].id;
@@ -930,23 +950,13 @@ struct msm_kms *sde_kms_init(struct drm_device *dev)
sde_kms->hw_vbif[i] = sde_hw_vbif_init(vbif_idx,
sde_kms->vbif[vbif_idx], sde_kms->catalog);
if (IS_ERR_OR_NULL(sde_kms->hw_vbif[vbif_idx])) {
- SDE_ERROR("failed to init vbif %d\n", vbif_idx);
+ rc = PTR_ERR(sde_kms->hw_vbif[vbif_idx]);
+ SDE_ERROR("failed to init vbif %d: %d\n", vbif_idx, rc);
sde_kms->hw_vbif[vbif_idx] = NULL;
- goto catalog_err;
+ goto vbif_init_err;
}
}
- sde_kms->hw_mdp = sde_rm_get_mdp(&sde_kms->rm);
- if (IS_ERR_OR_NULL(sde_kms->hw_mdp)) {
- SDE_ERROR("failed to get hw_mdp\n");
- sde_kms->hw_mdp = NULL;
- goto catalog_err;
- }
-
- sde_kms->hw_intr = sde_hw_intr_init(sde_kms->mmio, sde_kms->catalog);
- if (IS_ERR_OR_NULL(sde_kms->hw_intr))
- goto catalog_err;
-
/*
* Now we need to read the HW catalog and initialize resources such as
* clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc
@@ -993,8 +1003,12 @@ struct msm_kms *sde_kms_init(struct drm_device *dev)
dev->mode_config.allow_fb_modifiers = true;
sde_kms->hw_intr = sde_hw_intr_init(sde_kms->mmio, sde_kms->catalog);
- if (IS_ERR_OR_NULL(sde_kms->hw_intr))
+ if (IS_ERR_OR_NULL(sde_kms->hw_intr)) {
+ rc = PTR_ERR(sde_kms->hw_intr);
+ SDE_ERROR("hw_intr init failed: %d\n", rc);
+ sde_kms->hw_intr = NULL;
goto hw_intr_init_err;
+ }
sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
@@ -1005,15 +1019,24 @@ hw_intr_init_err:
drm_obj_init_err:
_sde_debugfs_destroy(sde_kms);
debugfs_init_err:
- _sde_kms_mmu_destroy(sde_kms);
mmu_init_err:
+ _sde_kms_mmu_destroy(sde_kms);
+vbif_init_err:
+ for (i = 0; i < sde_kms->catalog->vbif_count; i++) {
+ u32 vbif_idx = sde_kms->catalog->vbif[i].id;
+
+ if ((vbif_idx < VBIF_MAX) && sde_kms->hw_vbif[vbif_idx])
+ sde_hw_vbif_destroy(sde_kms->hw_vbif[vbif_idx]);
+ }
+mdp_top_init_err:
sde_rm_destroy(&sde_kms->rm);
+rm_init_err:
catalog_err:
sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
-clk_rate_err:
+clk_enable_err:
sde_power_client_destroy(&priv->phandle, sde_kms->core_client);
kms_destroy:
- _sde_kms_hw_destroy(sde_kms);
+ _sde_kms_hw_destroy(sde_kms, dev->platformdev);
end:
return ERR_PTR(rc);
}