blob: 02739707aabcc5b1cba69fa04dd27e6608318b76 [file] [log] [blame]
David Lopoaa69a802008-11-17 14:14:51 -08001/*
2 * ci13xxx_udc.c - MIPS USB IP core family device controller
3 *
4 * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved.
5 *
6 * Author: David Lopo
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13/*
14 * Description: MIPS USB IP core family device controller
15 * Currently it only supports IP part number CI13412
16 *
17 * This driver is composed of several blocks:
18 * - HW: hardware interface
19 * - DBG: debug facilities (optional)
20 * - UTIL: utilities
21 * - ISR: interrupts handling
22 * - ENDPT: endpoint operations (Gadget API)
23 * - GADGET: gadget operations (Gadget API)
24 * - BUS: bus glue code, bus abstraction layer
David Lopoaa69a802008-11-17 14:14:51 -080025 *
26 * Compile Options
27 * - CONFIG_USB_GADGET_DEBUG_FILES: enable debug facilities
28 * - STALL_IN: non-empty bulk-in pipes cannot be halted
29 * if defined mass storage compliance succeeds but with warnings
30 * => case 4: Hi > Dn
31 * => case 5: Hi > Di
32 * => case 8: Hi <> Do
33 * if undefined usbtest 13 fails
34 * - TRACE: enable function tracing (depends on DEBUG)
35 *
36 * Main Features
37 * - Chapter 9 & Mass Storage Compliance with Gadget File Storage
38 * - Chapter 9 Compliance with Gadget Zero (STALL_IN undefined)
39 * - Normal & LPM support
40 *
41 * USBTEST Report
42 * - OK: 0-12, 13 (STALL_IN defined) & 14
43 * - Not Supported: 15 & 16 (ISO)
44 *
45 * TODO List
46 * - OTG
47 * - Isochronous & Interrupt Traffic
48 * - Handle requests which spawns into several TDs
49 * - GET_STATUS(device) - always reports 0
50 * - Gadget API (majority of optional features)
51 * - Suspend & Remote Wakeup
52 */
Matthias Kaehlcke36825a22009-04-15 22:28:36 +020053#include <linux/delay.h>
David Lopoaa69a802008-11-17 14:14:51 -080054#include <linux/device.h>
55#include <linux/dmapool.h>
56#include <linux/dma-mapping.h>
57#include <linux/init.h>
58#include <linux/interrupt.h>
David Lopoaa69a802008-11-17 14:14:51 -080059#include <linux/io.h>
60#include <linux/irq.h>
61#include <linux/kernel.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090062#include <linux/slab.h>
Pavankumar Kondetic0360192010-12-07 17:54:04 +053063#include <linux/pm_runtime.h>
David Lopoaa69a802008-11-17 14:14:51 -080064#include <linux/usb/ch9.h>
65#include <linux/usb/gadget.h>
Pavankumar Kondetif01ef572010-12-07 17:54:02 +053066#include <linux/usb/otg.h>
David Lopoaa69a802008-11-17 14:14:51 -080067
68#include "ci13xxx_udc.h"
69
70
71/******************************************************************************
72 * DEFINE
73 *****************************************************************************/
Michael Grzeschik954aad82011-10-10 18:38:06 +020074
75#define DMA_ADDR_INVALID (~(dma_addr_t)0)
76
David Lopoaa69a802008-11-17 14:14:51 -080077/* control endpoint description */
78static const struct usb_endpoint_descriptor
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053079ctrl_endpt_out_desc = {
David Lopoaa69a802008-11-17 14:14:51 -080080 .bLength = USB_DT_ENDPOINT_SIZE,
81 .bDescriptorType = USB_DT_ENDPOINT,
82
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +053083 .bEndpointAddress = USB_DIR_OUT,
84 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
85 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
86};
87
88static const struct usb_endpoint_descriptor
89ctrl_endpt_in_desc = {
90 .bLength = USB_DT_ENDPOINT_SIZE,
91 .bDescriptorType = USB_DT_ENDPOINT,
92
93 .bEndpointAddress = USB_DIR_IN,
David Lopoaa69a802008-11-17 14:14:51 -080094 .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
95 .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX),
96};
97
98/* UDC descriptor */
99static struct ci13xxx *_udc;
100
101/* Interrupt statistics */
102#define ISR_MASK 0x1F
103static struct {
104 u32 test;
105 u32 ui;
106 u32 uei;
107 u32 pci;
108 u32 uri;
109 u32 sli;
110 u32 none;
111 struct {
112 u32 cnt;
113 u32 buf[ISR_MASK+1];
114 u32 idx;
115 } hndl;
116} isr_statistics;
117
118/**
119 * ffs_nr: find first (least significant) bit set
120 * @x: the word to search
121 *
122 * This function returns bit number (instead of position)
123 */
124static int ffs_nr(u32 x)
125{
126 int n = ffs(x);
127
128 return n ? n-1 : 32;
129}
130
131/******************************************************************************
132 * HW block
133 *****************************************************************************/
David Lopoaa69a802008-11-17 14:14:51 -0800134
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530135/* MSM specific */
136#define ABS_AHBBURST (0x0090UL)
137#define ABS_AHBMODE (0x0098UL)
David Lopoaa69a802008-11-17 14:14:51 -0800138/* UDC register map */
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300139#define CAP_CAPLENGTH (0x000UL)
140#define CAP_HCCPARAMS (0x008UL)
141#define CAP_DCCPARAMS (0x024UL)
Alexander Shishkind3595d12012-05-08 23:28:58 +0300142#define ABS_TESTMODE (udc->hw_bank.lpm ? 0x0FCUL : 0x138UL)
David Lopoaa69a802008-11-17 14:14:51 -0800143/* offset to CAPLENTGH (addr + data) */
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300144#define OP_USBCMD (0x000UL)
145#define OP_USBSTS (0x004UL)
146#define OP_USBINTR (0x008UL)
147#define OP_DEVICEADDR (0x014UL)
148#define OP_ENDPTLISTADDR (0x018UL)
149#define OP_PORTSC (0x044UL)
150#define OP_DEVLC (0x084UL)
Alexander Shishkind3595d12012-05-08 23:28:58 +0300151#define OP_USBMODE (udc->hw_bank.lpm ? 0x0C8UL : 0x068UL)
152#define OP_ENDPTSETUPSTAT (udc->hw_bank.lpm ? 0x0D8UL : 0x06CUL)
153#define OP_ENDPTPRIME (udc->hw_bank.lpm ? 0x0DCUL : 0x070UL)
154#define OP_ENDPTFLUSH (udc->hw_bank.lpm ? 0x0E0UL : 0x074UL)
155#define OP_ENDPTSTAT (udc->hw_bank.lpm ? 0x0E4UL : 0x078UL)
156#define OP_ENDPTCOMPLETE (udc->hw_bank.lpm ? 0x0E8UL : 0x07CUL)
157#define OP_ENDPTCTRL (udc->hw_bank.lpm ? 0x0ECUL : 0x080UL)
158#define OP_LAST (udc->hw_bank.lpm ? 0x12CUL : 0x0C0UL)
David Lopoaa69a802008-11-17 14:14:51 -0800159
160/**
161 * hw_ep_bit: calculates the bit number
162 * @num: endpoint number
163 * @dir: endpoint direction
164 *
165 * This function returns bit number
166 */
167static inline int hw_ep_bit(int num, int dir)
168{
169 return num + (dir ? 16 : 0);
170}
171
Alexander Shishkind3595d12012-05-08 23:28:58 +0300172static int ep_to_bit(struct ci13xxx *udc, int n)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200173{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300174 int fill = 16 - udc->hw_ep_max / 2;
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200175
Alexander Shishkind3595d12012-05-08 23:28:58 +0300176 if (n >= udc->hw_ep_max / 2)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200177 n += fill;
178
179 return n;
180}
181
David Lopoaa69a802008-11-17 14:14:51 -0800182/**
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300183 * hw_read: reads from a register bitfield
184 * @base: register block address
185 * @addr: address relative to operational register base
David Lopoaa69a802008-11-17 14:14:51 -0800186 * @mask: bitfield mask
187 *
188 * This function returns register bitfield data
189 */
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300190static u32 hw_read(void __iomem *base, u32 addr, u32 mask)
David Lopoaa69a802008-11-17 14:14:51 -0800191{
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300192 return ioread32(addr + base) & mask;
David Lopoaa69a802008-11-17 14:14:51 -0800193}
194
195/**
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300196 * hw_write: writes to a register bitfield
197 * @base: register block address
198 * @addr: address relative to operational register base
David Lopoaa69a802008-11-17 14:14:51 -0800199 * @mask: bitfield mask
200 * @data: new data
201 */
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300202static void hw_write(void __iomem *base, u32 addr, u32 mask, u32 data)
David Lopoaa69a802008-11-17 14:14:51 -0800203{
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300204 iowrite32(hw_read(base, addr, ~mask) | (data & mask),
205 addr + base);
David Lopoaa69a802008-11-17 14:14:51 -0800206}
207
208/**
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300209 * hw_test_and_clear: tests & clears operational register bitfield
210 * @base: register block address
211 * @addr: address relative to operational register base
David Lopoaa69a802008-11-17 14:14:51 -0800212 * @mask: bitfield mask
213 *
214 * This function returns register bitfield data
215 */
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300216static u32 hw_test_and_clear(void __iomem *base, u32 addr, u32 mask)
David Lopoaa69a802008-11-17 14:14:51 -0800217{
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300218 u32 reg = hw_read(base, addr, mask);
David Lopoaa69a802008-11-17 14:14:51 -0800219
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300220 iowrite32(reg, addr + base);
David Lopoaa69a802008-11-17 14:14:51 -0800221 return reg;
222}
223
224/**
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300225 * hw_test_and_write: tests & writes operational register bitfield
226 * @base: register block address
227 * @addr: address relative to operational register base
David Lopoaa69a802008-11-17 14:14:51 -0800228 * @mask: bitfield mask
229 * @data: new data
230 *
231 * This function returns register bitfield data
232 */
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300233static u32 hw_test_and_write(void __iomem *base, u32 addr, u32 mask, u32 data)
David Lopoaa69a802008-11-17 14:14:51 -0800234{
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300235 u32 reg = hw_read(base, addr, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800236
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300237 iowrite32((reg & ~mask) | (data & mask), addr + base);
David Lopoaa69a802008-11-17 14:14:51 -0800238 return (reg & mask) >> ffs_nr(mask);
239}
240
Alexander Shishkind3595d12012-05-08 23:28:58 +0300241static int hw_device_init(struct ci13xxx *udc, void __iomem *base,
242 uintptr_t cap_offset)
David Lopoaa69a802008-11-17 14:14:51 -0800243{
244 u32 reg;
245
246 /* bank is a module variable */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300247 udc->hw_bank.abs = base;
David Lopoaa69a802008-11-17 14:14:51 -0800248
Alexander Shishkind3595d12012-05-08 23:28:58 +0300249 udc->hw_bank.cap = udc->hw_bank.abs;
250 udc->hw_bank.cap += cap_offset;
251 udc->hw_bank.op = udc->hw_bank.cap + ioread8(udc->hw_bank.cap);
David Lopoaa69a802008-11-17 14:14:51 -0800252
Alexander Shishkind3595d12012-05-08 23:28:58 +0300253 reg = hw_read(udc->hw_bank.cap, CAP_HCCPARAMS, HCCPARAMS_LEN) >>
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300254 ffs_nr(HCCPARAMS_LEN);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300255 udc->hw_bank.lpm = reg;
256 udc->hw_bank.size = udc->hw_bank.op - udc->hw_bank.abs;
257 udc->hw_bank.size += OP_LAST;
258 udc->hw_bank.size /= sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -0800259
Alexander Shishkind3595d12012-05-08 23:28:58 +0300260 reg = hw_read(udc->hw_bank.cap, CAP_DCCPARAMS, DCCPARAMS_DEN) >>
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300261 ffs_nr(DCCPARAMS_DEN);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300262 udc->hw_ep_max = reg * 2; /* cache hw ENDPT_MAX */
David Lopoaa69a802008-11-17 14:14:51 -0800263
Alexander Shishkind3595d12012-05-08 23:28:58 +0300264 if (udc->hw_ep_max == 0 || udc->hw_ep_max > ENDPT_MAX)
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +0530265 return -ENODEV;
David Lopoaa69a802008-11-17 14:14:51 -0800266
267 /* setup lock mode ? */
268
269 /* ENDPTSETUPSTAT is '0' by default */
270
271 /* HCSPARAMS.bf.ppc SHOULD BE zero for device */
272
273 return 0;
274}
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530275/**
276 * hw_device_reset: resets chip (execute without interruption)
277 * @base: register base address
278 *
279 * This function returns an error code
280 */
281static int hw_device_reset(struct ci13xxx *udc)
282{
283 /* should flush & stop before reset */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300284 hw_write(udc->hw_bank.op, OP_ENDPTFLUSH, ~0, ~0);
285 hw_write(udc->hw_bank.op, OP_USBCMD, USBCMD_RS, 0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530286
Alexander Shishkind3595d12012-05-08 23:28:58 +0300287 hw_write(udc->hw_bank.op, OP_USBCMD, USBCMD_RST, USBCMD_RST);
288 while (hw_read(udc->hw_bank.op, OP_USBCMD, USBCMD_RST))
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530289 udelay(10); /* not RTOS friendly */
290
291
292 if (udc->udc_driver->notify_event)
293 udc->udc_driver->notify_event(udc,
294 CI13XXX_CONTROLLER_RESET_EVENT);
295
Pavankumar Kondeti8c2387a2011-05-02 11:56:28 +0530296 if (udc->udc_driver->flags & CI13XXX_DISABLE_STREAMING)
Alexander Shishkind3595d12012-05-08 23:28:58 +0300297 hw_write(udc->hw_bank.op, OP_USBMODE, USBMODE_SDIS,
298 USBMODE_SDIS);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530299
300 /* USBMODE should be configured step by step */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300301 hw_write(udc->hw_bank.op, OP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE);
302 hw_write(udc->hw_bank.op, OP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE);
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300303 /* HW >= 2.3 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300304 hw_write(udc->hw_bank.op, OP_USBMODE, USBMODE_SLOM, USBMODE_SLOM);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530305
Alexander Shishkind3595d12012-05-08 23:28:58 +0300306 if (hw_read(udc->hw_bank.op, OP_USBMODE, USBMODE_CM) !=
307 USBMODE_CM_DEVICE) {
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530308 pr_err("cannot enter in device mode");
Alexander Shishkind3595d12012-05-08 23:28:58 +0300309 pr_err("lpm = %i", udc->hw_bank.lpm);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +0530310 return -ENODEV;
311 }
312
313 return 0;
314}
David Lopoaa69a802008-11-17 14:14:51 -0800315
316/**
317 * hw_device_state: enables/disables interrupts & starts/stops device (execute
318 * without interruption)
319 * @dma: 0 => disable, !0 => enable and set dma engine
320 *
321 * This function returns an error code
322 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300323static int hw_device_state(struct ci13xxx *udc, u32 dma)
David Lopoaa69a802008-11-17 14:14:51 -0800324{
325 if (dma) {
Alexander Shishkind3595d12012-05-08 23:28:58 +0300326 hw_write(udc->hw_bank.op, OP_ENDPTLISTADDR, ~0, dma);
David Lopoaa69a802008-11-17 14:14:51 -0800327 /* interrupt, error, port change, reset, sleep/suspend */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300328 hw_write(udc->hw_bank.op, OP_USBINTR, ~0,
David Lopoaa69a802008-11-17 14:14:51 -0800329 USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI);
Alexander Shishkind3595d12012-05-08 23:28:58 +0300330 hw_write(udc->hw_bank.op, OP_USBCMD, USBCMD_RS, USBCMD_RS);
David Lopoaa69a802008-11-17 14:14:51 -0800331 } else {
Alexander Shishkind3595d12012-05-08 23:28:58 +0300332 hw_write(udc->hw_bank.op, OP_USBCMD, USBCMD_RS, 0);
333 hw_write(udc->hw_bank.op, OP_USBINTR, ~0, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800334 }
335 return 0;
336}
337
338/**
339 * hw_ep_flush: flush endpoint fifo (execute without interruption)
340 * @num: endpoint number
341 * @dir: endpoint direction
342 *
343 * This function returns an error code
344 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300345static int hw_ep_flush(struct ci13xxx *udc, int num, int dir)
David Lopoaa69a802008-11-17 14:14:51 -0800346{
347 int n = hw_ep_bit(num, dir);
348
349 do {
350 /* flush any pending transfer */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300351 hw_write(udc->hw_bank.op, OP_ENDPTFLUSH, BIT(n), BIT(n));
352 while (hw_read(udc->hw_bank.op, OP_ENDPTFLUSH, BIT(n)))
David Lopoaa69a802008-11-17 14:14:51 -0800353 cpu_relax();
Alexander Shishkind3595d12012-05-08 23:28:58 +0300354 } while (hw_read(udc->hw_bank.op, OP_ENDPTSTAT, BIT(n)));
David Lopoaa69a802008-11-17 14:14:51 -0800355
356 return 0;
357}
358
359/**
360 * hw_ep_disable: disables endpoint (execute without interruption)
361 * @num: endpoint number
362 * @dir: endpoint direction
363 *
364 * This function returns an error code
365 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300366static int hw_ep_disable(struct ci13xxx *udc, int num, int dir)
David Lopoaa69a802008-11-17 14:14:51 -0800367{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300368 hw_ep_flush(udc, num, dir);
369 hw_write(udc->hw_bank.op, OP_ENDPTCTRL + num * sizeof(u32),
370 dir ? ENDPTCTRL_TXE : ENDPTCTRL_RXE, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800371 return 0;
372}
373
374/**
375 * hw_ep_enable: enables endpoint (execute without interruption)
376 * @num: endpoint number
377 * @dir: endpoint direction
378 * @type: endpoint type
379 *
380 * This function returns an error code
381 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300382static int hw_ep_enable(struct ci13xxx *udc, int num, int dir, int type)
David Lopoaa69a802008-11-17 14:14:51 -0800383{
384 u32 mask, data;
385
386 if (dir) {
387 mask = ENDPTCTRL_TXT; /* type */
388 data = type << ffs_nr(mask);
389
390 mask |= ENDPTCTRL_TXS; /* unstall */
391 mask |= ENDPTCTRL_TXR; /* reset data toggle */
392 data |= ENDPTCTRL_TXR;
393 mask |= ENDPTCTRL_TXE; /* enable */
394 data |= ENDPTCTRL_TXE;
395 } else {
396 mask = ENDPTCTRL_RXT; /* type */
397 data = type << ffs_nr(mask);
398
399 mask |= ENDPTCTRL_RXS; /* unstall */
400 mask |= ENDPTCTRL_RXR; /* reset data toggle */
401 data |= ENDPTCTRL_RXR;
402 mask |= ENDPTCTRL_RXE; /* enable */
403 data |= ENDPTCTRL_RXE;
404 }
Alexander Shishkind3595d12012-05-08 23:28:58 +0300405 hw_write(udc->hw_bank.op, OP_ENDPTCTRL + num * sizeof(u32), mask, data);
David Lopoaa69a802008-11-17 14:14:51 -0800406 return 0;
407}
408
409/**
410 * hw_ep_get_halt: return endpoint halt status
411 * @num: endpoint number
412 * @dir: endpoint direction
413 *
414 * This function returns 1 if endpoint halted
415 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300416static int hw_ep_get_halt(struct ci13xxx *udc, int num, int dir)
David Lopoaa69a802008-11-17 14:14:51 -0800417{
418 u32 mask = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
419
Alexander Shishkind3595d12012-05-08 23:28:58 +0300420 return !!hw_read(udc->hw_bank.op, OP_ENDPTCTRL + num * sizeof(u32),
421 mask);
David Lopoaa69a802008-11-17 14:14:51 -0800422}
423
424/**
David Lopoaa69a802008-11-17 14:14:51 -0800425 * hw_test_and_clear_setup_status: test & clear setup status (execute without
426 * interruption)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200427 * @n: endpoint number
David Lopoaa69a802008-11-17 14:14:51 -0800428 *
429 * This function returns setup status
430 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300431static int hw_test_and_clear_setup_status(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800432{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300433 n = ep_to_bit(udc, n);
434 return hw_test_and_clear(udc->hw_bank.op, OP_ENDPTSETUPSTAT, BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800435}
436
437/**
438 * hw_ep_prime: primes endpoint (execute without interruption)
439 * @num: endpoint number
440 * @dir: endpoint direction
441 * @is_ctrl: true if control endpoint
442 *
443 * This function returns an error code
444 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300445static int hw_ep_prime(struct ci13xxx *udc, int num, int dir, int is_ctrl)
David Lopoaa69a802008-11-17 14:14:51 -0800446{
447 int n = hw_ep_bit(num, dir);
448
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300449 if (is_ctrl && dir == RX &&
Alexander Shishkind3595d12012-05-08 23:28:58 +0300450 hw_read(udc->hw_bank.op, OP_ENDPTSETUPSTAT, BIT(num)))
David Lopoaa69a802008-11-17 14:14:51 -0800451 return -EAGAIN;
452
Alexander Shishkind3595d12012-05-08 23:28:58 +0300453 hw_write(udc->hw_bank.op, OP_ENDPTPRIME, BIT(n), BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800454
Alexander Shishkind3595d12012-05-08 23:28:58 +0300455 while (hw_read(udc->hw_bank.op, OP_ENDPTPRIME, BIT(n)))
David Lopoaa69a802008-11-17 14:14:51 -0800456 cpu_relax();
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300457 if (is_ctrl && dir == RX &&
Alexander Shishkind3595d12012-05-08 23:28:58 +0300458 hw_read(udc->hw_bank.op, OP_ENDPTSETUPSTAT, BIT(num)))
David Lopoaa69a802008-11-17 14:14:51 -0800459 return -EAGAIN;
460
461 /* status shoult be tested according with manual but it doesn't work */
462 return 0;
463}
464
465/**
466 * hw_ep_set_halt: configures ep halt & resets data toggle after clear (execute
467 * without interruption)
468 * @num: endpoint number
469 * @dir: endpoint direction
470 * @value: true => stall, false => unstall
471 *
472 * This function returns an error code
473 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300474static int hw_ep_set_halt(struct ci13xxx *udc, int num, int dir, int value)
David Lopoaa69a802008-11-17 14:14:51 -0800475{
476 if (value != 0 && value != 1)
477 return -EINVAL;
478
479 do {
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300480 u32 addr = OP_ENDPTCTRL + num * sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -0800481 u32 mask_xs = dir ? ENDPTCTRL_TXS : ENDPTCTRL_RXS;
482 u32 mask_xr = dir ? ENDPTCTRL_TXR : ENDPTCTRL_RXR;
483
484 /* data toggle - reserved for EP0 but it's in ESS */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300485 hw_write(udc->hw_bank.op, addr, mask_xs|mask_xr,
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300486 value ? mask_xs : mask_xr);
David Lopoaa69a802008-11-17 14:14:51 -0800487
Alexander Shishkind3595d12012-05-08 23:28:58 +0300488 } while (value != hw_ep_get_halt(udc, num, dir));
David Lopoaa69a802008-11-17 14:14:51 -0800489
490 return 0;
491}
492
493/**
494 * hw_intr_clear: disables interrupt & clears interrupt status (execute without
495 * interruption)
496 * @n: interrupt bit
497 *
498 * This function returns an error code
499 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300500static int hw_intr_clear(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800501{
502 if (n >= REG_BITS)
503 return -EINVAL;
504
Alexander Shishkind3595d12012-05-08 23:28:58 +0300505 hw_write(udc->hw_bank.op, OP_USBINTR, BIT(n), 0);
506 hw_write(udc->hw_bank.op, OP_USBSTS, BIT(n), BIT(n));
507
David Lopoaa69a802008-11-17 14:14:51 -0800508 return 0;
509}
510
511/**
512 * hw_intr_force: enables interrupt & forces interrupt status (execute without
513 * interruption)
514 * @n: interrupt bit
515 *
516 * This function returns an error code
517 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300518static int hw_intr_force(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800519{
520 if (n >= REG_BITS)
521 return -EINVAL;
522
Alexander Shishkind3595d12012-05-08 23:28:58 +0300523 hw_write(udc->hw_bank.cap, ABS_TESTMODE, TESTMODE_FORCE,
524 TESTMODE_FORCE);
525 hw_write(udc->hw_bank.op, OP_USBINTR, BIT(n), BIT(n));
526 hw_write(udc->hw_bank.op, OP_USBSTS, BIT(n), BIT(n));
527 hw_write(udc->hw_bank.cap, ABS_TESTMODE, TESTMODE_FORCE, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800528 return 0;
529}
530
531/**
532 * hw_is_port_high_speed: test if port is high speed
533 *
534 * This function returns true if high speed port
535 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300536static int hw_port_is_high_speed(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800537{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300538 return udc->hw_bank.lpm
539 ? hw_read(udc->hw_bank.op, OP_DEVLC, DEVLC_PSPD)
540 : hw_read(udc->hw_bank.op, OP_PORTSC, PORTSC_HSP);
David Lopoaa69a802008-11-17 14:14:51 -0800541}
542
543/**
544 * hw_port_test_get: reads port test mode value
545 *
546 * This function returns port test mode value
547 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300548static u8 hw_port_test_get(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800549{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300550 return hw_read(udc->hw_bank.op, OP_PORTSC, PORTSC_PTC) >>
551 ffs_nr(PORTSC_PTC);
David Lopoaa69a802008-11-17 14:14:51 -0800552}
553
554/**
555 * hw_port_test_set: writes port test mode (execute without interruption)
556 * @mode: new value
557 *
558 * This function returns an error code
559 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300560static int hw_port_test_set(struct ci13xxx *udc, u8 mode)
David Lopoaa69a802008-11-17 14:14:51 -0800561{
562 const u8 TEST_MODE_MAX = 7;
563
564 if (mode > TEST_MODE_MAX)
565 return -EINVAL;
566
Alexander Shishkind3595d12012-05-08 23:28:58 +0300567 hw_write(udc->hw_bank.op, OP_PORTSC, PORTSC_PTC,
568 mode << ffs_nr(PORTSC_PTC));
David Lopoaa69a802008-11-17 14:14:51 -0800569 return 0;
570}
571
572/**
573 * hw_read_intr_enable: returns interrupt enable register
574 *
575 * This function returns register data
576 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300577static u32 hw_read_intr_enable(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800578{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300579 return hw_read(udc->hw_bank.op, OP_USBINTR, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800580}
581
582/**
583 * hw_read_intr_status: returns interrupt status register
584 *
585 * This function returns register data
586 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300587static u32 hw_read_intr_status(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800588{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300589 return hw_read(udc->hw_bank.op, OP_USBSTS, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800590}
591
592/**
593 * hw_register_read: reads all device registers (execute without interruption)
594 * @buf: destination buffer
595 * @size: buffer size
596 *
597 * This function returns number of registers read
598 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300599static size_t hw_register_read(struct ci13xxx *udc, u32 *buf, size_t size)
David Lopoaa69a802008-11-17 14:14:51 -0800600{
601 unsigned i;
602
Alexander Shishkind3595d12012-05-08 23:28:58 +0300603 if (size > udc->hw_bank.size)
604 size = udc->hw_bank.size;
David Lopoaa69a802008-11-17 14:14:51 -0800605
606 for (i = 0; i < size; i++)
Alexander Shishkind3595d12012-05-08 23:28:58 +0300607 buf[i] = hw_read(udc->hw_bank.cap, i * sizeof(u32), ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800608
609 return size;
610}
611
612/**
613 * hw_register_write: writes to register
614 * @addr: register address
615 * @data: register value
616 *
617 * This function returns an error code
618 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300619static int hw_register_write(struct ci13xxx *udc, u16 addr, u32 data)
David Lopoaa69a802008-11-17 14:14:51 -0800620{
621 /* align */
622 addr /= sizeof(u32);
623
Alexander Shishkind3595d12012-05-08 23:28:58 +0300624 if (addr >= udc->hw_bank.size)
David Lopoaa69a802008-11-17 14:14:51 -0800625 return -EINVAL;
626
627 /* align */
628 addr *= sizeof(u32);
629
Alexander Shishkind3595d12012-05-08 23:28:58 +0300630 hw_write(udc->hw_bank.cap, addr, ~0, data);
David Lopoaa69a802008-11-17 14:14:51 -0800631 return 0;
632}
633
634/**
635 * hw_test_and_clear_complete: test & clear complete status (execute without
636 * interruption)
Marc Kleine-Buddedd39c352011-10-10 18:38:10 +0200637 * @n: endpoint number
David Lopoaa69a802008-11-17 14:14:51 -0800638 *
639 * This function returns complete status
640 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300641static int hw_test_and_clear_complete(struct ci13xxx *udc, int n)
David Lopoaa69a802008-11-17 14:14:51 -0800642{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300643 n = ep_to_bit(udc, n);
644 return hw_test_and_clear(udc->hw_bank.op, OP_ENDPTCOMPLETE, BIT(n));
David Lopoaa69a802008-11-17 14:14:51 -0800645}
646
647/**
648 * hw_test_and_clear_intr_active: test & clear active interrupts (execute
649 * without interruption)
650 *
651 * This function returns active interrutps
652 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300653static u32 hw_test_and_clear_intr_active(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800654{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300655 u32 reg = hw_read_intr_status(udc) & hw_read_intr_enable(udc);
David Lopoaa69a802008-11-17 14:14:51 -0800656
Alexander Shishkind3595d12012-05-08 23:28:58 +0300657 hw_write(udc->hw_bank.op, OP_USBSTS, ~0, reg);
David Lopoaa69a802008-11-17 14:14:51 -0800658 return reg;
659}
660
661/**
662 * hw_test_and_clear_setup_guard: test & clear setup guard (execute without
663 * interruption)
664 *
665 * This function returns guard value
666 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300667static int hw_test_and_clear_setup_guard(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800668{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300669 return hw_test_and_write(udc->hw_bank.op, OP_USBCMD, USBCMD_SUTW, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800670}
671
672/**
673 * hw_test_and_set_setup_guard: test & set setup guard (execute without
674 * interruption)
675 *
676 * This function returns guard value
677 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300678static int hw_test_and_set_setup_guard(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800679{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300680 return hw_test_and_write(udc->hw_bank.op, OP_USBCMD, USBCMD_SUTW,
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300681 USBCMD_SUTW);
David Lopoaa69a802008-11-17 14:14:51 -0800682}
683
684/**
685 * hw_usb_set_address: configures USB address (execute without interruption)
686 * @value: new USB address
687 *
688 * This function returns an error code
689 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300690static int hw_usb_set_address(struct ci13xxx *udc, u8 value)
David Lopoaa69a802008-11-17 14:14:51 -0800691{
692 /* advance */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300693 hw_write(udc->hw_bank.op, OP_DEVICEADDR,
Alexander Shishkinf9df8392012-05-04 16:47:16 +0300694 DEVICEADDR_USBADR | DEVICEADDR_USBADRA,
695 value << ffs_nr(DEVICEADDR_USBADR) | DEVICEADDR_USBADRA);
David Lopoaa69a802008-11-17 14:14:51 -0800696 return 0;
697}
698
699/**
700 * hw_usb_reset: restart device after a bus reset (execute without
701 * interruption)
702 *
703 * This function returns an error code
704 */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300705static int hw_usb_reset(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -0800706{
Alexander Shishkind3595d12012-05-08 23:28:58 +0300707 hw_usb_set_address(udc, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800708
709 /* ESS flushes only at end?!? */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300710 hw_write(udc->hw_bank.op, OP_ENDPTFLUSH, ~0, ~0);
David Lopoaa69a802008-11-17 14:14:51 -0800711
712 /* clear setup token semaphores */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300713 hw_write(udc->hw_bank.op, OP_ENDPTSETUPSTAT, 0, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800714
715 /* clear complete status */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300716 hw_write(udc->hw_bank.op, OP_ENDPTCOMPLETE, 0, 0);
David Lopoaa69a802008-11-17 14:14:51 -0800717
718 /* wait until all bits cleared */
Alexander Shishkind3595d12012-05-08 23:28:58 +0300719 while (hw_read(udc->hw_bank.op, OP_ENDPTPRIME, ~0))
David Lopoaa69a802008-11-17 14:14:51 -0800720 udelay(10); /* not RTOS friendly */
721
722 /* reset all endpoints ? */
723
724 /* reset internal status and wait for further instructions
725 no need to verify the port reset status (ESS does it) */
726
727 return 0;
728}
729
730/******************************************************************************
731 * DBG block
732 *****************************************************************************/
733/**
734 * show_device: prints information about device capabilities and status
735 *
736 * Check "device.h" for details
737 */
738static ssize_t show_device(struct device *dev, struct device_attribute *attr,
739 char *buf)
740{
741 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
742 struct usb_gadget *gadget = &udc->gadget;
743 int n = 0;
744
745 dbg_trace("[%s] %p\n", __func__, buf);
746 if (attr == NULL || buf == NULL) {
747 dev_err(dev, "[%s] EINVAL\n", __func__);
748 return 0;
749 }
750
751 n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n",
752 gadget->speed);
Michal Nazarewiczd327ab52011-11-19 18:27:37 +0100753 n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n",
754 gadget->max_speed);
755 /* TODO: Scheduled for removal in 3.8. */
David Lopoaa69a802008-11-17 14:14:51 -0800756 n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n",
Michal Nazarewiczd327ab52011-11-19 18:27:37 +0100757 gadget_is_dualspeed(gadget));
David Lopoaa69a802008-11-17 14:14:51 -0800758 n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n",
759 gadget->is_otg);
760 n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n",
761 gadget->is_a_peripheral);
762 n += scnprintf(buf + n, PAGE_SIZE - n, "b_hnp_enable = %d\n",
763 gadget->b_hnp_enable);
764 n += scnprintf(buf + n, PAGE_SIZE - n, "a_hnp_support = %d\n",
765 gadget->a_hnp_support);
766 n += scnprintf(buf + n, PAGE_SIZE - n, "a_alt_hnp_support = %d\n",
767 gadget->a_alt_hnp_support);
768 n += scnprintf(buf + n, PAGE_SIZE - n, "name = %s\n",
769 (gadget->name ? gadget->name : ""));
770
771 return n;
772}
773static DEVICE_ATTR(device, S_IRUSR, show_device, NULL);
774
775/**
776 * show_driver: prints information about attached gadget (if any)
777 *
778 * Check "device.h" for details
779 */
780static ssize_t show_driver(struct device *dev, struct device_attribute *attr,
781 char *buf)
782{
783 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
784 struct usb_gadget_driver *driver = udc->driver;
785 int n = 0;
786
787 dbg_trace("[%s] %p\n", __func__, buf);
788 if (attr == NULL || buf == NULL) {
789 dev_err(dev, "[%s] EINVAL\n", __func__);
790 return 0;
791 }
792
793 if (driver == NULL)
794 return scnprintf(buf, PAGE_SIZE,
795 "There is no gadget attached!\n");
796
797 n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n",
798 (driver->function ? driver->function : ""));
799 n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n",
Michal Nazarewicz7177aed2011-11-19 18:27:38 +0100800 driver->max_speed);
David Lopoaa69a802008-11-17 14:14:51 -0800801
802 return n;
803}
804static DEVICE_ATTR(driver, S_IRUSR, show_driver, NULL);
805
806/* Maximum event message length */
807#define DBG_DATA_MSG 64UL
808
809/* Maximum event messages */
810#define DBG_DATA_MAX 128UL
811
812/* Event buffer descriptor */
813static struct {
814 char (buf[DBG_DATA_MAX])[DBG_DATA_MSG]; /* buffer */
815 unsigned idx; /* index */
816 unsigned tty; /* print to console? */
817 rwlock_t lck; /* lock */
818} dbg_data = {
819 .idx = 0,
820 .tty = 0,
821 .lck = __RW_LOCK_UNLOCKED(lck)
822};
823
824/**
825 * dbg_dec: decrements debug event index
826 * @idx: buffer index
827 */
828static void dbg_dec(unsigned *idx)
829{
830 *idx = (*idx - 1) & (DBG_DATA_MAX-1);
831}
832
833/**
834 * dbg_inc: increments debug event index
835 * @idx: buffer index
836 */
837static void dbg_inc(unsigned *idx)
838{
839 *idx = (*idx + 1) & (DBG_DATA_MAX-1);
840}
841
842/**
843 * dbg_print: prints the common part of the event
844 * @addr: endpoint address
845 * @name: event name
846 * @status: status
847 * @extra: extra information
848 */
849static void dbg_print(u8 addr, const char *name, int status, const char *extra)
850{
851 struct timeval tval;
852 unsigned int stamp;
853 unsigned long flags;
854
855 write_lock_irqsave(&dbg_data.lck, flags);
856
857 do_gettimeofday(&tval);
858 stamp = tval.tv_sec & 0xFFFF; /* 2^32 = 4294967296. Limit to 4096s */
859 stamp = stamp * 1000000 + tval.tv_usec;
860
861 scnprintf(dbg_data.buf[dbg_data.idx], DBG_DATA_MSG,
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +0300862 "%04X\t? %02X %-7.7s %4i ?\t%s\n",
David Lopoaa69a802008-11-17 14:14:51 -0800863 stamp, addr, name, status, extra);
864
865 dbg_inc(&dbg_data.idx);
866
867 write_unlock_irqrestore(&dbg_data.lck, flags);
868
869 if (dbg_data.tty != 0)
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +0300870 pr_notice("%04X\t? %02X %-7.7s %4i ?\t%s\n",
David Lopoaa69a802008-11-17 14:14:51 -0800871 stamp, addr, name, status, extra);
872}
873
874/**
875 * dbg_done: prints a DONE event
876 * @addr: endpoint address
877 * @td: transfer descriptor
878 * @status: status
879 */
880static void dbg_done(u8 addr, const u32 token, int status)
881{
882 char msg[DBG_DATA_MSG];
883
884 scnprintf(msg, sizeof(msg), "%d %02X",
885 (int)(token & TD_TOTAL_BYTES) >> ffs_nr(TD_TOTAL_BYTES),
886 (int)(token & TD_STATUS) >> ffs_nr(TD_STATUS));
887 dbg_print(addr, "DONE", status, msg);
888}
889
890/**
891 * dbg_event: prints a generic event
892 * @addr: endpoint address
893 * @name: event name
894 * @status: status
895 */
896static void dbg_event(u8 addr, const char *name, int status)
897{
898 if (name != NULL)
899 dbg_print(addr, name, status, "");
900}
901
902/*
903 * dbg_queue: prints a QUEUE event
904 * @addr: endpoint address
905 * @req: USB request
906 * @status: status
907 */
908static void dbg_queue(u8 addr, const struct usb_request *req, int status)
909{
910 char msg[DBG_DATA_MSG];
911
912 if (req != NULL) {
913 scnprintf(msg, sizeof(msg),
914 "%d %d", !req->no_interrupt, req->length);
915 dbg_print(addr, "QUEUE", status, msg);
916 }
917}
918
919/**
920 * dbg_setup: prints a SETUP event
921 * @addr: endpoint address
922 * @req: setup request
923 */
924static void dbg_setup(u8 addr, const struct usb_ctrlrequest *req)
925{
926 char msg[DBG_DATA_MSG];
927
928 if (req != NULL) {
929 scnprintf(msg, sizeof(msg),
930 "%02X %02X %04X %04X %d", req->bRequestType,
931 req->bRequest, le16_to_cpu(req->wValue),
932 le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
933 dbg_print(addr, "SETUP", 0, msg);
934 }
935}
936
937/**
938 * show_events: displays the event buffer
939 *
940 * Check "device.h" for details
941 */
942static ssize_t show_events(struct device *dev, struct device_attribute *attr,
943 char *buf)
944{
945 unsigned long flags;
946 unsigned i, j, n = 0;
947
948 dbg_trace("[%s] %p\n", __func__, buf);
949 if (attr == NULL || buf == NULL) {
950 dev_err(dev, "[%s] EINVAL\n", __func__);
951 return 0;
952 }
953
954 read_lock_irqsave(&dbg_data.lck, flags);
955
956 i = dbg_data.idx;
957 for (dbg_dec(&i); i != dbg_data.idx; dbg_dec(&i)) {
958 n += strlen(dbg_data.buf[i]);
959 if (n >= PAGE_SIZE) {
960 n -= strlen(dbg_data.buf[i]);
961 break;
962 }
963 }
964 for (j = 0, dbg_inc(&i); j < n; dbg_inc(&i))
965 j += scnprintf(buf + j, PAGE_SIZE - j,
966 "%s", dbg_data.buf[i]);
967
968 read_unlock_irqrestore(&dbg_data.lck, flags);
969
970 return n;
971}
972
973/**
974 * store_events: configure if events are going to be also printed to console
975 *
976 * Check "device.h" for details
977 */
978static ssize_t store_events(struct device *dev, struct device_attribute *attr,
979 const char *buf, size_t count)
980{
981 unsigned tty;
982
983 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
984 if (attr == NULL || buf == NULL) {
985 dev_err(dev, "[%s] EINVAL\n", __func__);
986 goto done;
987 }
988
989 if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
990 dev_err(dev, "<1|0>: enable|disable console log\n");
991 goto done;
992 }
993
994 dbg_data.tty = tty;
995 dev_info(dev, "tty = %u", dbg_data.tty);
996
997 done:
998 return count;
999}
1000static DEVICE_ATTR(events, S_IRUSR | S_IWUSR, show_events, store_events);
1001
1002/**
1003 * show_inters: interrupt status, enable status and historic
1004 *
1005 * Check "device.h" for details
1006 */
1007static ssize_t show_inters(struct device *dev, struct device_attribute *attr,
1008 char *buf)
1009{
1010 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1011 unsigned long flags;
1012 u32 intr;
1013 unsigned i, j, n = 0;
1014
1015 dbg_trace("[%s] %p\n", __func__, buf);
1016 if (attr == NULL || buf == NULL) {
1017 dev_err(dev, "[%s] EINVAL\n", __func__);
1018 return 0;
1019 }
1020
Alexander Shishkind3595d12012-05-08 23:28:58 +03001021 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001022
1023 n += scnprintf(buf + n, PAGE_SIZE - n,
Alexander Shishkind3595d12012-05-08 23:28:58 +03001024 "status = %08x\n", hw_read_intr_status(udc));
David Lopoaa69a802008-11-17 14:14:51 -08001025 n += scnprintf(buf + n, PAGE_SIZE - n,
Alexander Shishkind3595d12012-05-08 23:28:58 +03001026 "enable = %08x\n", hw_read_intr_enable(udc));
David Lopoaa69a802008-11-17 14:14:51 -08001027
1028 n += scnprintf(buf + n, PAGE_SIZE - n, "*test = %d\n",
1029 isr_statistics.test);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001030 n += scnprintf(buf + n, PAGE_SIZE - n, "? ui = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001031 isr_statistics.ui);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001032 n += scnprintf(buf + n, PAGE_SIZE - n, "? uei = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001033 isr_statistics.uei);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001034 n += scnprintf(buf + n, PAGE_SIZE - n, "? pci = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001035 isr_statistics.pci);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001036 n += scnprintf(buf + n, PAGE_SIZE - n, "? uri = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001037 isr_statistics.uri);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03001038 n += scnprintf(buf + n, PAGE_SIZE - n, "? sli = %d\n",
David Lopoaa69a802008-11-17 14:14:51 -08001039 isr_statistics.sli);
1040 n += scnprintf(buf + n, PAGE_SIZE - n, "*none = %d\n",
1041 isr_statistics.none);
1042 n += scnprintf(buf + n, PAGE_SIZE - n, "*hndl = %d\n",
1043 isr_statistics.hndl.cnt);
1044
1045 for (i = isr_statistics.hndl.idx, j = 0; j <= ISR_MASK; j++, i++) {
1046 i &= ISR_MASK;
1047 intr = isr_statistics.hndl.buf[i];
1048
1049 if (USBi_UI & intr)
1050 n += scnprintf(buf + n, PAGE_SIZE - n, "ui ");
1051 intr &= ~USBi_UI;
1052 if (USBi_UEI & intr)
1053 n += scnprintf(buf + n, PAGE_SIZE - n, "uei ");
1054 intr &= ~USBi_UEI;
1055 if (USBi_PCI & intr)
1056 n += scnprintf(buf + n, PAGE_SIZE - n, "pci ");
1057 intr &= ~USBi_PCI;
1058 if (USBi_URI & intr)
1059 n += scnprintf(buf + n, PAGE_SIZE - n, "uri ");
1060 intr &= ~USBi_URI;
1061 if (USBi_SLI & intr)
1062 n += scnprintf(buf + n, PAGE_SIZE - n, "sli ");
1063 intr &= ~USBi_SLI;
1064 if (intr)
1065 n += scnprintf(buf + n, PAGE_SIZE - n, "??? ");
1066 if (isr_statistics.hndl.buf[i])
1067 n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
1068 }
1069
Alexander Shishkind3595d12012-05-08 23:28:58 +03001070 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001071
1072 return n;
1073}
1074
1075/**
1076 * store_inters: enable & force or disable an individual interrutps
1077 * (to be used for test purposes only)
1078 *
1079 * Check "device.h" for details
1080 */
1081static ssize_t store_inters(struct device *dev, struct device_attribute *attr,
1082 const char *buf, size_t count)
1083{
1084 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1085 unsigned long flags;
1086 unsigned en, bit;
1087
1088 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1089 if (attr == NULL || buf == NULL) {
1090 dev_err(dev, "[%s] EINVAL\n", __func__);
1091 goto done;
1092 }
1093
1094 if (sscanf(buf, "%u %u", &en, &bit) != 2 || en > 1) {
1095 dev_err(dev, "<1|0> <bit>: enable|disable interrupt");
1096 goto done;
1097 }
1098
Alexander Shishkind3595d12012-05-08 23:28:58 +03001099 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001100 if (en) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001101 if (hw_intr_force(udc, bit))
David Lopoaa69a802008-11-17 14:14:51 -08001102 dev_err(dev, "invalid bit number\n");
1103 else
1104 isr_statistics.test++;
1105 } else {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001106 if (hw_intr_clear(udc, bit))
David Lopoaa69a802008-11-17 14:14:51 -08001107 dev_err(dev, "invalid bit number\n");
1108 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03001109 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001110
1111 done:
1112 return count;
1113}
1114static DEVICE_ATTR(inters, S_IRUSR | S_IWUSR, show_inters, store_inters);
1115
1116/**
1117 * show_port_test: reads port test mode
1118 *
1119 * Check "device.h" for details
1120 */
1121static ssize_t show_port_test(struct device *dev,
1122 struct device_attribute *attr, char *buf)
1123{
1124 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1125 unsigned long flags;
1126 unsigned mode;
1127
1128 dbg_trace("[%s] %p\n", __func__, buf);
1129 if (attr == NULL || buf == NULL) {
1130 dev_err(dev, "[%s] EINVAL\n", __func__);
1131 return 0;
1132 }
1133
Alexander Shishkind3595d12012-05-08 23:28:58 +03001134 spin_lock_irqsave(&udc->lock, flags);
1135 mode = hw_port_test_get(udc);
1136 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001137
1138 return scnprintf(buf, PAGE_SIZE, "mode = %u\n", mode);
1139}
1140
1141/**
1142 * store_port_test: writes port test mode
1143 *
1144 * Check "device.h" for details
1145 */
1146static ssize_t store_port_test(struct device *dev,
1147 struct device_attribute *attr,
1148 const char *buf, size_t count)
1149{
1150 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1151 unsigned long flags;
1152 unsigned mode;
1153
1154 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1155 if (attr == NULL || buf == NULL) {
1156 dev_err(dev, "[%s] EINVAL\n", __func__);
1157 goto done;
1158 }
1159
1160 if (sscanf(buf, "%u", &mode) != 1) {
1161 dev_err(dev, "<mode>: set port test mode");
1162 goto done;
1163 }
1164
Alexander Shishkind3595d12012-05-08 23:28:58 +03001165 spin_lock_irqsave(&udc->lock, flags);
1166 if (hw_port_test_set(udc, mode))
David Lopoaa69a802008-11-17 14:14:51 -08001167 dev_err(dev, "invalid mode\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03001168 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001169
1170 done:
1171 return count;
1172}
1173static DEVICE_ATTR(port_test, S_IRUSR | S_IWUSR,
1174 show_port_test, store_port_test);
1175
1176/**
1177 * show_qheads: DMA contents of all queue heads
1178 *
1179 * Check "device.h" for details
1180 */
1181static ssize_t show_qheads(struct device *dev, struct device_attribute *attr,
1182 char *buf)
1183{
1184 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1185 unsigned long flags;
1186 unsigned i, j, n = 0;
1187
1188 dbg_trace("[%s] %p\n", __func__, buf);
1189 if (attr == NULL || buf == NULL) {
1190 dev_err(dev, "[%s] EINVAL\n", __func__);
1191 return 0;
1192 }
1193
Alexander Shishkind3595d12012-05-08 23:28:58 +03001194 spin_lock_irqsave(&udc->lock, flags);
1195 for (i = 0; i < udc->hw_ep_max/2; i++) {
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301196 struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i];
Alexander Shishkind3595d12012-05-08 23:28:58 +03001197 struct ci13xxx_ep *mEpTx =
1198 &udc->ci13xxx_ep[i + udc->hw_ep_max/2];
David Lopoaa69a802008-11-17 14:14:51 -08001199 n += scnprintf(buf + n, PAGE_SIZE - n,
1200 "EP=%02i: RX=%08X TX=%08X\n",
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301201 i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08001202 for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) {
1203 n += scnprintf(buf + n, PAGE_SIZE - n,
1204 " %04X: %08X %08X\n", j,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301205 *((u32 *)mEpRx->qh.ptr + j),
1206 *((u32 *)mEpTx->qh.ptr + j));
David Lopoaa69a802008-11-17 14:14:51 -08001207 }
1208 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03001209 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001210
1211 return n;
1212}
1213static DEVICE_ATTR(qheads, S_IRUSR, show_qheads, NULL);
1214
1215/**
1216 * show_registers: dumps all registers
1217 *
1218 * Check "device.h" for details
1219 */
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001220#define DUMP_ENTRIES 512
David Lopoaa69a802008-11-17 14:14:51 -08001221static ssize_t show_registers(struct device *dev,
1222 struct device_attribute *attr, char *buf)
1223{
1224 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1225 unsigned long flags;
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001226 u32 *dump;
David Lopoaa69a802008-11-17 14:14:51 -08001227 unsigned i, k, n = 0;
1228
1229 dbg_trace("[%s] %p\n", __func__, buf);
1230 if (attr == NULL || buf == NULL) {
1231 dev_err(dev, "[%s] EINVAL\n", __func__);
1232 return 0;
1233 }
1234
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001235 dump = kmalloc(sizeof(u32) * DUMP_ENTRIES, GFP_KERNEL);
1236 if (!dump) {
1237 dev_err(dev, "%s: out of memory\n", __func__);
1238 return 0;
1239 }
1240
Alexander Shishkind3595d12012-05-08 23:28:58 +03001241 spin_lock_irqsave(&udc->lock, flags);
1242 k = hw_register_read(udc, dump, DUMP_ENTRIES);
1243 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001244
1245 for (i = 0; i < k; i++) {
1246 n += scnprintf(buf + n, PAGE_SIZE - n,
1247 "reg[0x%04X] = 0x%08X\n",
1248 i * (unsigned)sizeof(u32), dump[i]);
1249 }
Sebastian Andrzej Siewiorc2b65f82011-07-05 15:57:52 +03001250 kfree(dump);
David Lopoaa69a802008-11-17 14:14:51 -08001251
1252 return n;
1253}
1254
1255/**
1256 * store_registers: writes value to register address
1257 *
1258 * Check "device.h" for details
1259 */
1260static ssize_t store_registers(struct device *dev,
1261 struct device_attribute *attr,
1262 const char *buf, size_t count)
1263{
1264 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1265 unsigned long addr, data, flags;
1266
1267 dbg_trace("[%s] %p, %d\n", __func__, buf, count);
1268 if (attr == NULL || buf == NULL) {
1269 dev_err(dev, "[%s] EINVAL\n", __func__);
1270 goto done;
1271 }
1272
1273 if (sscanf(buf, "%li %li", &addr, &data) != 2) {
1274 dev_err(dev, "<addr> <data>: write data to register address");
1275 goto done;
1276 }
1277
Alexander Shishkind3595d12012-05-08 23:28:58 +03001278 spin_lock_irqsave(&udc->lock, flags);
1279 if (hw_register_write(udc, addr, data))
David Lopoaa69a802008-11-17 14:14:51 -08001280 dev_err(dev, "invalid address range\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03001281 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001282
1283 done:
1284 return count;
1285}
1286static DEVICE_ATTR(registers, S_IRUSR | S_IWUSR,
1287 show_registers, store_registers);
1288
1289/**
1290 * show_requests: DMA contents of all requests currently queued (all endpts)
1291 *
1292 * Check "device.h" for details
1293 */
1294static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
1295 char *buf)
1296{
1297 struct ci13xxx *udc = container_of(dev, struct ci13xxx, gadget.dev);
1298 unsigned long flags;
1299 struct list_head *ptr = NULL;
1300 struct ci13xxx_req *req = NULL;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301301 unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
David Lopoaa69a802008-11-17 14:14:51 -08001302
1303 dbg_trace("[%s] %p\n", __func__, buf);
1304 if (attr == NULL || buf == NULL) {
1305 dev_err(dev, "[%s] EINVAL\n", __func__);
1306 return 0;
1307 }
1308
Alexander Shishkind3595d12012-05-08 23:28:58 +03001309 spin_lock_irqsave(&udc->lock, flags);
1310 for (i = 0; i < udc->hw_ep_max; i++)
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301311 list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue)
1312 {
1313 req = list_entry(ptr, struct ci13xxx_req, queue);
David Lopoaa69a802008-11-17 14:14:51 -08001314
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301315 n += scnprintf(buf + n, PAGE_SIZE - n,
1316 "EP=%02i: TD=%08X %s\n",
Alexander Shishkind3595d12012-05-08 23:28:58 +03001317 i % udc->hw_ep_max/2, (u32)req->dma,
1318 ((i < udc->hw_ep_max/2) ? "RX" : "TX"));
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301319
1320 for (j = 0; j < qSize; j++)
David Lopoaa69a802008-11-17 14:14:51 -08001321 n += scnprintf(buf + n, PAGE_SIZE - n,
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301322 " %04X: %08X\n", j,
1323 *((u32 *)req->ptr + j));
1324 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03001325 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08001326
1327 return n;
1328}
1329static DEVICE_ATTR(requests, S_IRUSR, show_requests, NULL);
1330
1331/**
1332 * dbg_create_files: initializes the attribute interface
1333 * @dev: device
1334 *
1335 * This function returns an error code
1336 */
1337__maybe_unused static int dbg_create_files(struct device *dev)
1338{
1339 int retval = 0;
1340
1341 if (dev == NULL)
1342 return -EINVAL;
1343 retval = device_create_file(dev, &dev_attr_device);
1344 if (retval)
1345 goto done;
1346 retval = device_create_file(dev, &dev_attr_driver);
1347 if (retval)
1348 goto rm_device;
1349 retval = device_create_file(dev, &dev_attr_events);
1350 if (retval)
1351 goto rm_driver;
1352 retval = device_create_file(dev, &dev_attr_inters);
1353 if (retval)
1354 goto rm_events;
1355 retval = device_create_file(dev, &dev_attr_port_test);
1356 if (retval)
1357 goto rm_inters;
1358 retval = device_create_file(dev, &dev_attr_qheads);
1359 if (retval)
1360 goto rm_port_test;
1361 retval = device_create_file(dev, &dev_attr_registers);
1362 if (retval)
1363 goto rm_qheads;
1364 retval = device_create_file(dev, &dev_attr_requests);
1365 if (retval)
1366 goto rm_registers;
1367 return 0;
1368
1369 rm_registers:
1370 device_remove_file(dev, &dev_attr_registers);
1371 rm_qheads:
1372 device_remove_file(dev, &dev_attr_qheads);
1373 rm_port_test:
1374 device_remove_file(dev, &dev_attr_port_test);
1375 rm_inters:
1376 device_remove_file(dev, &dev_attr_inters);
1377 rm_events:
1378 device_remove_file(dev, &dev_attr_events);
1379 rm_driver:
1380 device_remove_file(dev, &dev_attr_driver);
1381 rm_device:
1382 device_remove_file(dev, &dev_attr_device);
1383 done:
1384 return retval;
1385}
1386
1387/**
1388 * dbg_remove_files: destroys the attribute interface
1389 * @dev: device
1390 *
1391 * This function returns an error code
1392 */
1393__maybe_unused static int dbg_remove_files(struct device *dev)
1394{
1395 if (dev == NULL)
1396 return -EINVAL;
1397 device_remove_file(dev, &dev_attr_requests);
1398 device_remove_file(dev, &dev_attr_registers);
1399 device_remove_file(dev, &dev_attr_qheads);
1400 device_remove_file(dev, &dev_attr_port_test);
1401 device_remove_file(dev, &dev_attr_inters);
1402 device_remove_file(dev, &dev_attr_events);
1403 device_remove_file(dev, &dev_attr_driver);
1404 device_remove_file(dev, &dev_attr_device);
1405 return 0;
1406}
1407
1408/******************************************************************************
1409 * UTIL block
1410 *****************************************************************************/
1411/**
1412 * _usb_addr: calculates endpoint address from direction & number
1413 * @ep: endpoint
1414 */
1415static inline u8 _usb_addr(struct ci13xxx_ep *ep)
1416{
1417 return ((ep->dir == TX) ? USB_ENDPOINT_DIR_MASK : 0) | ep->num;
1418}
1419
1420/**
1421 * _hardware_queue: configures a request at hardware level
1422 * @gadget: gadget
1423 * @mEp: endpoint
1424 *
1425 * This function returns an error code
1426 */
1427static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1428{
Alexander Shishkind3595d12012-05-08 23:28:58 +03001429 struct ci13xxx *udc = mEp->udc;
David Lopoaa69a802008-11-17 14:14:51 -08001430 unsigned i;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301431 int ret = 0;
1432 unsigned length = mReq->req.length;
David Lopoaa69a802008-11-17 14:14:51 -08001433
1434 trace("%p, %p", mEp, mReq);
1435
1436 /* don't queue twice */
1437 if (mReq->req.status == -EALREADY)
1438 return -EALREADY;
1439
David Lopoaa69a802008-11-17 14:14:51 -08001440 mReq->req.status = -EALREADY;
Michael Grzeschik954aad82011-10-10 18:38:06 +02001441 if (length && mReq->req.dma == DMA_ADDR_INVALID) {
David Lopoaa69a802008-11-17 14:14:51 -08001442 mReq->req.dma = \
1443 dma_map_single(mEp->device, mReq->req.buf,
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301444 length, mEp->dir ? DMA_TO_DEVICE :
1445 DMA_FROM_DEVICE);
David Lopoaa69a802008-11-17 14:14:51 -08001446 if (mReq->req.dma == 0)
1447 return -ENOMEM;
1448
1449 mReq->map = 1;
1450 }
1451
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301452 if (mReq->req.zero && length && (length % mEp->ep.maxpacket == 0)) {
1453 mReq->zptr = dma_pool_alloc(mEp->td_pool, GFP_ATOMIC,
1454 &mReq->zdma);
1455 if (mReq->zptr == NULL) {
1456 if (mReq->map) {
1457 dma_unmap_single(mEp->device, mReq->req.dma,
1458 length, mEp->dir ? DMA_TO_DEVICE :
1459 DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02001460 mReq->req.dma = DMA_ADDR_INVALID;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301461 mReq->map = 0;
1462 }
1463 return -ENOMEM;
1464 }
1465 memset(mReq->zptr, 0, sizeof(*mReq->zptr));
1466 mReq->zptr->next = TD_TERMINATE;
1467 mReq->zptr->token = TD_STATUS_ACTIVE;
1468 if (!mReq->req.no_interrupt)
1469 mReq->zptr->token |= TD_IOC;
1470 }
David Lopoaa69a802008-11-17 14:14:51 -08001471 /*
1472 * TD configuration
1473 * TODO - handle requests which spawns into several TDs
1474 */
1475 memset(mReq->ptr, 0, sizeof(*mReq->ptr));
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301476 mReq->ptr->token = length << ffs_nr(TD_TOTAL_BYTES);
David Lopoaa69a802008-11-17 14:14:51 -08001477 mReq->ptr->token &= TD_TOTAL_BYTES;
David Lopoaa69a802008-11-17 14:14:51 -08001478 mReq->ptr->token |= TD_STATUS_ACTIVE;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301479 if (mReq->zptr) {
1480 mReq->ptr->next = mReq->zdma;
1481 } else {
1482 mReq->ptr->next = TD_TERMINATE;
1483 if (!mReq->req.no_interrupt)
1484 mReq->ptr->token |= TD_IOC;
1485 }
David Lopoaa69a802008-11-17 14:14:51 -08001486 mReq->ptr->page[0] = mReq->req.dma;
1487 for (i = 1; i < 5; i++)
1488 mReq->ptr->page[i] =
Artem Leonenko0a313c42010-12-14 23:47:06 -08001489 (mReq->req.dma + i * CI13XXX_PAGE_SIZE) & ~TD_RESERVED_MASK;
David Lopoaa69a802008-11-17 14:14:51 -08001490
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301491 if (!list_empty(&mEp->qh.queue)) {
1492 struct ci13xxx_req *mReqPrev;
1493 int n = hw_ep_bit(mEp->num, mEp->dir);
1494 int tmp_stat;
1495
1496 mReqPrev = list_entry(mEp->qh.queue.prev,
1497 struct ci13xxx_req, queue);
1498 if (mReqPrev->zptr)
1499 mReqPrev->zptr->next = mReq->dma & TD_ADDR_MASK;
1500 else
1501 mReqPrev->ptr->next = mReq->dma & TD_ADDR_MASK;
1502 wmb();
Alexander Shishkind3595d12012-05-08 23:28:58 +03001503 if (hw_read(udc->hw_bank.op, OP_ENDPTPRIME, BIT(n)))
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301504 goto done;
1505 do {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001506 hw_write(udc->hw_bank.op, OP_USBCMD, USBCMD_ATDTW,
Alexander Shishkinf9df8392012-05-04 16:47:16 +03001507 USBCMD_ATDTW);
Alexander Shishkind3595d12012-05-08 23:28:58 +03001508 tmp_stat = hw_read(udc->hw_bank.op, OP_ENDPTSTAT,
1509 BIT(n));
1510 } while (!hw_read(udc->hw_bank.op, OP_USBCMD, USBCMD_ATDTW));
1511 hw_write(udc->hw_bank.op, OP_USBCMD, USBCMD_ATDTW, 0);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301512 if (tmp_stat)
1513 goto done;
1514 }
1515
1516 /* QH configuration */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301517 mEp->qh.ptr->td.next = mReq->dma; /* TERMINATE = 0 */
1518 mEp->qh.ptr->td.token &= ~TD_STATUS; /* clear status */
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301519 mEp->qh.ptr->cap |= QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08001520
1521 wmb(); /* synchronize before ep prime */
1522
Alexander Shishkind3595d12012-05-08 23:28:58 +03001523 ret = hw_ep_prime(udc, mEp->num, mEp->dir,
David Lopoaa69a802008-11-17 14:14:51 -08001524 mEp->type == USB_ENDPOINT_XFER_CONTROL);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301525done:
1526 return ret;
David Lopoaa69a802008-11-17 14:14:51 -08001527}
1528
1529/**
1530 * _hardware_dequeue: handles a request at hardware level
1531 * @gadget: gadget
1532 * @mEp: endpoint
1533 *
1534 * This function returns an error code
1535 */
1536static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
1537{
1538 trace("%p, %p", mEp, mReq);
1539
1540 if (mReq->req.status != -EALREADY)
1541 return -EINVAL;
1542
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301543 if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0)
1544 return -EBUSY;
1545
1546 if (mReq->zptr) {
1547 if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0)
1548 return -EBUSY;
1549 dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma);
1550 mReq->zptr = NULL;
1551 }
David Lopoaa69a802008-11-17 14:14:51 -08001552
1553 mReq->req.status = 0;
1554
1555 if (mReq->map) {
1556 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
1557 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02001558 mReq->req.dma = DMA_ADDR_INVALID;
David Lopoaa69a802008-11-17 14:14:51 -08001559 mReq->map = 0;
1560 }
1561
1562 mReq->req.status = mReq->ptr->token & TD_STATUS;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301563 if ((TD_STATUS_HALTED & mReq->req.status) != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001564 mReq->req.status = -1;
1565 else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0)
1566 mReq->req.status = -1;
1567 else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0)
1568 mReq->req.status = -1;
1569
1570 mReq->req.actual = mReq->ptr->token & TD_TOTAL_BYTES;
1571 mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES);
1572 mReq->req.actual = mReq->req.length - mReq->req.actual;
1573 mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual;
1574
1575 return mReq->req.actual;
1576}
1577
1578/**
1579 * _ep_nuke: dequeues all endpoint requests
1580 * @mEp: endpoint
1581 *
1582 * This function returns an error code
1583 * Caller must hold lock
1584 */
1585static int _ep_nuke(struct ci13xxx_ep *mEp)
1586__releases(mEp->lock)
1587__acquires(mEp->lock)
1588{
1589 trace("%p", mEp);
1590
1591 if (mEp == NULL)
1592 return -EINVAL;
1593
Alexander Shishkind3595d12012-05-08 23:28:58 +03001594 hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08001595
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301596 while (!list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08001597
1598 /* pop oldest request */
1599 struct ci13xxx_req *mReq = \
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301600 list_entry(mEp->qh.queue.next,
David Lopoaa69a802008-11-17 14:14:51 -08001601 struct ci13xxx_req, queue);
1602 list_del_init(&mReq->queue);
1603 mReq->req.status = -ESHUTDOWN;
1604
Artem Leonenko7c25a822010-12-14 23:46:55 -08001605 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08001606 spin_unlock(mEp->lock);
1607 mReq->req.complete(&mEp->ep, &mReq->req);
1608 spin_lock(mEp->lock);
1609 }
1610 }
1611 return 0;
1612}
1613
1614/**
1615 * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts
1616 * @gadget: gadget
1617 *
1618 * This function returns an error code
David Lopoaa69a802008-11-17 14:14:51 -08001619 */
1620static int _gadget_stop_activity(struct usb_gadget *gadget)
David Lopoaa69a802008-11-17 14:14:51 -08001621{
1622 struct usb_ep *ep;
1623 struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301624 unsigned long flags;
David Lopoaa69a802008-11-17 14:14:51 -08001625
1626 trace("%p", gadget);
1627
1628 if (gadget == NULL)
1629 return -EINVAL;
1630
Alexander Shishkind3595d12012-05-08 23:28:58 +03001631 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301632 udc->gadget.speed = USB_SPEED_UNKNOWN;
1633 udc->remote_wakeup = 0;
1634 udc->suspended = 0;
Alexander Shishkind3595d12012-05-08 23:28:58 +03001635 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301636
David Lopoaa69a802008-11-17 14:14:51 -08001637 /* flush all endpoints */
1638 gadget_for_each_ep(ep, gadget) {
1639 usb_ep_fifo_flush(ep);
1640 }
Alexander Shishkind36ade62012-05-04 16:47:15 +03001641 usb_ep_fifo_flush(&udc->ep0out->ep);
1642 usb_ep_fifo_flush(&udc->ep0in->ep);
David Lopoaa69a802008-11-17 14:14:51 -08001643
1644 udc->driver->disconnect(gadget);
1645
1646 /* make sure to disable all endpoints */
1647 gadget_for_each_ep(ep, gadget) {
1648 usb_ep_disable(ep);
1649 }
David Lopoaa69a802008-11-17 14:14:51 -08001650
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301651 if (udc->status != NULL) {
Alexander Shishkind36ade62012-05-04 16:47:15 +03001652 usb_ep_free_request(&udc->ep0in->ep, udc->status);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301653 udc->status = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08001654 }
1655
David Lopoaa69a802008-11-17 14:14:51 -08001656 return 0;
1657}
1658
1659/******************************************************************************
1660 * ISR block
1661 *****************************************************************************/
1662/**
1663 * isr_reset_handler: USB reset interrupt handler
1664 * @udc: UDC device
1665 *
1666 * This function resets USB engine after a bus reset occurred
1667 */
1668static void isr_reset_handler(struct ci13xxx *udc)
1669__releases(udc->lock)
1670__acquires(udc->lock)
1671{
David Lopoaa69a802008-11-17 14:14:51 -08001672 int retval;
1673
1674 trace("%p", udc);
1675
1676 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001677 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08001678 return;
1679 }
1680
1681 dbg_event(0xFF, "BUS RST", 0);
1682
Alexander Shishkind3595d12012-05-08 23:28:58 +03001683 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001684 retval = _gadget_stop_activity(&udc->gadget);
1685 if (retval)
1686 goto done;
1687
Alexander Shishkind3595d12012-05-08 23:28:58 +03001688 retval = hw_usb_reset(udc);
David Lopoaa69a802008-11-17 14:14:51 -08001689 if (retval)
1690 goto done;
1691
Alexander Shishkind36ade62012-05-04 16:47:15 +03001692 udc->status = usb_ep_alloc_request(&udc->ep0in->ep, GFP_ATOMIC);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05301693 if (udc->status == NULL)
1694 retval = -ENOMEM;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301695
Alexander Shishkind3595d12012-05-08 23:28:58 +03001696 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001697
1698 done:
1699 if (retval)
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001700 pr_err("error: %i\n", retval);
David Lopoaa69a802008-11-17 14:14:51 -08001701}
1702
1703/**
1704 * isr_get_status_complete: get_status request complete function
1705 * @ep: endpoint
1706 * @req: request handled
1707 *
1708 * Caller must release lock
1709 */
1710static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
1711{
1712 trace("%p, %p", ep, req);
1713
1714 if (ep == NULL || req == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001715 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08001716 return;
1717 }
1718
1719 kfree(req->buf);
1720 usb_ep_free_request(ep, req);
1721}
1722
1723/**
1724 * isr_get_status_response: get_status request response
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301725 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001726 * @setup: setup request packet
1727 *
1728 * This function returns an error code
1729 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301730static int isr_get_status_response(struct ci13xxx *udc,
David Lopoaa69a802008-11-17 14:14:51 -08001731 struct usb_ctrlrequest *setup)
1732__releases(mEp->lock)
1733__acquires(mEp->lock)
1734{
Alexander Shishkind36ade62012-05-04 16:47:15 +03001735 struct ci13xxx_ep *mEp = udc->ep0in;
David Lopoaa69a802008-11-17 14:14:51 -08001736 struct usb_request *req = NULL;
1737 gfp_t gfp_flags = GFP_ATOMIC;
1738 int dir, num, retval;
1739
1740 trace("%p, %p", mEp, setup);
1741
1742 if (mEp == NULL || setup == NULL)
1743 return -EINVAL;
1744
1745 spin_unlock(mEp->lock);
1746 req = usb_ep_alloc_request(&mEp->ep, gfp_flags);
1747 spin_lock(mEp->lock);
1748 if (req == NULL)
1749 return -ENOMEM;
1750
1751 req->complete = isr_get_status_complete;
1752 req->length = 2;
1753 req->buf = kzalloc(req->length, gfp_flags);
1754 if (req->buf == NULL) {
1755 retval = -ENOMEM;
1756 goto err_free_req;
1757 }
1758
1759 if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301760 /* Assume that device is bus powered for now. */
Alexander Shishkin1155a7b2012-05-08 23:28:57 +03001761 *(u16 *)req->buf = _udc->remote_wakeup << 1;
David Lopoaa69a802008-11-17 14:14:51 -08001762 retval = 0;
1763 } else if ((setup->bRequestType & USB_RECIP_MASK) \
1764 == USB_RECIP_ENDPOINT) {
1765 dir = (le16_to_cpu(setup->wIndex) & USB_ENDPOINT_DIR_MASK) ?
1766 TX : RX;
1767 num = le16_to_cpu(setup->wIndex) & USB_ENDPOINT_NUMBER_MASK;
Alexander Shishkind3595d12012-05-08 23:28:58 +03001768 *(u16 *)req->buf = hw_ep_get_halt(udc, num, dir);
David Lopoaa69a802008-11-17 14:14:51 -08001769 }
1770 /* else do nothing; reserved for future use */
1771
1772 spin_unlock(mEp->lock);
1773 retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
1774 spin_lock(mEp->lock);
1775 if (retval)
1776 goto err_free_buf;
1777
1778 return 0;
1779
1780 err_free_buf:
1781 kfree(req->buf);
1782 err_free_req:
1783 spin_unlock(mEp->lock);
1784 usb_ep_free_request(&mEp->ep, req);
1785 spin_lock(mEp->lock);
1786 return retval;
1787}
1788
1789/**
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301790 * isr_setup_status_complete: setup_status request complete function
1791 * @ep: endpoint
1792 * @req: request handled
1793 *
1794 * Caller must release lock. Put the port in test mode if test mode
1795 * feature is selected.
1796 */
1797static void
1798isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
1799{
1800 struct ci13xxx *udc = req->context;
1801 unsigned long flags;
1802
1803 trace("%p, %p", ep, req);
1804
Alexander Shishkind3595d12012-05-08 23:28:58 +03001805 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301806 if (udc->test_mode)
Alexander Shishkind3595d12012-05-08 23:28:58 +03001807 hw_port_test_set(udc, udc->test_mode);
1808 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301809}
1810
1811/**
David Lopoaa69a802008-11-17 14:14:51 -08001812 * isr_setup_status_phase: queues the status phase of a setup transation
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301813 * @udc: udc struct
David Lopoaa69a802008-11-17 14:14:51 -08001814 *
1815 * This function returns an error code
1816 */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301817static int isr_setup_status_phase(struct ci13xxx *udc)
David Lopoaa69a802008-11-17 14:14:51 -08001818__releases(mEp->lock)
1819__acquires(mEp->lock)
1820{
1821 int retval;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301822 struct ci13xxx_ep *mEp;
David Lopoaa69a802008-11-17 14:14:51 -08001823
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301824 trace("%p", udc);
David Lopoaa69a802008-11-17 14:14:51 -08001825
Alexander Shishkind36ade62012-05-04 16:47:15 +03001826 mEp = (udc->ep0_dir == TX) ? udc->ep0out : udc->ep0in;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301827 udc->status->context = udc;
1828 udc->status->complete = isr_setup_status_complete;
David Lopoaa69a802008-11-17 14:14:51 -08001829
1830 spin_unlock(mEp->lock);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301831 retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
David Lopoaa69a802008-11-17 14:14:51 -08001832 spin_lock(mEp->lock);
1833
1834 return retval;
1835}
1836
1837/**
1838 * isr_tr_complete_low: transaction complete low level handler
1839 * @mEp: endpoint
1840 *
1841 * This function returns an error code
1842 * Caller must hold lock
1843 */
1844static int isr_tr_complete_low(struct ci13xxx_ep *mEp)
1845__releases(mEp->lock)
1846__acquires(mEp->lock)
1847{
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301848 struct ci13xxx_req *mReq, *mReqTemp;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301849 struct ci13xxx_ep *mEpTemp = mEp;
Pavankumar Kondeti986b11b2011-05-02 11:56:29 +05301850 int uninitialized_var(retval);
David Lopoaa69a802008-11-17 14:14:51 -08001851
1852 trace("%p", mEp);
1853
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301854 if (list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08001855 return -EINVAL;
1856
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301857 list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue,
1858 queue) {
1859 retval = _hardware_dequeue(mEp, mReq);
1860 if (retval < 0)
1861 break;
1862 list_del_init(&mReq->queue);
1863 dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
1864 if (mReq->req.complete != NULL) {
1865 spin_unlock(mEp->lock);
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301866 if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
1867 mReq->req.length)
Alexander Shishkind36ade62012-05-04 16:47:15 +03001868 mEpTemp = _udc->ep0in;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05301869 mReq->req.complete(&mEpTemp->ep, &mReq->req);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301870 spin_lock(mEp->lock);
1871 }
1872 }
David Lopoaa69a802008-11-17 14:14:51 -08001873
Pavankumar Kondetief907482011-05-02 11:56:27 +05301874 if (retval == -EBUSY)
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05301875 retval = 0;
1876 if (retval < 0)
David Lopoaa69a802008-11-17 14:14:51 -08001877 dbg_event(_usb_addr(mEp), "DONE", retval);
David Lopoaa69a802008-11-17 14:14:51 -08001878
David Lopoaa69a802008-11-17 14:14:51 -08001879 return retval;
1880}
1881
1882/**
1883 * isr_tr_complete_handler: transaction complete interrupt handler
1884 * @udc: UDC descriptor
1885 *
1886 * This function handles traffic events
1887 */
1888static void isr_tr_complete_handler(struct ci13xxx *udc)
1889__releases(udc->lock)
1890__acquires(udc->lock)
1891{
1892 unsigned i;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05301893 u8 tmode = 0;
David Lopoaa69a802008-11-17 14:14:51 -08001894
1895 trace("%p", udc);
1896
1897 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001898 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08001899 return;
1900 }
1901
Alexander Shishkind3595d12012-05-08 23:28:58 +03001902 for (i = 0; i < udc->hw_ep_max; i++) {
David Lopoaa69a802008-11-17 14:14:51 -08001903 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301904 int type, num, dir, err = -EINVAL;
David Lopoaa69a802008-11-17 14:14:51 -08001905 struct usb_ctrlrequest req;
1906
Ido Shayevitz31fb6012012-03-12 20:25:23 +02001907 if (mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08001908 continue; /* not configured */
1909
Alexander Shishkind3595d12012-05-08 23:28:58 +03001910 if (hw_test_and_clear_complete(udc, i)) {
David Lopoaa69a802008-11-17 14:14:51 -08001911 err = isr_tr_complete_low(mEp);
1912 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
1913 if (err > 0) /* needs status phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301914 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08001915 if (err < 0) {
1916 dbg_event(_usb_addr(mEp),
1917 "ERROR", err);
Alexander Shishkind3595d12012-05-08 23:28:58 +03001918 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001919 if (usb_ep_set_halt(&mEp->ep))
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001920 dev_err(&udc->gadget.dev,
1921 "error: ep_set_halt\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03001922 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08001923 }
1924 }
1925 }
1926
1927 if (mEp->type != USB_ENDPOINT_XFER_CONTROL ||
Alexander Shishkind3595d12012-05-08 23:28:58 +03001928 !hw_test_and_clear_setup_status(udc, i))
David Lopoaa69a802008-11-17 14:14:51 -08001929 continue;
1930
1931 if (i != 0) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07001932 dev_warn(&udc->gadget.dev,
1933 "ctrl traffic received at endpoint\n");
David Lopoaa69a802008-11-17 14:14:51 -08001934 continue;
1935 }
1936
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301937 /*
1938 * Flush data and handshake transactions of previous
1939 * setup packet.
1940 */
Alexander Shishkind36ade62012-05-04 16:47:15 +03001941 _ep_nuke(udc->ep0out);
1942 _ep_nuke(udc->ep0in);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301943
David Lopoaa69a802008-11-17 14:14:51 -08001944 /* read_setup_packet */
1945 do {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001946 hw_test_and_set_setup_guard(udc);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301947 memcpy(&req, &mEp->qh.ptr->setup, sizeof(req));
Alexander Shishkind3595d12012-05-08 23:28:58 +03001948 } while (!hw_test_and_clear_setup_guard(udc));
David Lopoaa69a802008-11-17 14:14:51 -08001949
1950 type = req.bRequestType;
1951
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301952 udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX;
David Lopoaa69a802008-11-17 14:14:51 -08001953
1954 dbg_setup(_usb_addr(mEp), &req);
1955
1956 switch (req.bRequest) {
1957 case USB_REQ_CLEAR_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301958 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
1959 le16_to_cpu(req.wValue) ==
1960 USB_ENDPOINT_HALT) {
1961 if (req.wLength != 0)
David Lopoaa69a802008-11-17 14:14:51 -08001962 break;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301963 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301964 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301965 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05301966 if (dir) /* TX */
Alexander Shishkind3595d12012-05-08 23:28:58 +03001967 num += udc->hw_ep_max/2;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301968 if (!udc->ci13xxx_ep[num].wedge) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03001969 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301970 err = usb_ep_clear_halt(
1971 &udc->ci13xxx_ep[num].ep);
Alexander Shishkind3595d12012-05-08 23:28:58 +03001972 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05301973 if (err)
1974 break;
1975 }
1976 err = isr_setup_status_phase(udc);
1977 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE) &&
1978 le16_to_cpu(req.wValue) ==
1979 USB_DEVICE_REMOTE_WAKEUP) {
1980 if (req.wLength != 0)
1981 break;
1982 udc->remote_wakeup = 0;
1983 err = isr_setup_status_phase(udc);
1984 } else {
1985 goto delegate;
David Lopoaa69a802008-11-17 14:14:51 -08001986 }
David Lopoaa69a802008-11-17 14:14:51 -08001987 break;
1988 case USB_REQ_GET_STATUS:
1989 if (type != (USB_DIR_IN|USB_RECIP_DEVICE) &&
1990 type != (USB_DIR_IN|USB_RECIP_ENDPOINT) &&
1991 type != (USB_DIR_IN|USB_RECIP_INTERFACE))
1992 goto delegate;
1993 if (le16_to_cpu(req.wLength) != 2 ||
1994 le16_to_cpu(req.wValue) != 0)
1995 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05301996 err = isr_get_status_response(udc, &req);
David Lopoaa69a802008-11-17 14:14:51 -08001997 break;
1998 case USB_REQ_SET_ADDRESS:
1999 if (type != (USB_DIR_OUT|USB_RECIP_DEVICE))
2000 goto delegate;
2001 if (le16_to_cpu(req.wLength) != 0 ||
2002 le16_to_cpu(req.wIndex) != 0)
2003 break;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002004 err = hw_usb_set_address(udc,
2005 (u8)le16_to_cpu(req.wValue));
David Lopoaa69a802008-11-17 14:14:51 -08002006 if (err)
2007 break;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302008 err = isr_setup_status_phase(udc);
David Lopoaa69a802008-11-17 14:14:51 -08002009 break;
2010 case USB_REQ_SET_FEATURE:
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302011 if (type == (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
2012 le16_to_cpu(req.wValue) ==
2013 USB_ENDPOINT_HALT) {
2014 if (req.wLength != 0)
2015 break;
2016 num = le16_to_cpu(req.wIndex);
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302017 dir = num & USB_ENDPOINT_DIR_MASK;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302018 num &= USB_ENDPOINT_NUMBER_MASK;
Pavankumar Kondeti4c5212b2011-05-02 11:56:30 +05302019 if (dir) /* TX */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002020 num += udc->hw_ep_max/2;
David Lopoaa69a802008-11-17 14:14:51 -08002021
Alexander Shishkind3595d12012-05-08 23:28:58 +03002022 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302023 err = usb_ep_set_halt(&udc->ci13xxx_ep[num].ep);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002024 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302025 if (!err)
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302026 isr_setup_status_phase(udc);
2027 } else if (type == (USB_DIR_OUT|USB_RECIP_DEVICE)) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302028 if (req.wLength != 0)
2029 break;
Pavankumar Kondeti541cace2011-02-18 17:43:18 +05302030 switch (le16_to_cpu(req.wValue)) {
2031 case USB_DEVICE_REMOTE_WAKEUP:
2032 udc->remote_wakeup = 1;
2033 err = isr_setup_status_phase(udc);
2034 break;
2035 case USB_DEVICE_TEST_MODE:
2036 tmode = le16_to_cpu(req.wIndex) >> 8;
2037 switch (tmode) {
2038 case TEST_J:
2039 case TEST_K:
2040 case TEST_SE0_NAK:
2041 case TEST_PACKET:
2042 case TEST_FORCE_EN:
2043 udc->test_mode = tmode;
2044 err = isr_setup_status_phase(
2045 udc);
2046 break;
2047 default:
2048 break;
2049 }
2050 default:
2051 goto delegate;
2052 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302053 } else {
2054 goto delegate;
2055 }
David Lopoaa69a802008-11-17 14:14:51 -08002056 break;
2057 default:
2058delegate:
2059 if (req.wLength == 0) /* no data phase */
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302060 udc->ep0_dir = TX;
David Lopoaa69a802008-11-17 14:14:51 -08002061
Alexander Shishkind3595d12012-05-08 23:28:58 +03002062 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002063 err = udc->driver->setup(&udc->gadget, &req);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002064 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002065 break;
2066 }
2067
2068 if (err < 0) {
2069 dbg_event(_usb_addr(mEp), "ERROR", err);
2070
Alexander Shishkind3595d12012-05-08 23:28:58 +03002071 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002072 if (usb_ep_set_halt(&mEp->ep))
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002073 dev_err(&udc->gadget.dev,
2074 "error: ep_set_halt\n");
Alexander Shishkind3595d12012-05-08 23:28:58 +03002075 spin_lock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002076 }
2077 }
2078}
2079
2080/******************************************************************************
2081 * ENDPT block
2082 *****************************************************************************/
2083/**
2084 * ep_enable: configure endpoint, making it usable
2085 *
2086 * Check usb_ep_enable() at "usb_gadget.h" for details
2087 */
2088static int ep_enable(struct usb_ep *ep,
2089 const struct usb_endpoint_descriptor *desc)
2090{
2091 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302092 int retval = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002093 unsigned long flags;
2094
2095 trace("%p, %p", ep, desc);
2096
2097 if (ep == NULL || desc == NULL)
2098 return -EINVAL;
2099
2100 spin_lock_irqsave(mEp->lock, flags);
2101
2102 /* only internal SW should enable ctrl endpts */
2103
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002104 mEp->ep.desc = desc;
David Lopoaa69a802008-11-17 14:14:51 -08002105
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302106 if (!list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002107 warn("enabling a non-empty endpoint!");
2108
Matthias Kaehlcke15739bb2009-04-15 22:28:41 +02002109 mEp->dir = usb_endpoint_dir_in(desc) ? TX : RX;
2110 mEp->num = usb_endpoint_num(desc);
2111 mEp->type = usb_endpoint_type(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002112
Kuninori Morimoto29cc8892011-08-23 03:12:03 -07002113 mEp->ep.maxpacket = usb_endpoint_maxp(desc);
David Lopoaa69a802008-11-17 14:14:51 -08002114
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302115 dbg_event(_usb_addr(mEp), "ENABLE", 0);
David Lopoaa69a802008-11-17 14:14:51 -08002116
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302117 mEp->qh.ptr->cap = 0;
David Lopof23e6492009-04-16 14:35:24 -07002118
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302119 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2120 mEp->qh.ptr->cap |= QH_IOS;
2121 else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
2122 mEp->qh.ptr->cap &= ~QH_MULT;
2123 else
2124 mEp->qh.ptr->cap &= ~QH_ZLT;
David Lopoaa69a802008-11-17 14:14:51 -08002125
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302126 mEp->qh.ptr->cap |=
2127 (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
2128 mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */
David Lopoaa69a802008-11-17 14:14:51 -08002129
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302130 /*
2131 * Enable endpoints in the HW other than ep0 as ep0
2132 * is always enabled
2133 */
2134 if (mEp->num)
Alexander Shishkind3595d12012-05-08 23:28:58 +03002135 retval |= hw_ep_enable(mEp->udc, mEp->num, mEp->dir, mEp->type);
David Lopoaa69a802008-11-17 14:14:51 -08002136
2137 spin_unlock_irqrestore(mEp->lock, flags);
2138 return retval;
2139}
2140
2141/**
2142 * ep_disable: endpoint is no longer usable
2143 *
2144 * Check usb_ep_disable() at "usb_gadget.h" for details
2145 */
2146static int ep_disable(struct usb_ep *ep)
2147{
2148 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2149 int direction, retval = 0;
2150 unsigned long flags;
2151
2152 trace("%p", ep);
2153
2154 if (ep == NULL)
2155 return -EINVAL;
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002156 else if (mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002157 return -EBUSY;
2158
2159 spin_lock_irqsave(mEp->lock, flags);
2160
2161 /* only internal SW should disable ctrl endpts */
2162
2163 direction = mEp->dir;
2164 do {
2165 dbg_event(_usb_addr(mEp), "DISABLE", 0);
2166
2167 retval |= _ep_nuke(mEp);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002168 retval |= hw_ep_disable(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002169
2170 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2171 mEp->dir = (mEp->dir == TX) ? RX : TX;
2172
2173 } while (mEp->dir != direction);
2174
Ido Shayevitzf9c56cd2012-02-08 13:56:48 +02002175 mEp->ep.desc = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002176
2177 spin_unlock_irqrestore(mEp->lock, flags);
2178 return retval;
2179}
2180
2181/**
2182 * ep_alloc_request: allocate a request object to use with this endpoint
2183 *
2184 * Check usb_ep_alloc_request() at "usb_gadget.h" for details
2185 */
2186static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
2187{
2188 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2189 struct ci13xxx_req *mReq = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002190
2191 trace("%p, %i", ep, gfp_flags);
2192
2193 if (ep == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002194 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08002195 return NULL;
2196 }
2197
David Lopoaa69a802008-11-17 14:14:51 -08002198 mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
2199 if (mReq != NULL) {
2200 INIT_LIST_HEAD(&mReq->queue);
Michael Grzeschik954aad82011-10-10 18:38:06 +02002201 mReq->req.dma = DMA_ADDR_INVALID;
David Lopoaa69a802008-11-17 14:14:51 -08002202
2203 mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
2204 &mReq->dma);
2205 if (mReq->ptr == NULL) {
2206 kfree(mReq);
2207 mReq = NULL;
2208 }
2209 }
2210
2211 dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL);
2212
David Lopoaa69a802008-11-17 14:14:51 -08002213 return (mReq == NULL) ? NULL : &mReq->req;
2214}
2215
2216/**
2217 * ep_free_request: frees a request object
2218 *
2219 * Check usb_ep_free_request() at "usb_gadget.h" for details
2220 */
2221static void ep_free_request(struct usb_ep *ep, struct usb_request *req)
2222{
2223 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2224 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2225 unsigned long flags;
2226
2227 trace("%p, %p", ep, req);
2228
2229 if (ep == NULL || req == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002230 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08002231 return;
2232 } else if (!list_empty(&mReq->queue)) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002233 pr_err("EBUSY\n");
David Lopoaa69a802008-11-17 14:14:51 -08002234 return;
2235 }
2236
2237 spin_lock_irqsave(mEp->lock, flags);
2238
2239 if (mReq->ptr)
2240 dma_pool_free(mEp->td_pool, mReq->ptr, mReq->dma);
2241 kfree(mReq);
2242
2243 dbg_event(_usb_addr(mEp), "FREE", 0);
2244
2245 spin_unlock_irqrestore(mEp->lock, flags);
2246}
2247
2248/**
2249 * ep_queue: queues (submits) an I/O request to an endpoint
2250 *
2251 * Check usb_ep_queue()* at usb_gadget.h" for details
2252 */
2253static int ep_queue(struct usb_ep *ep, struct usb_request *req,
2254 gfp_t __maybe_unused gfp_flags)
2255{
2256 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2257 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2258 int retval = 0;
2259 unsigned long flags;
2260
2261 trace("%p, %p, %X", ep, req, gfp_flags);
2262
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002263 if (ep == NULL || req == NULL || mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002264 return -EINVAL;
2265
2266 spin_lock_irqsave(mEp->lock, flags);
2267
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302268 if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
2269 if (req->length)
2270 mEp = (_udc->ep0_dir == RX) ?
Alexander Shishkind36ade62012-05-04 16:47:15 +03002271 _udc->ep0out : _udc->ep0in;
Pavankumar Kondeti76cd9cf2011-05-02 11:56:31 +05302272 if (!list_empty(&mEp->qh.queue)) {
2273 _ep_nuke(mEp);
2274 retval = -EOVERFLOW;
2275 warn("endpoint ctrl %X nuked", _usb_addr(mEp));
2276 }
David Lopoaa69a802008-11-17 14:14:51 -08002277 }
2278
2279 /* first nuke then test link, e.g. previous status has not sent */
2280 if (!list_empty(&mReq->queue)) {
2281 retval = -EBUSY;
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002282 pr_err("request already in queue\n");
David Lopoaa69a802008-11-17 14:14:51 -08002283 goto done;
2284 }
2285
Alexander Shishkin1155a7b2012-05-08 23:28:57 +03002286 if (req->length > 4 * CI13XXX_PAGE_SIZE) {
2287 req->length = 4 * CI13XXX_PAGE_SIZE;
David Lopoaa69a802008-11-17 14:14:51 -08002288 retval = -EMSGSIZE;
2289 warn("request length truncated");
2290 }
2291
2292 dbg_queue(_usb_addr(mEp), req, retval);
2293
2294 /* push request */
2295 mReq->req.status = -EINPROGRESS;
2296 mReq->req.actual = 0;
David Lopoaa69a802008-11-17 14:14:51 -08002297
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302298 retval = _hardware_enqueue(mEp, mReq);
Artem Leonenkod9bb9c12010-12-14 23:45:50 -08002299
2300 if (retval == -EALREADY) {
David Lopoaa69a802008-11-17 14:14:51 -08002301 dbg_event(_usb_addr(mEp), "QUEUE", retval);
2302 retval = 0;
2303 }
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302304 if (!retval)
2305 list_add_tail(&mReq->queue, &mEp->qh.queue);
David Lopoaa69a802008-11-17 14:14:51 -08002306
2307 done:
2308 spin_unlock_irqrestore(mEp->lock, flags);
2309 return retval;
2310}
2311
2312/**
2313 * ep_dequeue: dequeues (cancels, unlinks) an I/O request from an endpoint
2314 *
2315 * Check usb_ep_dequeue() at "usb_gadget.h" for details
2316 */
2317static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
2318{
2319 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2320 struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
2321 unsigned long flags;
2322
2323 trace("%p, %p", ep, req);
2324
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302325 if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002326 mEp->ep.desc == NULL || list_empty(&mReq->queue) ||
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302327 list_empty(&mEp->qh.queue))
David Lopoaa69a802008-11-17 14:14:51 -08002328 return -EINVAL;
2329
2330 spin_lock_irqsave(mEp->lock, flags);
2331
2332 dbg_event(_usb_addr(mEp), "DEQUEUE", 0);
2333
Alexander Shishkind3595d12012-05-08 23:28:58 +03002334 hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002335
2336 /* pop request */
2337 list_del_init(&mReq->queue);
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302338 if (mReq->map) {
2339 dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
2340 mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
Michael Grzeschik954aad82011-10-10 18:38:06 +02002341 mReq->req.dma = DMA_ADDR_INVALID;
Pavankumar Kondeti0e6ca192011-02-18 17:43:16 +05302342 mReq->map = 0;
2343 }
David Lopoaa69a802008-11-17 14:14:51 -08002344 req->status = -ECONNRESET;
2345
Artem Leonenko7c25a822010-12-14 23:46:55 -08002346 if (mReq->req.complete != NULL) {
David Lopoaa69a802008-11-17 14:14:51 -08002347 spin_unlock(mEp->lock);
2348 mReq->req.complete(&mEp->ep, &mReq->req);
2349 spin_lock(mEp->lock);
2350 }
2351
2352 spin_unlock_irqrestore(mEp->lock, flags);
2353 return 0;
2354}
2355
2356/**
2357 * ep_set_halt: sets the endpoint halt feature
2358 *
2359 * Check usb_ep_set_halt() at "usb_gadget.h" for details
2360 */
2361static int ep_set_halt(struct usb_ep *ep, int value)
2362{
2363 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2364 int direction, retval = 0;
2365 unsigned long flags;
2366
2367 trace("%p, %i", ep, value);
2368
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002369 if (ep == NULL || mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002370 return -EINVAL;
2371
2372 spin_lock_irqsave(mEp->lock, flags);
2373
2374#ifndef STALL_IN
2375 /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
2376 if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302377 !list_empty(&mEp->qh.queue)) {
David Lopoaa69a802008-11-17 14:14:51 -08002378 spin_unlock_irqrestore(mEp->lock, flags);
2379 return -EAGAIN;
2380 }
2381#endif
2382
2383 direction = mEp->dir;
2384 do {
2385 dbg_event(_usb_addr(mEp), "HALT", value);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002386 retval |= hw_ep_set_halt(mEp->udc, mEp->num, mEp->dir, value);
David Lopoaa69a802008-11-17 14:14:51 -08002387
2388 if (!value)
2389 mEp->wedge = 0;
2390
2391 if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
2392 mEp->dir = (mEp->dir == TX) ? RX : TX;
2393
2394 } while (mEp->dir != direction);
2395
2396 spin_unlock_irqrestore(mEp->lock, flags);
2397 return retval;
2398}
2399
2400/**
2401 * ep_set_wedge: sets the halt feature and ignores clear requests
2402 *
2403 * Check usb_ep_set_wedge() at "usb_gadget.h" for details
2404 */
2405static int ep_set_wedge(struct usb_ep *ep)
2406{
2407 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2408 unsigned long flags;
2409
2410 trace("%p", ep);
2411
Ido Shayevitz31fb6012012-03-12 20:25:23 +02002412 if (ep == NULL || mEp->ep.desc == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002413 return -EINVAL;
2414
2415 spin_lock_irqsave(mEp->lock, flags);
2416
2417 dbg_event(_usb_addr(mEp), "WEDGE", 0);
2418 mEp->wedge = 1;
2419
2420 spin_unlock_irqrestore(mEp->lock, flags);
2421
2422 return usb_ep_set_halt(ep);
2423}
2424
2425/**
2426 * ep_fifo_flush: flushes contents of a fifo
2427 *
2428 * Check usb_ep_fifo_flush() at "usb_gadget.h" for details
2429 */
2430static void ep_fifo_flush(struct usb_ep *ep)
2431{
2432 struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
2433 unsigned long flags;
2434
2435 trace("%p", ep);
2436
2437 if (ep == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002438 pr_err("%02X: -EINVAL\n", _usb_addr(mEp));
David Lopoaa69a802008-11-17 14:14:51 -08002439 return;
2440 }
2441
2442 spin_lock_irqsave(mEp->lock, flags);
2443
2444 dbg_event(_usb_addr(mEp), "FFLUSH", 0);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002445 hw_ep_flush(mEp->udc, mEp->num, mEp->dir);
David Lopoaa69a802008-11-17 14:14:51 -08002446
2447 spin_unlock_irqrestore(mEp->lock, flags);
2448}
2449
2450/**
2451 * Endpoint-specific part of the API to the USB controller hardware
2452 * Check "usb_gadget.h" for details
2453 */
2454static const struct usb_ep_ops usb_ep_ops = {
2455 .enable = ep_enable,
2456 .disable = ep_disable,
2457 .alloc_request = ep_alloc_request,
2458 .free_request = ep_free_request,
2459 .queue = ep_queue,
2460 .dequeue = ep_dequeue,
2461 .set_halt = ep_set_halt,
2462 .set_wedge = ep_set_wedge,
2463 .fifo_flush = ep_fifo_flush,
2464};
2465
2466/******************************************************************************
2467 * GADGET block
2468 *****************************************************************************/
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302469static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
2470{
2471 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2472 unsigned long flags;
2473 int gadget_ready = 0;
2474
2475 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS))
2476 return -EOPNOTSUPP;
2477
Alexander Shishkind3595d12012-05-08 23:28:58 +03002478 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302479 udc->vbus_active = is_active;
2480 if (udc->driver)
2481 gadget_ready = 1;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002482 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302483
2484 if (gadget_ready) {
2485 if (is_active) {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302486 pm_runtime_get_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302487 hw_device_reset(udc);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002488 hw_device_state(udc, udc->ep0out->qh.dma);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302489 } else {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002490 hw_device_state(udc, 0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302491 if (udc->udc_driver->notify_event)
2492 udc->udc_driver->notify_event(udc,
2493 CI13XXX_CONTROLLER_STOPPED_EVENT);
2494 _gadget_stop_activity(&udc->gadget);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302495 pm_runtime_put_sync(&_gadget->dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302496 }
2497 }
2498
2499 return 0;
2500}
2501
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302502static int ci13xxx_wakeup(struct usb_gadget *_gadget)
2503{
2504 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2505 unsigned long flags;
2506 int ret = 0;
2507
2508 trace();
2509
Alexander Shishkind3595d12012-05-08 23:28:58 +03002510 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302511 if (!udc->remote_wakeup) {
2512 ret = -EOPNOTSUPP;
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002513 trace("remote wakeup feature is not enabled\n");
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302514 goto out;
2515 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03002516 if (!hw_read(udc->hw_bank.op, OP_PORTSC, PORTSC_SUSP)) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302517 ret = -EINVAL;
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002518 trace("port is not suspended\n");
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302519 goto out;
2520 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03002521 hw_write(udc->hw_bank.op, OP_PORTSC, PORTSC_FPR, PORTSC_FPR);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302522out:
Alexander Shishkind3595d12012-05-08 23:28:58 +03002523 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302524 return ret;
2525}
2526
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302527static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
2528{
2529 struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget);
2530
2531 if (udc->transceiver)
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002532 return usb_phy_set_power(udc->transceiver, mA);
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302533 return -ENOTSUPP;
2534}
2535
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002536static int ci13xxx_start(struct usb_gadget_driver *driver,
2537 int (*bind)(struct usb_gadget *));
2538static int ci13xxx_stop(struct usb_gadget_driver *driver);
David Lopoaa69a802008-11-17 14:14:51 -08002539/**
2540 * Device operations part of the API to the USB controller hardware,
2541 * which don't involve endpoints (or i/o)
2542 * Check "usb_gadget.h" for details
2543 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302544static const struct usb_gadget_ops usb_gadget_ops = {
2545 .vbus_session = ci13xxx_vbus_session,
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302546 .wakeup = ci13xxx_wakeup,
Pavankumar Kondetid8608522011-05-04 10:19:47 +05302547 .vbus_draw = ci13xxx_vbus_draw,
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002548 .start = ci13xxx_start,
2549 .stop = ci13xxx_stop,
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302550};
David Lopoaa69a802008-11-17 14:14:51 -08002551
2552/**
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002553 * ci13xxx_start: register a gadget driver
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002554 * @driver: the driver being registered
2555 * @bind: the driver's bind callback
David Lopoaa69a802008-11-17 14:14:51 -08002556 *
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002557 * Check ci13xxx_start() at <linux/usb/gadget.h> for details.
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002558 * Interrupts are enabled here.
David Lopoaa69a802008-11-17 14:14:51 -08002559 */
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002560static int ci13xxx_start(struct usb_gadget_driver *driver,
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002561 int (*bind)(struct usb_gadget *))
David Lopoaa69a802008-11-17 14:14:51 -08002562{
2563 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302564 unsigned long flags;
2565 int i, j;
David Lopoaa69a802008-11-17 14:14:51 -08002566 int retval = -ENOMEM;
2567
2568 trace("%p", driver);
2569
2570 if (driver == NULL ||
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002571 bind == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002572 driver->setup == NULL ||
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002573 driver->disconnect == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002574 return -EINVAL;
2575 else if (udc == NULL)
2576 return -ENODEV;
2577 else if (udc->driver != NULL)
2578 return -EBUSY;
2579
2580 /* alloc resources */
2581 udc->qh_pool = dma_pool_create("ci13xxx_qh", &udc->gadget.dev,
2582 sizeof(struct ci13xxx_qh),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002583 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002584 if (udc->qh_pool == NULL)
2585 return -ENOMEM;
2586
2587 udc->td_pool = dma_pool_create("ci13xxx_td", &udc->gadget.dev,
2588 sizeof(struct ci13xxx_td),
Artem Leonenko0a313c42010-12-14 23:47:06 -08002589 64, CI13XXX_PAGE_SIZE);
David Lopoaa69a802008-11-17 14:14:51 -08002590 if (udc->td_pool == NULL) {
2591 dma_pool_destroy(udc->qh_pool);
2592 udc->qh_pool = NULL;
2593 return -ENOMEM;
2594 }
2595
Alexander Shishkind3595d12012-05-08 23:28:58 +03002596 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002597
Alexander Shishkind3595d12012-05-08 23:28:58 +03002598 info("hw_ep_max = %d", udc->hw_ep_max);
David Lopoaa69a802008-11-17 14:14:51 -08002599
David Lopoaa69a802008-11-17 14:14:51 -08002600 udc->gadget.dev.driver = NULL;
2601
2602 retval = 0;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002603 for (i = 0; i < udc->hw_ep_max/2; i++) {
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302604 for (j = RX; j <= TX; j++) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002605 int k = i + j * udc->hw_ep_max/2;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302606 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k];
David Lopoaa69a802008-11-17 14:14:51 -08002607
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302608 scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i,
2609 (j == TX) ? "in" : "out");
David Lopoaa69a802008-11-17 14:14:51 -08002610
Alexander Shishkind3595d12012-05-08 23:28:58 +03002611 mEp->udc = udc;
2612 mEp->lock = &udc->lock;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302613 mEp->device = &udc->gadget.dev;
2614 mEp->td_pool = udc->td_pool;
David Lopoaa69a802008-11-17 14:14:51 -08002615
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302616 mEp->ep.name = mEp->name;
2617 mEp->ep.ops = &usb_ep_ops;
2618 mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
David Lopoaa69a802008-11-17 14:14:51 -08002619
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302620 INIT_LIST_HEAD(&mEp->qh.queue);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002621 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302622 mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL,
2623 &mEp->qh.dma);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002624 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302625 if (mEp->qh.ptr == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002626 retval = -ENOMEM;
2627 else
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302628 memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr));
2629
Alexander Shishkind36ade62012-05-04 16:47:15 +03002630 /*
2631 * set up shorthands for ep0 out and in endpoints,
2632 * don't add to gadget's ep_list
2633 */
2634 if (i == 0) {
2635 if (j == RX)
2636 udc->ep0out = mEp;
2637 else
2638 udc->ep0in = mEp;
2639
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302640 continue;
Alexander Shishkind36ade62012-05-04 16:47:15 +03002641 }
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302642
David Lopoaa69a802008-11-17 14:14:51 -08002643 list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list);
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302644 }
David Lopoaa69a802008-11-17 14:14:51 -08002645 }
2646 if (retval)
2647 goto done;
Alexander Shishkind36ade62012-05-04 16:47:15 +03002648
Alexander Shishkind3595d12012-05-08 23:28:58 +03002649 spin_unlock_irqrestore(&udc->lock, flags);
Alexander Shishkind36ade62012-05-04 16:47:15 +03002650 udc->ep0out->ep.desc = &ctrl_endpt_out_desc;
2651 retval = usb_ep_enable(&udc->ep0out->ep);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302652 if (retval)
2653 return retval;
Felipe Balbi877c1f52011-06-29 16:41:57 +03002654
Alexander Shishkind36ade62012-05-04 16:47:15 +03002655 udc->ep0in->ep.desc = &ctrl_endpt_in_desc;
2656 retval = usb_ep_enable(&udc->ep0in->ep);
Anji jonnalaac1aa6a2011-05-02 11:56:32 +05302657 if (retval)
2658 return retval;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002659 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002660
Alexander Shishkind36ade62012-05-04 16:47:15 +03002661 udc->gadget.ep0 = &udc->ep0in->ep;
David Lopoaa69a802008-11-17 14:14:51 -08002662 /* bind gadget */
2663 driver->driver.bus = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002664 udc->gadget.dev.driver = &driver->driver;
2665
Alexander Shishkind3595d12012-05-08 23:28:58 +03002666 spin_unlock_irqrestore(&udc->lock, flags);
Uwe Kleine-Königb0fca502010-08-12 17:43:53 +02002667 retval = bind(&udc->gadget); /* MAY SLEEP */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002668 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002669
2670 if (retval) {
David Lopoaa69a802008-11-17 14:14:51 -08002671 udc->gadget.dev.driver = NULL;
2672 goto done;
2673 }
2674
Pavankumar Kondeti49d3df52011-01-11 09:19:21 +05302675 udc->driver = driver;
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302676 pm_runtime_get_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302677 if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) {
2678 if (udc->vbus_active) {
2679 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED)
2680 hw_device_reset(udc);
2681 } else {
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302682 pm_runtime_put_sync(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302683 goto done;
2684 }
2685 }
2686
Alexander Shishkind3595d12012-05-08 23:28:58 +03002687 retval = hw_device_state(udc, udc->ep0out->qh.dma);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302688 if (retval)
2689 pm_runtime_put_sync(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002690
2691 done:
Alexander Shishkind3595d12012-05-08 23:28:58 +03002692 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002693 return retval;
2694}
David Lopoaa69a802008-11-17 14:14:51 -08002695
2696/**
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002697 * ci13xxx_stop: unregister a gadget driver
David Lopoaa69a802008-11-17 14:14:51 -08002698 *
2699 * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
2700 */
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002701static int ci13xxx_stop(struct usb_gadget_driver *driver)
David Lopoaa69a802008-11-17 14:14:51 -08002702{
2703 struct ci13xxx *udc = _udc;
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302704 unsigned long i, flags;
David Lopoaa69a802008-11-17 14:14:51 -08002705
2706 trace("%p", driver);
2707
2708 if (driver == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002709 driver->unbind == NULL ||
2710 driver->setup == NULL ||
2711 driver->disconnect == NULL ||
David Lopoaa69a802008-11-17 14:14:51 -08002712 driver != udc->driver)
2713 return -EINVAL;
2714
Alexander Shishkind3595d12012-05-08 23:28:58 +03002715 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002716
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302717 if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) ||
2718 udc->vbus_active) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002719 hw_device_state(udc, 0);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302720 if (udc->udc_driver->notify_event)
2721 udc->udc_driver->notify_event(udc,
2722 CI13XXX_CONTROLLER_STOPPED_EVENT);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002723 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302724 _gadget_stop_activity(&udc->gadget);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002725 spin_lock_irqsave(&udc->lock, flags);
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302726 pm_runtime_put(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302727 }
David Lopoaa69a802008-11-17 14:14:51 -08002728
2729 /* unbind gadget */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002730 spin_unlock_irqrestore(&udc->lock, flags);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302731 driver->unbind(&udc->gadget); /* MAY SLEEP */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002732 spin_lock_irqsave(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002733
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302734 udc->gadget.dev.driver = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002735
2736 /* free resources */
Alexander Shishkind3595d12012-05-08 23:28:58 +03002737 for (i = 0; i < udc->hw_ep_max; i++) {
David Lopoaa69a802008-11-17 14:14:51 -08002738 struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
2739
Alexander Shishkinefa015b2012-05-04 16:47:14 +03002740 if (mEp->num)
David Lopoaa69a802008-11-17 14:14:51 -08002741 list_del_init(&mEp->ep.ep_list);
2742
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302743 if (mEp->qh.ptr != NULL)
2744 dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
David Lopoaa69a802008-11-17 14:14:51 -08002745 }
2746
Pavankumar Kondetica9cfea2011-01-11 09:19:22 +05302747 udc->gadget.ep0 = NULL;
David Lopoaa69a802008-11-17 14:14:51 -08002748 udc->driver = NULL;
2749
Alexander Shishkind3595d12012-05-08 23:28:58 +03002750 spin_unlock_irqrestore(&udc->lock, flags);
David Lopoaa69a802008-11-17 14:14:51 -08002751
2752 if (udc->td_pool != NULL) {
2753 dma_pool_destroy(udc->td_pool);
2754 udc->td_pool = NULL;
2755 }
2756 if (udc->qh_pool != NULL) {
2757 dma_pool_destroy(udc->qh_pool);
2758 udc->qh_pool = NULL;
2759 }
2760
2761 return 0;
2762}
David Lopoaa69a802008-11-17 14:14:51 -08002763
2764/******************************************************************************
2765 * BUS block
2766 *****************************************************************************/
2767/**
2768 * udc_irq: global interrupt handler
2769 *
2770 * This function returns IRQ_HANDLED if the IRQ has been handled
2771 * It locks access to registers
2772 */
2773static irqreturn_t udc_irq(void)
2774{
2775 struct ci13xxx *udc = _udc;
2776 irqreturn_t retval;
2777 u32 intr;
2778
2779 trace();
2780
2781 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002782 pr_err("ENODEV\n");
David Lopoaa69a802008-11-17 14:14:51 -08002783 return IRQ_HANDLED;
2784 }
2785
Alexander Shishkind3595d12012-05-08 23:28:58 +03002786 spin_lock(&udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302787
2788 if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002789 if (hw_read(udc->hw_bank.op, OP_USBMODE, USBMODE_CM) !=
Alexander Shishkinf9df8392012-05-04 16:47:16 +03002790 USBMODE_CM_DEVICE) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002791 spin_unlock(&udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302792 return IRQ_NONE;
2793 }
2794 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03002795 intr = hw_test_and_clear_intr_active(udc);
David Lopoaa69a802008-11-17 14:14:51 -08002796 if (intr) {
2797 isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr;
2798 isr_statistics.hndl.idx &= ISR_MASK;
2799 isr_statistics.hndl.cnt++;
2800
2801 /* order defines priority - do NOT change it */
2802 if (USBi_URI & intr) {
2803 isr_statistics.uri++;
2804 isr_reset_handler(udc);
2805 }
2806 if (USBi_PCI & intr) {
2807 isr_statistics.pci++;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002808 udc->gadget.speed = hw_port_is_high_speed(udc) ?
David Lopoaa69a802008-11-17 14:14:51 -08002809 USB_SPEED_HIGH : USB_SPEED_FULL;
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002810 if (udc->suspended && udc->driver->resume) {
Alexander Shishkind3595d12012-05-08 23:28:58 +03002811 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302812 udc->driver->resume(&udc->gadget);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002813 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302814 udc->suspended = 0;
2815 }
David Lopoaa69a802008-11-17 14:14:51 -08002816 }
2817 if (USBi_UEI & intr)
2818 isr_statistics.uei++;
2819 if (USBi_UI & intr) {
2820 isr_statistics.ui++;
2821 isr_tr_complete_handler(udc);
2822 }
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302823 if (USBi_SLI & intr) {
Marc Kleine-Budde7bb4fdc2011-10-10 18:38:09 +02002824 if (udc->gadget.speed != USB_SPEED_UNKNOWN &&
2825 udc->driver->suspend) {
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302826 udc->suspended = 1;
Alexander Shishkind3595d12012-05-08 23:28:58 +03002827 spin_unlock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302828 udc->driver->suspend(&udc->gadget);
Alexander Shishkind3595d12012-05-08 23:28:58 +03002829 spin_lock(&udc->lock);
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302830 }
David Lopoaa69a802008-11-17 14:14:51 -08002831 isr_statistics.sli++;
Pavankumar Kondetie2b61c12011-02-18 17:43:17 +05302832 }
David Lopoaa69a802008-11-17 14:14:51 -08002833 retval = IRQ_HANDLED;
2834 } else {
2835 isr_statistics.none++;
2836 retval = IRQ_NONE;
2837 }
Alexander Shishkind3595d12012-05-08 23:28:58 +03002838 spin_unlock(&udc->lock);
David Lopoaa69a802008-11-17 14:14:51 -08002839
2840 return retval;
2841}
2842
2843/**
2844 * udc_release: driver release function
2845 * @dev: device
2846 *
2847 * Currently does nothing
2848 */
2849static void udc_release(struct device *dev)
2850{
2851 trace("%p", dev);
2852
2853 if (dev == NULL)
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002854 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08002855}
2856
2857/**
2858 * udc_probe: parent probe must call this to initialize UDC
2859 * @dev: parent device
2860 * @regs: registers base address
2861 * @name: driver name
2862 *
2863 * This function returns an error code
2864 * No interrupts active, the IRQ has not been requested yet
2865 * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask
2866 */
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302867static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
Alexander Shishkinf9df8392012-05-04 16:47:16 +03002868 void __iomem *regs, uintptr_t capoffset)
David Lopoaa69a802008-11-17 14:14:51 -08002869{
2870 struct ci13xxx *udc;
2871 int retval = 0;
2872
Marc Kleine-Budde194fa472011-10-10 18:38:08 +02002873 trace("%p, %p, %p", dev, regs, driver->name);
David Lopoaa69a802008-11-17 14:14:51 -08002874
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302875 if (dev == NULL || regs == NULL || driver == NULL ||
2876 driver->name == NULL)
David Lopoaa69a802008-11-17 14:14:51 -08002877 return -EINVAL;
2878
2879 udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL);
2880 if (udc == NULL)
2881 return -ENOMEM;
2882
Alexander Shishkind3595d12012-05-08 23:28:58 +03002883 spin_lock_init(&udc->lock);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302884 udc->regs = regs;
2885 udc->udc_driver = driver;
David Lopoaa69a802008-11-17 14:14:51 -08002886
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302887 udc->gadget.ops = &usb_gadget_ops;
David Lopoaa69a802008-11-17 14:14:51 -08002888 udc->gadget.speed = USB_SPEED_UNKNOWN;
Michal Nazarewiczd327ab52011-11-19 18:27:37 +01002889 udc->gadget.max_speed = USB_SPEED_HIGH;
David Lopoaa69a802008-11-17 14:14:51 -08002890 udc->gadget.is_otg = 0;
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302891 udc->gadget.name = driver->name;
David Lopoaa69a802008-11-17 14:14:51 -08002892
2893 INIT_LIST_HEAD(&udc->gadget.ep_list);
2894 udc->gadget.ep0 = NULL;
2895
Kay Sievers5df585242009-03-24 16:38:23 -07002896 dev_set_name(&udc->gadget.dev, "gadget");
David Lopoaa69a802008-11-17 14:14:51 -08002897 udc->gadget.dev.dma_mask = dev->dma_mask;
Pavankumar Kondeti61948ee2010-12-07 17:54:01 +05302898 udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask;
David Lopoaa69a802008-11-17 14:14:51 -08002899 udc->gadget.dev.parent = dev;
2900 udc->gadget.dev.release = udc_release;
2901
Alexander Shishkind3595d12012-05-08 23:28:58 +03002902 retval = hw_device_init(udc, regs, capoffset);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302903 if (retval < 0)
2904 goto free_udc;
2905
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002906 udc->transceiver = usb_get_transceiver();
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302907
2908 if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
2909 if (udc->transceiver == NULL) {
2910 retval = -ENODEV;
2911 goto free_udc;
2912 }
2913 }
2914
2915 if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) {
2916 retval = hw_device_reset(udc);
2917 if (retval)
2918 goto put_transceiver;
2919 }
2920
David Lopoaa69a802008-11-17 14:14:51 -08002921 retval = device_register(&udc->gadget.dev);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302922 if (retval) {
2923 put_device(&udc->gadget.dev);
2924 goto put_transceiver;
2925 }
David Lopoaa69a802008-11-17 14:14:51 -08002926
2927#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2928 retval = dbg_create_files(&udc->gadget.dev);
2929#endif
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302930 if (retval)
2931 goto unreg_device;
2932
2933 if (udc->transceiver) {
Heikki Krogerus6e13c652012-02-13 13:24:20 +02002934 retval = otg_set_peripheral(udc->transceiver->otg,
2935 &udc->gadget);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302936 if (retval)
2937 goto remove_dbg;
David Lopoaa69a802008-11-17 14:14:51 -08002938 }
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002939
2940 retval = usb_add_gadget_udc(dev, &udc->gadget);
2941 if (retval)
2942 goto remove_trans;
2943
Pavankumar Kondetic0360192010-12-07 17:54:04 +05302944 pm_runtime_no_callbacks(&udc->gadget.dev);
2945 pm_runtime_enable(&udc->gadget.dev);
David Lopoaa69a802008-11-17 14:14:51 -08002946
2947 _udc = udc;
2948 return retval;
2949
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002950remove_trans:
2951 if (udc->transceiver) {
Heikki Krogerus6e13c652012-02-13 13:24:20 +02002952 otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002953 usb_put_transceiver(udc->transceiver);
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002954 }
2955
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002956 dev_err(dev, "error = %i\n", retval);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302957remove_dbg:
2958#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2959 dbg_remove_files(&udc->gadget.dev);
2960#endif
2961unreg_device:
2962 device_unregister(&udc->gadget.dev);
2963put_transceiver:
2964 if (udc->transceiver)
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002965 usb_put_transceiver(udc->transceiver);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302966free_udc:
David Lopoaa69a802008-11-17 14:14:51 -08002967 kfree(udc);
2968 _udc = NULL;
2969 return retval;
2970}
2971
2972/**
2973 * udc_remove: parent remove must call this to remove UDC
2974 *
2975 * No interrupts active, the IRQ has been released
2976 */
2977static void udc_remove(void)
2978{
2979 struct ci13xxx *udc = _udc;
2980
2981 if (udc == NULL) {
Greg Kroah-Hartman0917ba82012-04-27 11:24:39 -07002982 pr_err("EINVAL\n");
David Lopoaa69a802008-11-17 14:14:51 -08002983 return;
2984 }
Sebastian Andrzej Siewior0f913492011-06-28 16:33:47 +03002985 usb_del_gadget_udc(&udc->gadget);
David Lopoaa69a802008-11-17 14:14:51 -08002986
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302987 if (udc->transceiver) {
Heikki Krogerus6e13c652012-02-13 13:24:20 +02002988 otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
Heikki Krogerusb96d3b02012-02-13 13:24:18 +02002989 usb_put_transceiver(udc->transceiver);
Pavankumar Kondetif01ef572010-12-07 17:54:02 +05302990 }
David Lopoaa69a802008-11-17 14:14:51 -08002991#ifdef CONFIG_USB_GADGET_DEBUG_FILES
2992 dbg_remove_files(&udc->gadget.dev);
2993#endif
2994 device_unregister(&udc->gadget.dev);
2995
2996 kfree(udc);
2997 _udc = NULL;
2998}