forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/clk/tegra/clk-periph.c
....@@ -1,19 +1,9 @@
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
6
+#include <linux/clk.h>
177 #include <linux/clk-provider.h>
188 #include <linux/export.h>
199 #include <linux/slab.h>
....@@ -110,6 +100,32 @@
110100 gate_ops->disable(gate_hw);
111101 }
112102
103
+static void clk_periph_disable_unused(struct clk_hw *hw)
104
+{
105
+ struct tegra_clk_periph *periph = to_clk_periph(hw);
106
+ const struct clk_ops *gate_ops = periph->gate_ops;
107
+ struct clk_hw *gate_hw = &periph->gate.hw;
108
+
109
+ gate_ops->disable_unused(gate_hw);
110
+}
111
+
112
+static void clk_periph_restore_context(struct clk_hw *hw)
113
+{
114
+ struct tegra_clk_periph *periph = to_clk_periph(hw);
115
+ const struct clk_ops *div_ops = periph->div_ops;
116
+ struct clk_hw *div_hw = &periph->divider.hw;
117
+ int parent_id;
118
+
119
+ parent_id = clk_hw_get_parent_index(hw);
120
+ if (WARN_ON(parent_id < 0))
121
+ return;
122
+
123
+ if (!(periph->gate.flags & TEGRA_PERIPH_NO_DIV))
124
+ div_ops->restore_context(div_hw);
125
+
126
+ clk_periph_set_parent(hw, parent_id);
127
+}
128
+
113129 const struct clk_ops tegra_clk_periph_ops = {
114130 .get_parent = clk_periph_get_parent,
115131 .set_parent = clk_periph_set_parent,
....@@ -119,6 +135,8 @@
119135 .is_enabled = clk_periph_is_enabled,
120136 .enable = clk_periph_enable,
121137 .disable = clk_periph_disable,
138
+ .disable_unused = clk_periph_disable_unused,
139
+ .restore_context = clk_periph_restore_context,
122140 };
123141
124142 static const struct clk_ops tegra_clk_periph_nodiv_ops = {
....@@ -127,6 +145,8 @@
127145 .is_enabled = clk_periph_is_enabled,
128146 .enable = clk_periph_enable,
129147 .disable = clk_periph_disable,
148
+ .disable_unused = clk_periph_disable_unused,
149
+ .restore_context = clk_periph_restore_context,
130150 };
131151
132152 static const struct clk_ops tegra_clk_periph_no_gate_ops = {
....@@ -135,6 +155,7 @@
135155 .recalc_rate = clk_periph_recalc_rate,
136156 .round_rate = clk_periph_round_rate,
137157 .set_rate = clk_periph_set_rate,
158
+ .restore_context = clk_periph_restore_context,
138159 };
139160
140161 static struct clk *_tegra_clk_register_periph(const char *name,
....@@ -144,7 +165,7 @@
144165 unsigned long flags)
145166 {
146167 struct clk *clk;
147
- struct clk_init_data init = {};
168
+ struct clk_init_data init;
148169 const struct tegra_clk_periph_regs *bank;
149170 bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV);
150171