blob: 09c76a17a1041a56a46bf35e79c9af9acd3fd0e6 [file] [log] [blame]
David Lopoaa69a802008-11-17 14:14:51 -08001/*
2 * ci13xxx_udc.c - MIPS USB IP core family device controller
3 *
4 * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
5 *
6 * Author: David Lopo
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 version 2 as
10 * published by the Free Software Foundation.
11 */
12
13/*
14 * Description: MIPS USB IP core family device controller
15 * Currently it only supports IP part number CI13412
16 *
17 * This driver is composed of several blocks:
18 * - HW: hardware interface
19 * - DBG: debug facilities (optional)
20 * - UTIL: utilities
21 * - ISR: interrupts handling
22 * - ENDPT: endpoint operations (Gadget API)
23 * - GADGET: gadget operations (Gadget API)
24 * - BUS: bus glue code, bus abstraction layer
David Lopoaa69a802008-11-17 14:14:51 -080025 *
26 * Compile Options
27 * - CONFIG_USB_GADGET_DEBUG_FILES: enable debug facilities
28 * - STALL_IN: non-empty bulk-in pipes cannot be halted
29 * if defined mass storage compliance succeeds but with warnings
30 * => case 4: Hi > Dn
31 * => case 5: Hi > Di
32 * => case 8: Hi <> Do
33 * if undefined usbtest 13 fails
34 * - TRACE: enable function tracing (depends on DEBUG)
35 *
36 * Main Features
37 * - Chapter 9 & Mass Storage Compliance with Gadget File Storage
38 * - Chapter 9 Compliance with Gadget Zero (STALL_IN undefined)
39 * - Normal & LPM support
40 *
41 * USBTEST Report
42 * - OK: 0-12, 13 (STALL_IN defined) & 14
43 * - Not Supported: 15 & 16 (ISO)
44 *
45 * TODO List
46 * - OTG
47 * - Isochronous & Interrupt Traffic
48 * - Handle requests which spawns into several TDs
49 * - GET_STATUS(device) - always reports 0
50 * - Gadget API (majority of optional features)
51 * - Suspend & Remote Wakeup
52 */
Matthias Kaehlcke36825a22009-04-15 22:28:36 +020053#include <linux/delay.h>
David Lopoaa69a802008-11-17 14:14:51 -080054#include <linux/device.h>
55#include <linux/dmapool.h>
56#include <linux/dma-mapping.h>
57#include <linux/init.h>
58#include <linux/interrupt.h>
David Lopoaa69a802008-11-17 14:14:51 -080059#include <linux/io.h>
60#include <linux/irq.h>
61#include <linux/kernel.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090062#include <linux/slab.h>
Pavankumar Kondetic0360192010-12-07 17:54:04 +053063#include <linux/pm_runtime.h>
David Lopoaa69a802008-11-17 14:14:51 -080064#include <linux/usb/ch9.h>
65#include <linux/usb/gadget.h>
Pavankumar Kondetif01ef572010-12-07 17:54:02 +053066#include <linux/usb/otg.h>
David Lopoaa69a802008-11-17 14:14:51 -080067
68#include "ci13xxx_udc.h"
69
70
71/******************************************************************************
72 * DEFINE
73 *****************************************************************************/
74/* ctrl register bank access */
75static DEFINE_SPINLOCK(udc_lock);
76
David Lopoaa69a802008-11-17 14:14:51 -080077/* control endpoint description */
78static const struct usb_endpoint_descriptor
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053079ctrl_endpt_out_desc = {
David Lopoaa69a802008-11-17 14:14:51 -080080 .bLength = USB_DT_ENDPOINT_SIZE,
81 .bDescriptorType = USB_DT_ENDPOINT,
82
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053083 .bEndpointAddress = USB_DIR_OUT,
84 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
85 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
86};
87
88static const struct usb_endpoint_descriptor
89ctrl_endpt_in_desc = {
90 .bLength = USB_DT_ENDPOINT_SIZE,
91 .bDescriptorType = USB_DT_ENDPOINT,
92
93 .bEndpointAddress = USB_DIR_IN,
David Lopoaa69a802008-11-17 14:14:51 -080094 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
95 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
96};
97
98/* UDC descriptor */
99static struct ci13xxx *_udc;
100
101/* Interrupt statistics */
102#define ISR_MASK 0x1F
103static struct {
104 u32 test;
105 u32 ui;
106 u32 uei;
107 u32 pci;
108 u32 uri;
109 u32 sli;
110 u32 none;
111 struct {
112 u32 cnt;
113 u32 buf[ISR_MASK+1];
114 u32 idx;
115 } hndl;
116} isr_statistics;
117
118/**
119 * ffs_nr: find first (least significant) bit set
120 * @x: the word to search
121 *
122 * This function returns bit number (instead of position)
123 */
124static int ffs_nr(u32 x)
125{
126 int n = ffs(x);
127
128 return n ? n-1 : 32;
129}
130
131/******************************************************************************
132 * HW block
133 *****************************************************************************/
134/* register bank descriptor */
135static struct {
136 unsigned lpm; /* is LPM? */
137 void __iomem *abs; /* bus map offset */
138 void __iomem *cap; /* bus map offset + CAP offset + CAP data */
139 size_t size; /* bank size */
140} hw_bank;
141
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530142/* MSM specific */
143#define ABS_AHBBURST (0x0090UL)
144#define ABS_AHBMODE (0x0098UL)
David Lopoaa69a802008-11-17 14:14:51 -0800145/* UDC register map */
146#define ABS_CAPLENGTH (0x100UL)
147#define ABS_HCCPARAMS (0x108UL)
148#define ABS_DCCPARAMS (0x124UL)
149#define ABS_TESTMODE (hw_bank.lpm ? 0x0FCUL : 0x138UL)
150/* offset to CAPLENTGH (addr + data) */
151#define CAP_USBCMD (0x000UL)
152#define CAP_USBSTS (0x004UL)
153#define CAP_USBINTR (0x008UL)
154#define CAP_DEVICEADDR (0x014UL)
155#define CAP_ENDPTLISTADDR (0x018UL)
156#define CAP_PORTSC (0x044UL)
David Lopof23e6492009-04-16 14:35:24 -0700157#define CAP_DEVLC (0x084UL)
David Lopoaa69a802008-11-17 14:14:51 -0800158#define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL)
159#define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL)
160#define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL)
161#define CAP_ENDPTFLUSH (hw_bank.lpm ? 0x0E0UL : 0x074UL)
162#define CAP_ENDPTSTAT (hw_bank.lpm ? 0x0E4UL : 0x078UL)
163#define CAP_ENDPTCOMPLETE (hw_bank.lpm ? 0x0E8UL : 0x07CUL)
164#define CAP_ENDPTCTRL (hw_bank.lpm ? 0x0ECUL : 0x080UL)
165#define CAP_LAST (hw_bank.lpm ? 0x12CUL : 0x0C0UL)
166
167/* maximum number of enpoints: valid only after hw_device_reset() */
168static unsigned hw_ep_max;
169
170/**
171 * hw_ep_bit: calculates the bit number
172 * @num: endpoint number
173 * @dir: endpoint direction
174 *
175 * This function returns bit number
176 */
177static inline int hw_ep_bit(int num, int dir)
178{
179 return num + (dir ? 16 : 0);
180}
181
182/**
183 * hw_aread: reads from register bitfield
184 * @addr: address relative to bus map
185 * @mask: bitfield mask
186 *
187 * This function returns register bitfield data
188 */
189static u32 hw_aread(u32 addr, u32 mask)
190{
191 return ioread32(addr + hw_bank.abs) & mask;
192}
193
194/**
195 * hw_awrite: writes to register bitfield
196 * @addr: address relative to bus map
197 * @mask: bitfield mask
198 * @data: new data
199 */
200static void hw_awrite(u32 addr, u32 mask, u32 data)
201{
202 iowrite32(hw_aread(addr, ~mask) | (data & mask),
203 addr + hw_bank.abs);
204}
205
206/**
207 * hw_cread: reads from register bitfield
208 * @addr: address relative to CAP offset plus content
209 * @mask: bitfield mask
210 *
211 * This function returns register bitfield data
212 */
213static u32 hw_cread(u32 addr, u32 mask)
214{
215 return ioread32(addr + hw_bank.cap) & mask;
216}
217
218/**
219 * hw_cwrite: writes to register bitfield
220 * @addr: address relative to CAP offset plus content
221 * @mask: bitfield mask
222 * @data: new data
223 */
224static void hw_cwrite(u32 addr, u32 mask, u32 data)
225{
226 iowrite32(hw_cread(addr, ~mask) | (data & mask),
227 addr + hw_bank.cap);
228}
229
230/**
231 * hw_ctest_and_clear: tests & clears register bitfield
232 * @addr: address relative to CAP offset plus content
233 * @mask: bitfield mask
234 *
235 * This function returns register bitfield data
236 */
237static u32 hw_ctest_and_clear(u32 addr, u32 mask)
238{
239 u32 reg = hw_cread(addr, mask);
240
241 iowrite32(reg, addr + hw_bank.cap);
242 return reg;
243}
244
245/**
246 * hw_ctest_and_write: tests & writes register bitfield
247 * @addr: address relative to CAP offset plus content
248 * @mask: bitfield mask
249 * @data: new data
250 *
251 * This function returns register bitfield data
252 */
253static u32 hw_ctest_and_write(u32 addr, u32 mask, u32 data)
254{
255 u32 reg = hw_cread(addr, ~0);
256
257 iowrite32((reg & ~mask) | (data & mask), addr + hw_bank.cap);
258 return (reg & mask) >> ffs_nr(mask);
259}
260
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530261static int hw_device_init(void __iomem *base)
David Lopoaa69a802008-11-17 14:14:51 -0800262{
263 u32 reg;
264
265 /* bank is a module variable */
266 hw_bank.abs = base;
267
268 hw_bank.cap = hw_bank.abs;
269 hw_bank.cap += ABS_CAPLENGTH;
270 hw_bank.cap += ioread8(hw_bank.cap);
271
272 reg = hw_aread(ABS_HCCPARAMS, HCCPARAMS_LEN) >> ffs_nr(HCCPARAMS_LEN);
273 hw_bank.lpm = reg;
274 hw_bank.size = hw_bank.cap - hw_bank.abs;
275 hw_bank.size += CAP_LAST;
276 hw_bank.size /= sizeof(u32);
277
David Lopoaa69a802008-11-17 14:14:51 -0800278 reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530279 hw_ep_max = reg * 2; /* cache hw ENDPT_MAX */
David Lopoaa69a802008-11-17 14:14:51 -0800280
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530281 if (hw_ep_max == 0 || hw_ep_max > ENDPT_MAX)
282 return -ENODEV;
David Lopoaa69a802008-11-17 14:14:51 -0800283
284 /* setup lock mode ? */
285
286 /* ENDPTSETUPSTAT is '0' by default */
287
288 /* HCSPARAMS.bf.ppc SHOULD BE zero for device */
289
290 return 0;
291}
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530292/**
293 * hw_device_reset: resets chip (execute without interruption)
294 * @base: register base address
295 *
296 * This function returns an error code
297 */
298static int hw_device_reset(struct ci13xxx *udc)
299{
300 /* should flush & stop before reset */
301 hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0);
302 hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
303
304 hw_cwrite(CAP_USBCMD, USBCMD_RST, USBCMD_RST);
305 while (hw_cread(CAP_USBCMD, USBCMD_RST))
306 udelay(10); /* not RTOS friendly */
307
308
309 if (udc->udc_driver->notify_event)
310 udc->udc_driver->notify_event(udc,
311 CI13XXX_CONTROLLER_RESET_EVENT);
312
Pavankumar Kondeti8c2387a2011-05-02 11:56:28 +0530313 if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530314 hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
315
316 /* USBMODE should be configured step by step */
317 hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
318 hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE);
319 hw_cwrite(CAP_USBMODE, USBMODE_SLOM, USBMODE_SLOM); /* HW >= 2.3 */
320
321 if (hw_cread(CAP_USBMODE, USBMODE_CM) != USBMODE_CM_DEVICE) {
322 pr_err("cannot enter in device mode");
323 pr_err("lpm = %i", hw_bank.lpm);
324 return -ENODEV;
325 }
326
327 return 0;
328}
David Lopoaa69a802008-11-17 14:14:51 -0800329
330/**
331 * hw_device_state: enables/disables interrupts & starts/stops device (execute
332 * without interruption)
333 * @dma: 0 => disable, !0 => enable and set dma engine
334 *
335 * This function returns an error code
336 */
337static int hw_device_state(u32 dma)
338{
339 if (dma) {
340 hw_cwrite(CAP_ENDPTLISTADDR, ~0, dma);
341 /* interrupt, error, port change, reset, sleep/suspend */
342 hw_cwrite(CAP_USBINTR, ~0,
343 USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
344 hw_cwrite(CAP_USBCMD, USBCMD_RS, USBCMD_RS);
345 } else {
346 hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
347 hw_cwrite(CAP_USBINTR, ~0, 0);
348 }
349 return 0;
350}
351
352/**
353 * hw_ep_flush: flush endpoint fifo (execute without interruption)
354 * @num: endpoint number
355 * @dir: endpoint direction
356 *
357 * This function returns an error code
358 */
359static int hw_ep_flush(int num, int dir)
360{
361 int n = hw_ep_bit(num, dir);
362
363 do {
364 /* flush any pending transfer */
365 hw_cwrite(CAP_ENDPTFLUSH, BIT(n), BIT(n));
366 while (hw_cread(CAP_ENDPTFLUSH, BIT(n)))
367 cpu_relax();
368 } while (hw_cread(CAP_ENDPTSTAT, BIT(n)));
369
370 return 0;
371}
372
373/**
374 * hw_ep_disable: disables endpoint (execute without interruption)
375 * @num: endpoint number
376 * @dir: endpoint direction
377 *
378 * This function returns an error code
379 */
380static int hw_ep_disable(int num, int dir)
381{
382 hw_ep_flush(num, dir);
383 hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32),
384 dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
385 return 0;
386}
387
388/**
389 * hw_ep_enable: enables endpoint (execute without interruption)
390 * @num: endpoint number
391 * @dir: endpoint direction
392 * @type: endpoint type
393 *
394 * This function returns an error code
395 */
396static int hw_ep_enable(int num, int dir, int type)
397{
398 u32 mask, data;
399
400 if (dir) {
401 mask = ENDPTCTRL_TXT; /* type */
402 data = type << ffs_nr(mask);
403
404 mask |= ENDPTCTRL_TXS; /* unstall */
405 mask |= ENDPTCTRL_TXR; /* reset data toggle */
406 data |= ENDPTCTRL_TXR;
407 mask |= ENDPTCTRL_TXE; /* enable */
408 data |= ENDPTCTRL_TXE;
409 } else {
410 mask = ENDPTCTRL_RXT; /* type */
411 data = type << ffs_nr(mask);
412
413 mask |= ENDPTCTRL_RXS; /* unstall */
414 mask |= ENDPTCTRL_RXR; /* reset data toggle */
415 data |= ENDPTCTRL_RXR;
416 mask |= ENDPTCTRL_RXE; /* enable */
417 data |= ENDPTCTRL_RXE;
418 }
419 hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32), mask, data);
420 return 0;
421}
422
423/**
424 * hw_ep_get_halt: return endpoint halt status
425 * @num: endpoint number
426 * @dir: endpoint direction
427 *
428 * This function returns 1 if endpoint halted
429 */
430static int hw_ep_get_halt(int num, int dir)
431{
432 u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
433
434 return hw_cread(CAP_ENDPTCTRL + num * sizeof(u32), mask) ? 1 : 0;
435}
436
437/**
David Lopoaa69a802008-11-17 14:14:51 -0800438 * hw_test_and_clear_setup_status: test & clear setup status (execute without
439 * interruption)
440 * @n: bit number (endpoint)
441 *
442 * This function returns setup status
443 */
444static int hw_test_and_clear_setup_status(int n)
445{
446 return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n));
447}
448
449/**
450 * hw_ep_prime: primes endpoint (execute without interruption)
451 * @num: endpoint number
452 * @dir: endpoint direction
453 * @is_ctrl: true if control endpoint
454 *
455 * This function returns an error code
456 */
457static int hw_ep_prime(int num, int dir, int is_ctrl)
458{
459 int n = hw_ep_bit(num, dir);
460
David Lopoaa69a802008-11-17 14:14:51 -0800461 if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
462 return -EAGAIN;
463
464 hw_cwrite(CAP_ENDPTPRIME, BIT(n), BIT(n));
465
466 while (hw_cread(CAP_ENDPTPRIME, BIT(n)))
467 cpu_relax();
468 if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
469 return -EAGAIN;
470
471 /* status shoult be tested according with manual but it doesn't work */
472 return 0;
473}
474
475/**
476 * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute
477 * without interruption)
478 * @num: endpoint number
479 * @dir: endpoint direction
480 * @value: true => stall, false => unstall
481 *
482 * This function returns an error code
483 */
484static int hw_ep_set_halt(int num, int dir, int value)
485{
486 if (value != 0 && value != 1)
487 return -EINVAL;
488
489 do {
490 u32 addr = CAP_ENDPTCTRL + num * sizeof(u32);
491 u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
492 u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
493
494 /* data toggle - reserved for EP0 but it's in ESS */
495 hw_cwrite(addr, mask_xs|mask_xr, value ? mask_xs : mask_xr);
496
497 } while (value != hw_ep_get_halt(num, dir));
498
499 return 0;
500}
501
502/**
503 * hw_intr_clear: disables interrupt & clears interrupt status (execute without
504 * interruption)
505 * @n: interrupt bit
506 *
507 * This function returns an error code
508 */
509static int hw_intr_clear(int n)
510{
511 if (n >= REG_BITS)
512 return -EINVAL;
513
514 hw_cwrite(CAP_USBINTR, BIT(n), 0);
515 hw_cwrite(CAP_USBSTS, BIT(n), BIT(n));
516 return 0;
517}
518
519/**
520 * hw_intr_force: enables interrupt & forces interrupt status (execute without
521 * interruption)
522 * @n: interrupt bit
523 *
524 * This function returns an error code
525 */
526static int hw_intr_force(int n)
527{
528 if (n >= REG_BITS)
529 return -EINVAL;
530
531 hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE);
532 hw_cwrite(CAP_USBINTR, BIT(n), BIT(n));
533 hw_cwrite(CAP_USBSTS, BIT(n), BIT(n));
534 hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, 0);
535 return 0;
536}
537
538/**
539 * hw_is_port_high_speed: test if port is high speed
540 *
541 * This function returns true if high speed port
542 */
543static int hw_port_is_high_speed(void)
544{
545 return hw_bank.lpm ? hw_cread(CAP_DEVLC, DEVLC_PSPD) :
546 hw_cread(CAP_PORTSC, PORTSC_HSP);
547}
548
549/**
550 * hw_port_test_get: reads port test mode value
551 *
552 * This function returns port test mode value
553 */
554static u8 hw_port_test_get(void)
555{
556 return hw_cread(CAP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC);
557}
558
559/**
560 * hw_port_test_set: writes port test mode (execute without interruption)
561 * @mode: new value
562 *
563 * This function returns an error code
564 */
565static int hw_port_test_set(u8 mode)
566{
567 const u8 TEST_MODE_MAX = 7;
568
569 if (mode > TEST_MODE_MAX)
570 return -EINVAL;
571
572 hw_cwrite(CAP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC));
573 return 0;
574}
575
576/**
577 * hw_read_intr_enable: returns interrupt enable register
578 *
579 * This function returns register data
580 */
581static u32 hw_read_intr_enable(void)
582{
583 return hw_cread(CAP_USBINTR, ~0);
584}
585
586/**
587 * hw_read_intr_status: returns interrupt status register
588 *
589 * This function returns register data
590 */
591static u32 hw_read_intr_status(void)
592{
593 return hw_cread(CAP_USBSTS, ~0);
594}
595
596/**
597 * hw_register_read: reads all device registers (execute without interruption)
598 * @buf: destination buffer
599 * @size: buffer size
600 *
601 * This function returns number of registers read
602 */
603static size_t hw_register_read(u32 *buf, size_t size)
604{
605 unsigned i;
606
607 if (size > hw_bank.size)
608 size = hw_bank.size;
609
610 for (i = 0; i < size; i++)
611 buf[i] = hw_aread(i * sizeof(u32), ~0);
612
613 return size;
614}
615
616/**
617 * hw_register_write: writes to register
618 * @addr: register address
619 * @data: register value
620 *
621 * This function returns an error code
622 */
623static int hw_register_write(u16 addr, u32 data)
624{
625 /* align */
626 addr /= sizeof(u32);
627
628 if (addr >= hw_bank.size)
629 return -EINVAL;
630
631 /* align */
632 addr *= sizeof(u32);
633
634 hw_awrite(addr, ~0, data);
635 return 0;
636}
637
638/**
639 * hw_test_and_clear_complete: test & clear complete status (execute without
640 * interruption)
641 * @n: bit number (endpoint)
642 *
643 * This function returns complete status
644 */
645static int hw_test_and_clear_complete(int n)
646{
647 return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n));
648}
649
650/**
651 * hw_test_and_clear_intr_active: test & clear active interrupts (execute
652 * without interruption)
653 *
654 * This function returns active interrutps
655 */
656static u32 hw_test_and_clear_intr_active(void)
657{
658 u32 reg = hw_read_intr_status() & hw_read_intr_enable();
659
660 hw_cwrite(CAP_USBSTS, ~0, reg);
661 return reg;
662}
663
664/**
665 * hw_test_and_clear_setup_guard: test & clear setup guard (execute without
666 * interruption)
667 *
668 * This function returns guard value
669 */
670static int hw_test_and_clear_setup_guard(void)
671{
672 return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, 0);
673}
674
675/**
676 * hw_test_and_set_setup_guard: test & set setup guard (execute without
677 * interruption)
678 *
679 * This function returns guard value
680 */
681static int hw_test_and_set_setup_guard(void)
682{
683 return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, USBCMD_SUTW);
684}
685
686/**
687 * hw_usb_set_address: configures USB address (execute without interruption)
688 * @value: new USB address
689 *
690 * This function returns an error code
691 */
692static int hw_usb_set_address(u8 value)
693{
694 /* advance */
695 hw_cwrite(CAP_DEVICEADDR, DEVICEADDR_USBADR | DEVICEADDR_USBADRA,
696 value << ffs_nr(DEVICEADDR_USBADR) | DEVICEADDR_USBADRA);
697 return 0;
698}
699
700/**
701 * hw_usb_reset: restart device after a bus reset (execute without
702 * interruption)
703 *
704 * This function returns an error code
705 */
706static int hw_usb_reset(void)
707{
708 hw_usb_set_address(0);
709
710 /* ESS flushes only at end?!? */
711 hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); /* flush all EPs */
712
713 /* clear setup token semaphores */
714 hw_cwrite(CAP_ENDPTSETUPSTAT, 0, 0); /* writes its content */
715
716 /* clear complete status */
717 hw_cwrite(CAP_ENDPTCOMPLETE, 0, 0); /* writes its content */
718
719 /* wait until all bits cleared */
720 while (hw_cread(CAP_ENDPTPRIME, ~0))
721 udelay(10); /* not RTOS friendly */
722
723 /* reset all endpoints ? */
724
725 /* reset internal status and wait for further instructions
726 no need to verify the port reset status (ESS does it) */
727
728 return 0;
729}
730
731/******************************************************************************
732 * DBG block
733 *****************************************************************************/
734/**
735 * show_device: prints information about device capabilities and status
736 *
737 * Check "device.h" for details
738 */
739static ssize_t show_device(struct device *dev, struct device_attribute *attr,
740 char *buf)
741{
742 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
743 struct usb_gadget *gadget = &udc->gadget;
744 int n = 0;
745
746 dbg_trace("[%s] %p\n", __func__, buf);
747 if (attr == NULL || buf == NULL) {
748 dev_err(dev, "[%s] EINVAL\n", __func__);
749 return 0;
750 }
751
752 n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n",
753 gadget->speed);
754 n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n",
755 gadget->is_dualspeed);
756 n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
757 gadget->is_otg);
758 n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
759 gadget->is_a_peripheral);
760 n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n",
761 gadget->b_hnp_enable);
762 n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n",
763 gadget->a_hnp_support);
764 n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n",
765 gadget->a_alt_hnp_support);
766 n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n",
767 (gadget->name ? gadget->name : ""));
768
769 return n;
770}
771static DEVICE_ATTR(device, S_IRUSR, show_device, NULL);
772
773/**
774 * show_driver: prints information about attached gadget (if any)
775 *
776 * Check "device.h" for details
777 */
778static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
779 char *buf)
780{
781 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
782 struct usb_gadget_driver *driver = udc->driver;
783 int n = 0;
784
785 dbg_trace("[%s] %p\n", __func__, buf);
786 if (attr == NULL || buf == NULL) {
787 dev_err(dev, "[%s] EINVAL\n", __func__);
788 return 0;
789 }
790
791 if (driver == NULL)
792 return scnprintf(buf, PAGE_SIZE,
793 "There is no gadget attached!\n");
794
795 n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n",
796 (driver->function ? driver->function : ""));
797 n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n",
798 driver->speed);
799
800 return n;
801}
802static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);
803
804/* Maximum event message length */
805#define DBG_DATA_MSG 64UL
806
807/* Maximum event messages */
808#define DBG_DATA_MAX 128UL
809
810/* Event buffer descriptor */
811static struct {
812 char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
813 unsigned idx; /* index */
814 unsigned tty; /* print to console? */
815 rwlock_t lck; /* lock */
816} dbg_data = {
817 .idx = 0,
818 .tty = 0,
819 .lck = __RW_LOCK_UNLOCKED(lck)
820};
821
822/**
823 * dbg_dec: decrements debug event index
824 * @idx: buffer index
825 */
826static void dbg_dec(unsigned *idx)
827{
828 *idx = (*idx - 1) & (DBG_DATA_MAX-1);
829}
830
831/**
832 * dbg_inc: increments debug event index
833 * @idx: buffer index
834 */
835static void dbg_inc(unsigned *idx)
836{
837 *idx = (*idx + 1) & (DBG_DATA_MAX-1);
838}
839
840/**
841 * dbg_print: prints the common part of the event
842 * @addr: endpoint address
843 * @name: event name
844 * @status: status
845 * @extra: extra information
846 */
847static void dbg_print(u8 addr, const char *name, int status, const char *extra)
848{
849 struct timeval tval;
850 unsigned int stamp;
851 unsigned long flags;
852
853 write_lock_irqsave(&dbg_data.lck, flags);
854
855 do_gettimeofday(&tval);
856 stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s */
857 stamp = stamp * 1000000 + tval.tv_usec;
858
859 scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
860 "%04X\t» %02X %-7.7s %4i «\t%s\n",
861 stamp, addr, name, status, extra);
862
863 dbg_inc(&dbg_data.idx);
864
865 write_unlock_irqrestore(&dbg_data.lck, flags);
866
867 if (dbg_data.tty != 0)
868 pr_notice("%04X\t» %02X %-7.7s %4i «\t%s\n",
869 stamp, addr, name, status, extra);
870}
871
872/**
873 * dbg_done: prints a DONE event
874 * @addr: endpoint address
875 * @td: transfer descriptor
876 * @status: status
877 */
878static void dbg_done(u8 addr, const u32 token, int status)
879{
880 char msg[DBG_DATA_MSG];
881
882 scnprintf(msg, sizeof(msg), "%d %02X",
883 (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES),
884 (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS));
885 dbg_print(addr, "DONE", status, msg);
886}
887
888/**
889 * dbg_event: prints a generic event
890 * @addr: endpoint address
891 * @name: event name
892 * @status: status
893 */
894static void dbg_event(u8 addr, const char *name, int status)
895{
896 if (name != NULL)
897 dbg_print(addr, name, status, "");
898}
899
900/*
901 * dbg_queue: prints a QUEUE event
902 * @addr: endpoint address
903 * @req: USB request
904 * @status: status
905 */
906static void dbg_queue(u8 addr, const struct usb_request *req, int status)
907{
908 char msg[DBG_DATA_MSG];
909
910 if (req != NULL) {
911 scnprintf(msg, sizeof(msg),
912 "%d %d", !req->no_interrupt, req->length);
913 dbg_print(addr, "QUEUE", status, msg);
914 }
915}
916
917/**
918 * dbg_setup: prints a SETUP event
919 * @addr: endpoint address
920 * @req: setup request
921 */
922static void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
923{
924 char msg[DBG_DATA_MSG];
925
926 if (req != NULL) {
927 scnprintf(msg, sizeof(msg),
928 "%02X %02X %04X %04X %d", req->bRequestType,
929 req->bRequest, le16_to_cpu(req->wValue),
930 le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
931 dbg_print(addr, "SETUP", 0, msg);
932 }
933}
934
935/**
936 * show_events: displays the event buffer
937 *
938 * Check "device.h" for details
939 */
940static ssize_t show_events(struct device *dev, struct device_attribute *attr,
941 char *buf)
942{
943 unsigned long flags;
944 unsigned i, j, n = 0;
945
946 dbg_trace("[%s] %p\n", __func__, buf);
947 if (attr == NULL || buf == NULL) {
948 dev_err(dev, "[%s] EINVAL\n", __func__);
949 return 0;
950 }
951
952 read_lock_irqsave(&dbg_data.lck, flags);
953
954 i = dbg_data.idx;
955 for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) {
956 n += strlen(dbg_data.buf[i]);
957 if (n >= PAGE_SIZE) {
958 n -= strlen(dbg_data.buf[i]);
959 break;
960 }
961 }
962 for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i))
963 j += scnprintf(buf + j, PAGE_SIZE - j,
964 "%s", dbg_data.buf[i]);
965
966 read_unlock_irqrestore(&dbg_data.lck, flags);
967
968 return n;
969}
970
971/**
972 * store_events: configure if events are going to be also printed to console
973 *
974 * Check "device.h" for details
975 */
976static ssize_t store_events(struct device *dev, struct device_attribute *attr,
977 const char *buf, size_t count)
978{
979 unsigned tty;
980
981 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
982 if (attr == NULL || buf == NULL) {
983 dev_err(dev, "[%s] EINVAL\n", __func__);
984 goto done;
985 }
986
987 if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
988 dev_err(dev, "<1|0>: enable|disable console log\n");
989 goto done;
990 }
991
992 dbg_data.tty = tty;
993 dev_info(dev, "tty = %u", dbg_data.tty);
994
995 done:
996 return count;
997}
998static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events);
999
1000/**
1001 * show_inters: interrupt status, enable status and historic
1002 *
1003 * Check "device.h" for details
1004 */
1005static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
1006 char *buf)
1007{
1008 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1009 unsigned long flags;
1010 u32 intr;
1011 unsigned i, j, n = 0;
1012
1013 dbg_trace("[%s] %p\n", __func__, buf);
1014 if (attr == NULL || buf == NULL) {
1015 dev_err(dev, "[%s] EINVAL\n", __func__);
1016 return 0;
1017 }
1018
1019 spin_lock_irqsave(udc->lock, flags);
1020
1021 n += scnprintf(buf + n, PAGE_SIZE - n,
1022 "status = %08x\n", hw_read_intr_status());
1023 n += scnprintf(buf + n, PAGE_SIZE - n,
1024 "enable = %08x\n", hw_read_intr_enable());
1025
1026 n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
1027 isr_statistics.test);
1028 n += scnprintf(buf + n, PAGE_SIZE - n, "» ui = %d\n",
1029 isr_statistics.ui);
1030 n += scnprintf(buf + n, PAGE_SIZE - n, "» uei = %d\n",
1031 isr_statistics.uei);
1032 n += scnprintf(buf + n, PAGE_SIZE - n, "» pci = %d\n",
1033 isr_statistics.pci);
1034 n += scnprintf(buf + n, PAGE_SIZE - n, "» uri = %d\n",
1035 isr_statistics.uri);
1036 n += scnprintf(buf + n, PAGE_SIZE - n, "» sli = %d\n",
1037 isr_statistics.sli);
1038 n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
1039 isr_statistics.none);
1040 n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n",
1041 isr_statistics.hndl.cnt);
1042
1043 for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) {
1044 i &= ISR_MASK;
1045 intr = isr_statistics.hndl.buf[i];
1046
1047 if (USBi_UI & intr)
1048 n += scnprintf(buf + n, PAGE_SIZE - n, "ui ");
1049 intr &= ~USBi_UI;
1050 if (USBi_UEI & intr)
1051 n += scnprintf(buf + n, PAGE_SIZE - n, "uei ");
1052 intr &= ~USBi_UEI;
1053 if (USBi_PCI & intr)
1054 n += scnprintf(buf + n, PAGE_SIZE - n, "pci ");
1055 intr &= ~USBi_PCI;
1056 if (USBi_URI & intr)
1057 n += scnprintf(buf + n, PAGE_SIZE - n, "uri ");
1058 intr &= ~USBi_URI;
1059 if (USBi_SLI & intr)
1060 n += scnprintf(buf + n, PAGE_SIZE - n, "sli ");
1061 intr &= ~USBi_SLI;
1062 if (intr)
1063 n += scnprintf(buf + n, PAGE_SIZE - n, "??? ");
1064 if (isr_statistics.hndl.buf[i])
1065 n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
1066 }
1067
1068 spin_unlock_irqrestore(udc->lock, flags);
1069
1070 return n;
1071}
1072
1073/**
1074 * store_inters: enable & force or disable an individual interrutps
1075 * (to be used for test purposes only)
1076 *
1077 * Check "device.h" for details
1078 */
1079static ssize_t store_inters(struct device *dev, struct device_attribute *attr,
1080 const char *buf, size_t count)
1081{
1082 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1083 unsigned long flags;
1084 unsigned en, bit;
1085
1086 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1087 if (attr == NULL || buf == NULL) {
1088 dev_err(dev, "[%s] EINVAL\n", __func__);
1089 goto done;
1090 }
1091
1092 if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) {
1093 dev_err(dev, "<1|0> <bit>: enable|disable interrupt");
1094 goto done;
1095 }
1096
1097 spin_lock_irqsave(udc->lock, flags);
1098 if (en) {
1099 if (hw_intr_force(bit))
1100 dev_err(dev, "invalid bit number\n");
1101 else
1102 isr_statistics.test++;
1103 } else {
1104 if (hw_intr_clear(bit))
1105 dev_err(dev, "invalid bit number\n");
1106 }
1107 spin_unlock_irqrestore(udc->lock, flags);
1108
1109 done:
1110 return count;
1111}
1112static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters);
1113
1114/**
1115 * show_port_test: reads port test mode
1116 *
1117 * Check "device.h" for details
1118 */
1119static ssize_t show_port_test(struct device *dev,
1120 struct device_attribute *attr, char *buf)
1121{
1122 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1123 unsigned long flags;
1124 unsigned mode;
1125
1126 dbg_trace("[%s] %p\n", __func__, buf);
1127 if (attr == NULL || buf == NULL) {
1128 dev_err(dev, "[%s] EINVAL\n", __func__);
1129 return 0;
1130 }
1131
1132 spin_lock_irqsave(udc->lock, flags);
1133 mode = hw_port_test_get();
1134 spin_unlock_irqrestore(udc->lock, flags);
1135
1136 return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode);
1137}
1138
1139/**
1140 * store_port_test: writes port test mode
1141 *
1142 * Check "device.h" for details
1143 */
1144static ssize_t store_port_test(struct device *dev,
1145 struct device_attribute *attr,
1146 const char *buf, size_t count)
1147{
1148 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1149 unsigned long flags;
1150 unsigned mode;
1151
1152 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1153 if (attr == NULL || buf == NULL) {
1154 dev_err(dev, "[%s] EINVAL\n", __func__);
1155 goto done;
1156 }
1157
1158 if (sscanf(buf, "%u", &mode) != 1) {
1159 dev_err(dev, "<mode>: set port test mode");
1160 goto done;
1161 }
1162
1163 spin_lock_irqsave(udc->lock, flags);
1164 if (hw_port_test_set(mode))
1165 dev_err(dev, "invalid mode\n");
1166 spin_unlock_irqrestore(udc->lock, flags);
1167
1168 done:
1169 return count;
1170}
1171static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR,
1172 show_port_test, store_port_test);
1173
1174/**
1175 * show_qheads: DMA contents of all queue heads
1176 *
1177 * Check "device.h" for details
1178 */
1179static ssize_t show_qheads(struct device *dev, struct device_attribute *attr,
1180 char *buf)
1181{
1182 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1183 unsigned long flags;
1184 unsigned i, j, n = 0;
1185
1186 dbg_trace("[%s] %p\n", __func__, buf);
1187 if (attr == NULL || buf == NULL) {
1188 dev_err(dev, "[%s] EINVAL\n", __func__);
1189 return 0;
1190 }
1191
1192 spin_lock_irqsave(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301193 for (i = 0; i < hw_ep_max/2; i++) {
1194 struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i];
1195 struct ci13xxx_ep *mEpTx = &udc->ci13xxx_ep[i + hw_ep_max/2];
David Lopoaa69a802008-11-17 14:14:51 -08001196 n += scnprintf(buf + n, PAGE_SIZE - n,
1197 "EP=%02i: RX=%08X TX=%08X\n",
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301198 i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08001199 for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) {
1200 n += scnprintf(buf + n, PAGE_SIZE - n,
1201 " %04X: %08X %08X\n", j,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301202 *((u32 *)mEpRx->qh.ptr + j),
1203 *((u32 *)mEpTx->qh.ptr + j));
David Lopoaa69a802008-11-17 14:14:51 -08001204 }
1205 }
1206 spin_unlock_irqrestore(udc->lock, flags);
1207
1208 return n;
1209}
1210static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL);
1211
1212/**
1213 * show_registers: dumps all registers
1214 *
1215 * Check "device.h" for details
1216 */
1217static ssize_t show_registers(struct device *dev,
1218 struct device_attribute *attr, char *buf)
1219{
1220 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1221 unsigned long flags;
1222 u32 dump[512];
1223 unsigned i, k, n = 0;
1224
1225 dbg_trace("[%s] %p\n", __func__, buf);
1226 if (attr == NULL || buf == NULL) {
1227 dev_err(dev, "[%s] EINVAL\n", __func__);
1228 return 0;
1229 }
1230
1231 spin_lock_irqsave(udc->lock, flags);
1232 k = hw_register_read(dump, sizeof(dump)/sizeof(u32));
1233 spin_unlock_irqrestore(udc->lock, flags);
1234
1235 for (i = 0; i < k; i++) {
1236 n += scnprintf(buf + n, PAGE_SIZE - n,
1237 "reg[0x%04X] = 0x%08X\n",
1238 i * (unsigned)sizeof(u32), dump[i]);
1239 }
1240
1241 return n;
1242}
1243
1244/**
1245 * store_registers: writes value to register address
1246 *
1247 * Check "device.h" for details
1248 */
1249static ssize_t store_registers(struct device *dev,
1250 struct device_attribute *attr,
1251 const char *buf, size_t count)
1252{
1253 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1254 unsigned long addr, data, flags;
1255
1256 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1257 if (attr == NULL || buf == NULL) {
1258 dev_err(dev, "[%s] EINVAL\n", __func__);
1259 goto done;
1260 }
1261
1262 if (sscanf(buf, "%li %li", &addr, &data) != 2) {
1263 dev_err(dev, "<addr> <data>: write data to register address");
1264 goto done;
1265 }
1266
1267 spin_lock_irqsave(udc->lock, flags);
1268 if (hw_register_write(addr, data))
1269 dev_err(dev, "invalid address range\n");
1270 spin_unlock_irqrestore(udc->lock, flags);
1271
1272 done:
1273 return count;
1274}
1275static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR,
1276 show_registers, store_registers);
1277
1278/**
1279 * show_requests: DMA contents of all requests currently queued (all endpts)
1280 *
1281 * Check "device.h" for details
1282 */
1283static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
1284 char *buf)
1285{
1286 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1287 unsigned long flags;
1288 struct list_head *ptr = NULL;
1289 struct ci13xxx_req *req = NULL;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301290 unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -08001291
1292 dbg_trace("[%s] %p\n", __func__, buf);
1293 if (attr == NULL || buf == NULL) {
1294 dev_err(dev, "[%s] EINVAL\n", __func__);
1295 return 0;
1296 }
1297
1298 spin_lock_irqsave(udc->lock, flags);
1299 for (i = 0; i < hw_ep_max; i++)
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301300 list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue)
1301 {
1302 req = list_entry(ptr, struct ci13xxx_req, queue);
David Lopoaa69a802008-11-17 14:14:51 -08001303
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301304 n += scnprintf(buf + n, PAGE_SIZE - n,
1305 "EP=%02i: TD=%08X %s\n",
1306 i % hw_ep_max/2, (u32)req->dma,
1307 ((i < hw_ep_max/2) ? "RX" : "TX"));
1308
1309 for (j = 0; j < qSize; j++)
David Lopoaa69a802008-11-17 14:14:51 -08001310 n += scnprintf(buf + n, PAGE_SIZE - n,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301311 " %04X: %08X\n", j,
1312 *((u32 *)req->ptr + j));
1313 }
David Lopoaa69a802008-11-17 14:14:51 -08001314 spin_unlock_irqrestore(udc->lock, flags);
1315
1316 return n;
1317}
1318static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL);
1319
1320/**
1321 * dbg_create_files: initializes the attribute interface
1322 * @dev: device
1323 *
1324 * This function returns an error code
1325 */
1326__maybe_unused static int dbg_create_files(struct device *dev)
1327{
1328 int retval = 0;
1329
1330 if (dev == NULL)
1331 return -EINVAL;
1332 retval = device_create_file(dev, &dev_attr_device);
1333 if (retval)
1334 goto done;
1335 retval = device_create_file(dev, &dev_attr_driver);
1336 if (retval)
1337 goto rm_device;
1338 retval = device_create_file(dev, &dev_attr_events);
1339 if (retval)
1340 goto rm_driver;
1341 retval = device_create_file(dev, &dev_attr_inters);
1342 if (retval)
1343 goto rm_events;
1344 retval = device_create_file(dev, &dev_attr_port_test);
1345 if (retval)
1346 goto rm_inters;
1347 retval = device_create_file(dev, &dev_attr_qheads);
1348 if (retval)
1349 goto rm_port_test;
1350 retval = device_create_file(dev, &dev_attr_registers);
1351 if (retval)
1352 goto rm_qheads;
1353 retval = device_create_file(dev, &dev_attr_requests);
1354 if (retval)
1355 goto rm_registers;
1356 return 0;
1357
1358 rm_registers:
1359 device_remove_file(dev, &dev_attr_registers);
1360 rm_qheads:
1361 device_remove_file(dev, &dev_attr_qheads);
1362 rm_port_test:
1363 device_remove_file(dev, &dev_attr_port_test);
1364 rm_inters:
1365 device_remove_file(dev, &dev_attr_inters);
1366 rm_events:
1367 device_remove_file(dev, &dev_attr_events);
1368 rm_driver:
1369 device_remove_file(dev, &dev_attr_driver);
1370 rm_device:
1371 device_remove_file(dev, &dev_attr_device);
1372 done:
1373 return retval;
1374}
1375
1376/**
1377 * dbg_remove_files: destroys the attribute interface
1378 * @dev: device
1379 *
1380 * This function returns an error code
1381 */
1382__maybe_unused static int dbg_remove_files(struct device *dev)
1383{
1384 if (dev == NULL)
1385 return -EINVAL;
1386 device_remove_file(dev, &dev_attr_requests);
1387 device_remove_file(dev, &dev_attr_registers);
1388 device_remove_file(dev, &dev_attr_qheads);
1389 device_remove_file(dev, &dev_attr_port_test);
1390 device_remove_file(dev, &dev_attr_inters);
1391 device_remove_file(dev, &dev_attr_events);
1392 device_remove_file(dev, &dev_attr_driver);
1393 device_remove_file(dev, &dev_attr_device);
1394 return 0;
1395}
1396
1397/******************************************************************************
1398 * UTIL block
1399 *****************************************************************************/
1400/**
1401 * _usb_addr: calculates endpoint address from direction & number
1402 * @ep: endpoint
1403 */
1404static inline u8 _usb_addr(struct ci13xxx_ep *ep)
1405{
1406 return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num;
1407}
1408
1409/**
1410 * _hardware_queue: configures a request at hardware level
1411 * @gadget: gadget
1412 * @mEp: endpoint
1413 *
1414 * This function returns an error code
1415 */
1416static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1417{
1418 unsigned i;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301419 int ret = 0;
1420 unsigned length = mReq->req.length;
David Lopoaa69a802008-11-17 14:14:51 -08001421
1422 trace("%p, %p", mEp, mReq);
1423
1424 /* don't queue twice */
1425 if (mReq->req.status == -EALREADY)
1426 return -EALREADY;
1427
David Lopoaa69a802008-11-17 14:14:51 -08001428 mReq->req.status = -EALREADY;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301429 if (length && !mReq->req.dma) {
David Lopoaa69a802008-11-17 14:14:51 -08001430 mReq->req.dma = \
1431 dma_map_single(mEp->device, mReq->req.buf,
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301432 length, mEp->dir ? DMA_TO_DEVICE :
1433 DMA_FROM_DEVICE);
David Lopoaa69a802008-11-17 14:14:51 -08001434 if (mReq->req.dma == 0)
1435 return -ENOMEM;
1436
1437 mReq->map = 1;
1438 }
1439
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301440 if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) {
1441 mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC,
1442 &mReq->zdma);
1443 if (mReq->zptr == NULL) {
1444 if (mReq->map) {
1445 dma_unmap_single(mEp->device, mReq->req.dma,
1446 length, mEp->dir ? DMA_TO_DEVICE :
1447 DMA_FROM_DEVICE);
1448 mReq->req.dma = 0;
1449 mReq->map = 0;
1450 }
1451 return -ENOMEM;
1452 }
1453 memset(mReq->zptr, 0, sizeof(*mReq->zptr));
1454 mReq->zptr->next = TD_TERMINATE;
1455 mReq->zptr->token = TD_STATUS_ACTIVE;
1456 if (!mReq->req.no_interrupt)
1457 mReq->zptr->token |= TD_IOC;
1458 }
David Lopoaa69a802008-11-17 14:14:51 -08001459 /*
1460 * TD configuration
1461 * TODO - handle requests which spawns into several TDs
1462 */
1463 memset(mReq->ptr, 0, sizeof(*mReq->ptr));
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301464 mReq->ptr->token = length << ffs_nr(TD_TOTAL_BYTES);
David Lopoaa69a802008-11-17 14:14:51 -08001465 mReq->ptr->token &= TD_TOTAL_BYTES;
David Lopoaa69a802008-11-17 14:14:51 -08001466 mReq->ptr->token |= TD_STATUS_ACTIVE;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301467 if (mReq->zptr) {
1468 mReq->ptr->next = mReq->zdma;
1469 } else {
1470 mReq->ptr->next = TD_TERMINATE;
1471 if (!mReq->req.no_interrupt)
1472 mReq->ptr->token |= TD_IOC;
1473 }
David Lopoaa69a802008-11-17 14:14:51 -08001474 mReq->ptr->page[0] = mReq->req.dma;
1475 for (i = 1; i < 5; i++)
1476 mReq->ptr->page[i] =
Artem Leonenko0a313c42010-12-14 23:47:06 -08001477 (mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
David Lopoaa69a802008-11-17 14:14:51 -08001478
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301479 if (!list_empty(&mEp->qh.queue)) {
1480 struct ci13xxx_req *mReqPrev;
1481 int n = hw_ep_bit(mEp->num, mEp->dir);
1482 int tmp_stat;
1483
1484 mReqPrev = list_entry(mEp->qh.queue.prev,
1485 struct ci13xxx_req, queue);
1486 if (mReqPrev->zptr)
1487 mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK;
1488 else
1489 mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK;
1490 wmb();
1491 if (hw_cread(CAP_ENDPTPRIME, BIT(n)))
1492 goto done;
1493 do {
1494 hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
1495 tmp_stat = hw_cread(CAP_ENDPTSTAT, BIT(n));
1496 } while (!hw_cread(CAP_USBCMD, USBCMD_ATDTW));
1497 hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, 0);
1498 if (tmp_stat)
1499 goto done;
1500 }
1501
1502 /* QH configuration */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301503 mEp->qh.ptr->td.next = mReq->dma; /* TERMINATE = 0 */
1504 mEp->qh.ptr->td.token &= ~TD_STATUS; /* clear status */
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301505 mEp->qh.ptr->cap |= QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08001506
1507 wmb(); /* synchronize before ep prime */
1508
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301509 ret = hw_ep_prime(mEp->num, mEp->dir,
David Lopoaa69a802008-11-17 14:14:51 -08001510 mEp->type == USB_ENDPOINT_XFER_CONTROL);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301511done:
1512 return ret;
David Lopoaa69a802008-11-17 14:14:51 -08001513}
1514
1515/**
1516 * _hardware_dequeue: handles a request at hardware level
1517 * @gadget: gadget
1518 * @mEp: endpoint
1519 *
1520 * This function returns an error code
1521 */
1522static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1523{
1524 trace("%p, %p", mEp, mReq);
1525
1526 if (mReq->req.status != -EALREADY)
1527 return -EINVAL;
1528
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301529 if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0)
1530 return -EBUSY;
1531
1532 if (mReq->zptr) {
1533 if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
1534 return -EBUSY;
1535 dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
1536 mReq->zptr = NULL;
1537 }
David Lopoaa69a802008-11-17 14:14:51 -08001538
1539 mReq->req.status = 0;
1540
1541 if (mReq->map) {
1542 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
1543 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
1544 mReq->req.dma = 0;
1545 mReq->map = 0;
1546 }
1547
1548 mReq->req.status = mReq->ptr->token & TD_STATUS;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301549 if ((TD_STATUS_HALTED & mReq->req.status) != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001550 mReq->req.status = -1;
1551 else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0)
1552 mReq->req.status = -1;
1553 else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0)
1554 mReq->req.status = -1;
1555
1556 mReq->req.actual = mReq->ptr->token & TD_TOTAL_BYTES;
1557 mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES);
1558 mReq->req.actual = mReq->req.length - mReq->req.actual;
1559 mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual;
1560
1561 return mReq->req.actual;
1562}
1563
1564/**
1565 * _ep_nuke: dequeues all endpoint requests
1566 * @mEp: endpoint
1567 *
1568 * This function returns an error code
1569 * Caller must hold lock
1570 */
1571static int _ep_nuke(struct ci13xxx_ep *mEp)
1572__releases(mEp->lock)
1573__acquires(mEp->lock)
1574{
1575 trace("%p", mEp);
1576
1577 if (mEp == NULL)
1578 return -EINVAL;
1579
1580 hw_ep_flush(mEp->num, mEp->dir);
1581
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301582 while (!list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08001583
1584 /* pop oldest request */
1585 struct ci13xxx_req *mReq = \
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301586 list_entry(mEp->qh.queue.next,
David Lopoaa69a802008-11-17 14:14:51 -08001587 struct ci13xxx_req, queue);
1588 list_del_init(&mReq->queue);
1589 mReq->req.status = -ESHUTDOWN;
1590
Artem Leonenko7c25a822010-12-14 23:46:55 -08001591 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08001592 spin_unlock(mEp->lock);
1593 mReq->req.complete(&mEp->ep, &mReq->req);
1594 spin_lock(mEp->lock);
1595 }
1596 }
1597 return 0;
1598}
1599
1600/**
1601 * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
1602 * @gadget: gadget
1603 *
1604 * This function returns an error code
1605 * Caller must hold lock
1606 */
1607static int _gadget_stop_activity(struct usb_gadget *gadget)
David Lopoaa69a802008-11-17 14:14:51 -08001608{
1609 struct usb_ep *ep;
1610 struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301611 unsigned long flags;
David Lopoaa69a802008-11-17 14:14:51 -08001612
1613 trace("%p", gadget);
1614
1615 if (gadget == NULL)
1616 return -EINVAL;
1617
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301618 spin_lock_irqsave(udc->lock, flags);
1619 udc->gadget.speed = USB_SPEED_UNKNOWN;
1620 udc->remote_wakeup = 0;
1621 udc->suspended = 0;
1622 spin_unlock_irqrestore(udc->lock, flags);
1623
David Lopoaa69a802008-11-17 14:14:51 -08001624 /* flush all endpoints */
1625 gadget_for_each_ep(ep, gadget) {
1626 usb_ep_fifo_flush(ep);
1627 }
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301628 usb_ep_fifo_flush(&udc->ep0out.ep);
1629 usb_ep_fifo_flush(&udc->ep0in.ep);
David Lopoaa69a802008-11-17 14:14:51 -08001630
1631 udc->driver->disconnect(gadget);
1632
1633 /* make sure to disable all endpoints */
1634 gadget_for_each_ep(ep, gadget) {
1635 usb_ep_disable(ep);
1636 }
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301637 usb_ep_disable(&udc->ep0out.ep);
1638 usb_ep_disable(&udc->ep0in.ep);
David Lopoaa69a802008-11-17 14:14:51 -08001639
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301640 if (udc->status != NULL) {
1641 usb_ep_free_request(&udc->ep0in.ep, udc->status);
1642 udc->status = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08001643 }
1644
David Lopoaa69a802008-11-17 14:14:51 -08001645 return 0;
1646}
1647
1648/******************************************************************************
1649 * ISR block
1650 *****************************************************************************/
1651/**
1652 * isr_reset_handler: USB reset interrupt handler
1653 * @udc: UDC device
1654 *
1655 * This function resets USB engine after a bus reset occurred
1656 */
1657static void isr_reset_handler(struct ci13xxx *udc)
1658__releases(udc->lock)
1659__acquires(udc->lock)
1660{
David Lopoaa69a802008-11-17 14:14:51 -08001661 int retval;
1662
1663 trace("%p", udc);
1664
1665 if (udc == NULL) {
1666 err("EINVAL");
1667 return;
1668 }
1669
1670 dbg_event(0xFF, "BUS RST", 0);
1671
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05301672 spin_unlock(udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001673 retval = _gadget_stop_activity(&udc->gadget);
1674 if (retval)
1675 goto done;
1676
1677 retval = hw_usb_reset();
1678 if (retval)
1679 goto done;
1680
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301681 retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc);
1682 if (retval)
1683 goto done;
1684
1685 retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc);
David Lopoaa69a802008-11-17 14:14:51 -08001686 if (!retval) {
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301687 udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC);
1688 if (udc->status == NULL) {
1689 usb_ep_disable(&udc->ep0out.ep);
David Lopoaa69a802008-11-17 14:14:51 -08001690 retval = -ENOMEM;
1691 }
1692 }
1693 spin_lock(udc->lock);
1694
1695 done:
1696 if (retval)
1697 err("error: %i", retval);
1698}
1699
1700/**
1701 * isr_get_status_complete: get_status request complete function
1702 * @ep: endpoint
1703 * @req: request handled
1704 *
1705 * Caller must release lock
1706 */
1707static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
1708{
1709 trace("%p, %p", ep, req);
1710
1711 if (ep == NULL || req == NULL) {
1712 err("EINVAL");
1713 return;
1714 }
1715
1716 kfree(req->buf);
1717 usb_ep_free_request(ep, req);
1718}
1719
1720/**
1721 * isr_get_status_response: get_status request response
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301722 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001723 * @setup: setup request packet
1724 *
1725 * This function returns an error code
1726 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301727static int isr_get_status_response(struct ci13xxx *udc,
David Lopoaa69a802008-11-17 14:14:51 -08001728 struct usb_ctrlrequest *setup)
1729__releases(mEp->lock)
1730__acquires(mEp->lock)
1731{
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301732 struct ci13xxx_ep *mEp = &udc->ep0in;
David Lopoaa69a802008-11-17 14:14:51 -08001733 struct usb_request *req = NULL;
1734 gfp_t gfp_flags = GFP_ATOMIC;
1735 int dir, num, retval;
1736
1737 trace("%p, %p", mEp, setup);
1738
1739 if (mEp == NULL || setup == NULL)
1740 return -EINVAL;
1741
1742 spin_unlock(mEp->lock);
1743 req = usb_ep_alloc_request(&mEp->ep, gfp_flags);
1744 spin_lock(mEp->lock);
1745 if (req == NULL)
1746 return -ENOMEM;
1747
1748 req->complete = isr_get_status_complete;
1749 req->length = 2;
1750 req->buf = kzalloc(req->length, gfp_flags);
1751 if (req->buf == NULL) {
1752 retval = -ENOMEM;
1753 goto err_free_req;
1754 }
1755
1756 if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301757 /* Assume that device is bus powered for now. */
1758 *((u16 *)req->buf) = _udc->remote_wakeup << 1;
David Lopoaa69a802008-11-17 14:14:51 -08001759 retval = 0;
1760 } else if ((setup->bRequestType & USB_RECIP_MASK) \
1761 == USB_RECIP_ENDPOINT) {
1762 dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ?
1763 TX : RX;
1764 num = le16_to_cpu(setup->wIndex) & USB_ENDPOINT_NUMBER_MASK;
1765 *((u16 *)req->buf) = hw_ep_get_halt(num, dir);
1766 }
1767 /* else do nothing; reserved for future use */
1768
1769 spin_unlock(mEp->lock);
1770 retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
1771 spin_lock(mEp->lock);
1772 if (retval)
1773 goto err_free_buf;
1774
1775 return 0;
1776
1777 err_free_buf:
1778 kfree(req->buf);
1779 err_free_req:
1780 spin_unlock(mEp->lock);
1781 usb_ep_free_request(&mEp->ep, req);
1782 spin_lock(mEp->lock);
1783 return retval;
1784}
1785
1786/**
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301787 * isr_setup_status_complete: setup_status request complete function
1788 * @ep: endpoint
1789 * @req: request handled
1790 *
1791 * Caller must release lock. Put the port in test mode if test mode
1792 * feature is selected.
1793 */
1794static void
1795isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
1796{
1797 struct ci13xxx *udc = req->context;
1798 unsigned long flags;
1799
1800 trace("%p, %p", ep, req);
1801
1802 spin_lock_irqsave(udc->lock, flags);
1803 if (udc->test_mode)
1804 hw_port_test_set(udc->test_mode);
1805 spin_unlock_irqrestore(udc->lock, flags);
1806}
1807
1808/**
David Lopoaa69a802008-11-17 14:14:51 -08001809 * isr_setup_status_phase: queues the status phase of a setup transation
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301810 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001811 *
1812 * This function returns an error code
1813 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301814static int isr_setup_status_phase(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -08001815__releases(mEp->lock)
1816__acquires(mEp->lock)
1817{
1818 int retval;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301819 struct ci13xxx_ep *mEp;
David Lopoaa69a802008-11-17 14:14:51 -08001820
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301821 trace("%p", udc);
David Lopoaa69a802008-11-17 14:14:51 -08001822
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301823 mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301824 udc->status->context = udc;
1825 udc->status->complete = isr_setup_status_complete;
David Lopoaa69a802008-11-17 14:14:51 -08001826
1827 spin_unlock(mEp->lock);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301828 retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
David Lopoaa69a802008-11-17 14:14:51 -08001829 spin_lock(mEp->lock);
1830
1831 return retval;
1832}
1833
1834/**
1835 * isr_tr_complete_low: transaction complete low level handler
1836 * @mEp: endpoint
1837 *
1838 * This function returns an error code
1839 * Caller must hold lock
1840 */
1841static int isr_tr_complete_low(struct ci13xxx_ep *mEp)
1842__releases(mEp->lock)
1843__acquires(mEp->lock)
1844{
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301845 struct ci13xxx_req *mReq, *mReqTemp;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301846 struct ci13xxx_ep *mEpTemp = mEp;
Pavankumar Kondeti986b11b2011-05-02 11:56:29 +05301847 int uninitialized_var(retval);
David Lopoaa69a802008-11-17 14:14:51 -08001848
1849 trace("%p", mEp);
1850
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301851 if (list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08001852 return -EINVAL;
1853
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301854 list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue,
1855 queue) {
1856 retval = _hardware_dequeue(mEp, mReq);
1857 if (retval < 0)
1858 break;
1859 list_del_init(&mReq->queue);
1860 dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
1861 if (mReq->req.complete != NULL) {
1862 spin_unlock(mEp->lock);
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301863 if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
1864 mReq->req.length)
1865 mEpTemp = &_udc->ep0in;
1866 mReq->req.complete(&mEpTemp->ep, &mReq->req);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301867 spin_lock(mEp->lock);
1868 }
1869 }
David Lopoaa69a802008-11-17 14:14:51 -08001870
Pavankumar Kondetief907482011-05-02 11:56:27 +05301871 if (retval == -EBUSY)
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301872 retval = 0;
1873 if (retval < 0)
David Lopoaa69a802008-11-17 14:14:51 -08001874 dbg_event(_usb_addr(mEp), "DONE", retval);
David Lopoaa69a802008-11-17 14:14:51 -08001875
David Lopoaa69a802008-11-17 14:14:51 -08001876 return retval;
1877}
1878
1879/**
1880 * isr_tr_complete_handler: transaction complete interrupt handler
1881 * @udc: UDC descriptor
1882 *
1883 * This function handles traffic events
1884 */
1885static void isr_tr_complete_handler(struct ci13xxx *udc)
1886__releases(udc->lock)
1887__acquires(udc->lock)
1888{
1889 unsigned i;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301890 u8 tmode = 0;
David Lopoaa69a802008-11-17 14:14:51 -08001891
1892 trace("%p", udc);
1893
1894 if (udc == NULL) {
1895 err("EINVAL");
1896 return;
1897 }
1898
1899 for (i = 0; i < hw_ep_max; i++) {
1900 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301901 int type, num, dir, err = -EINVAL;
David Lopoaa69a802008-11-17 14:14:51 -08001902 struct usb_ctrlrequest req;
1903
David Lopoaa69a802008-11-17 14:14:51 -08001904 if (mEp->desc == NULL)
1905 continue; /* not configured */
1906
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301907 if (hw_test_and_clear_complete(i)) {
David Lopoaa69a802008-11-17 14:14:51 -08001908 err = isr_tr_complete_low(mEp);
1909 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
1910 if (err > 0) /* needs status phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301911 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08001912 if (err < 0) {
1913 dbg_event(_usb_addr(mEp),
1914 "ERROR", err);
1915 spin_unlock(udc->lock);
1916 if (usb_ep_set_halt(&mEp->ep))
1917 err("error: ep_set_halt");
1918 spin_lock(udc->lock);
1919 }
1920 }
1921 }
1922
1923 if (mEp->type != USB_ENDPOINT_XFER_CONTROL ||
1924 !hw_test_and_clear_setup_status(i))
1925 continue;
1926
1927 if (i != 0) {
1928 warn("ctrl traffic received at endpoint");
1929 continue;
1930 }
1931
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301932 /*
1933 * Flush data and handshake transactions of previous
1934 * setup packet.
1935 */
1936 _ep_nuke(&udc->ep0out);
1937 _ep_nuke(&udc->ep0in);
1938
David Lopoaa69a802008-11-17 14:14:51 -08001939 /* read_setup_packet */
1940 do {
1941 hw_test_and_set_setup_guard();
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301942 memcpy(&req, &mEp->qh.ptr->setup, sizeof(req));
David Lopoaa69a802008-11-17 14:14:51 -08001943 } while (!hw_test_and_clear_setup_guard());
1944
1945 type = req.bRequestType;
1946
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301947 udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX;
David Lopoaa69a802008-11-17 14:14:51 -08001948
1949 dbg_setup(_usb_addr(mEp), &req);
1950
1951 switch (req.bRequest) {
1952 case USB_REQ_CLEAR_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301953 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
1954 le16_to_cpu(req.wValue) ==
1955 USB_ENDPOINT_HALT) {
1956 if (req.wLength != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001957 break;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301958 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301959 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301960 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301961 if (dir) /* TX */
1962 num += hw_ep_max/2;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301963 if (!udc->ci13xxx_ep[num].wedge) {
1964 spin_unlock(udc->lock);
1965 err = usb_ep_clear_halt(
1966 &udc->ci13xxx_ep[num].ep);
1967 spin_lock(udc->lock);
1968 if (err)
1969 break;
1970 }
1971 err = isr_setup_status_phase(udc);
1972 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) &&
1973 le16_to_cpu(req.wValue) ==
1974 USB_DEVICE_REMOTE_WAKEUP) {
1975 if (req.wLength != 0)
1976 break;
1977 udc->remote_wakeup = 0;
1978 err = isr_setup_status_phase(udc);
1979 } else {
1980 goto delegate;
David Lopoaa69a802008-11-17 14:14:51 -08001981 }
David Lopoaa69a802008-11-17 14:14:51 -08001982 break;
1983 case USB_REQ_GET_STATUS:
1984 if (type != (USB_DIR_IN|USB_RECIP_DEVICE) &&
1985 type != (USB_DIR_IN|USB_RECIP_ENDPOINT) &&
1986 type != (USB_DIR_IN|USB_RECIP_INTERFACE))
1987 goto delegate;
1988 if (le16_to_cpu(req.wLength) != 2 ||
1989 le16_to_cpu(req.wValue) != 0)
1990 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301991 err = isr_get_status_response(udc, &req);
David Lopoaa69a802008-11-17 14:14:51 -08001992 break;
1993 case USB_REQ_SET_ADDRESS:
1994 if (type != (USB_DIR_OUT|USB_RECIP_DEVICE))
1995 goto delegate;
1996 if (le16_to_cpu(req.wLength) != 0 ||
1997 le16_to_cpu(req.wIndex) != 0)
1998 break;
1999 err = hw_usb_set_address((u8)le16_to_cpu(req.wValue));
2000 if (err)
2001 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302002 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08002003 break;
2004 case USB_REQ_SET_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302005 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
2006 le16_to_cpu(req.wValue) ==
2007 USB_ENDPOINT_HALT) {
2008 if (req.wLength != 0)
2009 break;
2010 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302011 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302012 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302013 if (dir) /* TX */
2014 num += hw_ep_max/2;
David Lopoaa69a802008-11-17 14:14:51 -08002015
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302016 spin_unlock(udc->lock);
2017 err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep);
2018 spin_lock(udc->lock);
2019 if (!err)
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302020 isr_setup_status_phase(udc);
2021 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302022 if (req.wLength != 0)
2023 break;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302024 switch (le16_to_cpu(req.wValue)) {
2025 case USB_DEVICE_REMOTE_WAKEUP:
2026 udc->remote_wakeup = 1;
2027 err = isr_setup_status_phase(udc);
2028 break;
2029 case USB_DEVICE_TEST_MODE:
2030 tmode = le16_to_cpu(req.wIndex) >> 8;
2031 switch (tmode) {
2032 case TEST_J:
2033 case TEST_K:
2034 case TEST_SE0_NAK:
2035 case TEST_PACKET:
2036 case TEST_FORCE_EN:
2037 udc->test_mode = tmode;
2038 err = isr_setup_status_phase(
2039 udc);
2040 break;
2041 default:
2042 break;
2043 }
2044 default:
2045 goto delegate;
2046 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302047 } else {
2048 goto delegate;
2049 }
David Lopoaa69a802008-11-17 14:14:51 -08002050 break;
2051 default:
2052delegate:
2053 if (req.wLength == 0) /* no data phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302054 udc->ep0_dir = TX;
David Lopoaa69a802008-11-17 14:14:51 -08002055
2056 spin_unlock(udc->lock);
2057 err = udc->driver->setup(&udc->gadget, &req);
2058 spin_lock(udc->lock);
2059 break;
2060 }
2061
2062 if (err < 0) {
2063 dbg_event(_usb_addr(mEp), "ERROR", err);
2064
2065 spin_unlock(udc->lock);
2066 if (usb_ep_set_halt(&mEp->ep))
2067 err("error: ep_set_halt");
2068 spin_lock(udc->lock);
2069 }
2070 }
2071}
2072
2073/******************************************************************************
2074 * ENDPT block
2075 *****************************************************************************/
2076/**
2077 * ep_enable: configure endpoint, making it usable
2078 *
2079 * Check usb_ep_enable() at "usb_gadget.h" for details
2080 */
2081static int ep_enable(struct usb_ep *ep,
2082 const struct usb_endpoint_descriptor *desc)
2083{
2084 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302085 int retval = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002086 unsigned long flags;
2087
2088 trace("%p, %p", ep, desc);
2089
2090 if (ep == NULL || desc == NULL)
2091 return -EINVAL;
2092
2093 spin_lock_irqsave(mEp->lock, flags);
2094
2095 /* only internal SW should enable ctrl endpts */
2096
2097 mEp->desc = desc;
2098
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302099 if (!list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002100 warn("enabling a non-empty endpoint!");
2101
Matthias Kaehlcke15739bb2009-04-15 22:28:41 +02002102 mEp->dir = usb_endpoint_dir_in(desc) ? TX : RX;
2103 mEp->num = usb_endpoint_num(desc);
2104 mEp->type = usb_endpoint_type(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002105
2106 mEp->ep.maxpacket = __constant_le16_to_cpu(desc->wMaxPacketSize);
2107
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302108 dbg_event(_usb_addr(mEp), "ENABLE", 0);
David Lopoaa69a802008-11-17 14:14:51 -08002109
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302110 mEp->qh.ptr->cap = 0;
David Lopof23e6492009-04-16 14:35:24 -07002111
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302112 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2113 mEp->qh.ptr->cap |= QH_IOS;
2114 else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
2115 mEp->qh.ptr->cap &= ~QH_MULT;
2116 else
2117 mEp->qh.ptr->cap &= ~QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08002118
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302119 mEp->qh.ptr->cap |=
2120 (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
2121 mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */
David Lopoaa69a802008-11-17 14:14:51 -08002122
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302123 retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type);
David Lopoaa69a802008-11-17 14:14:51 -08002124
2125 spin_unlock_irqrestore(mEp->lock, flags);
2126 return retval;
2127}
2128
2129/**
2130 * ep_disable: endpoint is no longer usable
2131 *
2132 * Check usb_ep_disable() at "usb_gadget.h" for details
2133 */
2134static int ep_disable(struct usb_ep *ep)
2135{
2136 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2137 int direction, retval = 0;
2138 unsigned long flags;
2139
2140 trace("%p", ep);
2141
2142 if (ep == NULL)
2143 return -EINVAL;
2144 else if (mEp->desc == NULL)
2145 return -EBUSY;
2146
2147 spin_lock_irqsave(mEp->lock, flags);
2148
2149 /* only internal SW should disable ctrl endpts */
2150
2151 direction = mEp->dir;
2152 do {
2153 dbg_event(_usb_addr(mEp), "DISABLE", 0);
2154
2155 retval |= _ep_nuke(mEp);
2156 retval |= hw_ep_disable(mEp->num, mEp->dir);
2157
2158 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2159 mEp->dir = (mEp->dir == TX) ? RX : TX;
2160
2161 } while (mEp->dir != direction);
2162
2163 mEp->desc = NULL;
2164
2165 spin_unlock_irqrestore(mEp->lock, flags);
2166 return retval;
2167}
2168
2169/**
2170 * ep_alloc_request: allocate a request object to use with this endpoint
2171 *
2172 * Check usb_ep_alloc_request() at "usb_gadget.h" for details
2173 */
2174static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
2175{
2176 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2177 struct ci13xxx_req *mReq = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002178
2179 trace("%p, %i", ep, gfp_flags);
2180
2181 if (ep == NULL) {
2182 err("EINVAL");
2183 return NULL;
2184 }
2185
David Lopoaa69a802008-11-17 14:14:51 -08002186 mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
2187 if (mReq != NULL) {
2188 INIT_LIST_HEAD(&mReq->queue);
2189
2190 mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
2191 &mReq->dma);
2192 if (mReq->ptr == NULL) {
2193 kfree(mReq);
2194 mReq = NULL;
2195 }
2196 }
2197
2198 dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
2199
David Lopoaa69a802008-11-17 14:14:51 -08002200 return (mReq == NULL) ? NULL : &mReq->req;
2201}
2202
2203/**
2204 * ep_free_request: frees a request object
2205 *
2206 * Check usb_ep_free_request() at "usb_gadget.h" for details
2207 */
2208static void ep_free_request(struct usb_ep *ep, struct usb_request *req)
2209{
2210 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2211 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2212 unsigned long flags;
2213
2214 trace("%p, %p", ep, req);
2215
2216 if (ep == NULL || req == NULL) {
2217 err("EINVAL");
2218 return;
2219 } else if (!list_empty(&mReq->queue)) {
2220 err("EBUSY");
2221 return;
2222 }
2223
2224 spin_lock_irqsave(mEp->lock, flags);
2225
2226 if (mReq->ptr)
2227 dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma);
2228 kfree(mReq);
2229
2230 dbg_event(_usb_addr(mEp), "FREE", 0);
2231
2232 spin_unlock_irqrestore(mEp->lock, flags);
2233}
2234
2235/**
2236 * ep_queue: queues (submits) an I/O request to an endpoint
2237 *
2238 * Check usb_ep_queue()* at usb_gadget.h" for details
2239 */
2240static int ep_queue(struct usb_ep *ep, struct usb_request *req,
2241 gfp_t __maybe_unused gfp_flags)
2242{
2243 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2244 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2245 int retval = 0;
2246 unsigned long flags;
2247
2248 trace("%p, %p, %X", ep, req, gfp_flags);
2249
2250 if (ep == NULL || req == NULL || mEp->desc == NULL)
2251 return -EINVAL;
2252
2253 spin_lock_irqsave(mEp->lock, flags);
2254
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302255 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
2256 if (req->length)
2257 mEp = (_udc->ep0_dir == RX) ?
2258 &_udc->ep0out : &_udc->ep0in;
2259 if (!list_empty(&mEp->qh.queue)) {
2260 _ep_nuke(mEp);
2261 retval = -EOVERFLOW;
2262 warn("endpoint ctrl %X nuked", _usb_addr(mEp));
2263 }
David Lopoaa69a802008-11-17 14:14:51 -08002264 }
2265
2266 /* first nuke then test link, e.g. previous status has not sent */
2267 if (!list_empty(&mReq->queue)) {
2268 retval = -EBUSY;
2269 err("request already in queue");
2270 goto done;
2271 }
2272
Artem Leonenko0a313c42010-12-14 23:47:06 -08002273 if (req->length > (4 * CI13XXX_PAGE_SIZE)) {
2274 req->length = (4 * CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002275 retval = -EMSGSIZE;
2276 warn("request length truncated");
2277 }
2278
2279 dbg_queue(_usb_addr(mEp), req, retval);
2280
2281 /* push request */
2282 mReq->req.status = -EINPROGRESS;
2283 mReq->req.actual = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002284
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302285 retval = _hardware_enqueue(mEp, mReq);
Artem Leonenkod9bb9c12010-12-14 23:45:50 -08002286
2287 if (retval == -EALREADY) {
David Lopoaa69a802008-11-17 14:14:51 -08002288 dbg_event(_usb_addr(mEp), "QUEUE", retval);
2289 retval = 0;
2290 }
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302291 if (!retval)
2292 list_add_tail(&mReq->queue, &mEp->qh.queue);
David Lopoaa69a802008-11-17 14:14:51 -08002293
2294 done:
2295 spin_unlock_irqrestore(mEp->lock, flags);
2296 return retval;
2297}
2298
2299/**
2300 * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint
2301 *
2302 * Check usb_ep_dequeue() at "usb_gadget.h" for details
2303 */
2304static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
2305{
2306 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2307 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2308 unsigned long flags;
2309
2310 trace("%p, %p", ep, req);
2311
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302312 if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
2313 mEp->desc == NULL || list_empty(&mReq->queue) ||
2314 list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002315 return -EINVAL;
2316
2317 spin_lock_irqsave(mEp->lock, flags);
2318
2319 dbg_event(_usb_addr(mEp), "DEQUEUE", 0);
2320
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302321 hw_ep_flush(mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002322
2323 /* pop request */
2324 list_del_init(&mReq->queue);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302325 if (mReq->map) {
2326 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
2327 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
2328 mReq->req.dma = 0;
2329 mReq->map = 0;
2330 }
David Lopoaa69a802008-11-17 14:14:51 -08002331 req->status = -ECONNRESET;
2332
Artem Leonenko7c25a822010-12-14 23:46:55 -08002333 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08002334 spin_unlock(mEp->lock);
2335 mReq->req.complete(&mEp->ep, &mReq->req);
2336 spin_lock(mEp->lock);
2337 }
2338
2339 spin_unlock_irqrestore(mEp->lock, flags);
2340 return 0;
2341}
2342
2343/**
2344 * ep_set_halt: sets the endpoint halt feature
2345 *
2346 * Check usb_ep_set_halt() at "usb_gadget.h" for details
2347 */
2348static int ep_set_halt(struct usb_ep *ep, int value)
2349{
2350 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2351 int direction, retval = 0;
2352 unsigned long flags;
2353
2354 trace("%p, %i", ep, value);
2355
2356 if (ep == NULL || mEp->desc == NULL)
2357 return -EINVAL;
2358
2359 spin_lock_irqsave(mEp->lock, flags);
2360
2361#ifndef STALL_IN
2362 /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
2363 if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302364 !list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08002365 spin_unlock_irqrestore(mEp->lock, flags);
2366 return -EAGAIN;
2367 }
2368#endif
2369
2370 direction = mEp->dir;
2371 do {
2372 dbg_event(_usb_addr(mEp), "HALT", value);
2373 retval |= hw_ep_set_halt(mEp->num, mEp->dir, value);
2374
2375 if (!value)
2376 mEp->wedge = 0;
2377
2378 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2379 mEp->dir = (mEp->dir == TX) ? RX : TX;
2380
2381 } while (mEp->dir != direction);
2382
2383 spin_unlock_irqrestore(mEp->lock, flags);
2384 return retval;
2385}
2386
2387/**
2388 * ep_set_wedge: sets the halt feature and ignores clear requests
2389 *
2390 * Check usb_ep_set_wedge() at "usb_gadget.h" for details
2391 */
2392static int ep_set_wedge(struct usb_ep *ep)
2393{
2394 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2395 unsigned long flags;
2396
2397 trace("%p", ep);
2398
2399 if (ep == NULL || mEp->desc == NULL)
2400 return -EINVAL;
2401
2402 spin_lock_irqsave(mEp->lock, flags);
2403
2404 dbg_event(_usb_addr(mEp), "WEDGE", 0);
2405 mEp->wedge = 1;
2406
2407 spin_unlock_irqrestore(mEp->lock, flags);
2408
2409 return usb_ep_set_halt(ep);
2410}
2411
2412/**
2413 * ep_fifo_flush: flushes contents of a fifo
2414 *
2415 * Check usb_ep_fifo_flush() at "usb_gadget.h" for details
2416 */
2417static void ep_fifo_flush(struct usb_ep *ep)
2418{
2419 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2420 unsigned long flags;
2421
2422 trace("%p", ep);
2423
2424 if (ep == NULL) {
2425 err("%02X: -EINVAL", _usb_addr(mEp));
2426 return;
2427 }
2428
2429 spin_lock_irqsave(mEp->lock, flags);
2430
2431 dbg_event(_usb_addr(mEp), "FFLUSH", 0);
2432 hw_ep_flush(mEp->num, mEp->dir);
2433
2434 spin_unlock_irqrestore(mEp->lock, flags);
2435}
2436
2437/**
2438 * Endpoint-specific part of the API to the USB controller hardware
2439 * Check "usb_gadget.h" for details
2440 */
2441static const struct usb_ep_ops usb_ep_ops = {
2442 .enable = ep_enable,
2443 .disable = ep_disable,
2444 .alloc_request = ep_alloc_request,
2445 .free_request = ep_free_request,
2446 .queue = ep_queue,
2447 .dequeue = ep_dequeue,
2448 .set_halt = ep_set_halt,
2449 .set_wedge = ep_set_wedge,
2450 .fifo_flush = ep_fifo_flush,
2451};
2452
2453/******************************************************************************
2454 * GADGET block
2455 *****************************************************************************/
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302456static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
2457{
2458 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2459 unsigned long flags;
2460 int gadget_ready = 0;
2461
2462 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS))
2463 return -EOPNOTSUPP;
2464
2465 spin_lock_irqsave(udc->lock, flags);
2466 udc->vbus_active = is_active;
2467 if (udc->driver)
2468 gadget_ready = 1;
2469 spin_unlock_irqrestore(udc->lock, flags);
2470
2471 if (gadget_ready) {
2472 if (is_active) {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302473 pm_runtime_get_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302474 hw_device_reset(udc);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302475 hw_device_state(udc->ep0out.qh.dma);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302476 } else {
2477 hw_device_state(0);
2478 if (udc->udc_driver->notify_event)
2479 udc->udc_driver->notify_event(udc,
2480 CI13XXX_CONTROLLER_STOPPED_EVENT);
2481 _gadget_stop_activity(&udc->gadget);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302482 pm_runtime_put_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302483 }
2484 }
2485
2486 return 0;
2487}
2488
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302489static int ci13xxx_wakeup(struct usb_gadget *_gadget)
2490{
2491 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2492 unsigned long flags;
2493 int ret = 0;
2494
2495 trace();
2496
2497 spin_lock_irqsave(udc->lock, flags);
2498 if (!udc->remote_wakeup) {
2499 ret = -EOPNOTSUPP;
2500 dbg_trace("remote wakeup feature is not enabled\n");
2501 goto out;
2502 }
2503 if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) {
2504 ret = -EINVAL;
2505 dbg_trace("port is not suspended\n");
2506 goto out;
2507 }
2508 hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR);
2509out:
2510 spin_unlock_irqrestore(udc->lock, flags);
2511 return ret;
2512}
2513
David Lopoaa69a802008-11-17 14:14:51 -08002514/**
2515 * Device operations part of the API to the USB controller hardware,
2516 * which don't involve endpoints (or i/o)
2517 * Check "usb_gadget.h" for details
2518 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302519static const struct usb_gadget_ops usb_gadget_ops = {
2520 .vbus_session = ci13xxx_vbus_session,
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302521 .wakeup = ci13xxx_wakeup,
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302522};
David Lopoaa69a802008-11-17 14:14:51 -08002523
2524/**
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002525 * usb_gadget_probe_driver: register a gadget driver
2526 * @driver: the driver being registered
2527 * @bind: the driver's bind callback
David Lopoaa69a802008-11-17 14:14:51 -08002528 *
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002529 * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details.
2530 * Interrupts are enabled here.
David Lopoaa69a802008-11-17 14:14:51 -08002531 */
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002532int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
2533 int (*bind)(struct usb_gadget *))
David Lopoaa69a802008-11-17 14:14:51 -08002534{
2535 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302536 unsigned long flags;
2537 int i, j;
David Lopoaa69a802008-11-17 14:14:51 -08002538 int retval = -ENOMEM;
2539
2540 trace("%p", driver);
2541
2542 if (driver == NULL ||
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002543 bind == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002544 driver->setup == NULL ||
2545 driver->disconnect == NULL ||
2546 driver->suspend == NULL ||
2547 driver->resume == NULL)
2548 return -EINVAL;
2549 else if (udc == NULL)
2550 return -ENODEV;
2551 else if (udc->driver != NULL)
2552 return -EBUSY;
2553
2554 /* alloc resources */
2555 udc->qh_pool = dma_pool_create("ci13xxx_qh", &udc->gadget.dev,
2556 sizeof(struct ci13xxx_qh),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002557 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002558 if (udc->qh_pool == NULL)
2559 return -ENOMEM;
2560
2561 udc->td_pool = dma_pool_create("ci13xxx_td", &udc->gadget.dev,
2562 sizeof(struct ci13xxx_td),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002563 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002564 if (udc->td_pool == NULL) {
2565 dma_pool_destroy(udc->qh_pool);
2566 udc->qh_pool = NULL;
2567 return -ENOMEM;
2568 }
2569
2570 spin_lock_irqsave(udc->lock, flags);
2571
2572 info("hw_ep_max = %d", hw_ep_max);
2573
David Lopoaa69a802008-11-17 14:14:51 -08002574 udc->gadget.dev.driver = NULL;
2575
2576 retval = 0;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302577 for (i = 0; i < hw_ep_max/2; i++) {
2578 for (j = RX; j <= TX; j++) {
2579 int k = i + j * hw_ep_max/2;
2580 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k];
David Lopoaa69a802008-11-17 14:14:51 -08002581
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302582 scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i,
2583 (j == TX) ? "in" : "out");
David Lopoaa69a802008-11-17 14:14:51 -08002584
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302585 mEp->lock = udc->lock;
2586 mEp->device = &udc->gadget.dev;
2587 mEp->td_pool = udc->td_pool;
David Lopoaa69a802008-11-17 14:14:51 -08002588
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302589 mEp->ep.name = mEp->name;
2590 mEp->ep.ops = &usb_ep_ops;
2591 mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
David Lopoaa69a802008-11-17 14:14:51 -08002592
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302593 INIT_LIST_HEAD(&mEp->qh.queue);
Pavankumar Kondeti0a91efa2010-12-07 17:54:00 +05302594 spin_unlock_irqrestore(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302595 mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL,
2596 &mEp->qh.dma);
Pavankumar Kondeti0a91efa2010-12-07 17:54:00 +05302597 spin_lock_irqsave(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302598 if (mEp->qh.ptr == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002599 retval = -ENOMEM;
2600 else
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302601 memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr));
2602
2603 /* skip ep0 out and in endpoints */
2604 if (i == 0)
2605 continue;
2606
David Lopoaa69a802008-11-17 14:14:51 -08002607 list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302608 }
David Lopoaa69a802008-11-17 14:14:51 -08002609 }
2610 if (retval)
2611 goto done;
2612
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302613 udc->gadget.ep0 = &udc->ep0in.ep;
David Lopoaa69a802008-11-17 14:14:51 -08002614 /* bind gadget */
2615 driver->driver.bus = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002616 udc->gadget.dev.driver = &driver->driver;
2617
2618 spin_unlock_irqrestore(udc->lock, flags);
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002619 retval = bind(&udc->gadget); /* MAY SLEEP */
David Lopoaa69a802008-11-17 14:14:51 -08002620 spin_lock_irqsave(udc->lock, flags);
2621
2622 if (retval) {
David Lopoaa69a802008-11-17 14:14:51 -08002623 udc->gadget.dev.driver = NULL;
2624 goto done;
2625 }
2626
Pavankumar Kondeti49d3df52011-01-11 09:19:21 +05302627 udc->driver = driver;
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302628 pm_runtime_get_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302629 if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) {
2630 if (udc->vbus_active) {
2631 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED)
2632 hw_device_reset(udc);
2633 } else {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302634 pm_runtime_put_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302635 goto done;
2636 }
2637 }
2638
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302639 retval = hw_device_state(udc->ep0out.qh.dma);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302640 if (retval)
2641 pm_runtime_put_sync(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002642
2643 done:
2644 spin_unlock_irqrestore(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002645 return retval;
2646}
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002647EXPORT_SYMBOL(usb_gadget_probe_driver);
David Lopoaa69a802008-11-17 14:14:51 -08002648
2649/**
2650 * usb_gadget_unregister_driver: unregister a gadget driver
2651 *
2652 * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
2653 */
2654int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
2655{
2656 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302657 unsigned long i, flags;
David Lopoaa69a802008-11-17 14:14:51 -08002658
2659 trace("%p", driver);
2660
2661 if (driver == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002662 driver->unbind == NULL ||
2663 driver->setup == NULL ||
2664 driver->disconnect == NULL ||
2665 driver->suspend == NULL ||
2666 driver->resume == NULL ||
2667 driver != udc->driver)
2668 return -EINVAL;
2669
2670 spin_lock_irqsave(udc->lock, flags);
2671
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302672 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) ||
2673 udc->vbus_active) {
2674 hw_device_state(0);
2675 if (udc->udc_driver->notify_event)
2676 udc->udc_driver->notify_event(udc,
2677 CI13XXX_CONTROLLER_STOPPED_EVENT);
2678 _gadget_stop_activity(&udc->gadget);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302679 pm_runtime_put(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302680 }
David Lopoaa69a802008-11-17 14:14:51 -08002681
2682 /* unbind gadget */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302683 spin_unlock_irqrestore(udc->lock, flags);
2684 driver->unbind(&udc->gadget); /* MAY SLEEP */
2685 spin_lock_irqsave(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002686
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302687 udc->gadget.dev.driver = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002688
2689 /* free resources */
2690 for (i = 0; i < hw_ep_max; i++) {
2691 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
2692
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302693 if (!list_empty(&mEp->ep.ep_list))
David Lopoaa69a802008-11-17 14:14:51 -08002694 list_del_init(&mEp->ep.ep_list);
2695
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302696 if (mEp->qh.ptr != NULL)
2697 dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08002698 }
2699
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302700 udc->gadget.ep0 = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002701 udc->driver = NULL;
2702
2703 spin_unlock_irqrestore(udc->lock, flags);
2704
2705 if (udc->td_pool != NULL) {
2706 dma_pool_destroy(udc->td_pool);
2707 udc->td_pool = NULL;
2708 }
2709 if (udc->qh_pool != NULL) {
2710 dma_pool_destroy(udc->qh_pool);
2711 udc->qh_pool = NULL;
2712 }
2713
2714 return 0;
2715}
2716EXPORT_SYMBOL(usb_gadget_unregister_driver);
2717
2718/******************************************************************************
2719 * BUS block
2720 *****************************************************************************/
2721/**
2722 * udc_irq: global interrupt handler
2723 *
2724 * This function returns IRQ_HANDLED if the IRQ has been handled
2725 * It locks access to registers
2726 */
2727static irqreturn_t udc_irq(void)
2728{
2729 struct ci13xxx *udc = _udc;
2730 irqreturn_t retval;
2731 u32 intr;
2732
2733 trace();
2734
2735 if (udc == NULL) {
2736 err("ENODEV");
2737 return IRQ_HANDLED;
2738 }
2739
2740 spin_lock(udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302741
2742 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) {
2743 if (hw_cread(CAP_USBMODE, USBMODE_CM) !=
2744 USBMODE_CM_DEVICE) {
2745 spin_unlock(udc->lock);
2746 return IRQ_NONE;
2747 }
2748 }
David Lopoaa69a802008-11-17 14:14:51 -08002749 intr = hw_test_and_clear_intr_active();
2750 if (intr) {
2751 isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr;
2752 isr_statistics.hndl.idx &= ISR_MASK;
2753 isr_statistics.hndl.cnt++;
2754
2755 /* order defines priority - do NOT change it */
2756 if (USBi_URI & intr) {
2757 isr_statistics.uri++;
2758 isr_reset_handler(udc);
2759 }
2760 if (USBi_PCI & intr) {
2761 isr_statistics.pci++;
2762 udc->gadget.speed = hw_port_is_high_speed() ?
2763 USB_SPEED_HIGH : USB_SPEED_FULL;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302764 if (udc->suspended) {
2765 spin_unlock(udc->lock);
2766 udc->driver->resume(&udc->gadget);
2767 spin_lock(udc->lock);
2768 udc->suspended = 0;
2769 }
David Lopoaa69a802008-11-17 14:14:51 -08002770 }
2771 if (USBi_UEI & intr)
2772 isr_statistics.uei++;
2773 if (USBi_UI & intr) {
2774 isr_statistics.ui++;
2775 isr_tr_complete_handler(udc);
2776 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302777 if (USBi_SLI & intr) {
2778 if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
2779 udc->suspended = 1;
2780 spin_unlock(udc->lock);
2781 udc->driver->suspend(&udc->gadget);
2782 spin_lock(udc->lock);
2783 }
David Lopoaa69a802008-11-17 14:14:51 -08002784 isr_statistics.sli++;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302785 }
David Lopoaa69a802008-11-17 14:14:51 -08002786 retval = IRQ_HANDLED;
2787 } else {
2788 isr_statistics.none++;
2789 retval = IRQ_NONE;
2790 }
2791 spin_unlock(udc->lock);
2792
2793 return retval;
2794}
2795
2796/**
2797 * udc_release: driver release function
2798 * @dev: device
2799 *
2800 * Currently does nothing
2801 */
2802static void udc_release(struct device *dev)
2803{
2804 trace("%p", dev);
2805
2806 if (dev == NULL)
2807 err("EINVAL");
2808}
2809
2810/**
2811 * udc_probe: parent probe must call this to initialize UDC
2812 * @dev: parent device
2813 * @regs: registers base address
2814 * @name: driver name
2815 *
2816 * This function returns an error code
2817 * No interrupts active, the IRQ has not been requested yet
2818 * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask
2819 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302820static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
2821 void __iomem *regs)
David Lopoaa69a802008-11-17 14:14:51 -08002822{
2823 struct ci13xxx *udc;
2824 int retval = 0;
2825
2826 trace("%p, %p, %p", dev, regs, name);
2827
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302828 if (dev == NULL || regs == NULL || driver == NULL ||
2829 driver->name == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002830 return -EINVAL;
2831
2832 udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL);
2833 if (udc == NULL)
2834 return -ENOMEM;
2835
2836 udc->lock = &udc_lock;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302837 udc->regs = regs;
2838 udc->udc_driver = driver;
David Lopoaa69a802008-11-17 14:14:51 -08002839
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302840 udc->gadget.ops = &usb_gadget_ops;
David Lopoaa69a802008-11-17 14:14:51 -08002841 udc->gadget.speed = USB_SPEED_UNKNOWN;
2842 udc->gadget.is_dualspeed = 1;
2843 udc->gadget.is_otg = 0;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302844 udc->gadget.name = driver->name;
David Lopoaa69a802008-11-17 14:14:51 -08002845
2846 INIT_LIST_HEAD(&udc->gadget.ep_list);
2847 udc->gadget.ep0 = NULL;
2848
Kay Sievers5df58522009-03-24 16:38:23 -07002849 dev_set_name(&udc->gadget.dev, "gadget");
David Lopoaa69a802008-11-17 14:14:51 -08002850 udc->gadget.dev.dma_mask = dev->dma_mask;
Pavankumar Kondeti61948ee2010-12-07 17:54:01 +05302851 udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask;
David Lopoaa69a802008-11-17 14:14:51 -08002852 udc->gadget.dev.parent = dev;
2853 udc->gadget.dev.release = udc_release;
2854
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302855 retval = hw_device_init(regs);
2856 if (retval < 0)
2857 goto free_udc;
2858
2859 udc->transceiver = otg_get_transceiver();
2860
2861 if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
2862 if (udc->transceiver == NULL) {
2863 retval = -ENODEV;
2864 goto free_udc;
2865 }
2866 }
2867
2868 if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) {
2869 retval = hw_device_reset(udc);
2870 if (retval)
2871 goto put_transceiver;
2872 }
2873
David Lopoaa69a802008-11-17 14:14:51 -08002874 retval = device_register(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302875 if (retval) {
2876 put_device(&udc->gadget.dev);
2877 goto put_transceiver;
2878 }
David Lopoaa69a802008-11-17 14:14:51 -08002879
2880#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2881 retval = dbg_create_files(&udc->gadget.dev);
2882#endif
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302883 if (retval)
2884 goto unreg_device;
2885
2886 if (udc->transceiver) {
2887 retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
2888 if (retval)
2889 goto remove_dbg;
David Lopoaa69a802008-11-17 14:14:51 -08002890 }
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302891 pm_runtime_no_callbacks(&udc->gadget.dev);
2892 pm_runtime_enable(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002893
2894 _udc = udc;
2895 return retval;
2896
David Lopoaa69a802008-11-17 14:14:51 -08002897 err("error = %i", retval);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302898remove_dbg:
2899#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2900 dbg_remove_files(&udc->gadget.dev);
2901#endif
2902unreg_device:
2903 device_unregister(&udc->gadget.dev);
2904put_transceiver:
2905 if (udc->transceiver)
2906 otg_put_transceiver(udc->transceiver);
2907free_udc:
David Lopoaa69a802008-11-17 14:14:51 -08002908 kfree(udc);
2909 _udc = NULL;
2910 return retval;
2911}
2912
2913/**
2914 * udc_remove: parent remove must call this to remove UDC
2915 *
2916 * No interrupts active, the IRQ has been released
2917 */
2918static void udc_remove(void)
2919{
2920 struct ci13xxx *udc = _udc;
2921
2922 if (udc == NULL) {
2923 err("EINVAL");
2924 return;
2925 }
2926
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302927 if (udc->transceiver) {
2928 otg_set_peripheral(udc->transceiver, &udc->gadget);
2929 otg_put_transceiver(udc->transceiver);
2930 }
David Lopoaa69a802008-11-17 14:14:51 -08002931#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2932 dbg_remove_files(&udc->gadget.dev);
2933#endif
2934 device_unregister(&udc->gadget.dev);
2935
2936 kfree(udc);
2937 _udc = NULL;
2938}