summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/dsi_panel_v2.c6
-rw-r--r--drivers/video/fbdev/msm/mdp3.c81
-rw-r--r--drivers/video/fbdev/msm/mdp3.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c2
4 files changed, 77 insertions, 13 deletions
diff --git a/drivers/video/fbdev/msm/dsi_panel_v2.c b/drivers/video/fbdev/msm/dsi_panel_v2.c
index 3639a44c57a6..51c1f064773b 100644
--- a/drivers/video/fbdev/msm/dsi_panel_v2.c
+++ b/drivers/video/fbdev/msm/dsi_panel_v2.c
@@ -104,8 +104,14 @@ void dsi_panel_deinit(void)
kfree(panel_private->on_cmds);
kfree(panel_private->off_cmds);
+
kfree(panel_private);
panel_private = NULL;
+
+ if (bl_led_trigger) {
+ led_trigger_unregister_simple(bl_led_trigger);
+ bl_led_trigger = NULL;
+ }
}
int dsi_panel_power(int enable)
{
diff --git a/drivers/video/fbdev/msm/mdp3.c b/drivers/video/fbdev/msm/mdp3.c
index 5fe6f4a300f9..1a602e252c52 100644
--- a/drivers/video/fbdev/msm/mdp3.c
+++ b/drivers/video/fbdev/msm/mdp3.c
@@ -291,12 +291,16 @@ static int mdp3_bus_scale_register(void)
static void mdp3_bus_scale_unregister(void)
{
int i;
+
+ if (!mdp3_res->bus_handle)
+ return;
+
for (i = 0; i < MDP3_BUS_HANDLE_MAX; i++) {
pr_debug("unregister index=%d bus_handle=%x\n",
i, mdp3_res->bus_handle[i].handle);
if (mdp3_res->bus_handle[i].handle) {
msm_bus_scale_unregister_client(
- mdp3_res->bus_handle[i].handle);
+ mdp3_res->bus_handle[i].handle);
mdp3_res->bus_handle[i].handle = 0;
}
}
@@ -485,11 +489,20 @@ static int mdp3_clk_setup(void)
static void mdp3_clk_remove(void)
{
- clk_put(mdp3_res->clocks[MDP3_CLK_AHB]);
- clk_put(mdp3_res->clocks[MDP3_CLK_CORE]);
- clk_put(mdp3_res->clocks[MDP3_CLK_VSYNC]);
- clk_put(mdp3_res->clocks[MDP3_CLK_LCDC]);
- clk_put(mdp3_res->clocks[MDP3_CLK_DSI]);
+ if (!IS_ERR_OR_NULL(mdp3_res->clocks[MDP3_CLK_AHB]))
+ clk_put(mdp3_res->clocks[MDP3_CLK_AHB]);
+
+ if (!IS_ERR_OR_NULL(mdp3_res->clocks[MDP3_CLK_CORE]))
+ clk_put(mdp3_res->clocks[MDP3_CLK_CORE]);
+
+ if (!IS_ERR_OR_NULL(mdp3_res->clocks[MDP3_CLK_VSYNC]))
+ clk_put(mdp3_res->clocks[MDP3_CLK_VSYNC]);
+
+ if (!IS_ERR_OR_NULL(mdp3_res->clocks[MDP3_CLK_LCDC]))
+ clk_put(mdp3_res->clocks[MDP3_CLK_LCDC]);
+
+ if (!IS_ERR_OR_NULL(mdp3_res->clocks[MDP3_CLK_DSI]))
+ clk_put(mdp3_res->clocks[MDP3_CLK_DSI]);
}
int mdp3_clk_enable(int enable)
@@ -520,6 +533,7 @@ static int mdp3_irq_setup(void)
return ret;
}
disable_irq(mdp3_res->irq);
+ mdp3_res->irq_registered = true;
return 0;
}
@@ -557,7 +571,8 @@ int mdp3_iommu_dettach(int context)
struct mdp3_iommu_ctx_map *context_map;
struct mdp3_iommu_domain_map *domain_map;
- if (context >= MDP3_IOMMU_CTX_MAX)
+ if (!mdp3_res->iommu_contexts ||
+ context >= MDP3_IOMMU_CTX_MAX)
return -EINVAL;
context_map = mdp3_res->iommu_contexts + context;
@@ -596,10 +611,13 @@ int mdp3_iommu_domain_init(void)
mdp3_iommu_domains[i].domain_idx = domain_idx;
mdp3_iommu_domains[i].domain = msm_get_iommu_domain(domain_idx);
- if (!mdp3_iommu_domains[i].domain) {
+ if (IS_ERR_OR_NULL(mdp3_iommu_domains[i].domain)) {
pr_err("unable to get iommu domain(%d)\n",
domain_idx);
- return -EINVAL;
+ if (!mdp3_iommu_domains[i].domain)
+ return -EINVAL;
+ else
+ return PTR_ERR(mdp3_iommu_domains[i].domain);
}
iommu_set_fault_handler(mdp3_iommu_domains[i].domain,
mdp3_iommu_fault_handler,
@@ -624,10 +642,13 @@ int mdp3_iommu_context_init(void)
mdp3_iommu_contexts[i].ctx =
msm_iommu_get_ctx(mdp3_iommu_contexts[i].ctx_name);
- if (!mdp3_iommu_contexts[i].ctx) {
+ if (IS_ERR_OR_NULL(mdp3_iommu_contexts[i].ctx)) {
pr_warn("unable to get iommu ctx(%s)\n",
mdp3_iommu_contexts[i].ctx_name);
- return -EINVAL;
+ if (!mdp3_iommu_contexts[i].ctx)
+ return -EINVAL;
+ else
+ return PTR_ERR(mdp3_iommu_contexts[i].ctx);
}
}
@@ -654,6 +675,19 @@ int mdp3_iommu_init(void)
return ret;
}
+void mdp3_iommu_deinit(void)
+{
+ int i;
+
+ if (!mdp3_res->domains)
+ return;
+
+ for (i = 0; i < MDP3_IOMMU_DOMAIN_MAX; i++) {
+ if (!IS_ERR_OR_NULL(mdp3_res->domains[i].domain))
+ msm_unregister_domain(mdp3_res->domains[i].domain);
+ }
+}
+
static int mdp3_check_version(void)
{
int rc;
@@ -743,6 +777,21 @@ static int mdp3_res_init(void)
return rc;
}
+static void mdp3_res_deinit(void)
+{
+ mdp3_bus_scale_unregister();
+ mdp3_iommu_dettach(MDP3_IOMMU_CTX_DMA_0);
+ mdp3_iommu_deinit();
+
+ if (!IS_ERR_OR_NULL(mdp3_res->ion_client))
+ ion_client_destroy(mdp3_res->ion_client);
+
+ mdp3_clk_remove();
+
+ if (mdp3_res->irq_registered)
+ devm_free_irq(&mdp3_res->pdev->dev, mdp3_res->irq, mdp3_res);
+}
+
static int mdp3_parse_dt(struct platform_device *pdev)
{
struct resource *res;
@@ -848,7 +897,10 @@ int mdp3_get_img(struct msmfb_data *img, struct mdp3_img_data *data)
data->srcp_ihdl = ion_import_dma_buf(iclient, img->memory_id);
if (IS_ERR_OR_NULL(data->srcp_ihdl)) {
pr_err("error on ion_import_fd\n");
- ret = PTR_ERR(data->srcp_ihdl);
+ if (!data->srcp_ihdl)
+ ret = -EINVAL;
+ else
+ ret = PTR_ERR(data->srcp_ihdl);
data->srcp_ihdl = NULL;
return ret;
}
@@ -1003,6 +1055,11 @@ static int mdp3_probe(struct platform_device *pdev)
probe_done:
if (IS_ERR_VALUE(rc)) {
+ mdp3_res_deinit();
+
+ if (mdp3_res->mdp_base)
+ devm_iounmap(&pdev->dev, mdp3_res->mdp_base);
+
devm_kfree(&pdev->dev, mdp3_res);
mdp3_res = NULL;
}
diff --git a/drivers/video/fbdev/msm/mdp3.h b/drivers/video/fbdev/msm/mdp3.h
index cf4d91a0cf7c..47635811064c 100644
--- a/drivers/video/fbdev/msm/mdp3.h
+++ b/drivers/video/fbdev/msm/mdp3.h
@@ -117,6 +117,7 @@ struct mdp3_hw_resource {
u32 irq_ref_count[MDP3_MAX_INTR];
u32 irq_mask;
struct mdp3_intr_cb callbacks[MDP3_MAX_INTR];
+ int irq_registered;
};
struct mdp3_img_data {
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 149b01872a2a..08093296e6dd 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -1726,7 +1726,7 @@ int mdss_register_panel(struct platform_device *pdev,
if (!mdp_instance) {
pr_err("mdss mdp resource not initialized yet\n");
- return -ENODEV;
+ return -EPROBE_DEFER;
}
node = of_parse_phandle(pdev->dev.of_node, "qcom,mdss-fb-map", 0);