hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/clk/at91/pmc.c
....@@ -1,11 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License as published by
6
- * the Free Software Foundation; either version 2 of the License, or
7
- * (at your option) any later version.
8
- *
94 */
105
116 #include <linux/clk-provider.h>
....@@ -18,6 +13,8 @@
1813 #include <linux/syscore_ops.h>
1914
2015 #include <asm/proc-fns.h>
16
+
17
+#include <dt-bindings/clock/at91.h>
2118
2219 #include "pmc.h"
2320
....@@ -46,6 +43,72 @@
4643 return 0;
4744 }
4845 EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
46
+
47
+struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
48
+{
49
+ unsigned int type = clkspec->args[0];
50
+ unsigned int idx = clkspec->args[1];
51
+ struct pmc_data *pmc_data = data;
52
+
53
+ switch (type) {
54
+ case PMC_TYPE_CORE:
55
+ if (idx < pmc_data->ncore)
56
+ return pmc_data->chws[idx];
57
+ break;
58
+ case PMC_TYPE_SYSTEM:
59
+ if (idx < pmc_data->nsystem)
60
+ return pmc_data->shws[idx];
61
+ break;
62
+ case PMC_TYPE_PERIPHERAL:
63
+ if (idx < pmc_data->nperiph)
64
+ return pmc_data->phws[idx];
65
+ break;
66
+ case PMC_TYPE_GCK:
67
+ if (idx < pmc_data->ngck)
68
+ return pmc_data->ghws[idx];
69
+ break;
70
+ case PMC_TYPE_PROGRAMMABLE:
71
+ if (idx < pmc_data->npck)
72
+ return pmc_data->pchws[idx];
73
+ break;
74
+ default:
75
+ break;
76
+ }
77
+
78
+ pr_err("%s: invalid type (%u) or index (%u)\n", __func__, type, idx);
79
+
80
+ return ERR_PTR(-EINVAL);
81
+}
82
+
83
+struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
84
+ unsigned int nperiph, unsigned int ngck,
85
+ unsigned int npck)
86
+{
87
+ unsigned int num_clks = ncore + nsystem + nperiph + ngck + npck;
88
+ struct pmc_data *pmc_data;
89
+
90
+ pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks),
91
+ GFP_KERNEL);
92
+ if (!pmc_data)
93
+ return NULL;
94
+
95
+ pmc_data->ncore = ncore;
96
+ pmc_data->chws = pmc_data->hwtable;
97
+
98
+ pmc_data->nsystem = nsystem;
99
+ pmc_data->shws = pmc_data->chws + ncore;
100
+
101
+ pmc_data->nperiph = nperiph;
102
+ pmc_data->phws = pmc_data->shws + nsystem;
103
+
104
+ pmc_data->ngck = ngck;
105
+ pmc_data->ghws = pmc_data->phws + nperiph;
106
+
107
+ pmc_data->npck = npck;
108
+ pmc_data->pchws = pmc_data->ghws + ngck;
109
+
110
+ return pmc_data;
111
+}
49112
50113 #ifdef CONFIG_PM
51114 static struct regmap *pmcreg;
....@@ -201,8 +264,16 @@
201264 struct device_node *np;
202265
203266 np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
267
+ if (!np)
268
+ return -ENODEV;
204269
205
- pmcreg = syscon_node_to_regmap(np);
270
+ if (!of_device_is_available(np)) {
271
+ of_node_put(np);
272
+ return -ENODEV;
273
+ }
274
+
275
+ pmcreg = device_node_to_regmap(np);
276
+ of_node_put(np);
206277 if (IS_ERR(pmcreg))
207278 return PTR_ERR(pmcreg);
208279