.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2016 Maxime Ripard |
---|
3 | 4 | * Maxime Ripard <maxime.ripard@free-electrons.com> |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or |
---|
6 | | - * modify it under the terms of the GNU General Public License as |
---|
7 | | - * published by the Free Software Foundation; either version 2 of |
---|
8 | | - * the License, or (at your option) any later version. |
---|
9 | 5 | */ |
---|
10 | 6 | |
---|
11 | 7 | #include <linux/clk-provider.h> |
---|
| 8 | +#include <linux/io.h> |
---|
12 | 9 | |
---|
13 | 10 | #include "ccu_gate.h" |
---|
14 | 11 | #include "ccu_nkmp.h" |
---|
.. | .. |
---|
137 | 134 | if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) |
---|
138 | 135 | rate *= nkmp->fixed_post_div; |
---|
139 | 136 | |
---|
| 137 | + if (nkmp->max_rate && rate > nkmp->max_rate) { |
---|
| 138 | + rate = nkmp->max_rate; |
---|
| 139 | + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) |
---|
| 140 | + rate /= nkmp->fixed_post_div; |
---|
| 141 | + return rate; |
---|
| 142 | + } |
---|
| 143 | + |
---|
140 | 144 | _nkmp.min_n = nkmp->n.min ?: 1; |
---|
141 | 145 | _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; |
---|
142 | 146 | _nkmp.min_k = nkmp->k.min ?: 1; |
---|
.. | .. |
---|
179 | 183 | |
---|
180 | 184 | ccu_nkmp_find_best(parent_rate, rate, &_nkmp); |
---|
181 | 185 | |
---|
| 186 | + /* |
---|
| 187 | + * If width is 0, GENMASK() macro may not generate expected mask (0) |
---|
| 188 | + * as it falls under undefined behaviour by C standard due to shifts |
---|
| 189 | + * which are equal or greater than width of left operand. This can |
---|
| 190 | + * be easily avoided by explicitly checking if width is 0. |
---|
| 191 | + */ |
---|
182 | 192 | if (nkmp->n.width) |
---|
183 | 193 | n_mask = GENMASK(nkmp->n.width + nkmp->n.shift - 1, |
---|
184 | 194 | nkmp->n.shift); |
---|