c695b69321e2ecb7cb6fbc35a6d9dedb735da97e
[pandora-u-boot.git] / drivers / clk / clk_sandbox_test.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2016, NVIDIA CORPORATION.
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <clk.h>
9 #include <malloc.h>
10 #include <asm/clk.h>
11 #include <dm/device_compat.h>
12 #include <linux/err.h>
13
14 static const char * const sandbox_clk_test_names[] = {
15         [SANDBOX_CLK_TEST_ID_FIXED] = "fixed",
16         [SANDBOX_CLK_TEST_ID_SPI] = "spi",
17         [SANDBOX_CLK_TEST_ID_I2C] = "i2c",
18         [SANDBOX_CLK_TEST_ID_I2C_ROOT] = "i2c_root",
19 };
20
21 int sandbox_clk_test_get(struct udevice *dev)
22 {
23         struct sandbox_clk_test *sbct = dev_get_priv(dev);
24         int i, ret;
25
26         for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++) {
27                 ret = clk_get_by_name(dev, sandbox_clk_test_names[i],
28                                       &sbct->clks[i]);
29                 if (ret)
30                         return ret;
31         }
32
33         return 0;
34 }
35
36 int sandbox_clk_test_devm_get(struct udevice *dev)
37 {
38         struct sandbox_clk_test *sbct = dev_get_priv(dev);
39         struct clk *clk;
40
41         clk = devm_clk_get(dev, "no-an-existing-clock");
42         if (!IS_ERR(clk)) {
43                 dev_err(dev, "devm_clk_get() should have failed\n");
44                 return -EINVAL;
45         }
46
47         clk = devm_clk_get(dev, "uart2");
48         if (IS_ERR(clk))
49                 return PTR_ERR(clk);
50         sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1] = clk;
51
52         clk = devm_clk_get_optional(dev, "uart1");
53         if (IS_ERR(clk))
54                 return PTR_ERR(clk);
55         sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM2] = clk;
56
57         sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM_NULL] = NULL;
58         clk = devm_clk_get_optional(dev, "not_an_existing_clock");
59         if (IS_ERR(clk))
60                 return PTR_ERR(clk);
61         if (clk)
62                 return -EINVAL;
63
64         return 0;
65 }
66
67 int sandbox_clk_test_get_bulk(struct udevice *dev)
68 {
69         struct sandbox_clk_test *sbct = dev_get_priv(dev);
70
71         return clk_get_bulk(dev, &sbct->bulk);
72 }
73
74 ulong sandbox_clk_test_get_rate(struct udevice *dev, int id)
75 {
76         struct sandbox_clk_test *sbct = dev_get_priv(dev);
77
78         if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
79                 return -EINVAL;
80
81         return clk_get_rate(sbct->clkps[id]);
82 }
83
84 ulong sandbox_clk_test_round_rate(struct udevice *dev, int id, ulong rate)
85 {
86         struct sandbox_clk_test *sbct = dev_get_priv(dev);
87
88         if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
89                 return -EINVAL;
90
91         return clk_round_rate(sbct->clkps[id], rate);
92 }
93
94 ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
95 {
96         struct sandbox_clk_test *sbct = dev_get_priv(dev);
97
98         if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
99                 return -EINVAL;
100
101         return clk_set_rate(sbct->clkps[id], rate);
102 }
103
104 int sandbox_clk_test_enable(struct udevice *dev, int id)
105 {
106         struct sandbox_clk_test *sbct = dev_get_priv(dev);
107
108         if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
109                 return -EINVAL;
110
111         return clk_enable(sbct->clkps[id]);
112 }
113
114 int sandbox_clk_test_enable_bulk(struct udevice *dev)
115 {
116         struct sandbox_clk_test *sbct = dev_get_priv(dev);
117
118         return clk_enable_bulk(&sbct->bulk);
119 }
120
121 int sandbox_clk_test_disable(struct udevice *dev, int id)
122 {
123         struct sandbox_clk_test *sbct = dev_get_priv(dev);
124
125         if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
126                 return -EINVAL;
127
128         return clk_disable(sbct->clkps[id]);
129 }
130
131 int sandbox_clk_test_disable_bulk(struct udevice *dev)
132 {
133         struct sandbox_clk_test *sbct = dev_get_priv(dev);
134
135         return clk_disable_bulk(&sbct->bulk);
136 }
137
138 int sandbox_clk_test_free(struct udevice *dev)
139 {
140         struct sandbox_clk_test *sbct = dev_get_priv(dev);
141         int i;
142
143         devm_clk_put(dev, sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1]);
144         for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++)
145                 clk_free(&sbct->clks[i]);
146
147         return 0;
148 }
149
150 int sandbox_clk_test_release_bulk(struct udevice *dev)
151 {
152         struct sandbox_clk_test *sbct = dev_get_priv(dev);
153
154         return clk_release_bulk(&sbct->bulk);
155 }
156
157 int sandbox_clk_test_valid(struct udevice *dev)
158 {
159         struct sandbox_clk_test *sbct = dev_get_priv(dev);
160         int i;
161
162         for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
163                 if (!clk_valid(sbct->clkps[i]))
164                         if (i != SANDBOX_CLK_TEST_ID_DEVM_NULL)
165                                 return -EINVAL;
166         }
167
168         return 0;
169 }
170
171 static int sandbox_clk_test_probe(struct udevice *dev)
172 {
173         struct sandbox_clk_test *sbct = dev_get_priv(dev);
174         int i;
175
176         for (i = 0; i < SANDBOX_CLK_TEST_ID_DEVM1; i++)
177                 sbct->clkps[i] = &sbct->clks[i];
178         for (i = SANDBOX_CLK_TEST_ID_DEVM1; i < SANDBOX_CLK_TEST_ID_COUNT; i++)
179                 sbct->clkps[i] = NULL;
180
181         return 0;
182 }
183
184 static const struct udevice_id sandbox_clk_test_ids[] = {
185         { .compatible = "sandbox,clk-test" },
186         { }
187 };
188
189 U_BOOT_DRIVER(sandbox_clk_test) = {
190         .name = "sandbox_clk_test",
191         .id = UCLASS_MISC,
192         .of_match = sandbox_clk_test_ids,
193         .probe = sandbox_clk_test_probe,
194         .priv_auto      = sizeof(struct sandbox_clk_test),
195 };