| .. | .. |
|---|
| 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 | |
|---|