Merge tag 'dm-pull-29oct19' of git://git.denx.de/u-boot-dm
[oweals/u-boot.git] / drivers / clk / clk_sandbox.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) Copyright 2015 Google, Inc
4  */
5
6 #include <common.h>
7 #include <clk-uclass.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <asm/clk.h>
11
12 struct sandbox_clk_priv {
13         bool probed;
14         ulong rate[SANDBOX_CLK_ID_COUNT];
15         bool enabled[SANDBOX_CLK_ID_COUNT];
16         bool requested[SANDBOX_CLK_ID_COUNT];
17 };
18
19 static ulong sandbox_clk_get_rate(struct clk *clk)
20 {
21         struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
22
23         if (!priv->probed)
24                 return -ENODEV;
25
26         if (clk->id >= SANDBOX_CLK_ID_COUNT)
27                 return -EINVAL;
28
29         return priv->rate[clk->id];
30 }
31
32 static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate)
33 {
34         struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
35         ulong old_rate;
36
37         if (!priv->probed)
38                 return -ENODEV;
39
40         if (clk->id >= SANDBOX_CLK_ID_COUNT)
41                 return -EINVAL;
42
43         if (!rate)
44                 return -EINVAL;
45
46         old_rate = priv->rate[clk->id];
47         priv->rate[clk->id] = rate;
48
49         return old_rate;
50 }
51
52 static int sandbox_clk_enable(struct clk *clk)
53 {
54         struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
55
56         if (!priv->probed)
57                 return -ENODEV;
58
59         if (clk->id >= SANDBOX_CLK_ID_COUNT)
60                 return -EINVAL;
61
62         priv->enabled[clk->id] = true;
63
64         return 0;
65 }
66
67 static int sandbox_clk_disable(struct clk *clk)
68 {
69         struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
70
71         if (!priv->probed)
72                 return -ENODEV;
73
74         if (clk->id >= SANDBOX_CLK_ID_COUNT)
75                 return -EINVAL;
76
77         priv->enabled[clk->id] = false;
78
79         return 0;
80 }
81
82 static int sandbox_clk_request(struct clk *clk)
83 {
84         struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
85
86         if (clk->id >= SANDBOX_CLK_ID_COUNT)
87                 return -EINVAL;
88
89         priv->requested[clk->id] = true;
90         return 0;
91 }
92
93 static int sandbox_clk_free(struct clk *clk)
94 {
95         struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
96
97         if (clk->id >= SANDBOX_CLK_ID_COUNT)
98                 return -EINVAL;
99
100         priv->requested[clk->id] = false;
101         return 0;
102 }
103
104 static struct clk_ops sandbox_clk_ops = {
105         .get_rate       = sandbox_clk_get_rate,
106         .set_rate       = sandbox_clk_set_rate,
107         .enable         = sandbox_clk_enable,
108         .disable        = sandbox_clk_disable,
109         .request        = sandbox_clk_request,
110         .free           = sandbox_clk_free,
111 };
112
113 static int sandbox_clk_probe(struct udevice *dev)
114 {
115         struct sandbox_clk_priv *priv = dev_get_priv(dev);
116
117         priv->probed = true;
118         return 0;
119 }
120
121 static const struct udevice_id sandbox_clk_ids[] = {
122         { .compatible = "sandbox,clk" },
123         { }
124 };
125
126 U_BOOT_DRIVER(clk_sandbox) = {
127         .name           = "clk_sandbox",
128         .id             = UCLASS_CLK,
129         .of_match       = sandbox_clk_ids,
130         .ops            = &sandbox_clk_ops,
131         .probe          = sandbox_clk_probe,
132         .priv_auto_alloc_size = sizeof(struct sandbox_clk_priv),
133 };
134
135 ulong sandbox_clk_query_rate(struct udevice *dev, int id)
136 {
137         struct sandbox_clk_priv *priv = dev_get_priv(dev);
138
139         if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
140                 return -EINVAL;
141
142         return priv->rate[id];
143 }
144
145 int sandbox_clk_query_enable(struct udevice *dev, int id)
146 {
147         struct sandbox_clk_priv *priv = dev_get_priv(dev);
148
149         if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
150                 return -EINVAL;
151
152         return priv->enabled[id];
153 }
154
155 int sandbox_clk_query_requested(struct udevice *dev, int id)
156 {
157         struct sandbox_clk_priv *priv = dev_get_priv(dev);
158
159         if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
160                 return -EINVAL;
161         return priv->requested[id];
162 }