diff options
| -rw-r--r-- | drivers/video/fbdev/msm/dsi_panel_v2.c | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp3.c | 81 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp3.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.c | 2 |
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); |
