]> git.sur5r.net Git - u-boot/blob - drivers/usb/host/ohci-generic.c
usb: ohci-generic: replace pr_err() by dev_err()
[u-boot] / drivers / usb / host / ohci-generic.c
1 /*
2  * Copyright (C) 2015 Alexey Brodkin <abrodkin@synopsys.com>
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <clk.h>
9 #include <dm.h>
10 #include <dm/ofnode.h>
11 #include <generic-phy.h>
12 #include <reset.h>
13 #include "ohci.h"
14
15 #if !defined(CONFIG_USB_OHCI_NEW)
16 # error "Generic OHCI driver requires CONFIG_USB_OHCI_NEW"
17 #endif
18
19 struct generic_ohci {
20         ohci_t ohci;
21         struct clk *clocks;     /* clock list */
22         struct reset_ctl *resets; /* reset list */
23         struct phy phy;
24         int clock_count;        /* number of clock in clock list */
25         int reset_count;        /* number of reset in reset list */
26 };
27
28 static int ohci_setup_phy(struct udevice *dev, int index)
29 {
30         struct generic_ohci *priv = dev_get_priv(dev);
31         int ret;
32
33         ret = generic_phy_get_by_index(dev, index, &priv->phy);
34         if (ret) {
35                 if (ret != -ENOENT) {
36                         dev_err(dev, "failed to get usb phy\n");
37                         return ret;
38                 }
39         } else {
40                 ret = generic_phy_init(&priv->phy);
41                 if (ret) {
42                         dev_err(dev, "failed to init usb phy\n");
43                         return ret;
44                 }
45
46                 ret = generic_phy_power_on(&priv->phy);
47                 if (ret) {
48                         dev_err(dev, "failed to power on usb phy\n");
49                         return generic_phy_exit(&priv->phy);
50                 }
51         }
52
53         return 0;
54 }
55
56 static int ohci_shutdown_phy(struct udevice *dev)
57 {
58         struct generic_ohci *priv = dev_get_priv(dev);
59         int ret = 0;
60
61         if (generic_phy_valid(&priv->phy)) {
62                 ret = generic_phy_power_off(&priv->phy);
63                 if (ret) {
64                         dev_err(dev, "failed to power off usb phy\n");
65                         return ret;
66                 }
67
68                 ret = generic_phy_exit(&priv->phy);
69                 if (ret) {
70                         dev_err(dev, "failed to power off usb phy\n");
71                         return ret;
72                 }
73         }
74
75         return 0;
76 }
77
78 static int ohci_usb_probe(struct udevice *dev)
79 {
80         struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev);
81         struct generic_ohci *priv = dev_get_priv(dev);
82         int i, err, ret, clock_nb, reset_nb;
83
84         err = 0;
85         priv->clock_count = 0;
86         clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells");
87         if (clock_nb > 0) {
88                 priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk),
89                                             GFP_KERNEL);
90                 if (!priv->clocks)
91                         return -ENOMEM;
92
93                 for (i = 0; i < clock_nb; i++) {
94                         err = clk_get_by_index(dev, i, &priv->clocks[i]);
95                         if (err < 0)
96                                 break;
97
98                         err = clk_enable(&priv->clocks[i]);
99                         if (err) {
100                                 dev_err(dev, "failed to enable clock %d\n", i);
101                                 clk_free(&priv->clocks[i]);
102                                 goto clk_err;
103                         }
104                         priv->clock_count++;
105                 }
106         } else if (clock_nb != -ENOENT) {
107                 dev_err(dev, "failed to get clock phandle(%d)\n", clock_nb);
108                 return clock_nb;
109         }
110
111         priv->reset_count = 0;
112         reset_nb = dev_count_phandle_with_args(dev, "resets", "#reset-cells");
113         if (reset_nb > 0) {
114                 priv->resets = devm_kcalloc(dev, reset_nb,
115                                             sizeof(struct reset_ctl),
116                                             GFP_KERNEL);
117                 if (!priv->resets)
118                         return -ENOMEM;
119
120                 for (i = 0; i < reset_nb; i++) {
121                         err = reset_get_by_index(dev, i, &priv->resets[i]);
122                         if (err < 0)
123                                 break;
124
125                         err = reset_deassert(&priv->resets[i]);
126                         if (err) {
127                                 dev_err(dev, "failed to deassert reset %d\n", i);
128                                 reset_free(&priv->resets[i]);
129                                 goto reset_err;
130                         }
131                         priv->reset_count++;
132                 }
133         } else if (reset_nb != -ENOENT) {
134                 dev_err(dev, "failed to get reset phandle(%d)\n", reset_nb);
135                 goto clk_err;
136         }
137
138         err = ohci_setup_phy(dev, 0);
139         if (err)
140                 goto reset_err;
141
142         err = ohci_register(dev, regs);
143         if (err)
144                 goto phy_err;
145
146         return 0;
147
148 phy_err:
149         ret = ohci_shutdown_phy(dev);
150         if (ret)
151                 dev_err(dev, "failed to shutdown usb phy\n");
152
153 reset_err:
154         ret = reset_release_all(priv->resets, priv->reset_count);
155         if (ret)
156                 dev_err(dev, "failed to assert all resets\n");
157 clk_err:
158         ret = clk_release_all(priv->clocks, priv->clock_count);
159         if (ret)
160                 dev_err(dev, "failed to disable all clocks\n");
161
162         return err;
163 }
164
165 static int ohci_usb_remove(struct udevice *dev)
166 {
167         struct generic_ohci *priv = dev_get_priv(dev);
168         int ret;
169
170         ret = ohci_deregister(dev);
171         if (ret)
172                 return ret;
173
174         ret = ohci_shutdown_phy(dev);
175         if (ret)
176                 return ret;
177
178         ret = reset_release_all(priv->resets, priv->reset_count);
179         if (ret)
180                 return ret;
181
182         return clk_release_all(priv->clocks, priv->clock_count);
183 }
184
185 static const struct udevice_id ohci_usb_ids[] = {
186         { .compatible = "generic-ohci" },
187         { }
188 };
189
190 U_BOOT_DRIVER(ohci_generic) = {
191         .name   = "ohci_generic",
192         .id     = UCLASS_USB,
193         .of_match = ohci_usb_ids,
194         .probe = ohci_usb_probe,
195         .remove = ohci_usb_remove,
196         .ops    = &ohci_usb_ops,
197         .priv_auto_alloc_size = sizeof(struct generic_ohci),
198         .flags  = DM_FLAG_ALLOC_PRIV_DMA,
199 };