.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * R-Car Gen2 Clock Pulse Generator |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2016 Cogent Embedded Inc. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or modify it |
---|
7 | | - * under the terms of the GNU General Public License version 2 as published |
---|
8 | | - * by the Free Software Foundation. |
---|
9 | 6 | */ |
---|
10 | 7 | |
---|
11 | 8 | #include <linux/bug.h> |
---|
.. | .. |
---|
66 | 63 | return div_u64((u64)parent_rate * mult, 32); |
---|
67 | 64 | } |
---|
68 | 65 | |
---|
69 | | -static long cpg_z_clk_round_rate(struct clk_hw *hw, unsigned long rate, |
---|
70 | | - unsigned long *parent_rate) |
---|
| 66 | +static int cpg_z_clk_determine_rate(struct clk_hw *hw, |
---|
| 67 | + struct clk_rate_request *req) |
---|
71 | 68 | { |
---|
72 | | - unsigned long prate = *parent_rate; |
---|
73 | | - unsigned int mult; |
---|
| 69 | + unsigned long prate = req->best_parent_rate; |
---|
| 70 | + unsigned int min_mult, max_mult, mult; |
---|
74 | 71 | |
---|
75 | | - if (!prate) |
---|
76 | | - prate = 1; |
---|
| 72 | + min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL); |
---|
| 73 | + max_mult = min(div64_ul(req->max_rate * 32ULL, prate), 32ULL); |
---|
| 74 | + if (max_mult < min_mult) |
---|
| 75 | + return -EINVAL; |
---|
77 | 76 | |
---|
78 | | - mult = div_u64((u64)rate * 32, prate); |
---|
79 | | - mult = clamp(mult, 1U, 32U); |
---|
| 77 | + mult = div64_ul(req->rate * 32ULL, prate); |
---|
| 78 | + mult = clamp(mult, min_mult, max_mult); |
---|
80 | 79 | |
---|
81 | | - return *parent_rate / 32 * mult; |
---|
| 80 | + req->rate = div_u64((u64)prate * mult, 32); |
---|
| 81 | + return 0; |
---|
82 | 82 | } |
---|
83 | 83 | |
---|
84 | 84 | static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, |
---|
.. | .. |
---|
89 | 89 | u32 val, kick; |
---|
90 | 90 | unsigned int i; |
---|
91 | 91 | |
---|
92 | | - mult = div_u64((u64)rate * 32, parent_rate); |
---|
| 92 | + mult = div64_ul(rate * 32ULL, parent_rate); |
---|
93 | 93 | mult = clamp(mult, 1U, 32U); |
---|
94 | 94 | |
---|
95 | 95 | if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) |
---|
.. | .. |
---|
129 | 129 | |
---|
130 | 130 | static const struct clk_ops cpg_z_clk_ops = { |
---|
131 | 131 | .recalc_rate = cpg_z_clk_recalc_rate, |
---|
132 | | - .round_rate = cpg_z_clk_round_rate, |
---|
| 132 | + .determine_rate = cpg_z_clk_determine_rate, |
---|
133 | 133 | .set_rate = cpg_z_clk_set_rate, |
---|
134 | 134 | }; |
---|
135 | 135 | |
---|
.. | .. |
---|
137 | 137 | const char *parent_name, |
---|
138 | 138 | void __iomem *base) |
---|
139 | 139 | { |
---|
140 | | - struct clk_init_data init = {}; |
---|
| 140 | + struct clk_init_data init; |
---|
141 | 141 | struct cpg_z_clk *zclk; |
---|
142 | 142 | struct clk *clk; |
---|
143 | 143 | |
---|