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 struct dwc3_of_simple {
21 	struct clk_bulk		clks;
22 	struct reset_ctl_bulk	resets;
23 };
24 
25 static int dwc3_of_simple_reset_init(struct udevice *dev,
26 				     struct dwc3_of_simple *simple)
27 {
28 	int ret;
29 
30 	ret = reset_get_bulk(dev, &simple->resets);
31 	if (ret == -ENOTSUPP)
32 		return 0;
33 	else if (ret)
34 		return ret;
35 
36 	ret = reset_deassert_bulk(&simple->resets);
37 	if (ret) {
38 		reset_release_bulk(&simple->resets);
39 		return ret;
40 	}
41 
42 	return 0;
43 }
44 
45 static int dwc3_of_simple_clk_init(struct udevice *dev,
46 				   struct dwc3_of_simple *simple)
47 {
48 	int ret;
49 
50 	ret = clk_get_bulk(dev, &simple->clks);
51 	if (ret == -ENOSYS)
52 		return 0;
53 	if (ret)
54 		return ret;
55 
56 #if CONFIG_IS_ENABLED(CLK)
57 	ret = clk_enable_bulk(&simple->clks);
58 	if (ret) {
59 		clk_release_bulk(&simple->clks);
60 		return ret;
61 	}
62 #endif
63 
64 	return 0;
65 }
66 
67 static int dwc3_of_simple_probe(struct udevice *dev)
68 {
69 	struct dwc3_of_simple *simple = dev_get_platdata(dev);
70 	int ret;
71 
72 	ret = dwc3_of_simple_clk_init(dev, simple);
73 	if (ret)
74 		return ret;
75 
76 	ret = dwc3_of_simple_reset_init(dev, simple);
77 	if (ret)
78 		return ret;
79 
80 	return 0;
81 }
82 
83 static int dwc3_of_simple_remove(struct udevice *dev)
84 {
85 	struct dwc3_of_simple *simple = dev_get_platdata(dev);
86 
87 	reset_release_bulk(&simple->resets);
88 
89 	clk_release_bulk(&simple->clks);
90 
91 	return dm_scan_fdt_dev(dev);
92 }
93 
94 static const struct udevice_id dwc3_of_simple_ids[] = {
95 	{ .compatible = "amlogic,meson-gxl-dwc3" },
96 	{ .compatible = "ti,dwc3" },
97 	{ }
98 };
99 
100 U_BOOT_DRIVER(dwc3_of_simple) = {
101 	.name = "dwc3-of-simple",
102 	.id = UCLASS_SIMPLE_BUS,
103 	.of_match = dwc3_of_simple_ids,
104 	.probe = dwc3_of_simple_probe,
105 	.remove = dwc3_of_simple_remove,
106 	.platdata_auto_alloc_size = sizeof(struct dwc3_of_simple),
107 	.flags = DM_FLAG_ALLOC_PRIV_DMA,
108 };
109