Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
usb
dwc3
dwc3-exynos.c
Go to the documentation of this file.
1
15
#include <linux/module.h>
16
#include <linux/kernel.h>
17
#include <linux/slab.h>
18
#include <
linux/platform_device.h
>
19
#include <
linux/platform_data/dwc3-exynos.h
>
20
#include <
linux/dma-mapping.h
>
21
#include <
linux/clk.h
>
22
#include <
linux/usb/otg.h
>
23
#include <
linux/usb/nop-usb-xceiv.h
>
24
25
#include "
core.h
"
26
27
struct
dwc3_exynos
{
28
struct
platform_device
*
dwc3
;
29
struct
platform_device
*
usb2_phy
;
30
struct
platform_device
*
usb3_phy
;
31
struct
device
*
dev
;
32
33
struct
clk
*
clk
;
34
};
35
36
static
int
__devinit
dwc3_exynos_register_phys(
struct
dwc3_exynos
*exynos)
37
{
38
struct
nop_usb_xceiv_platform_data
pdata;
39
struct
platform_device
*
pdev
;
40
int
ret
;
41
42
memset
(&pdata, 0x00,
sizeof
(pdata));
43
44
pdev =
platform_device_alloc
(
"nop_usb_xceiv"
, 0);
45
if
(!pdev)
46
return
-
ENOMEM
;
47
48
exynos->
usb2_phy
= pdev;
49
pdata.
type
=
USB_PHY_TYPE_USB2
;
50
51
ret =
platform_device_add_data
(exynos->
usb2_phy
, &pdata,
sizeof
(pdata));
52
if
(ret)
53
goto
err1;
54
55
pdev =
platform_device_alloc
(
"nop_usb_xceiv"
, 1);
56
if
(!pdev) {
57
ret = -
ENOMEM
;
58
goto
err1;
59
}
60
61
exynos->
usb3_phy
= pdev;
62
pdata.
type
=
USB_PHY_TYPE_USB3
;
63
64
ret =
platform_device_add_data
(exynos->
usb3_phy
, &pdata,
sizeof
(pdata));
65
if
(ret)
66
goto
err2;
67
68
ret =
platform_device_add
(exynos->
usb2_phy
);
69
if
(ret)
70
goto
err2;
71
72
ret =
platform_device_add
(exynos->
usb3_phy
);
73
if
(ret)
74
goto
err3;
75
76
return
0;
77
78
err3:
79
platform_device_del
(exynos->
usb2_phy
);
80
81
err2:
82
platform_device_put
(exynos->
usb3_phy
);
83
84
err1:
85
platform_device_put
(exynos->
usb2_phy
);
86
87
return
ret
;
88
}
89
90
static
int
__devinit
dwc3_exynos_probe(
struct
platform_device
*pdev)
91
{
92
struct
dwc3_exynos_data
*pdata = pdev->
dev
.platform_data;
93
struct
platform_device
*
dwc3
;
94
struct
dwc3_exynos
*exynos;
95
struct
clk
*
clk
;
96
97
int
devid
;
98
int
ret = -
ENOMEM
;
99
100
exynos = kzalloc(
sizeof
(*exynos),
GFP_KERNEL
);
101
if
(!exynos) {
102
dev_err
(&pdev->
dev
,
"not enough memory\n"
);
103
goto
err0;
104
}
105
106
platform_set_drvdata(pdev, exynos);
107
108
devid =
dwc3_get_device_id
();
109
if
(devid < 0)
110
goto
err1;
111
112
ret = dwc3_exynos_register_phys(exynos);
113
if
(ret) {
114
dev_err
(&pdev->
dev
,
"couldn't register PHYs\n"
);
115
goto
err1;
116
}
117
118
dwc3 =
platform_device_alloc
(
"dwc3"
, devid);
119
if
(!dwc3) {
120
dev_err
(&pdev->
dev
,
"couldn't allocate dwc3 device\n"
);
121
goto
err2;
122
}
123
124
clk =
clk_get
(&pdev->
dev
,
"usbdrd30"
);
125
if
(IS_ERR(clk)) {
126
dev_err
(&pdev->
dev
,
"couldn't get clock\n"
);
127
ret = -
EINVAL
;
128
goto
err3;
129
}
130
131
dma_set_coherent_mask
(&dwc3->
dev
, pdev->
dev
.coherent_dma_mask);
132
133
dwc3->
dev
.parent = &pdev->
dev
;
134
dwc3->
dev
.dma_mask = pdev->
dev
.dma_mask;
135
dwc3->
dev
.dma_parms = pdev->
dev
.dma_parms;
136
exynos->
dwc3
= dwc3;
137
exynos->
dev
= &pdev->
dev
;
138
exynos->
clk
= clk;
139
140
clk_enable
(exynos->
clk
);
141
142
/* PHY initialization */
143
if
(!pdata) {
144
dev_dbg
(&pdev->
dev
,
"missing platform data\n"
);
145
}
else
{
146
if
(pdata->
phy_init
)
147
pdata->
phy_init
(pdev, pdata->
phy_type
);
148
}
149
150
ret =
platform_device_add_resources
(dwc3, pdev->
resource
,
151
pdev->
num_resources
);
152
if
(ret) {
153
dev_err
(&pdev->
dev
,
"couldn't add resources to dwc3 device\n"
);
154
goto
err4;
155
}
156
157
ret =
platform_device_add
(dwc3);
158
if
(ret) {
159
dev_err
(&pdev->
dev
,
"failed to register dwc3 device\n"
);
160
goto
err4;
161
}
162
163
return
0;
164
165
err4:
166
if
(pdata && pdata->
phy_exit
)
167
pdata->
phy_exit
(pdev, pdata->
phy_type
);
168
169
clk_disable
(clk);
170
clk_put
(clk);
171
err3:
172
platform_device_put
(dwc3);
173
err2:
174
dwc3_put_device_id
(devid);
175
err1:
176
kfree
(exynos);
177
err0:
178
return
ret
;
179
}
180
181
static
int
__devexit
dwc3_exynos_remove(
struct
platform_device
*pdev)
182
{
183
struct
dwc3_exynos
*exynos = platform_get_drvdata(pdev);
184
struct
dwc3_exynos_data
*pdata = pdev->
dev
.platform_data;
185
186
platform_device_unregister
(exynos->
dwc3
);
187
platform_device_unregister
(exynos->
usb2_phy
);
188
platform_device_unregister
(exynos->
usb3_phy
);
189
190
dwc3_put_device_id
(exynos->
dwc3
->id);
191
192
if
(pdata && pdata->
phy_exit
)
193
pdata->
phy_exit
(pdev, pdata->
phy_type
);
194
195
clk_disable
(exynos->
clk
);
196
clk_put
(exynos->
clk
);
197
198
kfree
(exynos);
199
200
return
0;
201
}
202
203
static
struct
platform_driver
dwc3_exynos_driver = {
204
.probe = dwc3_exynos_probe,
205
.remove =
__devexit_p
(dwc3_exynos_remove),
206
.driver = {
207
.name =
"exynos-dwc3"
,
208
},
209
};
210
211
module_platform_driver
(dwc3_exynos_driver);
212
213
MODULE_ALIAS
(
"platform:exynos-dwc3"
);
214
MODULE_AUTHOR
(
"Anton Tikhomirov <
[email protected]
>"
);
215
MODULE_LICENSE
(
"GPL"
);
216
MODULE_DESCRIPTION
(
"DesignWare USB3 EXYNOS Glue Layer"
);
Generated on Thu Jan 10 2013 14:35:55 for Linux Kernel by
1.8.2