blob: 8956a2448b33857aed708194064946581884b36d [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
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200185static int ep_to_bit(int n)
186{
187 int fill = 16 - hw_ep_max / 2;
188
189 if (n >= hw_ep_max / 2)
190 n += fill;
191
192 return n;
193}
194
David Lopoaa69a802008-11-17 14:14:51 -0800195/**
196 * hw_aread: reads from register bitfield
197 * @addr: address relative to bus map
198 * @mask: bitfield mask
199 *
200 * This function returns register bitfield data
201 */
202static u32 hw_aread(u32 addr, u32 mask)
203{
204 return ioread32(addr + hw_bank.abs) & mask;
205}
206
207/**
208 * hw_awrite: writes to register bitfield
209 * @addr: address relative to bus map
210 * @mask: bitfield mask
211 * @data: new data
212 */
213static void hw_awrite(u32 addr, u32 mask, u32 data)
214{
215 iowrite32(hw_aread(addr, ~mask) | (data & mask),
216 addr + hw_bank.abs);
217}
218
219/**
220 * hw_cread: reads from register bitfield
221 * @addr: address relative to CAP offset plus content
222 * @mask: bitfield mask
223 *
224 * This function returns register bitfield data
225 */
226static u32 hw_cread(u32 addr, u32 mask)
227{
228 return ioread32(addr + hw_bank.cap) & mask;
229}
230
231/**
232 * hw_cwrite: writes to register bitfield
233 * @addr: address relative to CAP offset plus content
234 * @mask: bitfield mask
235 * @data: new data
236 */
237static void hw_cwrite(u32 addr, u32 mask, u32 data)
238{
239 iowrite32(hw_cread(addr, ~mask) | (data & mask),
240 addr + hw_bank.cap);
241}
242
243/**
244 * hw_ctest_and_clear: tests & clears register bitfield
245 * @addr: address relative to CAP offset plus content
246 * @mask: bitfield mask
247 *
248 * This function returns register bitfield data
249 */
250static u32 hw_ctest_and_clear(u32 addr, u32 mask)
251{
252 u32 reg = hw_cread(addr, mask);
253
254 iowrite32(reg, addr + hw_bank.cap);
255 return reg;
256}
257
258/**
259 * hw_ctest_and_write: tests & writes register bitfield
260 * @addr: address relative to CAP offset plus content
261 * @mask: bitfield mask
262 * @data: new data
263 *
264 * This function returns register bitfield data
265 */
266static u32 hw_ctest_and_write(u32 addr, u32 mask, u32 data)
267{
268 u32 reg = hw_cread(addr, ~0);
269
270 iowrite32((reg & ~mask) | (data & mask), addr + hw_bank.cap);
271 return (reg & mask) >> ffs_nr(mask);
272}
273
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530274static int hw_device_init(void __iomem *base)
David Lopoaa69a802008-11-17 14:14:51 -0800275{
276 u32 reg;
277
278 /* bank is a module variable */
279 hw_bank.abs = base;
280
281 hw_bank.cap = hw_bank.abs;
282 hw_bank.cap += ABS_CAPLENGTH;
283 hw_bank.cap += ioread8(hw_bank.cap);
284
285 reg = hw_aread(ABS_HCCPARAMS, HCCPARAMS_LEN) >> ffs_nr(HCCPARAMS_LEN);
286 hw_bank.lpm = reg;
287 hw_bank.size = hw_bank.cap - hw_bank.abs;
288 hw_bank.size += CAP_LAST;
289 hw_bank.size /= sizeof(u32);
290
David Lopoaa69a802008-11-17 14:14:51 -0800291 reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530292 hw_ep_max = reg * 2; /* cache hw ENDPT_MAX */
David Lopoaa69a802008-11-17 14:14:51 -0800293
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530294 if (hw_ep_max == 0 || hw_ep_max > ENDPT_MAX)
295 return -ENODEV;
David Lopoaa69a802008-11-17 14:14:51 -0800296
297 /* setup lock mode ? */
298
299 /* ENDPTSETUPSTAT is '0' by default */
300
301 /* HCSPARAMS.bf.ppc SHOULD BE zero for device */
302
303 return 0;
304}
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530305/**
306 * hw_device_reset: resets chip (execute without interruption)
307 * @base: register base address
308 *
309 * This function returns an error code
310 */
311static int hw_device_reset(struct ci13xxx *udc)
312{
313 /* should flush & stop before reset */
314 hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0);
315 hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
316
317 hw_cwrite(CAP_USBCMD, USBCMD_RST, USBCMD_RST);
318 while (hw_cread(CAP_USBCMD, USBCMD_RST))
319 udelay(10); /* not RTOS friendly */
320
321
322 if (udc->udc_driver->notify_event)
323 udc->udc_driver->notify_event(udc,
324 CI13XXX_CONTROLLER_RESET_EVENT);
325
Pavankumar Kondeti8c2387a2011-05-02 11:56:28 +0530326 if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530327 hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
328
329 /* USBMODE should be configured step by step */
330 hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
331 hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE);
332 hw_cwrite(CAP_USBMODE, USBMODE_SLOM, USBMODE_SLOM); /* HW >= 2.3 */
333
334 if (hw_cread(CAP_USBMODE, USBMODE_CM) != USBMODE_CM_DEVICE) {
335 pr_err("cannot enter in device mode");
336 pr_err("lpm = %i", hw_bank.lpm);
337 return -ENODEV;
338 }
339
340 return 0;
341}
David Lopoaa69a802008-11-17 14:14:51 -0800342
343/**
344 * hw_device_state: enables/disables interrupts & starts/stops device (execute
345 * without interruption)
346 * @dma: 0 => disable, !0 => enable and set dma engine
347 *
348 * This function returns an error code
349 */
350static int hw_device_state(u32 dma)
351{
352 if (dma) {
353 hw_cwrite(CAP_ENDPTLISTADDR, ~0, dma);
354 /* interrupt, error, port change, reset, sleep/suspend */
355 hw_cwrite(CAP_USBINTR, ~0,
356 USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
357 hw_cwrite(CAP_USBCMD, USBCMD_RS, USBCMD_RS);
358 } else {
359 hw_cwrite(CAP_USBCMD, USBCMD_RS, 0);
360 hw_cwrite(CAP_USBINTR, ~0, 0);
361 }
362 return 0;
363}
364
365/**
366 * hw_ep_flush: flush endpoint fifo (execute without interruption)
367 * @num: endpoint number
368 * @dir: endpoint direction
369 *
370 * This function returns an error code
371 */
372static int hw_ep_flush(int num, int dir)
373{
374 int n = hw_ep_bit(num, dir);
375
376 do {
377 /* flush any pending transfer */
378 hw_cwrite(CAP_ENDPTFLUSH, BIT(n), BIT(n));
379 while (hw_cread(CAP_ENDPTFLUSH, BIT(n)))
380 cpu_relax();
381 } while (hw_cread(CAP_ENDPTSTAT, BIT(n)));
382
383 return 0;
384}
385
386/**
387 * hw_ep_disable: disables endpoint (execute without interruption)
388 * @num: endpoint number
389 * @dir: endpoint direction
390 *
391 * This function returns an error code
392 */
393static int hw_ep_disable(int num, int dir)
394{
395 hw_ep_flush(num, dir);
396 hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32),
397 dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
398 return 0;
399}
400
401/**
402 * hw_ep_enable: enables endpoint (execute without interruption)
403 * @num: endpoint number
404 * @dir: endpoint direction
405 * @type: endpoint type
406 *
407 * This function returns an error code
408 */
409static int hw_ep_enable(int num, int dir, int type)
410{
411 u32 mask, data;
412
413 if (dir) {
414 mask = ENDPTCTRL_TXT; /* type */
415 data = type << ffs_nr(mask);
416
417 mask |= ENDPTCTRL_TXS; /* unstall */
418 mask |= ENDPTCTRL_TXR; /* reset data toggle */
419 data |= ENDPTCTRL_TXR;
420 mask |= ENDPTCTRL_TXE; /* enable */
421 data |= ENDPTCTRL_TXE;
422 } else {
423 mask = ENDPTCTRL_RXT; /* type */
424 data = type << ffs_nr(mask);
425
426 mask |= ENDPTCTRL_RXS; /* unstall */
427 mask |= ENDPTCTRL_RXR; /* reset data toggle */
428 data |= ENDPTCTRL_RXR;
429 mask |= ENDPTCTRL_RXE; /* enable */
430 data |= ENDPTCTRL_RXE;
431 }
432 hw_cwrite(CAP_ENDPTCTRL + num * sizeof(u32), mask, data);
433 return 0;
434}
435
436/**
437 * hw_ep_get_halt: return endpoint halt status
438 * @num: endpoint number
439 * @dir: endpoint direction
440 *
441 * This function returns 1 if endpoint halted
442 */
443static int hw_ep_get_halt(int num, int dir)
444{
445 u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
446
447 return hw_cread(CAP_ENDPTCTRL + num * sizeof(u32), mask) ? 1 : 0;
448}
449
450/**
David Lopoaa69a802008-11-17 14:14:51 -0800451 * hw_test_and_clear_setup_status: test & clear setup status (execute without
452 * interruption)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200453 * @n: endpoint number
David Lopoaa69a802008-11-17 14:14:51 -0800454 *
455 * This function returns setup status
456 */
457static int hw_test_and_clear_setup_status(int n)
458{
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200459 n = ep_to_bit(n);
David Lopoaa69a802008-11-17 14:14:51 -0800460 return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n));
461}
462
463/**
464 * hw_ep_prime: primes endpoint (execute without interruption)
465 * @num: endpoint number
466 * @dir: endpoint direction
467 * @is_ctrl: true if control endpoint
468 *
469 * This function returns an error code
470 */
471static int hw_ep_prime(int num, int dir, int is_ctrl)
472{
473 int n = hw_ep_bit(num, dir);
474
David Lopoaa69a802008-11-17 14:14:51 -0800475 if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
476 return -EAGAIN;
477
478 hw_cwrite(CAP_ENDPTPRIME, BIT(n), BIT(n));
479
480 while (hw_cread(CAP_ENDPTPRIME, BIT(n)))
481 cpu_relax();
482 if (is_ctrl && dir == RX && hw_cread(CAP_ENDPTSETUPSTAT, BIT(num)))
483 return -EAGAIN;
484
485 /* status shoult be tested according with manual but it doesn't work */
486 return 0;
487}
488
489/**
490 * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute
491 * without interruption)
492 * @num: endpoint number
493 * @dir: endpoint direction
494 * @value: true => stall, false => unstall
495 *
496 * This function returns an error code
497 */
498static int hw_ep_set_halt(int num, int dir, int value)
499{
500 if (value != 0 && value != 1)
501 return -EINVAL;
502
503 do {
504 u32 addr = CAP_ENDPTCTRL + num * sizeof(u32);
505 u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
506 u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
507
508 /* data toggle - reserved for EP0 but it's in ESS */
509 hw_cwrite(addr, mask_xs|mask_xr, value ? mask_xs : mask_xr);
510
511 } while (value != hw_ep_get_halt(num, dir));
512
513 return 0;
514}
515
516/**
517 * hw_intr_clear: disables interrupt & clears interrupt status (execute without
518 * interruption)
519 * @n: interrupt bit
520 *
521 * This function returns an error code
522 */
523static int hw_intr_clear(int n)
524{
525 if (n >= REG_BITS)
526 return -EINVAL;
527
528 hw_cwrite(CAP_USBINTR, BIT(n), 0);
529 hw_cwrite(CAP_USBSTS, BIT(n), BIT(n));
530 return 0;
531}
532
533/**
534 * hw_intr_force: enables interrupt & forces interrupt status (execute without
535 * interruption)
536 * @n: interrupt bit
537 *
538 * This function returns an error code
539 */
540static int hw_intr_force(int n)
541{
542 if (n >= REG_BITS)
543 return -EINVAL;
544
545 hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE);
546 hw_cwrite(CAP_USBINTR, BIT(n), BIT(n));
547 hw_cwrite(CAP_USBSTS, BIT(n), BIT(n));
548 hw_awrite(ABS_TESTMODE, TESTMODE_FORCE, 0);
549 return 0;
550}
551
552/**
553 * hw_is_port_high_speed: test if port is high speed
554 *
555 * This function returns true if high speed port
556 */
557static int hw_port_is_high_speed(void)
558{
559 return hw_bank.lpm ? hw_cread(CAP_DEVLC, DEVLC_PSPD) :
560 hw_cread(CAP_PORTSC, PORTSC_HSP);
561}
562
563/**
564 * hw_port_test_get: reads port test mode value
565 *
566 * This function returns port test mode value
567 */
568static u8 hw_port_test_get(void)
569{
570 return hw_cread(CAP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC);
571}
572
573/**
574 * hw_port_test_set: writes port test mode (execute without interruption)
575 * @mode: new value
576 *
577 * This function returns an error code
578 */
579static int hw_port_test_set(u8 mode)
580{
581 const u8 TEST_MODE_MAX = 7;
582
583 if (mode > TEST_MODE_MAX)
584 return -EINVAL;
585
586 hw_cwrite(CAP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC));
587 return 0;
588}
589
590/**
591 * hw_read_intr_enable: returns interrupt enable register
592 *
593 * This function returns register data
594 */
595static u32 hw_read_intr_enable(void)
596{
597 return hw_cread(CAP_USBINTR, ~0);
598}
599
600/**
601 * hw_read_intr_status: returns interrupt status register
602 *
603 * This function returns register data
604 */
605static u32 hw_read_intr_status(void)
606{
607 return hw_cread(CAP_USBSTS, ~0);
608}
609
610/**
611 * hw_register_read: reads all device registers (execute without interruption)
612 * @buf: destination buffer
613 * @size: buffer size
614 *
615 * This function returns number of registers read
616 */
617static size_t hw_register_read(u32 *buf, size_t size)
618{
619 unsigned i;
620
621 if (size > hw_bank.size)
622 size = hw_bank.size;
623
624 for (i = 0; i < size; i++)
625 buf[i] = hw_aread(i * sizeof(u32), ~0);
626
627 return size;
628}
629
630/**
631 * hw_register_write: writes to register
632 * @addr: register address
633 * @data: register value
634 *
635 * This function returns an error code
636 */
637static int hw_register_write(u16 addr, u32 data)
638{
639 /* align */
640 addr /= sizeof(u32);
641
642 if (addr >= hw_bank.size)
643 return -EINVAL;
644
645 /* align */
646 addr *= sizeof(u32);
647
648 hw_awrite(addr, ~0, data);
649 return 0;
650}
651
652/**
653 * hw_test_and_clear_complete: test & clear complete status (execute without
654 * interruption)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200655 * @n: endpoint number
David Lopoaa69a802008-11-17 14:14:51 -0800656 *
657 * This function returns complete status
658 */
659static int hw_test_and_clear_complete(int n)
660{
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200661 n = ep_to_bit(n);
David Lopoaa69a802008-11-17 14:14:51 -0800662 return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n));
663}
664
665/**
666 * hw_test_and_clear_intr_active: test & clear active interrupts (execute
667 * without interruption)
668 *
669 * This function returns active interrutps
670 */
671static u32 hw_test_and_clear_intr_active(void)
672{
673 u32 reg = hw_read_intr_status() & hw_read_intr_enable();
674
675 hw_cwrite(CAP_USBSTS, ~0, reg);
676 return reg;
677}
678
679/**
680 * hw_test_and_clear_setup_guard: test & clear setup guard (execute without
681 * interruption)
682 *
683 * This function returns guard value
684 */
685static int hw_test_and_clear_setup_guard(void)
686{
687 return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, 0);
688}
689
690/**
691 * hw_test_and_set_setup_guard: test & set setup guard (execute without
692 * interruption)
693 *
694 * This function returns guard value
695 */
696static int hw_test_and_set_setup_guard(void)
697{
698 return hw_ctest_and_write(CAP_USBCMD, USBCMD_SUTW, USBCMD_SUTW);
699}
700
701/**
702 * hw_usb_set_address: configures USB address (execute without interruption)
703 * @value: new USB address
704 *
705 * This function returns an error code
706 */
707static int hw_usb_set_address(u8 value)
708{
709 /* advance */
710 hw_cwrite(CAP_DEVICEADDR, DEVICEADDR_USBADR | DEVICEADDR_USBADRA,
711 value << ffs_nr(DEVICEADDR_USBADR) | DEVICEADDR_USBADRA);
712 return 0;
713}
714
715/**
716 * hw_usb_reset: restart device after a bus reset (execute without
717 * interruption)
718 *
719 * This function returns an error code
720 */
721static int hw_usb_reset(void)
722{
723 hw_usb_set_address(0);
724
725 /* ESS flushes only at end?!? */
726 hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); /* flush all EPs */
727
728 /* clear setup token semaphores */
729 hw_cwrite(CAP_ENDPTSETUPSTAT, 0, 0); /* writes its content */
730
731 /* clear complete status */
732 hw_cwrite(CAP_ENDPTCOMPLETE, 0, 0); /* writes its content */
733
734 /* wait until all bits cleared */
735 while (hw_cread(CAP_ENDPTPRIME, ~0))
736 udelay(10); /* not RTOS friendly */
737
738 /* reset all endpoints ? */
739
740 /* reset internal status and wait for further instructions
741 no need to verify the port reset status (ESS does it) */
742
743 return 0;
744}
745
746/******************************************************************************
747 * DBG block
748 *****************************************************************************/
749/**
750 * show_device: prints information about device capabilities and status
751 *
752 * Check "device.h" for details
753 */
754static ssize_t show_device(struct device *dev, struct device_attribute *attr,
755 char *buf)
756{
757 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
758 struct usb_gadget *gadget = &udc->gadget;
759 int n = 0;
760
761 dbg_trace("[%s] %p\n", __func__, buf);
762 if (attr == NULL || buf == NULL) {
763 dev_err(dev, "[%s] EINVAL\n", __func__);
764 return 0;
765 }
766
767 n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n",
768 gadget->speed);
769 n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n",
770 gadget->is_dualspeed);
771 n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
772 gadget->is_otg);
773 n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
774 gadget->is_a_peripheral);
775 n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n",
776 gadget->b_hnp_enable);
777 n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n",
778 gadget->a_hnp_support);
779 n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n",
780 gadget->a_alt_hnp_support);
781 n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n",
782 (gadget->name ? gadget->name : ""));
783
784 return n;
785}
786static DEVICE_ATTR(device, S_IRUSR, show_device, NULL);
787
788/**
789 * show_driver: prints information about attached gadget (if any)
790 *
791 * Check "device.h" for details
792 */
793static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
794 char *buf)
795{
796 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
797 struct usb_gadget_driver *driver = udc->driver;
798 int n = 0;
799
800 dbg_trace("[%s] %p\n", __func__, buf);
801 if (attr == NULL || buf == NULL) {
802 dev_err(dev, "[%s] EINVAL\n", __func__);
803 return 0;
804 }
805
806 if (driver == NULL)
807 return scnprintf(buf, PAGE_SIZE,
808 "There is no gadget attached!\n");
809
810 n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n",
811 (driver->function ? driver->function : ""));
812 n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n",
813 driver->speed);
814
815 return n;
816}
817static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);
818
819/* Maximum event message length */
820#define DBG_DATA_MSG 64UL
821
822/* Maximum event messages */
823#define DBG_DATA_MAX 128UL
824
825/* Event buffer descriptor */
826static struct {
827 char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
828 unsigned idx; /* index */
829 unsigned tty; /* print to console? */
830 rwlock_t lck; /* lock */
831} dbg_data = {
832 .idx = 0,
833 .tty = 0,
834 .lck = __RW_LOCK_UNLOCKED(lck)
835};
836
837/**
838 * dbg_dec: decrements debug event index
839 * @idx: buffer index
840 */
841static void dbg_dec(unsigned *idx)
842{
843 *idx = (*idx - 1) & (DBG_DATA_MAX-1);
844}
845
846/**
847 * dbg_inc: increments debug event index
848 * @idx: buffer index
849 */
850static void dbg_inc(unsigned *idx)
851{
852 *idx = (*idx + 1) & (DBG_DATA_MAX-1);
853}
854
855/**
856 * dbg_print: prints the common part of the event
857 * @addr: endpoint address
858 * @name: event name
859 * @status: status
860 * @extra: extra information
861 */
862static void dbg_print(u8 addr, const char *name, int status, const char *extra)
863{
864 struct timeval tval;
865 unsigned int stamp;
866 unsigned long flags;
867
868 write_lock_irqsave(&dbg_data.lck, flags);
869
870 do_gettimeofday(&tval);
871 stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s */
872 stamp = stamp * 1000000 + tval.tv_usec;
873
874 scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +0300875 "%04X\t? %02X %-7.7s %4i ?\t%s\n",
David Lopoaa69a802008-11-17 14:14:51 -0800876 stamp, addr, name, status, extra);
877
878 dbg_inc(&dbg_data.idx);
879
880 write_unlock_irqrestore(&dbg_data.lck, flags);
881
882 if (dbg_data.tty != 0)
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +0300883 pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n",
David Lopoaa69a802008-11-17 14:14:51 -0800884 stamp, addr, name, status, extra);
885}
886
887/**
888 * dbg_done: prints a DONE event
889 * @addr: endpoint address
890 * @td: transfer descriptor
891 * @status: status
892 */
893static void dbg_done(u8 addr, const u32 token, int status)
894{
895 char msg[DBG_DATA_MSG];
896
897 scnprintf(msg, sizeof(msg), "%d %02X",
898 (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES),
899 (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS));
900 dbg_print(addr, "DONE", status, msg);
901}
902
903/**
904 * dbg_event: prints a generic event
905 * @addr: endpoint address
906 * @name: event name
907 * @status: status
908 */
909static void dbg_event(u8 addr, const char *name, int status)
910{
911 if (name != NULL)
912 dbg_print(addr, name, status, "");
913}
914
915/*
916 * dbg_queue: prints a QUEUE event
917 * @addr: endpoint address
918 * @req: USB request
919 * @status: status
920 */
921static void dbg_queue(u8 addr, const struct usb_request *req, int status)
922{
923 char msg[DBG_DATA_MSG];
924
925 if (req != NULL) {
926 scnprintf(msg, sizeof(msg),
927 "%d %d", !req->no_interrupt, req->length);
928 dbg_print(addr, "QUEUE", status, msg);
929 }
930}
931
932/**
933 * dbg_setup: prints a SETUP event
934 * @addr: endpoint address
935 * @req: setup request
936 */
937static void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
938{
939 char msg[DBG_DATA_MSG];
940
941 if (req != NULL) {
942 scnprintf(msg, sizeof(msg),
943 "%02X %02X %04X %04X %d", req->bRequestType,
944 req->bRequest, le16_to_cpu(req->wValue),
945 le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
946 dbg_print(addr, "SETUP", 0, msg);
947 }
948}
949
950/**
951 * show_events: displays the event buffer
952 *
953 * Check "device.h" for details
954 */
955static ssize_t show_events(struct device *dev, struct device_attribute *attr,
956 char *buf)
957{
958 unsigned long flags;
959 unsigned i, j, n = 0;
960
961 dbg_trace("[%s] %p\n", __func__, buf);
962 if (attr == NULL || buf == NULL) {
963 dev_err(dev, "[%s] EINVAL\n", __func__);
964 return 0;
965 }
966
967 read_lock_irqsave(&dbg_data.lck, flags);
968
969 i = dbg_data.idx;
970 for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) {
971 n += strlen(dbg_data.buf[i]);
972 if (n >= PAGE_SIZE) {
973 n -= strlen(dbg_data.buf[i]);
974 break;
975 }
976 }
977 for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i))
978 j += scnprintf(buf + j, PAGE_SIZE - j,
979 "%s", dbg_data.buf[i]);
980
981 read_unlock_irqrestore(&dbg_data.lck, flags);
982
983 return n;
984}
985
986/**
987 * store_events: configure if events are going to be also printed to console
988 *
989 * Check "device.h" for details
990 */
991static ssize_t store_events(struct device *dev, struct device_attribute *attr,
992 const char *buf, size_t count)
993{
994 unsigned tty;
995
996 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
997 if (attr == NULL || buf == NULL) {
998 dev_err(dev, "[%s] EINVAL\n", __func__);
999 goto done;
1000 }
1001
1002 if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
1003 dev_err(dev, "<1|0>: enable|disable console log\n");
1004 goto done;
1005 }
1006
1007 dbg_data.tty = tty;
1008 dev_info(dev, "tty = %u", dbg_data.tty);
1009
1010 done:
1011 return count;
1012}
1013static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events);
1014
1015/**
1016 * show_inters: interrupt status, enable status and historic
1017 *
1018 * Check "device.h" for details
1019 */
1020static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
1021 char *buf)
1022{
1023 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1024 unsigned long flags;
1025 u32 intr;
1026 unsigned i, j, n = 0;
1027
1028 dbg_trace("[%s] %p\n", __func__, buf);
1029 if (attr == NULL || buf == NULL) {
1030 dev_err(dev, "[%s] EINVAL\n", __func__);
1031 return 0;
1032 }
1033
1034 spin_lock_irqsave(udc->lock, flags);
1035
1036 n += scnprintf(buf + n, PAGE_SIZE - n,
1037 "status = %08x\n", hw_read_intr_status());
1038 n += scnprintf(buf + n, PAGE_SIZE - n,
1039 "enable = %08x\n", hw_read_intr_enable());
1040
1041 n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
1042 isr_statistics.test);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001043 n += scnprintf(buf + n, PAGE_SIZE - n, "? ui = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001044 isr_statistics.ui);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001045 n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001046 isr_statistics.uei);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001047 n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001048 isr_statistics.pci);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001049 n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001050 isr_statistics.uri);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001051 n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001052 isr_statistics.sli);
1053 n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
1054 isr_statistics.none);
1055 n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n",
1056 isr_statistics.hndl.cnt);
1057
1058 for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) {
1059 i &= ISR_MASK;
1060 intr = isr_statistics.hndl.buf[i];
1061
1062 if (USBi_UI & intr)
1063 n += scnprintf(buf + n, PAGE_SIZE - n, "ui ");
1064 intr &= ~USBi_UI;
1065 if (USBi_UEI & intr)
1066 n += scnprintf(buf + n, PAGE_SIZE - n, "uei ");
1067 intr &= ~USBi_UEI;
1068 if (USBi_PCI & intr)
1069 n += scnprintf(buf + n, PAGE_SIZE - n, "pci ");
1070 intr &= ~USBi_PCI;
1071 if (USBi_URI & intr)
1072 n += scnprintf(buf + n, PAGE_SIZE - n, "uri ");
1073 intr &= ~USBi_URI;
1074 if (USBi_SLI & intr)
1075 n += scnprintf(buf + n, PAGE_SIZE - n, "sli ");
1076 intr &= ~USBi_SLI;
1077 if (intr)
1078 n += scnprintf(buf + n, PAGE_SIZE - n, "??? ");
1079 if (isr_statistics.hndl.buf[i])
1080 n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
1081 }
1082
1083 spin_unlock_irqrestore(udc->lock, flags);
1084
1085 return n;
1086}
1087
1088/**
1089 * store_inters: enable & force or disable an individual interrutps
1090 * (to be used for test purposes only)
1091 *
1092 * Check "device.h" for details
1093 */
1094static ssize_t store_inters(struct device *dev, struct device_attribute *attr,
1095 const char *buf, size_t count)
1096{
1097 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1098 unsigned long flags;
1099 unsigned en, bit;
1100
1101 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1102 if (attr == NULL || buf == NULL) {
1103 dev_err(dev, "[%s] EINVAL\n", __func__);
1104 goto done;
1105 }
1106
1107 if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) {
1108 dev_err(dev, "<1|0> <bit>: enable|disable interrupt");
1109 goto done;
1110 }
1111
1112 spin_lock_irqsave(udc->lock, flags);
1113 if (en) {
1114 if (hw_intr_force(bit))
1115 dev_err(dev, "invalid bit number\n");
1116 else
1117 isr_statistics.test++;
1118 } else {
1119 if (hw_intr_clear(bit))
1120 dev_err(dev, "invalid bit number\n");
1121 }
1122 spin_unlock_irqrestore(udc->lock, flags);
1123
1124 done:
1125 return count;
1126}
1127static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters);
1128
1129/**
1130 * show_port_test: reads port test mode
1131 *
1132 * Check "device.h" for details
1133 */
1134static ssize_t show_port_test(struct device *dev,
1135 struct device_attribute *attr, char *buf)
1136{
1137 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1138 unsigned long flags;
1139 unsigned mode;
1140
1141 dbg_trace("[%s] %p\n", __func__, buf);
1142 if (attr == NULL || buf == NULL) {
1143 dev_err(dev, "[%s] EINVAL\n", __func__);
1144 return 0;
1145 }
1146
1147 spin_lock_irqsave(udc->lock, flags);
1148 mode = hw_port_test_get();
1149 spin_unlock_irqrestore(udc->lock, flags);
1150
1151 return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode);
1152}
1153
1154/**
1155 * store_port_test: writes port test mode
1156 *
1157 * Check "device.h" for details
1158 */
1159static ssize_t store_port_test(struct device *dev,
1160 struct device_attribute *attr,
1161 const char *buf, size_t count)
1162{
1163 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1164 unsigned long flags;
1165 unsigned mode;
1166
1167 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1168 if (attr == NULL || buf == NULL) {
1169 dev_err(dev, "[%s] EINVAL\n", __func__);
1170 goto done;
1171 }
1172
1173 if (sscanf(buf, "%u", &mode) != 1) {
1174 dev_err(dev, "<mode>: set port test mode");
1175 goto done;
1176 }
1177
1178 spin_lock_irqsave(udc->lock, flags);
1179 if (hw_port_test_set(mode))
1180 dev_err(dev, "invalid mode\n");
1181 spin_unlock_irqrestore(udc->lock, flags);
1182
1183 done:
1184 return count;
1185}
1186static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR,
1187 show_port_test, store_port_test);
1188
1189/**
1190 * show_qheads: DMA contents of all queue heads
1191 *
1192 * Check "device.h" for details
1193 */
1194static ssize_t show_qheads(struct device *dev, struct device_attribute *attr,
1195 char *buf)
1196{
1197 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1198 unsigned long flags;
1199 unsigned i, j, n = 0;
1200
1201 dbg_trace("[%s] %p\n", __func__, buf);
1202 if (attr == NULL || buf == NULL) {
1203 dev_err(dev, "[%s] EINVAL\n", __func__);
1204 return 0;
1205 }
1206
1207 spin_lock_irqsave(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301208 for (i = 0; i < hw_ep_max/2; i++) {
1209 struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i];
1210 struct ci13xxx_ep *mEpTx = &udc->ci13xxx_ep[i + hw_ep_max/2];
David Lopoaa69a802008-11-17 14:14:51 -08001211 n += scnprintf(buf + n, PAGE_SIZE - n,
1212 "EP=%02i: RX=%08X TX=%08X\n",
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301213 i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08001214 for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) {
1215 n += scnprintf(buf + n, PAGE_SIZE - n,
1216 " %04X: %08X %08X\n", j,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301217 *((u32 *)mEpRx->qh.ptr + j),
1218 *((u32 *)mEpTx->qh.ptr + j));
David Lopoaa69a802008-11-17 14:14:51 -08001219 }
1220 }
1221 spin_unlock_irqrestore(udc->lock, flags);
1222
1223 return n;
1224}
1225static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL);
1226
1227/**
1228 * show_registers: dumps all registers
1229 *
1230 * Check "device.h" for details
1231 */
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001232#define DUMP_ENTRIES 512
David Lopoaa69a802008-11-17 14:14:51 -08001233static ssize_t show_registers(struct device *dev,
1234 struct device_attribute *attr, char *buf)
1235{
1236 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1237 unsigned long flags;
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001238 u32 *dump;
David Lopoaa69a802008-11-17 14:14:51 -08001239 unsigned i, k, n = 0;
1240
1241 dbg_trace("[%s] %p\n", __func__, buf);
1242 if (attr == NULL || buf == NULL) {
1243 dev_err(dev, "[%s] EINVAL\n", __func__);
1244 return 0;
1245 }
1246
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001247 dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL);
1248 if (!dump) {
1249 dev_err(dev, "%s: out of memory\n", __func__);
1250 return 0;
1251 }
1252
David Lopoaa69a802008-11-17 14:14:51 -08001253 spin_lock_irqsave(udc->lock, flags);
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001254 k = hw_register_read(dump, DUMP_ENTRIES);
David Lopoaa69a802008-11-17 14:14:51 -08001255 spin_unlock_irqrestore(udc->lock, flags);
1256
1257 for (i = 0; i < k; i++) {
1258 n += scnprintf(buf + n, PAGE_SIZE - n,
1259 "reg[0x%04X] = 0x%08X\n",
1260 i * (unsigned)sizeof(u32), dump[i]);
1261 }
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001262 kfree(dump);
David Lopoaa69a802008-11-17 14:14:51 -08001263
1264 return n;
1265}
1266
1267/**
1268 * store_registers: writes value to register address
1269 *
1270 * Check "device.h" for details
1271 */
1272static ssize_t store_registers(struct device *dev,
1273 struct device_attribute *attr,
1274 const char *buf, size_t count)
1275{
1276 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1277 unsigned long addr, data, flags;
1278
1279 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1280 if (attr == NULL || buf == NULL) {
1281 dev_err(dev, "[%s] EINVAL\n", __func__);
1282 goto done;
1283 }
1284
1285 if (sscanf(buf, "%li %li", &addr, &data) != 2) {
1286 dev_err(dev, "<addr> <data>: write data to register address");
1287 goto done;
1288 }
1289
1290 spin_lock_irqsave(udc->lock, flags);
1291 if (hw_register_write(addr, data))
1292 dev_err(dev, "invalid address range\n");
1293 spin_unlock_irqrestore(udc->lock, flags);
1294
1295 done:
1296 return count;
1297}
1298static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR,
1299 show_registers, store_registers);
1300
1301/**
1302 * show_requests: DMA contents of all requests currently queued (all endpts)
1303 *
1304 * Check "device.h" for details
1305 */
1306static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
1307 char *buf)
1308{
1309 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1310 unsigned long flags;
1311 struct list_head *ptr = NULL;
1312 struct ci13xxx_req *req = NULL;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301313 unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -08001314
1315 dbg_trace("[%s] %p\n", __func__, buf);
1316 if (attr == NULL || buf == NULL) {
1317 dev_err(dev, "[%s] EINVAL\n", __func__);
1318 return 0;
1319 }
1320
1321 spin_lock_irqsave(udc->lock, flags);
1322 for (i = 0; i < hw_ep_max; i++)
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301323 list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue)
1324 {
1325 req = list_entry(ptr, struct ci13xxx_req, queue);
David Lopoaa69a802008-11-17 14:14:51 -08001326
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301327 n += scnprintf(buf + n, PAGE_SIZE - n,
1328 "EP=%02i: TD=%08X %s\n",
1329 i % hw_ep_max/2, (u32)req->dma,
1330 ((i < hw_ep_max/2) ? "RX" : "TX"));
1331
1332 for (j = 0; j < qSize; j++)
David Lopoaa69a802008-11-17 14:14:51 -08001333 n += scnprintf(buf + n, PAGE_SIZE - n,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301334 " %04X: %08X\n", j,
1335 *((u32 *)req->ptr + j));
1336 }
David Lopoaa69a802008-11-17 14:14:51 -08001337 spin_unlock_irqrestore(udc->lock, flags);
1338
1339 return n;
1340}
1341static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL);
1342
1343/**
1344 * dbg_create_files: initializes the attribute interface
1345 * @dev: device
1346 *
1347 * This function returns an error code
1348 */
1349__maybe_unused static int dbg_create_files(struct device *dev)
1350{
1351 int retval = 0;
1352
1353 if (dev == NULL)
1354 return -EINVAL;
1355 retval = device_create_file(dev, &dev_attr_device);
1356 if (retval)
1357 goto done;
1358 retval = device_create_file(dev, &dev_attr_driver);
1359 if (retval)
1360 goto rm_device;
1361 retval = device_create_file(dev, &dev_attr_events);
1362 if (retval)
1363 goto rm_driver;
1364 retval = device_create_file(dev, &dev_attr_inters);
1365 if (retval)
1366 goto rm_events;
1367 retval = device_create_file(dev, &dev_attr_port_test);
1368 if (retval)
1369 goto rm_inters;
1370 retval = device_create_file(dev, &dev_attr_qheads);
1371 if (retval)
1372 goto rm_port_test;
1373 retval = device_create_file(dev, &dev_attr_registers);
1374 if (retval)
1375 goto rm_qheads;
1376 retval = device_create_file(dev, &dev_attr_requests);
1377 if (retval)
1378 goto rm_registers;
1379 return 0;
1380
1381 rm_registers:
1382 device_remove_file(dev, &dev_attr_registers);
1383 rm_qheads:
1384 device_remove_file(dev, &dev_attr_qheads);
1385 rm_port_test:
1386 device_remove_file(dev, &dev_attr_port_test);
1387 rm_inters:
1388 device_remove_file(dev, &dev_attr_inters);
1389 rm_events:
1390 device_remove_file(dev, &dev_attr_events);
1391 rm_driver:
1392 device_remove_file(dev, &dev_attr_driver);
1393 rm_device:
1394 device_remove_file(dev, &dev_attr_device);
1395 done:
1396 return retval;
1397}
1398
1399/**
1400 * dbg_remove_files: destroys the attribute interface
1401 * @dev: device
1402 *
1403 * This function returns an error code
1404 */
1405__maybe_unused static int dbg_remove_files(struct device *dev)
1406{
1407 if (dev == NULL)
1408 return -EINVAL;
1409 device_remove_file(dev, &dev_attr_requests);
1410 device_remove_file(dev, &dev_attr_registers);
1411 device_remove_file(dev, &dev_attr_qheads);
1412 device_remove_file(dev, &dev_attr_port_test);
1413 device_remove_file(dev, &dev_attr_inters);
1414 device_remove_file(dev, &dev_attr_events);
1415 device_remove_file(dev, &dev_attr_driver);
1416 device_remove_file(dev, &dev_attr_device);
1417 return 0;
1418}
1419
1420/******************************************************************************
1421 * UTIL block
1422 *****************************************************************************/
1423/**
1424 * _usb_addr: calculates endpoint address from direction & number
1425 * @ep: endpoint
1426 */
1427static inline u8 _usb_addr(struct ci13xxx_ep *ep)
1428{
1429 return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num;
1430}
1431
1432/**
1433 * _hardware_queue: configures a request at hardware level
1434 * @gadget: gadget
1435 * @mEp: endpoint
1436 *
1437 * This function returns an error code
1438 */
1439static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1440{
1441 unsigned i;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301442 int ret = 0;
1443 unsigned length = mReq->req.length;
David Lopoaa69a802008-11-17 14:14:51 -08001444
1445 trace("%p, %p", mEp, mReq);
1446
1447 /* don't queue twice */
1448 if (mReq->req.status == -EALREADY)
1449 return -EALREADY;
1450
David Lopoaa69a802008-11-17 14:14:51 -08001451 mReq->req.status = -EALREADY;
Michael Grzeschik954aad82011-10-10 18:38:06 +02001452 if (length && mReq->req.dma == DMA_ADDR_INVALID) {
David Lopoaa69a802008-11-17 14:14:51 -08001453 mReq->req.dma = \
1454 dma_map_single(mEp->device, mReq->req.buf,
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301455 length, mEp->dir ? DMA_TO_DEVICE :
1456 DMA_FROM_DEVICE);
David Lopoaa69a802008-11-17 14:14:51 -08001457 if (mReq->req.dma == 0)
1458 return -ENOMEM;
1459
1460 mReq->map = 1;
1461 }
1462
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301463 if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) {
1464 mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC,
1465 &mReq->zdma);
1466 if (mReq->zptr == NULL) {
1467 if (mReq->map) {
1468 dma_unmap_single(mEp->device, mReq->req.dma,
1469 length, mEp->dir ? DMA_TO_DEVICE :
1470 DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02001471 mReq->req.dma = DMA_ADDR_INVALID;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301472 mReq->map = 0;
1473 }
1474 return -ENOMEM;
1475 }
1476 memset(mReq->zptr, 0, sizeof(*mReq->zptr));
1477 mReq->zptr->next = TD_TERMINATE;
1478 mReq->zptr->token = TD_STATUS_ACTIVE;
1479 if (!mReq->req.no_interrupt)
1480 mReq->zptr->token |= TD_IOC;
1481 }
David Lopoaa69a802008-11-17 14:14:51 -08001482 /*
1483 * TD configuration
1484 * TODO - handle requests which spawns into several TDs
1485 */
1486 memset(mReq->ptr, 0, sizeof(*mReq->ptr));
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301487 mReq->ptr->token = length << ffs_nr(TD_TOTAL_BYTES);
David Lopoaa69a802008-11-17 14:14:51 -08001488 mReq->ptr->token &= TD_TOTAL_BYTES;
David Lopoaa69a802008-11-17 14:14:51 -08001489 mReq->ptr->token |= TD_STATUS_ACTIVE;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301490 if (mReq->zptr) {
1491 mReq->ptr->next = mReq->zdma;
1492 } else {
1493 mReq->ptr->next = TD_TERMINATE;
1494 if (!mReq->req.no_interrupt)
1495 mReq->ptr->token |= TD_IOC;
1496 }
David Lopoaa69a802008-11-17 14:14:51 -08001497 mReq->ptr->page[0] = mReq->req.dma;
1498 for (i = 1; i < 5; i++)
1499 mReq->ptr->page[i] =
Artem Leonenko0a313c42010-12-14 23:47:06 -08001500 (mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
David Lopoaa69a802008-11-17 14:14:51 -08001501
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301502 if (!list_empty(&mEp->qh.queue)) {
1503 struct ci13xxx_req *mReqPrev;
1504 int n = hw_ep_bit(mEp->num, mEp->dir);
1505 int tmp_stat;
1506
1507 mReqPrev = list_entry(mEp->qh.queue.prev,
1508 struct ci13xxx_req, queue);
1509 if (mReqPrev->zptr)
1510 mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK;
1511 else
1512 mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK;
1513 wmb();
1514 if (hw_cread(CAP_ENDPTPRIME, BIT(n)))
1515 goto done;
1516 do {
1517 hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
1518 tmp_stat = hw_cread(CAP_ENDPTSTAT, BIT(n));
1519 } while (!hw_cread(CAP_USBCMD, USBCMD_ATDTW));
1520 hw_cwrite(CAP_USBCMD, USBCMD_ATDTW, 0);
1521 if (tmp_stat)
1522 goto done;
1523 }
1524
1525 /* QH configuration */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301526 mEp->qh.ptr->td.next = mReq->dma; /* TERMINATE = 0 */
1527 mEp->qh.ptr->td.token &= ~TD_STATUS; /* clear status */
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301528 mEp->qh.ptr->cap |= QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08001529
1530 wmb(); /* synchronize before ep prime */
1531
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301532 ret = hw_ep_prime(mEp->num, mEp->dir,
David Lopoaa69a802008-11-17 14:14:51 -08001533 mEp->type == USB_ENDPOINT_XFER_CONTROL);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301534done:
1535 return ret;
David Lopoaa69a802008-11-17 14:14:51 -08001536}
1537
1538/**
1539 * _hardware_dequeue: handles a request at hardware level
1540 * @gadget: gadget
1541 * @mEp: endpoint
1542 *
1543 * This function returns an error code
1544 */
1545static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1546{
1547 trace("%p, %p", mEp, mReq);
1548
1549 if (mReq->req.status != -EALREADY)
1550 return -EINVAL;
1551
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301552 if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0)
1553 return -EBUSY;
1554
1555 if (mReq->zptr) {
1556 if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
1557 return -EBUSY;
1558 dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
1559 mReq->zptr = NULL;
1560 }
David Lopoaa69a802008-11-17 14:14:51 -08001561
1562 mReq->req.status = 0;
1563
1564 if (mReq->map) {
1565 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
1566 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02001567 mReq->req.dma = DMA_ADDR_INVALID;
David Lopoaa69a802008-11-17 14:14:51 -08001568 mReq->map = 0;
1569 }
1570
1571 mReq->req.status = mReq->ptr->token & TD_STATUS;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301572 if ((TD_STATUS_HALTED & mReq->req.status) != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001573 mReq->req.status = -1;
1574 else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0)
1575 mReq->req.status = -1;
1576 else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0)
1577 mReq->req.status = -1;
1578
1579 mReq->req.actual = mReq->ptr->token & TD_TOTAL_BYTES;
1580 mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES);
1581 mReq->req.actual = mReq->req.length - mReq->req.actual;
1582 mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual;
1583
1584 return mReq->req.actual;
1585}
1586
1587/**
1588 * _ep_nuke: dequeues all endpoint requests
1589 * @mEp: endpoint
1590 *
1591 * This function returns an error code
1592 * Caller must hold lock
1593 */
1594static int _ep_nuke(struct ci13xxx_ep *mEp)
1595__releases(mEp->lock)
1596__acquires(mEp->lock)
1597{
1598 trace("%p", mEp);
1599
1600 if (mEp == NULL)
1601 return -EINVAL;
1602
1603 hw_ep_flush(mEp->num, mEp->dir);
1604
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301605 while (!list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08001606
1607 /* pop oldest request */
1608 struct ci13xxx_req *mReq = \
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301609 list_entry(mEp->qh.queue.next,
David Lopoaa69a802008-11-17 14:14:51 -08001610 struct ci13xxx_req, queue);
1611 list_del_init(&mReq->queue);
1612 mReq->req.status = -ESHUTDOWN;
1613
Artem Leonenko7c25a822010-12-14 23:46:55 -08001614 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08001615 spin_unlock(mEp->lock);
1616 mReq->req.complete(&mEp->ep, &mReq->req);
1617 spin_lock(mEp->lock);
1618 }
1619 }
1620 return 0;
1621}
1622
1623/**
1624 * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
1625 * @gadget: gadget
1626 *
1627 * This function returns an error code
David Lopoaa69a802008-11-17 14:14:51 -08001628 */
1629static int _gadget_stop_activity(struct usb_gadget *gadget)
David Lopoaa69a802008-11-17 14:14:51 -08001630{
1631 struct usb_ep *ep;
1632 struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301633 unsigned long flags;
David Lopoaa69a802008-11-17 14:14:51 -08001634
1635 trace("%p", gadget);
1636
1637 if (gadget == NULL)
1638 return -EINVAL;
1639
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301640 spin_lock_irqsave(udc->lock, flags);
1641 udc->gadget.speed = USB_SPEED_UNKNOWN;
1642 udc->remote_wakeup = 0;
1643 udc->suspended = 0;
1644 spin_unlock_irqrestore(udc->lock, flags);
1645
David Lopoaa69a802008-11-17 14:14:51 -08001646 /* flush all endpoints */
1647 gadget_for_each_ep(ep, gadget) {
1648 usb_ep_fifo_flush(ep);
1649 }
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301650 usb_ep_fifo_flush(&udc->ep0out.ep);
1651 usb_ep_fifo_flush(&udc->ep0in.ep);
David Lopoaa69a802008-11-17 14:14:51 -08001652
1653 udc->driver->disconnect(gadget);
1654
1655 /* make sure to disable all endpoints */
1656 gadget_for_each_ep(ep, gadget) {
1657 usb_ep_disable(ep);
1658 }
David Lopoaa69a802008-11-17 14:14:51 -08001659
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301660 if (udc->status != NULL) {
1661 usb_ep_free_request(&udc->ep0in.ep, udc->status);
1662 udc->status = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08001663 }
1664
David Lopoaa69a802008-11-17 14:14:51 -08001665 return 0;
1666}
1667
1668/******************************************************************************
1669 * ISR block
1670 *****************************************************************************/
1671/**
1672 * isr_reset_handler: USB reset interrupt handler
1673 * @udc: UDC device
1674 *
1675 * This function resets USB engine after a bus reset occurred
1676 */
1677static void isr_reset_handler(struct ci13xxx *udc)
1678__releases(udc->lock)
1679__acquires(udc->lock)
1680{
David Lopoaa69a802008-11-17 14:14:51 -08001681 int retval;
1682
1683 trace("%p", udc);
1684
1685 if (udc == NULL) {
1686 err("EINVAL");
1687 return;
1688 }
1689
1690 dbg_event(0xFF, "BUS RST", 0);
1691
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05301692 spin_unlock(udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001693 retval = _gadget_stop_activity(&udc->gadget);
1694 if (retval)
1695 goto done;
1696
1697 retval = hw_usb_reset();
1698 if (retval)
1699 goto done;
1700
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05301701 udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC);
1702 if (udc->status == NULL)
1703 retval = -ENOMEM;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301704
David Lopoaa69a802008-11-17 14:14:51 -08001705 spin_lock(udc->lock);
1706
1707 done:
1708 if (retval)
1709 err("error: %i", retval);
1710}
1711
1712/**
1713 * isr_get_status_complete: get_status request complete function
1714 * @ep: endpoint
1715 * @req: request handled
1716 *
1717 * Caller must release lock
1718 */
1719static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
1720{
1721 trace("%p, %p", ep, req);
1722
1723 if (ep == NULL || req == NULL) {
1724 err("EINVAL");
1725 return;
1726 }
1727
1728 kfree(req->buf);
1729 usb_ep_free_request(ep, req);
1730}
1731
1732/**
1733 * isr_get_status_response: get_status request response
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301734 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001735 * @setup: setup request packet
1736 *
1737 * This function returns an error code
1738 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301739static int isr_get_status_response(struct ci13xxx *udc,
David Lopoaa69a802008-11-17 14:14:51 -08001740 struct usb_ctrlrequest *setup)
1741__releases(mEp->lock)
1742__acquires(mEp->lock)
1743{
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301744 struct ci13xxx_ep *mEp = &udc->ep0in;
David Lopoaa69a802008-11-17 14:14:51 -08001745 struct usb_request *req = NULL;
1746 gfp_t gfp_flags = GFP_ATOMIC;
1747 int dir, num, retval;
1748
1749 trace("%p, %p", mEp, setup);
1750
1751 if (mEp == NULL || setup == NULL)
1752 return -EINVAL;
1753
1754 spin_unlock(mEp->lock);
1755 req = usb_ep_alloc_request(&mEp->ep, gfp_flags);
1756 spin_lock(mEp->lock);
1757 if (req == NULL)
1758 return -ENOMEM;
1759
1760 req->complete = isr_get_status_complete;
1761 req->length = 2;
1762 req->buf = kzalloc(req->length, gfp_flags);
1763 if (req->buf == NULL) {
1764 retval = -ENOMEM;
1765 goto err_free_req;
1766 }
1767
1768 if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301769 /* Assume that device is bus powered for now. */
1770 *((u16 *)req->buf) = _udc->remote_wakeup << 1;
David Lopoaa69a802008-11-17 14:14:51 -08001771 retval = 0;
1772 } else if ((setup->bRequestType & USB_RECIP_MASK) \
1773 == USB_RECIP_ENDPOINT) {
1774 dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ?
1775 TX : RX;
1776 num = le16_to_cpu(setup->wIndex) & USB_ENDPOINT_NUMBER_MASK;
1777 *((u16 *)req->buf) = hw_ep_get_halt(num, dir);
1778 }
1779 /* else do nothing; reserved for future use */
1780
1781 spin_unlock(mEp->lock);
1782 retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
1783 spin_lock(mEp->lock);
1784 if (retval)
1785 goto err_free_buf;
1786
1787 return 0;
1788
1789 err_free_buf:
1790 kfree(req->buf);
1791 err_free_req:
1792 spin_unlock(mEp->lock);
1793 usb_ep_free_request(&mEp->ep, req);
1794 spin_lock(mEp->lock);
1795 return retval;
1796}
1797
1798/**
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301799 * isr_setup_status_complete: setup_status request complete function
1800 * @ep: endpoint
1801 * @req: request handled
1802 *
1803 * Caller must release lock. Put the port in test mode if test mode
1804 * feature is selected.
1805 */
1806static void
1807isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
1808{
1809 struct ci13xxx *udc = req->context;
1810 unsigned long flags;
1811
1812 trace("%p, %p", ep, req);
1813
1814 spin_lock_irqsave(udc->lock, flags);
1815 if (udc->test_mode)
1816 hw_port_test_set(udc->test_mode);
1817 spin_unlock_irqrestore(udc->lock, flags);
1818}
1819
1820/**
David Lopoaa69a802008-11-17 14:14:51 -08001821 * isr_setup_status_phase: queues the status phase of a setup transation
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301822 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001823 *
1824 * This function returns an error code
1825 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301826static int isr_setup_status_phase(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -08001827__releases(mEp->lock)
1828__acquires(mEp->lock)
1829{
1830 int retval;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301831 struct ci13xxx_ep *mEp;
David Lopoaa69a802008-11-17 14:14:51 -08001832
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301833 trace("%p", udc);
David Lopoaa69a802008-11-17 14:14:51 -08001834
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301835 mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301836 udc->status->context = udc;
1837 udc->status->complete = isr_setup_status_complete;
David Lopoaa69a802008-11-17 14:14:51 -08001838
1839 spin_unlock(mEp->lock);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301840 retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
David Lopoaa69a802008-11-17 14:14:51 -08001841 spin_lock(mEp->lock);
1842
1843 return retval;
1844}
1845
1846/**
1847 * isr_tr_complete_low: transaction complete low level handler
1848 * @mEp: endpoint
1849 *
1850 * This function returns an error code
1851 * Caller must hold lock
1852 */
1853static int isr_tr_complete_low(struct ci13xxx_ep *mEp)
1854__releases(mEp->lock)
1855__acquires(mEp->lock)
1856{
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301857 struct ci13xxx_req *mReq, *mReqTemp;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301858 struct ci13xxx_ep *mEpTemp = mEp;
Pavankumar Kondeti986b11b2011-05-02 11:56:29 +05301859 int uninitialized_var(retval);
David Lopoaa69a802008-11-17 14:14:51 -08001860
1861 trace("%p", mEp);
1862
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301863 if (list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08001864 return -EINVAL;
1865
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301866 list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue,
1867 queue) {
1868 retval = _hardware_dequeue(mEp, mReq);
1869 if (retval < 0)
1870 break;
1871 list_del_init(&mReq->queue);
1872 dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
1873 if (mReq->req.complete != NULL) {
1874 spin_unlock(mEp->lock);
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301875 if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
1876 mReq->req.length)
1877 mEpTemp = &_udc->ep0in;
1878 mReq->req.complete(&mEpTemp->ep, &mReq->req);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301879 spin_lock(mEp->lock);
1880 }
1881 }
David Lopoaa69a802008-11-17 14:14:51 -08001882
Pavankumar Kondetief907482011-05-02 11:56:27 +05301883 if (retval == -EBUSY)
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301884 retval = 0;
1885 if (retval < 0)
David Lopoaa69a802008-11-17 14:14:51 -08001886 dbg_event(_usb_addr(mEp), "DONE", retval);
David Lopoaa69a802008-11-17 14:14:51 -08001887
David Lopoaa69a802008-11-17 14:14:51 -08001888 return retval;
1889}
1890
1891/**
1892 * isr_tr_complete_handler: transaction complete interrupt handler
1893 * @udc: UDC descriptor
1894 *
1895 * This function handles traffic events
1896 */
1897static void isr_tr_complete_handler(struct ci13xxx *udc)
1898__releases(udc->lock)
1899__acquires(udc->lock)
1900{
1901 unsigned i;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301902 u8 tmode = 0;
David Lopoaa69a802008-11-17 14:14:51 -08001903
1904 trace("%p", udc);
1905
1906 if (udc == NULL) {
1907 err("EINVAL");
1908 return;
1909 }
1910
1911 for (i = 0; i < hw_ep_max; i++) {
1912 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301913 int type, num, dir, err = -EINVAL;
David Lopoaa69a802008-11-17 14:14:51 -08001914 struct usb_ctrlrequest req;
1915
David Lopoaa69a802008-11-17 14:14:51 -08001916 if (mEp->desc == NULL)
1917 continue; /* not configured */
1918
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301919 if (hw_test_and_clear_complete(i)) {
David Lopoaa69a802008-11-17 14:14:51 -08001920 err = isr_tr_complete_low(mEp);
1921 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
1922 if (err > 0) /* needs status phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301923 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08001924 if (err < 0) {
1925 dbg_event(_usb_addr(mEp),
1926 "ERROR", err);
1927 spin_unlock(udc->lock);
1928 if (usb_ep_set_halt(&mEp->ep))
1929 err("error: ep_set_halt");
1930 spin_lock(udc->lock);
1931 }
1932 }
1933 }
1934
1935 if (mEp->type != USB_ENDPOINT_XFER_CONTROL ||
1936 !hw_test_and_clear_setup_status(i))
1937 continue;
1938
1939 if (i != 0) {
1940 warn("ctrl traffic received at endpoint");
1941 continue;
1942 }
1943
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301944 /*
1945 * Flush data and handshake transactions of previous
1946 * setup packet.
1947 */
1948 _ep_nuke(&udc->ep0out);
1949 _ep_nuke(&udc->ep0in);
1950
David Lopoaa69a802008-11-17 14:14:51 -08001951 /* read_setup_packet */
1952 do {
1953 hw_test_and_set_setup_guard();
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301954 memcpy(&req, &mEp->qh.ptr->setup, sizeof(req));
David Lopoaa69a802008-11-17 14:14:51 -08001955 } while (!hw_test_and_clear_setup_guard());
1956
1957 type = req.bRequestType;
1958
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301959 udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX;
David Lopoaa69a802008-11-17 14:14:51 -08001960
1961 dbg_setup(_usb_addr(mEp), &req);
1962
1963 switch (req.bRequest) {
1964 case USB_REQ_CLEAR_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301965 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
1966 le16_to_cpu(req.wValue) ==
1967 USB_ENDPOINT_HALT) {
1968 if (req.wLength != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001969 break;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301970 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301971 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301972 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301973 if (dir) /* TX */
1974 num += hw_ep_max/2;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301975 if (!udc->ci13xxx_ep[num].wedge) {
1976 spin_unlock(udc->lock);
1977 err = usb_ep_clear_halt(
1978 &udc->ci13xxx_ep[num].ep);
1979 spin_lock(udc->lock);
1980 if (err)
1981 break;
1982 }
1983 err = isr_setup_status_phase(udc);
1984 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) &&
1985 le16_to_cpu(req.wValue) ==
1986 USB_DEVICE_REMOTE_WAKEUP) {
1987 if (req.wLength != 0)
1988 break;
1989 udc->remote_wakeup = 0;
1990 err = isr_setup_status_phase(udc);
1991 } else {
1992 goto delegate;
David Lopoaa69a802008-11-17 14:14:51 -08001993 }
David Lopoaa69a802008-11-17 14:14:51 -08001994 break;
1995 case USB_REQ_GET_STATUS:
1996 if (type != (USB_DIR_IN|USB_RECIP_DEVICE) &&
1997 type != (USB_DIR_IN|USB_RECIP_ENDPOINT) &&
1998 type != (USB_DIR_IN|USB_RECIP_INTERFACE))
1999 goto delegate;
2000 if (le16_to_cpu(req.wLength) != 2 ||
2001 le16_to_cpu(req.wValue) != 0)
2002 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302003 err = isr_get_status_response(udc, &req);
David Lopoaa69a802008-11-17 14:14:51 -08002004 break;
2005 case USB_REQ_SET_ADDRESS:
2006 if (type != (USB_DIR_OUT|USB_RECIP_DEVICE))
2007 goto delegate;
2008 if (le16_to_cpu(req.wLength) != 0 ||
2009 le16_to_cpu(req.wIndex) != 0)
2010 break;
2011 err = hw_usb_set_address((u8)le16_to_cpu(req.wValue));
2012 if (err)
2013 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302014 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08002015 break;
2016 case USB_REQ_SET_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302017 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
2018 le16_to_cpu(req.wValue) ==
2019 USB_ENDPOINT_HALT) {
2020 if (req.wLength != 0)
2021 break;
2022 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302023 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302024 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302025 if (dir) /* TX */
2026 num += hw_ep_max/2;
David Lopoaa69a802008-11-17 14:14:51 -08002027
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302028 spin_unlock(udc->lock);
2029 err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep);
2030 spin_lock(udc->lock);
2031 if (!err)
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302032 isr_setup_status_phase(udc);
2033 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302034 if (req.wLength != 0)
2035 break;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302036 switch (le16_to_cpu(req.wValue)) {
2037 case USB_DEVICE_REMOTE_WAKEUP:
2038 udc->remote_wakeup = 1;
2039 err = isr_setup_status_phase(udc);
2040 break;
2041 case USB_DEVICE_TEST_MODE:
2042 tmode = le16_to_cpu(req.wIndex) >> 8;
2043 switch (tmode) {
2044 case TEST_J:
2045 case TEST_K:
2046 case TEST_SE0_NAK:
2047 case TEST_PACKET:
2048 case TEST_FORCE_EN:
2049 udc->test_mode = tmode;
2050 err = isr_setup_status_phase(
2051 udc);
2052 break;
2053 default:
2054 break;
2055 }
2056 default:
2057 goto delegate;
2058 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302059 } else {
2060 goto delegate;
2061 }
David Lopoaa69a802008-11-17 14:14:51 -08002062 break;
2063 default:
2064delegate:
2065 if (req.wLength == 0) /* no data phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302066 udc->ep0_dir = TX;
David Lopoaa69a802008-11-17 14:14:51 -08002067
2068 spin_unlock(udc->lock);
2069 err = udc->driver->setup(&udc->gadget, &req);
2070 spin_lock(udc->lock);
2071 break;
2072 }
2073
2074 if (err < 0) {
2075 dbg_event(_usb_addr(mEp), "ERROR", err);
2076
2077 spin_unlock(udc->lock);
2078 if (usb_ep_set_halt(&mEp->ep))
2079 err("error: ep_set_halt");
2080 spin_lock(udc->lock);
2081 }
2082 }
2083}
2084
2085/******************************************************************************
2086 * ENDPT block
2087 *****************************************************************************/
2088/**
2089 * ep_enable: configure endpoint, making it usable
2090 *
2091 * Check usb_ep_enable() at "usb_gadget.h" for details
2092 */
2093static int ep_enable(struct usb_ep *ep,
2094 const struct usb_endpoint_descriptor *desc)
2095{
2096 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302097 int retval = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002098 unsigned long flags;
2099
2100 trace("%p, %p", ep, desc);
2101
2102 if (ep == NULL || desc == NULL)
2103 return -EINVAL;
2104
2105 spin_lock_irqsave(mEp->lock, flags);
2106
2107 /* only internal SW should enable ctrl endpts */
2108
2109 mEp->desc = desc;
2110
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302111 if (!list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002112 warn("enabling a non-empty endpoint!");
2113
Matthias Kaehlcke15739bb2009-04-15 22:28:41 +02002114 mEp->dir = usb_endpoint_dir_in(desc) ? TX : RX;
2115 mEp->num = usb_endpoint_num(desc);
2116 mEp->type = usb_endpoint_type(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002117
Kuninori Morimoto29cc8892011-08-23 03:12:03 -07002118 mEp->ep.maxpacket = usb_endpoint_maxp(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002119
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302120 dbg_event(_usb_addr(mEp), "ENABLE", 0);
David Lopoaa69a802008-11-17 14:14:51 -08002121
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302122 mEp->qh.ptr->cap = 0;
David Lopof23e6492009-04-16 14:35:24 -07002123
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302124 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2125 mEp->qh.ptr->cap |= QH_IOS;
2126 else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
2127 mEp->qh.ptr->cap &= ~QH_MULT;
2128 else
2129 mEp->qh.ptr->cap &= ~QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08002130
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302131 mEp->qh.ptr->cap |=
2132 (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
2133 mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */
David Lopoaa69a802008-11-17 14:14:51 -08002134
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302135 /*
2136 * Enable endpoints in the HW other than ep0 as ep0
2137 * is always enabled
2138 */
2139 if (mEp->num)
2140 retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type);
David Lopoaa69a802008-11-17 14:14:51 -08002141
2142 spin_unlock_irqrestore(mEp->lock, flags);
2143 return retval;
2144}
2145
2146/**
2147 * ep_disable: endpoint is no longer usable
2148 *
2149 * Check usb_ep_disable() at "usb_gadget.h" for details
2150 */
2151static int ep_disable(struct usb_ep *ep)
2152{
2153 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2154 int direction, retval = 0;
2155 unsigned long flags;
2156
2157 trace("%p", ep);
2158
2159 if (ep == NULL)
2160 return -EINVAL;
2161 else if (mEp->desc == NULL)
2162 return -EBUSY;
2163
2164 spin_lock_irqsave(mEp->lock, flags);
2165
2166 /* only internal SW should disable ctrl endpts */
2167
2168 direction = mEp->dir;
2169 do {
2170 dbg_event(_usb_addr(mEp), "DISABLE", 0);
2171
2172 retval |= _ep_nuke(mEp);
2173 retval |= hw_ep_disable(mEp->num, mEp->dir);
2174
2175 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2176 mEp->dir = (mEp->dir == TX) ? RX : TX;
2177
2178 } while (mEp->dir != direction);
2179
2180 mEp->desc = NULL;
2181
2182 spin_unlock_irqrestore(mEp->lock, flags);
2183 return retval;
2184}
2185
2186/**
2187 * ep_alloc_request: allocate a request object to use with this endpoint
2188 *
2189 * Check usb_ep_alloc_request() at "usb_gadget.h" for details
2190 */
2191static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
2192{
2193 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2194 struct ci13xxx_req *mReq = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002195
2196 trace("%p, %i", ep, gfp_flags);
2197
2198 if (ep == NULL) {
2199 err("EINVAL");
2200 return NULL;
2201 }
2202
David Lopoaa69a802008-11-17 14:14:51 -08002203 mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
2204 if (mReq != NULL) {
2205 INIT_LIST_HEAD(&mReq->queue);
Michael Grzeschik954aad82011-10-10 18:38:06 +02002206 mReq->req.dma = DMA_ADDR_INVALID;
David Lopoaa69a802008-11-17 14:14:51 -08002207
2208 mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
2209 &mReq->dma);
2210 if (mReq->ptr == NULL) {
2211 kfree(mReq);
2212 mReq = NULL;
2213 }
2214 }
2215
2216 dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
2217
David Lopoaa69a802008-11-17 14:14:51 -08002218 return (mReq == NULL) ? NULL : &mReq->req;
2219}
2220
2221/**
2222 * ep_free_request: frees a request object
2223 *
2224 * Check usb_ep_free_request() at "usb_gadget.h" for details
2225 */
2226static void ep_free_request(struct usb_ep *ep, struct usb_request *req)
2227{
2228 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2229 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2230 unsigned long flags;
2231
2232 trace("%p, %p", ep, req);
2233
2234 if (ep == NULL || req == NULL) {
2235 err("EINVAL");
2236 return;
2237 } else if (!list_empty(&mReq->queue)) {
2238 err("EBUSY");
2239 return;
2240 }
2241
2242 spin_lock_irqsave(mEp->lock, flags);
2243
2244 if (mReq->ptr)
2245 dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma);
2246 kfree(mReq);
2247
2248 dbg_event(_usb_addr(mEp), "FREE", 0);
2249
2250 spin_unlock_irqrestore(mEp->lock, flags);
2251}
2252
2253/**
2254 * ep_queue: queues (submits) an I/O request to an endpoint
2255 *
2256 * Check usb_ep_queue()* at usb_gadget.h" for details
2257 */
2258static int ep_queue(struct usb_ep *ep, struct usb_request *req,
2259 gfp_t __maybe_unused gfp_flags)
2260{
2261 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2262 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2263 int retval = 0;
2264 unsigned long flags;
2265
2266 trace("%p, %p, %X", ep, req, gfp_flags);
2267
2268 if (ep == NULL || req == NULL || mEp->desc == NULL)
2269 return -EINVAL;
2270
2271 spin_lock_irqsave(mEp->lock, flags);
2272
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302273 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
2274 if (req->length)
2275 mEp = (_udc->ep0_dir == RX) ?
2276 &_udc->ep0out : &_udc->ep0in;
2277 if (!list_empty(&mEp->qh.queue)) {
2278 _ep_nuke(mEp);
2279 retval = -EOVERFLOW;
2280 warn("endpoint ctrl %X nuked", _usb_addr(mEp));
2281 }
David Lopoaa69a802008-11-17 14:14:51 -08002282 }
2283
2284 /* first nuke then test link, e.g. previous status has not sent */
2285 if (!list_empty(&mReq->queue)) {
2286 retval = -EBUSY;
2287 err("request already in queue");
2288 goto done;
2289 }
2290
Artem Leonenko0a313c42010-12-14 23:47:06 -08002291 if (req->length > (4 * CI13XXX_PAGE_SIZE)) {
2292 req->length = (4 * CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002293 retval = -EMSGSIZE;
2294 warn("request length truncated");
2295 }
2296
2297 dbg_queue(_usb_addr(mEp), req, retval);
2298
2299 /* push request */
2300 mReq->req.status = -EINPROGRESS;
2301 mReq->req.actual = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002302
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302303 retval = _hardware_enqueue(mEp, mReq);
Artem Leonenkod9bb9c12010-12-14 23:45:50 -08002304
2305 if (retval == -EALREADY) {
David Lopoaa69a802008-11-17 14:14:51 -08002306 dbg_event(_usb_addr(mEp), "QUEUE", retval);
2307 retval = 0;
2308 }
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302309 if (!retval)
2310 list_add_tail(&mReq->queue, &mEp->qh.queue);
David Lopoaa69a802008-11-17 14:14:51 -08002311
2312 done:
2313 spin_unlock_irqrestore(mEp->lock, flags);
2314 return retval;
2315}
2316
2317/**
2318 * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint
2319 *
2320 * Check usb_ep_dequeue() at "usb_gadget.h" for details
2321 */
2322static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
2323{
2324 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2325 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2326 unsigned long flags;
2327
2328 trace("%p, %p", ep, req);
2329
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302330 if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
2331 mEp->desc == NULL || list_empty(&mReq->queue) ||
2332 list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002333 return -EINVAL;
2334
2335 spin_lock_irqsave(mEp->lock, flags);
2336
2337 dbg_event(_usb_addr(mEp), "DEQUEUE", 0);
2338
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302339 hw_ep_flush(mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002340
2341 /* pop request */
2342 list_del_init(&mReq->queue);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302343 if (mReq->map) {
2344 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
2345 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02002346 mReq->req.dma = DMA_ADDR_INVALID;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302347 mReq->map = 0;
2348 }
David Lopoaa69a802008-11-17 14:14:51 -08002349 req->status = -ECONNRESET;
2350
Artem Leonenko7c25a822010-12-14 23:46:55 -08002351 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08002352 spin_unlock(mEp->lock);
2353 mReq->req.complete(&mEp->ep, &mReq->req);
2354 spin_lock(mEp->lock);
2355 }
2356
2357 spin_unlock_irqrestore(mEp->lock, flags);
2358 return 0;
2359}
2360
2361/**
2362 * ep_set_halt: sets the endpoint halt feature
2363 *
2364 * Check usb_ep_set_halt() at "usb_gadget.h" for details
2365 */
2366static int ep_set_halt(struct usb_ep *ep, int value)
2367{
2368 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2369 int direction, retval = 0;
2370 unsigned long flags;
2371
2372 trace("%p, %i", ep, value);
2373
2374 if (ep == NULL || mEp->desc == NULL)
2375 return -EINVAL;
2376
2377 spin_lock_irqsave(mEp->lock, flags);
2378
2379#ifndef STALL_IN
2380 /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
2381 if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302382 !list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08002383 spin_unlock_irqrestore(mEp->lock, flags);
2384 return -EAGAIN;
2385 }
2386#endif
2387
2388 direction = mEp->dir;
2389 do {
2390 dbg_event(_usb_addr(mEp), "HALT", value);
2391 retval |= hw_ep_set_halt(mEp->num, mEp->dir, value);
2392
2393 if (!value)
2394 mEp->wedge = 0;
2395
2396 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2397 mEp->dir = (mEp->dir == TX) ? RX : TX;
2398
2399 } while (mEp->dir != direction);
2400
2401 spin_unlock_irqrestore(mEp->lock, flags);
2402 return retval;
2403}
2404
2405/**
2406 * ep_set_wedge: sets the halt feature and ignores clear requests
2407 *
2408 * Check usb_ep_set_wedge() at "usb_gadget.h" for details
2409 */
2410static int ep_set_wedge(struct usb_ep *ep)
2411{
2412 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2413 unsigned long flags;
2414
2415 trace("%p", ep);
2416
2417 if (ep == NULL || mEp->desc == NULL)
2418 return -EINVAL;
2419
2420 spin_lock_irqsave(mEp->lock, flags);
2421
2422 dbg_event(_usb_addr(mEp), "WEDGE", 0);
2423 mEp->wedge = 1;
2424
2425 spin_unlock_irqrestore(mEp->lock, flags);
2426
2427 return usb_ep_set_halt(ep);
2428}
2429
2430/**
2431 * ep_fifo_flush: flushes contents of a fifo
2432 *
2433 * Check usb_ep_fifo_flush() at "usb_gadget.h" for details
2434 */
2435static void ep_fifo_flush(struct usb_ep *ep)
2436{
2437 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2438 unsigned long flags;
2439
2440 trace("%p", ep);
2441
2442 if (ep == NULL) {
2443 err("%02X: -EINVAL", _usb_addr(mEp));
2444 return;
2445 }
2446
2447 spin_lock_irqsave(mEp->lock, flags);
2448
2449 dbg_event(_usb_addr(mEp), "FFLUSH", 0);
2450 hw_ep_flush(mEp->num, mEp->dir);
2451
2452 spin_unlock_irqrestore(mEp->lock, flags);
2453}
2454
2455/**
2456 * Endpoint-specific part of the API to the USB controller hardware
2457 * Check "usb_gadget.h" for details
2458 */
2459static const struct usb_ep_ops usb_ep_ops = {
2460 .enable = ep_enable,
2461 .disable = ep_disable,
2462 .alloc_request = ep_alloc_request,
2463 .free_request = ep_free_request,
2464 .queue = ep_queue,
2465 .dequeue = ep_dequeue,
2466 .set_halt = ep_set_halt,
2467 .set_wedge = ep_set_wedge,
2468 .fifo_flush = ep_fifo_flush,
2469};
2470
2471/******************************************************************************
2472 * GADGET block
2473 *****************************************************************************/
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302474static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
2475{
2476 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2477 unsigned long flags;
2478 int gadget_ready = 0;
2479
2480 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS))
2481 return -EOPNOTSUPP;
2482
2483 spin_lock_irqsave(udc->lock, flags);
2484 udc->vbus_active = is_active;
2485 if (udc->driver)
2486 gadget_ready = 1;
2487 spin_unlock_irqrestore(udc->lock, flags);
2488
2489 if (gadget_ready) {
2490 if (is_active) {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302491 pm_runtime_get_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302492 hw_device_reset(udc);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302493 hw_device_state(udc->ep0out.qh.dma);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302494 } else {
2495 hw_device_state(0);
2496 if (udc->udc_driver->notify_event)
2497 udc->udc_driver->notify_event(udc,
2498 CI13XXX_CONTROLLER_STOPPED_EVENT);
2499 _gadget_stop_activity(&udc->gadget);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302500 pm_runtime_put_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302501 }
2502 }
2503
2504 return 0;
2505}
2506
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302507static int ci13xxx_wakeup(struct usb_gadget *_gadget)
2508{
2509 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2510 unsigned long flags;
2511 int ret = 0;
2512
2513 trace();
2514
2515 spin_lock_irqsave(udc->lock, flags);
2516 if (!udc->remote_wakeup) {
2517 ret = -EOPNOTSUPP;
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002518 trace("remote wakeup feature is not enabled\n");
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302519 goto out;
2520 }
2521 if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) {
2522 ret = -EINVAL;
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002523 trace("port is not suspended\n");
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302524 goto out;
2525 }
2526 hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR);
2527out:
2528 spin_unlock_irqrestore(udc->lock, flags);
2529 return ret;
2530}
2531
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302532static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
2533{
2534 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2535
2536 if (udc->transceiver)
2537 return otg_set_power(udc->transceiver, mA);
2538 return -ENOTSUPP;
2539}
2540
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002541static int ci13xxx_start(struct usb_gadget_driver *driver,
2542 int (*bind)(struct usb_gadget *));
2543static int ci13xxx_stop(struct usb_gadget_driver *driver);
David Lopoaa69a802008-11-17 14:14:51 -08002544/**
2545 * Device operations part of the API to the USB controller hardware,
2546 * which don't involve endpoints (or i/o)
2547 * Check "usb_gadget.h" for details
2548 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302549static const struct usb_gadget_ops usb_gadget_ops = {
2550 .vbus_session = ci13xxx_vbus_session,
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302551 .wakeup = ci13xxx_wakeup,
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302552 .vbus_draw = ci13xxx_vbus_draw,
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002553 .start = ci13xxx_start,
2554 .stop = ci13xxx_stop,
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302555};
David Lopoaa69a802008-11-17 14:14:51 -08002556
2557/**
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002558 * ci13xxx_start: register a gadget driver
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002559 * @driver: the driver being registered
2560 * @bind: the driver's bind callback
David Lopoaa69a802008-11-17 14:14:51 -08002561 *
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002562 * Check ci13xxx_start() at <linux/usb/gadget.h> for details.
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002563 * Interrupts are enabled here.
David Lopoaa69a802008-11-17 14:14:51 -08002564 */
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002565static int ci13xxx_start(struct usb_gadget_driver *driver,
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002566 int (*bind)(struct usb_gadget *))
David Lopoaa69a802008-11-17 14:14:51 -08002567{
2568 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302569 unsigned long flags;
2570 int i, j;
David Lopoaa69a802008-11-17 14:14:51 -08002571 int retval = -ENOMEM;
2572
2573 trace("%p", driver);
2574
2575 if (driver == NULL ||
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002576 bind == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002577 driver->setup == NULL ||
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002578 driver->disconnect == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002579 return -EINVAL;
2580 else if (udc == NULL)
2581 return -ENODEV;
2582 else if (udc->driver != NULL)
2583 return -EBUSY;
2584
2585 /* alloc resources */
2586 udc->qh_pool = dma_pool_create("ci13xxx_qh", &udc->gadget.dev,
2587 sizeof(struct ci13xxx_qh),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002588 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002589 if (udc->qh_pool == NULL)
2590 return -ENOMEM;
2591
2592 udc->td_pool = dma_pool_create("ci13xxx_td", &udc->gadget.dev,
2593 sizeof(struct ci13xxx_td),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002594 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002595 if (udc->td_pool == NULL) {
2596 dma_pool_destroy(udc->qh_pool);
2597 udc->qh_pool = NULL;
2598 return -ENOMEM;
2599 }
2600
2601 spin_lock_irqsave(udc->lock, flags);
2602
2603 info("hw_ep_max = %d", hw_ep_max);
2604
David Lopoaa69a802008-11-17 14:14:51 -08002605 udc->gadget.dev.driver = NULL;
2606
2607 retval = 0;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302608 for (i = 0; i < hw_ep_max/2; i++) {
2609 for (j = RX; j <= TX; j++) {
2610 int k = i + j * hw_ep_max/2;
2611 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k];
David Lopoaa69a802008-11-17 14:14:51 -08002612
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302613 scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i,
2614 (j == TX) ? "in" : "out");
David Lopoaa69a802008-11-17 14:14:51 -08002615
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302616 mEp->lock = udc->lock;
2617 mEp->device = &udc->gadget.dev;
2618 mEp->td_pool = udc->td_pool;
David Lopoaa69a802008-11-17 14:14:51 -08002619
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302620 mEp->ep.name = mEp->name;
2621 mEp->ep.ops = &usb_ep_ops;
2622 mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
David Lopoaa69a802008-11-17 14:14:51 -08002623
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302624 INIT_LIST_HEAD(&mEp->qh.queue);
Pavankumar Kondeti0a91efa2010-12-07 17:54:00 +05302625 spin_unlock_irqrestore(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302626 mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL,
2627 &mEp->qh.dma);
Pavankumar Kondeti0a91efa2010-12-07 17:54:00 +05302628 spin_lock_irqsave(udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302629 if (mEp->qh.ptr == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002630 retval = -ENOMEM;
2631 else
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302632 memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr));
2633
2634 /* skip ep0 out and in endpoints */
2635 if (i == 0)
2636 continue;
2637
David Lopoaa69a802008-11-17 14:14:51 -08002638 list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302639 }
David Lopoaa69a802008-11-17 14:14:51 -08002640 }
2641 if (retval)
2642 goto done;
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302643 spin_unlock_irqrestore(udc->lock, flags);
Felipe Balbi877c1f52011-06-29 16:41:57 +03002644 udc->ep0out.ep.desc = &ctrl_endpt_out_desc;
2645 retval = usb_ep_enable(&udc->ep0out.ep);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302646 if (retval)
2647 return retval;
Felipe Balbi877c1f52011-06-29 16:41:57 +03002648
2649 udc->ep0in.ep.desc = &ctrl_endpt_in_desc;
2650 retval = usb_ep_enable(&udc->ep0in.ep);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302651 if (retval)
2652 return retval;
2653 spin_lock_irqsave(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002654
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302655 udc->gadget.ep0 = &udc->ep0in.ep;
David Lopoaa69a802008-11-17 14:14:51 -08002656 /* bind gadget */
2657 driver->driver.bus = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002658 udc->gadget.dev.driver = &driver->driver;
2659
2660 spin_unlock_irqrestore(udc->lock, flags);
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002661 retval = bind(&udc->gadget); /* MAY SLEEP */
David Lopoaa69a802008-11-17 14:14:51 -08002662 spin_lock_irqsave(udc->lock, flags);
2663
2664 if (retval) {
David Lopoaa69a802008-11-17 14:14:51 -08002665 udc->gadget.dev.driver = NULL;
2666 goto done;
2667 }
2668
Pavankumar Kondeti49d3df52011-01-11 09:19:21 +05302669 udc->driver = driver;
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302670 pm_runtime_get_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302671 if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) {
2672 if (udc->vbus_active) {
2673 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED)
2674 hw_device_reset(udc);
2675 } else {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302676 pm_runtime_put_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302677 goto done;
2678 }
2679 }
2680
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302681 retval = hw_device_state(udc->ep0out.qh.dma);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302682 if (retval)
2683 pm_runtime_put_sync(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002684
2685 done:
2686 spin_unlock_irqrestore(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002687 return retval;
2688}
David Lopoaa69a802008-11-17 14:14:51 -08002689
2690/**
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002691 * ci13xxx_stop: unregister a gadget driver
David Lopoaa69a802008-11-17 14:14:51 -08002692 *
2693 * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
2694 */
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002695static int ci13xxx_stop(struct usb_gadget_driver *driver)
David Lopoaa69a802008-11-17 14:14:51 -08002696{
2697 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302698 unsigned long i, flags;
David Lopoaa69a802008-11-17 14:14:51 -08002699
2700 trace("%p", driver);
2701
2702 if (driver == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002703 driver->unbind == NULL ||
2704 driver->setup == NULL ||
2705 driver->disconnect == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002706 driver != udc->driver)
2707 return -EINVAL;
2708
2709 spin_lock_irqsave(udc->lock, flags);
2710
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302711 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) ||
2712 udc->vbus_active) {
2713 hw_device_state(0);
2714 if (udc->udc_driver->notify_event)
2715 udc->udc_driver->notify_event(udc,
2716 CI13XXX_CONTROLLER_STOPPED_EVENT);
Marc Kleine-Buddefd537c02011-10-10 18:38:07 +02002717 spin_unlock_irqrestore(udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302718 _gadget_stop_activity(&udc->gadget);
Marc Kleine-Buddefd537c02011-10-10 18:38:07 +02002719 spin_lock_irqsave(udc->lock, flags);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302720 pm_runtime_put(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302721 }
David Lopoaa69a802008-11-17 14:14:51 -08002722
2723 /* unbind gadget */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302724 spin_unlock_irqrestore(udc->lock, flags);
2725 driver->unbind(&udc->gadget); /* MAY SLEEP */
2726 spin_lock_irqsave(udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002727
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302728 udc->gadget.dev.driver = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002729
2730 /* free resources */
2731 for (i = 0; i < hw_ep_max; i++) {
2732 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
2733
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302734 if (!list_empty(&mEp->ep.ep_list))
David Lopoaa69a802008-11-17 14:14:51 -08002735 list_del_init(&mEp->ep.ep_list);
2736
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302737 if (mEp->qh.ptr != NULL)
2738 dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08002739 }
2740
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302741 udc->gadget.ep0 = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002742 udc->driver = NULL;
2743
2744 spin_unlock_irqrestore(udc->lock, flags);
2745
2746 if (udc->td_pool != NULL) {
2747 dma_pool_destroy(udc->td_pool);
2748 udc->td_pool = NULL;
2749 }
2750 if (udc->qh_pool != NULL) {
2751 dma_pool_destroy(udc->qh_pool);
2752 udc->qh_pool = NULL;
2753 }
2754
2755 return 0;
2756}
David Lopoaa69a802008-11-17 14:14:51 -08002757
2758/******************************************************************************
2759 * BUS block
2760 *****************************************************************************/
2761/**
2762 * udc_irq: global interrupt handler
2763 *
2764 * This function returns IRQ_HANDLED if the IRQ has been handled
2765 * It locks access to registers
2766 */
2767static irqreturn_t udc_irq(void)
2768{
2769 struct ci13xxx *udc = _udc;
2770 irqreturn_t retval;
2771 u32 intr;
2772
2773 trace();
2774
2775 if (udc == NULL) {
2776 err("ENODEV");
2777 return IRQ_HANDLED;
2778 }
2779
2780 spin_lock(udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302781
2782 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) {
2783 if (hw_cread(CAP_USBMODE, USBMODE_CM) !=
2784 USBMODE_CM_DEVICE) {
2785 spin_unlock(udc->lock);
2786 return IRQ_NONE;
2787 }
2788 }
David Lopoaa69a802008-11-17 14:14:51 -08002789 intr = hw_test_and_clear_intr_active();
2790 if (intr) {
2791 isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr;
2792 isr_statistics.hndl.idx &= ISR_MASK;
2793 isr_statistics.hndl.cnt++;
2794
2795 /* order defines priority - do NOT change it */
2796 if (USBi_URI & intr) {
2797 isr_statistics.uri++;
2798 isr_reset_handler(udc);
2799 }
2800 if (USBi_PCI & intr) {
2801 isr_statistics.pci++;
2802 udc->gadget.speed = hw_port_is_high_speed() ?
2803 USB_SPEED_HIGH : USB_SPEED_FULL;
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002804 if (udc->suspended && udc->driver->resume) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302805 spin_unlock(udc->lock);
2806 udc->driver->resume(&udc->gadget);
2807 spin_lock(udc->lock);
2808 udc->suspended = 0;
2809 }
David Lopoaa69a802008-11-17 14:14:51 -08002810 }
2811 if (USBi_UEI & intr)
2812 isr_statistics.uei++;
2813 if (USBi_UI & intr) {
2814 isr_statistics.ui++;
2815 isr_tr_complete_handler(udc);
2816 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302817 if (USBi_SLI & intr) {
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002818 if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
2819 udc->driver->suspend) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302820 udc->suspended = 1;
2821 spin_unlock(udc->lock);
2822 udc->driver->suspend(&udc->gadget);
2823 spin_lock(udc->lock);
2824 }
David Lopoaa69a802008-11-17 14:14:51 -08002825 isr_statistics.sli++;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302826 }
David Lopoaa69a802008-11-17 14:14:51 -08002827 retval = IRQ_HANDLED;
2828 } else {
2829 isr_statistics.none++;
2830 retval = IRQ_NONE;
2831 }
2832 spin_unlock(udc->lock);
2833
2834 return retval;
2835}
2836
2837/**
2838 * udc_release: driver release function
2839 * @dev: device
2840 *
2841 * Currently does nothing
2842 */
2843static void udc_release(struct device *dev)
2844{
2845 trace("%p", dev);
2846
2847 if (dev == NULL)
2848 err("EINVAL");
2849}
2850
2851/**
2852 * udc_probe: parent probe must call this to initialize UDC
2853 * @dev: parent device
2854 * @regs: registers base address
2855 * @name: driver name
2856 *
2857 * This function returns an error code
2858 * No interrupts active, the IRQ has not been requested yet
2859 * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask
2860 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302861static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
2862 void __iomem *regs)
David Lopoaa69a802008-11-17 14:14:51 -08002863{
2864 struct ci13xxx *udc;
2865 int retval = 0;
2866
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002867 trace("%p, %p, %p", dev, regs, driver->name);
David Lopoaa69a802008-11-17 14:14:51 -08002868
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302869 if (dev == NULL || regs == NULL || driver == NULL ||
2870 driver->name == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002871 return -EINVAL;
2872
2873 udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL);
2874 if (udc == NULL)
2875 return -ENOMEM;
2876
2877 udc->lock = &udc_lock;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302878 udc->regs = regs;
2879 udc->udc_driver = driver;
David Lopoaa69a802008-11-17 14:14:51 -08002880
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302881 udc->gadget.ops = &usb_gadget_ops;
David Lopoaa69a802008-11-17 14:14:51 -08002882 udc->gadget.speed = USB_SPEED_UNKNOWN;
2883 udc->gadget.is_dualspeed = 1;
2884 udc->gadget.is_otg = 0;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302885 udc->gadget.name = driver->name;
David Lopoaa69a802008-11-17 14:14:51 -08002886
2887 INIT_LIST_HEAD(&udc->gadget.ep_list);
2888 udc->gadget.ep0 = NULL;
2889
Kay Sievers5df58522009-03-24 16:38:23 -07002890 dev_set_name(&udc->gadget.dev, "gadget");
David Lopoaa69a802008-11-17 14:14:51 -08002891 udc->gadget.dev.dma_mask = dev->dma_mask;
Pavankumar Kondeti61948ee2010-12-07 17:54:01 +05302892 udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask;
David Lopoaa69a802008-11-17 14:14:51 -08002893 udc->gadget.dev.parent = dev;
2894 udc->gadget.dev.release = udc_release;
2895
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302896 retval = hw_device_init(regs);
2897 if (retval < 0)
2898 goto free_udc;
2899
2900 udc->transceiver = otg_get_transceiver();
2901
2902 if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
2903 if (udc->transceiver == NULL) {
2904 retval = -ENODEV;
2905 goto free_udc;
2906 }
2907 }
2908
2909 if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) {
2910 retval = hw_device_reset(udc);
2911 if (retval)
2912 goto put_transceiver;
2913 }
2914
David Lopoaa69a802008-11-17 14:14:51 -08002915 retval = device_register(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302916 if (retval) {
2917 put_device(&udc->gadget.dev);
2918 goto put_transceiver;
2919 }
David Lopoaa69a802008-11-17 14:14:51 -08002920
2921#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2922 retval = dbg_create_files(&udc->gadget.dev);
2923#endif
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302924 if (retval)
2925 goto unreg_device;
2926
2927 if (udc->transceiver) {
2928 retval = otg_set_peripheral(udc->transceiver, &udc->gadget);
2929 if (retval)
2930 goto remove_dbg;
David Lopoaa69a802008-11-17 14:14:51 -08002931 }
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002932
2933 retval = usb_add_gadget_udc(dev, &udc->gadget);
2934 if (retval)
2935 goto remove_trans;
2936
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302937 pm_runtime_no_callbacks(&udc->gadget.dev);
2938 pm_runtime_enable(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002939
2940 _udc = udc;
2941 return retval;
2942
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002943remove_trans:
2944 if (udc->transceiver) {
2945 otg_set_peripheral(udc->transceiver, &udc->gadget);
2946 otg_put_transceiver(udc->transceiver);
2947 }
2948
David Lopoaa69a802008-11-17 14:14:51 -08002949 err("error = %i", retval);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302950remove_dbg:
2951#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2952 dbg_remove_files(&udc->gadget.dev);
2953#endif
2954unreg_device:
2955 device_unregister(&udc->gadget.dev);
2956put_transceiver:
2957 if (udc->transceiver)
2958 otg_put_transceiver(udc->transceiver);
2959free_udc:
David Lopoaa69a802008-11-17 14:14:51 -08002960 kfree(udc);
2961 _udc = NULL;
2962 return retval;
2963}
2964
2965/**
2966 * udc_remove: parent remove must call this to remove UDC
2967 *
2968 * No interrupts active, the IRQ has been released
2969 */
2970static void udc_remove(void)
2971{
2972 struct ci13xxx *udc = _udc;
2973
2974 if (udc == NULL) {
2975 err("EINVAL");
2976 return;
2977 }
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002978 usb_del_gadget_udc(&udc->gadget);
David Lopoaa69a802008-11-17 14:14:51 -08002979
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302980 if (udc->transceiver) {
2981 otg_set_peripheral(udc->transceiver, &udc->gadget);
2982 otg_put_transceiver(udc->transceiver);
2983 }
David Lopoaa69a802008-11-17 14:14:51 -08002984#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2985 dbg_remove_files(&udc->gadget.dev);
2986#endif
2987 device_unregister(&udc->gadget.dev);
2988
2989 kfree(udc);
2990 _udc = NULL;
2991}