blob: 9db7e7667c2b05e2be281d398716e0d6584983de [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 *****************************************************************************/
Michael Grzeschik954aad82011-10-10 18:38:06 +020074
75#define DMA_ADDR_INVALID (~(dma_addr_t)0)
76
David Lopoaa69a802008-11-17 14:14:51 -080077/* ctrl register bank access */
78static DEFINE_SPINLOCK(udc_lock);
79
David Lopoaa69a802008-11-17 14:14:51 -080080/* control endpoint description */
81static const struct usb_endpoint_descriptor
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053082ctrl_endpt_out_desc = {
David Lopoaa69a802008-11-17 14:14:51 -080083 .bLength = USB_DT_ENDPOINT_SIZE,
84 .bDescriptorType = USB_DT_ENDPOINT,
85
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053086 .bEndpointAddress = USB_DIR_OUT,
87 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
88 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
89};
90
91static const struct usb_endpoint_descriptor
92ctrl_endpt_in_desc = {
93 .bLength = USB_DT_ENDPOINT_SIZE,
94 .bDescriptorType = USB_DT_ENDPOINT,
95
96 .bEndpointAddress = USB_DIR_IN,
David Lopoaa69a802008-11-17 14:14:51 -080097 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
98 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
99};
100
101/* UDC descriptor */
102static struct ci13xxx *_udc;
103
104/* Interrupt statistics */
105#define ISR_MASK 0x1F
106static struct {
107 u32 test;
108 u32 ui;
109 u32 uei;
110 u32 pci;
111 u32 uri;
112 u32 sli;
113 u32 none;
114 struct {
115 u32 cnt;
116 u32 buf[ISR_MASK+1];
117 u32 idx;
118 } hndl;
119} isr_statistics;
120
121/**
122 * ffs_nr: find first (least significant) bit set
123 * @x: the word to search
124 *
125 * This function returns bit number (instead of position)
126 */
127static int ffs_nr(u32 x)
128{
129 int n = ffs(x);
130
131 return n ? n-1 : 32;
132}
133
134/******************************************************************************
135 * HW block
136 *****************************************************************************/
137/* register bank descriptor */
138static struct {
139 unsigned lpm; /* is LPM? */
140 void __iomem *abs; /* bus map offset */
141 void __iomem *cap; /* bus map offset + CAP offset + CAP data */
142 size_t size; /* bank size */
143} hw_bank;
144
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530145/* MSM specific */
146#define ABS_AHBBURST (0x0090UL)
147#define ABS_AHBMODE (0x0098UL)
David Lopoaa69a802008-11-17 14:14:51 -0800148/* UDC register map */
149#define ABS_CAPLENGTH (0x100UL)
150#define ABS_HCCPARAMS (0x108UL)
151#define ABS_DCCPARAMS (0x124UL)
152#define ABS_TESTMODE (hw_bank.lpm ? 0x0FCUL : 0x138UL)
153/* offset to CAPLENTGH (addr + data) */
154#define CAP_USBCMD (0x000UL)
155#define CAP_USBSTS (0x004UL)
156#define CAP_USBINTR (0x008UL)
157#define CAP_DEVICEADDR (0x014UL)
158#define CAP_ENDPTLISTADDR (0x018UL)
159#define CAP_PORTSC (0x044UL)
David Lopof23e6492009-04-16 14:35:24 -0700160#define CAP_DEVLC (0x084UL)
David Lopoaa69a802008-11-17 14:14:51 -0800161#define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL)
162#define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL)
163#define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL)
164#define CAP_ENDPTFLUSH (hw_bank.lpm ? 0x0E0UL : 0x074UL)
165#define CAP_ENDPTSTAT (hw_bank.lpm ? 0x0E4UL : 0x078UL)
166#define CAP_ENDPTCOMPLETE (hw_bank.lpm ? 0x0E8UL : 0x07CUL)
167#define CAP_ENDPTCTRL (hw_bank.lpm ? 0x0ECUL : 0x080UL)
168#define CAP_LAST (hw_bank.lpm ? 0x12CUL : 0x0C0UL)
169
170/* maximum number of enpoints: valid only after hw_device_reset() */
171static unsigned hw_ep_max;
172
173/**
174 * hw_ep_bit: calculates the bit number
175 * @num: endpoint number
176 * @dir: endpoint direction
177 *
178 * This function returns bit number
179 */
180static inline int hw_ep_bit(int num, int dir)
181{
182 return num + (dir ? 16 : 0);
183}
184
185/**
186 * hw_aread: reads from register bitfield
187 * @addr: address relative to bus map
188 * @mask: bitfield mask
189 *
190 * This function returns register bitfield data
191 */
192static u32 hw_aread(u32 addr, u32 mask)
193{
194 return ioread32(addr + hw_bank.abs) & mask;
195}
196
197/**
198 * hw_awrite: writes to register bitfield
199 * @addr: address relative to bus map
200 * @mask: bitfield mask
201 * @data: new data
202 */
203static void hw_awrite(u32 addr, u32 mask, u32 data)
204{
205 iowrite32(hw_aread(addr, ~mask) | (data & mask),
206 addr + hw_bank.abs);
207}
208
209/**
210 * hw_cread: reads from register bitfield
211 * @addr: address relative to CAP offset plus content
212 * @mask: bitfield mask
213 *
214 * This function returns register bitfield data
215 */
216static u32 hw_cread(u32 addr, u32 mask)
217{
218 return ioread32(addr + hw_bank.cap) & mask;
219}
220
221/**
222 * hw_cwrite: writes to register bitfield
223 * @addr: address relative to CAP offset plus content
224 * @mask: bitfield mask
225 * @data: new data
226 */
227static void hw_cwrite(u32 addr, u32 mask, u32 data)
228{
229 iowrite32(hw_cread(addr, ~mask) | (data & mask),
230 addr + hw_bank.cap);
231}
232
233/**
234 * hw_ctest_and_clear: tests & clears register bitfield
235 * @addr: address relative to CAP offset plus content
236 * @mask: bitfield mask
237 *
238 * This function returns register bitfield data
239 */
240static u32 hw_ctest_and_clear(u32 addr, u32 mask)
241{
242 u32 reg = hw_cread(addr, mask);
243
244 iowrite32(reg, addr + hw_bank.cap);
245 return reg;
246}
247
248/**
249 * hw_ctest_and_write: tests & writes register bitfield
250 * @addr: address relative to CAP offset plus content
251 * @mask: bitfield mask
252 * @data: new data
253 *
254 * This function returns register bitfield data
255 */
256static u32 hw_ctest_and_write(u32 addr, u32 mask, u32 data)
257{
258 u32 reg = hw_cread(addr, ~0);
259
260 iowrite32((reg & ~mask) | (data & mask), addr + hw_bank.cap);
261 return (reg & mask) >> ffs_nr(mask);
262}
263
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530264static int hw_device_init(void __iomem *base)
David Lopoaa69a802008-11-17 14:14:51 -0800265{
266 u32 reg;
267
268 /* bank is a module variable */
269 hw_bank.abs = base;
270
271 hw_bank.cap = hw_bank.abs;
272 hw_bank.cap += ABS_CAPLENGTH;
273 hw_bank.cap += ioread8(hw_bank.cap);
274
275 reg = hw_aread(ABS_HCCPARAMS, HCCPARAMS_LEN) >> ffs_nr(HCCPARAMS_LEN);
276 hw_bank.lpm = reg;
277 hw_bank.size = hw_bank.cap - hw_bank.abs;
278 hw_bank.size += CAP_LAST;
279 hw_bank.size /= sizeof(u32);
280
David Lopoaa69a802008-11-17 14:14:51 -0800281 reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530282 hw_ep_max = reg * 2; /* cache hw ENDPT_MAX */
David Lopoaa69a802008-11-17 14:14:51 -0800283
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530284 if (hw_ep_max == 0 || hw_ep_max > ENDPT_MAX)
285 return -ENODEV;
David Lopoaa69a802008-11-17 14:14:51 -0800286
287 /* setup lock mode ? */
288
289 /* ENDPTSETUPSTAT is '0' by default */
290
291 /* HCSPARAMS.bf.ppc SHOULD BE zero for device */
292
293 return 0;
294}
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530295/**
296 * hw_device_reset: resets chip (execute without interruption)
297 * @base: register base address
298 *
299 * This function returns an error code
300 */
301static int hw_device_reset(struct ci13xxx *udc)
302{
303 /* should flush & stop before reset */
304 hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0);
305 hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
306
307 hw_cwrite(CAP_USBCMD, USBCMD_RST, USBCMD_RST);
308 while (hw_cread(CAP_USBCMD, USBCMD_RST))
309 udelay(10); /* not RTOS friendly */
310
311
312 if (udc->udc_driver->notify_event)
313 udc->udc_driver->notify_event(udc,
314 CI13XXX_CONTROLLER_RESET_EVENT);
315
Pavankumar Kondeti8c2387a2011-05-02 11:56:28 +0530316 if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530317 hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
318
319 /* USBMODE should be configured step by step */
320 hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
321 hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE);
322 hw_cwrite(CAP_USBMODE, USBMODE_SLOM, USBMODE_SLOM); /* HW >= 2.3 */
323
324 if (hw_cread(CAP_USBMODE, USBMODE_CM) != USBMODE_CM_DEVICE) {
325 pr_err("cannot enter in device mode");
326 pr_err("lpm = %i", hw_bank.lpm);
327 return -ENODEV;
328 }
329
330 return 0;
331}
David Lopoaa69a802008-11-17 14:14:51 -0800332
333/**
334 * hw_device_state: enables/disables interrupts & starts/stops device (execute
335 * without interruption)
336 * @dma: 0 => disable, !0 => enable and set dma engine
337 *
338 * This function returns an error code
339 */
340static int hw_device_state(u32 dma)
341{
342 if (dma) {
343 hw_cwrite(CAP_ENDPTLISTADDR, ~0, dma);
344 /* interrupt, error, port change, reset, sleep/suspend */
345 hw_cwrite(CAP_USBINTR, ~0,
346 USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
347 hw_cwrite(CAP_USBCMD, USBCMD_RS, USBCMD_RS);
348 } else {
349 hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
350 hw_cwrite(CAP_USBINTR, ~0, 0);
351 }
352 return 0;
353}
354
355/**
356 * hw_ep_flush: flush endpoint fifo (execute without interruption)
357 * @num: endpoint number
358 * @dir: endpoint direction
359 *
360 * This function returns an error code
361 */
362static int hw_ep_flush(int num, int dir)
363{
364 int n = hw_ep_bit(num, dir);
365
366 do {
367 /* flush any pending transfer */
368 hw_cwrite(CAP_ENDPTFLUSH, BIT(n), BIT(n));
369 while (hw_cread(CAP_ENDPTFLUSH, BIT(n)))
370 cpu_relax();
371 } while (hw_cread(CAP_ENDPTSTAT, BIT(n)));
372
373 return 0;
374}
375
376/**
377 * hw_ep_disable: disables endpoint (execute without interruption)
378 * @num: endpoint number
379 * @dir: endpoint direction
380 *
381 * This function returns an error code
382 */
383static int hw_ep_disable(int num, int dir)
384{
385 hw_ep_flush(num, dir);
386 hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32),
387 dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
388 return 0;
389}
390
391/**
392 * hw_ep_enable: enables endpoint (execute without interruption)
393 * @num: endpoint number
394 * @dir: endpoint direction
395 * @type: endpoint type
396 *
397 * This function returns an error code
398 */
399static int hw_ep_enable(int num, int dir, int type)
400{
401 u32 mask, data;
402
403 if (dir) {
404 mask = ENDPTCTRL_TXT; /* type */
405 data = type << ffs_nr(mask);
406
407 mask |= ENDPTCTRL_TXS; /* unstall */
408 mask |= ENDPTCTRL_TXR; /* reset data toggle */
409 data |= ENDPTCTRL_TXR;
410 mask |= ENDPTCTRL_TXE; /* enable */
411 data |= ENDPTCTRL_TXE;
412 } else {
413 mask = ENDPTCTRL_RXT; /* type */
414 data = type << ffs_nr(mask);
415
416 mask |= ENDPTCTRL_RXS; /* unstall */
417 mask |= ENDPTCTRL_RXR; /* reset data toggle */
418 data |= ENDPTCTRL_RXR;
419 mask |= ENDPTCTRL_RXE; /* enable */
420 data |= ENDPTCTRL_RXE;
421 }
422 hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32), mask, data);
423 return 0;
424}
425
426/**
427 * hw_ep_get_halt: return endpoint halt status
428 * @num: endpoint number
429 * @dir: endpoint direction
430 *
431 * This function returns 1 if endpoint halted
432 */
433static int hw_ep_get_halt(int num, int dir)
434{
435 u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
436
437 return hw_cread(CAP_ENDPTCTRL + num * sizeof(u32), mask) ? 1 : 0;
438}
439
440/**
David Lopoaa69a802008-11-17 14:14:51 -0800441 * hw_test_and_clear_setup_status: test & clear setup status (execute without
442 * interruption)
443 * @n: bit number (endpoint)
444 *
445 * This function returns setup status
446 */
447static int hw_test_and_clear_setup_status(int n)
448{
449 return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n));
450}
451
452/**
453 * hw_ep_prime: primes endpoint (execute without interruption)
454 * @num: endpoint number
455 * @dir: endpoint direction
456 * @is_ctrl: true if control endpoint
457 *
458 * This function returns an error code
459 */
460static int hw_ep_prime(int num, int dir, int is_ctrl)
461{
462 int n = hw_ep_bit(num, dir);
463
David Lopoaa69a802008-11-17 14:14:51 -0800464 if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
465 return -EAGAIN;
466
467 hw_cwrite(CAP_ENDPTPRIME, BIT(n), BIT(n));
468
469 while (hw_cread(CAP_ENDPTPRIME, BIT(n)))
470 cpu_relax();
471 if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
472 return -EAGAIN;
473
474 /* status shoult be tested according with manual but it doesn't work */
475 return 0;
476}
477
478/**
479 * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute
480 * without interruption)
481 * @num: endpoint number
482 * @dir: endpoint direction
483 * @value: true => stall, false => unstall
484 *
485 * This function returns an error code
486 */
487static int hw_ep_set_halt(int num, int dir, int value)
488{
489 if (value != 0 && value != 1)
490 return -EINVAL;
491
492 do {
493 u32 addr = CAP_ENDPTCTRL + num * sizeof(u32);
494 u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
495 u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
496
497 /* data toggle - reserved for EP0 but it's in ESS */
498 hw_cwrite(addr, mask_xs|mask_xr, value ? mask_xs : mask_xr);
499
500 } while (value != hw_ep_get_halt(num, dir));
501
502 return 0;
503}
504
505/**
506 * hw_intr_clear: disables interrupt & clears interrupt status (execute without
507 * interruption)
508 * @n: interrupt bit
509 *
510 * This function returns an error code
511 */
512static int hw_intr_clear(int n)
513{
514 if (n >= REG_BITS)
515 return -EINVAL;
516
517 hw_cwrite(CAP_USBINTR, BIT(n), 0);
518 hw_cwrite(CAP_USBSTS, BIT(n), BIT(n));
519 return 0;
520}
521
522/**
523 * hw_intr_force: enables interrupt & forces interrupt status (execute without
524 * interruption)
525 * @n: interrupt bit
526 *
527 * This function returns an error code
528 */
529static int hw_intr_force(int n)
530{
531 if (n >= REG_BITS)
532 return -EINVAL;
533
534 hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE);
535 hw_cwrite(CAP_USBINTR, BIT(n), BIT(n));
536 hw_cwrite(CAP_USBSTS, BIT(n), BIT(n));
537 hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, 0);
538 return 0;
539}
540
541/**
542 * hw_is_port_high_speed: test if port is high speed
543 *
544 * This function returns true if high speed port
545 */
546static int hw_port_is_high_speed(void)
547{
548 return hw_bank.lpm ? hw_cread(CAP_DEVLC, DEVLC_PSPD) :
549 hw_cread(CAP_PORTSC, PORTSC_HSP);
550}
551
552/**
553 * hw_port_test_get: reads port test mode value
554 *
555 * This function returns port test mode value
556 */
557static u8 hw_port_test_get(void)
558{
559 return hw_cread(CAP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC);
560}
561
562/**
563 * hw_port_test_set: writes port test mode (execute without interruption)
564 * @mode: new value
565 *
566 * This function returns an error code
567 */
568static int hw_port_test_set(u8 mode)
569{
570 const u8 TEST_MODE_MAX = 7;
571
572 if (mode > TEST_MODE_MAX)
573 return -EINVAL;
574
575 hw_cwrite(CAP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC));
576 return 0;
577}
578
579/**
580 * hw_read_intr_enable: returns interrupt enable register
581 *
582 * This function returns register data
583 */
584static u32 hw_read_intr_enable(void)
585{
586 return hw_cread(CAP_USBINTR, ~0);
587}
588
589/**
590 * hw_read_intr_status: returns interrupt status register
591 *
592 * This function returns register data
593 */
594static u32 hw_read_intr_status(void)
595{
596 return hw_cread(CAP_USBSTS, ~0);
597}
598
599/**
600 * hw_register_read: reads all device registers (execute without interruption)
601 * @buf: destination buffer
602 * @size: buffer size
603 *
604 * This function returns number of registers read
605 */
606static size_t hw_register_read(u32 *buf, size_t size)
607{
608 unsigned i;
609
610 if (size > hw_bank.size)
611 size = hw_bank.size;
612
613 for (i = 0; i < size; i++)
614 buf[i] = hw_aread(i * sizeof(u32), ~0);
615
616 return size;
617}
618
619/**
620 * hw_register_write: writes to register
621 * @addr: register address
622 * @data: register value
623 *
624 * This function returns an error code
625 */
626static int hw_register_write(u16 addr, u32 data)
627{
628 /* align */
629 addr /= sizeof(u32);
630
631 if (addr >= hw_bank.size)
632 return -EINVAL;
633
634 /* align */
635 addr *= sizeof(u32);
636
637 hw_awrite(addr, ~0, data);
638 return 0;
639}
640
641/**
642 * hw_test_and_clear_complete: test & clear complete status (execute without
643 * interruption)
644 * @n: bit number (endpoint)
645 *
646 * This function returns complete status
647 */
648static int hw_test_and_clear_complete(int n)
649{
650 return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n));
651}
652
653/**
654 * hw_test_and_clear_intr_active: test & clear active interrupts (execute
655 * without interruption)
656 *
657 * This function returns active interrutps
658 */
659static u32 hw_test_and_clear_intr_active(void)
660{
661 u32 reg = hw_read_intr_status() & hw_read_intr_enable();
662
663 hw_cwrite(CAP_USBSTS, ~0, reg);
664 return reg;
665}
666
667/**
668 * hw_test_and_clear_setup_guard: test & clear setup guard (execute without
669 * interruption)
670 *
671 * This function returns guard value
672 */
673static int hw_test_and_clear_setup_guard(void)
674{
675 return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, 0);
676}
677
678/**
679 * hw_test_and_set_setup_guard: test & set setup guard (execute without
680 * interruption)
681 *
682 * This function returns guard value
683 */
684static int hw_test_and_set_setup_guard(void)
685{
686 return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, USBCMD_SUTW);
687}
688
689/**
690 * hw_usb_set_address: configures USB address (execute without interruption)
691 * @value: new USB address
692 *
693 * This function returns an error code
694 */
695static int hw_usb_set_address(u8 value)
696{
697 /* advance */
698 hw_cwrite(CAP_DEVICEADDR, DEVICEADDR_USBADR | DEVICEADDR_USBADRA,
699 value << ffs_nr(DEVICEADDR_USBADR) | DEVICEADDR_USBADRA);
700 return 0;
701}
702
703/**
704 * hw_usb_reset: restart device after a bus reset (execute without
705 * interruption)
706 *
707 * This function returns an error code
708 */
709static int hw_usb_reset(void)
710{
711 hw_usb_set_address(0);
712
713 /* ESS flushes only at end?!? */
714 hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); /* flush all EPs */
715
716 /* clear setup token semaphores */
717 hw_cwrite(CAP_ENDPTSETUPSTAT, 0, 0); /* writes its content */
718
719 /* clear complete status */
720 hw_cwrite(CAP_ENDPTCOMPLETE, 0, 0); /* writes its content */
721
722 /* wait until all bits cleared */
723 while (hw_cread(CAP_ENDPTPRIME, ~0))
724 udelay(10); /* not RTOS friendly */
725
726 /* reset all endpoints ? */
727
728 /* reset internal status and wait for further instructions
729 no need to verify the port reset status (ESS does it) */
730
731 return 0;
732}
733
734/******************************************************************************
735 * DBG block
736 *****************************************************************************/
737/**
738 * show_device: prints information about device capabilities and status
739 *
740 * Check "device.h" for details
741 */
742static ssize_t show_device(struct device *dev, struct device_attribute *attr,
743 char *buf)
744{
745 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
746 struct usb_gadget *gadget = &udc->gadget;
747 int n = 0;
748
749 dbg_trace("[%s] %p\n", __func__, buf);
750 if (attr == NULL || buf == NULL) {
751 dev_err(dev, "[%s] EINVAL\n", __func__);
752 return 0;
753 }
754
755 n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n",
756 gadget->speed);
757 n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n",
758 gadget->is_dualspeed);
759 n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
760 gadget->is_otg);
761 n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
762 gadget->is_a_peripheral);
763 n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n",
764 gadget->b_hnp_enable);
765 n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n",
766 gadget->a_hnp_support);
767 n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n",
768 gadget->a_alt_hnp_support);
769 n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n",
770 (gadget->name ? gadget->name : ""));
771
772 return n;
773}
774static DEVICE_ATTR(device, S_IRUSR, show_device, NULL);
775
776/**
777 * show_driver: prints information about attached gadget (if any)
778 *
779 * Check "device.h" for details
780 */
781static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
782 char *buf)
783{
784 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
785 struct usb_gadget_driver *driver = udc->driver;
786 int n = 0;
787
788 dbg_trace("[%s] %p\n", __func__, buf);
789 if (attr == NULL || buf == NULL) {
790 dev_err(dev, "[%s] EINVAL\n", __func__);
791 return 0;
792 }
793
794 if (driver == NULL)
795 return scnprintf(buf, PAGE_SIZE,
796 "There is no gadget attached!\n");
797
798 n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n",
799 (driver->function ? driver->function : ""));
800 n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n",
801 driver->speed);
802
803 return n;
804}
805static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);
806
807/* Maximum event message length */
808#define DBG_DATA_MSG 64UL
809
810/* Maximum event messages */
811#define DBG_DATA_MAX 128UL
812
813/* Event buffer descriptor */
814static struct {
815 char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
816 unsigned idx; /* index */
817 unsigned tty; /* print to console? */
818 rwlock_t lck; /* lock */
819} dbg_data = {
820 .idx = 0,
821 .tty = 0,
822 .lck = __RW_LOCK_UNLOCKED(lck)
823};
824
825/**
826 * dbg_dec: decrements debug event index
827 * @idx: buffer index
828 */
829static void dbg_dec(unsigned *idx)
830{
831 *idx = (*idx - 1) & (DBG_DATA_MAX-1);
832}
833
834/**
835 * dbg_inc: increments debug event index
836 * @idx: buffer index
837 */
838static void dbg_inc(unsigned *idx)
839{
840 *idx = (*idx + 1) & (DBG_DATA_MAX-1);
841}
842
843/**
844 * dbg_print: prints the common part of the event
845 * @addr: endpoint address
846 * @name: event name
847 * @status: status
848 * @extra: extra information
849 */
850static void dbg_print(u8 addr, const char *name, int status, const char *extra)
851{
852 struct timeval tval;
853 unsigned int stamp;
854 unsigned long flags;
855
856 write_lock_irqsave(&dbg_data.lck, flags);
857
858 do_gettimeofday(&tval);
859 stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s */
860 stamp = stamp * 1000000 + tval.tv_usec;
861
862 scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +0300863 "%04X\t? %02X %-7.7s %4i ?\t%s\n",
David Lopoaa69a802008-11-17 14:14:51 -0800864 stamp, addr, name, status, extra);
865
866 dbg_inc(&dbg_data.idx);
867
868 write_unlock_irqrestore(&dbg_data.lck, flags);
869
870 if (dbg_data.tty != 0)
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +0300871 pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n",
David Lopoaa69a802008-11-17 14:14:51 -0800872 stamp, addr, name, status, extra);
873}
874
875/**
876 * dbg_done: prints a DONE event
877 * @addr: endpoint address
878 * @td: transfer descriptor
879 * @status: status
880 */
881static void dbg_done(u8 addr, const u32 token, int status)
882{
883 char msg[DBG_DATA_MSG];
884
885 scnprintf(msg, sizeof(msg), "%d %02X",
886 (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES),
887 (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS));
888 dbg_print(addr, "DONE", status, msg);
889}
890
891/**
892 * dbg_event: prints a generic event
893 * @addr: endpoint address
894 * @name: event name
895 * @status: status
896 */
897static void dbg_event(u8 addr, const char *name, int status)
898{
899 if (name != NULL)
900 dbg_print(addr, name, status, "");
901}
902
903/*
904 * dbg_queue: prints a QUEUE event
905 * @addr: endpoint address
906 * @req: USB request
907 * @status: status
908 */
909static void dbg_queue(u8 addr, const struct usb_request *req, int status)
910{
911 char msg[DBG_DATA_MSG];
912
913 if (req != NULL) {
914 scnprintf(msg, sizeof(msg),
915 "%d %d", !req->no_interrupt, req->length);
916 dbg_print(addr, "QUEUE", status, msg);
917 }
918}
919
920/**
921 * dbg_setup: prints a SETUP event
922 * @addr: endpoint address
923 * @req: setup request
924 */
925static void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
926{
927 char msg[DBG_DATA_MSG];
928
929 if (req != NULL) {
930 scnprintf(msg, sizeof(msg),
931 "%02X %02X %04X %04X %d", req->bRequestType,
932 req->bRequest, le16_to_cpu(req->wValue),
933 le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
934 dbg_print(addr, "SETUP", 0, msg);
935 }
936}
937
938/**
939 * show_events: displays the event buffer
940 *
941 * Check "device.h" for details
942 */
943static ssize_t show_events(struct device *dev, struct device_attribute *attr,
944 char *buf)
945{
946 unsigned long flags;
947 unsigned i, j, n = 0;
948
949 dbg_trace("[%s] %p\n", __func__, buf);
950 if (attr == NULL || buf == NULL) {
951 dev_err(dev, "[%s] EINVAL\n", __func__);
952 return 0;
953 }
954
955 read_lock_irqsave(&dbg_data.lck, flags);
956
957 i = dbg_data.idx;
958 for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) {
959 n += strlen(dbg_data.buf[i]);
960 if (n >= PAGE_SIZE) {
961 n -= strlen(dbg_data.buf[i]);
962 break;
963 }
964 }
965 for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i))
966 j += scnprintf(buf + j, PAGE_SIZE - j,
967 "%s", dbg_data.buf[i]);
968
969 read_unlock_irqrestore(&dbg_data.lck, flags);
970
971 return n;
972}
973
974/**
975 * store_events: configure if events are going to be also printed to console
976 *
977 * Check "device.h" for details
978 */
979static ssize_t store_events(struct device *dev, struct device_attribute *attr,
980 const char *buf, size_t count)
981{
982 unsigned tty;
983
984 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
985 if (attr == NULL || buf == NULL) {
986 dev_err(dev, "[%s] EINVAL\n", __func__);
987 goto done;
988 }
989
990 if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
991 dev_err(dev, "<1|0>: enable|disable console log\n");
992 goto done;
993 }
994
995 dbg_data.tty = tty;
996 dev_info(dev, "tty = %u", dbg_data.tty);
997
998 done:
999 return count;
1000}
1001static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events);
1002
1003/**
1004 * show_inters: interrupt status, enable status and historic
1005 *
1006 * Check "device.h" for details
1007 */
1008static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
1009 char *buf)
1010{
1011 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1012 unsigned long flags;
1013 u32 intr;
1014 unsigned i, j, n = 0;
1015
1016 dbg_trace("[%s] %p\n", __func__, buf);
1017 if (attr == NULL || buf == NULL) {
1018 dev_err(dev, "[%s] EINVAL\n", __func__);
1019 return 0;
1020 }
1021
1022 spin_lock_irqsave(udc->lock, flags);
1023
1024 n += scnprintf(buf + n, PAGE_SIZE - n,
1025 "status = %08x\n", hw_read_intr_status());
1026 n += scnprintf(buf + n, PAGE_SIZE - n,
1027 "enable = %08x\n", hw_read_intr_enable());
1028
1029 n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
1030 isr_statistics.test);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001031 n += scnprintf(buf + n, PAGE_SIZE - n, "? ui = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001032 isr_statistics.ui);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001033 n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001034 isr_statistics.uei);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001035 n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001036 isr_statistics.pci);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001037 n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001038 isr_statistics.uri);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001039 n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001040 isr_statistics.sli);
1041 n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
1042 isr_statistics.none);
1043 n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n",
1044 isr_statistics.hndl.cnt);
1045
1046 for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) {
1047 i &= ISR_MASK;
1048 intr = isr_statistics.hndl.buf[i];
1049
1050 if (USBi_UI & intr)
1051 n += scnprintf(buf + n, PAGE_SIZE - n, "ui ");
1052 intr &= ~USBi_UI;
1053 if (USBi_UEI & intr)
1054 n += scnprintf(buf + n, PAGE_SIZE - n, "uei ");
1055 intr &= ~USBi_UEI;
1056 if (USBi_PCI & intr)
1057 n += scnprintf(buf + n, PAGE_SIZE - n, "pci ");
1058 intr &= ~USBi_PCI;
1059 if (USBi_URI & intr)
1060 n += scnprintf(buf + n, PAGE_SIZE - n, "uri ");
1061 intr &= ~USBi_URI;
1062 if (USBi_SLI & intr)
1063 n += scnprintf(buf + n, PAGE_SIZE - n, "sli ");
1064 intr &= ~USBi_SLI;
1065 if (intr)
1066 n += scnprintf(buf + n, PAGE_SIZE - n, "??? ");
1067 if (isr_statistics.hndl.buf[i])
1068 n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
1069 }
1070
1071 spin_unlock_irqrestore(udc->lock, flags);
1072
1073 return n;
1074}
1075
1076/**
1077 * store_inters: enable & force or disable an individual interrutps
1078 * (to be used for test purposes only)
1079 *
1080 * Check "device.h" for details
1081 */
1082static ssize_t store_inters(struct device *dev, struct device_attribute *attr,
1083 const char *buf, size_t count)
1084{
1085 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1086 unsigned long flags;
1087 unsigned en, bit;
1088
1089 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1090 if (attr == NULL || buf == NULL) {
1091 dev_err(dev, "[%s] EINVAL\n", __func__);
1092 goto done;
1093 }
1094
1095 if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) {
1096 dev_err(dev, "<1|0> <bit>: enable|disable interrupt");
1097 goto done;
1098 }
1099
1100 spin_lock_irqsave(udc->lock, flags);
1101 if (en) {
1102 if (hw_intr_force(bit))
1103 dev_err(dev, "invalid bit number\n");
1104 else
1105 isr_statistics.test++;
1106 } else {
1107 if (hw_intr_clear(bit))
1108 dev_err(dev, "invalid bit number\n");
1109 }
1110 spin_unlock_irqrestore(udc->lock, flags);
1111
1112 done:
1113 return count;
1114}
1115static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters);
1116
1117/**
1118 * show_port_test: reads port test mode
1119 *
1120 * Check "device.h" for details
1121 */
1122static ssize_t show_port_test(struct device *dev,
1123 struct device_attribute *attr, char *buf)
1124{
1125 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1126 unsigned long flags;
1127 unsigned mode;
1128
1129 dbg_trace("[%s] %p\n", __func__, buf);
1130 if (attr == NULL || buf == NULL) {
1131 dev_err(dev, "[%s] EINVAL\n", __func__);
1132 return 0;
1133 }
1134
1135 spin_lock_irqsave(udc->lock, flags);
1136 mode = hw_port_test_get();
1137 spin_unlock_irqrestore(udc->lock, flags);
1138
1139 return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode);
1140}
1141
1142/**
1143 * store_port_test: writes port test mode
1144 *
1145 * Check "device.h" for details
1146 */
1147static ssize_t store_port_test(struct device *dev,
1148 struct device_attribute *attr,
1149 const char *buf, size_t count)
1150{
1151 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1152 unsigned long flags;
1153 unsigned mode;
1154
1155 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1156 if (attr == NULL || buf == NULL) {
1157 dev_err(dev, "[%s] EINVAL\n", __func__);
1158 goto done;
1159 }
1160
1161 if (sscanf(buf, "%u", &mode) != 1) {
1162 dev_err(dev, "<mode>: set port test mode");
1163 goto done;
1164 }
1165
1166 spin_lock_irqsave(udc->lock, flags);
1167 if (hw_port_test_set(mode))
1168 dev_err(dev, "invalid mode\n");
1169 spin_unlock_irqrestore(udc->lock, flags);
1170
1171 done:
1172 return count;
1173}
1174static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR,
1175 show_port_test, store_port_test);
1176
1177/**
1178 * show_qheads: DMA contents of all queue heads
1179 *
1180 * Check "device.h" for details
1181 */
1182static ssize_t show_qheads(struct device *dev, struct device_attribute *attr,
1183 char *buf)
1184{
1185 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1186 unsigned long flags;
1187 unsigned i, j, n = 0;
1188
1189 dbg_trace("[%s] %p\n", __func__, buf);
1190 if (attr == NULL || buf == NULL) {
1191 dev_err(dev, "[%s] EINVAL\n", __func__);
1192 return 0;
1193 }
1194
1195 spin_lock_irqsave(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301196 for (i = 0; i < hw_ep_max/2; i++) {
1197 struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i];
1198 struct ci13xxx_ep *mEpTx = &udc->ci13xxx_ep[i + hw_ep_max/2];
David Lopoaa69a802008-11-17 14:14:51 -08001199 n += scnprintf(buf + n, PAGE_SIZE - n,
1200 "EP=%02i: RX=%08X TX=%08X\n",
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301201 i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08001202 for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) {
1203 n += scnprintf(buf + n, PAGE_SIZE - n,
1204 " %04X: %08X %08X\n", j,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301205 *((u32 *)mEpRx->qh.ptr + j),
1206 *((u32 *)mEpTx->qh.ptr + j));
David Lopoaa69a802008-11-17 14:14:51 -08001207 }
1208 }
1209 spin_unlock_irqrestore(udc->lock, flags);
1210
1211 return n;
1212}
1213static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL);
1214
1215/**
1216 * show_registers: dumps all registers
1217 *
1218 * Check "device.h" for details
1219 */
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001220#define DUMP_ENTRIES 512
David Lopoaa69a802008-11-17 14:14:51 -08001221static ssize_t show_registers(struct device *dev,
1222 struct device_attribute *attr, char *buf)
1223{
1224 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1225 unsigned long flags;
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001226 u32 *dump;
David Lopoaa69a802008-11-17 14:14:51 -08001227 unsigned i, k, n = 0;
1228
1229 dbg_trace("[%s] %p\n", __func__, buf);
1230 if (attr == NULL || buf == NULL) {
1231 dev_err(dev, "[%s] EINVAL\n", __func__);
1232 return 0;
1233 }
1234
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001235 dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL);
1236 if (!dump) {
1237 dev_err(dev, "%s: out of memory\n", __func__);
1238 return 0;
1239 }
1240
David Lopoaa69a802008-11-17 14:14:51 -08001241 spin_lock_irqsave(udc->lock, flags);
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001242 k = hw_register_read(dump, DUMP_ENTRIES);
David Lopoaa69a802008-11-17 14:14:51 -08001243 spin_unlock_irqrestore(udc->lock, flags);
1244
1245 for (i = 0; i < k; i++) {
1246 n += scnprintf(buf + n, PAGE_SIZE - n,
1247 "reg[0x%04X] = 0x%08X\n",
1248 i * (unsigned)sizeof(u32), dump[i]);
1249 }
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001250 kfree(dump);
David Lopoaa69a802008-11-17 14:14:51 -08001251
1252 return n;
1253}
1254
1255/**
1256 * store_registers: writes value to register address
1257 *
1258 * Check "device.h" for details
1259 */
1260static ssize_t store_registers(struct device *dev,
1261 struct device_attribute *attr,
1262 const char *buf, size_t count)
1263{
1264 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1265 unsigned long addr, data, flags;
1266
1267 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1268 if (attr == NULL || buf == NULL) {
1269 dev_err(dev, "[%s] EINVAL\n", __func__);
1270 goto done;
1271 }
1272
1273 if (sscanf(buf, "%li %li", &addr, &data) != 2) {
1274 dev_err(dev, "<addr> <data>: write data to register address");
1275 goto done;
1276 }
1277
1278 spin_lock_irqsave(udc->lock, flags);
1279 if (hw_register_write(addr, data))
1280 dev_err(dev, "invalid address range\n");
1281 spin_unlock_irqrestore(udc->lock, flags);
1282
1283 done:
1284 return count;
1285}
1286static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR,
1287 show_registers, store_registers);
1288
1289/**
1290 * show_requests: DMA contents of all requests currently queued (all endpts)
1291 *
1292 * Check "device.h" for details
1293 */
1294static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
1295 char *buf)
1296{
1297 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1298 unsigned long flags;
1299 struct list_head *ptr = NULL;
1300 struct ci13xxx_req *req = NULL;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301301 unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -08001302
1303 dbg_trace("[%s] %p\n", __func__, buf);
1304 if (attr == NULL || buf == NULL) {
1305 dev_err(dev, "[%s] EINVAL\n", __func__);
1306 return 0;
1307 }
1308
1309 spin_lock_irqsave(udc->lock, flags);
1310 for (i = 0; i < hw_ep_max; i++)
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301311 list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue)
1312 {
1313 req = list_entry(ptr, struct ci13xxx_req, queue);
David Lopoaa69a802008-11-17 14:14:51 -08001314
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301315 n += scnprintf(buf + n, PAGE_SIZE - n,
1316 "EP=%02i: TD=%08X %s\n",
1317 i % hw_ep_max/2, (u32)req->dma,
1318 ((i < hw_ep_max/2) ? "RX" : "TX"));
1319
1320 for (j = 0; j < qSize; j++)
David Lopoaa69a802008-11-17 14:14:51 -08001321 n += scnprintf(buf + n, PAGE_SIZE - n,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301322 " %04X: %08X\n", j,
1323 *((u32 *)req->ptr + j));
1324 }
David Lopoaa69a802008-11-17 14:14:51 -08001325 spin_unlock_irqrestore(udc->lock, flags);
1326
1327 return n;
1328}
1329static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL);
1330
1331/**
1332 * dbg_create_files: initializes the attribute interface
1333 * @dev: device
1334 *
1335 * This function returns an error code
1336 */
1337__maybe_unused static int dbg_create_files(struct device *dev)
1338{
1339 int retval = 0;
1340
1341 if (dev == NULL)
1342 return -EINVAL;
1343 retval = device_create_file(dev, &dev_attr_device);
1344 if (retval)
1345 goto done;
1346 retval = device_create_file(dev, &dev_attr_driver);
1347 if (retval)
1348 goto rm_device;
1349 retval = device_create_file(dev, &dev_attr_events);
1350 if (retval)
1351 goto rm_driver;
1352 retval = device_create_file(dev, &dev_attr_inters);
1353 if (retval)
1354 goto rm_events;
1355 retval = device_create_file(dev, &dev_attr_port_test);
1356 if (retval)
1357 goto rm_inters;
1358 retval = device_create_file(dev, &dev_attr_qheads);
1359 if (retval)
1360 goto rm_port_test;
1361 retval = device_create_file(dev, &dev_attr_registers);
1362 if (retval)
1363 goto rm_qheads;
1364 retval = device_create_file(dev, &dev_attr_requests);
1365 if (retval)
1366 goto rm_registers;
1367 return 0;
1368
1369 rm_registers:
1370 device_remove_file(dev, &dev_attr_registers);
1371 rm_qheads:
1372 device_remove_file(dev, &dev_attr_qheads);
1373 rm_port_test:
1374 device_remove_file(dev, &dev_attr_port_test);
1375 rm_inters:
1376 device_remove_file(dev, &dev_attr_inters);
1377 rm_events:
1378 device_remove_file(dev, &dev_attr_events);
1379 rm_driver:
1380 device_remove_file(dev, &dev_attr_driver);
1381 rm_device:
1382 device_remove_file(dev, &dev_attr_device);
1383 done:
1384 return retval;
1385}
1386
1387/**
1388 * dbg_remove_files: destroys the attribute interface
1389 * @dev: device
1390 *
1391 * This function returns an error code
1392 */
1393__maybe_unused static int dbg_remove_files(struct device *dev)
1394{
1395 if (dev == NULL)
1396 return -EINVAL;
1397 device_remove_file(dev, &dev_attr_requests);
1398 device_remove_file(dev, &dev_attr_registers);
1399 device_remove_file(dev, &dev_attr_qheads);
1400 device_remove_file(dev, &dev_attr_port_test);
1401 device_remove_file(dev, &dev_attr_inters);
1402 device_remove_file(dev, &dev_attr_events);
1403 device_remove_file(dev, &dev_attr_driver);
1404 device_remove_file(dev, &dev_attr_device);
1405 return 0;
1406}
1407
1408/******************************************************************************
1409 * UTIL block
1410 *****************************************************************************/
1411/**
1412 * _usb_addr: calculates endpoint address from direction & number
1413 * @ep: endpoint
1414 */
1415static inline u8 _usb_addr(struct ci13xxx_ep *ep)
1416{
1417 return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num;
1418}
1419
1420/**
1421 * _hardware_queue: configures a request at hardware level
1422 * @gadget: gadget
1423 * @mEp: endpoint
1424 *
1425 * This function returns an error code
1426 */
1427static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1428{
1429 unsigned i;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301430 int ret = 0;
1431 unsigned length = mReq->req.length;
David Lopoaa69a802008-11-17 14:14:51 -08001432
1433 trace("%p, %p", mEp, mReq);
1434
1435 /* don't queue twice */
1436 if (mReq->req.status == -EALREADY)
1437 return -EALREADY;
1438
David Lopoaa69a802008-11-17 14:14:51 -08001439 mReq->req.status = -EALREADY;
Michael Grzeschik954aad82011-10-10 18:38:06 +02001440 if (length && mReq->req.dma == DMA_ADDR_INVALID) {
David Lopoaa69a802008-11-17 14:14:51 -08001441 mReq->req.dma = \
1442 dma_map_single(mEp->device, mReq->req.buf,
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301443 length, mEp->dir ? DMA_TO_DEVICE :
1444 DMA_FROM_DEVICE);
David Lopoaa69a802008-11-17 14:14:51 -08001445 if (mReq->req.dma == 0)
1446 return -ENOMEM;
1447
1448 mReq->map = 1;
1449 }
1450
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301451 if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) {
1452 mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC,
1453 &mReq->zdma);
1454 if (mReq->zptr == NULL) {
1455 if (mReq->map) {
1456 dma_unmap_single(mEp->device, mReq->req.dma,
1457 length, mEp->dir ? DMA_TO_DEVICE :
1458 DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02001459 mReq->req.dma = DMA_ADDR_INVALID;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301460 mReq->map = 0;
1461 }
1462 return -ENOMEM;
1463 }
1464 memset(mReq->zptr, 0, sizeof(*mReq->zptr));
1465 mReq->zptr->next = TD_TERMINATE;
1466 mReq->zptr->token = TD_STATUS_ACTIVE;
1467 if (!mReq->req.no_interrupt)
1468 mReq->zptr->token |= TD_IOC;
1469 }
David Lopoaa69a802008-11-17 14:14:51 -08001470 /*
1471 * TD configuration
1472 * TODO - handle requests which spawns into several TDs
1473 */
1474 memset(mReq->ptr, 0, sizeof(*mReq->ptr));
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301475 mReq->ptr->token = length << ffs_nr(TD_TOTAL_BYTES);
David Lopoaa69a802008-11-17 14:14:51 -08001476 mReq->ptr->token &= TD_TOTAL_BYTES;
David Lopoaa69a802008-11-17 14:14:51 -08001477 mReq->ptr->token |= TD_STATUS_ACTIVE;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301478 if (mReq->zptr) {
1479 mReq->ptr->next = mReq->zdma;
1480 } else {
1481 mReq->ptr->next = TD_TERMINATE;
1482 if (!mReq->req.no_interrupt)
1483 mReq->ptr->token |= TD_IOC;
1484 }
David Lopoaa69a802008-11-17 14:14:51 -08001485 mReq->ptr->page[0] = mReq->req.dma;
1486 for (i = 1; i < 5; i++)
1487 mReq->ptr->page[i] =
Artem Leonenko0a313c42010-12-14 23:47:06 -08001488 (mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
David Lopoaa69a802008-11-17 14:14:51 -08001489
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301490 if (!list_empty(&mEp->qh.queue)) {
1491 struct ci13xxx_req *mReqPrev;
1492 int n = hw_ep_bit(mEp->num, mEp->dir);
1493 int tmp_stat;
1494
1495 mReqPrev = list_entry(mEp->qh.queue.prev,
1496 struct ci13xxx_req, queue);
1497 if (mReqPrev->zptr)
1498 mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK;
1499 else
1500 mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK;
1501 wmb();
1502 if (hw_cread(CAP_ENDPTPRIME, BIT(n)))
1503 goto done;
1504 do {
1505 hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
1506 tmp_stat = hw_cread(CAP_ENDPTSTAT, BIT(n));
1507 } while (!hw_cread(CAP_USBCMD, USBCMD_ATDTW));
1508 hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, 0);
1509 if (tmp_stat)
1510 goto done;
1511 }
1512
1513 /* QH configuration */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301514 mEp->qh.ptr->td.next = mReq->dma; /* TERMINATE = 0 */
1515 mEp->qh.ptr->td.token &= ~TD_STATUS; /* clear status */
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301516 mEp->qh.ptr->cap |= QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08001517
1518 wmb(); /* synchronize before ep prime */
1519
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301520 ret = hw_ep_prime(mEp->num, mEp->dir,
David Lopoaa69a802008-11-17 14:14:51 -08001521 mEp->type == USB_ENDPOINT_XFER_CONTROL);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301522done:
1523 return ret;
David Lopoaa69a802008-11-17 14:14:51 -08001524}
1525
1526/**
1527 * _hardware_dequeue: handles a request at hardware level
1528 * @gadget: gadget
1529 * @mEp: endpoint
1530 *
1531 * This function returns an error code
1532 */
1533static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1534{
1535 trace("%p, %p", mEp, mReq);
1536
1537 if (mReq->req.status != -EALREADY)
1538 return -EINVAL;
1539
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301540 if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0)
1541 return -EBUSY;
1542
1543 if (mReq->zptr) {
1544 if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
1545 return -EBUSY;
1546 dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
1547 mReq->zptr = NULL;
1548 }
David Lopoaa69a802008-11-17 14:14:51 -08001549
1550 mReq->req.status = 0;
1551
1552 if (mReq->map) {
1553 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
1554 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02001555 mReq->req.dma = DMA_ADDR_INVALID;
David Lopoaa69a802008-11-17 14:14:51 -08001556 mReq->map = 0;
1557 }
1558
1559 mReq->req.status = mReq->ptr->token & TD_STATUS;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301560 if ((TD_STATUS_HALTED & mReq->req.status) != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001561 mReq->req.status = -1;
1562 else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0)
1563 mReq->req.status = -1;
1564 else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0)
1565 mReq->req.status = -1;
1566
1567 mReq->req.actual = mReq->ptr->token & TD_TOTAL_BYTES;
1568 mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES);
1569 mReq->req.actual = mReq->req.length - mReq->req.actual;
1570 mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual;
1571
1572 return mReq->req.actual;
1573}
1574
1575/**
1576 * _ep_nuke: dequeues all endpoint requests
1577 * @mEp: endpoint
1578 *
1579 * This function returns an error code
1580 * Caller must hold lock
1581 */
1582static int _ep_nuke(struct ci13xxx_ep *mEp)
1583__releases(mEp->lock)
1584__acquires(mEp->lock)
1585{
1586 trace("%p", mEp);
1587
1588 if (mEp == NULL)
1589 return -EINVAL;
1590
1591 hw_ep_flush(mEp->num, mEp->dir);
1592
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301593 while (!list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08001594
1595 /* pop oldest request */
1596 struct ci13xxx_req *mReq = \
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301597 list_entry(mEp->qh.queue.next,
David Lopoaa69a802008-11-17 14:14:51 -08001598 struct ci13xxx_req, queue);
1599 list_del_init(&mReq->queue);
1600 mReq->req.status = -ESHUTDOWN;
1601
Artem Leonenko7c25a822010-12-14 23:46:55 -08001602 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08001603 spin_unlock(mEp->lock);
1604 mReq->req.complete(&mEp->ep, &mReq->req);
1605 spin_lock(mEp->lock);
1606 }
1607 }
1608 return 0;
1609}
1610
1611/**
1612 * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
1613 * @gadget: gadget
1614 *
1615 * This function returns an error code
David Lopoaa69a802008-11-17 14:14:51 -08001616 */
1617static int _gadget_stop_activity(struct usb_gadget *gadget)
David Lopoaa69a802008-11-17 14:14:51 -08001618{
1619 struct usb_ep *ep;
1620 struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301621 unsigned long flags;
David Lopoaa69a802008-11-17 14:14:51 -08001622
1623 trace("%p", gadget);
1624
1625 if (gadget == NULL)
1626 return -EINVAL;
1627
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301628 spin_lock_irqsave(udc->lock, flags);
1629 udc->gadget.speed = USB_SPEED_UNKNOWN;
1630 udc->remote_wakeup = 0;
1631 udc->suspended = 0;
1632 spin_unlock_irqrestore(udc->lock, flags);
1633
David Lopoaa69a802008-11-17 14:14:51 -08001634 /* flush all endpoints */
1635 gadget_for_each_ep(ep, gadget) {
1636 usb_ep_fifo_flush(ep);
1637 }
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301638 usb_ep_fifo_flush(&udc->ep0out.ep);
1639 usb_ep_fifo_flush(&udc->ep0in.ep);
David Lopoaa69a802008-11-17 14:14:51 -08001640
1641 udc->driver->disconnect(gadget);
1642
1643 /* make sure to disable all endpoints */
1644 gadget_for_each_ep(ep, gadget) {
1645 usb_ep_disable(ep);
1646 }
David Lopoaa69a802008-11-17 14:14:51 -08001647
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301648 if (udc->status != NULL) {
1649 usb_ep_free_request(&udc->ep0in.ep, udc->status);
1650 udc->status = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08001651 }
1652
David Lopoaa69a802008-11-17 14:14:51 -08001653 return 0;
1654}
1655
1656/******************************************************************************
1657 * ISR block
1658 *****************************************************************************/
1659/**
1660 * isr_reset_handler: USB reset interrupt handler
1661 * @udc: UDC device
1662 *
1663 * This function resets USB engine after a bus reset occurred
1664 */
1665static void isr_reset_handler(struct ci13xxx *udc)
1666__releases(udc->lock)
1667__acquires(udc->lock)
1668{
David Lopoaa69a802008-11-17 14:14:51 -08001669 int retval;
1670
1671 trace("%p", udc);
1672
1673 if (udc == NULL) {
1674 err("EINVAL");
1675 return;
1676 }
1677
1678 dbg_event(0xFF, "BUS RST", 0);
1679
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05301680 spin_unlock(udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001681 retval = _gadget_stop_activity(&udc->gadget);
1682 if (retval)
1683 goto done;
1684
1685 retval = hw_usb_reset();
1686 if (retval)
1687 goto done;
1688
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05301689 udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC);
1690 if (udc->status == NULL)
1691 retval = -ENOMEM;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301692
David Lopoaa69a802008-11-17 14:14:51 -08001693 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
Kuninori Morimoto29cc8892011-08-23 03:12:03 -07002106 mEp->ep.maxpacket = usb_endpoint_maxp(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002107
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
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302123 /*
2124 * Enable endpoints in the HW other than ep0 as ep0
2125 * is always enabled
2126 */
2127 if (mEp->num)
2128 retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type);
David Lopoaa69a802008-11-17 14:14:51 -08002129
2130 spin_unlock_irqrestore(mEp->lock, flags);
2131 return retval;
2132}
2133
2134/**
2135 * ep_disable: endpoint is no longer usable
2136 *
2137 * Check usb_ep_disable() at "usb_gadget.h" for details
2138 */
2139static int ep_disable(struct usb_ep *ep)
2140{
2141 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2142 int direction, retval = 0;
2143 unsigned long flags;
2144
2145 trace("%p", ep);
2146
2147 if (ep == NULL)
2148 return -EINVAL;
2149 else if (mEp->desc == NULL)
2150 return -EBUSY;
2151
2152 spin_lock_irqsave(mEp->lock, flags);
2153
2154 /* only internal SW should disable ctrl endpts */
2155
2156 direction = mEp->dir;
2157 do {
2158 dbg_event(_usb_addr(mEp), "DISABLE", 0);
2159
2160 retval |= _ep_nuke(mEp);
2161 retval |= hw_ep_disable(mEp->num, mEp->dir);
2162
2163 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2164 mEp->dir = (mEp->dir == TX) ? RX : TX;
2165
2166 } while (mEp->dir != direction);
2167
2168 mEp->desc = NULL;
2169
2170 spin_unlock_irqrestore(mEp->lock, flags);
2171 return retval;
2172}
2173
2174/**
2175 * ep_alloc_request: allocate a request object to use with this endpoint
2176 *
2177 * Check usb_ep_alloc_request() at "usb_gadget.h" for details
2178 */
2179static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
2180{
2181 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2182 struct ci13xxx_req *mReq = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002183
2184 trace("%p, %i", ep, gfp_flags);
2185
2186 if (ep == NULL) {
2187 err("EINVAL");
2188 return NULL;
2189 }
2190
David Lopoaa69a802008-11-17 14:14:51 -08002191 mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
2192 if (mReq != NULL) {
2193 INIT_LIST_HEAD(&mReq->queue);
Michael Grzeschik954aad82011-10-10 18:38:06 +02002194 mReq->req.dma = DMA_ADDR_INVALID;
David Lopoaa69a802008-11-17 14:14:51 -08002195
2196 mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
2197 &mReq->dma);
2198 if (mReq->ptr == NULL) {
2199 kfree(mReq);
2200 mReq = NULL;
2201 }
2202 }
2203
2204 dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
2205
David Lopoaa69a802008-11-17 14:14:51 -08002206 return (mReq == NULL) ? NULL : &mReq->req;
2207}
2208
2209/**
2210 * ep_free_request: frees a request object
2211 *
2212 * Check usb_ep_free_request() at "usb_gadget.h" for details
2213 */
2214static void ep_free_request(struct usb_ep *ep, struct usb_request *req)
2215{
2216 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2217 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2218 unsigned long flags;
2219
2220 trace("%p, %p", ep, req);
2221
2222 if (ep == NULL || req == NULL) {
2223 err("EINVAL");
2224 return;
2225 } else if (!list_empty(&mReq->queue)) {
2226 err("EBUSY");
2227 return;
2228 }
2229
2230 spin_lock_irqsave(mEp->lock, flags);
2231
2232 if (mReq->ptr)
2233 dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma);
2234 kfree(mReq);
2235
2236 dbg_event(_usb_addr(mEp), "FREE", 0);
2237
2238 spin_unlock_irqrestore(mEp->lock, flags);
2239}
2240
2241/**
2242 * ep_queue: queues (submits) an I/O request to an endpoint
2243 *
2244 * Check usb_ep_queue()* at usb_gadget.h" for details
2245 */
2246static int ep_queue(struct usb_ep *ep, struct usb_request *req,
2247 gfp_t __maybe_unused gfp_flags)
2248{
2249 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2250 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2251 int retval = 0;
2252 unsigned long flags;
2253
2254 trace("%p, %p, %X", ep, req, gfp_flags);
2255
2256 if (ep == NULL || req == NULL || mEp->desc == NULL)
2257 return -EINVAL;
2258
2259 spin_lock_irqsave(mEp->lock, flags);
2260
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302261 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
2262 if (req->length)
2263 mEp = (_udc->ep0_dir == RX) ?
2264 &_udc->ep0out : &_udc->ep0in;
2265 if (!list_empty(&mEp->qh.queue)) {
2266 _ep_nuke(mEp);
2267 retval = -EOVERFLOW;
2268 warn("endpoint ctrl %X nuked", _usb_addr(mEp));
2269 }
David Lopoaa69a802008-11-17 14:14:51 -08002270 }
2271
2272 /* first nuke then test link, e.g. previous status has not sent */
2273 if (!list_empty(&mReq->queue)) {
2274 retval = -EBUSY;
2275 err("request already in queue");
2276 goto done;
2277 }
2278
Artem Leonenko0a313c42010-12-14 23:47:06 -08002279 if (req->length > (4 * CI13XXX_PAGE_SIZE)) {
2280 req->length = (4 * CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002281 retval = -EMSGSIZE;
2282 warn("request length truncated");
2283 }
2284
2285 dbg_queue(_usb_addr(mEp), req, retval);
2286
2287 /* push request */
2288 mReq->req.status = -EINPROGRESS;
2289 mReq->req.actual = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002290
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302291 retval = _hardware_enqueue(mEp, mReq);
Artem Leonenkod9bb9c12010-12-14 23:45:50 -08002292
2293 if (retval == -EALREADY) {
David Lopoaa69a802008-11-17 14:14:51 -08002294 dbg_event(_usb_addr(mEp), "QUEUE", retval);
2295 retval = 0;
2296 }
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302297 if (!retval)
2298 list_add_tail(&mReq->queue, &mEp->qh.queue);
David Lopoaa69a802008-11-17 14:14:51 -08002299
2300 done:
2301 spin_unlock_irqrestore(mEp->lock, flags);
2302 return retval;
2303}
2304
2305/**
2306 * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint
2307 *
2308 * Check usb_ep_dequeue() at "usb_gadget.h" for details
2309 */
2310static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
2311{
2312 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2313 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2314 unsigned long flags;
2315
2316 trace("%p, %p", ep, req);
2317
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302318 if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
2319 mEp->desc == NULL || list_empty(&mReq->queue) ||
2320 list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002321 return -EINVAL;
2322
2323 spin_lock_irqsave(mEp->lock, flags);
2324
2325 dbg_event(_usb_addr(mEp), "DEQUEUE", 0);
2326
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302327 hw_ep_flush(mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002328
2329 /* pop request */
2330 list_del_init(&mReq->queue);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302331 if (mReq->map) {
2332 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
2333 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02002334 mReq->req.dma = DMA_ADDR_INVALID;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302335 mReq->map = 0;
2336 }
David Lopoaa69a802008-11-17 14:14:51 -08002337 req->status = -ECONNRESET;
2338
Artem Leonenko7c25a822010-12-14 23:46:55 -08002339 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08002340 spin_unlock(mEp->lock);
2341 mReq->req.complete(&mEp->ep, &mReq->req);
2342 spin_lock(mEp->lock);
2343 }
2344
2345 spin_unlock_irqrestore(mEp->lock, flags);
2346 return 0;
2347}
2348
2349/**
2350 * ep_set_halt: sets the endpoint halt feature
2351 *
2352 * Check usb_ep_set_halt() at "usb_gadget.h" for details
2353 */
2354static int ep_set_halt(struct usb_ep *ep, int value)
2355{
2356 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2357 int direction, retval = 0;
2358 unsigned long flags;
2359
2360 trace("%p, %i", ep, value);
2361
2362 if (ep == NULL || mEp->desc == NULL)
2363 return -EINVAL;
2364
2365 spin_lock_irqsave(mEp->lock, flags);
2366
2367#ifndef STALL_IN
2368 /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
2369 if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302370 !list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08002371 spin_unlock_irqrestore(mEp->lock, flags);
2372 return -EAGAIN;
2373 }
2374#endif
2375
2376 direction = mEp->dir;
2377 do {
2378 dbg_event(_usb_addr(mEp), "HALT", value);
2379 retval |= hw_ep_set_halt(mEp->num, mEp->dir, value);
2380
2381 if (!value)
2382 mEp->wedge = 0;
2383
2384 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2385 mEp->dir = (mEp->dir == TX) ? RX : TX;
2386
2387 } while (mEp->dir != direction);
2388
2389 spin_unlock_irqrestore(mEp->lock, flags);
2390 return retval;
2391}
2392
2393/**
2394 * ep_set_wedge: sets the halt feature and ignores clear requests
2395 *
2396 * Check usb_ep_set_wedge() at "usb_gadget.h" for details
2397 */
2398static int ep_set_wedge(struct usb_ep *ep)
2399{
2400 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2401 unsigned long flags;
2402
2403 trace("%p", ep);
2404
2405 if (ep == NULL || mEp->desc == NULL)
2406 return -EINVAL;
2407
2408 spin_lock_irqsave(mEp->lock, flags);
2409
2410 dbg_event(_usb_addr(mEp), "WEDGE", 0);
2411 mEp->wedge = 1;
2412
2413 spin_unlock_irqrestore(mEp->lock, flags);
2414
2415 return usb_ep_set_halt(ep);
2416}
2417
2418/**
2419 * ep_fifo_flush: flushes contents of a fifo
2420 *
2421 * Check usb_ep_fifo_flush() at "usb_gadget.h" for details
2422 */
2423static void ep_fifo_flush(struct usb_ep *ep)
2424{
2425 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2426 unsigned long flags;
2427
2428 trace("%p", ep);
2429
2430 if (ep == NULL) {
2431 err("%02X: -EINVAL", _usb_addr(mEp));
2432 return;
2433 }
2434
2435 spin_lock_irqsave(mEp->lock, flags);
2436
2437 dbg_event(_usb_addr(mEp), "FFLUSH", 0);
2438 hw_ep_flush(mEp->num, mEp->dir);
2439
2440 spin_unlock_irqrestore(mEp->lock, flags);
2441}
2442
2443/**
2444 * Endpoint-specific part of the API to the USB controller hardware
2445 * Check "usb_gadget.h" for details
2446 */
2447static const struct usb_ep_ops usb_ep_ops = {
2448 .enable = ep_enable,
2449 .disable = ep_disable,
2450 .alloc_request = ep_alloc_request,
2451 .free_request = ep_free_request,
2452 .queue = ep_queue,
2453 .dequeue = ep_dequeue,
2454 .set_halt = ep_set_halt,
2455 .set_wedge = ep_set_wedge,
2456 .fifo_flush = ep_fifo_flush,
2457};
2458
2459/******************************************************************************
2460 * GADGET block
2461 *****************************************************************************/
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302462static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
2463{
2464 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2465 unsigned long flags;
2466 int gadget_ready = 0;
2467
2468 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS))
2469 return -EOPNOTSUPP;
2470
2471 spin_lock_irqsave(udc->lock, flags);
2472 udc->vbus_active = is_active;
2473 if (udc->driver)
2474 gadget_ready = 1;
2475 spin_unlock_irqrestore(udc->lock, flags);
2476
2477 if (gadget_ready) {
2478 if (is_active) {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302479 pm_runtime_get_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302480 hw_device_reset(udc);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302481 hw_device_state(udc->ep0out.qh.dma);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302482 } else {
2483 hw_device_state(0);
2484 if (udc->udc_driver->notify_event)
2485 udc->udc_driver->notify_event(udc,
2486 CI13XXX_CONTROLLER_STOPPED_EVENT);
2487 _gadget_stop_activity(&udc->gadget);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302488 pm_runtime_put_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302489 }
2490 }
2491
2492 return 0;
2493}
2494
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302495static int ci13xxx_wakeup(struct usb_gadget *_gadget)
2496{
2497 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2498 unsigned long flags;
2499 int ret = 0;
2500
2501 trace();
2502
2503 spin_lock_irqsave(udc->lock, flags);
2504 if (!udc->remote_wakeup) {
2505 ret = -EOPNOTSUPP;
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002506 trace("remote wakeup feature is not enabled\n");
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302507 goto out;
2508 }
2509 if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) {
2510 ret = -EINVAL;
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002511 trace("port is not suspended\n");
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302512 goto out;
2513 }
2514 hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR);
2515out:
2516 spin_unlock_irqrestore(udc->lock, flags);
2517 return ret;
2518}
2519
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302520static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
2521{
2522 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2523
2524 if (udc->transceiver)
2525 return otg_set_power(udc->transceiver, mA);
2526 return -ENOTSUPP;
2527}
2528
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002529static int ci13xxx_start(struct usb_gadget_driver *driver,
2530 int (*bind)(struct usb_gadget *));
2531static int ci13xxx_stop(struct usb_gadget_driver *driver);
David Lopoaa69a802008-11-17 14:14:51 -08002532/**
2533 * Device operations part of the API to the USB controller hardware,
2534 * which don't involve endpoints (or i/o)
2535 * Check "usb_gadget.h" for details
2536 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302537static const struct usb_gadget_ops usb_gadget_ops = {
2538 .vbus_session = ci13xxx_vbus_session,
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302539 .wakeup = ci13xxx_wakeup,
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302540 .vbus_draw = ci13xxx_vbus_draw,
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002541 .start = ci13xxx_start,
2542 .stop = ci13xxx_stop,
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302543};
David Lopoaa69a802008-11-17 14:14:51 -08002544
2545/**
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002546 * ci13xxx_start: register a gadget driver
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002547 * @driver: the driver being registered
2548 * @bind: the driver's bind callback
David Lopoaa69a802008-11-17 14:14:51 -08002549 *
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002550 * Check ci13xxx_start() at <linux/usb/gadget.h> for details.
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002551 * Interrupts are enabled here.
David Lopoaa69a802008-11-17 14:14:51 -08002552 */
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002553static int ci13xxx_start(struct usb_gadget_driver *driver,
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002554 int (*bind)(struct usb_gadget *))
David Lopoaa69a802008-11-17 14:14:51 -08002555{
2556 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302557 unsigned long flags;
2558 int i, j;
David Lopoaa69a802008-11-17 14:14:51 -08002559 int retval = -ENOMEM;
2560
2561 trace("%p", driver);
2562
2563 if (driver == NULL ||
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002564 bind == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002565 driver->setup == NULL ||
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002566 driver->disconnect == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002567 return -EINVAL;
2568 else if (udc == NULL)
2569 return -ENODEV;
2570 else if (udc->driver != NULL)
2571 return -EBUSY;
2572
2573 /* alloc resources */
2574 udc->qh_pool = dma_pool_create("ci13xxx_qh", &udc->gadget.dev,
2575 sizeof(struct ci13xxx_qh),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002576 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002577 if (udc->qh_pool == NULL)
2578 return -ENOMEM;
2579
2580 udc->td_pool = dma_pool_create("ci13xxx_td", &udc->gadget.dev,
2581 sizeof(struct ci13xxx_td),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002582 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002583 if (udc->td_pool == NULL) {
2584 dma_pool_destroy(udc->qh_pool);
2585 udc->qh_pool = NULL;
2586 return -ENOMEM;
2587 }
2588
2589 spin_lock_irqsave(udc->lock, flags);
2590
2591 info("hw_ep_max = %d", hw_ep_max);
2592
David Lopoaa69a802008-11-17 14:14:51 -08002593 udc->gadget.dev.driver = NULL;
2594
2595 retval = 0;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302596 for (i = 0; i < hw_ep_max/2; i++) {
2597 for (j = RX; j <= TX; j++) {
2598 int k = i + j * hw_ep_max/2;
2599 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k];
David Lopoaa69a802008-11-17 14:14:51 -08002600
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302601 scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i,
2602 (j == TX) ? "in" : "out");
David Lopoaa69a802008-11-17 14:14:51 -08002603
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302604 mEp->lock = udc->lock;
2605 mEp->device = &udc->gadget.dev;
2606 mEp->td_pool = udc->td_pool;
David Lopoaa69a802008-11-17 14:14:51 -08002607
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302608 mEp->ep.name = mEp->name;
2609 mEp->ep.ops = &usb_ep_ops;
2610 mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
David Lopoaa69a802008-11-17 14:14:51 -08002611
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302612 INIT_LIST_HEAD(&mEp->qh.queue);
Pavankumar Kondeti0a91efa2010-12-07 17:54:00 +05302613 spin_unlock_irqrestore(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302614 mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL,
2615 &mEp->qh.dma);
Pavankumar Kondeti0a91efa2010-12-07 17:54:00 +05302616 spin_lock_irqsave(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302617 if (mEp->qh.ptr == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002618 retval = -ENOMEM;
2619 else
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302620 memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr));
2621
2622 /* skip ep0 out and in endpoints */
2623 if (i == 0)
2624 continue;
2625
David Lopoaa69a802008-11-17 14:14:51 -08002626 list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302627 }
David Lopoaa69a802008-11-17 14:14:51 -08002628 }
2629 if (retval)
2630 goto done;
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302631 spin_unlock_irqrestore(udc->lock, flags);
Felipe Balbi877c1f52011-06-29 16:41:57 +03002632 udc->ep0out.ep.desc = &ctrl_endpt_out_desc;
2633 retval = usb_ep_enable(&udc->ep0out.ep);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302634 if (retval)
2635 return retval;
Felipe Balbi877c1f52011-06-29 16:41:57 +03002636
2637 udc->ep0in.ep.desc = &ctrl_endpt_in_desc;
2638 retval = usb_ep_enable(&udc->ep0in.ep);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302639 if (retval)
2640 return retval;
2641 spin_lock_irqsave(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002642
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302643 udc->gadget.ep0 = &udc->ep0in.ep;
David Lopoaa69a802008-11-17 14:14:51 -08002644 /* bind gadget */
2645 driver->driver.bus = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002646 udc->gadget.dev.driver = &driver->driver;
2647
2648 spin_unlock_irqrestore(udc->lock, flags);
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002649 retval = bind(&udc->gadget); /* MAY SLEEP */
David Lopoaa69a802008-11-17 14:14:51 -08002650 spin_lock_irqsave(udc->lock, flags);
2651
2652 if (retval) {
David Lopoaa69a802008-11-17 14:14:51 -08002653 udc->gadget.dev.driver = NULL;
2654 goto done;
2655 }
2656
Pavankumar Kondeti49d3df52011-01-11 09:19:21 +05302657 udc->driver = driver;
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302658 pm_runtime_get_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302659 if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) {
2660 if (udc->vbus_active) {
2661 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED)
2662 hw_device_reset(udc);
2663 } else {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302664 pm_runtime_put_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302665 goto done;
2666 }
2667 }
2668
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302669 retval = hw_device_state(udc->ep0out.qh.dma);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302670 if (retval)
2671 pm_runtime_put_sync(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002672
2673 done:
2674 spin_unlock_irqrestore(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002675 return retval;
2676}
David Lopoaa69a802008-11-17 14:14:51 -08002677
2678/**
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002679 * ci13xxx_stop: unregister a gadget driver
David Lopoaa69a802008-11-17 14:14:51 -08002680 *
2681 * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
2682 */
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002683static int ci13xxx_stop(struct usb_gadget_driver *driver)
David Lopoaa69a802008-11-17 14:14:51 -08002684{
2685 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302686 unsigned long i, flags;
David Lopoaa69a802008-11-17 14:14:51 -08002687
2688 trace("%p", driver);
2689
2690 if (driver == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002691 driver->unbind == NULL ||
2692 driver->setup == NULL ||
2693 driver->disconnect == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002694 driver != udc->driver)
2695 return -EINVAL;
2696
2697 spin_lock_irqsave(udc->lock, flags);
2698
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302699 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) ||
2700 udc->vbus_active) {
2701 hw_device_state(0);
2702 if (udc->udc_driver->notify_event)
2703 udc->udc_driver->notify_event(udc,
2704 CI13XXX_CONTROLLER_STOPPED_EVENT);
Marc Kleine-Buddefd537c02011-10-10 18:38:07 +02002705 spin_unlock_irqrestore(udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302706 _gadget_stop_activity(&udc->gadget);
Marc Kleine-Buddefd537c02011-10-10 18:38:07 +02002707 spin_lock_irqsave(udc->lock, flags);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302708 pm_runtime_put(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302709 }
David Lopoaa69a802008-11-17 14:14:51 -08002710
2711 /* unbind gadget */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302712 spin_unlock_irqrestore(udc->lock, flags);
2713 driver->unbind(&udc->gadget); /* MAY SLEEP */
2714 spin_lock_irqsave(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002715
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302716 udc->gadget.dev.driver = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002717
2718 /* free resources */
2719 for (i = 0; i < hw_ep_max; i++) {
2720 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
2721
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302722 if (!list_empty(&mEp->ep.ep_list))
David Lopoaa69a802008-11-17 14:14:51 -08002723 list_del_init(&mEp->ep.ep_list);
2724
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302725 if (mEp->qh.ptr != NULL)
2726 dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08002727 }
2728
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302729 udc->gadget.ep0 = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002730 udc->driver = NULL;
2731
2732 spin_unlock_irqrestore(udc->lock, flags);
2733
2734 if (udc->td_pool != NULL) {
2735 dma_pool_destroy(udc->td_pool);
2736 udc->td_pool = NULL;
2737 }
2738 if (udc->qh_pool != NULL) {
2739 dma_pool_destroy(udc->qh_pool);
2740 udc->qh_pool = NULL;
2741 }
2742
2743 return 0;
2744}
David Lopoaa69a802008-11-17 14:14:51 -08002745
2746/******************************************************************************
2747 * BUS block
2748 *****************************************************************************/
2749/**
2750 * udc_irq: global interrupt handler
2751 *
2752 * This function returns IRQ_HANDLED if the IRQ has been handled
2753 * It locks access to registers
2754 */
2755static irqreturn_t udc_irq(void)
2756{
2757 struct ci13xxx *udc = _udc;
2758 irqreturn_t retval;
2759 u32 intr;
2760
2761 trace();
2762
2763 if (udc == NULL) {
2764 err("ENODEV");
2765 return IRQ_HANDLED;
2766 }
2767
2768 spin_lock(udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302769
2770 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) {
2771 if (hw_cread(CAP_USBMODE, USBMODE_CM) !=
2772 USBMODE_CM_DEVICE) {
2773 spin_unlock(udc->lock);
2774 return IRQ_NONE;
2775 }
2776 }
David Lopoaa69a802008-11-17 14:14:51 -08002777 intr = hw_test_and_clear_intr_active();
2778 if (intr) {
2779 isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr;
2780 isr_statistics.hndl.idx &= ISR_MASK;
2781 isr_statistics.hndl.cnt++;
2782
2783 /* order defines priority - do NOT change it */
2784 if (USBi_URI & intr) {
2785 isr_statistics.uri++;
2786 isr_reset_handler(udc);
2787 }
2788 if (USBi_PCI & intr) {
2789 isr_statistics.pci++;
2790 udc->gadget.speed = hw_port_is_high_speed() ?
2791 USB_SPEED_HIGH : USB_SPEED_FULL;
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002792 if (udc->suspended && udc->driver->resume) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302793 spin_unlock(udc->lock);
2794 udc->driver->resume(&udc->gadget);
2795 spin_lock(udc->lock);
2796 udc->suspended = 0;
2797 }
David Lopoaa69a802008-11-17 14:14:51 -08002798 }
2799 if (USBi_UEI & intr)
2800 isr_statistics.uei++;
2801 if (USBi_UI & intr) {
2802 isr_statistics.ui++;
2803 isr_tr_complete_handler(udc);
2804 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302805 if (USBi_SLI & intr) {
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002806 if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
2807 udc->driver->suspend) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302808 udc->suspended = 1;
2809 spin_unlock(udc->lock);
2810 udc->driver->suspend(&udc->gadget);
2811 spin_lock(udc->lock);
2812 }
David Lopoaa69a802008-11-17 14:14:51 -08002813 isr_statistics.sli++;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302814 }
David Lopoaa69a802008-11-17 14:14:51 -08002815 retval = IRQ_HANDLED;
2816 } else {
2817 isr_statistics.none++;
2818 retval = IRQ_NONE;
2819 }
2820 spin_unlock(udc->lock);
2821
2822 return retval;
2823}
2824
2825/**
2826 * udc_release: driver release function
2827 * @dev: device
2828 *
2829 * Currently does nothing
2830 */
2831static void udc_release(struct device *dev)
2832{
2833 trace("%p", dev);
2834
2835 if (dev == NULL)
2836 err("EINVAL");
2837}
2838
2839/**
2840 * udc_probe: parent probe must call this to initialize UDC
2841 * @dev: parent device
2842 * @regs: registers base address
2843 * @name: driver name
2844 *
2845 * This function returns an error code
2846 * No interrupts active, the IRQ has not been requested yet
2847 * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask
2848 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302849static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
2850 void __iomem *regs)
David Lopoaa69a802008-11-17 14:14:51 -08002851{
2852 struct ci13xxx *udc;
2853 int retval = 0;
2854
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002855 trace("%p, %p, %p", dev, regs, driver->name);
David Lopoaa69a802008-11-17 14:14:51 -08002856
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302857 if (dev == NULL || regs == NULL || driver == NULL ||
2858 driver->name == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002859 return -EINVAL;
2860
2861 udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL);
2862 if (udc == NULL)
2863 return -ENOMEM;
2864
2865 udc->lock = &udc_lock;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302866 udc->regs = regs;
2867 udc->udc_driver = driver;
David Lopoaa69a802008-11-17 14:14:51 -08002868
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302869 udc->gadget.ops = &usb_gadget_ops;
David Lopoaa69a802008-11-17 14:14:51 -08002870 udc->gadget.speed = USB_SPEED_UNKNOWN;
2871 udc->gadget.is_dualspeed = 1;
2872 udc->gadget.is_otg = 0;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302873 udc->gadget.name = driver->name;
David Lopoaa69a802008-11-17 14:14:51 -08002874
2875 INIT_LIST_HEAD(&udc->gadget.ep_list);
2876 udc->gadget.ep0 = NULL;
2877
Kay Sievers5df58522009-03-24 16:38:23 -07002878 dev_set_name(&udc->gadget.dev, "gadget");
David Lopoaa69a802008-11-17 14:14:51 -08002879 udc->gadget.dev.dma_mask = dev->dma_mask;
Pavankumar Kondeti61948ee2010-12-07 17:54:01 +05302880 udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask;
David Lopoaa69a802008-11-17 14:14:51 -08002881 udc->gadget.dev.parent = dev;
2882 udc->gadget.dev.release = udc_release;
2883
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302884 retval = hw_device_init(regs);
2885 if (retval < 0)
2886 goto free_udc;
2887
2888 udc->transceiver = otg_get_transceiver();
2889
2890 if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
2891 if (udc->transceiver == NULL) {
2892 retval = -ENODEV;
2893 goto free_udc;
2894 }
2895 }
2896
2897 if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) {
2898 retval = hw_device_reset(udc);
2899 if (retval)
2900 goto put_transceiver;
2901 }
2902
David Lopoaa69a802008-11-17 14:14:51 -08002903 retval = device_register(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302904 if (retval) {
2905 put_device(&udc->gadget.dev);
2906 goto put_transceiver;
2907 }
David Lopoaa69a802008-11-17 14:14:51 -08002908
2909#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2910 retval = dbg_create_files(&udc->gadget.dev);
2911#endif
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302912 if (retval)
2913 goto unreg_device;
2914
2915 if (udc->transceiver) {
2916 retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
2917 if (retval)
2918 goto remove_dbg;
David Lopoaa69a802008-11-17 14:14:51 -08002919 }
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002920
2921 retval = usb_add_gadget_udc(dev, &udc->gadget);
2922 if (retval)
2923 goto remove_trans;
2924
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302925 pm_runtime_no_callbacks(&udc->gadget.dev);
2926 pm_runtime_enable(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002927
2928 _udc = udc;
2929 return retval;
2930
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002931remove_trans:
2932 if (udc->transceiver) {
2933 otg_set_peripheral(udc->transceiver, &udc->gadget);
2934 otg_put_transceiver(udc->transceiver);
2935 }
2936
David Lopoaa69a802008-11-17 14:14:51 -08002937 err("error = %i", retval);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302938remove_dbg:
2939#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2940 dbg_remove_files(&udc->gadget.dev);
2941#endif
2942unreg_device:
2943 device_unregister(&udc->gadget.dev);
2944put_transceiver:
2945 if (udc->transceiver)
2946 otg_put_transceiver(udc->transceiver);
2947free_udc:
David Lopoaa69a802008-11-17 14:14:51 -08002948 kfree(udc);
2949 _udc = NULL;
2950 return retval;
2951}
2952
2953/**
2954 * udc_remove: parent remove must call this to remove UDC
2955 *
2956 * No interrupts active, the IRQ has been released
2957 */
2958static void udc_remove(void)
2959{
2960 struct ci13xxx *udc = _udc;
2961
2962 if (udc == NULL) {
2963 err("EINVAL");
2964 return;
2965 }
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002966 usb_del_gadget_udc(&udc->gadget);
David Lopoaa69a802008-11-17 14:14:51 -08002967
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302968 if (udc->transceiver) {
2969 otg_set_peripheral(udc->transceiver, &udc->gadget);
2970 otg_put_transceiver(udc->transceiver);
2971 }
David Lopoaa69a802008-11-17 14:14:51 -08002972#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2973 dbg_remove_files(&udc->gadget.dev);
2974#endif
2975 device_unregister(&udc->gadget.dev);
2976
2977 kfree(udc);
2978 _udc = NULL;
2979}