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-pci.c
Go to the documentation of this file.
1
39
#include <linux/kernel.h>
40
#include <linux/module.h>
41
#include <linux/slab.h>
42
#include <linux/pci.h>
43
#include <
linux/platform_device.h
>
44
45
#include <
linux/usb/otg.h
>
46
#include <
linux/usb/nop-usb-xceiv.h
>
47
48
#include "
core.h
"
49
50
/* FIXME define these in <linux/pci_ids.h> */
51
#define PCI_VENDOR_ID_SYNOPSYS 0x16c3
52
#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd
53
54
struct
dwc3_pci
{
55
struct
device
*
dev
;
56
struct
platform_device
*
dwc3
;
57
struct
platform_device
*
usb2_phy
;
58
struct
platform_device
*
usb3_phy
;
59
};
60
61
static
int
__devinit
dwc3_pci_register_phys(
struct
dwc3_pci
*glue)
62
{
63
struct
nop_usb_xceiv_platform_data
pdata;
64
struct
platform_device
*
pdev
;
65
int
ret
;
66
67
memset
(&pdata, 0x00,
sizeof
(pdata));
68
69
pdev =
platform_device_alloc
(
"nop_usb_xceiv"
, 0);
70
if
(!pdev)
71
return
-
ENOMEM
;
72
73
glue->
usb2_phy
= pdev;
74
pdata.
type
=
USB_PHY_TYPE_USB2
;
75
76
ret =
platform_device_add_data
(glue->
usb2_phy
, &pdata,
sizeof
(pdata));
77
if
(ret)
78
goto
err1;
79
80
pdev =
platform_device_alloc
(
"nop_usb_xceiv"
, 1);
81
if
(!pdev) {
82
ret = -
ENOMEM
;
83
goto
err1;
84
}
85
86
glue->
usb3_phy
= pdev;
87
pdata.
type
=
USB_PHY_TYPE_USB3
;
88
89
ret =
platform_device_add_data
(glue->
usb3_phy
, &pdata,
sizeof
(pdata));
90
if
(ret)
91
goto
err2;
92
93
ret =
platform_device_add
(glue->
usb2_phy
);
94
if
(ret)
95
goto
err2;
96
97
ret =
platform_device_add
(glue->
usb3_phy
);
98
if
(ret)
99
goto
err3;
100
101
return
0;
102
103
err3:
104
platform_device_del
(glue->
usb2_phy
);
105
106
err2:
107
platform_device_put
(glue->
usb3_phy
);
108
109
err1:
110
platform_device_put
(glue->
usb2_phy
);
111
112
return
ret
;
113
}
114
115
static
int
__devinit
dwc3_pci_probe(
struct
pci_dev
*pci,
116
const
struct
pci_device_id
*
id
)
117
{
118
struct
resource
res
[2];
119
struct
platform_device
*
dwc3
;
120
struct
dwc3_pci
*glue;
121
int
ret = -
ENOMEM
;
122
int
devid
;
123
struct
device
*
dev
= &pci->
dev
;
124
125
glue =
devm_kzalloc
(dev,
sizeof
(*glue),
GFP_KERNEL
);
126
if
(!glue) {
127
dev_err
(dev,
"not enough memory\n"
);
128
return
-
ENOMEM
;
129
}
130
131
glue->
dev
=
dev
;
132
133
ret =
pci_enable_device
(pci);
134
if
(ret) {
135
dev_err
(dev,
"failed to enable pci device\n"
);
136
return
-
ENODEV
;
137
}
138
139
pci_set_power_state
(pci,
PCI_D0
);
140
pci_set_master
(pci);
141
142
ret = dwc3_pci_register_phys(glue);
143
if
(ret) {
144
dev_err
(dev,
"couldn't register PHYs\n"
);
145
return
ret
;
146
}
147
148
devid =
dwc3_get_device_id
();
149
if
(devid < 0) {
150
ret = -
ENOMEM
;
151
goto
err1;
152
}
153
154
dwc3 =
platform_device_alloc
(
"dwc3"
, devid);
155
if
(!dwc3) {
156
dev_err
(dev,
"couldn't allocate dwc3 device\n"
);
157
ret = -
ENOMEM
;
158
goto
err1;
159
}
160
161
memset
(
res
, 0x00,
sizeof
(
struct
resource
) *
ARRAY_SIZE
(
res
));
162
163
res
[0].start =
pci_resource_start
(pci, 0);
164
res
[0].end =
pci_resource_end
(pci, 0);
165
res
[0].name =
"dwc_usb3"
;
166
res
[0].flags =
IORESOURCE_MEM
;
167
168
res
[1].start = pci->
irq
;
169
res
[1].name =
"dwc_usb3"
;
170
res
[1].flags =
IORESOURCE_IRQ
;
171
172
ret =
platform_device_add_resources
(dwc3,
res
,
ARRAY_SIZE
(
res
));
173
if
(ret) {
174
dev_err
(dev,
"couldn't add resources to dwc3 device\n"
);
175
goto
err2;
176
}
177
178
pci_set_drvdata(pci, glue);
179
180
dma_set_coherent_mask
(&dwc3->
dev
, dev->
coherent_dma_mask
);
181
182
dwc3->
dev
.dma_mask = dev->
dma_mask
;
183
dwc3->
dev
.dma_parms = dev->
dma_parms
;
184
dwc3->
dev
.parent =
dev
;
185
glue->
dwc3
= dwc3;
186
187
ret =
platform_device_add
(dwc3);
188
if
(ret) {
189
dev_err
(dev,
"failed to register dwc3 device\n"
);
190
goto
err3;
191
}
192
193
return
0;
194
195
err3:
196
pci_set_drvdata(pci,
NULL
);
197
platform_device_put
(dwc3);
198
199
err2:
200
dwc3_put_device_id
(devid);
201
202
err1:
203
pci_disable_device
(pci);
204
205
return
ret
;
206
}
207
208
static
void
__devexit
dwc3_pci_remove(
struct
pci_dev
*pci)
209
{
210
struct
dwc3_pci
*glue = pci_get_drvdata(pci);
211
212
platform_device_unregister
(glue->
usb2_phy
);
213
platform_device_unregister
(glue->
usb3_phy
);
214
dwc3_put_device_id
(glue->
dwc3
->id);
215
platform_device_unregister
(glue->
dwc3
);
216
pci_set_drvdata(pci,
NULL
);
217
pci_disable_device
(pci);
218
}
219
220
static
DEFINE_PCI_DEVICE_TABLE
(dwc3_pci_id_table) = {
221
{
222
PCI_DEVICE
(
PCI_VENDOR_ID_SYNOPSYS
,
223
PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3
),
224
},
225
{ }
/* Terminating Entry */
226
};
227
MODULE_DEVICE_TABLE
(pci, dwc3_pci_id_table);
228
229
static
struct
pci_driver
dwc3_pci_driver = {
230
.name =
"dwc3-pci"
,
231
.id_table = dwc3_pci_id_table,
232
.probe = dwc3_pci_probe,
233
.remove =
__devexit_p
(dwc3_pci_remove),
234
};
235
236
MODULE_AUTHOR
(
"Felipe Balbi <
[email protected]
>"
);
237
MODULE_LICENSE
(
"Dual BSD/GPL"
);
238
MODULE_DESCRIPTION
(
"DesignWare USB3 PCI Glue Layer"
);
239
240
module_pci_driver
(dwc3_pci_driver);
Generated on Thu Jan 10 2013 14:35:55 for Linux Kernel by
1.8.2