blob: 009a3cd5895dba890f68cafce206dbfd660cfe07 [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>
Alexander Shishkin62bb84e2012-05-08 23:29:01 +030058#include <linux/platform_device.h>
59#include <linux/module.h>
David Lopoaa69a802008-11-17 14:14:51 -080060#include <linux/interrupt.h>
David Lopoaa69a802008-11-17 14:14:51 -080061#include <linux/io.h>
62#include <linux/irq.h>
63#include <linux/kernel.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090064#include <linux/slab.h>
Pavankumar Kondetic0360192010-12-07 17:54:04 +053065#include <linux/pm_runtime.h>
David Lopoaa69a802008-11-17 14:14:51 -080066#include <linux/usb/ch9.h>
67#include <linux/usb/gadget.h>
Pavankumar Kondetif01ef572010-12-07 17:54:02 +053068#include <linux/usb/otg.h>
David Lopoaa69a802008-11-17 14:14:51 -080069
70#include "ci13xxx_udc.h"
71
David Lopoaa69a802008-11-17 14:14:51 -080072/******************************************************************************
73 * DEFINE
74 *****************************************************************************/
Michael Grzeschik954aad82011-10-10 18:38:06 +020075
76#define DMA_ADDR_INVALID (~(dma_addr_t)0)
77
David Lopoaa69a802008-11-17 14:14:51 -080078/* control endpoint description */
79static const struct usb_endpoint_descriptor
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053080ctrl_endpt_out_desc = {
David Lopoaa69a802008-11-17 14:14:51 -080081 .bLength = USB_DT_ENDPOINT_SIZE,
82 .bDescriptorType = USB_DT_ENDPOINT,
83
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053084 .bEndpointAddress = USB_DIR_OUT,
85 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
86 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
87};
88
89static const struct usb_endpoint_descriptor
90ctrl_endpt_in_desc = {
91 .bLength = USB_DT_ENDPOINT_SIZE,
92 .bDescriptorType = USB_DT_ENDPOINT,
93
94 .bEndpointAddress = USB_DIR_IN,
David Lopoaa69a802008-11-17 14:14:51 -080095 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
96 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
97};
98
99/* UDC descriptor */
100static struct ci13xxx *_udc;
101
102/* Interrupt statistics */
103#define ISR_MASK 0x1F
104static struct {
105 u32 test;
106 u32 ui;
107 u32 uei;
108 u32 pci;
109 u32 uri;
110 u32 sli;
111 u32 none;
112 struct {
113 u32 cnt;
114 u32 buf[ISR_MASK+1];
115 u32 idx;
116 } hndl;
117} isr_statistics;
118
119/**
120 * ffs_nr: find first (least significant) bit set
121 * @x: the word to search
122 *
123 * This function returns bit number (instead of position)
124 */
125static int ffs_nr(u32 x)
126{
127 int n = ffs(x);
128
129 return n ? n-1 : 32;
130}
131
132/******************************************************************************
133 * HW block
134 *****************************************************************************/
David Lopoaa69a802008-11-17 14:14:51 -0800135
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530136/* MSM specific */
137#define ABS_AHBBURST (0x0090UL)
138#define ABS_AHBMODE (0x0098UL)
David Lopoaa69a802008-11-17 14:14:51 -0800139/* UDC register map */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300140static uintptr_t ci_regs_nolpm[] = {
141 [CAP_CAPLENGTH] = 0x000UL,
142 [CAP_HCCPARAMS] = 0x008UL,
143 [CAP_DCCPARAMS] = 0x024UL,
144 [CAP_TESTMODE] = 0x038UL,
145 [OP_USBCMD] = 0x000UL,
146 [OP_USBSTS] = 0x004UL,
147 [OP_USBINTR] = 0x008UL,
148 [OP_DEVICEADDR] = 0x014UL,
149 [OP_ENDPTLISTADDR] = 0x018UL,
150 [OP_PORTSC] = 0x044UL,
151 [OP_DEVLC] = 0x084UL,
152 [OP_USBMODE] = 0x068UL,
153 [OP_ENDPTSETUPSTAT] = 0x06CUL,
154 [OP_ENDPTPRIME] = 0x070UL,
155 [OP_ENDPTFLUSH] = 0x074UL,
156 [OP_ENDPTSTAT] = 0x078UL,
157 [OP_ENDPTCOMPLETE] = 0x07CUL,
158 [OP_ENDPTCTRL] = 0x080UL,
159};
160
161static uintptr_t ci_regs_lpm[] = {
162 [CAP_CAPLENGTH] = 0x000UL,
163 [CAP_HCCPARAMS] = 0x008UL,
164 [CAP_DCCPARAMS] = 0x024UL,
165 [CAP_TESTMODE] = 0x0FCUL,
166 [OP_USBCMD] = 0x000UL,
167 [OP_USBSTS] = 0x004UL,
168 [OP_USBINTR] = 0x008UL,
169 [OP_DEVICEADDR] = 0x014UL,
170 [OP_ENDPTLISTADDR] = 0x018UL,
171 [OP_PORTSC] = 0x044UL,
172 [OP_DEVLC] = 0x084UL,
173 [OP_USBMODE] = 0x0C8UL,
174 [OP_ENDPTSETUPSTAT] = 0x0D8UL,
175 [OP_ENDPTPRIME] = 0x0DCUL,
176 [OP_ENDPTFLUSH] = 0x0E0UL,
177 [OP_ENDPTSTAT] = 0x0E4UL,
178 [OP_ENDPTCOMPLETE] = 0x0E8UL,
179 [OP_ENDPTCTRL] = 0x0ECUL,
180};
181
182static int hw_alloc_regmap(struct ci13xxx *udc, bool is_lpm)
183{
184 int i;
185
186 kfree(udc->hw_bank.regmap);
187
188 udc->hw_bank.regmap = kzalloc((OP_LAST + 1) * sizeof(void *),
189 GFP_KERNEL);
190 if (!udc->hw_bank.regmap)
191 return -ENOMEM;
192
193 for (i = 0; i < OP_ENDPTCTRL; i++)
194 udc->hw_bank.regmap[i] =
195 (i <= CAP_LAST ? udc->hw_bank.cap : udc->hw_bank.op) +
196 (is_lpm ? ci_regs_lpm[i] : ci_regs_nolpm[i]);
197
198 for (; i <= OP_LAST; i++)
199 udc->hw_bank.regmap[i] = udc->hw_bank.op +
200 4 * (i - OP_ENDPTCTRL) +
201 (is_lpm
202 ? ci_regs_lpm[OP_ENDPTCTRL]
203 : ci_regs_nolpm[OP_ENDPTCTRL]);
204
205 return 0;
206}
David Lopoaa69a802008-11-17 14:14:51 -0800207
208/**
209 * hw_ep_bit: calculates the bit number
210 * @num: endpoint number
211 * @dir: endpoint direction
212 *
213 * This function returns bit number
214 */
215static inline int hw_ep_bit(int num, int dir)
216{
217 return num + (dir ? 16 : 0);
218}
219
Alexander Shishkind3595d12012-05-08 23:28:58 +0300220static int ep_to_bit(struct ci13xxx *udc, int n)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200221{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300222 int fill = 16 - udc->hw_ep_max / 2;
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200223
Alexander Shishkind3595d12012-05-08 23:28:58 +0300224 if (n >= udc->hw_ep_max / 2)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200225 n += fill;
226
227 return n;
228}
229
David Lopoaa69a802008-11-17 14:14:51 -0800230/**
Alexander Shishkin262c1632012-05-08 23:28:59 +0300231 * hw_read: reads from a hw register
232 * @reg: register index
David Lopoaa69a802008-11-17 14:14:51 -0800233 * @mask: bitfield mask
234 *
Alexander Shishkin262c1632012-05-08 23:28:59 +0300235 * This function returns register contents
David Lopoaa69a802008-11-17 14:14:51 -0800236 */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300237static u32 hw_read(struct ci13xxx *udc, enum ci13xxx_regs reg, u32 mask)
David Lopoaa69a802008-11-17 14:14:51 -0800238{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300239 return ioread32(udc->hw_bank.regmap[reg]) & mask;
David Lopoaa69a802008-11-17 14:14:51 -0800240}
241
242/**
Alexander Shishkin262c1632012-05-08 23:28:59 +0300243 * hw_write: writes to a hw register
244 * @reg: register index
David Lopoaa69a802008-11-17 14:14:51 -0800245 * @mask: bitfield mask
Alexander Shishkin262c1632012-05-08 23:28:59 +0300246 * @data: new value
David Lopoaa69a802008-11-17 14:14:51 -0800247 */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300248static void hw_write(struct ci13xxx *udc, enum ci13xxx_regs reg, u32 mask,
249 u32 data)
David Lopoaa69a802008-11-17 14:14:51 -0800250{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300251 if (~mask)
252 data = (ioread32(udc->hw_bank.regmap[reg]) & ~mask)
253 | (data & mask);
254
255 iowrite32(data, udc->hw_bank.regmap[reg]);
David Lopoaa69a802008-11-17 14:14:51 -0800256}
257
258/**
Alexander Shishkin262c1632012-05-08 23:28:59 +0300259 * hw_test_and_clear: tests & clears a hw register
260 * @reg: register index
David Lopoaa69a802008-11-17 14:14:51 -0800261 * @mask: bitfield mask
262 *
Alexander Shishkin262c1632012-05-08 23:28:59 +0300263 * This function returns register contents
David Lopoaa69a802008-11-17 14:14:51 -0800264 */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300265static u32 hw_test_and_clear(struct ci13xxx *udc, enum ci13xxx_regs reg,
266 u32 mask)
David Lopoaa69a802008-11-17 14:14:51 -0800267{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300268 u32 val = ioread32(udc->hw_bank.regmap[reg]) & mask;
David Lopoaa69a802008-11-17 14:14:51 -0800269
Alexander Shishkin262c1632012-05-08 23:28:59 +0300270 iowrite32(val, udc->hw_bank.regmap[reg]);
271 return val;
David Lopoaa69a802008-11-17 14:14:51 -0800272}
273
274/**
Alexander Shishkin262c1632012-05-08 23:28:59 +0300275 * hw_test_and_write: tests & writes a hw register
276 * @reg: register index
David Lopoaa69a802008-11-17 14:14:51 -0800277 * @mask: bitfield mask
Alexander Shishkin262c1632012-05-08 23:28:59 +0300278 * @data: new value
David Lopoaa69a802008-11-17 14:14:51 -0800279 *
Alexander Shishkin262c1632012-05-08 23:28:59 +0300280 * This function returns register contents
David Lopoaa69a802008-11-17 14:14:51 -0800281 */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300282static u32 hw_test_and_write(struct ci13xxx *udc, enum ci13xxx_regs reg,
283 u32 mask, u32 data)
David Lopoaa69a802008-11-17 14:14:51 -0800284{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300285 u32 val = hw_read(udc, reg, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800286
Alexander Shishkin262c1632012-05-08 23:28:59 +0300287 hw_write(udc, reg, mask, data);
288 return (val & mask) >> ffs_nr(mask);
David Lopoaa69a802008-11-17 14:14:51 -0800289}
290
Alexander Shishkind3595d12012-05-08 23:28:58 +0300291static int hw_device_init(struct ci13xxx *udc, void __iomem *base,
292 uintptr_t cap_offset)
David Lopoaa69a802008-11-17 14:14:51 -0800293{
294 u32 reg;
295
296 /* bank is a module variable */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300297 udc->hw_bank.abs = base;
David Lopoaa69a802008-11-17 14:14:51 -0800298
Alexander Shishkind3595d12012-05-08 23:28:58 +0300299 udc->hw_bank.cap = udc->hw_bank.abs;
300 udc->hw_bank.cap += cap_offset;
301 udc->hw_bank.op = udc->hw_bank.cap + ioread8(udc->hw_bank.cap);
David Lopoaa69a802008-11-17 14:14:51 -0800302
Alexander Shishkin262c1632012-05-08 23:28:59 +0300303 hw_alloc_regmap(udc, false);
304 reg = hw_read(udc, CAP_HCCPARAMS, HCCPARAMS_LEN) >>
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300305 ffs_nr(HCCPARAMS_LEN);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300306 udc->hw_bank.lpm = reg;
Alexander Shishkin262c1632012-05-08 23:28:59 +0300307 hw_alloc_regmap(udc, !!reg);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300308 udc->hw_bank.size = udc->hw_bank.op - udc->hw_bank.abs;
309 udc->hw_bank.size += OP_LAST;
310 udc->hw_bank.size /= sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -0800311
Alexander Shishkin262c1632012-05-08 23:28:59 +0300312 reg = hw_read(udc, CAP_DCCPARAMS, DCCPARAMS_DEN) >>
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300313 ffs_nr(DCCPARAMS_DEN);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300314 udc->hw_ep_max = reg * 2; /* cache hw ENDPT_MAX */
David Lopoaa69a802008-11-17 14:14:51 -0800315
Alexander Shishkind3595d12012-05-08 23:28:58 +0300316 if (udc->hw_ep_max == 0 || udc->hw_ep_max > ENDPT_MAX)
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530317 return -ENODEV;
David Lopoaa69a802008-11-17 14:14:51 -0800318
319 /* setup lock mode ? */
320
321 /* ENDPTSETUPSTAT is '0' by default */
322
323 /* HCSPARAMS.bf.ppc SHOULD BE zero for device */
324
325 return 0;
326}
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530327/**
328 * hw_device_reset: resets chip (execute without interruption)
329 * @base: register base address
330 *
331 * This function returns an error code
332 */
333static int hw_device_reset(struct ci13xxx *udc)
334{
335 /* should flush & stop before reset */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300336 hw_write(udc, OP_ENDPTFLUSH, ~0, ~0);
337 hw_write(udc, OP_USBCMD, USBCMD_RS, 0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530338
Alexander Shishkin262c1632012-05-08 23:28:59 +0300339 hw_write(udc, OP_USBCMD, USBCMD_RST, USBCMD_RST);
340 while (hw_read(udc, OP_USBCMD, USBCMD_RST))
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530341 udelay(10); /* not RTOS friendly */
342
343
344 if (udc->udc_driver->notify_event)
345 udc->udc_driver->notify_event(udc,
346 CI13XXX_CONTROLLER_RESET_EVENT);
347
Pavankumar Kondeti8c2387a2011-05-02 11:56:28 +0530348 if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
Alexander Shishkin262c1632012-05-08 23:28:59 +0300349 hw_write(udc, OP_USBMODE, USBMODE_SDIS, USBMODE_SDIS);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530350
351 /* USBMODE should be configured step by step */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300352 hw_write(udc, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
353 hw_write(udc, OP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE);
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300354 /* HW >= 2.3 */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300355 hw_write(udc, OP_USBMODE, USBMODE_SLOM, USBMODE_SLOM);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530356
Alexander Shishkin262c1632012-05-08 23:28:59 +0300357 if (hw_read(udc, OP_USBMODE, USBMODE_CM) != USBMODE_CM_DEVICE) {
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530358 pr_err("cannot enter in device mode");
Alexander Shishkind3595d12012-05-08 23:28:58 +0300359 pr_err("lpm = %i", udc->hw_bank.lpm);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530360 return -ENODEV;
361 }
362
363 return 0;
364}
David Lopoaa69a802008-11-17 14:14:51 -0800365
366/**
367 * hw_device_state: enables/disables interrupts & starts/stops device (execute
368 * without interruption)
369 * @dma: 0 => disable, !0 => enable and set dma engine
370 *
371 * This function returns an error code
372 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300373static int hw_device_state(struct ci13xxx *udc, u32 dma)
David Lopoaa69a802008-11-17 14:14:51 -0800374{
375 if (dma) {
Alexander Shishkin262c1632012-05-08 23:28:59 +0300376 hw_write(udc, OP_ENDPTLISTADDR, ~0, dma);
David Lopoaa69a802008-11-17 14:14:51 -0800377 /* interrupt, error, port change, reset, sleep/suspend */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300378 hw_write(udc, OP_USBINTR, ~0,
David Lopoaa69a802008-11-17 14:14:51 -0800379 USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
Alexander Shishkin262c1632012-05-08 23:28:59 +0300380 hw_write(udc, OP_USBCMD, USBCMD_RS, USBCMD_RS);
David Lopoaa69a802008-11-17 14:14:51 -0800381 } else {
Alexander Shishkin262c1632012-05-08 23:28:59 +0300382 hw_write(udc, OP_USBCMD, USBCMD_RS, 0);
383 hw_write(udc, OP_USBINTR, ~0, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800384 }
385 return 0;
386}
387
388/**
389 * hw_ep_flush: flush endpoint fifo (execute without interruption)
390 * @num: endpoint number
391 * @dir: endpoint direction
392 *
393 * This function returns an error code
394 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300395static int hw_ep_flush(struct ci13xxx *udc, int num, int dir)
David Lopoaa69a802008-11-17 14:14:51 -0800396{
397 int n = hw_ep_bit(num, dir);
398
399 do {
400 /* flush any pending transfer */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300401 hw_write(udc, OP_ENDPTFLUSH, BIT(n), BIT(n));
402 while (hw_read(udc, OP_ENDPTFLUSH, BIT(n)))
David Lopoaa69a802008-11-17 14:14:51 -0800403 cpu_relax();
Alexander Shishkin262c1632012-05-08 23:28:59 +0300404 } while (hw_read(udc, OP_ENDPTSTAT, BIT(n)));
David Lopoaa69a802008-11-17 14:14:51 -0800405
406 return 0;
407}
408
409/**
410 * hw_ep_disable: disables endpoint (execute without interruption)
411 * @num: endpoint number
412 * @dir: endpoint direction
413 *
414 * This function returns an error code
415 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300416static int hw_ep_disable(struct ci13xxx *udc, int num, int dir)
David Lopoaa69a802008-11-17 14:14:51 -0800417{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300418 hw_ep_flush(udc, num, dir);
Alexander Shishkin262c1632012-05-08 23:28:59 +0300419 hw_write(udc, OP_ENDPTCTRL + num,
Alexander Shishkind3595d12012-05-08 23:28:58 +0300420 dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800421 return 0;
422}
423
424/**
425 * hw_ep_enable: enables endpoint (execute without interruption)
426 * @num: endpoint number
427 * @dir: endpoint direction
428 * @type: endpoint type
429 *
430 * This function returns an error code
431 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300432static int hw_ep_enable(struct ci13xxx *udc, int num, int dir, int type)
David Lopoaa69a802008-11-17 14:14:51 -0800433{
434 u32 mask, data;
435
436 if (dir) {
437 mask = ENDPTCTRL_TXT; /* type */
438 data = type << ffs_nr(mask);
439
440 mask |= ENDPTCTRL_TXS; /* unstall */
441 mask |= ENDPTCTRL_TXR; /* reset data toggle */
442 data |= ENDPTCTRL_TXR;
443 mask |= ENDPTCTRL_TXE; /* enable */
444 data |= ENDPTCTRL_TXE;
445 } else {
446 mask = ENDPTCTRL_RXT; /* type */
447 data = type << ffs_nr(mask);
448
449 mask |= ENDPTCTRL_RXS; /* unstall */
450 mask |= ENDPTCTRL_RXR; /* reset data toggle */
451 data |= ENDPTCTRL_RXR;
452 mask |= ENDPTCTRL_RXE; /* enable */
453 data |= ENDPTCTRL_RXE;
454 }
Alexander Shishkin262c1632012-05-08 23:28:59 +0300455 hw_write(udc, OP_ENDPTCTRL + num, mask, data);
David Lopoaa69a802008-11-17 14:14:51 -0800456 return 0;
457}
458
459/**
460 * hw_ep_get_halt: return endpoint halt status
461 * @num: endpoint number
462 * @dir: endpoint direction
463 *
464 * This function returns 1 if endpoint halted
465 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300466static int hw_ep_get_halt(struct ci13xxx *udc, int num, int dir)
David Lopoaa69a802008-11-17 14:14:51 -0800467{
468 u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
469
Alexander Shishkin262c1632012-05-08 23:28:59 +0300470 return hw_read(udc, OP_ENDPTCTRL + num, mask) ? 1 : 0;
David Lopoaa69a802008-11-17 14:14:51 -0800471}
472
473/**
David Lopoaa69a802008-11-17 14:14:51 -0800474 * hw_test_and_clear_setup_status: test & clear setup status (execute without
475 * interruption)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200476 * @n: endpoint number
David Lopoaa69a802008-11-17 14:14:51 -0800477 *
478 * This function returns setup status
479 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300480static int hw_test_and_clear_setup_status(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800481{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300482 n = ep_to_bit(udc, n);
Alexander Shishkin262c1632012-05-08 23:28:59 +0300483 return hw_test_and_clear(udc, OP_ENDPTSETUPSTAT, BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800484}
485
486/**
487 * hw_ep_prime: primes endpoint (execute without interruption)
488 * @num: endpoint number
489 * @dir: endpoint direction
490 * @is_ctrl: true if control endpoint
491 *
492 * This function returns an error code
493 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300494static int hw_ep_prime(struct ci13xxx *udc, int num, int dir, int is_ctrl)
David Lopoaa69a802008-11-17 14:14:51 -0800495{
496 int n = hw_ep_bit(num, dir);
497
Alexander Shishkin262c1632012-05-08 23:28:59 +0300498 if (is_ctrl && dir == RX && hw_read(udc, OP_ENDPTSETUPSTAT, BIT(num)))
David Lopoaa69a802008-11-17 14:14:51 -0800499 return -EAGAIN;
500
Alexander Shishkin262c1632012-05-08 23:28:59 +0300501 hw_write(udc, OP_ENDPTPRIME, BIT(n), BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800502
Alexander Shishkin262c1632012-05-08 23:28:59 +0300503 while (hw_read(udc, OP_ENDPTPRIME, BIT(n)))
David Lopoaa69a802008-11-17 14:14:51 -0800504 cpu_relax();
Alexander Shishkin262c1632012-05-08 23:28:59 +0300505 if (is_ctrl && dir == RX && hw_read(udc, OP_ENDPTSETUPSTAT, BIT(num)))
David Lopoaa69a802008-11-17 14:14:51 -0800506 return -EAGAIN;
507
508 /* status shoult be tested according with manual but it doesn't work */
509 return 0;
510}
511
512/**
513 * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute
514 * without interruption)
515 * @num: endpoint number
516 * @dir: endpoint direction
517 * @value: true => stall, false => unstall
518 *
519 * This function returns an error code
520 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300521static int hw_ep_set_halt(struct ci13xxx *udc, int num, int dir, int value)
David Lopoaa69a802008-11-17 14:14:51 -0800522{
523 if (value != 0 && value != 1)
524 return -EINVAL;
525
526 do {
Alexander Shishkin262c1632012-05-08 23:28:59 +0300527 enum ci13xxx_regs reg = OP_ENDPTCTRL + num;
David Lopoaa69a802008-11-17 14:14:51 -0800528 u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
529 u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
530
531 /* data toggle - reserved for EP0 but it's in ESS */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300532 hw_write(udc, reg, mask_xs|mask_xr,
533 value ? mask_xs : mask_xr);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300534 } while (value != hw_ep_get_halt(udc, num, dir));
David Lopoaa69a802008-11-17 14:14:51 -0800535
536 return 0;
537}
538
539/**
540 * hw_intr_clear: disables interrupt & clears interrupt status (execute without
541 * interruption)
542 * @n: interrupt bit
543 *
544 * This function returns an error code
545 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300546static int hw_intr_clear(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800547{
548 if (n >= REG_BITS)
549 return -EINVAL;
550
Alexander Shishkin262c1632012-05-08 23:28:59 +0300551 hw_write(udc, OP_USBINTR, BIT(n), 0);
552 hw_write(udc, OP_USBSTS, BIT(n), BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800553 return 0;
554}
555
556/**
557 * hw_intr_force: enables interrupt & forces interrupt status (execute without
558 * interruption)
559 * @n: interrupt bit
560 *
561 * This function returns an error code
562 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300563static int hw_intr_force(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800564{
565 if (n >= REG_BITS)
566 return -EINVAL;
567
Alexander Shishkin262c1632012-05-08 23:28:59 +0300568 hw_write(udc, CAP_TESTMODE, TESTMODE_FORCE, TESTMODE_FORCE);
569 hw_write(udc, OP_USBINTR, BIT(n), BIT(n));
570 hw_write(udc, OP_USBSTS, BIT(n), BIT(n));
571 hw_write(udc, CAP_TESTMODE, TESTMODE_FORCE, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800572 return 0;
573}
574
575/**
576 * hw_is_port_high_speed: test if port is high speed
577 *
578 * This function returns true if high speed port
579 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300580static int hw_port_is_high_speed(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800581{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300582 return udc->hw_bank.lpm ? hw_read(udc, OP_DEVLC, DEVLC_PSPD) :
583 hw_read(udc, OP_PORTSC, PORTSC_HSP);
David Lopoaa69a802008-11-17 14:14:51 -0800584}
585
586/**
587 * hw_port_test_get: reads port test mode value
588 *
589 * This function returns port test mode value
590 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300591static u8 hw_port_test_get(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800592{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300593 return hw_read(udc, OP_PORTSC, PORTSC_PTC) >> ffs_nr(PORTSC_PTC);
David Lopoaa69a802008-11-17 14:14:51 -0800594}
595
596/**
597 * hw_port_test_set: writes port test mode (execute without interruption)
598 * @mode: new value
599 *
600 * This function returns an error code
601 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300602static int hw_port_test_set(struct ci13xxx *udc, u8 mode)
David Lopoaa69a802008-11-17 14:14:51 -0800603{
604 const u8 TEST_MODE_MAX = 7;
605
606 if (mode > TEST_MODE_MAX)
607 return -EINVAL;
608
Alexander Shishkin262c1632012-05-08 23:28:59 +0300609 hw_write(udc, OP_PORTSC, PORTSC_PTC, mode << ffs_nr(PORTSC_PTC));
David Lopoaa69a802008-11-17 14:14:51 -0800610 return 0;
611}
612
613/**
614 * hw_read_intr_enable: returns interrupt enable register
615 *
616 * This function returns register data
617 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300618static u32 hw_read_intr_enable(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800619{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300620 return hw_read(udc, OP_USBINTR, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800621}
622
623/**
624 * hw_read_intr_status: returns interrupt status register
625 *
626 * This function returns register data
627 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300628static u32 hw_read_intr_status(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800629{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300630 return hw_read(udc, OP_USBSTS, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800631}
632
633/**
634 * hw_register_read: reads all device registers (execute without interruption)
635 * @buf: destination buffer
636 * @size: buffer size
637 *
638 * This function returns number of registers read
639 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300640static size_t hw_register_read(struct ci13xxx *udc, u32 *buf, size_t size)
David Lopoaa69a802008-11-17 14:14:51 -0800641{
642 unsigned i;
643
Alexander Shishkind3595d12012-05-08 23:28:58 +0300644 if (size > udc->hw_bank.size)
645 size = udc->hw_bank.size;
David Lopoaa69a802008-11-17 14:14:51 -0800646
647 for (i = 0; i < size; i++)
Alexander Shishkin262c1632012-05-08 23:28:59 +0300648 buf[i] = hw_read(udc, i * sizeof(u32), ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800649
650 return size;
651}
652
653/**
654 * hw_register_write: writes to register
655 * @addr: register address
656 * @data: register value
657 *
658 * This function returns an error code
659 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300660static int hw_register_write(struct ci13xxx *udc, u16 addr, u32 data)
David Lopoaa69a802008-11-17 14:14:51 -0800661{
662 /* align */
663 addr /= sizeof(u32);
664
Alexander Shishkind3595d12012-05-08 23:28:58 +0300665 if (addr >= udc->hw_bank.size)
David Lopoaa69a802008-11-17 14:14:51 -0800666 return -EINVAL;
667
668 /* align */
669 addr *= sizeof(u32);
670
Alexander Shishkin262c1632012-05-08 23:28:59 +0300671 hw_write(udc, addr, ~0, data);
David Lopoaa69a802008-11-17 14:14:51 -0800672 return 0;
673}
674
675/**
676 * hw_test_and_clear_complete: test & clear complete status (execute without
677 * interruption)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200678 * @n: endpoint number
David Lopoaa69a802008-11-17 14:14:51 -0800679 *
680 * This function returns complete status
681 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300682static int hw_test_and_clear_complete(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800683{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300684 n = ep_to_bit(udc, n);
Alexander Shishkin262c1632012-05-08 23:28:59 +0300685 return hw_test_and_clear(udc, OP_ENDPTCOMPLETE, BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800686}
687
688/**
689 * hw_test_and_clear_intr_active: test & clear active interrupts (execute
690 * without interruption)
691 *
692 * This function returns active interrutps
693 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300694static u32 hw_test_and_clear_intr_active(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800695{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300696 u32 reg = hw_read_intr_status(udc) & hw_read_intr_enable(udc);
David Lopoaa69a802008-11-17 14:14:51 -0800697
Alexander Shishkin262c1632012-05-08 23:28:59 +0300698 hw_write(udc, OP_USBSTS, ~0, reg);
David Lopoaa69a802008-11-17 14:14:51 -0800699 return reg;
700}
701
702/**
703 * hw_test_and_clear_setup_guard: test & clear setup guard (execute without
704 * interruption)
705 *
706 * This function returns guard value
707 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300708static int hw_test_and_clear_setup_guard(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800709{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300710 return hw_test_and_write(udc, OP_USBCMD, USBCMD_SUTW, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800711}
712
713/**
714 * hw_test_and_set_setup_guard: test & set setup guard (execute without
715 * interruption)
716 *
717 * This function returns guard value
718 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300719static int hw_test_and_set_setup_guard(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800720{
Alexander Shishkin262c1632012-05-08 23:28:59 +0300721 return hw_test_and_write(udc, OP_USBCMD, USBCMD_SUTW, USBCMD_SUTW);
David Lopoaa69a802008-11-17 14:14:51 -0800722}
723
724/**
725 * hw_usb_set_address: configures USB address (execute without interruption)
726 * @value: new USB address
727 *
728 * This function returns an error code
729 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300730static int hw_usb_set_address(struct ci13xxx *udc, u8 value)
David Lopoaa69a802008-11-17 14:14:51 -0800731{
732 /* advance */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300733 hw_write(udc, OP_DEVICEADDR, DEVICEADDR_USBADR | DEVICEADDR_USBADRA,
734 value << ffs_nr(DEVICEADDR_USBADR) | DEVICEADDR_USBADRA);
David Lopoaa69a802008-11-17 14:14:51 -0800735 return 0;
736}
737
738/**
739 * hw_usb_reset: restart device after a bus reset (execute without
740 * interruption)
741 *
742 * This function returns an error code
743 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300744static int hw_usb_reset(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800745{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300746 hw_usb_set_address(udc, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800747
748 /* ESS flushes only at end?!? */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300749 hw_write(udc, OP_ENDPTFLUSH, ~0, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800750
751 /* clear setup token semaphores */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300752 hw_write(udc, OP_ENDPTSETUPSTAT, 0, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800753
754 /* clear complete status */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300755 hw_write(udc, OP_ENDPTCOMPLETE, 0, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800756
757 /* wait until all bits cleared */
Alexander Shishkin262c1632012-05-08 23:28:59 +0300758 while (hw_read(udc, OP_ENDPTPRIME, ~0))
David Lopoaa69a802008-11-17 14:14:51 -0800759 udelay(10); /* not RTOS friendly */
760
761 /* reset all endpoints ? */
762
763 /* reset internal status and wait for further instructions
764 no need to verify the port reset status (ESS does it) */
765
766 return 0;
767}
768
769/******************************************************************************
770 * DBG block
771 *****************************************************************************/
772/**
773 * show_device: prints information about device capabilities and status
774 *
775 * Check "device.h" for details
776 */
777static ssize_t show_device(struct device *dev, struct device_attribute *attr,
778 char *buf)
779{
780 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
781 struct usb_gadget *gadget = &udc->gadget;
782 int n = 0;
783
784 dbg_trace("[%s] %p\n", __func__, buf);
785 if (attr == NULL || buf == NULL) {
786 dev_err(dev, "[%s] EINVAL\n", __func__);
787 return 0;
788 }
789
790 n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n",
791 gadget->speed);
Michal Nazarewiczd327ab52011-11-19 18:27:37 +0100792 n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n",
793 gadget->max_speed);
794 /* TODO: Scheduled for removal in 3.8. */
David Lopoaa69a802008-11-17 14:14:51 -0800795 n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n",
Michal Nazarewiczd327ab52011-11-19 18:27:37 +0100796 gadget_is_dualspeed(gadget));
David Lopoaa69a802008-11-17 14:14:51 -0800797 n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
798 gadget->is_otg);
799 n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
800 gadget->is_a_peripheral);
801 n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n",
802 gadget->b_hnp_enable);
803 n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n",
804 gadget->a_hnp_support);
805 n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n",
806 gadget->a_alt_hnp_support);
807 n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n",
808 (gadget->name ? gadget->name : ""));
809
810 return n;
811}
812static DEVICE_ATTR(device, S_IRUSR, show_device, NULL);
813
814/**
815 * show_driver: prints information about attached gadget (if any)
816 *
817 * Check "device.h" for details
818 */
819static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
820 char *buf)
821{
822 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
823 struct usb_gadget_driver *driver = udc->driver;
824 int n = 0;
825
826 dbg_trace("[%s] %p\n", __func__, buf);
827 if (attr == NULL || buf == NULL) {
828 dev_err(dev, "[%s] EINVAL\n", __func__);
829 return 0;
830 }
831
832 if (driver == NULL)
833 return scnprintf(buf, PAGE_SIZE,
834 "There is no gadget attached!\n");
835
836 n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n",
837 (driver->function ? driver->function : ""));
838 n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n",
Michal Nazarewicz7177aed2011-11-19 18:27:38 +0100839 driver->max_speed);
David Lopoaa69a802008-11-17 14:14:51 -0800840
841 return n;
842}
843static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);
844
845/* Maximum event message length */
846#define DBG_DATA_MSG 64UL
847
848/* Maximum event messages */
849#define DBG_DATA_MAX 128UL
850
851/* Event buffer descriptor */
852static struct {
853 char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
854 unsigned idx; /* index */
855 unsigned tty; /* print to console? */
856 rwlock_t lck; /* lock */
857} dbg_data = {
858 .idx = 0,
859 .tty = 0,
860 .lck = __RW_LOCK_UNLOCKED(lck)
861};
862
863/**
864 * dbg_dec: decrements debug event index
865 * @idx: buffer index
866 */
867static void dbg_dec(unsigned *idx)
868{
869 *idx = (*idx - 1) & (DBG_DATA_MAX-1);
870}
871
872/**
873 * dbg_inc: increments debug event index
874 * @idx: buffer index
875 */
876static void dbg_inc(unsigned *idx)
877{
878 *idx = (*idx + 1) & (DBG_DATA_MAX-1);
879}
880
881/**
882 * dbg_print: prints the common part of the event
883 * @addr: endpoint address
884 * @name: event name
885 * @status: status
886 * @extra: extra information
887 */
888static void dbg_print(u8 addr, const char *name, int status, const char *extra)
889{
890 struct timeval tval;
891 unsigned int stamp;
892 unsigned long flags;
893
894 write_lock_irqsave(&dbg_data.lck, flags);
895
896 do_gettimeofday(&tval);
897 stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s */
898 stamp = stamp * 1000000 + tval.tv_usec;
899
900 scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +0300901 "%04X\t? %02X %-7.7s %4i ?\t%s\n",
David Lopoaa69a802008-11-17 14:14:51 -0800902 stamp, addr, name, status, extra);
903
904 dbg_inc(&dbg_data.idx);
905
906 write_unlock_irqrestore(&dbg_data.lck, flags);
907
908 if (dbg_data.tty != 0)
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +0300909 pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n",
David Lopoaa69a802008-11-17 14:14:51 -0800910 stamp, addr, name, status, extra);
911}
912
913/**
914 * dbg_done: prints a DONE event
915 * @addr: endpoint address
916 * @td: transfer descriptor
917 * @status: status
918 */
919static void dbg_done(u8 addr, const u32 token, int status)
920{
921 char msg[DBG_DATA_MSG];
922
923 scnprintf(msg, sizeof(msg), "%d %02X",
924 (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES),
925 (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS));
926 dbg_print(addr, "DONE", status, msg);
927}
928
929/**
930 * dbg_event: prints a generic event
931 * @addr: endpoint address
932 * @name: event name
933 * @status: status
934 */
935static void dbg_event(u8 addr, const char *name, int status)
936{
937 if (name != NULL)
938 dbg_print(addr, name, status, "");
939}
940
941/*
942 * dbg_queue: prints a QUEUE event
943 * @addr: endpoint address
944 * @req: USB request
945 * @status: status
946 */
947static void dbg_queue(u8 addr, const struct usb_request *req, int status)
948{
949 char msg[DBG_DATA_MSG];
950
951 if (req != NULL) {
952 scnprintf(msg, sizeof(msg),
953 "%d %d", !req->no_interrupt, req->length);
954 dbg_print(addr, "QUEUE", status, msg);
955 }
956}
957
958/**
959 * dbg_setup: prints a SETUP event
960 * @addr: endpoint address
961 * @req: setup request
962 */
963static void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
964{
965 char msg[DBG_DATA_MSG];
966
967 if (req != NULL) {
968 scnprintf(msg, sizeof(msg),
969 "%02X %02X %04X %04X %d", req->bRequestType,
970 req->bRequest, le16_to_cpu(req->wValue),
971 le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
972 dbg_print(addr, "SETUP", 0, msg);
973 }
974}
975
976/**
977 * show_events: displays the event buffer
978 *
979 * Check "device.h" for details
980 */
981static ssize_t show_events(struct device *dev, struct device_attribute *attr,
982 char *buf)
983{
984 unsigned long flags;
985 unsigned i, j, n = 0;
986
987 dbg_trace("[%s] %p\n", __func__, buf);
988 if (attr == NULL || buf == NULL) {
989 dev_err(dev, "[%s] EINVAL\n", __func__);
990 return 0;
991 }
992
993 read_lock_irqsave(&dbg_data.lck, flags);
994
995 i = dbg_data.idx;
996 for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) {
997 n += strlen(dbg_data.buf[i]);
998 if (n >= PAGE_SIZE) {
999 n -= strlen(dbg_data.buf[i]);
1000 break;
1001 }
1002 }
1003 for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i))
1004 j += scnprintf(buf + j, PAGE_SIZE - j,
1005 "%s", dbg_data.buf[i]);
1006
1007 read_unlock_irqrestore(&dbg_data.lck, flags);
1008
1009 return n;
1010}
1011
1012/**
1013 * store_events: configure if events are going to be also printed to console
1014 *
1015 * Check "device.h" for details
1016 */
1017static ssize_t store_events(struct device *dev, struct device_attribute *attr,
1018 const char *buf, size_t count)
1019{
1020 unsigned tty;
1021
1022 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1023 if (attr == NULL || buf == NULL) {
1024 dev_err(dev, "[%s] EINVAL\n", __func__);
1025 goto done;
1026 }
1027
1028 if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
1029 dev_err(dev, "<1|0>: enable|disable console log\n");
1030 goto done;
1031 }
1032
1033 dbg_data.tty = tty;
1034 dev_info(dev, "tty = %u", dbg_data.tty);
1035
1036 done:
1037 return count;
1038}
1039static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events);
1040
1041/**
1042 * show_inters: interrupt status, enable status and historic
1043 *
1044 * Check "device.h" for details
1045 */
1046static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
1047 char *buf)
1048{
1049 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1050 unsigned long flags;
1051 u32 intr;
1052 unsigned i, j, n = 0;
1053
1054 dbg_trace("[%s] %p\n", __func__, buf);
1055 if (attr == NULL || buf == NULL) {
1056 dev_err(dev, "[%s] EINVAL\n", __func__);
1057 return 0;
1058 }
1059
Alexander Shishkind3595d12012-05-08 23:28:58 +03001060 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001061
1062 n += scnprintf(buf + n, PAGE_SIZE - n,
Alexander Shishkind3595d12012-05-08 23:28:58 +03001063 "status = %08x\n", hw_read_intr_status(udc));
David Lopoaa69a802008-11-17 14:14:51 -08001064 n += scnprintf(buf + n, PAGE_SIZE - n,
Alexander Shishkind3595d12012-05-08 23:28:58 +03001065 "enable = %08x\n", hw_read_intr_enable(udc));
David Lopoaa69a802008-11-17 14:14:51 -08001066
1067 n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
1068 isr_statistics.test);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001069 n += scnprintf(buf + n, PAGE_SIZE - n, "? ui = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001070 isr_statistics.ui);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001071 n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001072 isr_statistics.uei);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001073 n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001074 isr_statistics.pci);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001075 n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001076 isr_statistics.uri);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001077 n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001078 isr_statistics.sli);
1079 n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
1080 isr_statistics.none);
1081 n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n",
1082 isr_statistics.hndl.cnt);
1083
1084 for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) {
1085 i &= ISR_MASK;
1086 intr = isr_statistics.hndl.buf[i];
1087
1088 if (USBi_UI & intr)
1089 n += scnprintf(buf + n, PAGE_SIZE - n, "ui ");
1090 intr &= ~USBi_UI;
1091 if (USBi_UEI & intr)
1092 n += scnprintf(buf + n, PAGE_SIZE - n, "uei ");
1093 intr &= ~USBi_UEI;
1094 if (USBi_PCI & intr)
1095 n += scnprintf(buf + n, PAGE_SIZE - n, "pci ");
1096 intr &= ~USBi_PCI;
1097 if (USBi_URI & intr)
1098 n += scnprintf(buf + n, PAGE_SIZE - n, "uri ");
1099 intr &= ~USBi_URI;
1100 if (USBi_SLI & intr)
1101 n += scnprintf(buf + n, PAGE_SIZE - n, "sli ");
1102 intr &= ~USBi_SLI;
1103 if (intr)
1104 n += scnprintf(buf + n, PAGE_SIZE - n, "??? ");
1105 if (isr_statistics.hndl.buf[i])
1106 n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
1107 }
1108
Alexander Shishkind3595d12012-05-08 23:28:58 +03001109 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001110
1111 return n;
1112}
1113
1114/**
1115 * store_inters: enable & force or disable an individual interrutps
1116 * (to be used for test purposes only)
1117 *
1118 * Check "device.h" for details
1119 */
1120static ssize_t store_inters(struct device *dev, struct device_attribute *attr,
1121 const char *buf, size_t count)
1122{
1123 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1124 unsigned long flags;
1125 unsigned en, bit;
1126
1127 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1128 if (attr == NULL || buf == NULL) {
1129 dev_err(dev, "[%s] EINVAL\n", __func__);
1130 goto done;
1131 }
1132
1133 if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) {
1134 dev_err(dev, "<1|0> <bit>: enable|disable interrupt");
1135 goto done;
1136 }
1137
Alexander Shishkind3595d12012-05-08 23:28:58 +03001138 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001139 if (en) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001140 if (hw_intr_force(udc, bit))
David Lopoaa69a802008-11-17 14:14:51 -08001141 dev_err(dev, "invalid bit number\n");
1142 else
1143 isr_statistics.test++;
1144 } else {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001145 if (hw_intr_clear(udc, bit))
David Lopoaa69a802008-11-17 14:14:51 -08001146 dev_err(dev, "invalid bit number\n");
1147 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03001148 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001149
1150 done:
1151 return count;
1152}
1153static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters);
1154
1155/**
1156 * show_port_test: reads port test mode
1157 *
1158 * Check "device.h" for details
1159 */
1160static ssize_t show_port_test(struct device *dev,
1161 struct device_attribute *attr, char *buf)
1162{
1163 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1164 unsigned long flags;
1165 unsigned mode;
1166
1167 dbg_trace("[%s] %p\n", __func__, buf);
1168 if (attr == NULL || buf == NULL) {
1169 dev_err(dev, "[%s] EINVAL\n", __func__);
1170 return 0;
1171 }
1172
Alexander Shishkind3595d12012-05-08 23:28:58 +03001173 spin_lock_irqsave(&udc->lock, flags);
1174 mode = hw_port_test_get(udc);
1175 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001176
1177 return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode);
1178}
1179
1180/**
1181 * store_port_test: writes port test mode
1182 *
1183 * Check "device.h" for details
1184 */
1185static ssize_t store_port_test(struct device *dev,
1186 struct device_attribute *attr,
1187 const char *buf, size_t count)
1188{
1189 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1190 unsigned long flags;
1191 unsigned mode;
1192
1193 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1194 if (attr == NULL || buf == NULL) {
1195 dev_err(dev, "[%s] EINVAL\n", __func__);
1196 goto done;
1197 }
1198
1199 if (sscanf(buf, "%u", &mode) != 1) {
1200 dev_err(dev, "<mode>: set port test mode");
1201 goto done;
1202 }
1203
Alexander Shishkind3595d12012-05-08 23:28:58 +03001204 spin_lock_irqsave(&udc->lock, flags);
1205 if (hw_port_test_set(udc, mode))
David Lopoaa69a802008-11-17 14:14:51 -08001206 dev_err(dev, "invalid mode\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03001207 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001208
1209 done:
1210 return count;
1211}
1212static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR,
1213 show_port_test, store_port_test);
1214
1215/**
1216 * show_qheads: DMA contents of all queue heads
1217 *
1218 * Check "device.h" for details
1219 */
1220static ssize_t show_qheads(struct device *dev, struct device_attribute *attr,
1221 char *buf)
1222{
1223 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1224 unsigned long flags;
1225 unsigned i, j, n = 0;
1226
1227 dbg_trace("[%s] %p\n", __func__, buf);
1228 if (attr == NULL || buf == NULL) {
1229 dev_err(dev, "[%s] EINVAL\n", __func__);
1230 return 0;
1231 }
1232
Alexander Shishkind3595d12012-05-08 23:28:58 +03001233 spin_lock_irqsave(&udc->lock, flags);
1234 for (i = 0; i < udc->hw_ep_max/2; i++) {
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301235 struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i];
Alexander Shishkind3595d12012-05-08 23:28:58 +03001236 struct ci13xxx_ep *mEpTx =
1237 &udc->ci13xxx_ep[i + udc->hw_ep_max/2];
David Lopoaa69a802008-11-17 14:14:51 -08001238 n += scnprintf(buf + n, PAGE_SIZE - n,
1239 "EP=%02i: RX=%08X TX=%08X\n",
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301240 i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08001241 for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) {
1242 n += scnprintf(buf + n, PAGE_SIZE - n,
1243 " %04X: %08X %08X\n", j,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301244 *((u32 *)mEpRx->qh.ptr + j),
1245 *((u32 *)mEpTx->qh.ptr + j));
David Lopoaa69a802008-11-17 14:14:51 -08001246 }
1247 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03001248 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001249
1250 return n;
1251}
1252static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL);
1253
1254/**
1255 * show_registers: dumps all registers
1256 *
1257 * Check "device.h" for details
1258 */
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001259#define DUMP_ENTRIES 512
David Lopoaa69a802008-11-17 14:14:51 -08001260static ssize_t show_registers(struct device *dev,
1261 struct device_attribute *attr, char *buf)
1262{
1263 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1264 unsigned long flags;
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001265 u32 *dump;
David Lopoaa69a802008-11-17 14:14:51 -08001266 unsigned i, k, n = 0;
1267
1268 dbg_trace("[%s] %p\n", __func__, buf);
1269 if (attr == NULL || buf == NULL) {
1270 dev_err(dev, "[%s] EINVAL\n", __func__);
1271 return 0;
1272 }
1273
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001274 dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL);
1275 if (!dump) {
1276 dev_err(dev, "%s: out of memory\n", __func__);
1277 return 0;
1278 }
1279
Alexander Shishkind3595d12012-05-08 23:28:58 +03001280 spin_lock_irqsave(&udc->lock, flags);
1281 k = hw_register_read(udc, dump, DUMP_ENTRIES);
1282 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001283
1284 for (i = 0; i < k; i++) {
1285 n += scnprintf(buf + n, PAGE_SIZE - n,
1286 "reg[0x%04X] = 0x%08X\n",
1287 i * (unsigned)sizeof(u32), dump[i]);
1288 }
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001289 kfree(dump);
David Lopoaa69a802008-11-17 14:14:51 -08001290
1291 return n;
1292}
1293
1294/**
1295 * store_registers: writes value to register address
1296 *
1297 * Check "device.h" for details
1298 */
1299static ssize_t store_registers(struct device *dev,
1300 struct device_attribute *attr,
1301 const char *buf, size_t count)
1302{
1303 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1304 unsigned long addr, data, flags;
1305
1306 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1307 if (attr == NULL || buf == NULL) {
1308 dev_err(dev, "[%s] EINVAL\n", __func__);
1309 goto done;
1310 }
1311
1312 if (sscanf(buf, "%li %li", &addr, &data) != 2) {
1313 dev_err(dev, "<addr> <data>: write data to register address");
1314 goto done;
1315 }
1316
Alexander Shishkind3595d12012-05-08 23:28:58 +03001317 spin_lock_irqsave(&udc->lock, flags);
1318 if (hw_register_write(udc, addr, data))
David Lopoaa69a802008-11-17 14:14:51 -08001319 dev_err(dev, "invalid address range\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03001320 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001321
1322 done:
1323 return count;
1324}
1325static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR,
1326 show_registers, store_registers);
1327
1328/**
1329 * show_requests: DMA contents of all requests currently queued (all endpts)
1330 *
1331 * Check "device.h" for details
1332 */
1333static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
1334 char *buf)
1335{
1336 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1337 unsigned long flags;
1338 struct list_head *ptr = NULL;
1339 struct ci13xxx_req *req = NULL;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301340 unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -08001341
1342 dbg_trace("[%s] %p\n", __func__, buf);
1343 if (attr == NULL || buf == NULL) {
1344 dev_err(dev, "[%s] EINVAL\n", __func__);
1345 return 0;
1346 }
1347
Alexander Shishkind3595d12012-05-08 23:28:58 +03001348 spin_lock_irqsave(&udc->lock, flags);
1349 for (i = 0; i < udc->hw_ep_max; i++)
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301350 list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue)
1351 {
1352 req = list_entry(ptr, struct ci13xxx_req, queue);
David Lopoaa69a802008-11-17 14:14:51 -08001353
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301354 n += scnprintf(buf + n, PAGE_SIZE - n,
1355 "EP=%02i: TD=%08X %s\n",
Alexander Shishkind3595d12012-05-08 23:28:58 +03001356 i % udc->hw_ep_max/2, (u32)req->dma,
1357 ((i < udc->hw_ep_max/2) ? "RX" : "TX"));
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301358
1359 for (j = 0; j < qSize; j++)
David Lopoaa69a802008-11-17 14:14:51 -08001360 n += scnprintf(buf + n, PAGE_SIZE - n,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301361 " %04X: %08X\n", j,
1362 *((u32 *)req->ptr + j));
1363 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03001364 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001365
1366 return n;
1367}
1368static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL);
1369
1370/**
1371 * dbg_create_files: initializes the attribute interface
1372 * @dev: device
1373 *
1374 * This function returns an error code
1375 */
1376__maybe_unused static int dbg_create_files(struct device *dev)
1377{
1378 int retval = 0;
1379
1380 if (dev == NULL)
1381 return -EINVAL;
1382 retval = device_create_file(dev, &dev_attr_device);
1383 if (retval)
1384 goto done;
1385 retval = device_create_file(dev, &dev_attr_driver);
1386 if (retval)
1387 goto rm_device;
1388 retval = device_create_file(dev, &dev_attr_events);
1389 if (retval)
1390 goto rm_driver;
1391 retval = device_create_file(dev, &dev_attr_inters);
1392 if (retval)
1393 goto rm_events;
1394 retval = device_create_file(dev, &dev_attr_port_test);
1395 if (retval)
1396 goto rm_inters;
1397 retval = device_create_file(dev, &dev_attr_qheads);
1398 if (retval)
1399 goto rm_port_test;
1400 retval = device_create_file(dev, &dev_attr_registers);
1401 if (retval)
1402 goto rm_qheads;
1403 retval = device_create_file(dev, &dev_attr_requests);
1404 if (retval)
1405 goto rm_registers;
1406 return 0;
1407
1408 rm_registers:
1409 device_remove_file(dev, &dev_attr_registers);
1410 rm_qheads:
1411 device_remove_file(dev, &dev_attr_qheads);
1412 rm_port_test:
1413 device_remove_file(dev, &dev_attr_port_test);
1414 rm_inters:
1415 device_remove_file(dev, &dev_attr_inters);
1416 rm_events:
1417 device_remove_file(dev, &dev_attr_events);
1418 rm_driver:
1419 device_remove_file(dev, &dev_attr_driver);
1420 rm_device:
1421 device_remove_file(dev, &dev_attr_device);
1422 done:
1423 return retval;
1424}
1425
1426/**
1427 * dbg_remove_files: destroys the attribute interface
1428 * @dev: device
1429 *
1430 * This function returns an error code
1431 */
1432__maybe_unused static int dbg_remove_files(struct device *dev)
1433{
1434 if (dev == NULL)
1435 return -EINVAL;
1436 device_remove_file(dev, &dev_attr_requests);
1437 device_remove_file(dev, &dev_attr_registers);
1438 device_remove_file(dev, &dev_attr_qheads);
1439 device_remove_file(dev, &dev_attr_port_test);
1440 device_remove_file(dev, &dev_attr_inters);
1441 device_remove_file(dev, &dev_attr_events);
1442 device_remove_file(dev, &dev_attr_driver);
1443 device_remove_file(dev, &dev_attr_device);
1444 return 0;
1445}
1446
1447/******************************************************************************
1448 * UTIL block
1449 *****************************************************************************/
1450/**
1451 * _usb_addr: calculates endpoint address from direction & number
1452 * @ep: endpoint
1453 */
1454static inline u8 _usb_addr(struct ci13xxx_ep *ep)
1455{
1456 return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num;
1457}
1458
1459/**
1460 * _hardware_queue: configures a request at hardware level
1461 * @gadget: gadget
1462 * @mEp: endpoint
1463 *
1464 * This function returns an error code
1465 */
1466static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1467{
Alexander Shishkind3595d12012-05-08 23:28:58 +03001468 struct ci13xxx *udc = mEp->udc;
David Lopoaa69a802008-11-17 14:14:51 -08001469 unsigned i;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301470 int ret = 0;
1471 unsigned length = mReq->req.length;
David Lopoaa69a802008-11-17 14:14:51 -08001472
1473 trace("%p, %p", mEp, mReq);
1474
1475 /* don't queue twice */
1476 if (mReq->req.status == -EALREADY)
1477 return -EALREADY;
1478
David Lopoaa69a802008-11-17 14:14:51 -08001479 mReq->req.status = -EALREADY;
Michael Grzeschik954aad82011-10-10 18:38:06 +02001480 if (length && mReq->req.dma == DMA_ADDR_INVALID) {
David Lopoaa69a802008-11-17 14:14:51 -08001481 mReq->req.dma = \
1482 dma_map_single(mEp->device, mReq->req.buf,
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301483 length, mEp->dir ? DMA_TO_DEVICE :
1484 DMA_FROM_DEVICE);
David Lopoaa69a802008-11-17 14:14:51 -08001485 if (mReq->req.dma == 0)
1486 return -ENOMEM;
1487
1488 mReq->map = 1;
1489 }
1490
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301491 if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) {
1492 mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC,
1493 &mReq->zdma);
1494 if (mReq->zptr == NULL) {
1495 if (mReq->map) {
1496 dma_unmap_single(mEp->device, mReq->req.dma,
1497 length, mEp->dir ? DMA_TO_DEVICE :
1498 DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02001499 mReq->req.dma = DMA_ADDR_INVALID;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301500 mReq->map = 0;
1501 }
1502 return -ENOMEM;
1503 }
1504 memset(mReq->zptr, 0, sizeof(*mReq->zptr));
1505 mReq->zptr->next = TD_TERMINATE;
1506 mReq->zptr->token = TD_STATUS_ACTIVE;
1507 if (!mReq->req.no_interrupt)
1508 mReq->zptr->token |= TD_IOC;
1509 }
David Lopoaa69a802008-11-17 14:14:51 -08001510 /*
1511 * TD configuration
1512 * TODO - handle requests which spawns into several TDs
1513 */
1514 memset(mReq->ptr, 0, sizeof(*mReq->ptr));
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301515 mReq->ptr->token = length << ffs_nr(TD_TOTAL_BYTES);
David Lopoaa69a802008-11-17 14:14:51 -08001516 mReq->ptr->token &= TD_TOTAL_BYTES;
David Lopoaa69a802008-11-17 14:14:51 -08001517 mReq->ptr->token |= TD_STATUS_ACTIVE;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301518 if (mReq->zptr) {
1519 mReq->ptr->next = mReq->zdma;
1520 } else {
1521 mReq->ptr->next = TD_TERMINATE;
1522 if (!mReq->req.no_interrupt)
1523 mReq->ptr->token |= TD_IOC;
1524 }
David Lopoaa69a802008-11-17 14:14:51 -08001525 mReq->ptr->page[0] = mReq->req.dma;
1526 for (i = 1; i < 5; i++)
1527 mReq->ptr->page[i] =
Artem Leonenko0a313c42010-12-14 23:47:06 -08001528 (mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
David Lopoaa69a802008-11-17 14:14:51 -08001529
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301530 if (!list_empty(&mEp->qh.queue)) {
1531 struct ci13xxx_req *mReqPrev;
1532 int n = hw_ep_bit(mEp->num, mEp->dir);
1533 int tmp_stat;
1534
1535 mReqPrev = list_entry(mEp->qh.queue.prev,
1536 struct ci13xxx_req, queue);
1537 if (mReqPrev->zptr)
1538 mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK;
1539 else
1540 mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK;
1541 wmb();
Alexander Shishkin262c1632012-05-08 23:28:59 +03001542 if (hw_read(udc, OP_ENDPTPRIME, BIT(n)))
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301543 goto done;
1544 do {
Alexander Shishkin262c1632012-05-08 23:28:59 +03001545 hw_write(udc, OP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
1546 tmp_stat = hw_read(udc, OP_ENDPTSTAT, BIT(n));
1547 } while (!hw_read(udc, OP_USBCMD, USBCMD_ATDTW));
1548 hw_write(udc, OP_USBCMD, USBCMD_ATDTW, 0);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301549 if (tmp_stat)
1550 goto done;
1551 }
1552
1553 /* QH configuration */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301554 mEp->qh.ptr->td.next = mReq->dma; /* TERMINATE = 0 */
1555 mEp->qh.ptr->td.token &= ~TD_STATUS; /* clear status */
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301556 mEp->qh.ptr->cap |= QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08001557
1558 wmb(); /* synchronize before ep prime */
1559
Alexander Shishkind3595d12012-05-08 23:28:58 +03001560 ret = hw_ep_prime(udc, mEp->num, mEp->dir,
David Lopoaa69a802008-11-17 14:14:51 -08001561 mEp->type == USB_ENDPOINT_XFER_CONTROL);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301562done:
1563 return ret;
David Lopoaa69a802008-11-17 14:14:51 -08001564}
1565
1566/**
1567 * _hardware_dequeue: handles a request at hardware level
1568 * @gadget: gadget
1569 * @mEp: endpoint
1570 *
1571 * This function returns an error code
1572 */
1573static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1574{
1575 trace("%p, %p", mEp, mReq);
1576
1577 if (mReq->req.status != -EALREADY)
1578 return -EINVAL;
1579
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301580 if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0)
1581 return -EBUSY;
1582
1583 if (mReq->zptr) {
1584 if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
1585 return -EBUSY;
1586 dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
1587 mReq->zptr = NULL;
1588 }
David Lopoaa69a802008-11-17 14:14:51 -08001589
1590 mReq->req.status = 0;
1591
1592 if (mReq->map) {
1593 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
1594 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02001595 mReq->req.dma = DMA_ADDR_INVALID;
David Lopoaa69a802008-11-17 14:14:51 -08001596 mReq->map = 0;
1597 }
1598
1599 mReq->req.status = mReq->ptr->token & TD_STATUS;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301600 if ((TD_STATUS_HALTED & mReq->req.status) != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001601 mReq->req.status = -1;
1602 else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0)
1603 mReq->req.status = -1;
1604 else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0)
1605 mReq->req.status = -1;
1606
1607 mReq->req.actual = mReq->ptr->token & TD_TOTAL_BYTES;
1608 mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES);
1609 mReq->req.actual = mReq->req.length - mReq->req.actual;
1610 mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual;
1611
1612 return mReq->req.actual;
1613}
1614
1615/**
1616 * _ep_nuke: dequeues all endpoint requests
1617 * @mEp: endpoint
1618 *
1619 * This function returns an error code
1620 * Caller must hold lock
1621 */
1622static int _ep_nuke(struct ci13xxx_ep *mEp)
1623__releases(mEp->lock)
1624__acquires(mEp->lock)
1625{
1626 trace("%p", mEp);
1627
1628 if (mEp == NULL)
1629 return -EINVAL;
1630
Alexander Shishkind3595d12012-05-08 23:28:58 +03001631 hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08001632
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301633 while (!list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08001634
1635 /* pop oldest request */
1636 struct ci13xxx_req *mReq = \
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301637 list_entry(mEp->qh.queue.next,
David Lopoaa69a802008-11-17 14:14:51 -08001638 struct ci13xxx_req, queue);
1639 list_del_init(&mReq->queue);
1640 mReq->req.status = -ESHUTDOWN;
1641
Artem Leonenko7c25a822010-12-14 23:46:55 -08001642 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08001643 spin_unlock(mEp->lock);
1644 mReq->req.complete(&mEp->ep, &mReq->req);
1645 spin_lock(mEp->lock);
1646 }
1647 }
1648 return 0;
1649}
1650
1651/**
1652 * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
1653 * @gadget: gadget
1654 *
1655 * This function returns an error code
David Lopoaa69a802008-11-17 14:14:51 -08001656 */
1657static int _gadget_stop_activity(struct usb_gadget *gadget)
David Lopoaa69a802008-11-17 14:14:51 -08001658{
1659 struct usb_ep *ep;
1660 struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301661 unsigned long flags;
David Lopoaa69a802008-11-17 14:14:51 -08001662
1663 trace("%p", gadget);
1664
1665 if (gadget == NULL)
1666 return -EINVAL;
1667
Alexander Shishkind3595d12012-05-08 23:28:58 +03001668 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301669 udc->gadget.speed = USB_SPEED_UNKNOWN;
1670 udc->remote_wakeup = 0;
1671 udc->suspended = 0;
Alexander Shishkind3595d12012-05-08 23:28:58 +03001672 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301673
David Lopoaa69a802008-11-17 14:14:51 -08001674 /* flush all endpoints */
1675 gadget_for_each_ep(ep, gadget) {
1676 usb_ep_fifo_flush(ep);
1677 }
Alexander Shishkind36ade62012-05-04 16:47:15 +03001678 usb_ep_fifo_flush(&udc->ep0out->ep);
1679 usb_ep_fifo_flush(&udc->ep0in->ep);
David Lopoaa69a802008-11-17 14:14:51 -08001680
1681 udc->driver->disconnect(gadget);
1682
1683 /* make sure to disable all endpoints */
1684 gadget_for_each_ep(ep, gadget) {
1685 usb_ep_disable(ep);
1686 }
David Lopoaa69a802008-11-17 14:14:51 -08001687
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301688 if (udc->status != NULL) {
Alexander Shishkind36ade62012-05-04 16:47:15 +03001689 usb_ep_free_request(&udc->ep0in->ep, udc->status);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301690 udc->status = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08001691 }
1692
David Lopoaa69a802008-11-17 14:14:51 -08001693 return 0;
1694}
1695
1696/******************************************************************************
1697 * ISR block
1698 *****************************************************************************/
1699/**
1700 * isr_reset_handler: USB reset interrupt handler
1701 * @udc: UDC device
1702 *
1703 * This function resets USB engine after a bus reset occurred
1704 */
1705static void isr_reset_handler(struct ci13xxx *udc)
1706__releases(udc->lock)
1707__acquires(udc->lock)
1708{
David Lopoaa69a802008-11-17 14:14:51 -08001709 int retval;
1710
1711 trace("%p", udc);
1712
1713 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001714 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08001715 return;
1716 }
1717
1718 dbg_event(0xFF, "BUS RST", 0);
1719
Alexander Shishkind3595d12012-05-08 23:28:58 +03001720 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001721 retval = _gadget_stop_activity(&udc->gadget);
1722 if (retval)
1723 goto done;
1724
Alexander Shishkind3595d12012-05-08 23:28:58 +03001725 retval = hw_usb_reset(udc);
David Lopoaa69a802008-11-17 14:14:51 -08001726 if (retval)
1727 goto done;
1728
Alexander Shishkind36ade62012-05-04 16:47:15 +03001729 udc->status = usb_ep_alloc_request(&udc->ep0in->ep, GFP_ATOMIC);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05301730 if (udc->status == NULL)
1731 retval = -ENOMEM;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301732
Alexander Shishkind3595d12012-05-08 23:28:58 +03001733 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001734
1735 done:
1736 if (retval)
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001737 pr_err("error: %i\n", retval);
David Lopoaa69a802008-11-17 14:14:51 -08001738}
1739
1740/**
1741 * isr_get_status_complete: get_status request complete function
1742 * @ep: endpoint
1743 * @req: request handled
1744 *
1745 * Caller must release lock
1746 */
1747static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
1748{
1749 trace("%p, %p", ep, req);
1750
1751 if (ep == NULL || req == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001752 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08001753 return;
1754 }
1755
1756 kfree(req->buf);
1757 usb_ep_free_request(ep, req);
1758}
1759
1760/**
1761 * isr_get_status_response: get_status request response
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301762 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001763 * @setup: setup request packet
1764 *
1765 * This function returns an error code
1766 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301767static int isr_get_status_response(struct ci13xxx *udc,
David Lopoaa69a802008-11-17 14:14:51 -08001768 struct usb_ctrlrequest *setup)
1769__releases(mEp->lock)
1770__acquires(mEp->lock)
1771{
Alexander Shishkind36ade62012-05-04 16:47:15 +03001772 struct ci13xxx_ep *mEp = udc->ep0in;
David Lopoaa69a802008-11-17 14:14:51 -08001773 struct usb_request *req = NULL;
1774 gfp_t gfp_flags = GFP_ATOMIC;
1775 int dir, num, retval;
1776
1777 trace("%p, %p", mEp, setup);
1778
1779 if (mEp == NULL || setup == NULL)
1780 return -EINVAL;
1781
1782 spin_unlock(mEp->lock);
1783 req = usb_ep_alloc_request(&mEp->ep, gfp_flags);
1784 spin_lock(mEp->lock);
1785 if (req == NULL)
1786 return -ENOMEM;
1787
1788 req->complete = isr_get_status_complete;
1789 req->length = 2;
1790 req->buf = kzalloc(req->length, gfp_flags);
1791 if (req->buf == NULL) {
1792 retval = -ENOMEM;
1793 goto err_free_req;
1794 }
1795
1796 if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301797 /* Assume that device is bus powered for now. */
Alexander Shishkin1155a7b2012-05-08 23:28:57 +03001798 *(u16 *)req->buf = _udc->remote_wakeup << 1;
David Lopoaa69a802008-11-17 14:14:51 -08001799 retval = 0;
1800 } else if ((setup->bRequestType & USB_RECIP_MASK) \
1801 == USB_RECIP_ENDPOINT) {
1802 dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ?
1803 TX : RX;
1804 num = le16_to_cpu(setup->wIndex) & USB_ENDPOINT_NUMBER_MASK;
Alexander Shishkind3595d12012-05-08 23:28:58 +03001805 *(u16 *)req->buf = hw_ep_get_halt(udc, num, dir);
David Lopoaa69a802008-11-17 14:14:51 -08001806 }
1807 /* else do nothing; reserved for future use */
1808
1809 spin_unlock(mEp->lock);
1810 retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
1811 spin_lock(mEp->lock);
1812 if (retval)
1813 goto err_free_buf;
1814
1815 return 0;
1816
1817 err_free_buf:
1818 kfree(req->buf);
1819 err_free_req:
1820 spin_unlock(mEp->lock);
1821 usb_ep_free_request(&mEp->ep, req);
1822 spin_lock(mEp->lock);
1823 return retval;
1824}
1825
1826/**
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301827 * isr_setup_status_complete: setup_status request complete function
1828 * @ep: endpoint
1829 * @req: request handled
1830 *
1831 * Caller must release lock. Put the port in test mode if test mode
1832 * feature is selected.
1833 */
1834static void
1835isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
1836{
1837 struct ci13xxx *udc = req->context;
1838 unsigned long flags;
1839
1840 trace("%p, %p", ep, req);
1841
Alexander Shishkind3595d12012-05-08 23:28:58 +03001842 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301843 if (udc->test_mode)
Alexander Shishkind3595d12012-05-08 23:28:58 +03001844 hw_port_test_set(udc, udc->test_mode);
1845 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301846}
1847
1848/**
David Lopoaa69a802008-11-17 14:14:51 -08001849 * isr_setup_status_phase: queues the status phase of a setup transation
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301850 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001851 *
1852 * This function returns an error code
1853 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301854static int isr_setup_status_phase(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -08001855__releases(mEp->lock)
1856__acquires(mEp->lock)
1857{
1858 int retval;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301859 struct ci13xxx_ep *mEp;
David Lopoaa69a802008-11-17 14:14:51 -08001860
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301861 trace("%p", udc);
David Lopoaa69a802008-11-17 14:14:51 -08001862
Alexander Shishkind36ade62012-05-04 16:47:15 +03001863 mEp = (udc->ep0_dir == TX) ? udc->ep0out : udc->ep0in;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301864 udc->status->context = udc;
1865 udc->status->complete = isr_setup_status_complete;
David Lopoaa69a802008-11-17 14:14:51 -08001866
1867 spin_unlock(mEp->lock);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301868 retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
David Lopoaa69a802008-11-17 14:14:51 -08001869 spin_lock(mEp->lock);
1870
1871 return retval;
1872}
1873
1874/**
1875 * isr_tr_complete_low: transaction complete low level handler
1876 * @mEp: endpoint
1877 *
1878 * This function returns an error code
1879 * Caller must hold lock
1880 */
1881static int isr_tr_complete_low(struct ci13xxx_ep *mEp)
1882__releases(mEp->lock)
1883__acquires(mEp->lock)
1884{
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301885 struct ci13xxx_req *mReq, *mReqTemp;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301886 struct ci13xxx_ep *mEpTemp = mEp;
Pavankumar Kondeti986b11b2011-05-02 11:56:29 +05301887 int uninitialized_var(retval);
David Lopoaa69a802008-11-17 14:14:51 -08001888
1889 trace("%p", mEp);
1890
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301891 if (list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08001892 return -EINVAL;
1893
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301894 list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue,
1895 queue) {
1896 retval = _hardware_dequeue(mEp, mReq);
1897 if (retval < 0)
1898 break;
1899 list_del_init(&mReq->queue);
1900 dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
1901 if (mReq->req.complete != NULL) {
1902 spin_unlock(mEp->lock);
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301903 if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
1904 mReq->req.length)
Alexander Shishkind36ade62012-05-04 16:47:15 +03001905 mEpTemp = _udc->ep0in;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301906 mReq->req.complete(&mEpTemp->ep, &mReq->req);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301907 spin_lock(mEp->lock);
1908 }
1909 }
David Lopoaa69a802008-11-17 14:14:51 -08001910
Pavankumar Kondetief907482011-05-02 11:56:27 +05301911 if (retval == -EBUSY)
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301912 retval = 0;
1913 if (retval < 0)
David Lopoaa69a802008-11-17 14:14:51 -08001914 dbg_event(_usb_addr(mEp), "DONE", retval);
David Lopoaa69a802008-11-17 14:14:51 -08001915
David Lopoaa69a802008-11-17 14:14:51 -08001916 return retval;
1917}
1918
1919/**
1920 * isr_tr_complete_handler: transaction complete interrupt handler
1921 * @udc: UDC descriptor
1922 *
1923 * This function handles traffic events
1924 */
1925static void isr_tr_complete_handler(struct ci13xxx *udc)
1926__releases(udc->lock)
1927__acquires(udc->lock)
1928{
1929 unsigned i;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301930 u8 tmode = 0;
David Lopoaa69a802008-11-17 14:14:51 -08001931
1932 trace("%p", udc);
1933
1934 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001935 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08001936 return;
1937 }
1938
Alexander Shishkind3595d12012-05-08 23:28:58 +03001939 for (i = 0; i < udc->hw_ep_max; i++) {
David Lopoaa69a802008-11-17 14:14:51 -08001940 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301941 int type, num, dir, err = -EINVAL;
David Lopoaa69a802008-11-17 14:14:51 -08001942 struct usb_ctrlrequest req;
1943
Ido Shayevitz31fb6012012-03-12 20:25:23 +02001944 if (mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08001945 continue; /* not configured */
1946
Alexander Shishkind3595d12012-05-08 23:28:58 +03001947 if (hw_test_and_clear_complete(udc, i)) {
David Lopoaa69a802008-11-17 14:14:51 -08001948 err = isr_tr_complete_low(mEp);
1949 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
1950 if (err > 0) /* needs status phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301951 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08001952 if (err < 0) {
1953 dbg_event(_usb_addr(mEp),
1954 "ERROR", err);
Alexander Shishkind3595d12012-05-08 23:28:58 +03001955 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001956 if (usb_ep_set_halt(&mEp->ep))
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001957 dev_err(&udc->gadget.dev,
1958 "error: ep_set_halt\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03001959 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001960 }
1961 }
1962 }
1963
1964 if (mEp->type != USB_ENDPOINT_XFER_CONTROL ||
Alexander Shishkind3595d12012-05-08 23:28:58 +03001965 !hw_test_and_clear_setup_status(udc, i))
David Lopoaa69a802008-11-17 14:14:51 -08001966 continue;
1967
1968 if (i != 0) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001969 dev_warn(&udc->gadget.dev,
1970 "ctrl traffic received at endpoint\n");
David Lopoaa69a802008-11-17 14:14:51 -08001971 continue;
1972 }
1973
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301974 /*
1975 * Flush data and handshake transactions of previous
1976 * setup packet.
1977 */
Alexander Shishkind36ade62012-05-04 16:47:15 +03001978 _ep_nuke(udc->ep0out);
1979 _ep_nuke(udc->ep0in);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301980
David Lopoaa69a802008-11-17 14:14:51 -08001981 /* read_setup_packet */
1982 do {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001983 hw_test_and_set_setup_guard(udc);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301984 memcpy(&req, &mEp->qh.ptr->setup, sizeof(req));
Alexander Shishkind3595d12012-05-08 23:28:58 +03001985 } while (!hw_test_and_clear_setup_guard(udc));
David Lopoaa69a802008-11-17 14:14:51 -08001986
1987 type = req.bRequestType;
1988
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301989 udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX;
David Lopoaa69a802008-11-17 14:14:51 -08001990
1991 dbg_setup(_usb_addr(mEp), &req);
1992
1993 switch (req.bRequest) {
1994 case USB_REQ_CLEAR_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301995 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
1996 le16_to_cpu(req.wValue) ==
1997 USB_ENDPOINT_HALT) {
1998 if (req.wLength != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001999 break;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302000 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302001 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302002 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302003 if (dir) /* TX */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002004 num += udc->hw_ep_max/2;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302005 if (!udc->ci13xxx_ep[num].wedge) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002006 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302007 err = usb_ep_clear_halt(
2008 &udc->ci13xxx_ep[num].ep);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002009 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302010 if (err)
2011 break;
2012 }
2013 err = isr_setup_status_phase(udc);
2014 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) &&
2015 le16_to_cpu(req.wValue) ==
2016 USB_DEVICE_REMOTE_WAKEUP) {
2017 if (req.wLength != 0)
2018 break;
2019 udc->remote_wakeup = 0;
2020 err = isr_setup_status_phase(udc);
2021 } else {
2022 goto delegate;
David Lopoaa69a802008-11-17 14:14:51 -08002023 }
David Lopoaa69a802008-11-17 14:14:51 -08002024 break;
2025 case USB_REQ_GET_STATUS:
2026 if (type != (USB_DIR_IN|USB_RECIP_DEVICE) &&
2027 type != (USB_DIR_IN|USB_RECIP_ENDPOINT) &&
2028 type != (USB_DIR_IN|USB_RECIP_INTERFACE))
2029 goto delegate;
2030 if (le16_to_cpu(req.wLength) != 2 ||
2031 le16_to_cpu(req.wValue) != 0)
2032 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302033 err = isr_get_status_response(udc, &req);
David Lopoaa69a802008-11-17 14:14:51 -08002034 break;
2035 case USB_REQ_SET_ADDRESS:
2036 if (type != (USB_DIR_OUT|USB_RECIP_DEVICE))
2037 goto delegate;
2038 if (le16_to_cpu(req.wLength) != 0 ||
2039 le16_to_cpu(req.wIndex) != 0)
2040 break;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002041 err = hw_usb_set_address(udc,
2042 (u8)le16_to_cpu(req.wValue));
David Lopoaa69a802008-11-17 14:14:51 -08002043 if (err)
2044 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302045 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08002046 break;
2047 case USB_REQ_SET_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302048 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
2049 le16_to_cpu(req.wValue) ==
2050 USB_ENDPOINT_HALT) {
2051 if (req.wLength != 0)
2052 break;
2053 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302054 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302055 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302056 if (dir) /* TX */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002057 num += udc->hw_ep_max/2;
David Lopoaa69a802008-11-17 14:14:51 -08002058
Alexander Shishkind3595d12012-05-08 23:28:58 +03002059 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302060 err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002061 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302062 if (!err)
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302063 isr_setup_status_phase(udc);
2064 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302065 if (req.wLength != 0)
2066 break;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302067 switch (le16_to_cpu(req.wValue)) {
2068 case USB_DEVICE_REMOTE_WAKEUP:
2069 udc->remote_wakeup = 1;
2070 err = isr_setup_status_phase(udc);
2071 break;
2072 case USB_DEVICE_TEST_MODE:
2073 tmode = le16_to_cpu(req.wIndex) >> 8;
2074 switch (tmode) {
2075 case TEST_J:
2076 case TEST_K:
2077 case TEST_SE0_NAK:
2078 case TEST_PACKET:
2079 case TEST_FORCE_EN:
2080 udc->test_mode = tmode;
2081 err = isr_setup_status_phase(
2082 udc);
2083 break;
2084 default:
2085 break;
2086 }
2087 default:
2088 goto delegate;
2089 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302090 } else {
2091 goto delegate;
2092 }
David Lopoaa69a802008-11-17 14:14:51 -08002093 break;
2094 default:
2095delegate:
2096 if (req.wLength == 0) /* no data phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302097 udc->ep0_dir = TX;
David Lopoaa69a802008-11-17 14:14:51 -08002098
Alexander Shishkind3595d12012-05-08 23:28:58 +03002099 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002100 err = udc->driver->setup(&udc->gadget, &req);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002101 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002102 break;
2103 }
2104
2105 if (err < 0) {
2106 dbg_event(_usb_addr(mEp), "ERROR", err);
2107
Alexander Shishkind3595d12012-05-08 23:28:58 +03002108 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002109 if (usb_ep_set_halt(&mEp->ep))
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002110 dev_err(&udc->gadget.dev,
2111 "error: ep_set_halt\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03002112 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002113 }
2114 }
2115}
2116
2117/******************************************************************************
2118 * ENDPT block
2119 *****************************************************************************/
2120/**
2121 * ep_enable: configure endpoint, making it usable
2122 *
2123 * Check usb_ep_enable() at "usb_gadget.h" for details
2124 */
2125static int ep_enable(struct usb_ep *ep,
2126 const struct usb_endpoint_descriptor *desc)
2127{
2128 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302129 int retval = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002130 unsigned long flags;
2131
2132 trace("%p, %p", ep, desc);
2133
2134 if (ep == NULL || desc == NULL)
2135 return -EINVAL;
2136
2137 spin_lock_irqsave(mEp->lock, flags);
2138
2139 /* only internal SW should enable ctrl endpts */
2140
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002141 mEp->ep.desc = desc;
David Lopoaa69a802008-11-17 14:14:51 -08002142
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302143 if (!list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002144 warn("enabling a non-empty endpoint!");
2145
Matthias Kaehlcke15739bb2009-04-15 22:28:41 +02002146 mEp->dir = usb_endpoint_dir_in(desc) ? TX : RX;
2147 mEp->num = usb_endpoint_num(desc);
2148 mEp->type = usb_endpoint_type(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002149
Kuninori Morimoto29cc8892011-08-23 03:12:03 -07002150 mEp->ep.maxpacket = usb_endpoint_maxp(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002151
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302152 dbg_event(_usb_addr(mEp), "ENABLE", 0);
David Lopoaa69a802008-11-17 14:14:51 -08002153
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302154 mEp->qh.ptr->cap = 0;
David Lopof23e6492009-04-16 14:35:24 -07002155
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302156 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2157 mEp->qh.ptr->cap |= QH_IOS;
2158 else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
2159 mEp->qh.ptr->cap &= ~QH_MULT;
2160 else
2161 mEp->qh.ptr->cap &= ~QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08002162
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302163 mEp->qh.ptr->cap |=
2164 (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
2165 mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */
David Lopoaa69a802008-11-17 14:14:51 -08002166
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302167 /*
2168 * Enable endpoints in the HW other than ep0 as ep0
2169 * is always enabled
2170 */
2171 if (mEp->num)
Alexander Shishkind3595d12012-05-08 23:28:58 +03002172 retval |= hw_ep_enable(mEp->udc, mEp->num, mEp->dir, mEp->type);
David Lopoaa69a802008-11-17 14:14:51 -08002173
2174 spin_unlock_irqrestore(mEp->lock, flags);
2175 return retval;
2176}
2177
2178/**
2179 * ep_disable: endpoint is no longer usable
2180 *
2181 * Check usb_ep_disable() at "usb_gadget.h" for details
2182 */
2183static int ep_disable(struct usb_ep *ep)
2184{
2185 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2186 int direction, retval = 0;
2187 unsigned long flags;
2188
2189 trace("%p", ep);
2190
2191 if (ep == NULL)
2192 return -EINVAL;
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002193 else if (mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002194 return -EBUSY;
2195
2196 spin_lock_irqsave(mEp->lock, flags);
2197
2198 /* only internal SW should disable ctrl endpts */
2199
2200 direction = mEp->dir;
2201 do {
2202 dbg_event(_usb_addr(mEp), "DISABLE", 0);
2203
2204 retval |= _ep_nuke(mEp);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002205 retval |= hw_ep_disable(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002206
2207 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2208 mEp->dir = (mEp->dir == TX) ? RX : TX;
2209
2210 } while (mEp->dir != direction);
2211
Ido Shayevitzf9c56cd2012-02-08 13:56:48 +02002212 mEp->ep.desc = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002213
2214 spin_unlock_irqrestore(mEp->lock, flags);
2215 return retval;
2216}
2217
2218/**
2219 * ep_alloc_request: allocate a request object to use with this endpoint
2220 *
2221 * Check usb_ep_alloc_request() at "usb_gadget.h" for details
2222 */
2223static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
2224{
2225 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2226 struct ci13xxx_req *mReq = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002227
2228 trace("%p, %i", ep, gfp_flags);
2229
2230 if (ep == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002231 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08002232 return NULL;
2233 }
2234
David Lopoaa69a802008-11-17 14:14:51 -08002235 mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
2236 if (mReq != NULL) {
2237 INIT_LIST_HEAD(&mReq->queue);
Michael Grzeschik954aad82011-10-10 18:38:06 +02002238 mReq->req.dma = DMA_ADDR_INVALID;
David Lopoaa69a802008-11-17 14:14:51 -08002239
2240 mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
2241 &mReq->dma);
2242 if (mReq->ptr == NULL) {
2243 kfree(mReq);
2244 mReq = NULL;
2245 }
2246 }
2247
2248 dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
2249
David Lopoaa69a802008-11-17 14:14:51 -08002250 return (mReq == NULL) ? NULL : &mReq->req;
2251}
2252
2253/**
2254 * ep_free_request: frees a request object
2255 *
2256 * Check usb_ep_free_request() at "usb_gadget.h" for details
2257 */
2258static void ep_free_request(struct usb_ep *ep, struct usb_request *req)
2259{
2260 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2261 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2262 unsigned long flags;
2263
2264 trace("%p, %p", ep, req);
2265
2266 if (ep == NULL || req == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002267 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08002268 return;
2269 } else if (!list_empty(&mReq->queue)) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002270 pr_err("EBUSY\n");
David Lopoaa69a802008-11-17 14:14:51 -08002271 return;
2272 }
2273
2274 spin_lock_irqsave(mEp->lock, flags);
2275
2276 if (mReq->ptr)
2277 dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma);
2278 kfree(mReq);
2279
2280 dbg_event(_usb_addr(mEp), "FREE", 0);
2281
2282 spin_unlock_irqrestore(mEp->lock, flags);
2283}
2284
2285/**
2286 * ep_queue: queues (submits) an I/O request to an endpoint
2287 *
2288 * Check usb_ep_queue()* at usb_gadget.h" for details
2289 */
2290static int ep_queue(struct usb_ep *ep, struct usb_request *req,
2291 gfp_t __maybe_unused gfp_flags)
2292{
2293 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2294 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2295 int retval = 0;
2296 unsigned long flags;
2297
2298 trace("%p, %p, %X", ep, req, gfp_flags);
2299
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002300 if (ep == NULL || req == NULL || mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002301 return -EINVAL;
2302
2303 spin_lock_irqsave(mEp->lock, flags);
2304
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302305 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
2306 if (req->length)
2307 mEp = (_udc->ep0_dir == RX) ?
Alexander Shishkind36ade62012-05-04 16:47:15 +03002308 _udc->ep0out : _udc->ep0in;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302309 if (!list_empty(&mEp->qh.queue)) {
2310 _ep_nuke(mEp);
2311 retval = -EOVERFLOW;
2312 warn("endpoint ctrl %X nuked", _usb_addr(mEp));
2313 }
David Lopoaa69a802008-11-17 14:14:51 -08002314 }
2315
2316 /* first nuke then test link, e.g. previous status has not sent */
2317 if (!list_empty(&mReq->queue)) {
2318 retval = -EBUSY;
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002319 pr_err("request already in queue\n");
David Lopoaa69a802008-11-17 14:14:51 -08002320 goto done;
2321 }
2322
Alexander Shishkin1155a7b2012-05-08 23:28:57 +03002323 if (req->length > 4 * CI13XXX_PAGE_SIZE) {
2324 req->length = 4 * CI13XXX_PAGE_SIZE;
David Lopoaa69a802008-11-17 14:14:51 -08002325 retval = -EMSGSIZE;
2326 warn("request length truncated");
2327 }
2328
2329 dbg_queue(_usb_addr(mEp), req, retval);
2330
2331 /* push request */
2332 mReq->req.status = -EINPROGRESS;
2333 mReq->req.actual = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002334
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302335 retval = _hardware_enqueue(mEp, mReq);
Artem Leonenkod9bb9c12010-12-14 23:45:50 -08002336
2337 if (retval == -EALREADY) {
David Lopoaa69a802008-11-17 14:14:51 -08002338 dbg_event(_usb_addr(mEp), "QUEUE", retval);
2339 retval = 0;
2340 }
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302341 if (!retval)
2342 list_add_tail(&mReq->queue, &mEp->qh.queue);
David Lopoaa69a802008-11-17 14:14:51 -08002343
2344 done:
2345 spin_unlock_irqrestore(mEp->lock, flags);
2346 return retval;
2347}
2348
2349/**
2350 * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint
2351 *
2352 * Check usb_ep_dequeue() at "usb_gadget.h" for details
2353 */
2354static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
2355{
2356 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2357 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2358 unsigned long flags;
2359
2360 trace("%p, %p", ep, req);
2361
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302362 if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002363 mEp->ep.desc == NULL || list_empty(&mReq->queue) ||
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302364 list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002365 return -EINVAL;
2366
2367 spin_lock_irqsave(mEp->lock, flags);
2368
2369 dbg_event(_usb_addr(mEp), "DEQUEUE", 0);
2370
Alexander Shishkind3595d12012-05-08 23:28:58 +03002371 hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002372
2373 /* pop request */
2374 list_del_init(&mReq->queue);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302375 if (mReq->map) {
2376 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
2377 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02002378 mReq->req.dma = DMA_ADDR_INVALID;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302379 mReq->map = 0;
2380 }
David Lopoaa69a802008-11-17 14:14:51 -08002381 req->status = -ECONNRESET;
2382
Artem Leonenko7c25a822010-12-14 23:46:55 -08002383 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08002384 spin_unlock(mEp->lock);
2385 mReq->req.complete(&mEp->ep, &mReq->req);
2386 spin_lock(mEp->lock);
2387 }
2388
2389 spin_unlock_irqrestore(mEp->lock, flags);
2390 return 0;
2391}
2392
2393/**
2394 * ep_set_halt: sets the endpoint halt feature
2395 *
2396 * Check usb_ep_set_halt() at "usb_gadget.h" for details
2397 */
2398static int ep_set_halt(struct usb_ep *ep, int value)
2399{
2400 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2401 int direction, retval = 0;
2402 unsigned long flags;
2403
2404 trace("%p, %i", ep, value);
2405
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002406 if (ep == NULL || mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002407 return -EINVAL;
2408
2409 spin_lock_irqsave(mEp->lock, flags);
2410
2411#ifndef STALL_IN
2412 /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
2413 if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302414 !list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08002415 spin_unlock_irqrestore(mEp->lock, flags);
2416 return -EAGAIN;
2417 }
2418#endif
2419
2420 direction = mEp->dir;
2421 do {
2422 dbg_event(_usb_addr(mEp), "HALT", value);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002423 retval |= hw_ep_set_halt(mEp->udc, mEp->num, mEp->dir, value);
David Lopoaa69a802008-11-17 14:14:51 -08002424
2425 if (!value)
2426 mEp->wedge = 0;
2427
2428 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2429 mEp->dir = (mEp->dir == TX) ? RX : TX;
2430
2431 } while (mEp->dir != direction);
2432
2433 spin_unlock_irqrestore(mEp->lock, flags);
2434 return retval;
2435}
2436
2437/**
2438 * ep_set_wedge: sets the halt feature and ignores clear requests
2439 *
2440 * Check usb_ep_set_wedge() at "usb_gadget.h" for details
2441 */
2442static int ep_set_wedge(struct usb_ep *ep)
2443{
2444 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2445 unsigned long flags;
2446
2447 trace("%p", ep);
2448
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002449 if (ep == NULL || mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002450 return -EINVAL;
2451
2452 spin_lock_irqsave(mEp->lock, flags);
2453
2454 dbg_event(_usb_addr(mEp), "WEDGE", 0);
2455 mEp->wedge = 1;
2456
2457 spin_unlock_irqrestore(mEp->lock, flags);
2458
2459 return usb_ep_set_halt(ep);
2460}
2461
2462/**
2463 * ep_fifo_flush: flushes contents of a fifo
2464 *
2465 * Check usb_ep_fifo_flush() at "usb_gadget.h" for details
2466 */
2467static void ep_fifo_flush(struct usb_ep *ep)
2468{
2469 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2470 unsigned long flags;
2471
2472 trace("%p", ep);
2473
2474 if (ep == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002475 pr_err("%02X: -EINVAL\n", _usb_addr(mEp));
David Lopoaa69a802008-11-17 14:14:51 -08002476 return;
2477 }
2478
2479 spin_lock_irqsave(mEp->lock, flags);
2480
2481 dbg_event(_usb_addr(mEp), "FFLUSH", 0);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002482 hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002483
2484 spin_unlock_irqrestore(mEp->lock, flags);
2485}
2486
2487/**
2488 * Endpoint-specific part of the API to the USB controller hardware
2489 * Check "usb_gadget.h" for details
2490 */
2491static const struct usb_ep_ops usb_ep_ops = {
2492 .enable = ep_enable,
2493 .disable = ep_disable,
2494 .alloc_request = ep_alloc_request,
2495 .free_request = ep_free_request,
2496 .queue = ep_queue,
2497 .dequeue = ep_dequeue,
2498 .set_halt = ep_set_halt,
2499 .set_wedge = ep_set_wedge,
2500 .fifo_flush = ep_fifo_flush,
2501};
2502
2503/******************************************************************************
2504 * GADGET block
2505 *****************************************************************************/
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302506static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
2507{
2508 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2509 unsigned long flags;
2510 int gadget_ready = 0;
2511
2512 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS))
2513 return -EOPNOTSUPP;
2514
Alexander Shishkind3595d12012-05-08 23:28:58 +03002515 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302516 udc->vbus_active = is_active;
2517 if (udc->driver)
2518 gadget_ready = 1;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002519 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302520
2521 if (gadget_ready) {
2522 if (is_active) {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302523 pm_runtime_get_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302524 hw_device_reset(udc);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002525 hw_device_state(udc, udc->ep0out->qh.dma);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302526 } else {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002527 hw_device_state(udc, 0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302528 if (udc->udc_driver->notify_event)
2529 udc->udc_driver->notify_event(udc,
2530 CI13XXX_CONTROLLER_STOPPED_EVENT);
2531 _gadget_stop_activity(&udc->gadget);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302532 pm_runtime_put_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302533 }
2534 }
2535
2536 return 0;
2537}
2538
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302539static int ci13xxx_wakeup(struct usb_gadget *_gadget)
2540{
2541 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2542 unsigned long flags;
2543 int ret = 0;
2544
2545 trace();
2546
Alexander Shishkind3595d12012-05-08 23:28:58 +03002547 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302548 if (!udc->remote_wakeup) {
2549 ret = -EOPNOTSUPP;
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002550 trace("remote wakeup feature is not enabled\n");
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302551 goto out;
2552 }
Alexander Shishkin262c1632012-05-08 23:28:59 +03002553 if (!hw_read(udc, OP_PORTSC, PORTSC_SUSP)) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302554 ret = -EINVAL;
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002555 trace("port is not suspended\n");
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302556 goto out;
2557 }
Alexander Shishkin262c1632012-05-08 23:28:59 +03002558 hw_write(udc, OP_PORTSC, PORTSC_FPR, PORTSC_FPR);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302559out:
Alexander Shishkind3595d12012-05-08 23:28:58 +03002560 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302561 return ret;
2562}
2563
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302564static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
2565{
2566 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2567
2568 if (udc->transceiver)
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002569 return usb_phy_set_power(udc->transceiver, mA);
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302570 return -ENOTSUPP;
2571}
2572
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002573static int ci13xxx_start(struct usb_gadget_driver *driver,
2574 int (*bind)(struct usb_gadget *));
2575static int ci13xxx_stop(struct usb_gadget_driver *driver);
David Lopoaa69a802008-11-17 14:14:51 -08002576/**
2577 * Device operations part of the API to the USB controller hardware,
2578 * which don't involve endpoints (or i/o)
2579 * Check "usb_gadget.h" for details
2580 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302581static const struct usb_gadget_ops usb_gadget_ops = {
2582 .vbus_session = ci13xxx_vbus_session,
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302583 .wakeup = ci13xxx_wakeup,
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302584 .vbus_draw = ci13xxx_vbus_draw,
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002585 .start = ci13xxx_start,
2586 .stop = ci13xxx_stop,
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302587};
David Lopoaa69a802008-11-17 14:14:51 -08002588
2589/**
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002590 * ci13xxx_start: register a gadget driver
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002591 * @driver: the driver being registered
2592 * @bind: the driver's bind callback
David Lopoaa69a802008-11-17 14:14:51 -08002593 *
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002594 * Check ci13xxx_start() at <linux/usb/gadget.h> for details.
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002595 * Interrupts are enabled here.
David Lopoaa69a802008-11-17 14:14:51 -08002596 */
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002597static int ci13xxx_start(struct usb_gadget_driver *driver,
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002598 int (*bind)(struct usb_gadget *))
David Lopoaa69a802008-11-17 14:14:51 -08002599{
2600 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302601 unsigned long flags;
2602 int i, j;
David Lopoaa69a802008-11-17 14:14:51 -08002603 int retval = -ENOMEM;
2604
2605 trace("%p", driver);
2606
2607 if (driver == NULL ||
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002608 bind == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002609 driver->setup == NULL ||
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002610 driver->disconnect == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002611 return -EINVAL;
2612 else if (udc == NULL)
2613 return -ENODEV;
2614 else if (udc->driver != NULL)
2615 return -EBUSY;
2616
2617 /* alloc resources */
2618 udc->qh_pool = dma_pool_create("ci13xxx_qh", &udc->gadget.dev,
2619 sizeof(struct ci13xxx_qh),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002620 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002621 if (udc->qh_pool == NULL)
2622 return -ENOMEM;
2623
2624 udc->td_pool = dma_pool_create("ci13xxx_td", &udc->gadget.dev,
2625 sizeof(struct ci13xxx_td),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002626 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002627 if (udc->td_pool == NULL) {
2628 dma_pool_destroy(udc->qh_pool);
2629 udc->qh_pool = NULL;
2630 return -ENOMEM;
2631 }
2632
Alexander Shishkind3595d12012-05-08 23:28:58 +03002633 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002634
Alexander Shishkind3595d12012-05-08 23:28:58 +03002635 info("hw_ep_max = %d", udc->hw_ep_max);
David Lopoaa69a802008-11-17 14:14:51 -08002636
David Lopoaa69a802008-11-17 14:14:51 -08002637 udc->gadget.dev.driver = NULL;
2638
2639 retval = 0;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002640 for (i = 0; i < udc->hw_ep_max/2; i++) {
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302641 for (j = RX; j <= TX; j++) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002642 int k = i + j * udc->hw_ep_max/2;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302643 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k];
David Lopoaa69a802008-11-17 14:14:51 -08002644
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302645 scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i,
2646 (j == TX) ? "in" : "out");
David Lopoaa69a802008-11-17 14:14:51 -08002647
Alexander Shishkind3595d12012-05-08 23:28:58 +03002648 mEp->udc = udc;
2649 mEp->lock = &udc->lock;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302650 mEp->device = &udc->gadget.dev;
2651 mEp->td_pool = udc->td_pool;
David Lopoaa69a802008-11-17 14:14:51 -08002652
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302653 mEp->ep.name = mEp->name;
2654 mEp->ep.ops = &usb_ep_ops;
2655 mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
David Lopoaa69a802008-11-17 14:14:51 -08002656
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302657 INIT_LIST_HEAD(&mEp->qh.queue);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002658 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302659 mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL,
2660 &mEp->qh.dma);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002661 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302662 if (mEp->qh.ptr == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002663 retval = -ENOMEM;
2664 else
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302665 memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr));
2666
Alexander Shishkind36ade62012-05-04 16:47:15 +03002667 /*
2668 * set up shorthands for ep0 out and in endpoints,
2669 * don't add to gadget's ep_list
2670 */
2671 if (i == 0) {
2672 if (j == RX)
2673 udc->ep0out = mEp;
2674 else
2675 udc->ep0in = mEp;
2676
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302677 continue;
Alexander Shishkind36ade62012-05-04 16:47:15 +03002678 }
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302679
David Lopoaa69a802008-11-17 14:14:51 -08002680 list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302681 }
David Lopoaa69a802008-11-17 14:14:51 -08002682 }
2683 if (retval)
2684 goto done;
Alexander Shishkind36ade62012-05-04 16:47:15 +03002685
Alexander Shishkind3595d12012-05-08 23:28:58 +03002686 spin_unlock_irqrestore(&udc->lock, flags);
Alexander Shishkind36ade62012-05-04 16:47:15 +03002687 udc->ep0out->ep.desc = &ctrl_endpt_out_desc;
2688 retval = usb_ep_enable(&udc->ep0out->ep);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302689 if (retval)
2690 return retval;
Felipe Balbi877c1f52011-06-29 16:41:57 +03002691
Alexander Shishkind36ade62012-05-04 16:47:15 +03002692 udc->ep0in->ep.desc = &ctrl_endpt_in_desc;
2693 retval = usb_ep_enable(&udc->ep0in->ep);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302694 if (retval)
2695 return retval;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002696 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002697
Alexander Shishkind36ade62012-05-04 16:47:15 +03002698 udc->gadget.ep0 = &udc->ep0in->ep;
David Lopoaa69a802008-11-17 14:14:51 -08002699 /* bind gadget */
2700 driver->driver.bus = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002701 udc->gadget.dev.driver = &driver->driver;
2702
Alexander Shishkind3595d12012-05-08 23:28:58 +03002703 spin_unlock_irqrestore(&udc->lock, flags);
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002704 retval = bind(&udc->gadget); /* MAY SLEEP */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002705 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002706
2707 if (retval) {
David Lopoaa69a802008-11-17 14:14:51 -08002708 udc->gadget.dev.driver = NULL;
2709 goto done;
2710 }
2711
Pavankumar Kondeti49d3df52011-01-11 09:19:21 +05302712 udc->driver = driver;
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302713 pm_runtime_get_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302714 if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) {
2715 if (udc->vbus_active) {
2716 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED)
2717 hw_device_reset(udc);
2718 } else {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302719 pm_runtime_put_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302720 goto done;
2721 }
2722 }
2723
Alexander Shishkind3595d12012-05-08 23:28:58 +03002724 retval = hw_device_state(udc, udc->ep0out->qh.dma);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302725 if (retval)
2726 pm_runtime_put_sync(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002727
2728 done:
Alexander Shishkind3595d12012-05-08 23:28:58 +03002729 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002730 return retval;
2731}
David Lopoaa69a802008-11-17 14:14:51 -08002732
2733/**
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002734 * ci13xxx_stop: unregister a gadget driver
David Lopoaa69a802008-11-17 14:14:51 -08002735 *
2736 * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
2737 */
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002738static int ci13xxx_stop(struct usb_gadget_driver *driver)
David Lopoaa69a802008-11-17 14:14:51 -08002739{
2740 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302741 unsigned long i, flags;
David Lopoaa69a802008-11-17 14:14:51 -08002742
2743 trace("%p", driver);
2744
2745 if (driver == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002746 driver->unbind == NULL ||
2747 driver->setup == NULL ||
2748 driver->disconnect == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002749 driver != udc->driver)
2750 return -EINVAL;
2751
Alexander Shishkind3595d12012-05-08 23:28:58 +03002752 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002753
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302754 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) ||
2755 udc->vbus_active) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002756 hw_device_state(udc, 0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302757 if (udc->udc_driver->notify_event)
2758 udc->udc_driver->notify_event(udc,
2759 CI13XXX_CONTROLLER_STOPPED_EVENT);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002760 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302761 _gadget_stop_activity(&udc->gadget);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002762 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302763 pm_runtime_put(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302764 }
David Lopoaa69a802008-11-17 14:14:51 -08002765
2766 /* unbind gadget */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002767 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302768 driver->unbind(&udc->gadget); /* MAY SLEEP */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002769 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002770
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302771 udc->gadget.dev.driver = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002772
2773 /* free resources */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002774 for (i = 0; i < udc->hw_ep_max; i++) {
David Lopoaa69a802008-11-17 14:14:51 -08002775 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
2776
Alexander Shishkinefa015b2012-05-04 16:47:14 +03002777 if (mEp->num)
David Lopoaa69a802008-11-17 14:14:51 -08002778 list_del_init(&mEp->ep.ep_list);
2779
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302780 if (mEp->qh.ptr != NULL)
2781 dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08002782 }
2783
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302784 udc->gadget.ep0 = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002785 udc->driver = NULL;
2786
Alexander Shishkind3595d12012-05-08 23:28:58 +03002787 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002788
2789 if (udc->td_pool != NULL) {
2790 dma_pool_destroy(udc->td_pool);
2791 udc->td_pool = NULL;
2792 }
2793 if (udc->qh_pool != NULL) {
2794 dma_pool_destroy(udc->qh_pool);
2795 udc->qh_pool = NULL;
2796 }
2797
2798 return 0;
2799}
David Lopoaa69a802008-11-17 14:14:51 -08002800
2801/******************************************************************************
2802 * BUS block
2803 *****************************************************************************/
2804/**
2805 * udc_irq: global interrupt handler
2806 *
2807 * This function returns IRQ_HANDLED if the IRQ has been handled
2808 * It locks access to registers
2809 */
Alexander Shishkin62bb84e2012-05-08 23:29:01 +03002810static irqreturn_t udc_irq(int irq, void *data)
David Lopoaa69a802008-11-17 14:14:51 -08002811{
2812 struct ci13xxx *udc = _udc;
2813 irqreturn_t retval;
2814 u32 intr;
2815
2816 trace();
2817
2818 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002819 pr_err("ENODEV\n");
David Lopoaa69a802008-11-17 14:14:51 -08002820 return IRQ_HANDLED;
2821 }
2822
Alexander Shishkind3595d12012-05-08 23:28:58 +03002823 spin_lock(&udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302824
2825 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) {
Alexander Shishkin262c1632012-05-08 23:28:59 +03002826 if (hw_read(udc, OP_USBMODE, USBMODE_CM) !=
2827 USBMODE_CM_DEVICE) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002828 spin_unlock(&udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302829 return IRQ_NONE;
2830 }
2831 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03002832 intr = hw_test_and_clear_intr_active(udc);
David Lopoaa69a802008-11-17 14:14:51 -08002833 if (intr) {
2834 isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr;
2835 isr_statistics.hndl.idx &= ISR_MASK;
2836 isr_statistics.hndl.cnt++;
2837
2838 /* order defines priority - do NOT change it */
2839 if (USBi_URI & intr) {
2840 isr_statistics.uri++;
2841 isr_reset_handler(udc);
2842 }
2843 if (USBi_PCI & intr) {
2844 isr_statistics.pci++;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002845 udc->gadget.speed = hw_port_is_high_speed(udc) ?
David Lopoaa69a802008-11-17 14:14:51 -08002846 USB_SPEED_HIGH : USB_SPEED_FULL;
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002847 if (udc->suspended && udc->driver->resume) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002848 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302849 udc->driver->resume(&udc->gadget);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002850 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302851 udc->suspended = 0;
2852 }
David Lopoaa69a802008-11-17 14:14:51 -08002853 }
2854 if (USBi_UEI & intr)
2855 isr_statistics.uei++;
2856 if (USBi_UI & intr) {
2857 isr_statistics.ui++;
2858 isr_tr_complete_handler(udc);
2859 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302860 if (USBi_SLI & intr) {
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002861 if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
2862 udc->driver->suspend) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302863 udc->suspended = 1;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002864 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302865 udc->driver->suspend(&udc->gadget);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002866 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302867 }
David Lopoaa69a802008-11-17 14:14:51 -08002868 isr_statistics.sli++;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302869 }
David Lopoaa69a802008-11-17 14:14:51 -08002870 retval = IRQ_HANDLED;
2871 } else {
2872 isr_statistics.none++;
2873 retval = IRQ_NONE;
2874 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03002875 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002876
2877 return retval;
2878}
2879
2880/**
2881 * udc_release: driver release function
2882 * @dev: device
2883 *
2884 * Currently does nothing
2885 */
2886static void udc_release(struct device *dev)
2887{
2888 trace("%p", dev);
2889
2890 if (dev == NULL)
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002891 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08002892}
2893
2894/**
2895 * udc_probe: parent probe must call this to initialize UDC
2896 * @dev: parent device
2897 * @regs: registers base address
2898 * @name: driver name
2899 *
2900 * This function returns an error code
2901 * No interrupts active, the IRQ has not been requested yet
2902 * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask
2903 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302904static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
Alexander Shishkin62bb84e2012-05-08 23:29:01 +03002905 void __iomem *regs)
David Lopoaa69a802008-11-17 14:14:51 -08002906{
2907 struct ci13xxx *udc;
2908 int retval = 0;
2909
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002910 trace("%p, %p, %p", dev, regs, driver->name);
David Lopoaa69a802008-11-17 14:14:51 -08002911
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302912 if (dev == NULL || regs == NULL || driver == NULL ||
2913 driver->name == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002914 return -EINVAL;
2915
2916 udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL);
2917 if (udc == NULL)
2918 return -ENOMEM;
2919
Alexander Shishkind3595d12012-05-08 23:28:58 +03002920 spin_lock_init(&udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302921 udc->regs = regs;
2922 udc->udc_driver = driver;
David Lopoaa69a802008-11-17 14:14:51 -08002923
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302924 udc->gadget.ops = &usb_gadget_ops;
David Lopoaa69a802008-11-17 14:14:51 -08002925 udc->gadget.speed = USB_SPEED_UNKNOWN;
Michal Nazarewiczd327ab52011-11-19 18:27:37 +01002926 udc->gadget.max_speed = USB_SPEED_HIGH;
David Lopoaa69a802008-11-17 14:14:51 -08002927 udc->gadget.is_otg = 0;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302928 udc->gadget.name = driver->name;
David Lopoaa69a802008-11-17 14:14:51 -08002929
2930 INIT_LIST_HEAD(&udc->gadget.ep_list);
2931 udc->gadget.ep0 = NULL;
2932
Kay Sievers5df585242009-03-24 16:38:23 -07002933 dev_set_name(&udc->gadget.dev, "gadget");
David Lopoaa69a802008-11-17 14:14:51 -08002934 udc->gadget.dev.dma_mask = dev->dma_mask;
Pavankumar Kondeti61948ee2010-12-07 17:54:01 +05302935 udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask;
David Lopoaa69a802008-11-17 14:14:51 -08002936 udc->gadget.dev.parent = dev;
2937 udc->gadget.dev.release = udc_release;
2938
Alexander Shishkin62bb84e2012-05-08 23:29:01 +03002939 retval = hw_device_init(udc, regs, driver->capoffset);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302940 if (retval < 0)
2941 goto free_udc;
2942
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002943 udc->transceiver = usb_get_transceiver();
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302944
2945 if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
2946 if (udc->transceiver == NULL) {
2947 retval = -ENODEV;
2948 goto free_udc;
2949 }
2950 }
2951
2952 if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) {
2953 retval = hw_device_reset(udc);
2954 if (retval)
2955 goto put_transceiver;
2956 }
2957
David Lopoaa69a802008-11-17 14:14:51 -08002958 retval = device_register(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302959 if (retval) {
2960 put_device(&udc->gadget.dev);
2961 goto put_transceiver;
2962 }
David Lopoaa69a802008-11-17 14:14:51 -08002963
2964#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2965 retval = dbg_create_files(&udc->gadget.dev);
2966#endif
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302967 if (retval)
2968 goto unreg_device;
2969
2970 if (udc->transceiver) {
Heikki Krogerus6e13c652012-02-13 13:24:20 +02002971 retval = otg_set_peripheral(udc->transceiver->otg,
2972 &udc->gadget);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302973 if (retval)
2974 goto remove_dbg;
David Lopoaa69a802008-11-17 14:14:51 -08002975 }
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002976
2977 retval = usb_add_gadget_udc(dev, &udc->gadget);
2978 if (retval)
2979 goto remove_trans;
2980
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302981 pm_runtime_no_callbacks(&udc->gadget.dev);
2982 pm_runtime_enable(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002983
2984 _udc = udc;
2985 return retval;
2986
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002987remove_trans:
2988 if (udc->transceiver) {
Heikki Krogerus6e13c652012-02-13 13:24:20 +02002989 otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002990 usb_put_transceiver(udc->transceiver);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002991 }
2992
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002993 dev_err(dev, "error = %i\n", retval);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302994remove_dbg:
2995#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2996 dbg_remove_files(&udc->gadget.dev);
2997#endif
2998unreg_device:
2999 device_unregister(&udc->gadget.dev);
3000put_transceiver:
3001 if (udc->transceiver)
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02003002 usb_put_transceiver(udc->transceiver);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303003free_udc:
David Lopoaa69a802008-11-17 14:14:51 -08003004 kfree(udc);
3005 _udc = NULL;
3006 return retval;
3007}
3008
3009/**
3010 * udc_remove: parent remove must call this to remove UDC
3011 *
3012 * No interrupts active, the IRQ has been released
3013 */
3014static void udc_remove(void)
3015{
3016 struct ci13xxx *udc = _udc;
3017
3018 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07003019 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08003020 return;
3021 }
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03003022 usb_del_gadget_udc(&udc->gadget);
David Lopoaa69a802008-11-17 14:14:51 -08003023
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303024 if (udc->transceiver) {
Heikki Krogerus6e13c652012-02-13 13:24:20 +02003025 otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02003026 usb_put_transceiver(udc->transceiver);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05303027 }
David Lopoaa69a802008-11-17 14:14:51 -08003028#ifdef CONFIG_USB_GADGET_DEBUG_FILES
3029 dbg_remove_files(&udc->gadget.dev);
3030#endif
3031 device_unregister(&udc->gadget.dev);
3032
Alexander Shishkin262c1632012-05-08 23:28:59 +03003033 kfree(udc->hw_bank.regmap);
David Lopoaa69a802008-11-17 14:14:51 -08003034 kfree(udc);
3035 _udc = NULL;
3036}
Alexander Shishkin62bb84e2012-05-08 23:29:01 +03003037
3038static int __devinit ci_udc_probe(struct platform_device *pdev)
3039{
3040 struct device *dev = &pdev->dev;
3041 struct ci13xxx_udc_driver *driver = dev->platform_data;
3042 struct resource *res;
3043 void __iomem *base;
3044 int ret;
3045
3046 if (!driver) {
3047 dev_err(dev, "platform data missing\n");
3048 return -ENODEV;
3049 }
3050
3051 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
3052 if (!res) {
3053 dev_err(dev, "missing resource\n");
3054 return -ENODEV;
3055 }
3056
3057 base = devm_request_and_ioremap(dev, res);
3058 if (!res) {
3059 dev_err(dev, "can't request and ioremap resource\n");
3060 return -ENOMEM;
3061 }
3062
3063 ret = udc_probe(driver, dev, base);
3064 if (ret)
3065 return ret;
3066
3067 _udc->irq = platform_get_irq(pdev, 0);
3068 if (_udc->irq < 0) {
3069 dev_err(dev, "missing IRQ\n");
3070 ret = -ENODEV;
3071 goto out;
3072 }
3073
3074 ret = request_irq(_udc->irq, udc_irq, IRQF_SHARED, driver->name, _udc);
3075
3076out:
3077 if (ret)
3078 udc_remove();
3079
3080 return ret;
3081}
3082
3083static int __devexit ci_udc_remove(struct platform_device *pdev)
3084{
3085 free_irq(_udc->irq, _udc);
3086 udc_remove();
3087
3088 return 0;
3089}
3090
3091static struct platform_driver ci_udc_driver = {
3092 .probe = ci_udc_probe,
3093 .remove = __devexit_p(ci_udc_remove),
3094 .driver = {
3095 .name = "ci_udc",
3096 },
3097};
3098
3099module_platform_driver(ci_udc_driver);
3100
3101MODULE_ALIAS("platform:ci_udc");
3102MODULE_ALIAS("platform:ci13xxx");
3103MODULE_LICENSE("GPL v2");
3104MODULE_AUTHOR("David Lopo <dlopo@chipidea.mips.com>");
3105MODULE_DESCRIPTION("ChipIdea UDC Driver");