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