xref: /rk3399_rockchip-uboot/drivers/usb/gadget/pxa25x_udc.c (revision 1a4f6af8bfd44c8ae6e87a81ff125eed47042cc5)
13c09a283SLukasz Dalek /*
23c09a283SLukasz Dalek  * Intel PXA25x and IXP4xx on-chip full speed USB device controllers
33c09a283SLukasz Dalek  *
43c09a283SLukasz Dalek  * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker)
53c09a283SLukasz Dalek  * Copyright (C) 2003 Robert Schwebel, Pengutronix
63c09a283SLukasz Dalek  * Copyright (C) 2003 Benedikt Spranger, Pengutronix
73c09a283SLukasz Dalek  * Copyright (C) 2003 David Brownell
83c09a283SLukasz Dalek  * Copyright (C) 2003 Joshua Wise
93c09a283SLukasz Dalek  * Copyright (C) 2012 Lukasz Dalek <luk0104@gmail.com>
103c09a283SLukasz Dalek  *
111a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
123c09a283SLukasz Dalek  *
133c09a283SLukasz Dalek  * MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell");
143c09a283SLukasz Dalek  */
153c09a283SLukasz Dalek 
163c09a283SLukasz Dalek #define CONFIG_USB_PXA25X_SMALL
173c09a283SLukasz Dalek #define DRIVER_NAME "pxa25x_udc_linux"
183c09a283SLukasz Dalek #define ARCH_HAS_PREFETCH
193c09a283SLukasz Dalek 
203c09a283SLukasz Dalek #include <common.h>
213c09a283SLukasz Dalek #include <errno.h>
223c09a283SLukasz Dalek #include <asm/byteorder.h>
233c09a283SLukasz Dalek #include <asm/system.h>
243c09a283SLukasz Dalek #include <asm/mach-types.h>
253c09a283SLukasz Dalek #include <asm/unaligned.h>
263c09a283SLukasz Dalek #include <linux/compat.h>
273c09a283SLukasz Dalek #include <malloc.h>
283c09a283SLukasz Dalek #include <asm/io.h>
293c09a283SLukasz Dalek #include <asm/arch/pxa.h>
303c09a283SLukasz Dalek 
313c09a283SLukasz Dalek #include <linux/usb/ch9.h>
323c09a283SLukasz Dalek #include <linux/usb/gadget.h>
333c09a283SLukasz Dalek #include <asm/arch/pxa-regs.h>
343c09a283SLukasz Dalek 
353c09a283SLukasz Dalek #include "pxa25x_udc.h"
363c09a283SLukasz Dalek 
373c09a283SLukasz Dalek /*
383c09a283SLukasz Dalek  * This driver handles the USB Device Controller (UDC) in Intel's PXA 25x
393c09a283SLukasz Dalek  * series processors.  The UDC for the IXP 4xx series is very similar.
403c09a283SLukasz Dalek  * There are fifteen endpoints, in addition to ep0.
413c09a283SLukasz Dalek  *
423c09a283SLukasz Dalek  * Such controller drivers work with a gadget driver.  The gadget driver
433c09a283SLukasz Dalek  * returns descriptors, implements configuration and data protocols used
443c09a283SLukasz Dalek  * by the host to interact with this device, and allocates endpoints to
453c09a283SLukasz Dalek  * the different protocol interfaces.  The controller driver virtualizes
463c09a283SLukasz Dalek  * usb hardware so that the gadget drivers will be more portable.
473c09a283SLukasz Dalek  *
483c09a283SLukasz Dalek  * This UDC hardware wants to implement a bit too much USB protocol, so
493c09a283SLukasz Dalek  * it constrains the sorts of USB configuration change events that work.
503c09a283SLukasz Dalek  * The errata for these chips are misleading; some "fixed" bugs from
513c09a283SLukasz Dalek  * pxa250 a0/a1 b0/b1/b2 sure act like they're still there.
523c09a283SLukasz Dalek  *
533c09a283SLukasz Dalek  * Note that the UDC hardware supports DMA (except on IXP) but that's
543c09a283SLukasz Dalek  * not used here.  IN-DMA (to host) is simple enough, when the data is
553c09a283SLukasz Dalek  * suitably aligned (16 bytes) ... the network stack doesn't do that,
563c09a283SLukasz Dalek  * other software can.  OUT-DMA is buggy in most chip versions, as well
573c09a283SLukasz Dalek  * as poorly designed (data toggle not automatic).  So this driver won't
583c09a283SLukasz Dalek  * bother using DMA.  (Mostly-working IN-DMA support was available in
593c09a283SLukasz Dalek  * kernels before 2.6.23, but was never enabled or well tested.)
603c09a283SLukasz Dalek  */
613c09a283SLukasz Dalek 
623c09a283SLukasz Dalek #define DRIVER_VERSION	"18-August-2012"
633c09a283SLukasz Dalek #define DRIVER_DESC	"PXA 25x USB Device Controller driver"
643c09a283SLukasz Dalek 
653c09a283SLukasz Dalek static const char driver_name[] = "pxa25x_udc";
663c09a283SLukasz Dalek static const char ep0name[] = "ep0";
673c09a283SLukasz Dalek 
683c09a283SLukasz Dalek /* Watchdog */
start_watchdog(struct pxa25x_udc * udc)693c09a283SLukasz Dalek static inline void start_watchdog(struct pxa25x_udc *udc)
703c09a283SLukasz Dalek {
713c09a283SLukasz Dalek 	debug("Started watchdog\n");
723c09a283SLukasz Dalek 	udc->watchdog.base = get_timer(0);
733c09a283SLukasz Dalek 	udc->watchdog.running = 1;
743c09a283SLukasz Dalek }
753c09a283SLukasz Dalek 
stop_watchdog(struct pxa25x_udc * udc)763c09a283SLukasz Dalek static inline void stop_watchdog(struct pxa25x_udc *udc)
773c09a283SLukasz Dalek {
783c09a283SLukasz Dalek 	udc->watchdog.running = 0;
793c09a283SLukasz Dalek 	debug("Stopped watchdog\n");
803c09a283SLukasz Dalek }
813c09a283SLukasz Dalek 
test_watchdog(struct pxa25x_udc * udc)823c09a283SLukasz Dalek static inline void test_watchdog(struct pxa25x_udc *udc)
833c09a283SLukasz Dalek {
843c09a283SLukasz Dalek 	if (!udc->watchdog.running)
853c09a283SLukasz Dalek 		return;
863c09a283SLukasz Dalek 
873c09a283SLukasz Dalek 	debug("watchdog %ld %ld\n", get_timer(udc->watchdog.base),
883c09a283SLukasz Dalek 		udc->watchdog.period);
893c09a283SLukasz Dalek 
903c09a283SLukasz Dalek 	if (get_timer(udc->watchdog.base) >= udc->watchdog.period) {
913c09a283SLukasz Dalek 		stop_watchdog(udc);
923c09a283SLukasz Dalek 		udc->watchdog.function(udc);
933c09a283SLukasz Dalek 	}
943c09a283SLukasz Dalek }
953c09a283SLukasz Dalek 
udc_watchdog(struct pxa25x_udc * dev)963c09a283SLukasz Dalek static void udc_watchdog(struct pxa25x_udc *dev)
973c09a283SLukasz Dalek {
983c09a283SLukasz Dalek 	uint32_t udccs0 = readl(&dev->regs->udccs[0]);
993c09a283SLukasz Dalek 
1003c09a283SLukasz Dalek 	debug("Fired up udc_watchdog\n");
1013c09a283SLukasz Dalek 
1023c09a283SLukasz Dalek 	local_irq_disable();
1033c09a283SLukasz Dalek 	if (dev->ep0state == EP0_STALL
1043c09a283SLukasz Dalek 			&& (udccs0 & UDCCS0_FST) == 0
1053c09a283SLukasz Dalek 			&& (udccs0 & UDCCS0_SST) == 0) {
1063c09a283SLukasz Dalek 		writel(UDCCS0_FST|UDCCS0_FTF, &dev->regs->udccs[0]);
1073c09a283SLukasz Dalek 		debug("ep0 re-stall\n");
1083c09a283SLukasz Dalek 		start_watchdog(dev);
1093c09a283SLukasz Dalek 	}
1103c09a283SLukasz Dalek 	local_irq_enable();
1113c09a283SLukasz Dalek }
1123c09a283SLukasz Dalek 
1133c09a283SLukasz Dalek #ifdef DEBUG
1143c09a283SLukasz Dalek 
1153c09a283SLukasz Dalek static const char * const state_name[] = {
1163c09a283SLukasz Dalek 	"EP0_IDLE",
1173c09a283SLukasz Dalek 	"EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE",
1183c09a283SLukasz Dalek 	"EP0_END_XFER", "EP0_STALL"
1193c09a283SLukasz Dalek };
1203c09a283SLukasz Dalek 
1213c09a283SLukasz Dalek static void
dump_udccr(const char * label)1223c09a283SLukasz Dalek dump_udccr(const char *label)
1233c09a283SLukasz Dalek {
1243c09a283SLukasz Dalek 	u32 udccr = readl(&UDC_REGS->udccr);
1253c09a283SLukasz Dalek 	debug("%s %02X =%s%s%s%s%s%s%s%s\n",
1263c09a283SLukasz Dalek 		label, udccr,
1273c09a283SLukasz Dalek 		(udccr & UDCCR_REM) ? " rem" : "",
1283c09a283SLukasz Dalek 		(udccr & UDCCR_RSTIR) ? " rstir" : "",
1293c09a283SLukasz Dalek 		(udccr & UDCCR_SRM) ? " srm" : "",
1303c09a283SLukasz Dalek 		(udccr & UDCCR_SUSIR) ? " susir" : "",
1313c09a283SLukasz Dalek 		(udccr & UDCCR_RESIR) ? " resir" : "",
1323c09a283SLukasz Dalek 		(udccr & UDCCR_RSM) ? " rsm" : "",
1333c09a283SLukasz Dalek 		(udccr & UDCCR_UDA) ? " uda" : "",
1343c09a283SLukasz Dalek 		(udccr & UDCCR_UDE) ? " ude" : "");
1353c09a283SLukasz Dalek }
1363c09a283SLukasz Dalek 
1373c09a283SLukasz Dalek static void
dump_udccs0(const char * label)1383c09a283SLukasz Dalek dump_udccs0(const char *label)
1393c09a283SLukasz Dalek {
1403c09a283SLukasz Dalek 	u32 udccs0 = readl(&UDC_REGS->udccs[0]);
1413c09a283SLukasz Dalek 
1423c09a283SLukasz Dalek 	debug("%s %s %02X =%s%s%s%s%s%s%s%s\n",
1433c09a283SLukasz Dalek 		label, state_name[the_controller->ep0state], udccs0,
1443c09a283SLukasz Dalek 		(udccs0 & UDCCS0_SA) ? " sa" : "",
1453c09a283SLukasz Dalek 		(udccs0 & UDCCS0_RNE) ? " rne" : "",
1463c09a283SLukasz Dalek 		(udccs0 & UDCCS0_FST) ? " fst" : "",
1473c09a283SLukasz Dalek 		(udccs0 & UDCCS0_SST) ? " sst" : "",
1483c09a283SLukasz Dalek 		(udccs0 & UDCCS0_DRWF) ? " dwrf" : "",
1493c09a283SLukasz Dalek 		(udccs0 & UDCCS0_FTF) ? " ftf" : "",
1503c09a283SLukasz Dalek 		(udccs0 & UDCCS0_IPR) ? " ipr" : "",
1513c09a283SLukasz Dalek 		(udccs0 & UDCCS0_OPR) ? " opr" : "");
1523c09a283SLukasz Dalek }
1533c09a283SLukasz Dalek 
1543c09a283SLukasz Dalek static void
dump_state(struct pxa25x_udc * dev)1553c09a283SLukasz Dalek dump_state(struct pxa25x_udc *dev)
1563c09a283SLukasz Dalek {
1573c09a283SLukasz Dalek 	u32 tmp;
1583c09a283SLukasz Dalek 	unsigned i;
1593c09a283SLukasz Dalek 
1603c09a283SLukasz Dalek 	debug("%s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n",
1613c09a283SLukasz Dalek 		state_name[dev->ep0state],
1623c09a283SLukasz Dalek 		readl(&UDC_REGS->uicr1), readl(&UDC_REGS->uicr0),
1633c09a283SLukasz Dalek 		readl(&UDC_REGS->usir1), readl(&UDC_REGS->usir0),
1643c09a283SLukasz Dalek 		readl(&UDC_REGS->ufnrh), readl(&UDC_REGS->ufnrl));
1653c09a283SLukasz Dalek 	dump_udccr("udccr");
1663c09a283SLukasz Dalek 	if (dev->has_cfr) {
1673c09a283SLukasz Dalek 		tmp = readl(&UDC_REGS->udccfr);
1683c09a283SLukasz Dalek 		debug("udccfr %02X =%s%s\n", tmp,
1693c09a283SLukasz Dalek 			(tmp & UDCCFR_AREN) ? " aren" : "",
1703c09a283SLukasz Dalek 			(tmp & UDCCFR_ACM) ? " acm" : "");
1713c09a283SLukasz Dalek 	}
1723c09a283SLukasz Dalek 
1733c09a283SLukasz Dalek 	if (!dev->driver) {
1743c09a283SLukasz Dalek 		debug("no gadget driver bound\n");
1753c09a283SLukasz Dalek 		return;
1763c09a283SLukasz Dalek 	} else
1773c09a283SLukasz Dalek 		debug("ep0 driver '%s'\n", "ether");
1783c09a283SLukasz Dalek 
1793c09a283SLukasz Dalek 	dump_udccs0("udccs0");
1803c09a283SLukasz Dalek 	debug("ep0 IN %lu/%lu, OUT %lu/%lu\n",
1813c09a283SLukasz Dalek 		dev->stats.write.bytes, dev->stats.write.ops,
1823c09a283SLukasz Dalek 		dev->stats.read.bytes, dev->stats.read.ops);
1833c09a283SLukasz Dalek 
1843c09a283SLukasz Dalek 	for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) {
1853c09a283SLukasz Dalek 		if (dev->ep[i].desc == NULL)
1863c09a283SLukasz Dalek 			continue;
1873c09a283SLukasz Dalek 		debug("udccs%d = %02x\n", i, *dev->ep->reg_udccs);
1883c09a283SLukasz Dalek 	}
1893c09a283SLukasz Dalek }
1903c09a283SLukasz Dalek 
1913c09a283SLukasz Dalek #else /* DEBUG */
1923c09a283SLukasz Dalek 
dump_udccr(const char * label)1933c09a283SLukasz Dalek static inline void dump_udccr(const char *label) { }
dump_udccs0(const char * label)1943c09a283SLukasz Dalek static inline void dump_udccs0(const char *label) { }
dump_state(struct pxa25x_udc * dev)1953c09a283SLukasz Dalek static inline void dump_state(struct pxa25x_udc *dev) { }
1963c09a283SLukasz Dalek 
1973c09a283SLukasz Dalek #endif /* DEBUG */
1983c09a283SLukasz Dalek 
1993c09a283SLukasz Dalek /*
2003c09a283SLukasz Dalek  * ---------------------------------------------------------------------------
2013c09a283SLukasz Dalek  *	endpoint related parts of the api to the usb controller hardware,
2023c09a283SLukasz Dalek  *	used by gadget driver; and the inner talker-to-hardware core.
2033c09a283SLukasz Dalek  * ---------------------------------------------------------------------------
2043c09a283SLukasz Dalek  */
2053c09a283SLukasz Dalek 
2063c09a283SLukasz Dalek static void pxa25x_ep_fifo_flush(struct usb_ep *ep);
2073c09a283SLukasz Dalek static void nuke(struct pxa25x_ep *, int status);
2083c09a283SLukasz Dalek 
2093c09a283SLukasz Dalek /* one GPIO should control a D+ pullup, so host sees this device (or not) */
pullup_off(void)2103c09a283SLukasz Dalek static void pullup_off(void)
2113c09a283SLukasz Dalek {
2123c09a283SLukasz Dalek 	struct pxa2xx_udc_mach_info *mach = the_controller->mach;
2133c09a283SLukasz Dalek 
2143c09a283SLukasz Dalek 	if (mach->udc_command)
2153c09a283SLukasz Dalek 		mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
2163c09a283SLukasz Dalek }
2173c09a283SLukasz Dalek 
pullup_on(void)2183c09a283SLukasz Dalek static void pullup_on(void)
2193c09a283SLukasz Dalek {
2203c09a283SLukasz Dalek 	struct pxa2xx_udc_mach_info *mach = the_controller->mach;
2213c09a283SLukasz Dalek 
2223c09a283SLukasz Dalek 	if (mach->udc_command)
2233c09a283SLukasz Dalek 		mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
2243c09a283SLukasz Dalek }
2253c09a283SLukasz Dalek 
pio_irq_enable(int bEndpointAddress)2263c09a283SLukasz Dalek static void pio_irq_enable(int bEndpointAddress)
2273c09a283SLukasz Dalek {
2283c09a283SLukasz Dalek 	bEndpointAddress &= 0xf;
2293c09a283SLukasz Dalek 	if (bEndpointAddress < 8) {
2303c09a283SLukasz Dalek 		clrbits_le32(&the_controller->regs->uicr0,
2313c09a283SLukasz Dalek 			1 << bEndpointAddress);
2323c09a283SLukasz Dalek 	} else {
2333c09a283SLukasz Dalek 		bEndpointAddress -= 8;
2343c09a283SLukasz Dalek 		clrbits_le32(&the_controller->regs->uicr1,
2353c09a283SLukasz Dalek 			1 << bEndpointAddress);
2363c09a283SLukasz Dalek 	}
2373c09a283SLukasz Dalek }
2383c09a283SLukasz Dalek 
pio_irq_disable(int bEndpointAddress)2393c09a283SLukasz Dalek static void pio_irq_disable(int bEndpointAddress)
2403c09a283SLukasz Dalek {
2413c09a283SLukasz Dalek 	bEndpointAddress &= 0xf;
2423c09a283SLukasz Dalek 	if (bEndpointAddress < 8) {
2433c09a283SLukasz Dalek 		setbits_le32(&the_controller->regs->uicr0,
2443c09a283SLukasz Dalek 			1 << bEndpointAddress);
2453c09a283SLukasz Dalek 	} else {
2463c09a283SLukasz Dalek 		bEndpointAddress -= 8;
2473c09a283SLukasz Dalek 		setbits_le32(&the_controller->regs->uicr1,
2483c09a283SLukasz Dalek 			1 << bEndpointAddress);
2493c09a283SLukasz Dalek 	}
2503c09a283SLukasz Dalek }
2513c09a283SLukasz Dalek 
udc_set_mask_UDCCR(int mask)2523c09a283SLukasz Dalek static inline void udc_set_mask_UDCCR(int mask)
2533c09a283SLukasz Dalek {
2543c09a283SLukasz Dalek 	/*
2553c09a283SLukasz Dalek 	 * The UDCCR reg contains mask and interrupt status bits,
2563c09a283SLukasz Dalek 	 * so using '|=' isn't safe as it may ack an interrupt.
2573c09a283SLukasz Dalek 	 */
2583c09a283SLukasz Dalek 	const uint32_t mask_bits = UDCCR_REM | UDCCR_SRM | UDCCR_UDE;
2593c09a283SLukasz Dalek 
2603c09a283SLukasz Dalek 	mask &= mask_bits;
2613c09a283SLukasz Dalek 	clrsetbits_le32(&the_controller->regs->udccr, ~mask_bits, mask);
2623c09a283SLukasz Dalek }
2633c09a283SLukasz Dalek 
udc_clear_mask_UDCCR(int mask)2643c09a283SLukasz Dalek static inline void udc_clear_mask_UDCCR(int mask)
2653c09a283SLukasz Dalek {
2663c09a283SLukasz Dalek 	const uint32_t mask_bits = UDCCR_REM | UDCCR_SRM | UDCCR_UDE;
2673c09a283SLukasz Dalek 
2683c09a283SLukasz Dalek 	mask = ~mask & mask_bits;
2693c09a283SLukasz Dalek 	clrbits_le32(&the_controller->regs->udccr, ~mask);
2703c09a283SLukasz Dalek }
2713c09a283SLukasz Dalek 
udc_ack_int_UDCCR(int mask)2723c09a283SLukasz Dalek static inline void udc_ack_int_UDCCR(int mask)
2733c09a283SLukasz Dalek {
2743c09a283SLukasz Dalek 	const uint32_t mask_bits = UDCCR_REM | UDCCR_SRM | UDCCR_UDE;
2753c09a283SLukasz Dalek 
2763c09a283SLukasz Dalek 	mask &= ~mask_bits;
2773c09a283SLukasz Dalek 	clrsetbits_le32(&the_controller->regs->udccr, ~mask_bits, mask);
2783c09a283SLukasz Dalek }
2793c09a283SLukasz Dalek 
2803c09a283SLukasz Dalek /*
2813c09a283SLukasz Dalek  * endpoint enable/disable
2823c09a283SLukasz Dalek  *
2833c09a283SLukasz Dalek  * we need to verify the descriptors used to enable endpoints.  since pxa25x
2843c09a283SLukasz Dalek  * endpoint configurations are fixed, and are pretty much always enabled,
2853c09a283SLukasz Dalek  * there's not a lot to manage here.
2863c09a283SLukasz Dalek  *
2873c09a283SLukasz Dalek  * because pxa25x can't selectively initialize bulk (or interrupt) endpoints,
2883c09a283SLukasz Dalek  * (resetting endpoint halt and toggle), SET_INTERFACE is unusable except
2893c09a283SLukasz Dalek  * for a single interface (with only the default altsetting) and for gadget
2903c09a283SLukasz Dalek  * drivers that don't halt endpoints (not reset by set_interface).  that also
2913c09a283SLukasz Dalek  * means that if you use ISO, you must violate the USB spec rule that all
2923c09a283SLukasz Dalek  * iso endpoints must be in non-default altsettings.
2933c09a283SLukasz Dalek  */
pxa25x_ep_enable(struct usb_ep * _ep,const struct usb_endpoint_descriptor * desc)2943c09a283SLukasz Dalek static int pxa25x_ep_enable(struct usb_ep *_ep,
2953c09a283SLukasz Dalek 		const struct usb_endpoint_descriptor *desc)
2963c09a283SLukasz Dalek {
2973c09a283SLukasz Dalek 	struct pxa25x_ep *ep;
2983c09a283SLukasz Dalek 	struct pxa25x_udc *dev;
2993c09a283SLukasz Dalek 
3003c09a283SLukasz Dalek 	ep = container_of(_ep, struct pxa25x_ep, ep);
3013c09a283SLukasz Dalek 	if (!_ep || !desc || ep->desc || _ep->name == ep0name
3023c09a283SLukasz Dalek 			|| desc->bDescriptorType != USB_DT_ENDPOINT
3033c09a283SLukasz Dalek 			|| ep->bEndpointAddress != desc->bEndpointAddress
304f6664ba4SVivek Gautam 			|| ep->fifo_size <
305f6664ba4SVivek Gautam 			   le16_to_cpu(get_unaligned(&desc->wMaxPacketSize))) {
3063c09a283SLukasz Dalek 		printf("%s, bad ep or descriptor\n", __func__);
3073c09a283SLukasz Dalek 		return -EINVAL;
3083c09a283SLukasz Dalek 	}
3093c09a283SLukasz Dalek 
3103c09a283SLukasz Dalek 	/* xfer types must match, except that interrupt ~= bulk */
3113c09a283SLukasz Dalek 	if (ep->bmAttributes != desc->bmAttributes
3123c09a283SLukasz Dalek 			&& ep->bmAttributes != USB_ENDPOINT_XFER_BULK
3133c09a283SLukasz Dalek 			&& desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
3143c09a283SLukasz Dalek 		printf("%s, %s type mismatch\n", __func__, _ep->name);
3153c09a283SLukasz Dalek 		return -EINVAL;
3163c09a283SLukasz Dalek 	}
3173c09a283SLukasz Dalek 
3183c09a283SLukasz Dalek 	/* hardware _could_ do smaller, but driver doesn't */
3193c09a283SLukasz Dalek 	if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
320f6664ba4SVivek Gautam 			&& le16_to_cpu(get_unaligned(&desc->wMaxPacketSize))
3213c09a283SLukasz Dalek 						!= BULK_FIFO_SIZE)
322f6664ba4SVivek Gautam 			|| !get_unaligned(&desc->wMaxPacketSize)) {
3233c09a283SLukasz Dalek 		printf("%s, bad %s maxpacket\n", __func__, _ep->name);
3243c09a283SLukasz Dalek 		return -ERANGE;
3253c09a283SLukasz Dalek 	}
3263c09a283SLukasz Dalek 
3273c09a283SLukasz Dalek 	dev = ep->dev;
3283c09a283SLukasz Dalek 	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
3293c09a283SLukasz Dalek 		printf("%s, bogus device state\n", __func__);
3303c09a283SLukasz Dalek 		return -ESHUTDOWN;
3313c09a283SLukasz Dalek 	}
3323c09a283SLukasz Dalek 
3333c09a283SLukasz Dalek 	ep->desc = desc;
3343c09a283SLukasz Dalek 	ep->stopped = 0;
3353c09a283SLukasz Dalek 	ep->pio_irqs = 0;
336f6664ba4SVivek Gautam 	ep->ep.maxpacket = le16_to_cpu(get_unaligned(&desc->wMaxPacketSize));
3373c09a283SLukasz Dalek 
3383c09a283SLukasz Dalek 	/* flush fifo (mostly for OUT buffers) */
3393c09a283SLukasz Dalek 	pxa25x_ep_fifo_flush(_ep);
3403c09a283SLukasz Dalek 
3413c09a283SLukasz Dalek 	/* ... reset halt state too, if we could ... */
3423c09a283SLukasz Dalek 
3433c09a283SLukasz Dalek 	debug("enabled %s\n", _ep->name);
3443c09a283SLukasz Dalek 	return 0;
3453c09a283SLukasz Dalek }
3463c09a283SLukasz Dalek 
pxa25x_ep_disable(struct usb_ep * _ep)3473c09a283SLukasz Dalek static int pxa25x_ep_disable(struct usb_ep *_ep)
3483c09a283SLukasz Dalek {
3493c09a283SLukasz Dalek 	struct pxa25x_ep *ep;
3503c09a283SLukasz Dalek 	unsigned long flags;
3513c09a283SLukasz Dalek 
3523c09a283SLukasz Dalek 	ep = container_of(_ep, struct pxa25x_ep, ep);
3533c09a283SLukasz Dalek 	if (!_ep || !ep->desc) {
3543c09a283SLukasz Dalek 		printf("%s, %s not enabled\n", __func__,
3553c09a283SLukasz Dalek 			_ep ? ep->ep.name : NULL);
3563c09a283SLukasz Dalek 		return -EINVAL;
3573c09a283SLukasz Dalek 	}
3583c09a283SLukasz Dalek 	local_irq_save(flags);
3593c09a283SLukasz Dalek 
3603c09a283SLukasz Dalek 	nuke(ep, -ESHUTDOWN);
3613c09a283SLukasz Dalek 
3623c09a283SLukasz Dalek 	/* flush fifo (mostly for IN buffers) */
3633c09a283SLukasz Dalek 	pxa25x_ep_fifo_flush(_ep);
3643c09a283SLukasz Dalek 
3653c09a283SLukasz Dalek 	ep->desc = NULL;
3663c09a283SLukasz Dalek 	ep->stopped = 1;
3673c09a283SLukasz Dalek 
3683c09a283SLukasz Dalek 	local_irq_restore(flags);
3693c09a283SLukasz Dalek 	debug("%s disabled\n", _ep->name);
3703c09a283SLukasz Dalek 	return 0;
3713c09a283SLukasz Dalek }
3723c09a283SLukasz Dalek 
3733c09a283SLukasz Dalek /*-------------------------------------------------------------------------*/
3743c09a283SLukasz Dalek 
3753c09a283SLukasz Dalek /*
3763c09a283SLukasz Dalek  * for the pxa25x, these can just wrap kmalloc/kfree.  gadget drivers
3773c09a283SLukasz Dalek  * must still pass correctly initialized endpoints, since other controller
3783c09a283SLukasz Dalek  * drivers may care about how it's currently set up (dma issues etc).
3793c09a283SLukasz Dalek  */
3803c09a283SLukasz Dalek 
3813c09a283SLukasz Dalek /*
3823c09a283SLukasz Dalek  *	pxa25x_ep_alloc_request - allocate a request data structure
3833c09a283SLukasz Dalek  */
3843c09a283SLukasz Dalek static struct usb_request *
pxa25x_ep_alloc_request(struct usb_ep * _ep,gfp_t gfp_flags)3853c09a283SLukasz Dalek pxa25x_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
3863c09a283SLukasz Dalek {
3873c09a283SLukasz Dalek 	struct pxa25x_request *req;
3883c09a283SLukasz Dalek 
3893c09a283SLukasz Dalek 	req = kzalloc(sizeof(*req), gfp_flags);
3903c09a283SLukasz Dalek 	if (!req)
3913c09a283SLukasz Dalek 		return NULL;
3923c09a283SLukasz Dalek 
3933c09a283SLukasz Dalek 	INIT_LIST_HEAD(&req->queue);
3943c09a283SLukasz Dalek 	return &req->req;
3953c09a283SLukasz Dalek }
3963c09a283SLukasz Dalek 
3973c09a283SLukasz Dalek 
3983c09a283SLukasz Dalek /*
3993c09a283SLukasz Dalek  *	pxa25x_ep_free_request - deallocate a request data structure
4003c09a283SLukasz Dalek  */
4013c09a283SLukasz Dalek static void
pxa25x_ep_free_request(struct usb_ep * _ep,struct usb_request * _req)4023c09a283SLukasz Dalek pxa25x_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
4033c09a283SLukasz Dalek {
4043c09a283SLukasz Dalek 	struct pxa25x_request	*req;
4053c09a283SLukasz Dalek 
4063c09a283SLukasz Dalek 	req = container_of(_req, struct pxa25x_request, req);
4073c09a283SLukasz Dalek 	WARN_ON(!list_empty(&req->queue));
4083c09a283SLukasz Dalek 	kfree(req);
4093c09a283SLukasz Dalek }
4103c09a283SLukasz Dalek 
4113c09a283SLukasz Dalek /*-------------------------------------------------------------------------*/
4123c09a283SLukasz Dalek 
4133c09a283SLukasz Dalek /*
4143c09a283SLukasz Dalek  *	done - retire a request; caller blocked irqs
4153c09a283SLukasz Dalek  */
done(struct pxa25x_ep * ep,struct pxa25x_request * req,int status)4163c09a283SLukasz Dalek static void done(struct pxa25x_ep *ep, struct pxa25x_request *req, int status)
4173c09a283SLukasz Dalek {
4183c09a283SLukasz Dalek 	unsigned stopped = ep->stopped;
4193c09a283SLukasz Dalek 
4203c09a283SLukasz Dalek 	list_del_init(&req->queue);
4213c09a283SLukasz Dalek 
4223c09a283SLukasz Dalek 	if (likely(req->req.status == -EINPROGRESS))
4233c09a283SLukasz Dalek 		req->req.status = status;
4243c09a283SLukasz Dalek 	else
4253c09a283SLukasz Dalek 		status = req->req.status;
4263c09a283SLukasz Dalek 
4273c09a283SLukasz Dalek 	if (status && status != -ESHUTDOWN)
4283c09a283SLukasz Dalek 		debug("complete %s req %p stat %d len %u/%u\n",
4293c09a283SLukasz Dalek 			ep->ep.name, &req->req, status,
4303c09a283SLukasz Dalek 			req->req.actual, req->req.length);
4313c09a283SLukasz Dalek 
4323c09a283SLukasz Dalek 	/* don't modify queue heads during completion callback */
4333c09a283SLukasz Dalek 	ep->stopped = 1;
4343c09a283SLukasz Dalek 	req->req.complete(&ep->ep, &req->req);
4353c09a283SLukasz Dalek 	ep->stopped = stopped;
4363c09a283SLukasz Dalek }
4373c09a283SLukasz Dalek 
4383c09a283SLukasz Dalek 
ep0_idle(struct pxa25x_udc * dev)4393c09a283SLukasz Dalek static inline void ep0_idle(struct pxa25x_udc *dev)
4403c09a283SLukasz Dalek {
4413c09a283SLukasz Dalek 	dev->ep0state = EP0_IDLE;
4423c09a283SLukasz Dalek }
4433c09a283SLukasz Dalek 
4443c09a283SLukasz Dalek static int
write_packet(u32 * uddr,struct pxa25x_request * req,unsigned max)4453c09a283SLukasz Dalek write_packet(u32 *uddr, struct pxa25x_request *req, unsigned max)
4463c09a283SLukasz Dalek {
4473c09a283SLukasz Dalek 	u8 *buf;
4483c09a283SLukasz Dalek 	unsigned length, count;
4493c09a283SLukasz Dalek 
4503c09a283SLukasz Dalek 	debug("%s(): uddr %p\n", __func__, uddr);
4513c09a283SLukasz Dalek 
4523c09a283SLukasz Dalek 	buf = req->req.buf + req->req.actual;
4533c09a283SLukasz Dalek 	prefetch(buf);
4543c09a283SLukasz Dalek 
4553c09a283SLukasz Dalek 	/* how big will this packet be? */
4563c09a283SLukasz Dalek 	length = min(req->req.length - req->req.actual, max);
4573c09a283SLukasz Dalek 	req->req.actual += length;
4583c09a283SLukasz Dalek 
4593c09a283SLukasz Dalek 	count = length;
4603c09a283SLukasz Dalek 	while (likely(count--))
4613c09a283SLukasz Dalek 		writeb(*buf++, uddr);
4623c09a283SLukasz Dalek 
4633c09a283SLukasz Dalek 	return length;
4643c09a283SLukasz Dalek }
4653c09a283SLukasz Dalek 
4663c09a283SLukasz Dalek /*
4673c09a283SLukasz Dalek  * write to an IN endpoint fifo, as many packets as possible.
4683c09a283SLukasz Dalek  * irqs will use this to write the rest later.
4693c09a283SLukasz Dalek  * caller guarantees at least one packet buffer is ready (or a zlp).
4703c09a283SLukasz Dalek  */
4713c09a283SLukasz Dalek static int
write_fifo(struct pxa25x_ep * ep,struct pxa25x_request * req)4723c09a283SLukasz Dalek write_fifo(struct pxa25x_ep *ep, struct pxa25x_request *req)
4733c09a283SLukasz Dalek {
4743c09a283SLukasz Dalek 	unsigned max;
4753c09a283SLukasz Dalek 
476f6664ba4SVivek Gautam 	max = le16_to_cpu(get_unaligned(&ep->desc->wMaxPacketSize));
4773c09a283SLukasz Dalek 	do {
4783c09a283SLukasz Dalek 		unsigned count;
4793c09a283SLukasz Dalek 		int is_last, is_short;
4803c09a283SLukasz Dalek 
4813c09a283SLukasz Dalek 		count = write_packet(ep->reg_uddr, req, max);
4823c09a283SLukasz Dalek 
4833c09a283SLukasz Dalek 		/* last packet is usually short (or a zlp) */
4843c09a283SLukasz Dalek 		if (unlikely(count != max))
4853c09a283SLukasz Dalek 			is_last = is_short = 1;
4863c09a283SLukasz Dalek 		else {
4873c09a283SLukasz Dalek 			if (likely(req->req.length != req->req.actual)
4883c09a283SLukasz Dalek 					|| req->req.zero)
4893c09a283SLukasz Dalek 				is_last = 0;
4903c09a283SLukasz Dalek 			else
4913c09a283SLukasz Dalek 				is_last = 1;
4923c09a283SLukasz Dalek 			/* interrupt/iso maxpacket may not fill the fifo */
4933c09a283SLukasz Dalek 			is_short = unlikely(max < ep->fifo_size);
4943c09a283SLukasz Dalek 		}
4953c09a283SLukasz Dalek 
4963c09a283SLukasz Dalek 		debug_cond(NOISY, "wrote %s %d bytes%s%s %d left %p\n",
4973c09a283SLukasz Dalek 			ep->ep.name, count,
4983c09a283SLukasz Dalek 			is_last ? "/L" : "", is_short ? "/S" : "",
4993c09a283SLukasz Dalek 			req->req.length - req->req.actual, req);
5003c09a283SLukasz Dalek 
5013c09a283SLukasz Dalek 		/*
5023c09a283SLukasz Dalek 		 * let loose that packet. maybe try writing another one,
5033c09a283SLukasz Dalek 		 * double buffering might work.  TSP, TPC, and TFS
5043c09a283SLukasz Dalek 		 * bit values are the same for all normal IN endpoints.
5053c09a283SLukasz Dalek 		 */
5063c09a283SLukasz Dalek 		writel(UDCCS_BI_TPC, ep->reg_udccs);
5073c09a283SLukasz Dalek 		if (is_short)
5083c09a283SLukasz Dalek 			writel(UDCCS_BI_TSP, ep->reg_udccs);
5093c09a283SLukasz Dalek 
5103c09a283SLukasz Dalek 		/* requests complete when all IN data is in the FIFO */
5113c09a283SLukasz Dalek 		if (is_last) {
5123c09a283SLukasz Dalek 			done(ep, req, 0);
5133c09a283SLukasz Dalek 			if (list_empty(&ep->queue))
5143c09a283SLukasz Dalek 				pio_irq_disable(ep->bEndpointAddress);
5153c09a283SLukasz Dalek 			return 1;
5163c09a283SLukasz Dalek 		}
5173c09a283SLukasz Dalek 
5183c09a283SLukasz Dalek 		/*
5193c09a283SLukasz Dalek 		 * TODO experiment: how robust can fifo mode tweaking be?
5203c09a283SLukasz Dalek 		 * double buffering is off in the default fifo mode, which
5213c09a283SLukasz Dalek 		 * prevents TFS from being set here.
5223c09a283SLukasz Dalek 		 */
5233c09a283SLukasz Dalek 
5243c09a283SLukasz Dalek 	} while (readl(ep->reg_udccs) & UDCCS_BI_TFS);
5253c09a283SLukasz Dalek 	return 0;
5263c09a283SLukasz Dalek }
5273c09a283SLukasz Dalek 
5283c09a283SLukasz Dalek /*
5293c09a283SLukasz Dalek  * caller asserts req->pending (ep0 irq status nyet cleared); starts
5303c09a283SLukasz Dalek  * ep0 data stage.  these chips want very simple state transitions.
5313c09a283SLukasz Dalek  */
5323c09a283SLukasz Dalek static inline
ep0start(struct pxa25x_udc * dev,u32 flags,const char * tag)5333c09a283SLukasz Dalek void ep0start(struct pxa25x_udc *dev, u32 flags, const char *tag)
5343c09a283SLukasz Dalek {
5353c09a283SLukasz Dalek 	writel(flags|UDCCS0_SA|UDCCS0_OPR, &dev->regs->udccs[0]);
5363c09a283SLukasz Dalek 	writel(USIR0_IR0, &dev->regs->usir0);
5373c09a283SLukasz Dalek 	dev->req_pending = 0;
5383c09a283SLukasz Dalek 	debug_cond(NOISY, "%s() %s, udccs0: %02x/%02x usir: %X.%X\n",
5393c09a283SLukasz Dalek 		__func__, tag, readl(&dev->regs->udccs[0]), flags,
5403c09a283SLukasz Dalek 		readl(&dev->regs->usir1), readl(&dev->regs->usir0));
5413c09a283SLukasz Dalek }
5423c09a283SLukasz Dalek 
5433c09a283SLukasz Dalek static int
write_ep0_fifo(struct pxa25x_ep * ep,struct pxa25x_request * req)5443c09a283SLukasz Dalek write_ep0_fifo(struct pxa25x_ep *ep, struct pxa25x_request *req)
5453c09a283SLukasz Dalek {
5463c09a283SLukasz Dalek 	unsigned count;
5473c09a283SLukasz Dalek 	int is_short;
5483c09a283SLukasz Dalek 
5493c09a283SLukasz Dalek 	count = write_packet(&ep->dev->regs->uddr0, req, EP0_FIFO_SIZE);
5503c09a283SLukasz Dalek 	ep->dev->stats.write.bytes += count;
5513c09a283SLukasz Dalek 
5523c09a283SLukasz Dalek 	/* last packet "must be" short (or a zlp) */
5533c09a283SLukasz Dalek 	is_short = (count != EP0_FIFO_SIZE);
5543c09a283SLukasz Dalek 
5553c09a283SLukasz Dalek 	debug_cond(NOISY, "ep0in %d bytes %d left %p\n", count,
5563c09a283SLukasz Dalek 		req->req.length - req->req.actual, req);
5573c09a283SLukasz Dalek 
5583c09a283SLukasz Dalek 	if (unlikely(is_short)) {
5593c09a283SLukasz Dalek 		if (ep->dev->req_pending)
5603c09a283SLukasz Dalek 			ep0start(ep->dev, UDCCS0_IPR, "short IN");
5613c09a283SLukasz Dalek 		else
5623c09a283SLukasz Dalek 			writel(UDCCS0_IPR, &ep->dev->regs->udccs[0]);
5633c09a283SLukasz Dalek 
5643c09a283SLukasz Dalek 		count = req->req.length;
5653c09a283SLukasz Dalek 		done(ep, req, 0);
5663c09a283SLukasz Dalek 		ep0_idle(ep->dev);
5673c09a283SLukasz Dalek 
5683c09a283SLukasz Dalek 		/*
5693c09a283SLukasz Dalek 		 * This seems to get rid of lost status irqs in some cases:
5703c09a283SLukasz Dalek 		 * host responds quickly, or next request involves config
5713c09a283SLukasz Dalek 		 * change automagic, or should have been hidden, or ...
5723c09a283SLukasz Dalek 		 *
5733c09a283SLukasz Dalek 		 * FIXME get rid of all udelays possible...
5743c09a283SLukasz Dalek 		 */
5753c09a283SLukasz Dalek 		if (count >= EP0_FIFO_SIZE) {
5763c09a283SLukasz Dalek 			count = 100;
5773c09a283SLukasz Dalek 			do {
5783c09a283SLukasz Dalek 				if ((readl(&ep->dev->regs->udccs[0]) &
5793c09a283SLukasz Dalek 				     UDCCS0_OPR) != 0) {
5803c09a283SLukasz Dalek 					/* clear OPR, generate ack */
5813c09a283SLukasz Dalek 					writel(UDCCS0_OPR,
5823c09a283SLukasz Dalek 						&ep->dev->regs->udccs[0]);
5833c09a283SLukasz Dalek 					break;
5843c09a283SLukasz Dalek 				}
5853c09a283SLukasz Dalek 				count--;
5863c09a283SLukasz Dalek 				udelay(1);
5873c09a283SLukasz Dalek 			} while (count);
5883c09a283SLukasz Dalek 		}
5893c09a283SLukasz Dalek 	} else if (ep->dev->req_pending)
5903c09a283SLukasz Dalek 		ep0start(ep->dev, 0, "IN");
5913c09a283SLukasz Dalek 
5923c09a283SLukasz Dalek 	return is_short;
5933c09a283SLukasz Dalek }
5943c09a283SLukasz Dalek 
5953c09a283SLukasz Dalek 
5963c09a283SLukasz Dalek /*
5973c09a283SLukasz Dalek  * read_fifo -  unload packet(s) from the fifo we use for usb OUT
5983c09a283SLukasz Dalek  * transfers and put them into the request.  caller should have made
5993c09a283SLukasz Dalek  * sure there's at least one packet ready.
6003c09a283SLukasz Dalek  *
6013c09a283SLukasz Dalek  * returns true if the request completed because of short packet or the
6023c09a283SLukasz Dalek  * request buffer having filled (and maybe overran till end-of-packet).
6033c09a283SLukasz Dalek  */
6043c09a283SLukasz Dalek static int
read_fifo(struct pxa25x_ep * ep,struct pxa25x_request * req)6053c09a283SLukasz Dalek read_fifo(struct pxa25x_ep *ep, struct pxa25x_request *req)
6063c09a283SLukasz Dalek {
6073c09a283SLukasz Dalek 	u32 udccs;
6083c09a283SLukasz Dalek 	u8 *buf;
6093c09a283SLukasz Dalek 	unsigned bufferspace, count, is_short;
6103c09a283SLukasz Dalek 
6113c09a283SLukasz Dalek 	for (;;) {
6123c09a283SLukasz Dalek 		/*
6133c09a283SLukasz Dalek 		 * make sure there's a packet in the FIFO.
6143c09a283SLukasz Dalek 		 * UDCCS_{BO,IO}_RPC are all the same bit value.
6153c09a283SLukasz Dalek 		 * UDCCS_{BO,IO}_RNE are all the same bit value.
6163c09a283SLukasz Dalek 		 */
6173c09a283SLukasz Dalek 		udccs = readl(ep->reg_udccs);
6183c09a283SLukasz Dalek 		if (unlikely((udccs & UDCCS_BO_RPC) == 0))
6193c09a283SLukasz Dalek 			break;
6203c09a283SLukasz Dalek 		buf = req->req.buf + req->req.actual;
6213c09a283SLukasz Dalek 		prefetchw(buf);
6223c09a283SLukasz Dalek 		bufferspace = req->req.length - req->req.actual;
6233c09a283SLukasz Dalek 
6243c09a283SLukasz Dalek 		/* read all bytes from this packet */
6253c09a283SLukasz Dalek 		if (likely(udccs & UDCCS_BO_RNE)) {
6263c09a283SLukasz Dalek 			count = 1 + (0x0ff & readl(ep->reg_ubcr));
6273c09a283SLukasz Dalek 			req->req.actual += min(count, bufferspace);
6283c09a283SLukasz Dalek 		} else /* zlp */
6293c09a283SLukasz Dalek 			count = 0;
6303c09a283SLukasz Dalek 		is_short = (count < ep->ep.maxpacket);
6313c09a283SLukasz Dalek 		debug_cond(NOISY, "read %s %02x, %d bytes%s req %p %d/%d\n",
6323c09a283SLukasz Dalek 			ep->ep.name, udccs, count,
6333c09a283SLukasz Dalek 			is_short ? "/S" : "",
6343c09a283SLukasz Dalek 			req, req->req.actual, req->req.length);
6353c09a283SLukasz Dalek 		while (likely(count-- != 0)) {
6363c09a283SLukasz Dalek 			u8 byte = readb(ep->reg_uddr);
6373c09a283SLukasz Dalek 
6383c09a283SLukasz Dalek 			if (unlikely(bufferspace == 0)) {
6393c09a283SLukasz Dalek 				/*
6403c09a283SLukasz Dalek 				 * this happens when the driver's buffer
6413c09a283SLukasz Dalek 				 * is smaller than what the host sent.
6423c09a283SLukasz Dalek 				 * discard the extra data.
6433c09a283SLukasz Dalek 				 */
6443c09a283SLukasz Dalek 				if (req->req.status != -EOVERFLOW)
6453c09a283SLukasz Dalek 					printf("%s overflow %d\n",
6463c09a283SLukasz Dalek 						ep->ep.name, count);
6473c09a283SLukasz Dalek 				req->req.status = -EOVERFLOW;
6483c09a283SLukasz Dalek 			} else {
6493c09a283SLukasz Dalek 				*buf++ = byte;
6503c09a283SLukasz Dalek 				bufferspace--;
6513c09a283SLukasz Dalek 			}
6523c09a283SLukasz Dalek 		}
6533c09a283SLukasz Dalek 		writel(UDCCS_BO_RPC, ep->reg_udccs);
6543c09a283SLukasz Dalek 		/* RPC/RSP/RNE could now reflect the other packet buffer */
6553c09a283SLukasz Dalek 
6563c09a283SLukasz Dalek 		/* iso is one request per packet */
6573c09a283SLukasz Dalek 		if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
6583c09a283SLukasz Dalek 			if (udccs & UDCCS_IO_ROF)
6593c09a283SLukasz Dalek 				req->req.status = -EHOSTUNREACH;
6603c09a283SLukasz Dalek 			/* more like "is_done" */
6613c09a283SLukasz Dalek 			is_short = 1;
6623c09a283SLukasz Dalek 		}
6633c09a283SLukasz Dalek 
6643c09a283SLukasz Dalek 		/* completion */
6653c09a283SLukasz Dalek 		if (is_short || req->req.actual == req->req.length) {
6663c09a283SLukasz Dalek 			done(ep, req, 0);
6673c09a283SLukasz Dalek 			if (list_empty(&ep->queue))
6683c09a283SLukasz Dalek 				pio_irq_disable(ep->bEndpointAddress);
6693c09a283SLukasz Dalek 			return 1;
6703c09a283SLukasz Dalek 		}
6713c09a283SLukasz Dalek 
6723c09a283SLukasz Dalek 		/* finished that packet.  the next one may be waiting... */
6733c09a283SLukasz Dalek 	}
6743c09a283SLukasz Dalek 	return 0;
6753c09a283SLukasz Dalek }
6763c09a283SLukasz Dalek 
6773c09a283SLukasz Dalek /*
6783c09a283SLukasz Dalek  * special ep0 version of the above.  no UBCR0 or double buffering; status
6793c09a283SLukasz Dalek  * handshaking is magic.  most device protocols don't need control-OUT.
6803c09a283SLukasz Dalek  * CDC vendor commands (and RNDIS), mass storage CB/CBI, and some other
6813c09a283SLukasz Dalek  * protocols do use them.
6823c09a283SLukasz Dalek  */
6833c09a283SLukasz Dalek static int
read_ep0_fifo(struct pxa25x_ep * ep,struct pxa25x_request * req)6843c09a283SLukasz Dalek read_ep0_fifo(struct pxa25x_ep *ep, struct pxa25x_request *req)
6853c09a283SLukasz Dalek {
6863c09a283SLukasz Dalek 	u8 *buf, byte;
6873c09a283SLukasz Dalek 	unsigned bufferspace;
6883c09a283SLukasz Dalek 
6893c09a283SLukasz Dalek 	buf = req->req.buf + req->req.actual;
6903c09a283SLukasz Dalek 	bufferspace = req->req.length - req->req.actual;
6913c09a283SLukasz Dalek 
6923c09a283SLukasz Dalek 	while (readl(&ep->dev->regs->udccs[0]) & UDCCS0_RNE) {
6933c09a283SLukasz Dalek 		byte = (u8)readb(&ep->dev->regs->uddr0);
6943c09a283SLukasz Dalek 
6953c09a283SLukasz Dalek 		if (unlikely(bufferspace == 0)) {
6963c09a283SLukasz Dalek 			/*
6973c09a283SLukasz Dalek 			 * this happens when the driver's buffer
6983c09a283SLukasz Dalek 			 * is smaller than what the host sent.
6993c09a283SLukasz Dalek 			 * discard the extra data.
7003c09a283SLukasz Dalek 			 */
7013c09a283SLukasz Dalek 			if (req->req.status != -EOVERFLOW)
7023c09a283SLukasz Dalek 				printf("%s overflow\n", ep->ep.name);
7033c09a283SLukasz Dalek 			req->req.status = -EOVERFLOW;
7043c09a283SLukasz Dalek 		} else {
7053c09a283SLukasz Dalek 			*buf++ = byte;
7063c09a283SLukasz Dalek 			req->req.actual++;
7073c09a283SLukasz Dalek 			bufferspace--;
7083c09a283SLukasz Dalek 		}
7093c09a283SLukasz Dalek 	}
7103c09a283SLukasz Dalek 
7113c09a283SLukasz Dalek 	writel(UDCCS0_OPR | UDCCS0_IPR, &ep->dev->regs->udccs[0]);
7123c09a283SLukasz Dalek 
7133c09a283SLukasz Dalek 	/* completion */
7143c09a283SLukasz Dalek 	if (req->req.actual >= req->req.length)
7153c09a283SLukasz Dalek 		return 1;
7163c09a283SLukasz Dalek 
7173c09a283SLukasz Dalek 	/* finished that packet.  the next one may be waiting... */
7183c09a283SLukasz Dalek 	return 0;
7193c09a283SLukasz Dalek }
7203c09a283SLukasz Dalek 
7213c09a283SLukasz Dalek /*-------------------------------------------------------------------------*/
7223c09a283SLukasz Dalek 
7233c09a283SLukasz Dalek static int
pxa25x_ep_queue(struct usb_ep * _ep,struct usb_request * _req,gfp_t gfp_flags)7243c09a283SLukasz Dalek pxa25x_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
7253c09a283SLukasz Dalek {
7263c09a283SLukasz Dalek 	struct pxa25x_request *req;
7273c09a283SLukasz Dalek 	struct pxa25x_ep *ep;
7283c09a283SLukasz Dalek 	struct pxa25x_udc *dev;
7293c09a283SLukasz Dalek 	unsigned long flags;
7303c09a283SLukasz Dalek 
7313c09a283SLukasz Dalek 	req = container_of(_req, struct pxa25x_request, req);
7323c09a283SLukasz Dalek 	if (unlikely(!_req || !_req->complete || !_req->buf
7333c09a283SLukasz Dalek 			|| !list_empty(&req->queue))) {
7343c09a283SLukasz Dalek 		printf("%s, bad params\n", __func__);
7353c09a283SLukasz Dalek 		return -EINVAL;
7363c09a283SLukasz Dalek 	}
7373c09a283SLukasz Dalek 
7383c09a283SLukasz Dalek 	ep = container_of(_ep, struct pxa25x_ep, ep);
7393c09a283SLukasz Dalek 	if (unlikely(!_ep || (!ep->desc && ep->ep.name != ep0name))) {
7403c09a283SLukasz Dalek 		printf("%s, bad ep\n", __func__);
7413c09a283SLukasz Dalek 		return -EINVAL;
7423c09a283SLukasz Dalek 	}
7433c09a283SLukasz Dalek 
7443c09a283SLukasz Dalek 	dev = ep->dev;
7453c09a283SLukasz Dalek 	if (unlikely(!dev->driver
7463c09a283SLukasz Dalek 			|| dev->gadget.speed == USB_SPEED_UNKNOWN)) {
7473c09a283SLukasz Dalek 		printf("%s, bogus device state\n", __func__);
7483c09a283SLukasz Dalek 		return -ESHUTDOWN;
7493c09a283SLukasz Dalek 	}
7503c09a283SLukasz Dalek 
7513c09a283SLukasz Dalek 	/*
7523c09a283SLukasz Dalek 	 * iso is always one packet per request, that's the only way
7533c09a283SLukasz Dalek 	 * we can report per-packet status.  that also helps with dma.
7543c09a283SLukasz Dalek 	 */
7553c09a283SLukasz Dalek 	if (unlikely(ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
7563c09a283SLukasz Dalek 			&& req->req.length >
757f6664ba4SVivek Gautam 			le16_to_cpu(get_unaligned(&ep->desc->wMaxPacketSize))))
7583c09a283SLukasz Dalek 		return -EMSGSIZE;
7593c09a283SLukasz Dalek 
7603c09a283SLukasz Dalek 	debug_cond(NOISY, "%s queue req %p, len %d buf %p\n",
7613c09a283SLukasz Dalek 		_ep->name, _req, _req->length, _req->buf);
7623c09a283SLukasz Dalek 
7633c09a283SLukasz Dalek 	local_irq_save(flags);
7643c09a283SLukasz Dalek 
7653c09a283SLukasz Dalek 	_req->status = -EINPROGRESS;
7663c09a283SLukasz Dalek 	_req->actual = 0;
7673c09a283SLukasz Dalek 
7683c09a283SLukasz Dalek 	/* kickstart this i/o queue? */
7693c09a283SLukasz Dalek 	if (list_empty(&ep->queue) && !ep->stopped) {
7703c09a283SLukasz Dalek 		if (ep->desc == NULL/* ep0 */) {
7713c09a283SLukasz Dalek 			unsigned length = _req->length;
7723c09a283SLukasz Dalek 
7733c09a283SLukasz Dalek 			switch (dev->ep0state) {
7743c09a283SLukasz Dalek 			case EP0_IN_DATA_PHASE:
7753c09a283SLukasz Dalek 				dev->stats.write.ops++;
7763c09a283SLukasz Dalek 				if (write_ep0_fifo(ep, req))
7773c09a283SLukasz Dalek 					req = NULL;
7783c09a283SLukasz Dalek 				break;
7793c09a283SLukasz Dalek 
7803c09a283SLukasz Dalek 			case EP0_OUT_DATA_PHASE:
7813c09a283SLukasz Dalek 				dev->stats.read.ops++;
7823c09a283SLukasz Dalek 				/* messy ... */
7833c09a283SLukasz Dalek 				if (dev->req_config) {
7843c09a283SLukasz Dalek 					debug("ep0 config ack%s\n",
7853c09a283SLukasz Dalek 						dev->has_cfr ?  "" : " raced");
7863c09a283SLukasz Dalek 					if (dev->has_cfr)
7873c09a283SLukasz Dalek 						writel(UDCCFR_AREN|UDCCFR_ACM
7883c09a283SLukasz Dalek 							|UDCCFR_MB1,
7893c09a283SLukasz Dalek 							&ep->dev->regs->udccfr);
7903c09a283SLukasz Dalek 					done(ep, req, 0);
7913c09a283SLukasz Dalek 					dev->ep0state = EP0_END_XFER;
7923c09a283SLukasz Dalek 					local_irq_restore(flags);
7933c09a283SLukasz Dalek 					return 0;
7943c09a283SLukasz Dalek 				}
7953c09a283SLukasz Dalek 				if (dev->req_pending)
7963c09a283SLukasz Dalek 					ep0start(dev, UDCCS0_IPR, "OUT");
7973c09a283SLukasz Dalek 				if (length == 0 ||
7983c09a283SLukasz Dalek 						((readl(
7993c09a283SLukasz Dalek 						&ep->dev->regs->udccs[0])
8003c09a283SLukasz Dalek 						& UDCCS0_RNE) != 0
8013c09a283SLukasz Dalek 						&& read_ep0_fifo(ep, req))) {
8023c09a283SLukasz Dalek 					ep0_idle(dev);
8033c09a283SLukasz Dalek 					done(ep, req, 0);
8043c09a283SLukasz Dalek 					req = NULL;
8053c09a283SLukasz Dalek 				}
8063c09a283SLukasz Dalek 				break;
8073c09a283SLukasz Dalek 
8083c09a283SLukasz Dalek 			default:
8093c09a283SLukasz Dalek 				printf("ep0 i/o, odd state %d\n",
8103c09a283SLukasz Dalek 					dev->ep0state);
8113c09a283SLukasz Dalek 				local_irq_restore(flags);
8123c09a283SLukasz Dalek 				return -EL2HLT;
8133c09a283SLukasz Dalek 			}
8143c09a283SLukasz Dalek 		/* can the FIFO can satisfy the request immediately? */
8153c09a283SLukasz Dalek 		} else if ((ep->bEndpointAddress & USB_DIR_IN) != 0) {
8163c09a283SLukasz Dalek 			if ((readl(ep->reg_udccs) & UDCCS_BI_TFS) != 0
8173c09a283SLukasz Dalek 					&& write_fifo(ep, req))
8183c09a283SLukasz Dalek 				req = NULL;
8193c09a283SLukasz Dalek 		} else if ((readl(ep->reg_udccs) & UDCCS_BO_RFS) != 0
8203c09a283SLukasz Dalek 				&& read_fifo(ep, req)) {
8213c09a283SLukasz Dalek 			req = NULL;
8223c09a283SLukasz Dalek 		}
8233c09a283SLukasz Dalek 
8243c09a283SLukasz Dalek 		if (likely(req && ep->desc))
8253c09a283SLukasz Dalek 			pio_irq_enable(ep->bEndpointAddress);
8263c09a283SLukasz Dalek 	}
8273c09a283SLukasz Dalek 
8283c09a283SLukasz Dalek 	/* pio or dma irq handler advances the queue. */
8293c09a283SLukasz Dalek 	if (likely(req != NULL))
8303c09a283SLukasz Dalek 		list_add_tail(&req->queue, &ep->queue);
8313c09a283SLukasz Dalek 	local_irq_restore(flags);
8323c09a283SLukasz Dalek 
8333c09a283SLukasz Dalek 	return 0;
8343c09a283SLukasz Dalek }
8353c09a283SLukasz Dalek 
8363c09a283SLukasz Dalek 
8373c09a283SLukasz Dalek /*
8383c09a283SLukasz Dalek  *	nuke - dequeue ALL requests
8393c09a283SLukasz Dalek  */
nuke(struct pxa25x_ep * ep,int status)8403c09a283SLukasz Dalek static void nuke(struct pxa25x_ep *ep, int status)
8413c09a283SLukasz Dalek {
8423c09a283SLukasz Dalek 	struct pxa25x_request *req;
8433c09a283SLukasz Dalek 
8443c09a283SLukasz Dalek 	/* called with irqs blocked */
8453c09a283SLukasz Dalek 	while (!list_empty(&ep->queue)) {
8463c09a283SLukasz Dalek 		req = list_entry(ep->queue.next,
8473c09a283SLukasz Dalek 				struct pxa25x_request,
8483c09a283SLukasz Dalek 				queue);
8493c09a283SLukasz Dalek 		done(ep, req, status);
8503c09a283SLukasz Dalek 	}
8513c09a283SLukasz Dalek 	if (ep->desc)
8523c09a283SLukasz Dalek 		pio_irq_disable(ep->bEndpointAddress);
8533c09a283SLukasz Dalek }
8543c09a283SLukasz Dalek 
8553c09a283SLukasz Dalek 
8563c09a283SLukasz Dalek /* dequeue JUST ONE request */
pxa25x_ep_dequeue(struct usb_ep * _ep,struct usb_request * _req)8573c09a283SLukasz Dalek static int pxa25x_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
8583c09a283SLukasz Dalek {
8593c09a283SLukasz Dalek 	struct pxa25x_ep *ep;
8603c09a283SLukasz Dalek 	struct pxa25x_request *req;
8613c09a283SLukasz Dalek 	unsigned long flags;
8623c09a283SLukasz Dalek 
8633c09a283SLukasz Dalek 	ep = container_of(_ep, struct pxa25x_ep, ep);
8643c09a283SLukasz Dalek 	if (!_ep || ep->ep.name == ep0name)
8653c09a283SLukasz Dalek 		return -EINVAL;
8663c09a283SLukasz Dalek 
8673c09a283SLukasz Dalek 	local_irq_save(flags);
8683c09a283SLukasz Dalek 
8693c09a283SLukasz Dalek 	/* make sure it's actually queued on this endpoint */
8703c09a283SLukasz Dalek 	list_for_each_entry(req, &ep->queue, queue) {
8713c09a283SLukasz Dalek 		if (&req->req == _req)
8723c09a283SLukasz Dalek 			break;
8733c09a283SLukasz Dalek 	}
8743c09a283SLukasz Dalek 	if (&req->req != _req) {
8753c09a283SLukasz Dalek 		local_irq_restore(flags);
8763c09a283SLukasz Dalek 		return -EINVAL;
8773c09a283SLukasz Dalek 	}
8783c09a283SLukasz Dalek 
8793c09a283SLukasz Dalek 	done(ep, req, -ECONNRESET);
8803c09a283SLukasz Dalek 
8813c09a283SLukasz Dalek 	local_irq_restore(flags);
8823c09a283SLukasz Dalek 	return 0;
8833c09a283SLukasz Dalek }
8843c09a283SLukasz Dalek 
8853c09a283SLukasz Dalek /*-------------------------------------------------------------------------*/
8863c09a283SLukasz Dalek 
pxa25x_ep_set_halt(struct usb_ep * _ep,int value)8873c09a283SLukasz Dalek static int pxa25x_ep_set_halt(struct usb_ep *_ep, int value)
8883c09a283SLukasz Dalek {
8893c09a283SLukasz Dalek 	struct pxa25x_ep *ep;
8903c09a283SLukasz Dalek 	unsigned long flags;
8913c09a283SLukasz Dalek 
8923c09a283SLukasz Dalek 	ep = container_of(_ep, struct pxa25x_ep, ep);
8933c09a283SLukasz Dalek 	if (unlikely(!_ep
8943c09a283SLukasz Dalek 			|| (!ep->desc && ep->ep.name != ep0name))
8953c09a283SLukasz Dalek 			|| ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
8963c09a283SLukasz Dalek 		printf("%s, bad ep\n", __func__);
8973c09a283SLukasz Dalek 		return -EINVAL;
8983c09a283SLukasz Dalek 	}
8993c09a283SLukasz Dalek 	if (value == 0) {
9003c09a283SLukasz Dalek 		/*
9013c09a283SLukasz Dalek 		 * this path (reset toggle+halt) is needed to implement
9023c09a283SLukasz Dalek 		 * SET_INTERFACE on normal hardware.  but it can't be
9033c09a283SLukasz Dalek 		 * done from software on the PXA UDC, and the hardware
9043c09a283SLukasz Dalek 		 * forgets to do it as part of SET_INTERFACE automagic.
9053c09a283SLukasz Dalek 		 */
9063c09a283SLukasz Dalek 		printf("only host can clear %s halt\n", _ep->name);
9073c09a283SLukasz Dalek 		return -EROFS;
9083c09a283SLukasz Dalek 	}
9093c09a283SLukasz Dalek 
9103c09a283SLukasz Dalek 	local_irq_save(flags);
9113c09a283SLukasz Dalek 
9123c09a283SLukasz Dalek 	if ((ep->bEndpointAddress & USB_DIR_IN) != 0
9133c09a283SLukasz Dalek 			&& ((readl(ep->reg_udccs) & UDCCS_BI_TFS) == 0
9143c09a283SLukasz Dalek 			   || !list_empty(&ep->queue))) {
9153c09a283SLukasz Dalek 		local_irq_restore(flags);
9163c09a283SLukasz Dalek 		return -EAGAIN;
9173c09a283SLukasz Dalek 	}
9183c09a283SLukasz Dalek 
9193c09a283SLukasz Dalek 	/* FST bit is the same for control, bulk in, bulk out, interrupt in */
9203c09a283SLukasz Dalek 	writel(UDCCS_BI_FST|UDCCS_BI_FTF, ep->reg_udccs);
9213c09a283SLukasz Dalek 
9223c09a283SLukasz Dalek 	/* ep0 needs special care */
9233c09a283SLukasz Dalek 	if (!ep->desc) {
9243c09a283SLukasz Dalek 		start_watchdog(ep->dev);
9253c09a283SLukasz Dalek 		ep->dev->req_pending = 0;
9263c09a283SLukasz Dalek 		ep->dev->ep0state = EP0_STALL;
9273c09a283SLukasz Dalek 
9283c09a283SLukasz Dalek 	/* and bulk/intr endpoints like dropping stalls too */
9293c09a283SLukasz Dalek 	} else {
9303c09a283SLukasz Dalek 		unsigned i;
9313c09a283SLukasz Dalek 		for (i = 0; i < 1000; i += 20) {
9323c09a283SLukasz Dalek 			if (readl(ep->reg_udccs) & UDCCS_BI_SST)
9333c09a283SLukasz Dalek 				break;
9343c09a283SLukasz Dalek 			udelay(20);
9353c09a283SLukasz Dalek 		}
9363c09a283SLukasz Dalek 	}
9373c09a283SLukasz Dalek 	local_irq_restore(flags);
9383c09a283SLukasz Dalek 
9393c09a283SLukasz Dalek 	debug("%s halt\n", _ep->name);
9403c09a283SLukasz Dalek 	return 0;
9413c09a283SLukasz Dalek }
9423c09a283SLukasz Dalek 
pxa25x_ep_fifo_status(struct usb_ep * _ep)9433c09a283SLukasz Dalek static int pxa25x_ep_fifo_status(struct usb_ep *_ep)
9443c09a283SLukasz Dalek {
9453c09a283SLukasz Dalek 	struct pxa25x_ep        *ep;
9463c09a283SLukasz Dalek 
9473c09a283SLukasz Dalek 	ep = container_of(_ep, struct pxa25x_ep, ep);
9483c09a283SLukasz Dalek 	if (!_ep) {
9493c09a283SLukasz Dalek 		printf("%s, bad ep\n", __func__);
9503c09a283SLukasz Dalek 		return -ENODEV;
9513c09a283SLukasz Dalek 	}
9523c09a283SLukasz Dalek 	/* pxa can't report unclaimed bytes from IN fifos */
9533c09a283SLukasz Dalek 	if ((ep->bEndpointAddress & USB_DIR_IN) != 0)
9543c09a283SLukasz Dalek 		return -EOPNOTSUPP;
9553c09a283SLukasz Dalek 	if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN
9563c09a283SLukasz Dalek 			|| (readl(ep->reg_udccs) & UDCCS_BO_RFS) == 0)
9573c09a283SLukasz Dalek 		return 0;
9583c09a283SLukasz Dalek 	else
9593c09a283SLukasz Dalek 		return (readl(ep->reg_ubcr) & 0xfff) + 1;
9603c09a283SLukasz Dalek }
9613c09a283SLukasz Dalek 
pxa25x_ep_fifo_flush(struct usb_ep * _ep)9623c09a283SLukasz Dalek static void pxa25x_ep_fifo_flush(struct usb_ep *_ep)
9633c09a283SLukasz Dalek {
9643c09a283SLukasz Dalek 	struct pxa25x_ep        *ep;
9653c09a283SLukasz Dalek 
9663c09a283SLukasz Dalek 	ep = container_of(_ep, struct pxa25x_ep, ep);
9673c09a283SLukasz Dalek 	if (!_ep || ep->ep.name == ep0name || !list_empty(&ep->queue)) {
9683c09a283SLukasz Dalek 		printf("%s, bad ep\n", __func__);
9693c09a283SLukasz Dalek 		return;
9703c09a283SLukasz Dalek 	}
9713c09a283SLukasz Dalek 
9723c09a283SLukasz Dalek 	/* toggle and halt bits stay unchanged */
9733c09a283SLukasz Dalek 
9743c09a283SLukasz Dalek 	/* for OUT, just read and discard the FIFO contents. */
9753c09a283SLukasz Dalek 	if ((ep->bEndpointAddress & USB_DIR_IN) == 0) {
9763c09a283SLukasz Dalek 		while (((readl(ep->reg_udccs)) & UDCCS_BO_RNE) != 0)
9773c09a283SLukasz Dalek 			(void)readb(ep->reg_uddr);
9783c09a283SLukasz Dalek 		return;
9793c09a283SLukasz Dalek 	}
9803c09a283SLukasz Dalek 
9813c09a283SLukasz Dalek 	/* most IN status is the same, but ISO can't stall */
9823c09a283SLukasz Dalek 	writel(UDCCS_BI_TPC|UDCCS_BI_FTF|UDCCS_BI_TUR
9833c09a283SLukasz Dalek 		| (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
9843c09a283SLukasz Dalek 			? 0 : UDCCS_BI_SST), ep->reg_udccs);
9853c09a283SLukasz Dalek }
9863c09a283SLukasz Dalek 
9873c09a283SLukasz Dalek 
9883c09a283SLukasz Dalek static struct usb_ep_ops pxa25x_ep_ops = {
9893c09a283SLukasz Dalek 	.enable		= pxa25x_ep_enable,
9903c09a283SLukasz Dalek 	.disable	= pxa25x_ep_disable,
9913c09a283SLukasz Dalek 
9923c09a283SLukasz Dalek 	.alloc_request	= pxa25x_ep_alloc_request,
9933c09a283SLukasz Dalek 	.free_request	= pxa25x_ep_free_request,
9943c09a283SLukasz Dalek 
9953c09a283SLukasz Dalek 	.queue		= pxa25x_ep_queue,
9963c09a283SLukasz Dalek 	.dequeue	= pxa25x_ep_dequeue,
9973c09a283SLukasz Dalek 
9983c09a283SLukasz Dalek 	.set_halt	= pxa25x_ep_set_halt,
9993c09a283SLukasz Dalek 	.fifo_status	= pxa25x_ep_fifo_status,
10003c09a283SLukasz Dalek 	.fifo_flush	= pxa25x_ep_fifo_flush,
10013c09a283SLukasz Dalek };
10023c09a283SLukasz Dalek 
10033c09a283SLukasz Dalek 
10043c09a283SLukasz Dalek /* ---------------------------------------------------------------------------
10053c09a283SLukasz Dalek  *	device-scoped parts of the api to the usb controller hardware
10063c09a283SLukasz Dalek  * ---------------------------------------------------------------------------
10073c09a283SLukasz Dalek  */
10083c09a283SLukasz Dalek 
pxa25x_udc_get_frame(struct usb_gadget * _gadget)10093c09a283SLukasz Dalek static int pxa25x_udc_get_frame(struct usb_gadget *_gadget)
10103c09a283SLukasz Dalek {
10113c09a283SLukasz Dalek 	return ((readl(&the_controller->regs->ufnrh) & 0x07) << 8) |
10123c09a283SLukasz Dalek 		(readl(&the_controller->regs->ufnrl) & 0xff);
10133c09a283SLukasz Dalek }
10143c09a283SLukasz Dalek 
pxa25x_udc_wakeup(struct usb_gadget * _gadget)10153c09a283SLukasz Dalek static int pxa25x_udc_wakeup(struct usb_gadget *_gadget)
10163c09a283SLukasz Dalek {
10173c09a283SLukasz Dalek 	/* host may not have enabled remote wakeup */
10183c09a283SLukasz Dalek 	if ((readl(&the_controller->regs->udccs[0]) & UDCCS0_DRWF) == 0)
10193c09a283SLukasz Dalek 		return -EHOSTUNREACH;
10203c09a283SLukasz Dalek 	udc_set_mask_UDCCR(UDCCR_RSM);
10213c09a283SLukasz Dalek 	return 0;
10223c09a283SLukasz Dalek }
10233c09a283SLukasz Dalek 
10243c09a283SLukasz Dalek static void stop_activity(struct pxa25x_udc *, struct usb_gadget_driver *);
10253c09a283SLukasz Dalek static void udc_enable(struct pxa25x_udc *);
10263c09a283SLukasz Dalek static void udc_disable(struct pxa25x_udc *);
10273c09a283SLukasz Dalek 
10283c09a283SLukasz Dalek /*
10293c09a283SLukasz Dalek  * We disable the UDC -- and its 48 MHz clock -- whenever it's not
10303c09a283SLukasz Dalek  * in active use.
10313c09a283SLukasz Dalek  */
pullup(struct pxa25x_udc * udc)10323c09a283SLukasz Dalek static int pullup(struct pxa25x_udc *udc)
10333c09a283SLukasz Dalek {
10343c09a283SLukasz Dalek 	if (udc->pullup)
10353c09a283SLukasz Dalek 		pullup_on();
10363c09a283SLukasz Dalek 	else
10373c09a283SLukasz Dalek 		pullup_off();
10383c09a283SLukasz Dalek 
10393c09a283SLukasz Dalek 
10403c09a283SLukasz Dalek 	int is_active = udc->pullup;
10413c09a283SLukasz Dalek 	if (is_active) {
10423c09a283SLukasz Dalek 		if (!udc->active) {
10433c09a283SLukasz Dalek 			udc->active = 1;
10443c09a283SLukasz Dalek 			udc_enable(udc);
10453c09a283SLukasz Dalek 		}
10463c09a283SLukasz Dalek 	} else {
10473c09a283SLukasz Dalek 		if (udc->active) {
10483c09a283SLukasz Dalek 			if (udc->gadget.speed != USB_SPEED_UNKNOWN)
10493c09a283SLukasz Dalek 				stop_activity(udc, udc->driver);
10503c09a283SLukasz Dalek 			udc_disable(udc);
10513c09a283SLukasz Dalek 			udc->active = 0;
10523c09a283SLukasz Dalek 		}
10533c09a283SLukasz Dalek 
10543c09a283SLukasz Dalek 	}
10553c09a283SLukasz Dalek 	return 0;
10563c09a283SLukasz Dalek }
10573c09a283SLukasz Dalek 
10583c09a283SLukasz Dalek /* VBUS reporting logically comes from a transceiver */
pxa25x_udc_vbus_session(struct usb_gadget * _gadget,int is_active)10593c09a283SLukasz Dalek static int pxa25x_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
10603c09a283SLukasz Dalek {
10613c09a283SLukasz Dalek 	struct pxa25x_udc *udc;
10623c09a283SLukasz Dalek 
10633c09a283SLukasz Dalek 	udc = container_of(_gadget, struct pxa25x_udc, gadget);
10643c09a283SLukasz Dalek 	printf("vbus %s\n", is_active ? "supplied" : "inactive");
10653c09a283SLukasz Dalek 	pullup(udc);
10663c09a283SLukasz Dalek 	return 0;
10673c09a283SLukasz Dalek }
10683c09a283SLukasz Dalek 
10693c09a283SLukasz Dalek /* drivers may have software control over D+ pullup */
pxa25x_udc_pullup(struct usb_gadget * _gadget,int is_active)10703c09a283SLukasz Dalek static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active)
10713c09a283SLukasz Dalek {
10723c09a283SLukasz Dalek 	struct pxa25x_udc	*udc;
10733c09a283SLukasz Dalek 
10743c09a283SLukasz Dalek 	udc = container_of(_gadget, struct pxa25x_udc, gadget);
10753c09a283SLukasz Dalek 
10763c09a283SLukasz Dalek 	/* not all boards support pullup control */
10773c09a283SLukasz Dalek 	if (!udc->mach->udc_command)
10783c09a283SLukasz Dalek 		return -EOPNOTSUPP;
10793c09a283SLukasz Dalek 
10803c09a283SLukasz Dalek 	udc->pullup = (is_active != 0);
10813c09a283SLukasz Dalek 	pullup(udc);
10823c09a283SLukasz Dalek 	return 0;
10833c09a283SLukasz Dalek }
10843c09a283SLukasz Dalek 
10853c09a283SLukasz Dalek /*
10863c09a283SLukasz Dalek  * boards may consume current from VBUS, up to 100-500mA based on config.
10873c09a283SLukasz Dalek  * the 500uA suspend ceiling means that exclusively vbus-powered PXA designs
10883c09a283SLukasz Dalek  * violate USB specs.
10893c09a283SLukasz Dalek  */
pxa25x_udc_vbus_draw(struct usb_gadget * _gadget,unsigned mA)10903c09a283SLukasz Dalek static int pxa25x_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
10913c09a283SLukasz Dalek {
10923c09a283SLukasz Dalek 	return -EOPNOTSUPP;
10933c09a283SLukasz Dalek }
10943c09a283SLukasz Dalek 
10953c09a283SLukasz Dalek static const struct usb_gadget_ops pxa25x_udc_ops = {
10963c09a283SLukasz Dalek 	.get_frame	= pxa25x_udc_get_frame,
10973c09a283SLukasz Dalek 	.wakeup		= pxa25x_udc_wakeup,
10983c09a283SLukasz Dalek 	.vbus_session	= pxa25x_udc_vbus_session,
10993c09a283SLukasz Dalek 	.pullup		= pxa25x_udc_pullup,
11003c09a283SLukasz Dalek 	.vbus_draw	= pxa25x_udc_vbus_draw,
11013c09a283SLukasz Dalek };
11023c09a283SLukasz Dalek 
11033c09a283SLukasz Dalek /*-------------------------------------------------------------------------*/
11043c09a283SLukasz Dalek 
11053c09a283SLukasz Dalek /*
11063c09a283SLukasz Dalek  *	udc_disable - disable USB device controller
11073c09a283SLukasz Dalek  */
udc_disable(struct pxa25x_udc * dev)11083c09a283SLukasz Dalek static void udc_disable(struct pxa25x_udc *dev)
11093c09a283SLukasz Dalek {
11103c09a283SLukasz Dalek 	/* block all irqs */
11113c09a283SLukasz Dalek 	udc_set_mask_UDCCR(UDCCR_SRM|UDCCR_REM);
11123c09a283SLukasz Dalek 	writel(0xff, &dev->regs->uicr0);
11133c09a283SLukasz Dalek 	writel(0xff, &dev->regs->uicr1);
11143c09a283SLukasz Dalek 	writel(UFNRH_SIM, &dev->regs->ufnrh);
11153c09a283SLukasz Dalek 
11163c09a283SLukasz Dalek 	/* if hardware supports it, disconnect from usb */
11173c09a283SLukasz Dalek 	pullup_off();
11183c09a283SLukasz Dalek 
11193c09a283SLukasz Dalek 	udc_clear_mask_UDCCR(UDCCR_UDE);
11203c09a283SLukasz Dalek 
11213c09a283SLukasz Dalek 	ep0_idle(dev);
11223c09a283SLukasz Dalek 	dev->gadget.speed = USB_SPEED_UNKNOWN;
11233c09a283SLukasz Dalek }
11243c09a283SLukasz Dalek 
11253c09a283SLukasz Dalek /*
11263c09a283SLukasz Dalek  *	udc_reinit - initialize software state
11273c09a283SLukasz Dalek  */
udc_reinit(struct pxa25x_udc * dev)11283c09a283SLukasz Dalek static void udc_reinit(struct pxa25x_udc *dev)
11293c09a283SLukasz Dalek {
11303c09a283SLukasz Dalek 	u32 i;
11313c09a283SLukasz Dalek 
11323c09a283SLukasz Dalek 	/* device/ep0 records init */
11333c09a283SLukasz Dalek 	INIT_LIST_HEAD(&dev->gadget.ep_list);
11343c09a283SLukasz Dalek 	INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
11353c09a283SLukasz Dalek 	dev->ep0state = EP0_IDLE;
11363c09a283SLukasz Dalek 
11373c09a283SLukasz Dalek 	/* basic endpoint records init */
11383c09a283SLukasz Dalek 	for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) {
11393c09a283SLukasz Dalek 		struct pxa25x_ep *ep = &dev->ep[i];
11403c09a283SLukasz Dalek 
11413c09a283SLukasz Dalek 		if (i != 0)
11423c09a283SLukasz Dalek 			list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
11433c09a283SLukasz Dalek 
11443c09a283SLukasz Dalek 		ep->desc = NULL;
11453c09a283SLukasz Dalek 		ep->stopped = 0;
11463c09a283SLukasz Dalek 		INIT_LIST_HEAD(&ep->queue);
11473c09a283SLukasz Dalek 		ep->pio_irqs = 0;
11483c09a283SLukasz Dalek 	}
11493c09a283SLukasz Dalek 
11503c09a283SLukasz Dalek 	/* the rest was statically initialized, and is read-only */
11513c09a283SLukasz Dalek }
11523c09a283SLukasz Dalek 
11533c09a283SLukasz Dalek /*
11543c09a283SLukasz Dalek  * until it's enabled, this UDC should be completely invisible
11553c09a283SLukasz Dalek  * to any USB host.
11563c09a283SLukasz Dalek  */
udc_enable(struct pxa25x_udc * dev)11573c09a283SLukasz Dalek static void udc_enable(struct pxa25x_udc *dev)
11583c09a283SLukasz Dalek {
11593c09a283SLukasz Dalek 	debug("udc: enabling udc\n");
11603c09a283SLukasz Dalek 
11613c09a283SLukasz Dalek 	udc_clear_mask_UDCCR(UDCCR_UDE);
11623c09a283SLukasz Dalek 
11633c09a283SLukasz Dalek 	/*
11643c09a283SLukasz Dalek 	 * Try to clear these bits before we enable the udc.
11653c09a283SLukasz Dalek 	 * Do not touch reset ack bit, we would take care of it in
11663c09a283SLukasz Dalek 	 * interrupt handle routine
11673c09a283SLukasz Dalek 	 */
11683c09a283SLukasz Dalek 	udc_ack_int_UDCCR(UDCCR_SUSIR|UDCCR_RESIR);
11693c09a283SLukasz Dalek 
11703c09a283SLukasz Dalek 	ep0_idle(dev);
11713c09a283SLukasz Dalek 	dev->gadget.speed = USB_SPEED_UNKNOWN;
11723c09a283SLukasz Dalek 	dev->stats.irqs = 0;
11733c09a283SLukasz Dalek 
11743c09a283SLukasz Dalek 	/*
11753c09a283SLukasz Dalek 	 * sequence taken from chapter 12.5.10, PXA250 AppProcDevManual:
11763c09a283SLukasz Dalek 	 * - enable UDC
11773c09a283SLukasz Dalek 	 * - if RESET is already in progress, ack interrupt
11783c09a283SLukasz Dalek 	 * - unmask reset interrupt
11793c09a283SLukasz Dalek 	 */
11803c09a283SLukasz Dalek 	udc_set_mask_UDCCR(UDCCR_UDE);
11813c09a283SLukasz Dalek 	if (!(readl(&dev->regs->udccr) & UDCCR_UDA))
11823c09a283SLukasz Dalek 		udc_ack_int_UDCCR(UDCCR_RSTIR);
11833c09a283SLukasz Dalek 
11843c09a283SLukasz Dalek 	if (dev->has_cfr /* UDC_RES2 is defined */) {
11853c09a283SLukasz Dalek 		/*
11863c09a283SLukasz Dalek 		 * pxa255 (a0+) can avoid a set_config race that could
11873c09a283SLukasz Dalek 		 * prevent gadget drivers from configuring correctly
11883c09a283SLukasz Dalek 		 */
11893c09a283SLukasz Dalek 		writel(UDCCFR_ACM | UDCCFR_MB1, &dev->regs->udccfr);
11903c09a283SLukasz Dalek 	}
11913c09a283SLukasz Dalek 
11923c09a283SLukasz Dalek 	/* enable suspend/resume and reset irqs */
11933c09a283SLukasz Dalek 	udc_clear_mask_UDCCR(UDCCR_SRM | UDCCR_REM);
11943c09a283SLukasz Dalek 
11953c09a283SLukasz Dalek 	/* enable ep0 irqs */
11963c09a283SLukasz Dalek 	clrbits_le32(&dev->regs->uicr0, UICR0_IM0);
11973c09a283SLukasz Dalek 
11983c09a283SLukasz Dalek 	/* if hardware supports it, pullup D+ and wait for reset */
11993c09a283SLukasz Dalek 	pullup_on();
12003c09a283SLukasz Dalek }
12013c09a283SLukasz Dalek 
clear_ep_state(struct pxa25x_udc * dev)12023c09a283SLukasz Dalek static inline void clear_ep_state(struct pxa25x_udc *dev)
12033c09a283SLukasz Dalek {
12043c09a283SLukasz Dalek 	unsigned i;
12053c09a283SLukasz Dalek 
12063c09a283SLukasz Dalek 	/*
12073c09a283SLukasz Dalek 	 * hardware SET_{CONFIGURATION,INTERFACE} automagic resets endpoint
12083c09a283SLukasz Dalek 	 * fifos, and pending transactions mustn't be continued in any case.
12093c09a283SLukasz Dalek 	 */
12103c09a283SLukasz Dalek 	for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++)
12113c09a283SLukasz Dalek 		nuke(&dev->ep[i], -ECONNABORTED);
12123c09a283SLukasz Dalek }
12133c09a283SLukasz Dalek 
handle_ep0(struct pxa25x_udc * dev)12143c09a283SLukasz Dalek static void handle_ep0(struct pxa25x_udc *dev)
12153c09a283SLukasz Dalek {
12163c09a283SLukasz Dalek 	u32 udccs0 = readl(&dev->regs->udccs[0]);
12173c09a283SLukasz Dalek 	struct pxa25x_ep *ep = &dev->ep[0];
12183c09a283SLukasz Dalek 	struct pxa25x_request *req;
12193c09a283SLukasz Dalek 	union {
12203c09a283SLukasz Dalek 		struct usb_ctrlrequest	r;
12213c09a283SLukasz Dalek 		u8			raw[8];
12223c09a283SLukasz Dalek 		u32			word[2];
12233c09a283SLukasz Dalek 	} u;
12243c09a283SLukasz Dalek 
12253c09a283SLukasz Dalek 	if (list_empty(&ep->queue))
12263c09a283SLukasz Dalek 		req = NULL;
12273c09a283SLukasz Dalek 	else
12283c09a283SLukasz Dalek 		req = list_entry(ep->queue.next, struct pxa25x_request, queue);
12293c09a283SLukasz Dalek 
12303c09a283SLukasz Dalek 	/* clear stall status */
12313c09a283SLukasz Dalek 	if (udccs0 & UDCCS0_SST) {
12323c09a283SLukasz Dalek 		nuke(ep, -EPIPE);
12333c09a283SLukasz Dalek 		writel(UDCCS0_SST, &dev->regs->udccs[0]);
12343c09a283SLukasz Dalek 		stop_watchdog(dev);
12353c09a283SLukasz Dalek 		ep0_idle(dev);
12363c09a283SLukasz Dalek 	}
12373c09a283SLukasz Dalek 
12383c09a283SLukasz Dalek 	/* previous request unfinished?  non-error iff back-to-back ... */
12393c09a283SLukasz Dalek 	if ((udccs0 & UDCCS0_SA) != 0 && dev->ep0state != EP0_IDLE) {
12403c09a283SLukasz Dalek 		nuke(ep, 0);
12413c09a283SLukasz Dalek 		stop_watchdog(dev);
12423c09a283SLukasz Dalek 		ep0_idle(dev);
12433c09a283SLukasz Dalek 	}
12443c09a283SLukasz Dalek 
12453c09a283SLukasz Dalek 	switch (dev->ep0state) {
12463c09a283SLukasz Dalek 	case EP0_IDLE:
12473c09a283SLukasz Dalek 		/* late-breaking status? */
12483c09a283SLukasz Dalek 		udccs0 = readl(&dev->regs->udccs[0]);
12493c09a283SLukasz Dalek 
12503c09a283SLukasz Dalek 		/* start control request? */
12513c09a283SLukasz Dalek 		if (likely((udccs0 & (UDCCS0_OPR|UDCCS0_SA|UDCCS0_RNE))
12523c09a283SLukasz Dalek 				== (UDCCS0_OPR|UDCCS0_SA|UDCCS0_RNE))) {
12533c09a283SLukasz Dalek 			int i;
12543c09a283SLukasz Dalek 
12553c09a283SLukasz Dalek 			nuke(ep, -EPROTO);
12563c09a283SLukasz Dalek 
12573c09a283SLukasz Dalek 			/* read SETUP packet */
12583c09a283SLukasz Dalek 			for (i = 0; i < 8; i++) {
12593c09a283SLukasz Dalek 				if (unlikely(!(readl(&dev->regs->udccs[0]) &
12603c09a283SLukasz Dalek 						UDCCS0_RNE))) {
12613c09a283SLukasz Dalek bad_setup:
12623c09a283SLukasz Dalek 					debug("SETUP %d!\n", i);
12633c09a283SLukasz Dalek 					goto stall;
12643c09a283SLukasz Dalek 				}
12653c09a283SLukasz Dalek 				u.raw[i] = (u8)readb(&dev->regs->uddr0);
12663c09a283SLukasz Dalek 			}
12673c09a283SLukasz Dalek 			if (unlikely((readl(&dev->regs->udccs[0]) &
12683c09a283SLukasz Dalek 					UDCCS0_RNE) != 0))
12693c09a283SLukasz Dalek 				goto bad_setup;
12703c09a283SLukasz Dalek 
12713c09a283SLukasz Dalek got_setup:
12723c09a283SLukasz Dalek 			debug("SETUP %02x.%02x v%04x i%04x l%04x\n",
12733c09a283SLukasz Dalek 				u.r.bRequestType, u.r.bRequest,
12743c09a283SLukasz Dalek 				le16_to_cpu(u.r.wValue),
12753c09a283SLukasz Dalek 				le16_to_cpu(u.r.wIndex),
12763c09a283SLukasz Dalek 				le16_to_cpu(u.r.wLength));
12773c09a283SLukasz Dalek 
12783c09a283SLukasz Dalek 			/* cope with automagic for some standard requests. */
12793c09a283SLukasz Dalek 			dev->req_std = (u.r.bRequestType & USB_TYPE_MASK)
12803c09a283SLukasz Dalek 						== USB_TYPE_STANDARD;
12813c09a283SLukasz Dalek 			dev->req_config = 0;
12823c09a283SLukasz Dalek 			dev->req_pending = 1;
12833c09a283SLukasz Dalek 			switch (u.r.bRequest) {
12843c09a283SLukasz Dalek 			/* hardware restricts gadget drivers here! */
12853c09a283SLukasz Dalek 			case USB_REQ_SET_CONFIGURATION:
12863c09a283SLukasz Dalek 				debug("GOT SET_CONFIGURATION\n");
12873c09a283SLukasz Dalek 				if (u.r.bRequestType == USB_RECIP_DEVICE) {
12883c09a283SLukasz Dalek 					/*
12893c09a283SLukasz Dalek 					 * reflect hardware's automagic
12903c09a283SLukasz Dalek 					 * up to the gadget driver.
12913c09a283SLukasz Dalek 					 */
12923c09a283SLukasz Dalek config_change:
12933c09a283SLukasz Dalek 					dev->req_config = 1;
12943c09a283SLukasz Dalek 					clear_ep_state(dev);
12953c09a283SLukasz Dalek 					/*
12963c09a283SLukasz Dalek 					 * if !has_cfr, there's no synch
12973c09a283SLukasz Dalek 					 * else use AREN (later) not SA|OPR
12983c09a283SLukasz Dalek 					 * USIR0_IR0 acts edge sensitive
12993c09a283SLukasz Dalek 					 */
13003c09a283SLukasz Dalek 				}
13013c09a283SLukasz Dalek 				break;
13023c09a283SLukasz Dalek 			/* ... and here, even more ... */
13033c09a283SLukasz Dalek 			case USB_REQ_SET_INTERFACE:
13043c09a283SLukasz Dalek 				if (u.r.bRequestType == USB_RECIP_INTERFACE) {
13053c09a283SLukasz Dalek 					/*
13063c09a283SLukasz Dalek 					 * udc hardware is broken by design:
13073c09a283SLukasz Dalek 					 *  - altsetting may only be zero;
13083c09a283SLukasz Dalek 					 *  - hw resets all interfaces' eps;
13093c09a283SLukasz Dalek 					 *  - ep reset doesn't include halt(?).
13103c09a283SLukasz Dalek 					 */
13113c09a283SLukasz Dalek 					printf("broken set_interface (%d/%d)\n",
13123c09a283SLukasz Dalek 						le16_to_cpu(u.r.wIndex),
13133c09a283SLukasz Dalek 						le16_to_cpu(u.r.wValue));
13143c09a283SLukasz Dalek 					goto config_change;
13153c09a283SLukasz Dalek 				}
13163c09a283SLukasz Dalek 				break;
13173c09a283SLukasz Dalek 			/* hardware was supposed to hide this */
13183c09a283SLukasz Dalek 			case USB_REQ_SET_ADDRESS:
13193c09a283SLukasz Dalek 				debug("GOT SET ADDRESS\n");
13203c09a283SLukasz Dalek 				if (u.r.bRequestType == USB_RECIP_DEVICE) {
13213c09a283SLukasz Dalek 					ep0start(dev, 0, "address");
13223c09a283SLukasz Dalek 					return;
13233c09a283SLukasz Dalek 				}
13243c09a283SLukasz Dalek 				break;
13253c09a283SLukasz Dalek 			}
13263c09a283SLukasz Dalek 
13273c09a283SLukasz Dalek 			if (u.r.bRequestType & USB_DIR_IN)
13283c09a283SLukasz Dalek 				dev->ep0state = EP0_IN_DATA_PHASE;
13293c09a283SLukasz Dalek 			else
13303c09a283SLukasz Dalek 				dev->ep0state = EP0_OUT_DATA_PHASE;
13313c09a283SLukasz Dalek 
13323c09a283SLukasz Dalek 			i = dev->driver->setup(&dev->gadget, &u.r);
13333c09a283SLukasz Dalek 			if (i < 0) {
13343c09a283SLukasz Dalek 				/* hardware automagic preventing STALL... */
13353c09a283SLukasz Dalek 				if (dev->req_config) {
13363c09a283SLukasz Dalek 					/*
13373c09a283SLukasz Dalek 					 * hardware sometimes neglects to tell
13383c09a283SLukasz Dalek 					 * tell us about config change events,
13393c09a283SLukasz Dalek 					 * so later ones may fail...
13403c09a283SLukasz Dalek 					 */
13413c09a283SLukasz Dalek 					printf("config change %02x fail %d?\n",
13423c09a283SLukasz Dalek 						u.r.bRequest, i);
13433c09a283SLukasz Dalek 					return;
13443c09a283SLukasz Dalek 					/*
13453c09a283SLukasz Dalek 					 * TODO experiment:  if has_cfr,
13463c09a283SLukasz Dalek 					 * hardware didn't ACK; maybe we
13473c09a283SLukasz Dalek 					 * could actually STALL!
13483c09a283SLukasz Dalek 					 */
13493c09a283SLukasz Dalek 				}
13503c09a283SLukasz Dalek 				if (0) {
13513c09a283SLukasz Dalek stall:
13523c09a283SLukasz Dalek 					/* uninitialized when goto stall */
13533c09a283SLukasz Dalek 					i = 0;
13543c09a283SLukasz Dalek 				}
13553c09a283SLukasz Dalek 				debug("protocol STALL, "
13563c09a283SLukasz Dalek 					"%02x err %d\n",
13573c09a283SLukasz Dalek 					readl(&dev->regs->udccs[0]), i);
13583c09a283SLukasz Dalek 
13593c09a283SLukasz Dalek 				/*
13603c09a283SLukasz Dalek 				 * the watchdog timer helps deal with cases
13613c09a283SLukasz Dalek 				 * where udc seems to clear FST wrongly, and
13623c09a283SLukasz Dalek 				 * then NAKs instead of STALLing.
13633c09a283SLukasz Dalek 				 */
13643c09a283SLukasz Dalek 				ep0start(dev, UDCCS0_FST|UDCCS0_FTF, "stall");
13653c09a283SLukasz Dalek 				start_watchdog(dev);
13663c09a283SLukasz Dalek 				dev->ep0state = EP0_STALL;
13673c09a283SLukasz Dalek 
13683c09a283SLukasz Dalek 			/* deferred i/o == no response yet */
13693c09a283SLukasz Dalek 			} else if (dev->req_pending) {
13703c09a283SLukasz Dalek 				if (likely(dev->ep0state == EP0_IN_DATA_PHASE
13713c09a283SLukasz Dalek 						|| dev->req_std || u.r.wLength))
13723c09a283SLukasz Dalek 					ep0start(dev, 0, "defer");
13733c09a283SLukasz Dalek 				else
13743c09a283SLukasz Dalek 					ep0start(dev, UDCCS0_IPR, "defer/IPR");
13753c09a283SLukasz Dalek 			}
13763c09a283SLukasz Dalek 
13773c09a283SLukasz Dalek 			/* expect at least one data or status stage irq */
13783c09a283SLukasz Dalek 			return;
13793c09a283SLukasz Dalek 
13803c09a283SLukasz Dalek 		} else if (likely((udccs0 & (UDCCS0_OPR|UDCCS0_SA))
13813c09a283SLukasz Dalek 				== (UDCCS0_OPR|UDCCS0_SA))) {
13823c09a283SLukasz Dalek 			unsigned i;
13833c09a283SLukasz Dalek 
13843c09a283SLukasz Dalek 			/*
13853c09a283SLukasz Dalek 			 * pxa210/250 erratum 131 for B0/B1 says RNE lies.
13863c09a283SLukasz Dalek 			 * still observed on a pxa255 a0.
13873c09a283SLukasz Dalek 			 */
13883c09a283SLukasz Dalek 			debug("e131\n");
13893c09a283SLukasz Dalek 			nuke(ep, -EPROTO);
13903c09a283SLukasz Dalek 
13913c09a283SLukasz Dalek 			/* read SETUP data, but don't trust it too much */
13923c09a283SLukasz Dalek 			for (i = 0; i < 8; i++)
13933c09a283SLukasz Dalek 				u.raw[i] = (u8)readb(&dev->regs->uddr0);
13943c09a283SLukasz Dalek 			if ((u.r.bRequestType & USB_RECIP_MASK)
13953c09a283SLukasz Dalek 					> USB_RECIP_OTHER)
13963c09a283SLukasz Dalek 				goto stall;
13973c09a283SLukasz Dalek 			if (u.word[0] == 0 && u.word[1] == 0)
13983c09a283SLukasz Dalek 				goto stall;
13993c09a283SLukasz Dalek 			goto got_setup;
14003c09a283SLukasz Dalek 		} else {
14013c09a283SLukasz Dalek 			/*
14023c09a283SLukasz Dalek 			 * some random early IRQ:
14033c09a283SLukasz Dalek 			 * - we acked FST
14043c09a283SLukasz Dalek 			 * - IPR cleared
14053c09a283SLukasz Dalek 			 * - OPR got set, without SA (likely status stage)
14063c09a283SLukasz Dalek 			 */
14073c09a283SLukasz Dalek 			debug("random IRQ %X %X\n", udccs0,
14083c09a283SLukasz Dalek 				readl(&dev->regs->udccs[0]));
14093c09a283SLukasz Dalek 			writel(udccs0 & (UDCCS0_SA|UDCCS0_OPR),
14103c09a283SLukasz Dalek 				&dev->regs->udccs[0]);
14113c09a283SLukasz Dalek 		}
14123c09a283SLukasz Dalek 		break;
14133c09a283SLukasz Dalek 	case EP0_IN_DATA_PHASE:			/* GET_DESCRIPTOR etc */
14143c09a283SLukasz Dalek 		if (udccs0 & UDCCS0_OPR) {
14153c09a283SLukasz Dalek 			debug("ep0in premature status\n");
14163c09a283SLukasz Dalek 			if (req)
14173c09a283SLukasz Dalek 				done(ep, req, 0);
14183c09a283SLukasz Dalek 			ep0_idle(dev);
14193c09a283SLukasz Dalek 		} else /* irq was IPR clearing */ {
14203c09a283SLukasz Dalek 			if (req) {
14213c09a283SLukasz Dalek 				debug("next ep0 in packet\n");
14223c09a283SLukasz Dalek 				/* this IN packet might finish the request */
14233c09a283SLukasz Dalek 				(void) write_ep0_fifo(ep, req);
14243c09a283SLukasz Dalek 			} /* else IN token before response was written */
14253c09a283SLukasz Dalek 		}
14263c09a283SLukasz Dalek 		break;
14273c09a283SLukasz Dalek 	case EP0_OUT_DATA_PHASE:		/* SET_DESCRIPTOR etc */
14283c09a283SLukasz Dalek 		if (udccs0 & UDCCS0_OPR) {
14293c09a283SLukasz Dalek 			if (req) {
14303c09a283SLukasz Dalek 				/* this OUT packet might finish the request */
14313c09a283SLukasz Dalek 				if (read_ep0_fifo(ep, req))
14323c09a283SLukasz Dalek 					done(ep, req, 0);
14333c09a283SLukasz Dalek 				/* else more OUT packets expected */
14343c09a283SLukasz Dalek 			} /* else OUT token before read was issued */
14353c09a283SLukasz Dalek 		} else /* irq was IPR clearing */ {
14363c09a283SLukasz Dalek 			debug("ep0out premature status\n");
14373c09a283SLukasz Dalek 			if (req)
14383c09a283SLukasz Dalek 				done(ep, req, 0);
14393c09a283SLukasz Dalek 			ep0_idle(dev);
14403c09a283SLukasz Dalek 		}
14413c09a283SLukasz Dalek 		break;
14423c09a283SLukasz Dalek 	case EP0_END_XFER:
14433c09a283SLukasz Dalek 		if (req)
14443c09a283SLukasz Dalek 			done(ep, req, 0);
14453c09a283SLukasz Dalek 		/*
14463c09a283SLukasz Dalek 		 * ack control-IN status (maybe in-zlp was skipped)
14473c09a283SLukasz Dalek 		 * also appears after some config change events.
14483c09a283SLukasz Dalek 		 */
14493c09a283SLukasz Dalek 		if (udccs0 & UDCCS0_OPR)
14503c09a283SLukasz Dalek 			writel(UDCCS0_OPR, &dev->regs->udccs[0]);
14513c09a283SLukasz Dalek 		ep0_idle(dev);
14523c09a283SLukasz Dalek 		break;
14533c09a283SLukasz Dalek 	case EP0_STALL:
14543c09a283SLukasz Dalek 		writel(UDCCS0_FST, &dev->regs->udccs[0]);
14553c09a283SLukasz Dalek 		break;
14563c09a283SLukasz Dalek 	}
14573c09a283SLukasz Dalek 
14583c09a283SLukasz Dalek 	writel(USIR0_IR0, &dev->regs->usir0);
14593c09a283SLukasz Dalek }
14603c09a283SLukasz Dalek 
handle_ep(struct pxa25x_ep * ep)14613c09a283SLukasz Dalek static void handle_ep(struct pxa25x_ep *ep)
14623c09a283SLukasz Dalek {
14633c09a283SLukasz Dalek 	struct pxa25x_request	*req;
14643c09a283SLukasz Dalek 	int			is_in = ep->bEndpointAddress & USB_DIR_IN;
14653c09a283SLukasz Dalek 	int			completed;
14663c09a283SLukasz Dalek 	u32			udccs, tmp;
14673c09a283SLukasz Dalek 
14683c09a283SLukasz Dalek 	do {
14693c09a283SLukasz Dalek 		completed = 0;
14703c09a283SLukasz Dalek 		if (likely(!list_empty(&ep->queue)))
14713c09a283SLukasz Dalek 			req = list_entry(ep->queue.next,
14723c09a283SLukasz Dalek 					struct pxa25x_request, queue);
14733c09a283SLukasz Dalek 		else
14743c09a283SLukasz Dalek 			req = NULL;
14753c09a283SLukasz Dalek 
14763c09a283SLukasz Dalek 		/* TODO check FST handling */
14773c09a283SLukasz Dalek 
14783c09a283SLukasz Dalek 		udccs = readl(ep->reg_udccs);
14793c09a283SLukasz Dalek 		if (unlikely(is_in)) {	/* irq from TPC, SST, or (ISO) TUR */
14803c09a283SLukasz Dalek 			tmp = UDCCS_BI_TUR;
14813c09a283SLukasz Dalek 			if (likely(ep->bmAttributes == USB_ENDPOINT_XFER_BULK))
14823c09a283SLukasz Dalek 				tmp |= UDCCS_BI_SST;
14833c09a283SLukasz Dalek 			tmp &= udccs;
14843c09a283SLukasz Dalek 			if (likely(tmp))
14853c09a283SLukasz Dalek 				writel(tmp, ep->reg_udccs);
14863c09a283SLukasz Dalek 			if (req && likely((udccs & UDCCS_BI_TFS) != 0))
14873c09a283SLukasz Dalek 				completed = write_fifo(ep, req);
14883c09a283SLukasz Dalek 
14893c09a283SLukasz Dalek 		} else {	/* irq from RPC (or for ISO, ROF) */
14903c09a283SLukasz Dalek 			if (likely(ep->bmAttributes == USB_ENDPOINT_XFER_BULK))
14913c09a283SLukasz Dalek 				tmp = UDCCS_BO_SST | UDCCS_BO_DME;
14923c09a283SLukasz Dalek 			else
14933c09a283SLukasz Dalek 				tmp = UDCCS_IO_ROF | UDCCS_IO_DME;
14943c09a283SLukasz Dalek 			tmp &= udccs;
14953c09a283SLukasz Dalek 			if (likely(tmp))
14963c09a283SLukasz Dalek 				writel(tmp, ep->reg_udccs);
14973c09a283SLukasz Dalek 
14983c09a283SLukasz Dalek 			/* fifos can hold packets, ready for reading... */
14993c09a283SLukasz Dalek 			if (likely(req))
15003c09a283SLukasz Dalek 				completed = read_fifo(ep, req);
15013c09a283SLukasz Dalek 			else
15023c09a283SLukasz Dalek 				pio_irq_disable(ep->bEndpointAddress);
15033c09a283SLukasz Dalek 		}
15043c09a283SLukasz Dalek 		ep->pio_irqs++;
15053c09a283SLukasz Dalek 	} while (completed);
15063c09a283SLukasz Dalek }
15073c09a283SLukasz Dalek 
15083c09a283SLukasz Dalek /*
15093c09a283SLukasz Dalek  *	pxa25x_udc_irq - interrupt handler
15103c09a283SLukasz Dalek  *
15113c09a283SLukasz Dalek  * avoid delays in ep0 processing. the control handshaking isn't always
15123c09a283SLukasz Dalek  * under software control (pxa250c0 and the pxa255 are better), and delays
15133c09a283SLukasz Dalek  * could cause usb protocol errors.
15143c09a283SLukasz Dalek  */
15153c09a283SLukasz Dalek static struct pxa25x_udc memory;
15163c09a283SLukasz Dalek static int
pxa25x_udc_irq(void)15173c09a283SLukasz Dalek pxa25x_udc_irq(void)
15183c09a283SLukasz Dalek {
15193c09a283SLukasz Dalek 	struct pxa25x_udc *dev = &memory;
15203c09a283SLukasz Dalek 	int handled;
15213c09a283SLukasz Dalek 
15223c09a283SLukasz Dalek 	test_watchdog(dev);
15233c09a283SLukasz Dalek 
15243c09a283SLukasz Dalek 	dev->stats.irqs++;
15253c09a283SLukasz Dalek 	do {
15263c09a283SLukasz Dalek 		u32 udccr = readl(&dev->regs->udccr);
15273c09a283SLukasz Dalek 
15283c09a283SLukasz Dalek 		handled = 0;
15293c09a283SLukasz Dalek 
15303c09a283SLukasz Dalek 		/* SUSpend Interrupt Request */
15313c09a283SLukasz Dalek 		if (unlikely(udccr & UDCCR_SUSIR)) {
15323c09a283SLukasz Dalek 			udc_ack_int_UDCCR(UDCCR_SUSIR);
15333c09a283SLukasz Dalek 			handled = 1;
15343c09a283SLukasz Dalek 			debug("USB suspend\n");
15353c09a283SLukasz Dalek 
15363c09a283SLukasz Dalek 			if (dev->gadget.speed != USB_SPEED_UNKNOWN
15373c09a283SLukasz Dalek 					&& dev->driver
15383c09a283SLukasz Dalek 					&& dev->driver->suspend)
15393c09a283SLukasz Dalek 				dev->driver->suspend(&dev->gadget);
15403c09a283SLukasz Dalek 			ep0_idle(dev);
15413c09a283SLukasz Dalek 		}
15423c09a283SLukasz Dalek 
15433c09a283SLukasz Dalek 		/* RESume Interrupt Request */
15443c09a283SLukasz Dalek 		if (unlikely(udccr & UDCCR_RESIR)) {
15453c09a283SLukasz Dalek 			udc_ack_int_UDCCR(UDCCR_RESIR);
15463c09a283SLukasz Dalek 			handled = 1;
15473c09a283SLukasz Dalek 			debug("USB resume\n");
15483c09a283SLukasz Dalek 
15493c09a283SLukasz Dalek 			if (dev->gadget.speed != USB_SPEED_UNKNOWN
15503c09a283SLukasz Dalek 					&& dev->driver
15513c09a283SLukasz Dalek 					&& dev->driver->resume)
15523c09a283SLukasz Dalek 				dev->driver->resume(&dev->gadget);
15533c09a283SLukasz Dalek 		}
15543c09a283SLukasz Dalek 
15553c09a283SLukasz Dalek 		/* ReSeT Interrupt Request - USB reset */
15563c09a283SLukasz Dalek 		if (unlikely(udccr & UDCCR_RSTIR)) {
15573c09a283SLukasz Dalek 			udc_ack_int_UDCCR(UDCCR_RSTIR);
15583c09a283SLukasz Dalek 			handled = 1;
15593c09a283SLukasz Dalek 
15603c09a283SLukasz Dalek 			if ((readl(&dev->regs->udccr) & UDCCR_UDA) == 0) {
15613c09a283SLukasz Dalek 				debug("USB reset start\n");
15623c09a283SLukasz Dalek 
15633c09a283SLukasz Dalek 				/*
15643c09a283SLukasz Dalek 				 * reset driver and endpoints,
15653c09a283SLukasz Dalek 				 * in case that's not yet done
15663c09a283SLukasz Dalek 				 */
15673c09a283SLukasz Dalek 				stop_activity(dev, dev->driver);
15683c09a283SLukasz Dalek 
15693c09a283SLukasz Dalek 			} else {
15703c09a283SLukasz Dalek 				debug("USB reset end\n");
15713c09a283SLukasz Dalek 				dev->gadget.speed = USB_SPEED_FULL;
15723c09a283SLukasz Dalek 				memset(&dev->stats, 0, sizeof dev->stats);
15733c09a283SLukasz Dalek 				/* driver and endpoints are still reset */
15743c09a283SLukasz Dalek 			}
15753c09a283SLukasz Dalek 
15763c09a283SLukasz Dalek 		} else {
15773c09a283SLukasz Dalek 			u32 uicr0 = readl(&dev->regs->uicr0);
15783c09a283SLukasz Dalek 			u32 uicr1 = readl(&dev->regs->uicr1);
15793c09a283SLukasz Dalek 			u32 usir0 = readl(&dev->regs->usir0);
15803c09a283SLukasz Dalek 			u32 usir1 = readl(&dev->regs->usir1);
15813c09a283SLukasz Dalek 
15823c09a283SLukasz Dalek 			usir0 = usir0 & ~uicr0;
15833c09a283SLukasz Dalek 			usir1 = usir1 & ~uicr1;
15843c09a283SLukasz Dalek 			int i;
15853c09a283SLukasz Dalek 
15863c09a283SLukasz Dalek 			if (unlikely(!usir0 && !usir1))
15873c09a283SLukasz Dalek 				continue;
15883c09a283SLukasz Dalek 
15893c09a283SLukasz Dalek 			debug_cond(NOISY, "irq %02x.%02x\n", usir1, usir0);
15903c09a283SLukasz Dalek 
15913c09a283SLukasz Dalek 			/* control traffic */
15923c09a283SLukasz Dalek 			if (usir0 & USIR0_IR0) {
15933c09a283SLukasz Dalek 				dev->ep[0].pio_irqs++;
15943c09a283SLukasz Dalek 				handle_ep0(dev);
15953c09a283SLukasz Dalek 				handled = 1;
15963c09a283SLukasz Dalek 			}
15973c09a283SLukasz Dalek 
15983c09a283SLukasz Dalek 			/* endpoint data transfers */
15993c09a283SLukasz Dalek 			for (i = 0; i < 8; i++) {
16003c09a283SLukasz Dalek 				u32	tmp = 1 << i;
16013c09a283SLukasz Dalek 
16023c09a283SLukasz Dalek 				if (i && (usir0 & tmp)) {
16033c09a283SLukasz Dalek 					handle_ep(&dev->ep[i]);
16043c09a283SLukasz Dalek 					setbits_le32(&dev->regs->usir0, tmp);
16053c09a283SLukasz Dalek 					handled = 1;
16063c09a283SLukasz Dalek 				}
16073c09a283SLukasz Dalek #ifndef	CONFIG_USB_PXA25X_SMALL
16083c09a283SLukasz Dalek 				if (usir1 & tmp) {
16093c09a283SLukasz Dalek 					handle_ep(&dev->ep[i+8]);
16103c09a283SLukasz Dalek 					setbits_le32(&dev->regs->usir1, tmp);
16113c09a283SLukasz Dalek 					handled = 1;
16123c09a283SLukasz Dalek 				}
16133c09a283SLukasz Dalek #endif
16143c09a283SLukasz Dalek 			}
16153c09a283SLukasz Dalek 		}
16163c09a283SLukasz Dalek 
16173c09a283SLukasz Dalek 		/* we could also ask for 1 msec SOF (SIR) interrupts */
16183c09a283SLukasz Dalek 
16193c09a283SLukasz Dalek 	} while (handled);
16203c09a283SLukasz Dalek 	return IRQ_HANDLED;
16213c09a283SLukasz Dalek }
16223c09a283SLukasz Dalek 
16233c09a283SLukasz Dalek /*-------------------------------------------------------------------------*/
16243c09a283SLukasz Dalek 
16253c09a283SLukasz Dalek /*
16263c09a283SLukasz Dalek  * this uses load-time allocation and initialization (instead of
16273c09a283SLukasz Dalek  * doing it at run-time) to save code, eliminate fault paths, and
16283c09a283SLukasz Dalek  * be more obviously correct.
16293c09a283SLukasz Dalek  */
16303c09a283SLukasz Dalek static struct pxa25x_udc memory = {
16313c09a283SLukasz Dalek 	.regs = UDC_REGS,
16323c09a283SLukasz Dalek 
16333c09a283SLukasz Dalek 	.gadget = {
16343c09a283SLukasz Dalek 		.ops		= &pxa25x_udc_ops,
16353c09a283SLukasz Dalek 		.ep0		= &memory.ep[0].ep,
16363c09a283SLukasz Dalek 		.name		= driver_name,
16373c09a283SLukasz Dalek 	},
16383c09a283SLukasz Dalek 
16393c09a283SLukasz Dalek 	/* control endpoint */
16403c09a283SLukasz Dalek 	.ep[0] = {
16413c09a283SLukasz Dalek 		.ep = {
16423c09a283SLukasz Dalek 			.name		= ep0name,
16433c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
16443c09a283SLukasz Dalek 			.maxpacket	= EP0_FIFO_SIZE,
16453c09a283SLukasz Dalek 		},
16463c09a283SLukasz Dalek 		.dev		= &memory,
16473c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[0],
16483c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr0,
16493c09a283SLukasz Dalek 	},
16503c09a283SLukasz Dalek 
16513c09a283SLukasz Dalek 	/* first group of endpoints */
16523c09a283SLukasz Dalek 	.ep[1] = {
16533c09a283SLukasz Dalek 		.ep = {
16543c09a283SLukasz Dalek 			.name		= "ep1in-bulk",
16553c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
16563c09a283SLukasz Dalek 			.maxpacket	= BULK_FIFO_SIZE,
16573c09a283SLukasz Dalek 		},
16583c09a283SLukasz Dalek 		.dev		= &memory,
16593c09a283SLukasz Dalek 		.fifo_size	= BULK_FIFO_SIZE,
16603c09a283SLukasz Dalek 		.bEndpointAddress = USB_DIR_IN | 1,
16613c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
16623c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[1],
16633c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr1,
16643c09a283SLukasz Dalek 	},
16653c09a283SLukasz Dalek 	.ep[2] = {
16663c09a283SLukasz Dalek 		.ep = {
16673c09a283SLukasz Dalek 			.name		= "ep2out-bulk",
16683c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
16693c09a283SLukasz Dalek 			.maxpacket	= BULK_FIFO_SIZE,
16703c09a283SLukasz Dalek 		},
16713c09a283SLukasz Dalek 		.dev		= &memory,
16723c09a283SLukasz Dalek 		.fifo_size	= BULK_FIFO_SIZE,
16733c09a283SLukasz Dalek 		.bEndpointAddress = 2,
16743c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
16753c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[2],
16763c09a283SLukasz Dalek 		.reg_ubcr	= &UDC_REGS->ubcr2,
16773c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr2,
16783c09a283SLukasz Dalek 	},
16793c09a283SLukasz Dalek #ifndef CONFIG_USB_PXA25X_SMALL
16803c09a283SLukasz Dalek 	.ep[3] = {
16813c09a283SLukasz Dalek 		.ep = {
16823c09a283SLukasz Dalek 			.name		= "ep3in-iso",
16833c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
16843c09a283SLukasz Dalek 			.maxpacket	= ISO_FIFO_SIZE,
16853c09a283SLukasz Dalek 		},
16863c09a283SLukasz Dalek 		.dev		= &memory,
16873c09a283SLukasz Dalek 		.fifo_size	= ISO_FIFO_SIZE,
16883c09a283SLukasz Dalek 		.bEndpointAddress = USB_DIR_IN | 3,
16893c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
16903c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[3],
16913c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr3,
16923c09a283SLukasz Dalek 	},
16933c09a283SLukasz Dalek 	.ep[4] = {
16943c09a283SLukasz Dalek 		.ep = {
16953c09a283SLukasz Dalek 			.name		= "ep4out-iso",
16963c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
16973c09a283SLukasz Dalek 			.maxpacket	= ISO_FIFO_SIZE,
16983c09a283SLukasz Dalek 		},
16993c09a283SLukasz Dalek 		.dev		= &memory,
17003c09a283SLukasz Dalek 		.fifo_size	= ISO_FIFO_SIZE,
17013c09a283SLukasz Dalek 		.bEndpointAddress = 4,
17023c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
17033c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[4],
17043c09a283SLukasz Dalek 		.reg_ubcr	= &UDC_REGS->ubcr4,
17053c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr4,
17063c09a283SLukasz Dalek 	},
17073c09a283SLukasz Dalek 	.ep[5] = {
17083c09a283SLukasz Dalek 		.ep = {
17093c09a283SLukasz Dalek 			.name		= "ep5in-int",
17103c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
17113c09a283SLukasz Dalek 			.maxpacket	= INT_FIFO_SIZE,
17123c09a283SLukasz Dalek 		},
17133c09a283SLukasz Dalek 		.dev		= &memory,
17143c09a283SLukasz Dalek 		.fifo_size	= INT_FIFO_SIZE,
17153c09a283SLukasz Dalek 		.bEndpointAddress = USB_DIR_IN | 5,
17163c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_INT,
17173c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[5],
17183c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr5,
17193c09a283SLukasz Dalek 	},
17203c09a283SLukasz Dalek 
17213c09a283SLukasz Dalek 	/* second group of endpoints */
17223c09a283SLukasz Dalek 	.ep[6] = {
17233c09a283SLukasz Dalek 		.ep = {
17243c09a283SLukasz Dalek 			.name		= "ep6in-bulk",
17253c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
17263c09a283SLukasz Dalek 			.maxpacket	= BULK_FIFO_SIZE,
17273c09a283SLukasz Dalek 		},
17283c09a283SLukasz Dalek 		.dev		= &memory,
17293c09a283SLukasz Dalek 		.fifo_size	= BULK_FIFO_SIZE,
17303c09a283SLukasz Dalek 		.bEndpointAddress = USB_DIR_IN | 6,
17313c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
17323c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[6],
17333c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr6,
17343c09a283SLukasz Dalek 	},
17353c09a283SLukasz Dalek 	.ep[7] = {
17363c09a283SLukasz Dalek 		.ep = {
17373c09a283SLukasz Dalek 			.name		= "ep7out-bulk",
17383c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
17393c09a283SLukasz Dalek 			.maxpacket	= BULK_FIFO_SIZE,
17403c09a283SLukasz Dalek 		},
17413c09a283SLukasz Dalek 		.dev		= &memory,
17423c09a283SLukasz Dalek 		.fifo_size	= BULK_FIFO_SIZE,
17433c09a283SLukasz Dalek 		.bEndpointAddress = 7,
17443c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
17453c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[7],
17463c09a283SLukasz Dalek 		.reg_ubcr	= &UDC_REGS->ubcr7,
17473c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr7,
17483c09a283SLukasz Dalek 	},
17493c09a283SLukasz Dalek 	.ep[8] = {
17503c09a283SLukasz Dalek 		.ep = {
17513c09a283SLukasz Dalek 			.name		= "ep8in-iso",
17523c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
17533c09a283SLukasz Dalek 			.maxpacket	= ISO_FIFO_SIZE,
17543c09a283SLukasz Dalek 		},
17553c09a283SLukasz Dalek 		.dev		= &memory,
17563c09a283SLukasz Dalek 		.fifo_size	= ISO_FIFO_SIZE,
17573c09a283SLukasz Dalek 		.bEndpointAddress = USB_DIR_IN | 8,
17583c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
17593c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[8],
17603c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr8,
17613c09a283SLukasz Dalek 	},
17623c09a283SLukasz Dalek 	.ep[9] = {
17633c09a283SLukasz Dalek 		.ep = {
17643c09a283SLukasz Dalek 			.name		= "ep9out-iso",
17653c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
17663c09a283SLukasz Dalek 			.maxpacket	= ISO_FIFO_SIZE,
17673c09a283SLukasz Dalek 		},
17683c09a283SLukasz Dalek 		.dev		= &memory,
17693c09a283SLukasz Dalek 		.fifo_size	= ISO_FIFO_SIZE,
17703c09a283SLukasz Dalek 		.bEndpointAddress = 9,
17713c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
17723c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[9],
17733c09a283SLukasz Dalek 		.reg_ubcr	= &UDC_REGS->ubcr9,
17743c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr9,
17753c09a283SLukasz Dalek 	},
17763c09a283SLukasz Dalek 	.ep[10] = {
17773c09a283SLukasz Dalek 		.ep = {
17783c09a283SLukasz Dalek 			.name		= "ep10in-int",
17793c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
17803c09a283SLukasz Dalek 			.maxpacket	= INT_FIFO_SIZE,
17813c09a283SLukasz Dalek 		},
17823c09a283SLukasz Dalek 		.dev		= &memory,
17833c09a283SLukasz Dalek 		.fifo_size	= INT_FIFO_SIZE,
17843c09a283SLukasz Dalek 		.bEndpointAddress = USB_DIR_IN | 10,
17853c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_INT,
17863c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[10],
17873c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr10,
17883c09a283SLukasz Dalek 	},
17893c09a283SLukasz Dalek 
17903c09a283SLukasz Dalek 	/* third group of endpoints */
17913c09a283SLukasz Dalek 	.ep[11] = {
17923c09a283SLukasz Dalek 		.ep = {
17933c09a283SLukasz Dalek 			.name		= "ep11in-bulk",
17943c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
17953c09a283SLukasz Dalek 			.maxpacket	= BULK_FIFO_SIZE,
17963c09a283SLukasz Dalek 		},
17973c09a283SLukasz Dalek 		.dev		= &memory,
17983c09a283SLukasz Dalek 		.fifo_size	= BULK_FIFO_SIZE,
17993c09a283SLukasz Dalek 		.bEndpointAddress = USB_DIR_IN | 11,
18003c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
18013c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[11],
18023c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr11,
18033c09a283SLukasz Dalek 	},
18043c09a283SLukasz Dalek 	.ep[12] = {
18053c09a283SLukasz Dalek 		.ep = {
18063c09a283SLukasz Dalek 			.name		= "ep12out-bulk",
18073c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
18083c09a283SLukasz Dalek 			.maxpacket	= BULK_FIFO_SIZE,
18093c09a283SLukasz Dalek 		},
18103c09a283SLukasz Dalek 		.dev		= &memory,
18113c09a283SLukasz Dalek 		.fifo_size	= BULK_FIFO_SIZE,
18123c09a283SLukasz Dalek 		.bEndpointAddress = 12,
18133c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_BULK,
18143c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[12],
18153c09a283SLukasz Dalek 		.reg_ubcr	= &UDC_REGS->ubcr12,
18163c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr12,
18173c09a283SLukasz Dalek 	},
18183c09a283SLukasz Dalek 	.ep[13] = {
18193c09a283SLukasz Dalek 		.ep = {
18203c09a283SLukasz Dalek 			.name		= "ep13in-iso",
18213c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
18223c09a283SLukasz Dalek 			.maxpacket	= ISO_FIFO_SIZE,
18233c09a283SLukasz Dalek 		},
18243c09a283SLukasz Dalek 		.dev		= &memory,
18253c09a283SLukasz Dalek 		.fifo_size	= ISO_FIFO_SIZE,
18263c09a283SLukasz Dalek 		.bEndpointAddress = USB_DIR_IN | 13,
18273c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
18283c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[13],
18293c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr13,
18303c09a283SLukasz Dalek 	},
18313c09a283SLukasz Dalek 	.ep[14] = {
18323c09a283SLukasz Dalek 		.ep = {
18333c09a283SLukasz Dalek 			.name		= "ep14out-iso",
18343c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
18353c09a283SLukasz Dalek 			.maxpacket	= ISO_FIFO_SIZE,
18363c09a283SLukasz Dalek 		},
18373c09a283SLukasz Dalek 		.dev		= &memory,
18383c09a283SLukasz Dalek 		.fifo_size	= ISO_FIFO_SIZE,
18393c09a283SLukasz Dalek 		.bEndpointAddress = 14,
18403c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_ISOC,
18413c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[14],
18423c09a283SLukasz Dalek 		.reg_ubcr	= &UDC_REGS->ubcr14,
18433c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr14,
18443c09a283SLukasz Dalek 	},
18453c09a283SLukasz Dalek 	.ep[15] = {
18463c09a283SLukasz Dalek 		.ep = {
18473c09a283SLukasz Dalek 			.name		= "ep15in-int",
18483c09a283SLukasz Dalek 			.ops		= &pxa25x_ep_ops,
18493c09a283SLukasz Dalek 			.maxpacket	= INT_FIFO_SIZE,
18503c09a283SLukasz Dalek 		},
18513c09a283SLukasz Dalek 		.dev		= &memory,
18523c09a283SLukasz Dalek 		.fifo_size	= INT_FIFO_SIZE,
18533c09a283SLukasz Dalek 		.bEndpointAddress = USB_DIR_IN | 15,
18543c09a283SLukasz Dalek 		.bmAttributes	= USB_ENDPOINT_XFER_INT,
18553c09a283SLukasz Dalek 		.reg_udccs	= &UDC_REGS->udccs[15],
18563c09a283SLukasz Dalek 		.reg_uddr	= &UDC_REGS->uddr15,
18573c09a283SLukasz Dalek 	},
18583c09a283SLukasz Dalek #endif /* !CONFIG_USB_PXA25X_SMALL */
18593c09a283SLukasz Dalek };
18603c09a283SLukasz Dalek 
udc_command(int cmd)18613c09a283SLukasz Dalek static void udc_command(int cmd)
18623c09a283SLukasz Dalek {
18633c09a283SLukasz Dalek 	switch (cmd) {
18643c09a283SLukasz Dalek 	case PXA2XX_UDC_CMD_CONNECT:
18653c09a283SLukasz Dalek 		setbits_le32(GPDR(CONFIG_USB_DEV_PULLUP_GPIO),
18663c09a283SLukasz Dalek 			GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO));
18673c09a283SLukasz Dalek 
18683c09a283SLukasz Dalek 		/* enable pullup */
18693c09a283SLukasz Dalek 		writel(GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO),
18703c09a283SLukasz Dalek 			GPCR(CONFIG_USB_DEV_PULLUP_GPIO));
18713c09a283SLukasz Dalek 
18723c09a283SLukasz Dalek 		debug("Connected to USB\n");
18733c09a283SLukasz Dalek 		break;
18743c09a283SLukasz Dalek 
18753c09a283SLukasz Dalek 	case PXA2XX_UDC_CMD_DISCONNECT:
18763c09a283SLukasz Dalek 		/* disable pullup resistor */
18773c09a283SLukasz Dalek 		writel(GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO),
18783c09a283SLukasz Dalek 			GPSR(CONFIG_USB_DEV_PULLUP_GPIO));
18793c09a283SLukasz Dalek 
18803c09a283SLukasz Dalek 		/* setup pin as input, line will float */
18813c09a283SLukasz Dalek 		clrbits_le32(GPDR(CONFIG_USB_DEV_PULLUP_GPIO),
18823c09a283SLukasz Dalek 			GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO));
18833c09a283SLukasz Dalek 
18843c09a283SLukasz Dalek 		debug("Disconnected from USB\n");
18853c09a283SLukasz Dalek 		break;
18863c09a283SLukasz Dalek 	}
18873c09a283SLukasz Dalek }
18883c09a283SLukasz Dalek 
18893c09a283SLukasz Dalek static struct pxa2xx_udc_mach_info mach_info = {
18903c09a283SLukasz Dalek 	.udc_command = udc_command,
18913c09a283SLukasz Dalek };
18923c09a283SLukasz Dalek 
18933c09a283SLukasz Dalek /*
18943c09a283SLukasz Dalek  * when a driver is successfully registered, it will receive
18953c09a283SLukasz Dalek  * control requests including set_configuration(), which enables
18963c09a283SLukasz Dalek  * non-control requests.  then usb traffic follows until a
18973c09a283SLukasz Dalek  * disconnect is reported.  then a host may connect again, or
18983c09a283SLukasz Dalek  * the driver might get unbound.
18993c09a283SLukasz Dalek  */
usb_gadget_register_driver(struct usb_gadget_driver * driver)19003c09a283SLukasz Dalek int usb_gadget_register_driver(struct usb_gadget_driver *driver)
19013c09a283SLukasz Dalek {
19023c09a283SLukasz Dalek 	struct pxa25x_udc *dev = &memory;
19033c09a283SLukasz Dalek 	int retval;
19043c09a283SLukasz Dalek 	uint32_t chiprev;
19053c09a283SLukasz Dalek 
19063c09a283SLukasz Dalek 	if (!driver
19073c09a283SLukasz Dalek 			|| driver->speed < USB_SPEED_FULL
19083c09a283SLukasz Dalek 			|| !driver->disconnect
19093c09a283SLukasz Dalek 			|| !driver->setup)
19103c09a283SLukasz Dalek 		return -EINVAL;
19113c09a283SLukasz Dalek 	if (!dev)
19123c09a283SLukasz Dalek 		return -ENODEV;
19133c09a283SLukasz Dalek 	if (dev->driver)
19143c09a283SLukasz Dalek 		return -EBUSY;
19153c09a283SLukasz Dalek 
19163c09a283SLukasz Dalek 	/* Enable clock for usb controller */
19173c09a283SLukasz Dalek 	setbits_le32(CKEN, CKEN11_USB);
19183c09a283SLukasz Dalek 
19193c09a283SLukasz Dalek 	/* first hook up the driver ... */
19203c09a283SLukasz Dalek 	dev->driver = driver;
19213c09a283SLukasz Dalek 	dev->pullup = 1;
19223c09a283SLukasz Dalek 
19233c09a283SLukasz Dalek 	/* trigger chiprev-specific logic */
19243c09a283SLukasz Dalek 	switch ((chiprev = pxa_get_cpu_revision())) {
19253c09a283SLukasz Dalek 	case PXA255_A0:
19263c09a283SLukasz Dalek 		dev->has_cfr = 1;
19273c09a283SLukasz Dalek 		break;
19283c09a283SLukasz Dalek 	case PXA250_A0:
19293c09a283SLukasz Dalek 	case PXA250_A1:
19303c09a283SLukasz Dalek 		/* A0/A1 "not released"; ep 13, 15 unusable */
19313c09a283SLukasz Dalek 		/* fall through */
19323c09a283SLukasz Dalek 	case PXA250_B2: case PXA210_B2:
19333c09a283SLukasz Dalek 	case PXA250_B1: case PXA210_B1:
19343c09a283SLukasz Dalek 	case PXA250_B0: case PXA210_B0:
19353c09a283SLukasz Dalek 		/* OUT-DMA is broken ... */
19363c09a283SLukasz Dalek 		/* fall through */
19373c09a283SLukasz Dalek 	case PXA250_C0: case PXA210_C0:
19383c09a283SLukasz Dalek 		break;
19393c09a283SLukasz Dalek 	default:
19403c09a283SLukasz Dalek 		printf("%s: unrecognized processor: %08x\n",
19413c09a283SLukasz Dalek 			DRIVER_NAME, chiprev);
19423c09a283SLukasz Dalek 		return -ENODEV;
19433c09a283SLukasz Dalek 	}
19443c09a283SLukasz Dalek 
19453c09a283SLukasz Dalek 	the_controller = dev;
19463c09a283SLukasz Dalek 
19473c09a283SLukasz Dalek 	/* prepare watchdog timer */
19483c09a283SLukasz Dalek 	dev->watchdog.running = 0;
19493c09a283SLukasz Dalek 	dev->watchdog.period = 5000 * CONFIG_SYS_HZ / 1000000; /* 5 ms */
19503c09a283SLukasz Dalek 	dev->watchdog.function = udc_watchdog;
19513c09a283SLukasz Dalek 
1952c0978a94SAlex Sadovsky 	dev->mach = &mach_info;
1953c0978a94SAlex Sadovsky 
19543c09a283SLukasz Dalek 	udc_disable(dev);
19553c09a283SLukasz Dalek 	udc_reinit(dev);
19563c09a283SLukasz Dalek 
19573c09a283SLukasz Dalek 	dev->gadget.name = "pxa2xx_udc";
19583c09a283SLukasz Dalek 	retval = driver->bind(&dev->gadget);
19593c09a283SLukasz Dalek 	if (retval) {
19603c09a283SLukasz Dalek 		printf("bind to driver %s --> error %d\n",
19613c09a283SLukasz Dalek 				DRIVER_NAME, retval);
19623c09a283SLukasz Dalek 		dev->driver = NULL;
19633c09a283SLukasz Dalek 		return retval;
19643c09a283SLukasz Dalek 	}
19653c09a283SLukasz Dalek 
19663c09a283SLukasz Dalek 	/*
19673c09a283SLukasz Dalek 	 * ... then enable host detection and ep0; and we're ready
19683c09a283SLukasz Dalek 	 * for set_configuration as well as eventual disconnect.
19693c09a283SLukasz Dalek 	 */
19703c09a283SLukasz Dalek 	printf("registered gadget driver '%s'\n", DRIVER_NAME);
19713c09a283SLukasz Dalek 
19723c09a283SLukasz Dalek 	pullup(dev);
19733c09a283SLukasz Dalek 	dump_state(dev);
19743c09a283SLukasz Dalek 	return 0;
19753c09a283SLukasz Dalek }
19763c09a283SLukasz Dalek 
19773c09a283SLukasz Dalek static void
stop_activity(struct pxa25x_udc * dev,struct usb_gadget_driver * driver)19783c09a283SLukasz Dalek stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
19793c09a283SLukasz Dalek {
19803c09a283SLukasz Dalek 	int i;
19813c09a283SLukasz Dalek 
19823c09a283SLukasz Dalek 	/* don't disconnect drivers more than once */
19833c09a283SLukasz Dalek 	if (dev->gadget.speed == USB_SPEED_UNKNOWN)
19843c09a283SLukasz Dalek 		driver = NULL;
19853c09a283SLukasz Dalek 	dev->gadget.speed = USB_SPEED_UNKNOWN;
19863c09a283SLukasz Dalek 
19873c09a283SLukasz Dalek 	/* prevent new request submissions, kill any outstanding requests  */
19883c09a283SLukasz Dalek 	for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) {
19893c09a283SLukasz Dalek 		struct pxa25x_ep *ep = &dev->ep[i];
19903c09a283SLukasz Dalek 
19913c09a283SLukasz Dalek 		ep->stopped = 1;
19923c09a283SLukasz Dalek 		nuke(ep, -ESHUTDOWN);
19933c09a283SLukasz Dalek 	}
19943c09a283SLukasz Dalek 	stop_watchdog(dev);
19953c09a283SLukasz Dalek 
19963c09a283SLukasz Dalek 	/* report disconnect; the driver is already quiesced */
19973c09a283SLukasz Dalek 	if (driver)
19983c09a283SLukasz Dalek 		driver->disconnect(&dev->gadget);
19993c09a283SLukasz Dalek 
20003c09a283SLukasz Dalek 	/* re-init driver-visible data structures */
20013c09a283SLukasz Dalek 	udc_reinit(dev);
20023c09a283SLukasz Dalek }
20033c09a283SLukasz Dalek 
usb_gadget_unregister_driver(struct usb_gadget_driver * driver)20043c09a283SLukasz Dalek int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
20053c09a283SLukasz Dalek {
20063c09a283SLukasz Dalek 	struct pxa25x_udc	*dev = the_controller;
20073c09a283SLukasz Dalek 
20083c09a283SLukasz Dalek 	if (!dev)
20093c09a283SLukasz Dalek 		return -ENODEV;
20103c09a283SLukasz Dalek 	if (!driver || driver != dev->driver || !driver->unbind)
20113c09a283SLukasz Dalek 		return -EINVAL;
20123c09a283SLukasz Dalek 
20133c09a283SLukasz Dalek 	local_irq_disable();
20143c09a283SLukasz Dalek 	dev->pullup = 0;
20153c09a283SLukasz Dalek 	pullup(dev);
20163c09a283SLukasz Dalek 	stop_activity(dev, driver);
20173c09a283SLukasz Dalek 	local_irq_enable();
20183c09a283SLukasz Dalek 
20193c09a283SLukasz Dalek 	driver->unbind(&dev->gadget);
20203c09a283SLukasz Dalek 	dev->driver = NULL;
20213c09a283SLukasz Dalek 
20223c09a283SLukasz Dalek 	printf("unregistered gadget driver '%s'\n", DRIVER_NAME);
20233c09a283SLukasz Dalek 	dump_state(dev);
20243c09a283SLukasz Dalek 
20253c09a283SLukasz Dalek 	the_controller = NULL;
20263c09a283SLukasz Dalek 
20273c09a283SLukasz Dalek 	clrbits_le32(CKEN, CKEN11_USB);
20283c09a283SLukasz Dalek 
20293c09a283SLukasz Dalek 	return 0;
20303c09a283SLukasz Dalek }
20313c09a283SLukasz Dalek 
udc_disconnect(void)20323c09a283SLukasz Dalek extern void udc_disconnect(void)
20333c09a283SLukasz Dalek {
20343c09a283SLukasz Dalek 	setbits_le32(CKEN, CKEN11_USB);
20353c09a283SLukasz Dalek 	udc_clear_mask_UDCCR(UDCCR_UDE);
20363c09a283SLukasz Dalek 	udc_command(PXA2XX_UDC_CMD_DISCONNECT);
20373c09a283SLukasz Dalek 	clrbits_le32(CKEN, CKEN11_USB);
20383c09a283SLukasz Dalek }
20393c09a283SLukasz Dalek 
20403c09a283SLukasz Dalek /*-------------------------------------------------------------------------*/
20413c09a283SLukasz Dalek 
20423c09a283SLukasz Dalek extern int
usb_gadget_handle_interrupts(int index)2043*2d48aa69SKishon Vijay Abraham I usb_gadget_handle_interrupts(int index)
20443c09a283SLukasz Dalek {
20453c09a283SLukasz Dalek 	return pxa25x_udc_irq();
20463c09a283SLukasz Dalek }
2047