treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / gpu / drm / msm / disp / dpu1 / dpu_io_util.c
blob078afc5f58820e81b2f8994f10ff6538719a033a
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2012-2015, 2017-2018, The Linux Foundation.
3 * All rights reserved.
4 */
6 #include <linux/clk.h>
7 #include <linux/clk/clk-conf.h>
8 #include <linux/err.h>
9 #include <linux/delay.h>
10 #include <linux/of.h>
12 #include <drm/drm_print.h>
14 #include "dpu_io_util.h"
16 void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk)
18 int i;
20 for (i = num_clk - 1; i >= 0; i--) {
21 if (clk_arry[i].clk)
22 clk_put(clk_arry[i].clk);
23 clk_arry[i].clk = NULL;
27 int msm_dss_get_clk(struct device *dev, struct dss_clk *clk_arry, int num_clk)
29 int i, rc = 0;
31 for (i = 0; i < num_clk; i++) {
32 clk_arry[i].clk = clk_get(dev, clk_arry[i].clk_name);
33 rc = PTR_ERR_OR_ZERO(clk_arry[i].clk);
34 if (rc) {
35 DEV_ERR("%pS->%s: '%s' get failed. rc=%d\n",
36 __builtin_return_address(0), __func__,
37 clk_arry[i].clk_name, rc);
38 goto error;
42 return rc;
44 error:
45 for (i--; i >= 0; i--) {
46 if (clk_arry[i].clk)
47 clk_put(clk_arry[i].clk);
48 clk_arry[i].clk = NULL;
51 return rc;
54 int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk)
56 int i, rc = 0;
58 for (i = 0; i < num_clk; i++) {
59 if (clk_arry[i].clk) {
60 if (clk_arry[i].type != DSS_CLK_AHB) {
61 DEV_DBG("%pS->%s: '%s' rate %ld\n",
62 __builtin_return_address(0), __func__,
63 clk_arry[i].clk_name,
64 clk_arry[i].rate);
65 rc = clk_set_rate(clk_arry[i].clk,
66 clk_arry[i].rate);
67 if (rc) {
68 DEV_ERR("%pS->%s: %s failed. rc=%d\n",
69 __builtin_return_address(0),
70 __func__,
71 clk_arry[i].clk_name, rc);
72 break;
75 } else {
76 DEV_ERR("%pS->%s: '%s' is not available\n",
77 __builtin_return_address(0), __func__,
78 clk_arry[i].clk_name);
79 rc = -EPERM;
80 break;
84 return rc;
87 int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable)
89 int i, rc = 0;
91 if (enable) {
92 for (i = 0; i < num_clk; i++) {
93 DEV_DBG("%pS->%s: enable '%s'\n",
94 __builtin_return_address(0), __func__,
95 clk_arry[i].clk_name);
96 rc = clk_prepare_enable(clk_arry[i].clk);
97 if (rc)
98 DEV_ERR("%pS->%s: %s en fail. rc=%d\n",
99 __builtin_return_address(0),
100 __func__,
101 clk_arry[i].clk_name, rc);
103 if (rc && i) {
104 msm_dss_enable_clk(&clk_arry[i - 1],
105 i - 1, false);
106 break;
109 } else {
110 for (i = num_clk - 1; i >= 0; i--) {
111 DEV_DBG("%pS->%s: disable '%s'\n",
112 __builtin_return_address(0), __func__,
113 clk_arry[i].clk_name);
115 clk_disable_unprepare(clk_arry[i].clk);
119 return rc;
122 int msm_dss_parse_clock(struct platform_device *pdev,
123 struct dss_module_power *mp)
125 u32 i, rc = 0;
126 const char *clock_name;
127 int num_clk = 0;
129 if (!pdev || !mp)
130 return -EINVAL;
132 mp->num_clk = 0;
133 num_clk = of_property_count_strings(pdev->dev.of_node, "clock-names");
134 if (num_clk <= 0) {
135 pr_debug("clocks are not defined\n");
136 return 0;
139 mp->clk_config = devm_kcalloc(&pdev->dev,
140 num_clk, sizeof(struct dss_clk),
141 GFP_KERNEL);
142 if (!mp->clk_config)
143 return -ENOMEM;
145 for (i = 0; i < num_clk; i++) {
146 rc = of_property_read_string_index(pdev->dev.of_node,
147 "clock-names", i,
148 &clock_name);
149 if (rc) {
150 DRM_DEV_ERROR(&pdev->dev, "Failed to get clock name for %d\n",
152 break;
154 strlcpy(mp->clk_config[i].clk_name, clock_name,
155 sizeof(mp->clk_config[i].clk_name));
157 mp->clk_config[i].type = DSS_CLK_AHB;
160 rc = msm_dss_get_clk(&pdev->dev, mp->clk_config, num_clk);
161 if (rc) {
162 DRM_DEV_ERROR(&pdev->dev, "Failed to get clock refs %d\n", rc);
163 goto err;
166 rc = of_clk_set_defaults(pdev->dev.of_node, false);
167 if (rc) {
168 DRM_DEV_ERROR(&pdev->dev, "Failed to set clock defaults %d\n", rc);
169 goto err;
172 for (i = 0; i < num_clk; i++) {
173 u32 rate = clk_get_rate(mp->clk_config[i].clk);
174 if (!rate)
175 continue;
176 mp->clk_config[i].rate = rate;
177 mp->clk_config[i].type = DSS_CLK_PCLK;
178 mp->clk_config[i].max_rate = rate;
181 mp->num_clk = num_clk;
182 return 0;
184 err:
185 msm_dss_put_clk(mp->clk_config, num_clk);
186 return rc;