blob: 3b47ca1b64ee56557af8bb3fd99beced2faad5a4 [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/* control endpoint description */
78static const struct usb_endpoint_descriptor
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053079ctrl_endpt_out_desc = {
David Lopoaa69a802008-11-17 14:14:51 -080080 .bLength = USB_DT_ENDPOINT_SIZE,
81 .bDescriptorType = USB_DT_ENDPOINT,
82
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053083 .bEndpointAddress = USB_DIR_OUT,
84 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
85 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
86};
87
88static const struct usb_endpoint_descriptor
89ctrl_endpt_in_desc = {
90 .bLength = USB_DT_ENDPOINT_SIZE,
91 .bDescriptorType = USB_DT_ENDPOINT,
92
93 .bEndpointAddress = USB_DIR_IN,
David Lopoaa69a802008-11-17 14:14:51 -080094 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
95 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
96};
97
98/* UDC descriptor */
99static struct ci13xxx *_udc;
100
101/* Interrupt statistics */
102#define ISR_MASK 0x1F
103static struct {
104 u32 test;
105 u32 ui;
106 u32 uei;
107 u32 pci;
108 u32 uri;
109 u32 sli;
110 u32 none;
111 struct {
112 u32 cnt;
113 u32 buf[ISR_MASK+1];
114 u32 idx;
115 } hndl;
116} isr_statistics;
117
118/**
119 * ffs_nr: find first (least significant) bit set
120 * @x: the word to search
121 *
122 * This function returns bit number (instead of position)
123 */
124static int ffs_nr(u32 x)
125{
126 int n = ffs(x);
127
128 return n ? n-1 : 32;
129}
130
131/******************************************************************************
132 * HW block
133 *****************************************************************************/
David Lopoaa69a802008-11-17 14:14:51 -0800134
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530135/* MSM specific */
136#define ABS_AHBBURST (0x0090UL)
137#define ABS_AHBMODE (0x0098UL)
David Lopoaa69a802008-11-17 14:14:51 -0800138/* UDC register map */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300139static uintptr_t ci_regs_nolpm[] = {
140 [CAP_CAPLENGTH] = 0x000UL,
141 [CAP_HCCPARAMS] = 0x008UL,
142 [CAP_DCCPARAMS] = 0x024UL,
143 [CAP_TESTMODE] = 0x038UL,
144 [OP_USBCMD] = 0x000UL,
145 [OP_USBSTS] = 0x004UL,
146 [OP_USBINTR] = 0x008UL,
147 [OP_DEVICEADDR] = 0x014UL,
148 [OP_ENDPTLISTADDR] = 0x018UL,
149 [OP_PORTSC] = 0x044UL,
150 [OP_DEVLC] = 0x084UL,
151 [OP_USBMODE] = 0x068UL,
152 [OP_ENDPTSETUPSTAT] = 0x06CUL,
153 [OP_ENDPTPRIME] = 0x070UL,
154 [OP_ENDPTFLUSH] = 0x074UL,
155 [OP_ENDPTSTAT] = 0x078UL,
156 [OP_ENDPTCOMPLETE] = 0x07CUL,
157 [OP_ENDPTCTRL] = 0x080UL,
158};
159
160static uintptr_t ci_regs_lpm[] = {
161 [CAP_CAPLENGTH] = 0x000UL,
162 [CAP_HCCPARAMS] = 0x008UL,
163 [CAP_DCCPARAMS] = 0x024UL,
164 [CAP_TESTMODE] = 0x0FCUL,
165 [OP_USBCMD] = 0x000UL,
166 [OP_USBSTS] = 0x004UL,
167 [OP_USBINTR] = 0x008UL,
168 [OP_DEVICEADDR] = 0x014UL,
169 [OP_ENDPTLISTADDR] = 0x018UL,
170 [OP_PORTSC] = 0x044UL,
171 [OP_DEVLC] = 0x084UL,
172 [OP_USBMODE] = 0x0C8UL,
173 [OP_ENDPTSETUPSTAT] = 0x0D8UL,
174 [OP_ENDPTPRIME] = 0x0DCUL,
175 [OP_ENDPTFLUSH] = 0x0E0UL,
176 [OP_ENDPTSTAT] = 0x0E4UL,
177 [OP_ENDPTCOMPLETE] = 0x0E8UL,
178 [OP_ENDPTCTRL] = 0x0ECUL,
179};
180
181static int hw_alloc_regmap(struct ci13xxx *udc, bool is_lpm)
182{
183 int i;
184
185 kfree(udc->hw_bank.regmap);
186
187 udc->hw_bank.regmap = kzalloc((OP_LAST + 1) * sizeof(void *),
188 GFP_KERNEL);
189 if (!udc->hw_bank.regmap)
190 return -ENOMEM;
191
192 for (i = 0; i < OP_ENDPTCTRL; i++)
193 udc->hw_bank.regmap[i] =
194 (i <= CAP_LAST ? udc->hw_bank.cap : udc->hw_bank.op) +
195 (is_lpm ? ci_regs_lpm[i] : ci_regs_nolpm[i]);
196
197 for (; i <= OP_LAST; i++)
198 udc->hw_bank.regmap[i] = udc->hw_bank.op +
199 4 * (i - OP_ENDPTCTRL) +
200 (is_lpm
201 ? ci_regs_lpm[OP_ENDPTCTRL]
202 : ci_regs_nolpm[OP_ENDPTCTRL]);
203
204 return 0;
205}
David Lopoaa69a802008-11-17 14:14:51 -0800206
207/**
208 * hw_ep_bit: calculates the bit number
209 * @num: endpoint number
210 * @dir: endpoint direction
211 *
212 * This function returns bit number
213 */
214static inline int hw_ep_bit(int num, int dir)
215{
216 return num + (dir ? 16 : 0);
217}
218
Alexander Shishkind3595d12012-05-08 23:28:58 +0300219static int ep_to_bit(struct ci13xxx *udc, int n)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200220{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300221 int fill = 16 - udc->hw_ep_max / 2;
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200222
Alexander Shishkind3595d12012-05-08 23:28:58 +0300223 if (n >= udc->hw_ep_max / 2)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200224 n += fill;
225
226 return n;
227}
228
David Lopoaa69a802008-11-17 14:14:51 -0800229/**
Alexander Shishkin262c1632012-05-08 23:28:59 +0300230 * hw_read: reads from a hw register
231 * @reg: register index
David Lopoaa69a802008-11-17 14:14:51 -0800232 * @mask: bitfield mask
233 *
Alexander Shishkin262c1632012-05-08 23:28:59 +0300234 * This function returns register contents
David Lopoaa69a802008-11-17 14:14:51 -0800235 */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300236static u32 hw_read(struct ci13xxx *udc, enum ci13xxx_regs reg, u32 mask)
David Lopoaa69a802008-11-17 14:14:51 -0800237{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300238 return ioread32(udc->hw_bank.regmap[reg]) & mask;
David Lopoaa69a802008-11-17 14:14:51 -0800239}
240
241/**
Alexander Shishkin262c1632012-05-08 23:28:59 +0300242 * hw_write: writes to a hw register
243 * @reg: register index
David Lopoaa69a802008-11-17 14:14:51 -0800244 * @mask: bitfield mask
Alexander Shishkin262c1632012-05-08 23:28:59 +0300245 * @data: new value
David Lopoaa69a802008-11-17 14:14:51 -0800246 */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300247static void hw_write(struct ci13xxx *udc, enum ci13xxx_regs reg, u32 mask,
248 u32 data)
David Lopoaa69a802008-11-17 14:14:51 -0800249{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300250 if (~mask)
251 data = (ioread32(udc->hw_bank.regmap[reg]) & ~mask)
252 | (data & mask);
253
254 iowrite32(data, udc->hw_bank.regmap[reg]);
David Lopoaa69a802008-11-17 14:14:51 -0800255}
256
257/**
Alexander Shishkin262c1632012-05-08 23:28:59 +0300258 * hw_test_and_clear: tests & clears a hw register
259 * @reg: register index
David Lopoaa69a802008-11-17 14:14:51 -0800260 * @mask: bitfield mask
261 *
Alexander Shishkin262c1632012-05-08 23:28:59 +0300262 * This function returns register contents
David Lopoaa69a802008-11-17 14:14:51 -0800263 */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300264static u32 hw_test_and_clear(struct ci13xxx *udc, enum ci13xxx_regs reg,
265 u32 mask)
David Lopoaa69a802008-11-17 14:14:51 -0800266{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300267 u32 val = ioread32(udc->hw_bank.regmap[reg]) & mask;
David Lopoaa69a802008-11-17 14:14:51 -0800268
Alexander Shishkin262c1632012-05-08 23:28:59 +0300269 iowrite32(val, udc->hw_bank.regmap[reg]);
270 return val;
David Lopoaa69a802008-11-17 14:14:51 -0800271}
272
273/**
Alexander Shishkin262c1632012-05-08 23:28:59 +0300274 * hw_test_and_write: tests & writes a hw register
275 * @reg: register index
David Lopoaa69a802008-11-17 14:14:51 -0800276 * @mask: bitfield mask
Alexander Shishkin262c1632012-05-08 23:28:59 +0300277 * @data: new value
David Lopoaa69a802008-11-17 14:14:51 -0800278 *
Alexander Shishkin262c1632012-05-08 23:28:59 +0300279 * This function returns register contents
David Lopoaa69a802008-11-17 14:14:51 -0800280 */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300281static u32 hw_test_and_write(struct ci13xxx *udc, enum ci13xxx_regs reg,
282 u32 mask, u32 data)
David Lopoaa69a802008-11-17 14:14:51 -0800283{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300284 u32 val = hw_read(udc, reg, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800285
Alexander Shishkin262c1632012-05-08 23:28:59 +0300286 hw_write(udc, reg, mask, data);
287 return (val & mask) >> ffs_nr(mask);
David Lopoaa69a802008-11-17 14:14:51 -0800288}
289
Alexander Shishkind3595d12012-05-08 23:28:58 +0300290static int hw_device_init(struct ci13xxx *udc, void __iomem *base,
291 uintptr_t cap_offset)
David Lopoaa69a802008-11-17 14:14:51 -0800292{
293 u32 reg;
294
295 /* bank is a module variable */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300296 udc->hw_bank.abs = base;
David Lopoaa69a802008-11-17 14:14:51 -0800297
Alexander Shishkind3595d12012-05-08 23:28:58 +0300298 udc->hw_bank.cap = udc->hw_bank.abs;
299 udc->hw_bank.cap += cap_offset;
300 udc->hw_bank.op = udc->hw_bank.cap + ioread8(udc->hw_bank.cap);
David Lopoaa69a802008-11-17 14:14:51 -0800301
Alexander Shishkin262c1632012-05-08 23:28:59 +0300302 hw_alloc_regmap(udc, false);
303 reg = hw_read(udc, CAP_HCCPARAMS, HCCPARAMS_LEN) >>
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300304 ffs_nr(HCCPARAMS_LEN);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300305 udc->hw_bank.lpm = reg;
Alexander Shishkin262c1632012-05-08 23:28:59 +0300306 hw_alloc_regmap(udc, !!reg);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300307 udc->hw_bank.size = udc->hw_bank.op - udc->hw_bank.abs;
308 udc->hw_bank.size += OP_LAST;
309 udc->hw_bank.size /= sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -0800310
Alexander Shishkin262c1632012-05-08 23:28:59 +0300311 reg = hw_read(udc, CAP_DCCPARAMS, DCCPARAMS_DEN) >>
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300312 ffs_nr(DCCPARAMS_DEN);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300313 udc->hw_ep_max = reg * 2; /* cache hw ENDPT_MAX */
David Lopoaa69a802008-11-17 14:14:51 -0800314
Alexander Shishkind3595d12012-05-08 23:28:58 +0300315 if (udc->hw_ep_max == 0 || udc->hw_ep_max > ENDPT_MAX)
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530316 return -ENODEV;
David Lopoaa69a802008-11-17 14:14:51 -0800317
318 /* setup lock mode ? */
319
320 /* ENDPTSETUPSTAT is '0' by default */
321
322 /* HCSPARAMS.bf.ppc SHOULD BE zero for device */
323
324 return 0;
325}
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530326/**
327 * hw_device_reset: resets chip (execute without interruption)
328 * @base: register base address
329 *
330 * This function returns an error code
331 */
332static int hw_device_reset(struct ci13xxx *udc)
333{
334 /* should flush & stop before reset */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300335 hw_write(udc, OP_ENDPTFLUSH, ~0, ~0);
336 hw_write(udc, OP_USBCMD, USBCMD_RS, 0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530337
Alexander Shishkin262c1632012-05-08 23:28:59 +0300338 hw_write(udc, OP_USBCMD, USBCMD_RST, USBCMD_RST);
339 while (hw_read(udc, OP_USBCMD, USBCMD_RST))
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530340 udelay(10); /* not RTOS friendly */
341
342
343 if (udc->udc_driver->notify_event)
344 udc->udc_driver->notify_event(udc,
345 CI13XXX_CONTROLLER_RESET_EVENT);
346
Pavankumar Kondeti8c2387a2011-05-02 11:56:28 +0530347 if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
Alexander Shishkin262c1632012-05-08 23:28:59 +0300348 hw_write(udc, OP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530349
350 /* USBMODE should be configured step by step */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300351 hw_write(udc, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
352 hw_write(udc, OP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE);
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300353 /* HW >= 2.3 */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300354 hw_write(udc, OP_USBMODE, USBMODE_SLOM, USBMODE_SLOM);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530355
Alexander Shishkin262c1632012-05-08 23:28:59 +0300356 if (hw_read(udc, OP_USBMODE, USBMODE_CM) != USBMODE_CM_DEVICE) {
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530357 pr_err("cannot enter in device mode");
Alexander Shishkind3595d12012-05-08 23:28:58 +0300358 pr_err("lpm = %i", udc->hw_bank.lpm);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530359 return -ENODEV;
360 }
361
362 return 0;
363}
David Lopoaa69a802008-11-17 14:14:51 -0800364
365/**
366 * hw_device_state: enables/disables interrupts & starts/stops device (execute
367 * without interruption)
368 * @dma: 0 => disable, !0 => enable and set dma engine
369 *
370 * This function returns an error code
371 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300372static int hw_device_state(struct ci13xxx *udc, u32 dma)
David Lopoaa69a802008-11-17 14:14:51 -0800373{
374 if (dma) {
Alexander Shishkin262c1632012-05-08 23:28:59 +0300375 hw_write(udc, OP_ENDPTLISTADDR, ~0, dma);
David Lopoaa69a802008-11-17 14:14:51 -0800376 /* interrupt, error, port change, reset, sleep/suspend */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300377 hw_write(udc, OP_USBINTR, ~0,
David Lopoaa69a802008-11-17 14:14:51 -0800378 USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
Alexander Shishkin262c1632012-05-08 23:28:59 +0300379 hw_write(udc, OP_USBCMD, USBCMD_RS, USBCMD_RS);
David Lopoaa69a802008-11-17 14:14:51 -0800380 } else {
Alexander Shishkin262c1632012-05-08 23:28:59 +0300381 hw_write(udc, OP_USBCMD, USBCMD_RS, 0);
382 hw_write(udc, OP_USBINTR, ~0, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800383 }
384 return 0;
385}
386
387/**
388 * hw_ep_flush: flush endpoint fifo (execute without interruption)
389 * @num: endpoint number
390 * @dir: endpoint direction
391 *
392 * This function returns an error code
393 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300394static int hw_ep_flush(struct ci13xxx *udc, int num, int dir)
David Lopoaa69a802008-11-17 14:14:51 -0800395{
396 int n = hw_ep_bit(num, dir);
397
398 do {
399 /* flush any pending transfer */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300400 hw_write(udc, OP_ENDPTFLUSH, BIT(n), BIT(n));
401 while (hw_read(udc, OP_ENDPTFLUSH, BIT(n)))
David Lopoaa69a802008-11-17 14:14:51 -0800402 cpu_relax();
Alexander Shishkin262c1632012-05-08 23:28:59 +0300403 } while (hw_read(udc, OP_ENDPTSTAT, BIT(n)));
David Lopoaa69a802008-11-17 14:14:51 -0800404
405 return 0;
406}
407
408/**
409 * hw_ep_disable: disables endpoint (execute without interruption)
410 * @num: endpoint number
411 * @dir: endpoint direction
412 *
413 * This function returns an error code
414 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300415static int hw_ep_disable(struct ci13xxx *udc, int num, int dir)
David Lopoaa69a802008-11-17 14:14:51 -0800416{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300417 hw_ep_flush(udc, num, dir);
Alexander Shishkin262c1632012-05-08 23:28:59 +0300418 hw_write(udc, OP_ENDPTCTRL + num,
Alexander Shishkind3595d12012-05-08 23:28:58 +0300419 dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800420 return 0;
421}
422
423/**
424 * hw_ep_enable: enables endpoint (execute without interruption)
425 * @num: endpoint number
426 * @dir: endpoint direction
427 * @type: endpoint type
428 *
429 * This function returns an error code
430 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300431static int hw_ep_enable(struct ci13xxx *udc, int num, int dir, int type)
David Lopoaa69a802008-11-17 14:14:51 -0800432{
433 u32 mask, data;
434
435 if (dir) {
436 mask = ENDPTCTRL_TXT; /* type */
437 data = type << ffs_nr(mask);
438
439 mask |= ENDPTCTRL_TXS; /* unstall */
440 mask |= ENDPTCTRL_TXR; /* reset data toggle */
441 data |= ENDPTCTRL_TXR;
442 mask |= ENDPTCTRL_TXE; /* enable */
443 data |= ENDPTCTRL_TXE;
444 } else {
445 mask = ENDPTCTRL_RXT; /* type */
446 data = type << ffs_nr(mask);
447
448 mask |= ENDPTCTRL_RXS; /* unstall */
449 mask |= ENDPTCTRL_RXR; /* reset data toggle */
450 data |= ENDPTCTRL_RXR;
451 mask |= ENDPTCTRL_RXE; /* enable */
452 data |= ENDPTCTRL_RXE;
453 }
Alexander Shishkin262c1632012-05-08 23:28:59 +0300454 hw_write(udc, OP_ENDPTCTRL + num, mask, data);
David Lopoaa69a802008-11-17 14:14:51 -0800455 return 0;
456}
457
458/**
459 * hw_ep_get_halt: return endpoint halt status
460 * @num: endpoint number
461 * @dir: endpoint direction
462 *
463 * This function returns 1 if endpoint halted
464 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300465static int hw_ep_get_halt(struct ci13xxx *udc, int num, int dir)
David Lopoaa69a802008-11-17 14:14:51 -0800466{
467 u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
468
Alexander Shishkin262c1632012-05-08 23:28:59 +0300469 return hw_read(udc, OP_ENDPTCTRL + num, mask) ? 1 : 0;
David Lopoaa69a802008-11-17 14:14:51 -0800470}
471
472/**
David Lopoaa69a802008-11-17 14:14:51 -0800473 * hw_test_and_clear_setup_status: test & clear setup status (execute without
474 * interruption)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200475 * @n: endpoint number
David Lopoaa69a802008-11-17 14:14:51 -0800476 *
477 * This function returns setup status
478 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300479static int hw_test_and_clear_setup_status(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800480{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300481 n = ep_to_bit(udc, n);
Alexander Shishkin262c1632012-05-08 23:28:59 +0300482 return hw_test_and_clear(udc, OP_ENDPTSETUPSTAT, BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800483}
484
485/**
486 * hw_ep_prime: primes endpoint (execute without interruption)
487 * @num: endpoint number
488 * @dir: endpoint direction
489 * @is_ctrl: true if control endpoint
490 *
491 * This function returns an error code
492 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300493static int hw_ep_prime(struct ci13xxx *udc, int num, int dir, int is_ctrl)
David Lopoaa69a802008-11-17 14:14:51 -0800494{
495 int n = hw_ep_bit(num, dir);
496
Alexander Shishkin262c1632012-05-08 23:28:59 +0300497 if (is_ctrl && dir == RX && hw_read(udc, OP_ENDPTSETUPSTAT, BIT(num)))
David Lopoaa69a802008-11-17 14:14:51 -0800498 return -EAGAIN;
499
Alexander Shishkin262c1632012-05-08 23:28:59 +0300500 hw_write(udc, OP_ENDPTPRIME, BIT(n), BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800501
Alexander Shishkin262c1632012-05-08 23:28:59 +0300502 while (hw_read(udc, OP_ENDPTPRIME, BIT(n)))
David Lopoaa69a802008-11-17 14:14:51 -0800503 cpu_relax();
Alexander Shishkin262c1632012-05-08 23:28:59 +0300504 if (is_ctrl && dir == RX && hw_read(udc, OP_ENDPTSETUPSTAT, BIT(num)))
David Lopoaa69a802008-11-17 14:14:51 -0800505 return -EAGAIN;
506
507 /* status shoult be tested according with manual but it doesn't work */
508 return 0;
509}
510
511/**
512 * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute
513 * without interruption)
514 * @num: endpoint number
515 * @dir: endpoint direction
516 * @value: true => stall, false => unstall
517 *
518 * This function returns an error code
519 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300520static int hw_ep_set_halt(struct ci13xxx *udc, int num, int dir, int value)
David Lopoaa69a802008-11-17 14:14:51 -0800521{
522 if (value != 0 && value != 1)
523 return -EINVAL;
524
525 do {
Alexander Shishkin262c1632012-05-08 23:28:59 +0300526 enum ci13xxx_regs reg = OP_ENDPTCTRL + num;
David Lopoaa69a802008-11-17 14:14:51 -0800527 u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
528 u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
529
530 /* data toggle - reserved for EP0 but it's in ESS */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300531 hw_write(udc, reg, mask_xs|mask_xr,
532 value ? mask_xs : mask_xr);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300533 } while (value != hw_ep_get_halt(udc, num, dir));
David Lopoaa69a802008-11-17 14:14:51 -0800534
535 return 0;
536}
537
538/**
539 * hw_intr_clear: disables interrupt & clears interrupt status (execute without
540 * interruption)
541 * @n: interrupt bit
542 *
543 * This function returns an error code
544 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300545static int hw_intr_clear(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800546{
547 if (n >= REG_BITS)
548 return -EINVAL;
549
Alexander Shishkin262c1632012-05-08 23:28:59 +0300550 hw_write(udc, OP_USBINTR, BIT(n), 0);
551 hw_write(udc, OP_USBSTS, BIT(n), BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800552 return 0;
553}
554
555/**
556 * hw_intr_force: enables interrupt & forces interrupt status (execute without
557 * interruption)
558 * @n: interrupt bit
559 *
560 * This function returns an error code
561 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300562static int hw_intr_force(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800563{
564 if (n >= REG_BITS)
565 return -EINVAL;
566
Alexander Shishkin262c1632012-05-08 23:28:59 +0300567 hw_write(udc, CAP_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE);
568 hw_write(udc, OP_USBINTR, BIT(n), BIT(n));
569 hw_write(udc, OP_USBSTS, BIT(n), BIT(n));
570 hw_write(udc, CAP_TESTMODE, TESTMODE_FORCE, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800571 return 0;
572}
573
574/**
575 * hw_is_port_high_speed: test if port is high speed
576 *
577 * This function returns true if high speed port
578 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300579static int hw_port_is_high_speed(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800580{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300581 return udc->hw_bank.lpm ? hw_read(udc, OP_DEVLC, DEVLC_PSPD) :
582 hw_read(udc, OP_PORTSC, PORTSC_HSP);
David Lopoaa69a802008-11-17 14:14:51 -0800583}
584
585/**
586 * hw_port_test_get: reads port test mode value
587 *
588 * This function returns port test mode value
589 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300590static u8 hw_port_test_get(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800591{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300592 return hw_read(udc, OP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC);
David Lopoaa69a802008-11-17 14:14:51 -0800593}
594
595/**
596 * hw_port_test_set: writes port test mode (execute without interruption)
597 * @mode: new value
598 *
599 * This function returns an error code
600 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300601static int hw_port_test_set(struct ci13xxx *udc, u8 mode)
David Lopoaa69a802008-11-17 14:14:51 -0800602{
603 const u8 TEST_MODE_MAX = 7;
604
605 if (mode > TEST_MODE_MAX)
606 return -EINVAL;
607
Alexander Shishkin262c1632012-05-08 23:28:59 +0300608 hw_write(udc, OP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC));
David Lopoaa69a802008-11-17 14:14:51 -0800609 return 0;
610}
611
612/**
613 * hw_read_intr_enable: returns interrupt enable register
614 *
615 * This function returns register data
616 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300617static u32 hw_read_intr_enable(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800618{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300619 return hw_read(udc, OP_USBINTR, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800620}
621
622/**
623 * hw_read_intr_status: returns interrupt status register
624 *
625 * This function returns register data
626 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300627static u32 hw_read_intr_status(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800628{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300629 return hw_read(udc, OP_USBSTS, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800630}
631
632/**
633 * hw_register_read: reads all device registers (execute without interruption)
634 * @buf: destination buffer
635 * @size: buffer size
636 *
637 * This function returns number of registers read
638 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300639static size_t hw_register_read(struct ci13xxx *udc, u32 *buf, size_t size)
David Lopoaa69a802008-11-17 14:14:51 -0800640{
641 unsigned i;
642
Alexander Shishkind3595d12012-05-08 23:28:58 +0300643 if (size > udc->hw_bank.size)
644 size = udc->hw_bank.size;
David Lopoaa69a802008-11-17 14:14:51 -0800645
646 for (i = 0; i < size; i++)
Alexander Shishkin262c1632012-05-08 23:28:59 +0300647 buf[i] = hw_read(udc, i * sizeof(u32), ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800648
649 return size;
650}
651
652/**
653 * hw_register_write: writes to register
654 * @addr: register address
655 * @data: register value
656 *
657 * This function returns an error code
658 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300659static int hw_register_write(struct ci13xxx *udc, u16 addr, u32 data)
David Lopoaa69a802008-11-17 14:14:51 -0800660{
661 /* align */
662 addr /= sizeof(u32);
663
Alexander Shishkind3595d12012-05-08 23:28:58 +0300664 if (addr >= udc->hw_bank.size)
David Lopoaa69a802008-11-17 14:14:51 -0800665 return -EINVAL;
666
667 /* align */
668 addr *= sizeof(u32);
669
Alexander Shishkin262c1632012-05-08 23:28:59 +0300670 hw_write(udc, addr, ~0, data);
David Lopoaa69a802008-11-17 14:14:51 -0800671 return 0;
672}
673
674/**
675 * hw_test_and_clear_complete: test & clear complete status (execute without
676 * interruption)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200677 * @n: endpoint number
David Lopoaa69a802008-11-17 14:14:51 -0800678 *
679 * This function returns complete status
680 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300681static int hw_test_and_clear_complete(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800682{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300683 n = ep_to_bit(udc, n);
Alexander Shishkin262c1632012-05-08 23:28:59 +0300684 return hw_test_and_clear(udc, OP_ENDPTCOMPLETE, BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800685}
686
687/**
688 * hw_test_and_clear_intr_active: test & clear active interrupts (execute
689 * without interruption)
690 *
691 * This function returns active interrutps
692 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300693static u32 hw_test_and_clear_intr_active(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800694{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300695 u32 reg = hw_read_intr_status(udc) & hw_read_intr_enable(udc);
David Lopoaa69a802008-11-17 14:14:51 -0800696
Alexander Shishkin262c1632012-05-08 23:28:59 +0300697 hw_write(udc, OP_USBSTS, ~0, reg);
David Lopoaa69a802008-11-17 14:14:51 -0800698 return reg;
699}
700
701/**
702 * hw_test_and_clear_setup_guard: test & clear setup guard (execute without
703 * interruption)
704 *
705 * This function returns guard value
706 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300707static int hw_test_and_clear_setup_guard(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800708{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300709 return hw_test_and_write(udc, OP_USBCMD, USBCMD_SUTW, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800710}
711
712/**
713 * hw_test_and_set_setup_guard: test & set setup guard (execute without
714 * interruption)
715 *
716 * This function returns guard value
717 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300718static int hw_test_and_set_setup_guard(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800719{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300720 return hw_test_and_write(udc, OP_USBCMD, USBCMD_SUTW, USBCMD_SUTW);
David Lopoaa69a802008-11-17 14:14:51 -0800721}
722
723/**
724 * hw_usb_set_address: configures USB address (execute without interruption)
725 * @value: new USB address
726 *
727 * This function returns an error code
728 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300729static int hw_usb_set_address(struct ci13xxx *udc, u8 value)
David Lopoaa69a802008-11-17 14:14:51 -0800730{
731 /* advance */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300732 hw_write(udc, OP_DEVICEADDR, DEVICEADDR_USBADR | DEVICEADDR_USBADRA,
733 value << ffs_nr(DEVICEADDR_USBADR) | DEVICEADDR_USBADRA);
David Lopoaa69a802008-11-17 14:14:51 -0800734 return 0;
735}
736
737/**
738 * hw_usb_reset: restart device after a bus reset (execute without
739 * interruption)
740 *
741 * This function returns an error code
742 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300743static int hw_usb_reset(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800744{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300745 hw_usb_set_address(udc, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800746
747 /* ESS flushes only at end?!? */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300748 hw_write(udc, OP_ENDPTFLUSH, ~0, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800749
750 /* clear setup token semaphores */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300751 hw_write(udc, OP_ENDPTSETUPSTAT, 0, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800752
753 /* clear complete status */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300754 hw_write(udc, OP_ENDPTCOMPLETE, 0, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800755
756 /* wait until all bits cleared */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300757 while (hw_read(udc, OP_ENDPTPRIME, ~0))
David Lopoaa69a802008-11-17 14:14:51 -0800758 udelay(10); /* not RTOS friendly */
759
760 /* reset all endpoints ? */
761
762 /* reset internal status and wait for further instructions
763 no need to verify the port reset status (ESS does it) */
764
765 return 0;
766}
767
768/******************************************************************************
769 * DBG block
770 *****************************************************************************/
771/**
772 * show_device: prints information about device capabilities and status
773 *
774 * Check "device.h" for details
775 */
776static ssize_t show_device(struct device *dev, struct device_attribute *attr,
777 char *buf)
778{
779 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
780 struct usb_gadget *gadget = &udc->gadget;
781 int n = 0;
782
783 dbg_trace("[%s] %p\n", __func__, buf);
784 if (attr == NULL || buf == NULL) {
785 dev_err(dev, "[%s] EINVAL\n", __func__);
786 return 0;
787 }
788
789 n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n",
790 gadget->speed);
Michal Nazarewiczd327ab52011-11-19 18:27:37 +0100791 n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n",
792 gadget->max_speed);
793 /* TODO: Scheduled for removal in 3.8. */
David Lopoaa69a802008-11-17 14:14:51 -0800794 n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n",
Michal Nazarewiczd327ab52011-11-19 18:27:37 +0100795 gadget_is_dualspeed(gadget));
David Lopoaa69a802008-11-17 14:14:51 -0800796 n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
797 gadget->is_otg);
798 n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
799 gadget->is_a_peripheral);
800 n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n",
801 gadget->b_hnp_enable);
802 n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n",
803 gadget->a_hnp_support);
804 n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n",
805 gadget->a_alt_hnp_support);
806 n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n",
807 (gadget->name ? gadget->name : ""));
808
809 return n;
810}
811static DEVICE_ATTR(device, S_IRUSR, show_device, NULL);
812
813/**
814 * show_driver: prints information about attached gadget (if any)
815 *
816 * Check "device.h" for details
817 */
818static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
819 char *buf)
820{
821 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
822 struct usb_gadget_driver *driver = udc->driver;
823 int n = 0;
824
825 dbg_trace("[%s] %p\n", __func__, buf);
826 if (attr == NULL || buf == NULL) {
827 dev_err(dev, "[%s] EINVAL\n", __func__);
828 return 0;
829 }
830
831 if (driver == NULL)
832 return scnprintf(buf, PAGE_SIZE,
833 "There is no gadget attached!\n");
834
835 n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n",
836 (driver->function ? driver->function : ""));
837 n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n",
Michal Nazarewicz7177aed2011-11-19 18:27:38 +0100838 driver->max_speed);
David Lopoaa69a802008-11-17 14:14:51 -0800839
840 return n;
841}
842static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);
843
844/* Maximum event message length */
845#define DBG_DATA_MSG 64UL
846
847/* Maximum event messages */
848#define DBG_DATA_MAX 128UL
849
850/* Event buffer descriptor */
851static struct {
852 char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
853 unsigned idx; /* index */
854 unsigned tty; /* print to console? */
855 rwlock_t lck; /* lock */
856} dbg_data = {
857 .idx = 0,
858 .tty = 0,
859 .lck = __RW_LOCK_UNLOCKED(lck)
860};
861
862/**
863 * dbg_dec: decrements debug event index
864 * @idx: buffer index
865 */
866static void dbg_dec(unsigned *idx)
867{
868 *idx = (*idx - 1) & (DBG_DATA_MAX-1);
869}
870
871/**
872 * dbg_inc: increments debug event index
873 * @idx: buffer index
874 */
875static void dbg_inc(unsigned *idx)
876{
877 *idx = (*idx + 1) & (DBG_DATA_MAX-1);
878}
879
880/**
881 * dbg_print: prints the common part of the event
882 * @addr: endpoint address
883 * @name: event name
884 * @status: status
885 * @extra: extra information
886 */
887static void dbg_print(u8 addr, const char *name, int status, const char *extra)
888{
889 struct timeval tval;
890 unsigned int stamp;
891 unsigned long flags;
892
893 write_lock_irqsave(&dbg_data.lck, flags);
894
895 do_gettimeofday(&tval);
896 stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s */
897 stamp = stamp * 1000000 + tval.tv_usec;
898
899 scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +0300900 "%04X\t? %02X %-7.7s %4i ?\t%s\n",
David Lopoaa69a802008-11-17 14:14:51 -0800901 stamp, addr, name, status, extra);
902
903 dbg_inc(&dbg_data.idx);
904
905 write_unlock_irqrestore(&dbg_data.lck, flags);
906
907 if (dbg_data.tty != 0)
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +0300908 pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n",
David Lopoaa69a802008-11-17 14:14:51 -0800909 stamp, addr, name, status, extra);
910}
911
912/**
913 * dbg_done: prints a DONE event
914 * @addr: endpoint address
915 * @td: transfer descriptor
916 * @status: status
917 */
918static void dbg_done(u8 addr, const u32 token, int status)
919{
920 char msg[DBG_DATA_MSG];
921
922 scnprintf(msg, sizeof(msg), "%d %02X",
923 (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES),
924 (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS));
925 dbg_print(addr, "DONE", status, msg);
926}
927
928/**
929 * dbg_event: prints a generic event
930 * @addr: endpoint address
931 * @name: event name
932 * @status: status
933 */
934static void dbg_event(u8 addr, const char *name, int status)
935{
936 if (name != NULL)
937 dbg_print(addr, name, status, "");
938}
939
940/*
941 * dbg_queue: prints a QUEUE event
942 * @addr: endpoint address
943 * @req: USB request
944 * @status: status
945 */
946static void dbg_queue(u8 addr, const struct usb_request *req, int status)
947{
948 char msg[DBG_DATA_MSG];
949
950 if (req != NULL) {
951 scnprintf(msg, sizeof(msg),
952 "%d %d", !req->no_interrupt, req->length);
953 dbg_print(addr, "QUEUE", status, msg);
954 }
955}
956
957/**
958 * dbg_setup: prints a SETUP event
959 * @addr: endpoint address
960 * @req: setup request
961 */
962static void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
963{
964 char msg[DBG_DATA_MSG];
965
966 if (req != NULL) {
967 scnprintf(msg, sizeof(msg),
968 "%02X %02X %04X %04X %d", req->bRequestType,
969 req->bRequest, le16_to_cpu(req->wValue),
970 le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
971 dbg_print(addr, "SETUP", 0, msg);
972 }
973}
974
975/**
976 * show_events: displays the event buffer
977 *
978 * Check "device.h" for details
979 */
980static ssize_t show_events(struct device *dev, struct device_attribute *attr,
981 char *buf)
982{
983 unsigned long flags;
984 unsigned i, j, n = 0;
985
986 dbg_trace("[%s] %p\n", __func__, buf);
987 if (attr == NULL || buf == NULL) {
988 dev_err(dev, "[%s] EINVAL\n", __func__);
989 return 0;
990 }
991
992 read_lock_irqsave(&dbg_data.lck, flags);
993
994 i = dbg_data.idx;
995 for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) {
996 n += strlen(dbg_data.buf[i]);
997 if (n >= PAGE_SIZE) {
998 n -= strlen(dbg_data.buf[i]);
999 break;
1000 }
1001 }
1002 for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i))
1003 j += scnprintf(buf + j, PAGE_SIZE - j,
1004 "%s", dbg_data.buf[i]);
1005
1006 read_unlock_irqrestore(&dbg_data.lck, flags);
1007
1008 return n;
1009}
1010
1011/**
1012 * store_events: configure if events are going to be also printed to console
1013 *
1014 * Check "device.h" for details
1015 */
1016static ssize_t store_events(struct device *dev, struct device_attribute *attr,
1017 const char *buf, size_t count)
1018{
1019 unsigned tty;
1020
1021 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1022 if (attr == NULL || buf == NULL) {
1023 dev_err(dev, "[%s] EINVAL\n", __func__);
1024 goto done;
1025 }
1026
1027 if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
1028 dev_err(dev, "<1|0>: enable|disable console log\n");
1029 goto done;
1030 }
1031
1032 dbg_data.tty = tty;
1033 dev_info(dev, "tty = %u", dbg_data.tty);
1034
1035 done:
1036 return count;
1037}
1038static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events);
1039
1040/**
1041 * show_inters: interrupt status, enable status and historic
1042 *
1043 * Check "device.h" for details
1044 */
1045static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
1046 char *buf)
1047{
1048 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1049 unsigned long flags;
1050 u32 intr;
1051 unsigned i, j, n = 0;
1052
1053 dbg_trace("[%s] %p\n", __func__, buf);
1054 if (attr == NULL || buf == NULL) {
1055 dev_err(dev, "[%s] EINVAL\n", __func__);
1056 return 0;
1057 }
1058
Alexander Shishkind3595d12012-05-08 23:28:58 +03001059 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001060
1061 n += scnprintf(buf + n, PAGE_SIZE - n,
Alexander Shishkind3595d12012-05-08 23:28:58 +03001062 "status = %08x\n", hw_read_intr_status(udc));
David Lopoaa69a802008-11-17 14:14:51 -08001063 n += scnprintf(buf + n, PAGE_SIZE - n,
Alexander Shishkind3595d12012-05-08 23:28:58 +03001064 "enable = %08x\n", hw_read_intr_enable(udc));
David Lopoaa69a802008-11-17 14:14:51 -08001065
1066 n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
1067 isr_statistics.test);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001068 n += scnprintf(buf + n, PAGE_SIZE - n, "? ui = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001069 isr_statistics.ui);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001070 n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001071 isr_statistics.uei);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001072 n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001073 isr_statistics.pci);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001074 n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001075 isr_statistics.uri);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001076 n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001077 isr_statistics.sli);
1078 n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
1079 isr_statistics.none);
1080 n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n",
1081 isr_statistics.hndl.cnt);
1082
1083 for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) {
1084 i &= ISR_MASK;
1085 intr = isr_statistics.hndl.buf[i];
1086
1087 if (USBi_UI & intr)
1088 n += scnprintf(buf + n, PAGE_SIZE - n, "ui ");
1089 intr &= ~USBi_UI;
1090 if (USBi_UEI & intr)
1091 n += scnprintf(buf + n, PAGE_SIZE - n, "uei ");
1092 intr &= ~USBi_UEI;
1093 if (USBi_PCI & intr)
1094 n += scnprintf(buf + n, PAGE_SIZE - n, "pci ");
1095 intr &= ~USBi_PCI;
1096 if (USBi_URI & intr)
1097 n += scnprintf(buf + n, PAGE_SIZE - n, "uri ");
1098 intr &= ~USBi_URI;
1099 if (USBi_SLI & intr)
1100 n += scnprintf(buf + n, PAGE_SIZE - n, "sli ");
1101 intr &= ~USBi_SLI;
1102 if (intr)
1103 n += scnprintf(buf + n, PAGE_SIZE - n, "??? ");
1104 if (isr_statistics.hndl.buf[i])
1105 n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
1106 }
1107
Alexander Shishkind3595d12012-05-08 23:28:58 +03001108 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001109
1110 return n;
1111}
1112
1113/**
1114 * store_inters: enable & force or disable an individual interrutps
1115 * (to be used for test purposes only)
1116 *
1117 * Check "device.h" for details
1118 */
1119static ssize_t store_inters(struct device *dev, struct device_attribute *attr,
1120 const char *buf, size_t count)
1121{
1122 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1123 unsigned long flags;
1124 unsigned en, bit;
1125
1126 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1127 if (attr == NULL || buf == NULL) {
1128 dev_err(dev, "[%s] EINVAL\n", __func__);
1129 goto done;
1130 }
1131
1132 if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) {
1133 dev_err(dev, "<1|0> <bit>: enable|disable interrupt");
1134 goto done;
1135 }
1136
Alexander Shishkind3595d12012-05-08 23:28:58 +03001137 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001138 if (en) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001139 if (hw_intr_force(udc, bit))
David Lopoaa69a802008-11-17 14:14:51 -08001140 dev_err(dev, "invalid bit number\n");
1141 else
1142 isr_statistics.test++;
1143 } else {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001144 if (hw_intr_clear(udc, bit))
David Lopoaa69a802008-11-17 14:14:51 -08001145 dev_err(dev, "invalid bit number\n");
1146 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03001147 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001148
1149 done:
1150 return count;
1151}
1152static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters);
1153
1154/**
1155 * show_port_test: reads port test mode
1156 *
1157 * Check "device.h" for details
1158 */
1159static ssize_t show_port_test(struct device *dev,
1160 struct device_attribute *attr, char *buf)
1161{
1162 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1163 unsigned long flags;
1164 unsigned mode;
1165
1166 dbg_trace("[%s] %p\n", __func__, buf);
1167 if (attr == NULL || buf == NULL) {
1168 dev_err(dev, "[%s] EINVAL\n", __func__);
1169 return 0;
1170 }
1171
Alexander Shishkind3595d12012-05-08 23:28:58 +03001172 spin_lock_irqsave(&udc->lock, flags);
1173 mode = hw_port_test_get(udc);
1174 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001175
1176 return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode);
1177}
1178
1179/**
1180 * store_port_test: writes port test mode
1181 *
1182 * Check "device.h" for details
1183 */
1184static ssize_t store_port_test(struct device *dev,
1185 struct device_attribute *attr,
1186 const char *buf, size_t count)
1187{
1188 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1189 unsigned long flags;
1190 unsigned mode;
1191
1192 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1193 if (attr == NULL || buf == NULL) {
1194 dev_err(dev, "[%s] EINVAL\n", __func__);
1195 goto done;
1196 }
1197
1198 if (sscanf(buf, "%u", &mode) != 1) {
1199 dev_err(dev, "<mode>: set port test mode");
1200 goto done;
1201 }
1202
Alexander Shishkind3595d12012-05-08 23:28:58 +03001203 spin_lock_irqsave(&udc->lock, flags);
1204 if (hw_port_test_set(udc, mode))
David Lopoaa69a802008-11-17 14:14:51 -08001205 dev_err(dev, "invalid mode\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03001206 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001207
1208 done:
1209 return count;
1210}
1211static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR,
1212 show_port_test, store_port_test);
1213
1214/**
1215 * show_qheads: DMA contents of all queue heads
1216 *
1217 * Check "device.h" for details
1218 */
1219static ssize_t show_qheads(struct device *dev, struct device_attribute *attr,
1220 char *buf)
1221{
1222 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1223 unsigned long flags;
1224 unsigned i, j, n = 0;
1225
1226 dbg_trace("[%s] %p\n", __func__, buf);
1227 if (attr == NULL || buf == NULL) {
1228 dev_err(dev, "[%s] EINVAL\n", __func__);
1229 return 0;
1230 }
1231
Alexander Shishkind3595d12012-05-08 23:28:58 +03001232 spin_lock_irqsave(&udc->lock, flags);
1233 for (i = 0; i < udc->hw_ep_max/2; i++) {
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301234 struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i];
Alexander Shishkind3595d12012-05-08 23:28:58 +03001235 struct ci13xxx_ep *mEpTx =
1236 &udc->ci13xxx_ep[i + udc->hw_ep_max/2];
David Lopoaa69a802008-11-17 14:14:51 -08001237 n += scnprintf(buf + n, PAGE_SIZE - n,
1238 "EP=%02i: RX=%08X TX=%08X\n",
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301239 i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08001240 for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) {
1241 n += scnprintf(buf + n, PAGE_SIZE - n,
1242 " %04X: %08X %08X\n", j,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301243 *((u32 *)mEpRx->qh.ptr + j),
1244 *((u32 *)mEpTx->qh.ptr + j));
David Lopoaa69a802008-11-17 14:14:51 -08001245 }
1246 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03001247 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001248
1249 return n;
1250}
1251static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL);
1252
1253/**
1254 * show_registers: dumps all registers
1255 *
1256 * Check "device.h" for details
1257 */
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001258#define DUMP_ENTRIES 512
David Lopoaa69a802008-11-17 14:14:51 -08001259static ssize_t show_registers(struct device *dev,
1260 struct device_attribute *attr, char *buf)
1261{
1262 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1263 unsigned long flags;
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001264 u32 *dump;
David Lopoaa69a802008-11-17 14:14:51 -08001265 unsigned i, k, n = 0;
1266
1267 dbg_trace("[%s] %p\n", __func__, buf);
1268 if (attr == NULL || buf == NULL) {
1269 dev_err(dev, "[%s] EINVAL\n", __func__);
1270 return 0;
1271 }
1272
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001273 dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL);
1274 if (!dump) {
1275 dev_err(dev, "%s: out of memory\n", __func__);
1276 return 0;
1277 }
1278
Alexander Shishkind3595d12012-05-08 23:28:58 +03001279 spin_lock_irqsave(&udc->lock, flags);
1280 k = hw_register_read(udc, dump, DUMP_ENTRIES);
1281 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001282
1283 for (i = 0; i < k; i++) {
1284 n += scnprintf(buf + n, PAGE_SIZE - n,
1285 "reg[0x%04X] = 0x%08X\n",
1286 i * (unsigned)sizeof(u32), dump[i]);
1287 }
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001288 kfree(dump);
David Lopoaa69a802008-11-17 14:14:51 -08001289
1290 return n;
1291}
1292
1293/**
1294 * store_registers: writes value to register address
1295 *
1296 * Check "device.h" for details
1297 */
1298static ssize_t store_registers(struct device *dev,
1299 struct device_attribute *attr,
1300 const char *buf, size_t count)
1301{
1302 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1303 unsigned long addr, data, flags;
1304
1305 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1306 if (attr == NULL || buf == NULL) {
1307 dev_err(dev, "[%s] EINVAL\n", __func__);
1308 goto done;
1309 }
1310
1311 if (sscanf(buf, "%li %li", &addr, &data) != 2) {
1312 dev_err(dev, "<addr> <data>: write data to register address");
1313 goto done;
1314 }
1315
Alexander Shishkind3595d12012-05-08 23:28:58 +03001316 spin_lock_irqsave(&udc->lock, flags);
1317 if (hw_register_write(udc, addr, data))
David Lopoaa69a802008-11-17 14:14:51 -08001318 dev_err(dev, "invalid address range\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03001319 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001320
1321 done:
1322 return count;
1323}
1324static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR,
1325 show_registers, store_registers);
1326
1327/**
1328 * show_requests: DMA contents of all requests currently queued (all endpts)
1329 *
1330 * Check "device.h" for details
1331 */
1332static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
1333 char *buf)
1334{
1335 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1336 unsigned long flags;
1337 struct list_head *ptr = NULL;
1338 struct ci13xxx_req *req = NULL;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301339 unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -08001340
1341 dbg_trace("[%s] %p\n", __func__, buf);
1342 if (attr == NULL || buf == NULL) {
1343 dev_err(dev, "[%s] EINVAL\n", __func__);
1344 return 0;
1345 }
1346
Alexander Shishkind3595d12012-05-08 23:28:58 +03001347 spin_lock_irqsave(&udc->lock, flags);
1348 for (i = 0; i < udc->hw_ep_max; i++)
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301349 list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue)
1350 {
1351 req = list_entry(ptr, struct ci13xxx_req, queue);
David Lopoaa69a802008-11-17 14:14:51 -08001352
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301353 n += scnprintf(buf + n, PAGE_SIZE - n,
1354 "EP=%02i: TD=%08X %s\n",
Alexander Shishkind3595d12012-05-08 23:28:58 +03001355 i % udc->hw_ep_max/2, (u32)req->dma,
1356 ((i < udc->hw_ep_max/2) ? "RX" : "TX"));
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301357
1358 for (j = 0; j < qSize; j++)
David Lopoaa69a802008-11-17 14:14:51 -08001359 n += scnprintf(buf + n, PAGE_SIZE - n,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301360 " %04X: %08X\n", j,
1361 *((u32 *)req->ptr + j));
1362 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03001363 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001364
1365 return n;
1366}
1367static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL);
1368
1369/**
1370 * dbg_create_files: initializes the attribute interface
1371 * @dev: device
1372 *
1373 * This function returns an error code
1374 */
1375__maybe_unused static int dbg_create_files(struct device *dev)
1376{
1377 int retval = 0;
1378
1379 if (dev == NULL)
1380 return -EINVAL;
1381 retval = device_create_file(dev, &dev_attr_device);
1382 if (retval)
1383 goto done;
1384 retval = device_create_file(dev, &dev_attr_driver);
1385 if (retval)
1386 goto rm_device;
1387 retval = device_create_file(dev, &dev_attr_events);
1388 if (retval)
1389 goto rm_driver;
1390 retval = device_create_file(dev, &dev_attr_inters);
1391 if (retval)
1392 goto rm_events;
1393 retval = device_create_file(dev, &dev_attr_port_test);
1394 if (retval)
1395 goto rm_inters;
1396 retval = device_create_file(dev, &dev_attr_qheads);
1397 if (retval)
1398 goto rm_port_test;
1399 retval = device_create_file(dev, &dev_attr_registers);
1400 if (retval)
1401 goto rm_qheads;
1402 retval = device_create_file(dev, &dev_attr_requests);
1403 if (retval)
1404 goto rm_registers;
1405 return 0;
1406
1407 rm_registers:
1408 device_remove_file(dev, &dev_attr_registers);
1409 rm_qheads:
1410 device_remove_file(dev, &dev_attr_qheads);
1411 rm_port_test:
1412 device_remove_file(dev, &dev_attr_port_test);
1413 rm_inters:
1414 device_remove_file(dev, &dev_attr_inters);
1415 rm_events:
1416 device_remove_file(dev, &dev_attr_events);
1417 rm_driver:
1418 device_remove_file(dev, &dev_attr_driver);
1419 rm_device:
1420 device_remove_file(dev, &dev_attr_device);
1421 done:
1422 return retval;
1423}
1424
1425/**
1426 * dbg_remove_files: destroys the attribute interface
1427 * @dev: device
1428 *
1429 * This function returns an error code
1430 */
1431__maybe_unused static int dbg_remove_files(struct device *dev)
1432{
1433 if (dev == NULL)
1434 return -EINVAL;
1435 device_remove_file(dev, &dev_attr_requests);
1436 device_remove_file(dev, &dev_attr_registers);
1437 device_remove_file(dev, &dev_attr_qheads);
1438 device_remove_file(dev, &dev_attr_port_test);
1439 device_remove_file(dev, &dev_attr_inters);
1440 device_remove_file(dev, &dev_attr_events);
1441 device_remove_file(dev, &dev_attr_driver);
1442 device_remove_file(dev, &dev_attr_device);
1443 return 0;
1444}
1445
1446/******************************************************************************
1447 * UTIL block
1448 *****************************************************************************/
1449/**
1450 * _usb_addr: calculates endpoint address from direction & number
1451 * @ep: endpoint
1452 */
1453static inline u8 _usb_addr(struct ci13xxx_ep *ep)
1454{
1455 return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num;
1456}
1457
1458/**
1459 * _hardware_queue: configures a request at hardware level
1460 * @gadget: gadget
1461 * @mEp: endpoint
1462 *
1463 * This function returns an error code
1464 */
1465static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1466{
Alexander Shishkind3595d12012-05-08 23:28:58 +03001467 struct ci13xxx *udc = mEp->udc;
David Lopoaa69a802008-11-17 14:14:51 -08001468 unsigned i;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301469 int ret = 0;
1470 unsigned length = mReq->req.length;
David Lopoaa69a802008-11-17 14:14:51 -08001471
1472 trace("%p, %p", mEp, mReq);
1473
1474 /* don't queue twice */
1475 if (mReq->req.status == -EALREADY)
1476 return -EALREADY;
1477
David Lopoaa69a802008-11-17 14:14:51 -08001478 mReq->req.status = -EALREADY;
Michael Grzeschik954aad82011-10-10 18:38:06 +02001479 if (length && mReq->req.dma == DMA_ADDR_INVALID) {
David Lopoaa69a802008-11-17 14:14:51 -08001480 mReq->req.dma = \
1481 dma_map_single(mEp->device, mReq->req.buf,
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301482 length, mEp->dir ? DMA_TO_DEVICE :
1483 DMA_FROM_DEVICE);
David Lopoaa69a802008-11-17 14:14:51 -08001484 if (mReq->req.dma == 0)
1485 return -ENOMEM;
1486
1487 mReq->map = 1;
1488 }
1489
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301490 if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) {
1491 mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC,
1492 &mReq->zdma);
1493 if (mReq->zptr == NULL) {
1494 if (mReq->map) {
1495 dma_unmap_single(mEp->device, mReq->req.dma,
1496 length, mEp->dir ? DMA_TO_DEVICE :
1497 DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02001498 mReq->req.dma = DMA_ADDR_INVALID;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301499 mReq->map = 0;
1500 }
1501 return -ENOMEM;
1502 }
1503 memset(mReq->zptr, 0, sizeof(*mReq->zptr));
1504 mReq->zptr->next = TD_TERMINATE;
1505 mReq->zptr->token = TD_STATUS_ACTIVE;
1506 if (!mReq->req.no_interrupt)
1507 mReq->zptr->token |= TD_IOC;
1508 }
David Lopoaa69a802008-11-17 14:14:51 -08001509 /*
1510 * TD configuration
1511 * TODO - handle requests which spawns into several TDs
1512 */
1513 memset(mReq->ptr, 0, sizeof(*mReq->ptr));
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301514 mReq->ptr->token = length << ffs_nr(TD_TOTAL_BYTES);
David Lopoaa69a802008-11-17 14:14:51 -08001515 mReq->ptr->token &= TD_TOTAL_BYTES;
David Lopoaa69a802008-11-17 14:14:51 -08001516 mReq->ptr->token |= TD_STATUS_ACTIVE;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301517 if (mReq->zptr) {
1518 mReq->ptr->next = mReq->zdma;
1519 } else {
1520 mReq->ptr->next = TD_TERMINATE;
1521 if (!mReq->req.no_interrupt)
1522 mReq->ptr->token |= TD_IOC;
1523 }
David Lopoaa69a802008-11-17 14:14:51 -08001524 mReq->ptr->page[0] = mReq->req.dma;
1525 for (i = 1; i < 5; i++)
1526 mReq->ptr->page[i] =
Artem Leonenko0a313c42010-12-14 23:47:06 -08001527 (mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
David Lopoaa69a802008-11-17 14:14:51 -08001528
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301529 if (!list_empty(&mEp->qh.queue)) {
1530 struct ci13xxx_req *mReqPrev;
1531 int n = hw_ep_bit(mEp->num, mEp->dir);
1532 int tmp_stat;
1533
1534 mReqPrev = list_entry(mEp->qh.queue.prev,
1535 struct ci13xxx_req, queue);
1536 if (mReqPrev->zptr)
1537 mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK;
1538 else
1539 mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK;
1540 wmb();
Alexander Shishkin262c1632012-05-08 23:28:59 +03001541 if (hw_read(udc, OP_ENDPTPRIME, BIT(n)))
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301542 goto done;
1543 do {
Alexander Shishkin262c1632012-05-08 23:28:59 +03001544 hw_write(udc, OP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
1545 tmp_stat = hw_read(udc, OP_ENDPTSTAT, BIT(n));
1546 } while (!hw_read(udc, OP_USBCMD, USBCMD_ATDTW));
1547 hw_write(udc, OP_USBCMD, USBCMD_ATDTW, 0);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301548 if (tmp_stat)
1549 goto done;
1550 }
1551
1552 /* QH configuration */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301553 mEp->qh.ptr->td.next = mReq->dma; /* TERMINATE = 0 */
1554 mEp->qh.ptr->td.token &= ~TD_STATUS; /* clear status */
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301555 mEp->qh.ptr->cap |= QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08001556
1557 wmb(); /* synchronize before ep prime */
1558
Alexander Shishkind3595d12012-05-08 23:28:58 +03001559 ret = hw_ep_prime(udc, mEp->num, mEp->dir,
David Lopoaa69a802008-11-17 14:14:51 -08001560 mEp->type == USB_ENDPOINT_XFER_CONTROL);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301561done:
1562 return ret;
David Lopoaa69a802008-11-17 14:14:51 -08001563}
1564
1565/**
1566 * _hardware_dequeue: handles a request at hardware level
1567 * @gadget: gadget
1568 * @mEp: endpoint
1569 *
1570 * This function returns an error code
1571 */
1572static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1573{
1574 trace("%p, %p", mEp, mReq);
1575
1576 if (mReq->req.status != -EALREADY)
1577 return -EINVAL;
1578
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301579 if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0)
1580 return -EBUSY;
1581
1582 if (mReq->zptr) {
1583 if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
1584 return -EBUSY;
1585 dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
1586 mReq->zptr = NULL;
1587 }
David Lopoaa69a802008-11-17 14:14:51 -08001588
1589 mReq->req.status = 0;
1590
1591 if (mReq->map) {
1592 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
1593 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02001594 mReq->req.dma = DMA_ADDR_INVALID;
David Lopoaa69a802008-11-17 14:14:51 -08001595 mReq->map = 0;
1596 }
1597
1598 mReq->req.status = mReq->ptr->token & TD_STATUS;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301599 if ((TD_STATUS_HALTED & mReq->req.status) != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001600 mReq->req.status = -1;
1601 else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0)
1602 mReq->req.status = -1;
1603 else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0)
1604 mReq->req.status = -1;
1605
1606 mReq->req.actual = mReq->ptr->token & TD_TOTAL_BYTES;
1607 mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES);
1608 mReq->req.actual = mReq->req.length - mReq->req.actual;
1609 mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual;
1610
1611 return mReq->req.actual;
1612}
1613
1614/**
1615 * _ep_nuke: dequeues all endpoint requests
1616 * @mEp: endpoint
1617 *
1618 * This function returns an error code
1619 * Caller must hold lock
1620 */
1621static int _ep_nuke(struct ci13xxx_ep *mEp)
1622__releases(mEp->lock)
1623__acquires(mEp->lock)
1624{
1625 trace("%p", mEp);
1626
1627 if (mEp == NULL)
1628 return -EINVAL;
1629
Alexander Shishkind3595d12012-05-08 23:28:58 +03001630 hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08001631
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301632 while (!list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08001633
1634 /* pop oldest request */
1635 struct ci13xxx_req *mReq = \
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301636 list_entry(mEp->qh.queue.next,
David Lopoaa69a802008-11-17 14:14:51 -08001637 struct ci13xxx_req, queue);
1638 list_del_init(&mReq->queue);
1639 mReq->req.status = -ESHUTDOWN;
1640
Artem Leonenko7c25a822010-12-14 23:46:55 -08001641 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08001642 spin_unlock(mEp->lock);
1643 mReq->req.complete(&mEp->ep, &mReq->req);
1644 spin_lock(mEp->lock);
1645 }
1646 }
1647 return 0;
1648}
1649
1650/**
1651 * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
1652 * @gadget: gadget
1653 *
1654 * This function returns an error code
David Lopoaa69a802008-11-17 14:14:51 -08001655 */
1656static int _gadget_stop_activity(struct usb_gadget *gadget)
David Lopoaa69a802008-11-17 14:14:51 -08001657{
1658 struct usb_ep *ep;
1659 struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301660 unsigned long flags;
David Lopoaa69a802008-11-17 14:14:51 -08001661
1662 trace("%p", gadget);
1663
1664 if (gadget == NULL)
1665 return -EINVAL;
1666
Alexander Shishkind3595d12012-05-08 23:28:58 +03001667 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301668 udc->gadget.speed = USB_SPEED_UNKNOWN;
1669 udc->remote_wakeup = 0;
1670 udc->suspended = 0;
Alexander Shishkind3595d12012-05-08 23:28:58 +03001671 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301672
David Lopoaa69a802008-11-17 14:14:51 -08001673 /* flush all endpoints */
1674 gadget_for_each_ep(ep, gadget) {
1675 usb_ep_fifo_flush(ep);
1676 }
Alexander Shishkind36ade62012-05-04 16:47:15 +03001677 usb_ep_fifo_flush(&udc->ep0out->ep);
1678 usb_ep_fifo_flush(&udc->ep0in->ep);
David Lopoaa69a802008-11-17 14:14:51 -08001679
1680 udc->driver->disconnect(gadget);
1681
1682 /* make sure to disable all endpoints */
1683 gadget_for_each_ep(ep, gadget) {
1684 usb_ep_disable(ep);
1685 }
David Lopoaa69a802008-11-17 14:14:51 -08001686
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301687 if (udc->status != NULL) {
Alexander Shishkind36ade62012-05-04 16:47:15 +03001688 usb_ep_free_request(&udc->ep0in->ep, udc->status);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301689 udc->status = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08001690 }
1691
David Lopoaa69a802008-11-17 14:14:51 -08001692 return 0;
1693}
1694
1695/******************************************************************************
1696 * ISR block
1697 *****************************************************************************/
1698/**
1699 * isr_reset_handler: USB reset interrupt handler
1700 * @udc: UDC device
1701 *
1702 * This function resets USB engine after a bus reset occurred
1703 */
1704static void isr_reset_handler(struct ci13xxx *udc)
1705__releases(udc->lock)
1706__acquires(udc->lock)
1707{
David Lopoaa69a802008-11-17 14:14:51 -08001708 int retval;
1709
1710 trace("%p", udc);
1711
1712 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001713 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08001714 return;
1715 }
1716
1717 dbg_event(0xFF, "BUS RST", 0);
1718
Alexander Shishkind3595d12012-05-08 23:28:58 +03001719 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001720 retval = _gadget_stop_activity(&udc->gadget);
1721 if (retval)
1722 goto done;
1723
Alexander Shishkind3595d12012-05-08 23:28:58 +03001724 retval = hw_usb_reset(udc);
David Lopoaa69a802008-11-17 14:14:51 -08001725 if (retval)
1726 goto done;
1727
Alexander Shishkind36ade62012-05-04 16:47:15 +03001728 udc->status = usb_ep_alloc_request(&udc->ep0in->ep, GFP_ATOMIC);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05301729 if (udc->status == NULL)
1730 retval = -ENOMEM;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301731
Alexander Shishkind3595d12012-05-08 23:28:58 +03001732 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001733
1734 done:
1735 if (retval)
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001736 pr_err("error: %i\n", retval);
David Lopoaa69a802008-11-17 14:14:51 -08001737}
1738
1739/**
1740 * isr_get_status_complete: get_status request complete function
1741 * @ep: endpoint
1742 * @req: request handled
1743 *
1744 * Caller must release lock
1745 */
1746static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
1747{
1748 trace("%p, %p", ep, req);
1749
1750 if (ep == NULL || req == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001751 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08001752 return;
1753 }
1754
1755 kfree(req->buf);
1756 usb_ep_free_request(ep, req);
1757}
1758
1759/**
1760 * isr_get_status_response: get_status request response
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301761 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001762 * @setup: setup request packet
1763 *
1764 * This function returns an error code
1765 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301766static int isr_get_status_response(struct ci13xxx *udc,
David Lopoaa69a802008-11-17 14:14:51 -08001767 struct usb_ctrlrequest *setup)
1768__releases(mEp->lock)
1769__acquires(mEp->lock)
1770{
Alexander Shishkind36ade62012-05-04 16:47:15 +03001771 struct ci13xxx_ep *mEp = udc->ep0in;
David Lopoaa69a802008-11-17 14:14:51 -08001772 struct usb_request *req = NULL;
1773 gfp_t gfp_flags = GFP_ATOMIC;
1774 int dir, num, retval;
1775
1776 trace("%p, %p", mEp, setup);
1777
1778 if (mEp == NULL || setup == NULL)
1779 return -EINVAL;
1780
1781 spin_unlock(mEp->lock);
1782 req = usb_ep_alloc_request(&mEp->ep, gfp_flags);
1783 spin_lock(mEp->lock);
1784 if (req == NULL)
1785 return -ENOMEM;
1786
1787 req->complete = isr_get_status_complete;
1788 req->length = 2;
1789 req->buf = kzalloc(req->length, gfp_flags);
1790 if (req->buf == NULL) {
1791 retval = -ENOMEM;
1792 goto err_free_req;
1793 }
1794
1795 if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301796 /* Assume that device is bus powered for now. */
Alexander Shishkin1155a7b2012-05-08 23:28:57 +03001797 *(u16 *)req->buf = _udc->remote_wakeup << 1;
David Lopoaa69a802008-11-17 14:14:51 -08001798 retval = 0;
1799 } else if ((setup->bRequestType & USB_RECIP_MASK) \
1800 == USB_RECIP_ENDPOINT) {
1801 dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ?
1802 TX : RX;
1803 num = le16_to_cpu(setup->wIndex) & USB_ENDPOINT_NUMBER_MASK;
Alexander Shishkind3595d12012-05-08 23:28:58 +03001804 *(u16 *)req->buf = hw_ep_get_halt(udc, num, dir);
David Lopoaa69a802008-11-17 14:14:51 -08001805 }
1806 /* else do nothing; reserved for future use */
1807
1808 spin_unlock(mEp->lock);
1809 retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
1810 spin_lock(mEp->lock);
1811 if (retval)
1812 goto err_free_buf;
1813
1814 return 0;
1815
1816 err_free_buf:
1817 kfree(req->buf);
1818 err_free_req:
1819 spin_unlock(mEp->lock);
1820 usb_ep_free_request(&mEp->ep, req);
1821 spin_lock(mEp->lock);
1822 return retval;
1823}
1824
1825/**
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301826 * isr_setup_status_complete: setup_status request complete function
1827 * @ep: endpoint
1828 * @req: request handled
1829 *
1830 * Caller must release lock. Put the port in test mode if test mode
1831 * feature is selected.
1832 */
1833static void
1834isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
1835{
1836 struct ci13xxx *udc = req->context;
1837 unsigned long flags;
1838
1839 trace("%p, %p", ep, req);
1840
Alexander Shishkind3595d12012-05-08 23:28:58 +03001841 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301842 if (udc->test_mode)
Alexander Shishkind3595d12012-05-08 23:28:58 +03001843 hw_port_test_set(udc, udc->test_mode);
1844 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301845}
1846
1847/**
David Lopoaa69a802008-11-17 14:14:51 -08001848 * isr_setup_status_phase: queues the status phase of a setup transation
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301849 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001850 *
1851 * This function returns an error code
1852 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301853static int isr_setup_status_phase(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -08001854__releases(mEp->lock)
1855__acquires(mEp->lock)
1856{
1857 int retval;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301858 struct ci13xxx_ep *mEp;
David Lopoaa69a802008-11-17 14:14:51 -08001859
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301860 trace("%p", udc);
David Lopoaa69a802008-11-17 14:14:51 -08001861
Alexander Shishkind36ade62012-05-04 16:47:15 +03001862 mEp = (udc->ep0_dir == TX) ? udc->ep0out : udc->ep0in;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301863 udc->status->context = udc;
1864 udc->status->complete = isr_setup_status_complete;
David Lopoaa69a802008-11-17 14:14:51 -08001865
1866 spin_unlock(mEp->lock);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301867 retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
David Lopoaa69a802008-11-17 14:14:51 -08001868 spin_lock(mEp->lock);
1869
1870 return retval;
1871}
1872
1873/**
1874 * isr_tr_complete_low: transaction complete low level handler
1875 * @mEp: endpoint
1876 *
1877 * This function returns an error code
1878 * Caller must hold lock
1879 */
1880static int isr_tr_complete_low(struct ci13xxx_ep *mEp)
1881__releases(mEp->lock)
1882__acquires(mEp->lock)
1883{
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301884 struct ci13xxx_req *mReq, *mReqTemp;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301885 struct ci13xxx_ep *mEpTemp = mEp;
Pavankumar Kondeti986b11b2011-05-02 11:56:29 +05301886 int uninitialized_var(retval);
David Lopoaa69a802008-11-17 14:14:51 -08001887
1888 trace("%p", mEp);
1889
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301890 if (list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08001891 return -EINVAL;
1892
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301893 list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue,
1894 queue) {
1895 retval = _hardware_dequeue(mEp, mReq);
1896 if (retval < 0)
1897 break;
1898 list_del_init(&mReq->queue);
1899 dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
1900 if (mReq->req.complete != NULL) {
1901 spin_unlock(mEp->lock);
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301902 if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
1903 mReq->req.length)
Alexander Shishkind36ade62012-05-04 16:47:15 +03001904 mEpTemp = _udc->ep0in;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301905 mReq->req.complete(&mEpTemp->ep, &mReq->req);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301906 spin_lock(mEp->lock);
1907 }
1908 }
David Lopoaa69a802008-11-17 14:14:51 -08001909
Pavankumar Kondetief907482011-05-02 11:56:27 +05301910 if (retval == -EBUSY)
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301911 retval = 0;
1912 if (retval < 0)
David Lopoaa69a802008-11-17 14:14:51 -08001913 dbg_event(_usb_addr(mEp), "DONE", retval);
David Lopoaa69a802008-11-17 14:14:51 -08001914
David Lopoaa69a802008-11-17 14:14:51 -08001915 return retval;
1916}
1917
1918/**
1919 * isr_tr_complete_handler: transaction complete interrupt handler
1920 * @udc: UDC descriptor
1921 *
1922 * This function handles traffic events
1923 */
1924static void isr_tr_complete_handler(struct ci13xxx *udc)
1925__releases(udc->lock)
1926__acquires(udc->lock)
1927{
1928 unsigned i;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301929 u8 tmode = 0;
David Lopoaa69a802008-11-17 14:14:51 -08001930
1931 trace("%p", udc);
1932
1933 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001934 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08001935 return;
1936 }
1937
Alexander Shishkind3595d12012-05-08 23:28:58 +03001938 for (i = 0; i < udc->hw_ep_max; i++) {
David Lopoaa69a802008-11-17 14:14:51 -08001939 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301940 int type, num, dir, err = -EINVAL;
David Lopoaa69a802008-11-17 14:14:51 -08001941 struct usb_ctrlrequest req;
1942
Ido Shayevitz31fb6012012-03-12 20:25:23 +02001943 if (mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08001944 continue; /* not configured */
1945
Alexander Shishkind3595d12012-05-08 23:28:58 +03001946 if (hw_test_and_clear_complete(udc, i)) {
David Lopoaa69a802008-11-17 14:14:51 -08001947 err = isr_tr_complete_low(mEp);
1948 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
1949 if (err > 0) /* needs status phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301950 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08001951 if (err < 0) {
1952 dbg_event(_usb_addr(mEp),
1953 "ERROR", err);
Alexander Shishkind3595d12012-05-08 23:28:58 +03001954 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001955 if (usb_ep_set_halt(&mEp->ep))
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001956 dev_err(&udc->gadget.dev,
1957 "error: ep_set_halt\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03001958 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001959 }
1960 }
1961 }
1962
1963 if (mEp->type != USB_ENDPOINT_XFER_CONTROL ||
Alexander Shishkind3595d12012-05-08 23:28:58 +03001964 !hw_test_and_clear_setup_status(udc, i))
David Lopoaa69a802008-11-17 14:14:51 -08001965 continue;
1966
1967 if (i != 0) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001968 dev_warn(&udc->gadget.dev,
1969 "ctrl traffic received at endpoint\n");
David Lopoaa69a802008-11-17 14:14:51 -08001970 continue;
1971 }
1972
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301973 /*
1974 * Flush data and handshake transactions of previous
1975 * setup packet.
1976 */
Alexander Shishkind36ade62012-05-04 16:47:15 +03001977 _ep_nuke(udc->ep0out);
1978 _ep_nuke(udc->ep0in);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301979
David Lopoaa69a802008-11-17 14:14:51 -08001980 /* read_setup_packet */
1981 do {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001982 hw_test_and_set_setup_guard(udc);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301983 memcpy(&req, &mEp->qh.ptr->setup, sizeof(req));
Alexander Shishkind3595d12012-05-08 23:28:58 +03001984 } while (!hw_test_and_clear_setup_guard(udc));
David Lopoaa69a802008-11-17 14:14:51 -08001985
1986 type = req.bRequestType;
1987
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301988 udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX;
David Lopoaa69a802008-11-17 14:14:51 -08001989
1990 dbg_setup(_usb_addr(mEp), &req);
1991
1992 switch (req.bRequest) {
1993 case USB_REQ_CLEAR_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301994 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
1995 le16_to_cpu(req.wValue) ==
1996 USB_ENDPOINT_HALT) {
1997 if (req.wLength != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001998 break;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301999 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302000 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302001 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302002 if (dir) /* TX */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002003 num += udc->hw_ep_max/2;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302004 if (!udc->ci13xxx_ep[num].wedge) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002005 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302006 err = usb_ep_clear_halt(
2007 &udc->ci13xxx_ep[num].ep);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002008 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302009 if (err)
2010 break;
2011 }
2012 err = isr_setup_status_phase(udc);
2013 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) &&
2014 le16_to_cpu(req.wValue) ==
2015 USB_DEVICE_REMOTE_WAKEUP) {
2016 if (req.wLength != 0)
2017 break;
2018 udc->remote_wakeup = 0;
2019 err = isr_setup_status_phase(udc);
2020 } else {
2021 goto delegate;
David Lopoaa69a802008-11-17 14:14:51 -08002022 }
David Lopoaa69a802008-11-17 14:14:51 -08002023 break;
2024 case USB_REQ_GET_STATUS:
2025 if (type != (USB_DIR_IN|USB_RECIP_DEVICE) &&
2026 type != (USB_DIR_IN|USB_RECIP_ENDPOINT) &&
2027 type != (USB_DIR_IN|USB_RECIP_INTERFACE))
2028 goto delegate;
2029 if (le16_to_cpu(req.wLength) != 2 ||
2030 le16_to_cpu(req.wValue) != 0)
2031 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302032 err = isr_get_status_response(udc, &req);
David Lopoaa69a802008-11-17 14:14:51 -08002033 break;
2034 case USB_REQ_SET_ADDRESS:
2035 if (type != (USB_DIR_OUT|USB_RECIP_DEVICE))
2036 goto delegate;
2037 if (le16_to_cpu(req.wLength) != 0 ||
2038 le16_to_cpu(req.wIndex) != 0)
2039 break;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002040 err = hw_usb_set_address(udc,
2041 (u8)le16_to_cpu(req.wValue));
David Lopoaa69a802008-11-17 14:14:51 -08002042 if (err)
2043 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302044 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08002045 break;
2046 case USB_REQ_SET_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302047 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
2048 le16_to_cpu(req.wValue) ==
2049 USB_ENDPOINT_HALT) {
2050 if (req.wLength != 0)
2051 break;
2052 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302053 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302054 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302055 if (dir) /* TX */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002056 num += udc->hw_ep_max/2;
David Lopoaa69a802008-11-17 14:14:51 -08002057
Alexander Shishkind3595d12012-05-08 23:28:58 +03002058 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302059 err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002060 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302061 if (!err)
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302062 isr_setup_status_phase(udc);
2063 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302064 if (req.wLength != 0)
2065 break;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302066 switch (le16_to_cpu(req.wValue)) {
2067 case USB_DEVICE_REMOTE_WAKEUP:
2068 udc->remote_wakeup = 1;
2069 err = isr_setup_status_phase(udc);
2070 break;
2071 case USB_DEVICE_TEST_MODE:
2072 tmode = le16_to_cpu(req.wIndex) >> 8;
2073 switch (tmode) {
2074 case TEST_J:
2075 case TEST_K:
2076 case TEST_SE0_NAK:
2077 case TEST_PACKET:
2078 case TEST_FORCE_EN:
2079 udc->test_mode = tmode;
2080 err = isr_setup_status_phase(
2081 udc);
2082 break;
2083 default:
2084 break;
2085 }
2086 default:
2087 goto delegate;
2088 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302089 } else {
2090 goto delegate;
2091 }
David Lopoaa69a802008-11-17 14:14:51 -08002092 break;
2093 default:
2094delegate:
2095 if (req.wLength == 0) /* no data phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302096 udc->ep0_dir = TX;
David Lopoaa69a802008-11-17 14:14:51 -08002097
Alexander Shishkind3595d12012-05-08 23:28:58 +03002098 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002099 err = udc->driver->setup(&udc->gadget, &req);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002100 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002101 break;
2102 }
2103
2104 if (err < 0) {
2105 dbg_event(_usb_addr(mEp), "ERROR", err);
2106
Alexander Shishkind3595d12012-05-08 23:28:58 +03002107 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002108 if (usb_ep_set_halt(&mEp->ep))
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002109 dev_err(&udc->gadget.dev,
2110 "error: ep_set_halt\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03002111 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002112 }
2113 }
2114}
2115
2116/******************************************************************************
2117 * ENDPT block
2118 *****************************************************************************/
2119/**
2120 * ep_enable: configure endpoint, making it usable
2121 *
2122 * Check usb_ep_enable() at "usb_gadget.h" for details
2123 */
2124static int ep_enable(struct usb_ep *ep,
2125 const struct usb_endpoint_descriptor *desc)
2126{
2127 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302128 int retval = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002129 unsigned long flags;
2130
2131 trace("%p, %p", ep, desc);
2132
2133 if (ep == NULL || desc == NULL)
2134 return -EINVAL;
2135
2136 spin_lock_irqsave(mEp->lock, flags);
2137
2138 /* only internal SW should enable ctrl endpts */
2139
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002140 mEp->ep.desc = desc;
David Lopoaa69a802008-11-17 14:14:51 -08002141
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302142 if (!list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002143 warn("enabling a non-empty endpoint!");
2144
Matthias Kaehlcke15739bb2009-04-15 22:28:41 +02002145 mEp->dir = usb_endpoint_dir_in(desc) ? TX : RX;
2146 mEp->num = usb_endpoint_num(desc);
2147 mEp->type = usb_endpoint_type(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002148
Kuninori Morimoto29cc8892011-08-23 03:12:03 -07002149 mEp->ep.maxpacket = usb_endpoint_maxp(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002150
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302151 dbg_event(_usb_addr(mEp), "ENABLE", 0);
David Lopoaa69a802008-11-17 14:14:51 -08002152
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302153 mEp->qh.ptr->cap = 0;
David Lopof23e6492009-04-16 14:35:24 -07002154
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302155 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2156 mEp->qh.ptr->cap |= QH_IOS;
2157 else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
2158 mEp->qh.ptr->cap &= ~QH_MULT;
2159 else
2160 mEp->qh.ptr->cap &= ~QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08002161
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302162 mEp->qh.ptr->cap |=
2163 (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
2164 mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */
David Lopoaa69a802008-11-17 14:14:51 -08002165
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302166 /*
2167 * Enable endpoints in the HW other than ep0 as ep0
2168 * is always enabled
2169 */
2170 if (mEp->num)
Alexander Shishkind3595d12012-05-08 23:28:58 +03002171 retval |= hw_ep_enable(mEp->udc, mEp->num, mEp->dir, mEp->type);
David Lopoaa69a802008-11-17 14:14:51 -08002172
2173 spin_unlock_irqrestore(mEp->lock, flags);
2174 return retval;
2175}
2176
2177/**
2178 * ep_disable: endpoint is no longer usable
2179 *
2180 * Check usb_ep_disable() at "usb_gadget.h" for details
2181 */
2182static int ep_disable(struct usb_ep *ep)
2183{
2184 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2185 int direction, retval = 0;
2186 unsigned long flags;
2187
2188 trace("%p", ep);
2189
2190 if (ep == NULL)
2191 return -EINVAL;
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002192 else if (mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002193 return -EBUSY;
2194
2195 spin_lock_irqsave(mEp->lock, flags);
2196
2197 /* only internal SW should disable ctrl endpts */
2198
2199 direction = mEp->dir;
2200 do {
2201 dbg_event(_usb_addr(mEp), "DISABLE", 0);
2202
2203 retval |= _ep_nuke(mEp);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002204 retval |= hw_ep_disable(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002205
2206 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2207 mEp->dir = (mEp->dir == TX) ? RX : TX;
2208
2209 } while (mEp->dir != direction);
2210
Ido Shayevitzf9c56cd2012-02-08 13:56:48 +02002211 mEp->ep.desc = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002212
2213 spin_unlock_irqrestore(mEp->lock, flags);
2214 return retval;
2215}
2216
2217/**
2218 * ep_alloc_request: allocate a request object to use with this endpoint
2219 *
2220 * Check usb_ep_alloc_request() at "usb_gadget.h" for details
2221 */
2222static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
2223{
2224 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2225 struct ci13xxx_req *mReq = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002226
2227 trace("%p, %i", ep, gfp_flags);
2228
2229 if (ep == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002230 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08002231 return NULL;
2232 }
2233
David Lopoaa69a802008-11-17 14:14:51 -08002234 mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
2235 if (mReq != NULL) {
2236 INIT_LIST_HEAD(&mReq->queue);
Michael Grzeschik954aad82011-10-10 18:38:06 +02002237 mReq->req.dma = DMA_ADDR_INVALID;
David Lopoaa69a802008-11-17 14:14:51 -08002238
2239 mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
2240 &mReq->dma);
2241 if (mReq->ptr == NULL) {
2242 kfree(mReq);
2243 mReq = NULL;
2244 }
2245 }
2246
2247 dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
2248
David Lopoaa69a802008-11-17 14:14:51 -08002249 return (mReq == NULL) ? NULL : &mReq->req;
2250}
2251
2252/**
2253 * ep_free_request: frees a request object
2254 *
2255 * Check usb_ep_free_request() at "usb_gadget.h" for details
2256 */
2257static void ep_free_request(struct usb_ep *ep, struct usb_request *req)
2258{
2259 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2260 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2261 unsigned long flags;
2262
2263 trace("%p, %p", ep, req);
2264
2265 if (ep == NULL || req == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002266 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08002267 return;
2268 } else if (!list_empty(&mReq->queue)) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002269 pr_err("EBUSY\n");
David Lopoaa69a802008-11-17 14:14:51 -08002270 return;
2271 }
2272
2273 spin_lock_irqsave(mEp->lock, flags);
2274
2275 if (mReq->ptr)
2276 dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma);
2277 kfree(mReq);
2278
2279 dbg_event(_usb_addr(mEp), "FREE", 0);
2280
2281 spin_unlock_irqrestore(mEp->lock, flags);
2282}
2283
2284/**
2285 * ep_queue: queues (submits) an I/O request to an endpoint
2286 *
2287 * Check usb_ep_queue()* at usb_gadget.h" for details
2288 */
2289static int ep_queue(struct usb_ep *ep, struct usb_request *req,
2290 gfp_t __maybe_unused gfp_flags)
2291{
2292 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2293 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2294 int retval = 0;
2295 unsigned long flags;
2296
2297 trace("%p, %p, %X", ep, req, gfp_flags);
2298
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002299 if (ep == NULL || req == NULL || mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002300 return -EINVAL;
2301
2302 spin_lock_irqsave(mEp->lock, flags);
2303
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302304 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
2305 if (req->length)
2306 mEp = (_udc->ep0_dir == RX) ?
Alexander Shishkind36ade62012-05-04 16:47:15 +03002307 _udc->ep0out : _udc->ep0in;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302308 if (!list_empty(&mEp->qh.queue)) {
2309 _ep_nuke(mEp);
2310 retval = -EOVERFLOW;
2311 warn("endpoint ctrl %X nuked", _usb_addr(mEp));
2312 }
David Lopoaa69a802008-11-17 14:14:51 -08002313 }
2314
2315 /* first nuke then test link, e.g. previous status has not sent */
2316 if (!list_empty(&mReq->queue)) {
2317 retval = -EBUSY;
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002318 pr_err("request already in queue\n");
David Lopoaa69a802008-11-17 14:14:51 -08002319 goto done;
2320 }
2321
Alexander Shishkin1155a7b2012-05-08 23:28:57 +03002322 if (req->length > 4 * CI13XXX_PAGE_SIZE) {
2323 req->length = 4 * CI13XXX_PAGE_SIZE;
David Lopoaa69a802008-11-17 14:14:51 -08002324 retval = -EMSGSIZE;
2325 warn("request length truncated");
2326 }
2327
2328 dbg_queue(_usb_addr(mEp), req, retval);
2329
2330 /* push request */
2331 mReq->req.status = -EINPROGRESS;
2332 mReq->req.actual = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002333
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302334 retval = _hardware_enqueue(mEp, mReq);
Artem Leonenkod9bb9c12010-12-14 23:45:50 -08002335
2336 if (retval == -EALREADY) {
David Lopoaa69a802008-11-17 14:14:51 -08002337 dbg_event(_usb_addr(mEp), "QUEUE", retval);
2338 retval = 0;
2339 }
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302340 if (!retval)
2341 list_add_tail(&mReq->queue, &mEp->qh.queue);
David Lopoaa69a802008-11-17 14:14:51 -08002342
2343 done:
2344 spin_unlock_irqrestore(mEp->lock, flags);
2345 return retval;
2346}
2347
2348/**
2349 * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint
2350 *
2351 * Check usb_ep_dequeue() at "usb_gadget.h" for details
2352 */
2353static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
2354{
2355 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2356 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2357 unsigned long flags;
2358
2359 trace("%p, %p", ep, req);
2360
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302361 if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002362 mEp->ep.desc == NULL || list_empty(&mReq->queue) ||
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302363 list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002364 return -EINVAL;
2365
2366 spin_lock_irqsave(mEp->lock, flags);
2367
2368 dbg_event(_usb_addr(mEp), "DEQUEUE", 0);
2369
Alexander Shishkind3595d12012-05-08 23:28:58 +03002370 hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002371
2372 /* pop request */
2373 list_del_init(&mReq->queue);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302374 if (mReq->map) {
2375 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
2376 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02002377 mReq->req.dma = DMA_ADDR_INVALID;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302378 mReq->map = 0;
2379 }
David Lopoaa69a802008-11-17 14:14:51 -08002380 req->status = -ECONNRESET;
2381
Artem Leonenko7c25a822010-12-14 23:46:55 -08002382 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08002383 spin_unlock(mEp->lock);
2384 mReq->req.complete(&mEp->ep, &mReq->req);
2385 spin_lock(mEp->lock);
2386 }
2387
2388 spin_unlock_irqrestore(mEp->lock, flags);
2389 return 0;
2390}
2391
2392/**
2393 * ep_set_halt: sets the endpoint halt feature
2394 *
2395 * Check usb_ep_set_halt() at "usb_gadget.h" for details
2396 */
2397static int ep_set_halt(struct usb_ep *ep, int value)
2398{
2399 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2400 int direction, retval = 0;
2401 unsigned long flags;
2402
2403 trace("%p, %i", ep, value);
2404
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002405 if (ep == NULL || mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002406 return -EINVAL;
2407
2408 spin_lock_irqsave(mEp->lock, flags);
2409
2410#ifndef STALL_IN
2411 /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
2412 if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302413 !list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08002414 spin_unlock_irqrestore(mEp->lock, flags);
2415 return -EAGAIN;
2416 }
2417#endif
2418
2419 direction = mEp->dir;
2420 do {
2421 dbg_event(_usb_addr(mEp), "HALT", value);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002422 retval |= hw_ep_set_halt(mEp->udc, mEp->num, mEp->dir, value);
David Lopoaa69a802008-11-17 14:14:51 -08002423
2424 if (!value)
2425 mEp->wedge = 0;
2426
2427 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2428 mEp->dir = (mEp->dir == TX) ? RX : TX;
2429
2430 } while (mEp->dir != direction);
2431
2432 spin_unlock_irqrestore(mEp->lock, flags);
2433 return retval;
2434}
2435
2436/**
2437 * ep_set_wedge: sets the halt feature and ignores clear requests
2438 *
2439 * Check usb_ep_set_wedge() at "usb_gadget.h" for details
2440 */
2441static int ep_set_wedge(struct usb_ep *ep)
2442{
2443 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2444 unsigned long flags;
2445
2446 trace("%p", ep);
2447
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002448 if (ep == NULL || mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002449 return -EINVAL;
2450
2451 spin_lock_irqsave(mEp->lock, flags);
2452
2453 dbg_event(_usb_addr(mEp), "WEDGE", 0);
2454 mEp->wedge = 1;
2455
2456 spin_unlock_irqrestore(mEp->lock, flags);
2457
2458 return usb_ep_set_halt(ep);
2459}
2460
2461/**
2462 * ep_fifo_flush: flushes contents of a fifo
2463 *
2464 * Check usb_ep_fifo_flush() at "usb_gadget.h" for details
2465 */
2466static void ep_fifo_flush(struct usb_ep *ep)
2467{
2468 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2469 unsigned long flags;
2470
2471 trace("%p", ep);
2472
2473 if (ep == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002474 pr_err("%02X: -EINVAL\n", _usb_addr(mEp));
David Lopoaa69a802008-11-17 14:14:51 -08002475 return;
2476 }
2477
2478 spin_lock_irqsave(mEp->lock, flags);
2479
2480 dbg_event(_usb_addr(mEp), "FFLUSH", 0);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002481 hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002482
2483 spin_unlock_irqrestore(mEp->lock, flags);
2484}
2485
2486/**
2487 * Endpoint-specific part of the API to the USB controller hardware
2488 * Check "usb_gadget.h" for details
2489 */
2490static const struct usb_ep_ops usb_ep_ops = {
2491 .enable = ep_enable,
2492 .disable = ep_disable,
2493 .alloc_request = ep_alloc_request,
2494 .free_request = ep_free_request,
2495 .queue = ep_queue,
2496 .dequeue = ep_dequeue,
2497 .set_halt = ep_set_halt,
2498 .set_wedge = ep_set_wedge,
2499 .fifo_flush = ep_fifo_flush,
2500};
2501
2502/******************************************************************************
2503 * GADGET block
2504 *****************************************************************************/
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302505static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
2506{
2507 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2508 unsigned long flags;
2509 int gadget_ready = 0;
2510
2511 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS))
2512 return -EOPNOTSUPP;
2513
Alexander Shishkind3595d12012-05-08 23:28:58 +03002514 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302515 udc->vbus_active = is_active;
2516 if (udc->driver)
2517 gadget_ready = 1;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002518 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302519
2520 if (gadget_ready) {
2521 if (is_active) {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302522 pm_runtime_get_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302523 hw_device_reset(udc);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002524 hw_device_state(udc, udc->ep0out->qh.dma);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302525 } else {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002526 hw_device_state(udc, 0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302527 if (udc->udc_driver->notify_event)
2528 udc->udc_driver->notify_event(udc,
2529 CI13XXX_CONTROLLER_STOPPED_EVENT);
2530 _gadget_stop_activity(&udc->gadget);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302531 pm_runtime_put_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302532 }
2533 }
2534
2535 return 0;
2536}
2537
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302538static int ci13xxx_wakeup(struct usb_gadget *_gadget)
2539{
2540 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2541 unsigned long flags;
2542 int ret = 0;
2543
2544 trace();
2545
Alexander Shishkind3595d12012-05-08 23:28:58 +03002546 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302547 if (!udc->remote_wakeup) {
2548 ret = -EOPNOTSUPP;
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002549 trace("remote wakeup feature is not enabled\n");
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302550 goto out;
2551 }
Alexander Shishkin262c1632012-05-08 23:28:59 +03002552 if (!hw_read(udc, OP_PORTSC, PORTSC_SUSP)) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302553 ret = -EINVAL;
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002554 trace("port is not suspended\n");
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302555 goto out;
2556 }
Alexander Shishkin262c1632012-05-08 23:28:59 +03002557 hw_write(udc, OP_PORTSC, PORTSC_FPR, PORTSC_FPR);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302558out:
Alexander Shishkind3595d12012-05-08 23:28:58 +03002559 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302560 return ret;
2561}
2562
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302563static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
2564{
2565 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2566
2567 if (udc->transceiver)
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002568 return usb_phy_set_power(udc->transceiver, mA);
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302569 return -ENOTSUPP;
2570}
2571
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002572static int ci13xxx_start(struct usb_gadget_driver *driver,
2573 int (*bind)(struct usb_gadget *));
2574static int ci13xxx_stop(struct usb_gadget_driver *driver);
David Lopoaa69a802008-11-17 14:14:51 -08002575/**
2576 * Device operations part of the API to the USB controller hardware,
2577 * which don't involve endpoints (or i/o)
2578 * Check "usb_gadget.h" for details
2579 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302580static const struct usb_gadget_ops usb_gadget_ops = {
2581 .vbus_session = ci13xxx_vbus_session,
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302582 .wakeup = ci13xxx_wakeup,
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302583 .vbus_draw = ci13xxx_vbus_draw,
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002584 .start = ci13xxx_start,
2585 .stop = ci13xxx_stop,
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302586};
David Lopoaa69a802008-11-17 14:14:51 -08002587
2588/**
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002589 * ci13xxx_start: register a gadget driver
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002590 * @driver: the driver being registered
2591 * @bind: the driver's bind callback
David Lopoaa69a802008-11-17 14:14:51 -08002592 *
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002593 * Check ci13xxx_start() at <linux/usb/gadget.h> for details.
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002594 * Interrupts are enabled here.
David Lopoaa69a802008-11-17 14:14:51 -08002595 */
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002596static int ci13xxx_start(struct usb_gadget_driver *driver,
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002597 int (*bind)(struct usb_gadget *))
David Lopoaa69a802008-11-17 14:14:51 -08002598{
2599 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302600 unsigned long flags;
2601 int i, j;
David Lopoaa69a802008-11-17 14:14:51 -08002602 int retval = -ENOMEM;
2603
2604 trace("%p", driver);
2605
2606 if (driver == NULL ||
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002607 bind == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002608 driver->setup == NULL ||
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002609 driver->disconnect == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002610 return -EINVAL;
2611 else if (udc == NULL)
2612 return -ENODEV;
2613 else if (udc->driver != NULL)
2614 return -EBUSY;
2615
2616 /* alloc resources */
2617 udc->qh_pool = dma_pool_create("ci13xxx_qh", &udc->gadget.dev,
2618 sizeof(struct ci13xxx_qh),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002619 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002620 if (udc->qh_pool == NULL)
2621 return -ENOMEM;
2622
2623 udc->td_pool = dma_pool_create("ci13xxx_td", &udc->gadget.dev,
2624 sizeof(struct ci13xxx_td),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002625 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002626 if (udc->td_pool == NULL) {
2627 dma_pool_destroy(udc->qh_pool);
2628 udc->qh_pool = NULL;
2629 return -ENOMEM;
2630 }
2631
Alexander Shishkind3595d12012-05-08 23:28:58 +03002632 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002633
Alexander Shishkind3595d12012-05-08 23:28:58 +03002634 info("hw_ep_max = %d", udc->hw_ep_max);
David Lopoaa69a802008-11-17 14:14:51 -08002635
David Lopoaa69a802008-11-17 14:14:51 -08002636 udc->gadget.dev.driver = NULL;
2637
2638 retval = 0;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002639 for (i = 0; i < udc->hw_ep_max/2; i++) {
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302640 for (j = RX; j <= TX; j++) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002641 int k = i + j * udc->hw_ep_max/2;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302642 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k];
David Lopoaa69a802008-11-17 14:14:51 -08002643
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302644 scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i,
2645 (j == TX) ? "in" : "out");
David Lopoaa69a802008-11-17 14:14:51 -08002646
Alexander Shishkind3595d12012-05-08 23:28:58 +03002647 mEp->udc = udc;
2648 mEp->lock = &udc->lock;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302649 mEp->device = &udc->gadget.dev;
2650 mEp->td_pool = udc->td_pool;
David Lopoaa69a802008-11-17 14:14:51 -08002651
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302652 mEp->ep.name = mEp->name;
2653 mEp->ep.ops = &usb_ep_ops;
2654 mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
David Lopoaa69a802008-11-17 14:14:51 -08002655
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302656 INIT_LIST_HEAD(&mEp->qh.queue);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002657 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302658 mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL,
2659 &mEp->qh.dma);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002660 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302661 if (mEp->qh.ptr == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002662 retval = -ENOMEM;
2663 else
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302664 memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr));
2665
Alexander Shishkind36ade62012-05-04 16:47:15 +03002666 /*
2667 * set up shorthands for ep0 out and in endpoints,
2668 * don't add to gadget's ep_list
2669 */
2670 if (i == 0) {
2671 if (j == RX)
2672 udc->ep0out = mEp;
2673 else
2674 udc->ep0in = mEp;
2675
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302676 continue;
Alexander Shishkind36ade62012-05-04 16:47:15 +03002677 }
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302678
David Lopoaa69a802008-11-17 14:14:51 -08002679 list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302680 }
David Lopoaa69a802008-11-17 14:14:51 -08002681 }
2682 if (retval)
2683 goto done;
Alexander Shishkind36ade62012-05-04 16:47:15 +03002684
Alexander Shishkind3595d12012-05-08 23:28:58 +03002685 spin_unlock_irqrestore(&udc->lock, flags);
Alexander Shishkind36ade62012-05-04 16:47:15 +03002686 udc->ep0out->ep.desc = &ctrl_endpt_out_desc;
2687 retval = usb_ep_enable(&udc->ep0out->ep);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302688 if (retval)
2689 return retval;
Felipe Balbi877c1f52011-06-29 16:41:57 +03002690
Alexander Shishkind36ade62012-05-04 16:47:15 +03002691 udc->ep0in->ep.desc = &ctrl_endpt_in_desc;
2692 retval = usb_ep_enable(&udc->ep0in->ep);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302693 if (retval)
2694 return retval;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002695 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002696
Alexander Shishkind36ade62012-05-04 16:47:15 +03002697 udc->gadget.ep0 = &udc->ep0in->ep;
David Lopoaa69a802008-11-17 14:14:51 -08002698 /* bind gadget */
2699 driver->driver.bus = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002700 udc->gadget.dev.driver = &driver->driver;
2701
Alexander Shishkind3595d12012-05-08 23:28:58 +03002702 spin_unlock_irqrestore(&udc->lock, flags);
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002703 retval = bind(&udc->gadget); /* MAY SLEEP */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002704 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002705
2706 if (retval) {
David Lopoaa69a802008-11-17 14:14:51 -08002707 udc->gadget.dev.driver = NULL;
2708 goto done;
2709 }
2710
Pavankumar Kondeti49d3df52011-01-11 09:19:21 +05302711 udc->driver = driver;
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302712 pm_runtime_get_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302713 if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) {
2714 if (udc->vbus_active) {
2715 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED)
2716 hw_device_reset(udc);
2717 } else {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302718 pm_runtime_put_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302719 goto done;
2720 }
2721 }
2722
Alexander Shishkind3595d12012-05-08 23:28:58 +03002723 retval = hw_device_state(udc, udc->ep0out->qh.dma);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302724 if (retval)
2725 pm_runtime_put_sync(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002726
2727 done:
Alexander Shishkind3595d12012-05-08 23:28:58 +03002728 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002729 return retval;
2730}
David Lopoaa69a802008-11-17 14:14:51 -08002731
2732/**
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002733 * ci13xxx_stop: unregister a gadget driver
David Lopoaa69a802008-11-17 14:14:51 -08002734 *
2735 * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
2736 */
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002737static int ci13xxx_stop(struct usb_gadget_driver *driver)
David Lopoaa69a802008-11-17 14:14:51 -08002738{
2739 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302740 unsigned long i, flags;
David Lopoaa69a802008-11-17 14:14:51 -08002741
2742 trace("%p", driver);
2743
2744 if (driver == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002745 driver->unbind == NULL ||
2746 driver->setup == NULL ||
2747 driver->disconnect == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002748 driver != udc->driver)
2749 return -EINVAL;
2750
Alexander Shishkind3595d12012-05-08 23:28:58 +03002751 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002752
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302753 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) ||
2754 udc->vbus_active) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002755 hw_device_state(udc, 0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302756 if (udc->udc_driver->notify_event)
2757 udc->udc_driver->notify_event(udc,
2758 CI13XXX_CONTROLLER_STOPPED_EVENT);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002759 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302760 _gadget_stop_activity(&udc->gadget);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002761 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302762 pm_runtime_put(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302763 }
David Lopoaa69a802008-11-17 14:14:51 -08002764
2765 /* unbind gadget */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002766 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302767 driver->unbind(&udc->gadget); /* MAY SLEEP */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002768 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002769
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302770 udc->gadget.dev.driver = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002771
2772 /* free resources */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002773 for (i = 0; i < udc->hw_ep_max; i++) {
David Lopoaa69a802008-11-17 14:14:51 -08002774 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
2775
Alexander Shishkinefa015b2012-05-04 16:47:14 +03002776 if (mEp->num)
David Lopoaa69a802008-11-17 14:14:51 -08002777 list_del_init(&mEp->ep.ep_list);
2778
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302779 if (mEp->qh.ptr != NULL)
2780 dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08002781 }
2782
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302783 udc->gadget.ep0 = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002784 udc->driver = NULL;
2785
Alexander Shishkind3595d12012-05-08 23:28:58 +03002786 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002787
2788 if (udc->td_pool != NULL) {
2789 dma_pool_destroy(udc->td_pool);
2790 udc->td_pool = NULL;
2791 }
2792 if (udc->qh_pool != NULL) {
2793 dma_pool_destroy(udc->qh_pool);
2794 udc->qh_pool = NULL;
2795 }
2796
2797 return 0;
2798}
David Lopoaa69a802008-11-17 14:14:51 -08002799
2800/******************************************************************************
2801 * BUS block
2802 *****************************************************************************/
2803/**
2804 * udc_irq: global interrupt handler
2805 *
2806 * This function returns IRQ_HANDLED if the IRQ has been handled
2807 * It locks access to registers
2808 */
2809static irqreturn_t udc_irq(void)
2810{
2811 struct ci13xxx *udc = _udc;
2812 irqreturn_t retval;
2813 u32 intr;
2814
2815 trace();
2816
2817 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002818 pr_err("ENODEV\n");
David Lopoaa69a802008-11-17 14:14:51 -08002819 return IRQ_HANDLED;
2820 }
2821
Alexander Shishkind3595d12012-05-08 23:28:58 +03002822 spin_lock(&udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302823
2824 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) {
Alexander Shishkin262c1632012-05-08 23:28:59 +03002825 if (hw_read(udc, OP_USBMODE, USBMODE_CM) !=
2826 USBMODE_CM_DEVICE) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002827 spin_unlock(&udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302828 return IRQ_NONE;
2829 }
2830 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03002831 intr = hw_test_and_clear_intr_active(udc);
David Lopoaa69a802008-11-17 14:14:51 -08002832 if (intr) {
2833 isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr;
2834 isr_statistics.hndl.idx &= ISR_MASK;
2835 isr_statistics.hndl.cnt++;
2836
2837 /* order defines priority - do NOT change it */
2838 if (USBi_URI & intr) {
2839 isr_statistics.uri++;
2840 isr_reset_handler(udc);
2841 }
2842 if (USBi_PCI & intr) {
2843 isr_statistics.pci++;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002844 udc->gadget.speed = hw_port_is_high_speed(udc) ?
David Lopoaa69a802008-11-17 14:14:51 -08002845 USB_SPEED_HIGH : USB_SPEED_FULL;
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002846 if (udc->suspended && udc->driver->resume) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002847 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302848 udc->driver->resume(&udc->gadget);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002849 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302850 udc->suspended = 0;
2851 }
David Lopoaa69a802008-11-17 14:14:51 -08002852 }
2853 if (USBi_UEI & intr)
2854 isr_statistics.uei++;
2855 if (USBi_UI & intr) {
2856 isr_statistics.ui++;
2857 isr_tr_complete_handler(udc);
2858 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302859 if (USBi_SLI & intr) {
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002860 if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
2861 udc->driver->suspend) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302862 udc->suspended = 1;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002863 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302864 udc->driver->suspend(&udc->gadget);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002865 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302866 }
David Lopoaa69a802008-11-17 14:14:51 -08002867 isr_statistics.sli++;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302868 }
David Lopoaa69a802008-11-17 14:14:51 -08002869 retval = IRQ_HANDLED;
2870 } else {
2871 isr_statistics.none++;
2872 retval = IRQ_NONE;
2873 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03002874 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002875
2876 return retval;
2877}
2878
2879/**
2880 * udc_release: driver release function
2881 * @dev: device
2882 *
2883 * Currently does nothing
2884 */
2885static void udc_release(struct device *dev)
2886{
2887 trace("%p", dev);
2888
2889 if (dev == NULL)
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002890 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08002891}
2892
2893/**
2894 * udc_probe: parent probe must call this to initialize UDC
2895 * @dev: parent device
2896 * @regs: registers base address
2897 * @name: driver name
2898 *
2899 * This function returns an error code
2900 * No interrupts active, the IRQ has not been requested yet
2901 * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask
2902 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302903static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
Alexander Shishkinf9df8392012-05-04 16:47:16 +03002904 void __iomem *regs, uintptr_t capoffset)
David Lopoaa69a802008-11-17 14:14:51 -08002905{
2906 struct ci13xxx *udc;
2907 int retval = 0;
2908
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002909 trace("%p, %p, %p", dev, regs, driver->name);
David Lopoaa69a802008-11-17 14:14:51 -08002910
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302911 if (dev == NULL || regs == NULL || driver == NULL ||
2912 driver->name == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002913 return -EINVAL;
2914
2915 udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL);
2916 if (udc == NULL)
2917 return -ENOMEM;
2918
Alexander Shishkind3595d12012-05-08 23:28:58 +03002919 spin_lock_init(&udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302920 udc->regs = regs;
2921 udc->udc_driver = driver;
David Lopoaa69a802008-11-17 14:14:51 -08002922
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302923 udc->gadget.ops = &usb_gadget_ops;
David Lopoaa69a802008-11-17 14:14:51 -08002924 udc->gadget.speed = USB_SPEED_UNKNOWN;
Michal Nazarewiczd327ab52011-11-19 18:27:37 +01002925 udc->gadget.max_speed = USB_SPEED_HIGH;
David Lopoaa69a802008-11-17 14:14:51 -08002926 udc->gadget.is_otg = 0;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302927 udc->gadget.name = driver->name;
David Lopoaa69a802008-11-17 14:14:51 -08002928
2929 INIT_LIST_HEAD(&udc->gadget.ep_list);
2930 udc->gadget.ep0 = NULL;
2931
Kay Sievers5df585242009-03-24 16:38:23 -07002932 dev_set_name(&udc->gadget.dev, "gadget");
David Lopoaa69a802008-11-17 14:14:51 -08002933 udc->gadget.dev.dma_mask = dev->dma_mask;
Pavankumar Kondeti61948ee2010-12-07 17:54:01 +05302934 udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask;
David Lopoaa69a802008-11-17 14:14:51 -08002935 udc->gadget.dev.parent = dev;
2936 udc->gadget.dev.release = udc_release;
2937
Alexander Shishkind3595d12012-05-08 23:28:58 +03002938 retval = hw_device_init(udc, regs, capoffset);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302939 if (retval < 0)
2940 goto free_udc;
2941
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002942 udc->transceiver = usb_get_transceiver();
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302943
2944 if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
2945 if (udc->transceiver == NULL) {
2946 retval = -ENODEV;
2947 goto free_udc;
2948 }
2949 }
2950
2951 if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) {
2952 retval = hw_device_reset(udc);
2953 if (retval)
2954 goto put_transceiver;
2955 }
2956
David Lopoaa69a802008-11-17 14:14:51 -08002957 retval = device_register(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302958 if (retval) {
2959 put_device(&udc->gadget.dev);
2960 goto put_transceiver;
2961 }
David Lopoaa69a802008-11-17 14:14:51 -08002962
2963#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2964 retval = dbg_create_files(&udc->gadget.dev);
2965#endif
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302966 if (retval)
2967 goto unreg_device;
2968
2969 if (udc->transceiver) {
Heikki Krogerus6e13c652012-02-13 13:24:20 +02002970 retval = otg_set_peripheral(udc->transceiver->otg,
2971 &udc->gadget);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302972 if (retval)
2973 goto remove_dbg;
David Lopoaa69a802008-11-17 14:14:51 -08002974 }
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002975
2976 retval = usb_add_gadget_udc(dev, &udc->gadget);
2977 if (retval)
2978 goto remove_trans;
2979
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302980 pm_runtime_no_callbacks(&udc->gadget.dev);
2981 pm_runtime_enable(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002982
2983 _udc = udc;
2984 return retval;
2985
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002986remove_trans:
2987 if (udc->transceiver) {
Heikki Krogerus6e13c652012-02-13 13:24:20 +02002988 otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002989 usb_put_transceiver(udc->transceiver);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002990 }
2991
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002992 dev_err(dev, "error = %i\n", retval);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302993remove_dbg:
2994#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2995 dbg_remove_files(&udc->gadget.dev);
2996#endif
2997unreg_device:
2998 device_unregister(&udc->gadget.dev);
2999put_transceiver:
3000 if (udc->transceiver)
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02003001 usb_put_transceiver(udc->transceiver);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303002free_udc:
David Lopoaa69a802008-11-17 14:14:51 -08003003 kfree(udc);
3004 _udc = NULL;
3005 return retval;
3006}
3007
3008/**
3009 * udc_remove: parent remove must call this to remove UDC
3010 *
3011 * No interrupts active, the IRQ has been released
3012 */
3013static void udc_remove(void)
3014{
3015 struct ci13xxx *udc = _udc;
3016
3017 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07003018 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08003019 return;
3020 }
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03003021 usb_del_gadget_udc(&udc->gadget);
David Lopoaa69a802008-11-17 14:14:51 -08003022
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303023 if (udc->transceiver) {
Heikki Krogerus6e13c652012-02-13 13:24:20 +02003024 otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02003025 usb_put_transceiver(udc->transceiver);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303026 }
David Lopoaa69a802008-11-17 14:14:51 -08003027#ifdef CONFIG_USB_GADGET_DEBUG_FILES
3028 dbg_remove_files(&udc->gadget.dev);
3029#endif
3030 device_unregister(&udc->gadget.dev);
3031
Alexander Shishkin262c1632012-05-08 23:28:59 +03003032 kfree(udc->hw_bank.regmap);
David Lopoaa69a802008-11-17 14:14:51 -08003033 kfree(udc);
3034 _udc = NULL;
3035}