diff options
author | Andrzej Pietrasiewicz <andrzej.p@samsung.com> | 2014-07-15 07:09:45 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2014-07-16 13:15:28 -0400 |
commit | 90fccb529d241b55829701cfb9eb3086570f38b8 (patch) | |
tree | 4e788b13b8c35bc5c9d24597479cda82d503bf7c /drivers/usb/gadget/fusb300_udc.c | |
parent | 8443f2d2b7782fef35fe579bf1eb612c24951486 (diff) |
usb: gadget: Gadget directory cleanup - group UDC drivers
The drivers/usb/gadget directory contains many files.
Files which are related can be distributed into separate directories.
This patch moves the UDC drivers into a separate directory.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/fusb300_udc.c')
-rw-r--r-- | drivers/usb/gadget/fusb300_udc.c | 1499 |
1 files changed, 0 insertions, 1499 deletions
diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c deleted file mode 100644 index d40255f784df..000000000000 --- a/drivers/usb/gadget/fusb300_udc.c +++ /dev/null | |||
@@ -1,1499 +0,0 @@ | |||
1 | /* | ||
2 | * Fusb300 UDC (USB gadget) | ||
3 | * | ||
4 | * Copyright (C) 2010 Faraday Technology Corp. | ||
5 | * | ||
6 | * Author : Yuan-hsin Chen <yhchen@faraday-tech.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | */ | ||
12 | #include <linux/dma-mapping.h> | ||
13 | #include <linux/err.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/usb/ch9.h> | ||
19 | #include <linux/usb/gadget.h> | ||
20 | |||
21 | #include "fusb300_udc.h" | ||
22 | |||
23 | MODULE_DESCRIPTION("FUSB300 USB gadget driver"); | ||
24 | MODULE_LICENSE("GPL"); | ||
25 | MODULE_AUTHOR("Yuan-Hsin Chen, Feng-Hsin Chiang <john453@faraday-tech.com>"); | ||
26 | MODULE_ALIAS("platform:fusb300_udc"); | ||
27 | |||
28 | #define DRIVER_VERSION "20 October 2010" | ||
29 | |||
30 | static const char udc_name[] = "fusb300_udc"; | ||
31 | static const char * const fusb300_ep_name[] = { | ||
32 | "ep0", "ep1", "ep2", "ep3", "ep4", "ep5", "ep6", "ep7", "ep8", "ep9", | ||
33 | "ep10", "ep11", "ep12", "ep13", "ep14", "ep15" | ||
34 | }; | ||
35 | |||
36 | static void done(struct fusb300_ep *ep, struct fusb300_request *req, | ||
37 | int status); | ||
38 | |||
39 | static void fusb300_enable_bit(struct fusb300 *fusb300, u32 offset, | ||
40 | u32 value) | ||
41 | { | ||
42 | u32 reg = ioread32(fusb300->reg + offset); | ||
43 | |||
44 | reg |= value; | ||
45 | iowrite32(reg, fusb300->reg + offset); | ||
46 | } | ||
47 | |||
48 | static void fusb300_disable_bit(struct fusb300 *fusb300, u32 offset, | ||
49 | u32 value) | ||
50 | { | ||
51 | u32 reg = ioread32(fusb300->reg + offset); | ||
52 | |||
53 | reg &= ~value; | ||
54 | iowrite32(reg, fusb300->reg + offset); | ||
55 | } | ||
56 | |||
57 | |||
58 | static void fusb300_ep_setting(struct fusb300_ep *ep, | ||
59 | struct fusb300_ep_info info) | ||
60 | { | ||
61 | ep->epnum = info.epnum; | ||
62 | ep->type = info.type; | ||
63 | } | ||
64 | |||
65 | static int fusb300_ep_release(struct fusb300_ep *ep) | ||
66 | { | ||
67 | if (!ep->epnum) | ||
68 | return 0; | ||
69 | ep->epnum = 0; | ||
70 | ep->stall = 0; | ||
71 | ep->wedged = 0; | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static void fusb300_set_fifo_entry(struct fusb300 *fusb300, | ||
76 | u32 ep) | ||
77 | { | ||
78 | u32 val = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); | ||
79 | |||
80 | val &= ~FUSB300_EPSET1_FIFOENTRY_MSK; | ||
81 | val |= FUSB300_EPSET1_FIFOENTRY(FUSB300_FIFO_ENTRY_NUM); | ||
82 | iowrite32(val, fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); | ||
83 | } | ||
84 | |||
85 | static void fusb300_set_start_entry(struct fusb300 *fusb300, | ||
86 | u8 ep) | ||
87 | { | ||
88 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); | ||
89 | u32 start_entry = fusb300->fifo_entry_num * FUSB300_FIFO_ENTRY_NUM; | ||
90 | |||
91 | reg &= ~FUSB300_EPSET1_START_ENTRY_MSK ; | ||
92 | reg |= FUSB300_EPSET1_START_ENTRY(start_entry); | ||
93 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); | ||
94 | if (fusb300->fifo_entry_num == FUSB300_MAX_FIFO_ENTRY) { | ||
95 | fusb300->fifo_entry_num = 0; | ||
96 | fusb300->addrofs = 0; | ||
97 | pr_err("fifo entry is over the maximum number!\n"); | ||
98 | } else | ||
99 | fusb300->fifo_entry_num++; | ||
100 | } | ||
101 | |||
102 | /* set fusb300_set_start_entry first before fusb300_set_epaddrofs */ | ||
103 | static void fusb300_set_epaddrofs(struct fusb300 *fusb300, | ||
104 | struct fusb300_ep_info info) | ||
105 | { | ||
106 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET2(info.epnum)); | ||
107 | |||
108 | reg &= ~FUSB300_EPSET2_ADDROFS_MSK; | ||
109 | reg |= FUSB300_EPSET2_ADDROFS(fusb300->addrofs); | ||
110 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET2(info.epnum)); | ||
111 | fusb300->addrofs += (info.maxpacket + 7) / 8 * FUSB300_FIFO_ENTRY_NUM; | ||
112 | } | ||
113 | |||
114 | static void ep_fifo_setting(struct fusb300 *fusb300, | ||
115 | struct fusb300_ep_info info) | ||
116 | { | ||
117 | fusb300_set_fifo_entry(fusb300, info.epnum); | ||
118 | fusb300_set_start_entry(fusb300, info.epnum); | ||
119 | fusb300_set_epaddrofs(fusb300, info); | ||
120 | } | ||
121 | |||
122 | static void fusb300_set_eptype(struct fusb300 *fusb300, | ||
123 | struct fusb300_ep_info info) | ||
124 | { | ||
125 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); | ||
126 | |||
127 | reg &= ~FUSB300_EPSET1_TYPE_MSK; | ||
128 | reg |= FUSB300_EPSET1_TYPE(info.type); | ||
129 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); | ||
130 | } | ||
131 | |||
132 | static void fusb300_set_epdir(struct fusb300 *fusb300, | ||
133 | struct fusb300_ep_info info) | ||
134 | { | ||
135 | u32 reg; | ||
136 | |||
137 | if (!info.dir_in) | ||
138 | return; | ||
139 | reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); | ||
140 | reg &= ~FUSB300_EPSET1_DIR_MSK; | ||
141 | reg |= FUSB300_EPSET1_DIRIN; | ||
142 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); | ||
143 | } | ||
144 | |||
145 | static void fusb300_set_ep_active(struct fusb300 *fusb300, | ||
146 | u8 ep) | ||
147 | { | ||
148 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); | ||
149 | |||
150 | reg |= FUSB300_EPSET1_ACTEN; | ||
151 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(ep)); | ||
152 | } | ||
153 | |||
154 | static void fusb300_set_epmps(struct fusb300 *fusb300, | ||
155 | struct fusb300_ep_info info) | ||
156 | { | ||
157 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET2(info.epnum)); | ||
158 | |||
159 | reg &= ~FUSB300_EPSET2_MPS_MSK; | ||
160 | reg |= FUSB300_EPSET2_MPS(info.maxpacket); | ||
161 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET2(info.epnum)); | ||
162 | } | ||
163 | |||
164 | static void fusb300_set_interval(struct fusb300 *fusb300, | ||
165 | struct fusb300_ep_info info) | ||
166 | { | ||
167 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); | ||
168 | |||
169 | reg &= ~FUSB300_EPSET1_INTERVAL(0x7); | ||
170 | reg |= FUSB300_EPSET1_INTERVAL(info.interval); | ||
171 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); | ||
172 | } | ||
173 | |||
174 | static void fusb300_set_bwnum(struct fusb300 *fusb300, | ||
175 | struct fusb300_ep_info info) | ||
176 | { | ||
177 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); | ||
178 | |||
179 | reg &= ~FUSB300_EPSET1_BWNUM(0x3); | ||
180 | reg |= FUSB300_EPSET1_BWNUM(info.bw_num); | ||
181 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET1(info.epnum)); | ||
182 | } | ||
183 | |||
184 | static void set_ep_reg(struct fusb300 *fusb300, | ||
185 | struct fusb300_ep_info info) | ||
186 | { | ||
187 | fusb300_set_eptype(fusb300, info); | ||
188 | fusb300_set_epdir(fusb300, info); | ||
189 | fusb300_set_epmps(fusb300, info); | ||
190 | |||
191 | if (info.interval) | ||
192 | fusb300_set_interval(fusb300, info); | ||
193 | |||
194 | if (info.bw_num) | ||
195 | fusb300_set_bwnum(fusb300, info); | ||
196 | |||
197 | fusb300_set_ep_active(fusb300, info.epnum); | ||
198 | } | ||
199 | |||
200 | static int config_ep(struct fusb300_ep *ep, | ||
201 | const struct usb_endpoint_descriptor *desc) | ||
202 | { | ||
203 | struct fusb300 *fusb300 = ep->fusb300; | ||
204 | struct fusb300_ep_info info; | ||
205 | |||
206 | ep->ep.desc = desc; | ||
207 | |||
208 | info.interval = 0; | ||
209 | info.addrofs = 0; | ||
210 | info.bw_num = 0; | ||
211 | |||
212 | info.type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | ||
213 | info.dir_in = (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? 1 : 0; | ||
214 | info.maxpacket = usb_endpoint_maxp(desc); | ||
215 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | ||
216 | |||
217 | if ((info.type == USB_ENDPOINT_XFER_INT) || | ||
218 | (info.type == USB_ENDPOINT_XFER_ISOC)) { | ||
219 | info.interval = desc->bInterval; | ||
220 | if (info.type == USB_ENDPOINT_XFER_ISOC) | ||
221 | info.bw_num = ((desc->wMaxPacketSize & 0x1800) >> 11); | ||
222 | } | ||
223 | |||
224 | ep_fifo_setting(fusb300, info); | ||
225 | |||
226 | set_ep_reg(fusb300, info); | ||
227 | |||
228 | fusb300_ep_setting(ep, info); | ||
229 | |||
230 | fusb300->ep[info.epnum] = ep; | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static int fusb300_enable(struct usb_ep *_ep, | ||
236 | const struct usb_endpoint_descriptor *desc) | ||
237 | { | ||
238 | struct fusb300_ep *ep; | ||
239 | |||
240 | ep = container_of(_ep, struct fusb300_ep, ep); | ||
241 | |||
242 | if (ep->fusb300->reenum) { | ||
243 | ep->fusb300->fifo_entry_num = 0; | ||
244 | ep->fusb300->addrofs = 0; | ||
245 | ep->fusb300->reenum = 0; | ||
246 | } | ||
247 | |||
248 | return config_ep(ep, desc); | ||
249 | } | ||
250 | |||
251 | static int fusb300_disable(struct usb_ep *_ep) | ||
252 | { | ||
253 | struct fusb300_ep *ep; | ||
254 | struct fusb300_request *req; | ||
255 | unsigned long flags; | ||
256 | |||
257 | ep = container_of(_ep, struct fusb300_ep, ep); | ||
258 | |||
259 | BUG_ON(!ep); | ||
260 | |||
261 | while (!list_empty(&ep->queue)) { | ||
262 | req = list_entry(ep->queue.next, struct fusb300_request, queue); | ||
263 | spin_lock_irqsave(&ep->fusb300->lock, flags); | ||
264 | done(ep, req, -ECONNRESET); | ||
265 | spin_unlock_irqrestore(&ep->fusb300->lock, flags); | ||
266 | } | ||
267 | |||
268 | return fusb300_ep_release(ep); | ||
269 | } | ||
270 | |||
271 | static struct usb_request *fusb300_alloc_request(struct usb_ep *_ep, | ||
272 | gfp_t gfp_flags) | ||
273 | { | ||
274 | struct fusb300_request *req; | ||
275 | |||
276 | req = kzalloc(sizeof(struct fusb300_request), gfp_flags); | ||
277 | if (!req) | ||
278 | return NULL; | ||
279 | INIT_LIST_HEAD(&req->queue); | ||
280 | |||
281 | return &req->req; | ||
282 | } | ||
283 | |||
284 | static void fusb300_free_request(struct usb_ep *_ep, struct usb_request *_req) | ||
285 | { | ||
286 | struct fusb300_request *req; | ||
287 | |||
288 | req = container_of(_req, struct fusb300_request, req); | ||
289 | kfree(req); | ||
290 | } | ||
291 | |||
292 | static int enable_fifo_int(struct fusb300_ep *ep) | ||
293 | { | ||
294 | struct fusb300 *fusb300 = ep->fusb300; | ||
295 | |||
296 | if (ep->epnum) { | ||
297 | fusb300_enable_bit(fusb300, FUSB300_OFFSET_IGER0, | ||
298 | FUSB300_IGER0_EEPn_FIFO_INT(ep->epnum)); | ||
299 | } else { | ||
300 | pr_err("can't enable_fifo_int ep0\n"); | ||
301 | return -EINVAL; | ||
302 | } | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static int disable_fifo_int(struct fusb300_ep *ep) | ||
308 | { | ||
309 | struct fusb300 *fusb300 = ep->fusb300; | ||
310 | |||
311 | if (ep->epnum) { | ||
312 | fusb300_disable_bit(fusb300, FUSB300_OFFSET_IGER0, | ||
313 | FUSB300_IGER0_EEPn_FIFO_INT(ep->epnum)); | ||
314 | } else { | ||
315 | pr_err("can't disable_fifo_int ep0\n"); | ||
316 | return -EINVAL; | ||
317 | } | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static void fusb300_set_cxlen(struct fusb300 *fusb300, u32 length) | ||
323 | { | ||
324 | u32 reg; | ||
325 | |||
326 | reg = ioread32(fusb300->reg + FUSB300_OFFSET_CSR); | ||
327 | reg &= ~FUSB300_CSR_LEN_MSK; | ||
328 | reg |= FUSB300_CSR_LEN(length); | ||
329 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_CSR); | ||
330 | } | ||
331 | |||
332 | /* write data to cx fifo */ | ||
333 | static void fusb300_wrcxf(struct fusb300_ep *ep, | ||
334 | struct fusb300_request *req) | ||
335 | { | ||
336 | int i = 0; | ||
337 | u8 *tmp; | ||
338 | u32 data; | ||
339 | struct fusb300 *fusb300 = ep->fusb300; | ||
340 | u32 length = req->req.length - req->req.actual; | ||
341 | |||
342 | tmp = req->req.buf + req->req.actual; | ||
343 | |||
344 | if (length > SS_CTL_MAX_PACKET_SIZE) { | ||
345 | fusb300_set_cxlen(fusb300, SS_CTL_MAX_PACKET_SIZE); | ||
346 | for (i = (SS_CTL_MAX_PACKET_SIZE >> 2); i > 0; i--) { | ||
347 | data = *tmp | *(tmp + 1) << 8 | *(tmp + 2) << 16 | | ||
348 | *(tmp + 3) << 24; | ||
349 | iowrite32(data, fusb300->reg + FUSB300_OFFSET_CXPORT); | ||
350 | tmp += 4; | ||
351 | } | ||
352 | req->req.actual += SS_CTL_MAX_PACKET_SIZE; | ||
353 | } else { /* length is less than max packet size */ | ||
354 | fusb300_set_cxlen(fusb300, length); | ||
355 | for (i = length >> 2; i > 0; i--) { | ||
356 | data = *tmp | *(tmp + 1) << 8 | *(tmp + 2) << 16 | | ||
357 | *(tmp + 3) << 24; | ||
358 | printk(KERN_DEBUG " 0x%x\n", data); | ||
359 | iowrite32(data, fusb300->reg + FUSB300_OFFSET_CXPORT); | ||
360 | tmp = tmp + 4; | ||
361 | } | ||
362 | switch (length % 4) { | ||
363 | case 1: | ||
364 | data = *tmp; | ||
365 | printk(KERN_DEBUG " 0x%x\n", data); | ||
366 | iowrite32(data, fusb300->reg + FUSB300_OFFSET_CXPORT); | ||
367 | break; | ||
368 | case 2: | ||
369 | data = *tmp | *(tmp + 1) << 8; | ||
370 | printk(KERN_DEBUG " 0x%x\n", data); | ||
371 | iowrite32(data, fusb300->reg + FUSB300_OFFSET_CXPORT); | ||
372 | break; | ||
373 | case 3: | ||
374 | data = *tmp | *(tmp + 1) << 8 | *(tmp + 2) << 16; | ||
375 | printk(KERN_DEBUG " 0x%x\n", data); | ||
376 | iowrite32(data, fusb300->reg + FUSB300_OFFSET_CXPORT); | ||
377 | break; | ||
378 | default: | ||
379 | break; | ||
380 | } | ||
381 | req->req.actual += length; | ||
382 | } | ||
383 | } | ||
384 | |||
385 | static void fusb300_set_epnstall(struct fusb300 *fusb300, u8 ep) | ||
386 | { | ||
387 | fusb300_enable_bit(fusb300, FUSB300_OFFSET_EPSET0(ep), | ||
388 | FUSB300_EPSET0_STL); | ||
389 | } | ||
390 | |||
391 | static void fusb300_clear_epnstall(struct fusb300 *fusb300, u8 ep) | ||
392 | { | ||
393 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET0(ep)); | ||
394 | |||
395 | if (reg & FUSB300_EPSET0_STL) { | ||
396 | printk(KERN_DEBUG "EP%d stall... Clear!!\n", ep); | ||
397 | reg |= FUSB300_EPSET0_STL_CLR; | ||
398 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_EPSET0(ep)); | ||
399 | } | ||
400 | } | ||
401 | |||
402 | static void ep0_queue(struct fusb300_ep *ep, struct fusb300_request *req) | ||
403 | { | ||
404 | if (ep->fusb300->ep0_dir) { /* if IN */ | ||
405 | if (req->req.length) { | ||
406 | fusb300_wrcxf(ep, req); | ||
407 | } else | ||
408 | printk(KERN_DEBUG "%s : req->req.length = 0x%x\n", | ||
409 | __func__, req->req.length); | ||
410 | if ((req->req.length == req->req.actual) || | ||
411 | (req->req.actual < ep->ep.maxpacket)) | ||
412 | done(ep, req, 0); | ||
413 | } else { /* OUT */ | ||
414 | if (!req->req.length) | ||
415 | done(ep, req, 0); | ||
416 | else | ||
417 | fusb300_enable_bit(ep->fusb300, FUSB300_OFFSET_IGER1, | ||
418 | FUSB300_IGER1_CX_OUT_INT); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | static int fusb300_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
423 | gfp_t gfp_flags) | ||
424 | { | ||
425 | struct fusb300_ep *ep; | ||
426 | struct fusb300_request *req; | ||
427 | unsigned long flags; | ||
428 | int request = 0; | ||
429 | |||
430 | ep = container_of(_ep, struct fusb300_ep, ep); | ||
431 | req = container_of(_req, struct fusb300_request, req); | ||
432 | |||
433 | if (ep->fusb300->gadget.speed == USB_SPEED_UNKNOWN) | ||
434 | return -ESHUTDOWN; | ||
435 | |||
436 | spin_lock_irqsave(&ep->fusb300->lock, flags); | ||
437 | |||
438 | if (list_empty(&ep->queue)) | ||
439 | request = 1; | ||
440 | |||
441 | list_add_tail(&req->queue, &ep->queue); | ||
442 | |||
443 | req->req.actual = 0; | ||
444 | req->req.status = -EINPROGRESS; | ||
445 | |||
446 | if (ep->ep.desc == NULL) /* ep0 */ | ||
447 | ep0_queue(ep, req); | ||
448 | else if (request && !ep->stall) | ||
449 | enable_fifo_int(ep); | ||
450 | |||
451 | spin_unlock_irqrestore(&ep->fusb300->lock, flags); | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int fusb300_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
457 | { | ||
458 | struct fusb300_ep *ep; | ||
459 | struct fusb300_request *req; | ||
460 | unsigned long flags; | ||
461 | |||
462 | ep = container_of(_ep, struct fusb300_ep, ep); | ||
463 | req = container_of(_req, struct fusb300_request, req); | ||
464 | |||
465 | spin_lock_irqsave(&ep->fusb300->lock, flags); | ||
466 | if (!list_empty(&ep->queue)) | ||
467 | done(ep, req, -ECONNRESET); | ||
468 | spin_unlock_irqrestore(&ep->fusb300->lock, flags); | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static int fusb300_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedge) | ||
474 | { | ||
475 | struct fusb300_ep *ep; | ||
476 | struct fusb300 *fusb300; | ||
477 | unsigned long flags; | ||
478 | int ret = 0; | ||
479 | |||
480 | ep = container_of(_ep, struct fusb300_ep, ep); | ||
481 | |||
482 | fusb300 = ep->fusb300; | ||
483 | |||
484 | spin_lock_irqsave(&ep->fusb300->lock, flags); | ||
485 | |||
486 | if (!list_empty(&ep->queue)) { | ||
487 | ret = -EAGAIN; | ||
488 | goto out; | ||
489 | } | ||
490 | |||
491 | if (value) { | ||
492 | fusb300_set_epnstall(fusb300, ep->epnum); | ||
493 | ep->stall = 1; | ||
494 | if (wedge) | ||
495 | ep->wedged = 1; | ||
496 | } else { | ||
497 | fusb300_clear_epnstall(fusb300, ep->epnum); | ||
498 | ep->stall = 0; | ||
499 | ep->wedged = 0; | ||
500 | } | ||
501 | |||
502 | out: | ||
503 | spin_unlock_irqrestore(&ep->fusb300->lock, flags); | ||
504 | return ret; | ||
505 | } | ||
506 | |||
507 | static int fusb300_set_halt(struct usb_ep *_ep, int value) | ||
508 | { | ||
509 | return fusb300_set_halt_and_wedge(_ep, value, 0); | ||
510 | } | ||
511 | |||
512 | static int fusb300_set_wedge(struct usb_ep *_ep) | ||
513 | { | ||
514 | return fusb300_set_halt_and_wedge(_ep, 1, 1); | ||
515 | } | ||
516 | |||
517 | static void fusb300_fifo_flush(struct usb_ep *_ep) | ||
518 | { | ||
519 | } | ||
520 | |||
521 | static struct usb_ep_ops fusb300_ep_ops = { | ||
522 | .enable = fusb300_enable, | ||
523 | .disable = fusb300_disable, | ||
524 | |||
525 | .alloc_request = fusb300_alloc_request, | ||
526 | .free_request = fusb300_free_request, | ||
527 | |||
528 | .queue = fusb300_queue, | ||
529 | .dequeue = fusb300_dequeue, | ||
530 | |||
531 | .set_halt = fusb300_set_halt, | ||
532 | .fifo_flush = fusb300_fifo_flush, | ||
533 | .set_wedge = fusb300_set_wedge, | ||
534 | }; | ||
535 | |||
536 | /*****************************************************************************/ | ||
537 | static void fusb300_clear_int(struct fusb300 *fusb300, u32 offset, | ||
538 | u32 value) | ||
539 | { | ||
540 | iowrite32(value, fusb300->reg + offset); | ||
541 | } | ||
542 | |||
543 | static void fusb300_reset(void) | ||
544 | { | ||
545 | } | ||
546 | |||
547 | static void fusb300_set_cxstall(struct fusb300 *fusb300) | ||
548 | { | ||
549 | fusb300_enable_bit(fusb300, FUSB300_OFFSET_CSR, | ||
550 | FUSB300_CSR_STL); | ||
551 | } | ||
552 | |||
553 | static void fusb300_set_cxdone(struct fusb300 *fusb300) | ||
554 | { | ||
555 | fusb300_enable_bit(fusb300, FUSB300_OFFSET_CSR, | ||
556 | FUSB300_CSR_DONE); | ||
557 | } | ||
558 | |||
559 | /* read data from cx fifo */ | ||
560 | static void fusb300_rdcxf(struct fusb300 *fusb300, | ||
561 | u8 *buffer, u32 length) | ||
562 | { | ||
563 | int i = 0; | ||
564 | u8 *tmp; | ||
565 | u32 data; | ||
566 | |||
567 | tmp = buffer; | ||
568 | |||
569 | for (i = (length >> 2); i > 0; i--) { | ||
570 | data = ioread32(fusb300->reg + FUSB300_OFFSET_CXPORT); | ||
571 | printk(KERN_DEBUG " 0x%x\n", data); | ||
572 | *tmp = data & 0xFF; | ||
573 | *(tmp + 1) = (data >> 8) & 0xFF; | ||
574 | *(tmp + 2) = (data >> 16) & 0xFF; | ||
575 | *(tmp + 3) = (data >> 24) & 0xFF; | ||
576 | tmp = tmp + 4; | ||
577 | } | ||
578 | |||
579 | switch (length % 4) { | ||
580 | case 1: | ||
581 | data = ioread32(fusb300->reg + FUSB300_OFFSET_CXPORT); | ||
582 | printk(KERN_DEBUG " 0x%x\n", data); | ||
583 | *tmp = data & 0xFF; | ||
584 | break; | ||
585 | case 2: | ||
586 | data = ioread32(fusb300->reg + FUSB300_OFFSET_CXPORT); | ||
587 | printk(KERN_DEBUG " 0x%x\n", data); | ||
588 | *tmp = data & 0xFF; | ||
589 | *(tmp + 1) = (data >> 8) & 0xFF; | ||
590 | break; | ||
591 | case 3: | ||
592 | data = ioread32(fusb300->reg + FUSB300_OFFSET_CXPORT); | ||
593 | printk(KERN_DEBUG " 0x%x\n", data); | ||
594 | *tmp = data & 0xFF; | ||
595 | *(tmp + 1) = (data >> 8) & 0xFF; | ||
596 | *(tmp + 2) = (data >> 16) & 0xFF; | ||
597 | break; | ||
598 | default: | ||
599 | break; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | static void fusb300_rdfifo(struct fusb300_ep *ep, | ||
604 | struct fusb300_request *req, | ||
605 | u32 length) | ||
606 | { | ||
607 | int i = 0; | ||
608 | u8 *tmp; | ||
609 | u32 data, reg; | ||
610 | struct fusb300 *fusb300 = ep->fusb300; | ||
611 | |||
612 | tmp = req->req.buf + req->req.actual; | ||
613 | req->req.actual += length; | ||
614 | |||
615 | if (req->req.actual > req->req.length) | ||
616 | printk(KERN_DEBUG "req->req.actual > req->req.length\n"); | ||
617 | |||
618 | for (i = (length >> 2); i > 0; i--) { | ||
619 | data = ioread32(fusb300->reg + | ||
620 | FUSB300_OFFSET_EPPORT(ep->epnum)); | ||
621 | *tmp = data & 0xFF; | ||
622 | *(tmp + 1) = (data >> 8) & 0xFF; | ||
623 | *(tmp + 2) = (data >> 16) & 0xFF; | ||
624 | *(tmp + 3) = (data >> 24) & 0xFF; | ||
625 | tmp = tmp + 4; | ||
626 | } | ||
627 | |||
628 | switch (length % 4) { | ||
629 | case 1: | ||
630 | data = ioread32(fusb300->reg + | ||
631 | FUSB300_OFFSET_EPPORT(ep->epnum)); | ||
632 | *tmp = data & 0xFF; | ||
633 | break; | ||
634 | case 2: | ||
635 | data = ioread32(fusb300->reg + | ||
636 | FUSB300_OFFSET_EPPORT(ep->epnum)); | ||
637 | *tmp = data & 0xFF; | ||
638 | *(tmp + 1) = (data >> 8) & 0xFF; | ||
639 | break; | ||
640 | case 3: | ||
641 | data = ioread32(fusb300->reg + | ||
642 | FUSB300_OFFSET_EPPORT(ep->epnum)); | ||
643 | *tmp = data & 0xFF; | ||
644 | *(tmp + 1) = (data >> 8) & 0xFF; | ||
645 | *(tmp + 2) = (data >> 16) & 0xFF; | ||
646 | break; | ||
647 | default: | ||
648 | break; | ||
649 | } | ||
650 | |||
651 | do { | ||
652 | reg = ioread32(fusb300->reg + FUSB300_OFFSET_IGR1); | ||
653 | reg &= FUSB300_IGR1_SYNF0_EMPTY_INT; | ||
654 | if (i) | ||
655 | printk(KERN_INFO "sync fifo is not empty!\n"); | ||
656 | i++; | ||
657 | } while (!reg); | ||
658 | } | ||
659 | |||
660 | static u8 fusb300_get_epnstall(struct fusb300 *fusb300, u8 ep) | ||
661 | { | ||
662 | u8 value; | ||
663 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPSET0(ep)); | ||
664 | |||
665 | value = reg & FUSB300_EPSET0_STL; | ||
666 | |||
667 | return value; | ||
668 | } | ||
669 | |||
670 | static u8 fusb300_get_cxstall(struct fusb300 *fusb300) | ||
671 | { | ||
672 | u8 value; | ||
673 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_CSR); | ||
674 | |||
675 | value = (reg & FUSB300_CSR_STL) >> 1; | ||
676 | |||
677 | return value; | ||
678 | } | ||
679 | |||
680 | static void request_error(struct fusb300 *fusb300) | ||
681 | { | ||
682 | fusb300_set_cxstall(fusb300); | ||
683 | printk(KERN_DEBUG "request error!!\n"); | ||
684 | } | ||
685 | |||
686 | static void get_status(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) | ||
687 | __releases(fusb300->lock) | ||
688 | __acquires(fusb300->lock) | ||
689 | { | ||
690 | u8 ep; | ||
691 | u16 status = 0; | ||
692 | u16 w_index = ctrl->wIndex; | ||
693 | |||
694 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||
695 | case USB_RECIP_DEVICE: | ||
696 | status = 1 << USB_DEVICE_SELF_POWERED; | ||
697 | break; | ||
698 | case USB_RECIP_INTERFACE: | ||
699 | status = 0; | ||
700 | break; | ||
701 | case USB_RECIP_ENDPOINT: | ||
702 | ep = w_index & USB_ENDPOINT_NUMBER_MASK; | ||
703 | if (ep) { | ||
704 | if (fusb300_get_epnstall(fusb300, ep)) | ||
705 | status = 1 << USB_ENDPOINT_HALT; | ||
706 | } else { | ||
707 | if (fusb300_get_cxstall(fusb300)) | ||
708 | status = 0; | ||
709 | } | ||
710 | break; | ||
711 | |||
712 | default: | ||
713 | request_error(fusb300); | ||
714 | return; /* exit */ | ||
715 | } | ||
716 | |||
717 | fusb300->ep0_data = cpu_to_le16(status); | ||
718 | fusb300->ep0_req->buf = &fusb300->ep0_data; | ||
719 | fusb300->ep0_req->length = 2; | ||
720 | |||
721 | spin_unlock(&fusb300->lock); | ||
722 | fusb300_queue(fusb300->gadget.ep0, fusb300->ep0_req, GFP_KERNEL); | ||
723 | spin_lock(&fusb300->lock); | ||
724 | } | ||
725 | |||
726 | static void set_feature(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) | ||
727 | { | ||
728 | u8 ep; | ||
729 | |||
730 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||
731 | case USB_RECIP_DEVICE: | ||
732 | fusb300_set_cxdone(fusb300); | ||
733 | break; | ||
734 | case USB_RECIP_INTERFACE: | ||
735 | fusb300_set_cxdone(fusb300); | ||
736 | break; | ||
737 | case USB_RECIP_ENDPOINT: { | ||
738 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
739 | |||
740 | ep = w_index & USB_ENDPOINT_NUMBER_MASK; | ||
741 | if (ep) | ||
742 | fusb300_set_epnstall(fusb300, ep); | ||
743 | else | ||
744 | fusb300_set_cxstall(fusb300); | ||
745 | fusb300_set_cxdone(fusb300); | ||
746 | } | ||
747 | break; | ||
748 | default: | ||
749 | request_error(fusb300); | ||
750 | break; | ||
751 | } | ||
752 | } | ||
753 | |||
754 | static void fusb300_clear_seqnum(struct fusb300 *fusb300, u8 ep) | ||
755 | { | ||
756 | fusb300_enable_bit(fusb300, FUSB300_OFFSET_EPSET0(ep), | ||
757 | FUSB300_EPSET0_CLRSEQNUM); | ||
758 | } | ||
759 | |||
760 | static void clear_feature(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) | ||
761 | { | ||
762 | struct fusb300_ep *ep = | ||
763 | fusb300->ep[ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK]; | ||
764 | |||
765 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | ||
766 | case USB_RECIP_DEVICE: | ||
767 | fusb300_set_cxdone(fusb300); | ||
768 | break; | ||
769 | case USB_RECIP_INTERFACE: | ||
770 | fusb300_set_cxdone(fusb300); | ||
771 | break; | ||
772 | case USB_RECIP_ENDPOINT: | ||
773 | if (ctrl->wIndex & USB_ENDPOINT_NUMBER_MASK) { | ||
774 | if (ep->wedged) { | ||
775 | fusb300_set_cxdone(fusb300); | ||
776 | break; | ||
777 | } | ||
778 | if (ep->stall) { | ||
779 | ep->stall = 0; | ||
780 | fusb300_clear_seqnum(fusb300, ep->epnum); | ||
781 | fusb300_clear_epnstall(fusb300, ep->epnum); | ||
782 | if (!list_empty(&ep->queue)) | ||
783 | enable_fifo_int(ep); | ||
784 | } | ||
785 | } | ||
786 | fusb300_set_cxdone(fusb300); | ||
787 | break; | ||
788 | default: | ||
789 | request_error(fusb300); | ||
790 | break; | ||
791 | } | ||
792 | } | ||
793 | |||
794 | static void fusb300_set_dev_addr(struct fusb300 *fusb300, u16 addr) | ||
795 | { | ||
796 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_DAR); | ||
797 | |||
798 | reg &= ~FUSB300_DAR_DRVADDR_MSK; | ||
799 | reg |= FUSB300_DAR_DRVADDR(addr); | ||
800 | |||
801 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_DAR); | ||
802 | } | ||
803 | |||
804 | static void set_address(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) | ||
805 | { | ||
806 | if (ctrl->wValue >= 0x0100) | ||
807 | request_error(fusb300); | ||
808 | else { | ||
809 | fusb300_set_dev_addr(fusb300, ctrl->wValue); | ||
810 | fusb300_set_cxdone(fusb300); | ||
811 | } | ||
812 | } | ||
813 | |||
814 | #define UVC_COPY_DESCRIPTORS(mem, src) \ | ||
815 | do { \ | ||
816 | const struct usb_descriptor_header * const *__src; \ | ||
817 | for (__src = src; *__src; ++__src) { \ | ||
818 | memcpy(mem, *__src, (*__src)->bLength); \ | ||
819 | mem += (*__src)->bLength; \ | ||
820 | } \ | ||
821 | } while (0) | ||
822 | |||
823 | static int setup_packet(struct fusb300 *fusb300, struct usb_ctrlrequest *ctrl) | ||
824 | { | ||
825 | u8 *p = (u8 *)ctrl; | ||
826 | u8 ret = 0; | ||
827 | u8 i = 0; | ||
828 | |||
829 | fusb300_rdcxf(fusb300, p, 8); | ||
830 | fusb300->ep0_dir = ctrl->bRequestType & USB_DIR_IN; | ||
831 | fusb300->ep0_length = ctrl->wLength; | ||
832 | |||
833 | /* check request */ | ||
834 | if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | ||
835 | switch (ctrl->bRequest) { | ||
836 | case USB_REQ_GET_STATUS: | ||
837 | get_status(fusb300, ctrl); | ||
838 | break; | ||
839 | case USB_REQ_CLEAR_FEATURE: | ||
840 | clear_feature(fusb300, ctrl); | ||
841 | break; | ||
842 | case USB_REQ_SET_FEATURE: | ||
843 | set_feature(fusb300, ctrl); | ||
844 | break; | ||
845 | case USB_REQ_SET_ADDRESS: | ||
846 | set_address(fusb300, ctrl); | ||
847 | break; | ||
848 | case USB_REQ_SET_CONFIGURATION: | ||
849 | fusb300_enable_bit(fusb300, FUSB300_OFFSET_DAR, | ||
850 | FUSB300_DAR_SETCONFG); | ||
851 | /* clear sequence number */ | ||
852 | for (i = 1; i <= FUSB300_MAX_NUM_EP; i++) | ||
853 | fusb300_clear_seqnum(fusb300, i); | ||
854 | fusb300->reenum = 1; | ||
855 | ret = 1; | ||
856 | break; | ||
857 | default: | ||
858 | ret = 1; | ||
859 | break; | ||
860 | } | ||
861 | } else | ||
862 | ret = 1; | ||
863 | |||
864 | return ret; | ||
865 | } | ||
866 | |||
867 | static void done(struct fusb300_ep *ep, struct fusb300_request *req, | ||
868 | int status) | ||
869 | { | ||
870 | list_del_init(&req->queue); | ||
871 | |||
872 | /* don't modify queue heads during completion callback */ | ||
873 | if (ep->fusb300->gadget.speed == USB_SPEED_UNKNOWN) | ||
874 | req->req.status = -ESHUTDOWN; | ||
875 | else | ||
876 | req->req.status = status; | ||
877 | |||
878 | spin_unlock(&ep->fusb300->lock); | ||
879 | req->req.complete(&ep->ep, &req->req); | ||
880 | spin_lock(&ep->fusb300->lock); | ||
881 | |||
882 | if (ep->epnum) { | ||
883 | disable_fifo_int(ep); | ||
884 | if (!list_empty(&ep->queue)) | ||
885 | enable_fifo_int(ep); | ||
886 | } else | ||
887 | fusb300_set_cxdone(ep->fusb300); | ||
888 | } | ||
889 | |||
890 | static void fusb300_fill_idma_prdtbl(struct fusb300_ep *ep, dma_addr_t d, | ||
891 | u32 len) | ||
892 | { | ||
893 | u32 value; | ||
894 | u32 reg; | ||
895 | |||
896 | /* wait SW owner */ | ||
897 | do { | ||
898 | reg = ioread32(ep->fusb300->reg + | ||
899 | FUSB300_OFFSET_EPPRD_W0(ep->epnum)); | ||
900 | reg &= FUSB300_EPPRD0_H; | ||
901 | } while (reg); | ||
902 | |||
903 | iowrite32(d, ep->fusb300->reg + FUSB300_OFFSET_EPPRD_W1(ep->epnum)); | ||
904 | |||
905 | value = FUSB300_EPPRD0_BTC(len) | FUSB300_EPPRD0_H | | ||
906 | FUSB300_EPPRD0_F | FUSB300_EPPRD0_L | FUSB300_EPPRD0_I; | ||
907 | iowrite32(value, ep->fusb300->reg + FUSB300_OFFSET_EPPRD_W0(ep->epnum)); | ||
908 | |||
909 | iowrite32(0x0, ep->fusb300->reg + FUSB300_OFFSET_EPPRD_W2(ep->epnum)); | ||
910 | |||
911 | fusb300_enable_bit(ep->fusb300, FUSB300_OFFSET_EPPRDRDY, | ||
912 | FUSB300_EPPRDR_EP_PRD_RDY(ep->epnum)); | ||
913 | } | ||
914 | |||
915 | static void fusb300_wait_idma_finished(struct fusb300_ep *ep) | ||
916 | { | ||
917 | u32 reg; | ||
918 | |||
919 | do { | ||
920 | reg = ioread32(ep->fusb300->reg + FUSB300_OFFSET_IGR1); | ||
921 | if ((reg & FUSB300_IGR1_VBUS_CHG_INT) || | ||
922 | (reg & FUSB300_IGR1_WARM_RST_INT) || | ||
923 | (reg & FUSB300_IGR1_HOT_RST_INT) || | ||
924 | (reg & FUSB300_IGR1_USBRST_INT) | ||
925 | ) | ||
926 | goto IDMA_RESET; | ||
927 | reg = ioread32(ep->fusb300->reg + FUSB300_OFFSET_IGR0); | ||
928 | reg &= FUSB300_IGR0_EPn_PRD_INT(ep->epnum); | ||
929 | } while (!reg); | ||
930 | |||
931 | fusb300_clear_int(ep->fusb300, FUSB300_OFFSET_IGR0, | ||
932 | FUSB300_IGR0_EPn_PRD_INT(ep->epnum)); | ||
933 | return; | ||
934 | |||
935 | IDMA_RESET: | ||
936 | reg = ioread32(ep->fusb300->reg + FUSB300_OFFSET_IGER0); | ||
937 | reg &= ~FUSB300_IGER0_EEPn_PRD_INT(ep->epnum); | ||
938 | iowrite32(reg, ep->fusb300->reg + FUSB300_OFFSET_IGER0); | ||
939 | } | ||
940 | |||
941 | static void fusb300_set_idma(struct fusb300_ep *ep, | ||
942 | struct fusb300_request *req) | ||
943 | { | ||
944 | int ret; | ||
945 | |||
946 | ret = usb_gadget_map_request(&ep->fusb300->gadget, | ||
947 | &req->req, DMA_TO_DEVICE); | ||
948 | if (ret) | ||
949 | return; | ||
950 | |||
951 | fusb300_enable_bit(ep->fusb300, FUSB300_OFFSET_IGER0, | ||
952 | FUSB300_IGER0_EEPn_PRD_INT(ep->epnum)); | ||
953 | |||
954 | fusb300_fill_idma_prdtbl(ep, req->req.dma, req->req.length); | ||
955 | /* check idma is done */ | ||
956 | fusb300_wait_idma_finished(ep); | ||
957 | |||
958 | usb_gadget_unmap_request(&ep->fusb300->gadget, | ||
959 | &req->req, DMA_TO_DEVICE); | ||
960 | } | ||
961 | |||
962 | static void in_ep_fifo_handler(struct fusb300_ep *ep) | ||
963 | { | ||
964 | struct fusb300_request *req = list_entry(ep->queue.next, | ||
965 | struct fusb300_request, queue); | ||
966 | |||
967 | if (req->req.length) | ||
968 | fusb300_set_idma(ep, req); | ||
969 | done(ep, req, 0); | ||
970 | } | ||
971 | |||
972 | static void out_ep_fifo_handler(struct fusb300_ep *ep) | ||
973 | { | ||
974 | struct fusb300 *fusb300 = ep->fusb300; | ||
975 | struct fusb300_request *req = list_entry(ep->queue.next, | ||
976 | struct fusb300_request, queue); | ||
977 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_EPFFR(ep->epnum)); | ||
978 | u32 length = reg & FUSB300_FFR_BYCNT; | ||
979 | |||
980 | fusb300_rdfifo(ep, req, length); | ||
981 | |||
982 | /* finish out transfer */ | ||
983 | if ((req->req.length == req->req.actual) || (length < ep->ep.maxpacket)) | ||
984 | done(ep, req, 0); | ||
985 | } | ||
986 | |||
987 | static void check_device_mode(struct fusb300 *fusb300) | ||
988 | { | ||
989 | u32 reg = ioread32(fusb300->reg + FUSB300_OFFSET_GCR); | ||
990 | |||
991 | switch (reg & FUSB300_GCR_DEVEN_MSK) { | ||
992 | case FUSB300_GCR_DEVEN_SS: | ||
993 | fusb300->gadget.speed = USB_SPEED_SUPER; | ||
994 | break; | ||
995 | case FUSB300_GCR_DEVEN_HS: | ||
996 | fusb300->gadget.speed = USB_SPEED_HIGH; | ||
997 | break; | ||
998 | case FUSB300_GCR_DEVEN_FS: | ||
999 | fusb300->gadget.speed = USB_SPEED_FULL; | ||
1000 | break; | ||
1001 | default: | ||
1002 | fusb300->gadget.speed = USB_SPEED_UNKNOWN; | ||
1003 | break; | ||
1004 | } | ||
1005 | printk(KERN_INFO "dev_mode = %d\n", (reg & FUSB300_GCR_DEVEN_MSK)); | ||
1006 | } | ||
1007 | |||
1008 | |||
1009 | static void fusb300_ep0out(struct fusb300 *fusb300) | ||
1010 | { | ||
1011 | struct fusb300_ep *ep = fusb300->ep[0]; | ||
1012 | u32 reg; | ||
1013 | |||
1014 | if (!list_empty(&ep->queue)) { | ||
1015 | struct fusb300_request *req; | ||
1016 | |||
1017 | req = list_first_entry(&ep->queue, | ||
1018 | struct fusb300_request, queue); | ||
1019 | if (req->req.length) | ||
1020 | fusb300_rdcxf(ep->fusb300, req->req.buf, | ||
1021 | req->req.length); | ||
1022 | done(ep, req, 0); | ||
1023 | reg = ioread32(fusb300->reg + FUSB300_OFFSET_IGER1); | ||
1024 | reg &= ~FUSB300_IGER1_CX_OUT_INT; | ||
1025 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_IGER1); | ||
1026 | } else | ||
1027 | pr_err("%s : empty queue\n", __func__); | ||
1028 | } | ||
1029 | |||
1030 | static void fusb300_ep0in(struct fusb300 *fusb300) | ||
1031 | { | ||
1032 | struct fusb300_request *req; | ||
1033 | struct fusb300_ep *ep = fusb300->ep[0]; | ||
1034 | |||
1035 | if ((!list_empty(&ep->queue)) && (fusb300->ep0_dir)) { | ||
1036 | req = list_entry(ep->queue.next, | ||
1037 | struct fusb300_request, queue); | ||
1038 | if (req->req.length) | ||
1039 | fusb300_wrcxf(ep, req); | ||
1040 | if ((req->req.length - req->req.actual) < ep->ep.maxpacket) | ||
1041 | done(ep, req, 0); | ||
1042 | } else | ||
1043 | fusb300_set_cxdone(fusb300); | ||
1044 | } | ||
1045 | |||
1046 | static void fusb300_grp2_handler(void) | ||
1047 | { | ||
1048 | } | ||
1049 | |||
1050 | static void fusb300_grp3_handler(void) | ||
1051 | { | ||
1052 | } | ||
1053 | |||
1054 | static void fusb300_grp4_handler(void) | ||
1055 | { | ||
1056 | } | ||
1057 | |||
1058 | static void fusb300_grp5_handler(void) | ||
1059 | { | ||
1060 | } | ||
1061 | |||
1062 | static irqreturn_t fusb300_irq(int irq, void *_fusb300) | ||
1063 | { | ||
1064 | struct fusb300 *fusb300 = _fusb300; | ||
1065 | u32 int_grp1 = ioread32(fusb300->reg + FUSB300_OFFSET_IGR1); | ||
1066 | u32 int_grp1_en = ioread32(fusb300->reg + FUSB300_OFFSET_IGER1); | ||
1067 | u32 int_grp0 = ioread32(fusb300->reg + FUSB300_OFFSET_IGR0); | ||
1068 | u32 int_grp0_en = ioread32(fusb300->reg + FUSB300_OFFSET_IGER0); | ||
1069 | struct usb_ctrlrequest ctrl; | ||
1070 | u8 in; | ||
1071 | u32 reg; | ||
1072 | int i; | ||
1073 | |||
1074 | spin_lock(&fusb300->lock); | ||
1075 | |||
1076 | int_grp1 &= int_grp1_en; | ||
1077 | int_grp0 &= int_grp0_en; | ||
1078 | |||
1079 | if (int_grp1 & FUSB300_IGR1_WARM_RST_INT) { | ||
1080 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1081 | FUSB300_IGR1_WARM_RST_INT); | ||
1082 | printk(KERN_INFO"fusb300_warmreset\n"); | ||
1083 | fusb300_reset(); | ||
1084 | } | ||
1085 | |||
1086 | if (int_grp1 & FUSB300_IGR1_HOT_RST_INT) { | ||
1087 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1088 | FUSB300_IGR1_HOT_RST_INT); | ||
1089 | printk(KERN_INFO"fusb300_hotreset\n"); | ||
1090 | fusb300_reset(); | ||
1091 | } | ||
1092 | |||
1093 | if (int_grp1 & FUSB300_IGR1_USBRST_INT) { | ||
1094 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1095 | FUSB300_IGR1_USBRST_INT); | ||
1096 | fusb300_reset(); | ||
1097 | } | ||
1098 | /* COMABT_INT has a highest priority */ | ||
1099 | |||
1100 | if (int_grp1 & FUSB300_IGR1_CX_COMABT_INT) { | ||
1101 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1102 | FUSB300_IGR1_CX_COMABT_INT); | ||
1103 | printk(KERN_INFO"fusb300_ep0abt\n"); | ||
1104 | } | ||
1105 | |||
1106 | if (int_grp1 & FUSB300_IGR1_VBUS_CHG_INT) { | ||
1107 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1108 | FUSB300_IGR1_VBUS_CHG_INT); | ||
1109 | printk(KERN_INFO"fusb300_vbus_change\n"); | ||
1110 | } | ||
1111 | |||
1112 | if (int_grp1 & FUSB300_IGR1_U3_EXIT_FAIL_INT) { | ||
1113 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1114 | FUSB300_IGR1_U3_EXIT_FAIL_INT); | ||
1115 | } | ||
1116 | |||
1117 | if (int_grp1 & FUSB300_IGR1_U2_EXIT_FAIL_INT) { | ||
1118 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1119 | FUSB300_IGR1_U2_EXIT_FAIL_INT); | ||
1120 | } | ||
1121 | |||
1122 | if (int_grp1 & FUSB300_IGR1_U1_EXIT_FAIL_INT) { | ||
1123 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1124 | FUSB300_IGR1_U1_EXIT_FAIL_INT); | ||
1125 | } | ||
1126 | |||
1127 | if (int_grp1 & FUSB300_IGR1_U2_ENTRY_FAIL_INT) { | ||
1128 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1129 | FUSB300_IGR1_U2_ENTRY_FAIL_INT); | ||
1130 | } | ||
1131 | |||
1132 | if (int_grp1 & FUSB300_IGR1_U1_ENTRY_FAIL_INT) { | ||
1133 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1134 | FUSB300_IGR1_U1_ENTRY_FAIL_INT); | ||
1135 | } | ||
1136 | |||
1137 | if (int_grp1 & FUSB300_IGR1_U3_EXIT_INT) { | ||
1138 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1139 | FUSB300_IGR1_U3_EXIT_INT); | ||
1140 | printk(KERN_INFO "FUSB300_IGR1_U3_EXIT_INT\n"); | ||
1141 | } | ||
1142 | |||
1143 | if (int_grp1 & FUSB300_IGR1_U2_EXIT_INT) { | ||
1144 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1145 | FUSB300_IGR1_U2_EXIT_INT); | ||
1146 | printk(KERN_INFO "FUSB300_IGR1_U2_EXIT_INT\n"); | ||
1147 | } | ||
1148 | |||
1149 | if (int_grp1 & FUSB300_IGR1_U1_EXIT_INT) { | ||
1150 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1151 | FUSB300_IGR1_U1_EXIT_INT); | ||
1152 | printk(KERN_INFO "FUSB300_IGR1_U1_EXIT_INT\n"); | ||
1153 | } | ||
1154 | |||
1155 | if (int_grp1 & FUSB300_IGR1_U3_ENTRY_INT) { | ||
1156 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1157 | FUSB300_IGR1_U3_ENTRY_INT); | ||
1158 | printk(KERN_INFO "FUSB300_IGR1_U3_ENTRY_INT\n"); | ||
1159 | fusb300_enable_bit(fusb300, FUSB300_OFFSET_SSCR1, | ||
1160 | FUSB300_SSCR1_GO_U3_DONE); | ||
1161 | } | ||
1162 | |||
1163 | if (int_grp1 & FUSB300_IGR1_U2_ENTRY_INT) { | ||
1164 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1165 | FUSB300_IGR1_U2_ENTRY_INT); | ||
1166 | printk(KERN_INFO "FUSB300_IGR1_U2_ENTRY_INT\n"); | ||
1167 | } | ||
1168 | |||
1169 | if (int_grp1 & FUSB300_IGR1_U1_ENTRY_INT) { | ||
1170 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1171 | FUSB300_IGR1_U1_ENTRY_INT); | ||
1172 | printk(KERN_INFO "FUSB300_IGR1_U1_ENTRY_INT\n"); | ||
1173 | } | ||
1174 | |||
1175 | if (int_grp1 & FUSB300_IGR1_RESM_INT) { | ||
1176 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1177 | FUSB300_IGR1_RESM_INT); | ||
1178 | printk(KERN_INFO "fusb300_resume\n"); | ||
1179 | } | ||
1180 | |||
1181 | if (int_grp1 & FUSB300_IGR1_SUSP_INT) { | ||
1182 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1183 | FUSB300_IGR1_SUSP_INT); | ||
1184 | printk(KERN_INFO "fusb300_suspend\n"); | ||
1185 | } | ||
1186 | |||
1187 | if (int_grp1 & FUSB300_IGR1_HS_LPM_INT) { | ||
1188 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1189 | FUSB300_IGR1_HS_LPM_INT); | ||
1190 | printk(KERN_INFO "fusb300_HS_LPM_INT\n"); | ||
1191 | } | ||
1192 | |||
1193 | if (int_grp1 & FUSB300_IGR1_DEV_MODE_CHG_INT) { | ||
1194 | fusb300_clear_int(fusb300, FUSB300_OFFSET_IGR1, | ||
1195 | FUSB300_IGR1_DEV_MODE_CHG_INT); | ||
1196 | check_device_mode(fusb300); | ||
1197 | } | ||
1198 | |||
1199 | if (int_grp1 & FUSB300_IGR1_CX_COMFAIL_INT) { | ||
1200 | fusb300_set_cxstall(fusb300); | ||
1201 | printk(KERN_INFO "fusb300_ep0fail\n"); | ||
1202 | } | ||
1203 | |||
1204 | if (int_grp1 & FUSB300_IGR1_CX_SETUP_INT) { | ||
1205 | printk(KERN_INFO "fusb300_ep0setup\n"); | ||
1206 | if (setup_packet(fusb300, &ctrl)) { | ||
1207 | spin_unlock(&fusb300->lock); | ||
1208 | if (fusb300->driver->setup(&fusb300->gadget, &ctrl) < 0) | ||
1209 | fusb300_set_cxstall(fusb300); | ||
1210 | spin_lock(&fusb300->lock); | ||
1211 | } | ||
1212 | } | ||
1213 | |||
1214 | if (int_grp1 & FUSB300_IGR1_CX_CMDEND_INT) | ||
1215 | printk(KERN_INFO "fusb300_cmdend\n"); | ||
1216 | |||
1217 | |||
1218 | if (int_grp1 & FUSB300_IGR1_CX_OUT_INT) { | ||
1219 | printk(KERN_INFO "fusb300_cxout\n"); | ||
1220 | fusb300_ep0out(fusb300); | ||
1221 | } | ||
1222 | |||
1223 | if (int_grp1 & FUSB300_IGR1_CX_IN_INT) { | ||
1224 | printk(KERN_INFO "fusb300_cxin\n"); | ||
1225 | fusb300_ep0in(fusb300); | ||
1226 | } | ||
1227 | |||
1228 | if (int_grp1 & FUSB300_IGR1_INTGRP5) | ||
1229 | fusb300_grp5_handler(); | ||
1230 | |||
1231 | if (int_grp1 & FUSB300_IGR1_INTGRP4) | ||
1232 | fusb300_grp4_handler(); | ||
1233 | |||
1234 | if (int_grp1 & FUSB300_IGR1_INTGRP3) | ||
1235 | fusb300_grp3_handler(); | ||
1236 | |||
1237 | if (int_grp1 & FUSB300_IGR1_INTGRP2) | ||
1238 | fusb300_grp2_handler(); | ||
1239 | |||
1240 | if (int_grp0) { | ||
1241 | for (i = 1; i < FUSB300_MAX_NUM_EP; i++) { | ||
1242 | if (int_grp0 & FUSB300_IGR0_EPn_FIFO_INT(i)) { | ||
1243 | reg = ioread32(fusb300->reg + | ||
1244 | FUSB300_OFFSET_EPSET1(i)); | ||
1245 | in = (reg & FUSB300_EPSET1_DIRIN) ? 1 : 0; | ||
1246 | if (in) | ||
1247 | in_ep_fifo_handler(fusb300->ep[i]); | ||
1248 | else | ||
1249 | out_ep_fifo_handler(fusb300->ep[i]); | ||
1250 | } | ||
1251 | } | ||
1252 | } | ||
1253 | |||
1254 | spin_unlock(&fusb300->lock); | ||
1255 | |||
1256 | return IRQ_HANDLED; | ||
1257 | } | ||
1258 | |||
1259 | static void fusb300_set_u2_timeout(struct fusb300 *fusb300, | ||
1260 | u32 time) | ||
1261 | { | ||
1262 | u32 reg; | ||
1263 | |||
1264 | reg = ioread32(fusb300->reg + FUSB300_OFFSET_TT); | ||
1265 | reg &= ~0xff; | ||
1266 | reg |= FUSB300_SSCR2_U2TIMEOUT(time); | ||
1267 | |||
1268 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_TT); | ||
1269 | } | ||
1270 | |||
1271 | static void fusb300_set_u1_timeout(struct fusb300 *fusb300, | ||
1272 | u32 time) | ||
1273 | { | ||
1274 | u32 reg; | ||
1275 | |||
1276 | reg = ioread32(fusb300->reg + FUSB300_OFFSET_TT); | ||
1277 | reg &= ~(0xff << 8); | ||
1278 | reg |= FUSB300_SSCR2_U1TIMEOUT(time); | ||
1279 | |||
1280 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_TT); | ||
1281 | } | ||
1282 | |||
1283 | static void init_controller(struct fusb300 *fusb300) | ||
1284 | { | ||
1285 | u32 reg; | ||
1286 | u32 mask = 0; | ||
1287 | u32 val = 0; | ||
1288 | |||
1289 | /* split on */ | ||
1290 | mask = val = FUSB300_AHBBCR_S0_SPLIT_ON | FUSB300_AHBBCR_S1_SPLIT_ON; | ||
1291 | reg = ioread32(fusb300->reg + FUSB300_OFFSET_AHBCR); | ||
1292 | reg &= ~mask; | ||
1293 | reg |= val; | ||
1294 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_AHBCR); | ||
1295 | |||
1296 | /* enable high-speed LPM */ | ||
1297 | mask = val = FUSB300_HSCR_HS_LPM_PERMIT; | ||
1298 | reg = ioread32(fusb300->reg + FUSB300_OFFSET_HSCR); | ||
1299 | reg &= ~mask; | ||
1300 | reg |= val; | ||
1301 | iowrite32(reg, fusb300->reg + FUSB300_OFFSET_HSCR); | ||
1302 | |||
1303 | /*set u1 u2 timmer*/ | ||
1304 | fusb300_set_u2_timeout(fusb300, 0xff); | ||
1305 | fusb300_set_u1_timeout(fusb300, 0xff); | ||
1306 | |||
1307 | /* enable all grp1 interrupt */ | ||
1308 | iowrite32(0xcfffff9f, fusb300->reg + FUSB300_OFFSET_IGER1); | ||
1309 | } | ||
1310 | /*------------------------------------------------------------------------*/ | ||
1311 | static int fusb300_udc_start(struct usb_gadget *g, | ||
1312 | struct usb_gadget_driver *driver) | ||
1313 | { | ||
1314 | struct fusb300 *fusb300 = to_fusb300(g); | ||
1315 | |||
1316 | /* hook up the driver */ | ||
1317 | driver->driver.bus = NULL; | ||
1318 | fusb300->driver = driver; | ||
1319 | |||
1320 | return 0; | ||
1321 | } | ||
1322 | |||
1323 | static int fusb300_udc_stop(struct usb_gadget *g, | ||
1324 | struct usb_gadget_driver *driver) | ||
1325 | { | ||
1326 | struct fusb300 *fusb300 = to_fusb300(g); | ||
1327 | |||
1328 | init_controller(fusb300); | ||
1329 | fusb300->driver = NULL; | ||
1330 | |||
1331 | return 0; | ||
1332 | } | ||
1333 | /*--------------------------------------------------------------------------*/ | ||
1334 | |||
1335 | static int fusb300_udc_pullup(struct usb_gadget *_gadget, int is_active) | ||
1336 | { | ||
1337 | return 0; | ||
1338 | } | ||
1339 | |||
1340 | static const struct usb_gadget_ops fusb300_gadget_ops = { | ||
1341 | .pullup = fusb300_udc_pullup, | ||
1342 | .udc_start = fusb300_udc_start, | ||
1343 | .udc_stop = fusb300_udc_stop, | ||
1344 | }; | ||
1345 | |||
1346 | static int __exit fusb300_remove(struct platform_device *pdev) | ||
1347 | { | ||
1348 | struct fusb300 *fusb300 = platform_get_drvdata(pdev); | ||
1349 | |||
1350 | usb_del_gadget_udc(&fusb300->gadget); | ||
1351 | iounmap(fusb300->reg); | ||
1352 | free_irq(platform_get_irq(pdev, 0), fusb300); | ||
1353 | |||
1354 | fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); | ||
1355 | kfree(fusb300); | ||
1356 | |||
1357 | return 0; | ||
1358 | } | ||
1359 | |||
1360 | static int fusb300_probe(struct platform_device *pdev) | ||
1361 | { | ||
1362 | struct resource *res, *ires, *ires1; | ||
1363 | void __iomem *reg = NULL; | ||
1364 | struct fusb300 *fusb300 = NULL; | ||
1365 | struct fusb300_ep *_ep[FUSB300_MAX_NUM_EP]; | ||
1366 | int ret = 0; | ||
1367 | int i; | ||
1368 | |||
1369 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1370 | if (!res) { | ||
1371 | ret = -ENODEV; | ||
1372 | pr_err("platform_get_resource error.\n"); | ||
1373 | goto clean_up; | ||
1374 | } | ||
1375 | |||
1376 | ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
1377 | if (!ires) { | ||
1378 | ret = -ENODEV; | ||
1379 | dev_err(&pdev->dev, | ||
1380 | "platform_get_resource IORESOURCE_IRQ error.\n"); | ||
1381 | goto clean_up; | ||
1382 | } | ||
1383 | |||
1384 | ires1 = platform_get_resource(pdev, IORESOURCE_IRQ, 1); | ||
1385 | if (!ires1) { | ||
1386 | ret = -ENODEV; | ||
1387 | dev_err(&pdev->dev, | ||
1388 | "platform_get_resource IORESOURCE_IRQ 1 error.\n"); | ||
1389 | goto clean_up; | ||
1390 | } | ||
1391 | |||
1392 | reg = ioremap(res->start, resource_size(res)); | ||
1393 | if (reg == NULL) { | ||
1394 | ret = -ENOMEM; | ||
1395 | pr_err("ioremap error.\n"); | ||
1396 | goto clean_up; | ||
1397 | } | ||
1398 | |||
1399 | /* initialize udc */ | ||
1400 | fusb300 = kzalloc(sizeof(struct fusb300), GFP_KERNEL); | ||
1401 | if (fusb300 == NULL) | ||
1402 | goto clean_up; | ||
1403 | |||
1404 | for (i = 0; i < FUSB300_MAX_NUM_EP; i++) { | ||
1405 | _ep[i] = kzalloc(sizeof(struct fusb300_ep), GFP_KERNEL); | ||
1406 | if (_ep[i] == NULL) | ||
1407 | goto clean_up; | ||
1408 | fusb300->ep[i] = _ep[i]; | ||
1409 | } | ||
1410 | |||
1411 | spin_lock_init(&fusb300->lock); | ||
1412 | |||
1413 | platform_set_drvdata(pdev, fusb300); | ||
1414 | |||
1415 | fusb300->gadget.ops = &fusb300_gadget_ops; | ||
1416 | |||
1417 | fusb300->gadget.max_speed = USB_SPEED_HIGH; | ||
1418 | fusb300->gadget.name = udc_name; | ||
1419 | fusb300->reg = reg; | ||
1420 | |||
1421 | ret = request_irq(ires->start, fusb300_irq, IRQF_SHARED, | ||
1422 | udc_name, fusb300); | ||
1423 | if (ret < 0) { | ||
1424 | pr_err("request_irq error (%d)\n", ret); | ||
1425 | goto clean_up; | ||
1426 | } | ||
1427 | |||
1428 | ret = request_irq(ires1->start, fusb300_irq, | ||
1429 | IRQF_SHARED, udc_name, fusb300); | ||
1430 | if (ret < 0) { | ||
1431 | pr_err("request_irq1 error (%d)\n", ret); | ||
1432 | goto clean_up; | ||
1433 | } | ||
1434 | |||
1435 | INIT_LIST_HEAD(&fusb300->gadget.ep_list); | ||
1436 | |||
1437 | for (i = 0; i < FUSB300_MAX_NUM_EP ; i++) { | ||
1438 | struct fusb300_ep *ep = fusb300->ep[i]; | ||
1439 | |||
1440 | if (i != 0) { | ||
1441 | INIT_LIST_HEAD(&fusb300->ep[i]->ep.ep_list); | ||
1442 | list_add_tail(&fusb300->ep[i]->ep.ep_list, | ||
1443 | &fusb300->gadget.ep_list); | ||
1444 | } | ||
1445 | ep->fusb300 = fusb300; | ||
1446 | INIT_LIST_HEAD(&ep->queue); | ||
1447 | ep->ep.name = fusb300_ep_name[i]; | ||
1448 | ep->ep.ops = &fusb300_ep_ops; | ||
1449 | usb_ep_set_maxpacket_limit(&ep->ep, HS_BULK_MAX_PACKET_SIZE); | ||
1450 | } | ||
1451 | usb_ep_set_maxpacket_limit(&fusb300->ep[0]->ep, HS_CTL_MAX_PACKET_SIZE); | ||
1452 | fusb300->ep[0]->epnum = 0; | ||
1453 | fusb300->gadget.ep0 = &fusb300->ep[0]->ep; | ||
1454 | INIT_LIST_HEAD(&fusb300->gadget.ep0->ep_list); | ||
1455 | |||
1456 | fusb300->ep0_req = fusb300_alloc_request(&fusb300->ep[0]->ep, | ||
1457 | GFP_KERNEL); | ||
1458 | if (fusb300->ep0_req == NULL) { | ||
1459 | ret = -ENOMEM; | ||
1460 | goto clean_up3; | ||
1461 | } | ||
1462 | |||
1463 | init_controller(fusb300); | ||
1464 | ret = usb_add_gadget_udc(&pdev->dev, &fusb300->gadget); | ||
1465 | if (ret) | ||
1466 | goto err_add_udc; | ||
1467 | |||
1468 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); | ||
1469 | |||
1470 | return 0; | ||
1471 | |||
1472 | err_add_udc: | ||
1473 | fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req); | ||
1474 | |||
1475 | clean_up3: | ||
1476 | free_irq(ires->start, fusb300); | ||
1477 | |||
1478 | clean_up: | ||
1479 | if (fusb300) { | ||
1480 | if (fusb300->ep0_req) | ||
1481 | fusb300_free_request(&fusb300->ep[0]->ep, | ||
1482 | fusb300->ep0_req); | ||
1483 | kfree(fusb300); | ||
1484 | } | ||
1485 | if (reg) | ||
1486 | iounmap(reg); | ||
1487 | |||
1488 | return ret; | ||
1489 | } | ||
1490 | |||
1491 | static struct platform_driver fusb300_driver = { | ||
1492 | .remove = __exit_p(fusb300_remove), | ||
1493 | .driver = { | ||
1494 | .name = (char *) udc_name, | ||
1495 | .owner = THIS_MODULE, | ||
1496 | }, | ||
1497 | }; | ||
1498 | |||
1499 | module_platform_driver_probe(fusb300_driver, fusb300_probe); | ||