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 };
111