Merge branch 'next' of git://git.denx.de/u-boot-usb into next
[oweals/u-boot.git] / drivers / usb / host / dwc3-of-simple.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * dwc3-of-simple.c - OF glue layer for simple integrations
4  *
5  * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
6  *
7  * Author: Felipe Balbi <balbi@ti.com>
8  *
9  * Copyright (C) 2018 BayLibre, SAS
10  * Author: Neil Armstrong <narmstron@baylibre.com>
11  */
12
13 #include <common.h>
14 #include <dm.h>
15 #include <reset.h>
16 #include <clk.h>
17
18 struct dwc3_of_simple {
19         struct clk_bulk         clks;
20         struct reset_ctl_bulk   resets;
21 };
22
23 static int dwc3_of_simple_reset_init(struct udevice *dev,
24                                      struct dwc3_of_simple *simple)
25 {
26         int ret;
27
28         ret = reset_get_bulk(dev, &simple->resets);
29         if (ret == -ENOTSUPP)
30                 return 0;
31         else if (ret)
32                 return ret;
33
34         ret = reset_deassert_bulk(&simple->resets);
35         if (ret) {
36                 reset_release_bulk(&simple->resets);
37                 return ret;
38         }
39
40         return 0;
41 }
42
43 static int dwc3_of_simple_clk_init(struct udevice *dev,
44                                    struct dwc3_of_simple *simple)
45 {
46         int ret;
47
48         ret = clk_get_bulk(dev, &simple->clks);
49         if (ret == -ENOSYS)
50                 return 0;
51         if (ret)
52                 return ret;
53
54 #if CONFIG_IS_ENABLED(CLK)
55         ret = clk_enable_bulk(&simple->clks);
56         if (ret) {
57                 clk_release_bulk(&simple->clks);
58                 return ret;
59         }
60 #endif
61
62         return 0;
63 }
64
65 static int dwc3_of_simple_probe(struct udevice *dev)
66 {
67         struct dwc3_of_simple *simple = dev_get_platdata(dev);
68         int ret;
69
70         ret = dwc3_of_simple_clk_init(dev, simple);
71         if (ret)
72                 return ret;
73
74         ret = dwc3_of_simple_reset_init(dev, simple);
75         if (ret)
76                 return ret;
77
78         return 0;
79 }
80
81 static int dwc3_of_simple_remove(struct udevice *dev)
82 {
83         struct dwc3_of_simple *simple = dev_get_platdata(dev);
84
85         reset_release_bulk(&simple->resets);
86
87         clk_release_bulk(&simple->clks);
88
89         return dm_scan_fdt_dev(dev);
90 }
91
92 static const struct udevice_id dwc3_of_simple_ids[] = {
93         { .compatible = "amlogic,meson-gxl-dwc3" },
94         { .compatible = "rockchip,rk3399-dwc3" },
95         { .compatible = "ti,dwc3" },
96         { }
97 };
98
99 U_BOOT_DRIVER(dwc3_of_simple) = {
100         .name = "dwc3-of-simple",
101         .id = UCLASS_SIMPLE_BUS,
102         .of_match = dwc3_of_simple_ids,
103         .probe = dwc3_of_simple_probe,
104         .remove = dwc3_of_simple_remove,
105         .platdata_auto_alloc_size = sizeof(struct dwc3_of_simple),
106         .flags = DM_FLAG_ALLOC_PRIV_DMA,
107 };