hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/clk/tegra/clk-divider.c
....@@ -1,17 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3
- *
4
- * This program is free software; you can redistribute it and/or modify it
5
- * under the terms and conditions of the GNU General Public License,
6
- * version 2, as published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope it will be useful, but WITHOUT
9
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11
- * more details.
12
- *
13
- * You should have received a copy of the GNU General Public License
14
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
154 */
165
176 #include <linux/kernel.h>
....@@ -51,8 +40,13 @@
5140 int div, mul;
5241 u64 rate = parent_rate;
5342
54
- reg = readl_relaxed(divider->reg) >> divider->shift;
55
- div = reg & div_mask(divider);
43
+ reg = readl_relaxed(divider->reg);
44
+
45
+ if ((divider->flags & TEGRA_DIVIDER_UART) &&
46
+ !(reg & PERIPH_CLK_UART_DIV_ENB))
47
+ return rate;
48
+
49
+ div = (reg >> divider->shift) & div_mask(divider);
5650
5751 mul = get_mul(divider);
5852 div += mul;
....@@ -120,10 +114,21 @@
120114 return 0;
121115 }
122116
117
+static void clk_divider_restore_context(struct clk_hw *hw)
118
+{
119
+ struct clk_hw *parent = clk_hw_get_parent(hw);
120
+ unsigned long parent_rate = clk_hw_get_rate(parent);
121
+ unsigned long rate = clk_hw_get_rate(hw);
122
+
123
+ if (clk_frac_div_set_rate(hw, rate, parent_rate) < 0)
124
+ WARN_ON(1);
125
+}
126
+
123127 const struct clk_ops tegra_clk_frac_div_ops = {
124128 .recalc_rate = clk_frac_div_recalc_rate,
125129 .set_rate = clk_frac_div_set_rate,
126130 .round_rate = clk_frac_div_round_rate,
131
+ .restore_context = clk_divider_restore_context,
127132 };
128133
129134 struct clk *tegra_clk_register_divider(const char *name,
....@@ -133,7 +138,7 @@
133138 {
134139 struct tegra_clk_frac_div *divider;
135140 struct clk *clk;
136
- struct clk_init_data init = {};
141
+ struct clk_init_data init;
137142
138143 divider = kzalloc(sizeof(*divider), GFP_KERNEL);
139144 if (!divider) {
....@@ -175,6 +180,7 @@
175180 void __iomem *reg, spinlock_t *lock)
176181 {
177182 return clk_register_divider_table(NULL, name, parent_name,
178
- CLK_IS_CRITICAL, reg, 16, 1, 0,
183
+ CLK_IS_CRITICAL,
184
+ reg, 16, 1, CLK_DIVIDER_READ_ONLY,
179185 mc_div_table, lock);
180186 }