Skip to content

Commit 3c3ba2a

Browse files
wensbebarino
authored andcommitted
clk: mediatek: mtk: Implement error handling in register APIs
The remaining clk registration functions do not stop or return errors if any clk failed to be registered, nor do they implement error handling paths. This may result in a partially working device if any step fails. Make the register functions return proper error codes, and bail out if errors occur. Proper cleanup, i.e. unregister any clks that were successfully registered, is done in the new error path. This also makes the |struct clk_data *| argument mandatory, as it is used to track the list of clks registered. Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://lore.kernel.org/r/20220208124034.414635-27-wenst@chromium.org Reviewed-by: Chun-Jie Chen <chun-jie.chen@mediatek.com> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
1 parent 6ae34f2 commit 3c3ba2a

File tree

2 files changed

+103
-35
lines changed

2 files changed

+103
-35
lines changed

drivers/clk/mediatek/clk-mtk.c

Lines changed: 93 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -53,29 +53,46 @@ void mtk_free_clk_data(struct clk_onecell_data *clk_data)
5353
kfree(clk_data);
5454
}
5555

56-
void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
57-
int num, struct clk_onecell_data *clk_data)
56+
int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
57+
struct clk_onecell_data *clk_data)
5858
{
5959
int i;
6060
struct clk *clk;
6161

62+
if (!clk_data)
63+
return -ENOMEM;
64+
6265
for (i = 0; i < num; i++) {
6366
const struct mtk_fixed_clk *rc = &clks[i];
6467

65-
if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[rc->id]))
68+
if (!IS_ERR_OR_NULL(clk_data->clks[rc->id]))
6669
continue;
6770

6871
clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
6972
rc->rate);
7073

7174
if (IS_ERR(clk)) {
7275
pr_err("Failed to register clk %s: %pe\n", rc->name, clk);
73-
continue;
76+
goto err;
7477
}
7578

76-
if (clk_data)
77-
clk_data->clks[rc->id] = clk;
79+
clk_data->clks[rc->id] = clk;
7880
}
81+
82+
return 0;
83+
84+
err:
85+
while (--i >= 0) {
86+
const struct mtk_fixed_clk *rc = &clks[i];
87+
88+
if (IS_ERR_OR_NULL(clk_data->clks[rc->id]))
89+
continue;
90+
91+
clk_unregister_fixed_rate(clk_data->clks[rc->id]);
92+
clk_data->clks[rc->id] = ERR_PTR(-ENOENT);
93+
}
94+
95+
return PTR_ERR(clk);
7996
}
8097
EXPORT_SYMBOL_GPL(mtk_clk_register_fixed_clks);
8198

@@ -99,29 +116,46 @@ void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
99116
}
100117
EXPORT_SYMBOL_GPL(mtk_clk_unregister_fixed_clks);
101118

102-
void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
103-
int num, struct clk_onecell_data *clk_data)
119+
int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
120+
struct clk_onecell_data *clk_data)
104121
{
105122
int i;
106123
struct clk *clk;
107124

125+
if (!clk_data)
126+
return -ENOMEM;
127+
108128
for (i = 0; i < num; i++) {
109129
const struct mtk_fixed_factor *ff = &clks[i];
110130

111-
if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[ff->id]))
131+
if (!IS_ERR_OR_NULL(clk_data->clks[ff->id]))
112132
continue;
113133

114134
clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
115135
CLK_SET_RATE_PARENT, ff->mult, ff->div);
116136

117137
if (IS_ERR(clk)) {
118138
pr_err("Failed to register clk %s: %pe\n", ff->name, clk);
119-
continue;
139+
goto err;
120140
}
121141

122-
if (clk_data)
123-
clk_data->clks[ff->id] = clk;
142+
clk_data->clks[ff->id] = clk;
143+
}
144+
145+
return 0;
146+
147+
err:
148+
while (--i >= 0) {
149+
const struct mtk_fixed_factor *ff = &clks[i];
150+
151+
if (IS_ERR_OR_NULL(clk_data->clks[ff->id]))
152+
continue;
153+
154+
clk_unregister_fixed_factor(clk_data->clks[ff->id]);
155+
clk_data->clks[ff->id] = ERR_PTR(-ENOENT);
124156
}
157+
158+
return PTR_ERR(clk);
125159
}
126160
EXPORT_SYMBOL_GPL(mtk_clk_register_factors);
127161

@@ -258,13 +292,16 @@ static void mtk_clk_unregister_composite(struct clk *clk)
258292
kfree(mux);
259293
}
260294

