dm: core: Require users of devres to include the header
[oweals/u-boot.git] / drivers / usb / host / ehci-generic.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com>
4  */
5
6 #include <common.h>
7 #include <clk.h>
8 #include <dm/devres.h>
9 #include <dm/ofnode.h>
10 #include <generic-phy.h>
11 #include <reset.h>
12 #include <asm/io.h>
13 #include <dm.h>
14 #include "ehci.h"
15 #include <power/regulator.h>
16
17 /*
18  * Even though here we don't explicitly use "struct ehci_ctrl"
19  * ehci_register() expects it to be the first thing that resides in
20  * device's private data.
21  */
22 struct generic_ehci {
23         struct ehci_ctrl ctrl;
24         struct clk *clocks;
25         struct reset_ctl *resets;
26         struct phy phy;
27 #ifdef CONFIG_DM_REGULATOR
28         struct udevice *vbus_supply;
29 #endif
30         int clock_count;
31         int reset_count;
32 };
33
34 #ifdef CONFIG_DM_REGULATOR
35 static int ehci_enable_vbus_supply(struct udevice *dev)
36 {
37         struct generic_ehci *priv = dev_get_priv(dev);
38         int ret;
39
40         ret = device_get_supply_regulator(dev, "vbus-supply",
41                                           &priv->vbus_supply);
42         if (ret && ret != -ENOENT)
43                 return ret;
44
45         if (priv->vbus_supply) {
46                 ret = regulator_set_enable(priv->vbus_supply, true);
47                 if (ret) {
48                         dev_err(dev, "Error enabling VBUS supply\n");
49                         return ret;
50                 }
51         } else {
52                 dev_dbg(dev, "No vbus supply\n");
53         }
54
55         return 0;
56 }
57
58 static int ehci_disable_vbus_supply(struct generic_ehci *priv)
59 {
60         if (priv->vbus_supply)
61                 return regulator_set_enable(priv->vbus_supply, false);
62         else
63                 return 0;
64 }
65 #else
66 static int ehci_enable_vbus_supply(struct udevice *dev)
67 {
68         return 0;
69 }
70
71 static int ehci_disable_vbus_supply(struct generic_ehci *priv)
72 {
73         return 0;
74 }
75 #endif
76
77 static int ehci_usb_probe(struct udevice *dev)
78 {
79         struct generic_ehci *priv = dev_get_priv(dev);
80         struct ehci_hccr *hccr;
81         struct ehci_hcor *hcor;
82         int i, err, ret, clock_nb, reset_nb;
83
84         err = 0;
85         priv->clock_count = 0;
86         clock_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "clocks",
87                                                   "#clock-cells");
88         if (clock_nb > 0) {
89                 priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
90                                             GFP_KERNEL);
91                 if (!priv->clocks)
92                         return -ENOMEM;
93
94                 for (i = 0; i < clock_nb; i++) {
95                         err = clk_get_by_index(dev, i, &priv->clocks[i]);
96
97                         if (err < 0)
98                                 break;
99                         err = clk_enable(&priv->clocks[i]);
100                         if (err && err != -ENOSYS) {
101                                 dev_err(dev, "failed to enable clock %d\n", i);
102                                 clk_free(&priv->clocks[i]);
103                                 goto clk_err;
104                         }
105                         priv->clock_count++;
106                 }
107         } else {
108                 if (clock_nb != -ENOENT) {
109                         dev_err(dev, "failed to get clock phandle(%d)\n",
110                                 clock_nb);
111                         return clock_nb;
112                 }
113         }
114
115         priv->reset_count = 0;
116         reset_nb = ofnode_count_phandle_with_args(dev_ofnode(dev), "resets",
117                                                   "#reset-cells");
118         if (reset_nb > 0) {
119                 priv->resets = devm_kcalloc(dev, reset_nb,
120                                             sizeof(struct reset_ctl),
121                                             GFP_KERNEL);
122                 if (!priv->resets)
123                         return -ENOMEM;
124
125                 for (i = 0; i < reset_nb; i++) {
126                         err = reset_get_by_index(dev, i, &priv->resets[i]);
127                         if (err < 0)
128                                 break;
129
130                         if (reset_deassert(&priv->resets[i])) {
131                                 dev_err(dev, "failed to deassert reset %d\n",
132                                         i);
133                                 reset_free(&priv->resets[i]);
134                                 goto reset_err;
135                         }
136                         priv->reset_count++;
137                 }
138         } else {
139                 if (reset_nb != -ENOENT) {
140                         dev_err(dev, "failed to get reset phandle(%d)\n",
141                                 reset_nb);
142                         goto clk_err;
143                 }
144         }
145
146         err = ehci_enable_vbus_supply(dev);
147         if (err)
148                 goto reset_err;
149
150         err = ehci_setup_phy(dev, &priv->phy, 0);
151         if (err)
152                 goto regulator_err;
153
154         hccr = map_physmem(dev_read_addr(dev), 0x100, MAP_NOCACHE);
155         hcor = (struct ehci_hcor *)((uintptr_t)hccr +
156                                     HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
157
158         err = ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
159         if (err)
160                 goto phy_err;
161
162         return 0;
163
164 phy_err:
165         ret = ehci_shutdown_phy(dev, &priv->phy);
166         if (ret)
167                 dev_err(dev, "failed to shutdown usb phy\n");
168
169 regulator_err:
170         ret = ehci_disable_vbus_supply(priv);
171         if (ret)
172                 dev_err(dev, "failed to disable VBUS supply\n");
173
174 reset_err:
175         ret = reset_release_all(priv->resets, priv->reset_count);
176         if (ret)
177                 dev_err(dev, "failed to assert all resets\n");
178 clk_err:
179         ret = clk_release_all(priv->clocks, priv->clock_count);
180         if (ret)
181                 dev_err(dev, "failed to disable all clocks\n");
182
183         return err;
184 }
185
186 static int ehci_usb_remove(struct udevice *dev)
187 {
188         struct generic_ehci *priv = dev_get_priv(dev);
189         int ret;
190
191         ret = ehci_deregister(dev);
192         if (ret)
193                 return ret;
194
195         ret = ehci_shutdown_phy(dev, &priv->phy);
196         if (ret)
197                 return ret;
198
199         ret = ehci_disable_vbus_supply(priv);
200         if (ret)
201                 return ret;
202
203         ret =  reset_release_all(priv->resets, priv->reset_count);
204         if (ret)
205                 return ret;
206
207         return clk_release_all(priv->clocks, priv->clock_count);
208 }
209
210 static const struct udevice_id ehci_usb_ids[] = {
211         { .compatible = "generic-ehci" },
212         { }
213 };
214
215 U_BOOT_DRIVER(ehci_generic) = {
216         .name   = "ehci_generic",
217         .id     = UCLASS_USB,
218         .of_match = ehci_usb_ids,
219         .probe = ehci_usb_probe,
220         .remove = ehci_usb_remove,
221         .ops    = &ehci_usb_ops,
222         .priv_auto_alloc_size = sizeof(struct generic_ehci),
223         .flags  = DM_FLAG_ALLOC_PRIV_DMA,
224 };