forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
kernel/drivers/clk/versatile/clk-impd1.c
....@@ -1,16 +1,16 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Clock driver for the ARM Integrator/IM-PD1 board
34 * Copyright (C) 2012-2013 Linus Walleij
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License version 2 as
7
- * published by the Free Software Foundation.
85 */
96 #include <linux/clk-provider.h>
107 #include <linux/clkdev.h>
118 #include <linux/err.h>
129 #include <linux/io.h>
13
-#include <linux/platform_data/clk-integrator.h>
10
+#include <linux/platform_device.h>
11
+#include <linux/module.h>
12
+#include <linux/mfd/syscon.h>
13
+#include <linux/regmap.h>
1414
1515 #include "icst.h"
1616 #include "clk-icst.h"
....@@ -18,26 +18,6 @@
1818 #define IMPD1_OSC1 0x00
1919 #define IMPD1_OSC2 0x04
2020 #define IMPD1_LOCK 0x08
21
-
22
-struct impd1_clk {
23
- char *pclkname;
24
- struct clk *pclk;
25
- char *vco1name;
26
- struct clk *vco1clk;
27
- char *vco2name;
28
- struct clk *vco2clk;
29
- struct clk *mmciclk;
30
- char *uartname;
31
- struct clk *uartclk;
32
- char *spiname;
33
- struct clk *spiclk;
34
- char *scname;
35
- struct clk *scclk;
36
- struct clk_lookup *clks[15];
37
-};
38
-
39
-/* One entry for each connected IM-PD1 LM */
40
-static struct impd1_clk impd1_clks[4];
4121
4222 /*
4323 * There are two VCO's on the IM-PD1
....@@ -79,102 +59,80 @@
7959 .lock_offset = IMPD1_LOCK,
8060 };
8161
82
-/**
83
- * integrator_impd1_clk_init() - set up the integrator clock tree
84
- * @base: base address of the logic module (LM)
85
- * @id: the ID of this LM
86
- */
87
-void integrator_impd1_clk_init(void __iomem *base, unsigned int id)
62
+static int integrator_impd1_clk_spawn(struct device *dev,
63
+ struct device_node *parent,
64
+ struct device_node *np)
8865 {
89
- struct impd1_clk *imc;
90
- struct clk *clk;
91
- struct clk *pclk;
92
- int i;
66
+ struct regmap *map;
67
+ struct clk *clk = ERR_PTR(-EINVAL);
68
+ const char *name = np->name;
69
+ const char *parent_name;
70
+ const struct clk_icst_desc *desc;
71
+ int ret;
9372
94
- if (id > 3) {
95
- pr_crit("no more than 4 LMs can be attached\n");
96
- return;
73
+ map = syscon_node_to_regmap(parent);
74
+ if (IS_ERR(map)) {
75
+ pr_err("no regmap for syscon IM-PD1 ICST clock parent\n");
76
+ return PTR_ERR(map);
9777 }
98
- imc = &impd1_clks[id];
9978
100
- /* Register the fixed rate PCLK */
101
- imc->pclkname = kasprintf(GFP_KERNEL, "lm%x-pclk", id);
102
- pclk = clk_register_fixed_rate(NULL, imc->pclkname, NULL, 0, 0);
103
- imc->pclk = pclk;
79
+ if (of_device_is_compatible(np, "arm,impd1-vco1")) {
80
+ desc = &impd1_icst1_desc;
81
+ } else if (of_device_is_compatible(np, "arm,impd1-vco2")) {
82
+ desc = &impd1_icst2_desc;
83
+ } else {
84
+ dev_err(dev, "not a clock node %s\n", name);
85
+ return -ENODEV;
86
+ }
10487
105
- imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id);
106
- clk = icst_clk_register(NULL, &impd1_icst1_desc, imc->vco1name, NULL,
107
- base);
108
- imc->vco1clk = clk;
109
- imc->clks[0] = clkdev_alloc(pclk, "apb_pclk", "lm%x:01000", id);
110
- imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:01000", id);
88
+ of_property_read_string(np, "clock-output-names", &name);
89
+ parent_name = of_clk_get_parent_name(np, 0);
90
+ clk = icst_clk_setup(NULL, desc, name, parent_name, map,
91
+ ICST_INTEGRATOR_IM_PD1);
92
+ if (!IS_ERR(clk)) {
93
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
94
+ ret = 0;
95
+ } else {
96
+ dev_err(dev, "error setting up IM-PD1 ICST clock\n");
97
+ ret = PTR_ERR(clk);
98
+ }
11199
112
- /* VCO2 is also called "CLK2" */
113
- imc->vco2name = kasprintf(GFP_KERNEL, "lm%x-vco2", id);
114
- clk = icst_clk_register(NULL, &impd1_icst2_desc, imc->vco2name, NULL,
115
- base);
116
- imc->vco2clk = clk;
117
-
118
- /* MMCI uses CLK2 right off */
119
- imc->clks[2] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00700", id);
120
- imc->clks[3] = clkdev_alloc(clk, NULL, "lm%x:00700", id);
121
-
122
- /* UART reference clock divides CLK2 by a fixed factor 4 */
123
- imc->uartname = kasprintf(GFP_KERNEL, "lm%x-uartclk", id);
124
- clk = clk_register_fixed_factor(NULL, imc->uartname, imc->vco2name,
125
- CLK_IGNORE_UNUSED, 1, 4);
126
- imc->uartclk = clk;
127
- imc->clks[4] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00100", id);
128
- imc->clks[5] = clkdev_alloc(clk, NULL, "lm%x:00100", id);
129
- imc->clks[6] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00200", id);
130
- imc->clks[7] = clkdev_alloc(clk, NULL, "lm%x:00200", id);
131
-
132
- /* SPI PL022 clock divides CLK2 by a fixed factor 64 */
133
- imc->spiname = kasprintf(GFP_KERNEL, "lm%x-spiclk", id);
134
- clk = clk_register_fixed_factor(NULL, imc->spiname, imc->vco2name,
135
- CLK_IGNORE_UNUSED, 1, 64);
136
- imc->clks[8] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00300", id);
137
- imc->clks[9] = clkdev_alloc(clk, NULL, "lm%x:00300", id);
138
-
139
- /* The GPIO blocks and AACI have only PCLK */
140
- imc->clks[10] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00400", id);
141
- imc->clks[11] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00500", id);
142
- imc->clks[12] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00800", id);
143
-
144
- /* Smart Card clock divides CLK2 by a fixed factor 4 */
145
- imc->scname = kasprintf(GFP_KERNEL, "lm%x-scclk", id);
146
- clk = clk_register_fixed_factor(NULL, imc->scname, imc->vco2name,
147
- CLK_IGNORE_UNUSED, 1, 4);
148
- imc->scclk = clk;
149
- imc->clks[13] = clkdev_alloc(pclk, "apb_pclk", "lm%x:00600", id);
150
- imc->clks[14] = clkdev_alloc(clk, NULL, "lm%x:00600", id);
151
-
152
- for (i = 0; i < ARRAY_SIZE(imc->clks); i++)
153
- clkdev_add(imc->clks[i]);
100
+ return ret;
154101 }
155
-EXPORT_SYMBOL_GPL(integrator_impd1_clk_init);
156102
157
-void integrator_impd1_clk_exit(unsigned int id)
103
+static int integrator_impd1_clk_probe(struct platform_device *pdev)
158104 {
159
- int i;
160
- struct impd1_clk *imc;
105
+ struct device *dev = &pdev->dev;
106
+ struct device_node *np = dev->of_node;
107
+ struct device_node *child;
108
+ int ret = 0;
161109
162
- if (id > 3)
163
- return;
164
- imc = &impd1_clks[id];
110
+ for_each_available_child_of_node(np, child) {
111
+ ret = integrator_impd1_clk_spawn(dev, np, child);
112
+ if (ret) {
113
+ of_node_put(child);
114
+ break;
115
+ }
116
+ }
165117
166
- for (i = 0; i < ARRAY_SIZE(imc->clks); i++)
167
- clkdev_drop(imc->clks[i]);
168
- clk_unregister(imc->spiclk);
169
- clk_unregister(imc->uartclk);
170
- clk_unregister(imc->vco2clk);
171
- clk_unregister(imc->vco1clk);
172
- clk_unregister(imc->pclk);
173
- kfree(imc->scname);
174
- kfree(imc->spiname);
175
- kfree(imc->uartname);
176
- kfree(imc->vco2name);
177
- kfree(imc->vco1name);
178
- kfree(imc->pclkname);
118
+ return ret;
179119 }
180
-EXPORT_SYMBOL_GPL(integrator_impd1_clk_exit);
120
+
121
+static const struct of_device_id impd1_syscon_match[] = {
122
+ { .compatible = "arm,im-pd1-syscon", },
123
+ {}
124
+};
125
+MODULE_DEVICE_TABLE(of, impd1_syscon_match);
126
+
127
+static struct platform_driver impd1_clk_driver = {
128
+ .driver = {
129
+ .name = "impd1-clk",
130
+ .of_match_table = impd1_syscon_match,
131
+ },
132
+ .probe = integrator_impd1_clk_probe,
133
+};
134
+builtin_platform_driver(impd1_clk_driver);
135
+
136
+MODULE_AUTHOR("Linus Walleij <linusw@kernel.org>");
137
+MODULE_DESCRIPTION("Arm IM-PD1 module clock driver");
138
+MODULE_LICENSE("GPL v2");