261-
void mtk_clk_register_composites(const struct mtk_composite *mcs,
262-
int num, void __iomem *base, spinlock_t *lock,
263-
struct clk_onecell_data *clk_data)
295+
int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
296+
void __iomem *base, spinlock_t *lock,
297+
struct clk_onecell_data *clk_data)
264298
{
265299
struct clk *clk;
266300
int i;
267301

302+
if (!clk_data)
303+
return -ENOMEM;
304+
268305
for (i = 0; i < num; i++) {
269306
const struct mtk_composite *mc = &mcs[i];
270307

@@ -275,12 +312,26 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
275312

276313
if (IS_ERR(clk)) {
277314
pr_err("Failed to register clk %s: %pe\n", mc->name, clk);
278-
continue;
315+
goto err;
279316
}
280317

281-
if (clk_data)
282-
clk_data->clks[mc->id] = clk;
318+
clk_data->clks[mc->id] = clk;
319+
}
320+
321+
return 0;
322+
323+
err:
324+
while (--i >= 0) {
325+
const struct mtk_composite *mc = &mcs[i];
326+
327+
if (IS_ERR_OR_NULL(clk_data->clks[mcs->id]))
328+
continue;
329+
330+
mtk_clk_unregister_composite(clk_data->clks[mc->id]);
331+
clk_data->clks[mc->id] = ERR_PTR(-ENOENT);
283332
}
333+
334+
return PTR_ERR(clk);
284335
}
285336
EXPORT_SYMBOL_GPL(mtk_clk_register_composites);
286337

@@ -304,17 +355,20 @@ void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
304355
}
305356
EXPORT_SYMBOL_GPL(mtk_clk_unregister_composites);
306357

307-
void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
308-
int num, void __iomem *base, spinlock_t *lock,
309-
struct clk_onecell_data *clk_data)
358+
int mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
359+
void __iomem *base, spinlock_t *lock,
360+
struct clk_onecell_data *clk_data)
310361
{
311362
struct clk *clk;
312363
int i;
313364

365+
if (!clk_data)
366+
return -ENOMEM;
367+
314368
for (i = 0; i < num; i++) {
315369
const struct mtk_clk_divider *mcd = &mcds[i];
316370

317-
if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
371+
if (!IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
318372
continue;
319373

320374
clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
@@ -323,12 +377,26 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
323377

324378
if (IS_ERR(clk)) {
325379
pr_err("Failed to register clk %s: %pe\n", mcd->name, clk);
326-
continue;
380+
goto err;
327381
}
328382

329-
if (clk_data)
330-
clk_data->clks[mcd->id] = clk;
383+
clk_data->clks[mcd->id] = clk;
384+
}
385+
386+
return 0;
387+
388+
err:
389+
while (--i >= 0) {
390+
const struct mtk_clk_divider *mcd = &mcds[i];
391+
392+
if (IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
393+
continue;
394+
395+
mtk_clk_unregister_composite(clk_data->clks[mcd->id]);
396+
clk_data->clks[mcd->id] = ERR_PTR(-ENOENT);
331397
}
398+
399+
return PTR_ERR(clk);
332400
}
333401

334402
void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,

drivers/clk/mediatek/clk-mtk.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ struct mtk_fixed_clk {
3434
.rate = _rate, \
3535
}
3636

37-
void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
38-
struct clk_onecell_data *clk_data);
37+
int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
38+
struct clk_onecell_data *clk_data);
3939
void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
4040
struct clk_onecell_data *clk_data);
4141

@@ -55,8 +55,8 @@ struct mtk_fixed_factor {
5555
.div = _div, \
5656
}
5757

58-
void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
59-
struct clk_onecell_data *clk_data);
58+
int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
59+
struct clk_onecell_data *clk_data);
6060
void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,
6161
struct clk_onecell_data *clk_data);
6262

@@ -150,9 +150,9 @@ struct mtk_composite {
150150
struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
151151
void __iomem *base, spinlock_t *lock);
152152

153-
void mtk_clk_register_composites(const struct mtk_composite *mcs,
154-
int num, void __iomem *base, spinlock_t *lock,
155-
struct clk_onecell_data *clk_data);
153+
int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
154+
void __iomem *base, spinlock_t *lock,
155+
struct clk_onecell_data *clk_data);
156156
void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
157157
struct clk_onecell_data *clk_data);
158158

@@ -178,9 +178,9 @@ struct mtk_clk_divider {
178178
.div_width = _width, \
179179
}
180180

181-
void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
182-
void __iomem *base, spinlock_t *lock,
183-
struct clk_onecell_data *clk_data);
181+
int mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
182+
void __iomem *base, spinlock_t *lock,
183+
struct clk_onecell_data *clk_data);
184184
void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
185185
struct clk_onecell_data *clk_data);
186186

0 commit comments

Comments
 (0)