summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/linux/linux-2.6.21/.mtn2git_empty0
-rw-r--r--packages/linux/linux-2.6.21/270-usb-gadget-udc.patch2739
-rw-r--r--packages/linux/linux-2.6.21/arch-config.patch62
-rw-r--r--packages/linux/linux-2.6.21/bkpxa-pxa-cpu.patch117
-rw-r--r--packages/linux/linux-2.6.21/bkpxa-pxa-cpufreq.patch403
-rw-r--r--packages/linux/linux-2.6.21/board-init.patch81
-rw-r--r--packages/linux/linux-2.6.21/bugfix-i2c-include.patch12
-rw-r--r--packages/linux/linux-2.6.21/bugfix-mmc-clock.patch14
-rw-r--r--packages/linux/linux-2.6.21/bugfix-pxa-cpufreq.patch64
-rw-r--r--packages/linux/linux-2.6.21/bugfix-serial-interrupt.patch25
-rw-r--r--packages/linux/linux-2.6.21/bugfix-serial-register-status.patch69
-rw-r--r--packages/linux/linux-2.6.21/compact-flash.patch249
-rw-r--r--packages/linux/linux-2.6.21/compile-fix-pxa_cpufreq.patch13
-rw-r--r--packages/linux/linux-2.6.21/cpufreq-better-freqs.patch53
-rw-r--r--packages/linux/linux-2.6.21/cpufreq-fixup.patch26
-rw-r--r--packages/linux/linux-2.6.21/cpufreq-ondemand-by-default.patch42
-rw-r--r--packages/linux/linux-2.6.21/defconfig.patch766
-rw-r--r--packages/linux/linux-2.6.21/disable-uncompress-message.patch32
-rw-r--r--packages/linux/linux-2.6.21/ethernet-config.patch26
-rw-r--r--packages/linux/linux-2.6.21/flash.patch171
-rw-r--r--packages/linux/linux-2.6.21/gumstix-asoc.patch224
-rw-r--r--packages/linux/linux-2.6.21/gumstix-fb-logo.patch10455
-rw-r--r--packages/linux/linux-2.6.21/gumstix-pxa270-usb-host.patch366
-rw-r--r--packages/linux/linux-2.6.21/gumstix/.mtn2git_empty0
-rw-r--r--packages/linux/linux-2.6.21/gumstix/defconfig1558
-rw-r--r--packages/linux/linux-2.6.21/header.patch163
-rw-r--r--packages/linux/linux-2.6.21/mach-types-fix.patch13
-rw-r--r--packages/linux/linux-2.6.21/misalignment-handling.patch38
-rw-r--r--packages/linux/linux-2.6.21/mmc-card-detect.patch76
-rw-r--r--packages/linux/linux-2.6.21/modular-init-bluetooth.patch108
-rw-r--r--packages/linux/linux-2.6.21/modular-init-smc91x.patch203
-rw-r--r--packages/linux/linux-2.6.21/modular-init-usb-gadget.patch106
-rw-r--r--packages/linux/linux-2.6.21/pcm-gcc-411-bugfix.patch60
-rw-r--r--packages/linux/linux-2.6.21/proc-gpio.patch328
-rw-r--r--packages/linux/linux-2.6.21/pxa-regs-additions.patch28
-rw-r--r--packages/linux/linux-2.6.21/pxa-regs-fixup.patch12
-rw-r--r--packages/linux/linux-2.6.21/pxa2xx_udc.patch65
-rw-r--r--packages/linux/linux-2.6.21/pxafb-18bpp-mode.patch383
-rw-r--r--packages/linux/linux-2.6.21/pxafb-definition.patch183
-rw-r--r--packages/linux/linux-2.6.21/ramfs-mode-support.patch88
-rw-r--r--packages/linux/linux-2.6.21/serial-divisor.patch31
-rw-r--r--packages/linux/linux-2.6.21/serial-ether-addr.patch62
-rw-r--r--packages/linux/linux-2.6.21/smc-ether-addr.patch62
-rw-r--r--packages/linux/linux-2.6.21/uImage-in-own-partition.patch56
-rw-r--r--packages/linux/linux-2.6.21/ucb1400-ac97-audio.patch298
-rw-r--r--packages/linux/linux_2.6.21.bb45
46 files changed, 19975 insertions, 0 deletions
diff --git a/packages/linux/linux-2.6.21/.mtn2git_empty b/packages/linux/linux-2.6.21/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-2.6.21/.mtn2git_empty
diff --git a/packages/linux/linux-2.6.21/270-usb-gadget-udc.patch b/packages/linux/linux-2.6.21/270-usb-gadget-udc.patch
new file mode 100644
index 0000000000..630d188ea0
--- /dev/null
+++ b/packages/linux/linux-2.6.21/270-usb-gadget-udc.patch
@@ -0,0 +1,2739 @@
+Index: linux-2.6.21gum/drivers/usb/gadget/Kconfig
+===================================================================
+--- linux-2.6.21gum.orig/drivers/usb/gadget/Kconfig
++++ linux-2.6.21gum/drivers/usb/gadget/Kconfig
+@@ -129,6 +129,28 @@ config USB_PXA2XX_SMALL
+ default y if USB_ETH
+ default y if USB_G_SERIAL
+
++config USB_GADGET_PXA27X
++ boolean "PXA 27x"
++ depends on ARCH_PXA && PXA27x
++ help
++ Intel's PXA 27x series XScale ARM-5TE processors include
++ an integrated full speed USB 1.1 device controller.
++
++ Say "y" to link the driver statically, or "m" to build a
++ dynamically linked module called "pxa27x_udc" and force all
++ gadget drivers to also be dynamically linked.
++
++config USB_PXA27X
++ tristate
++ depends on USB_GADGET_PXA27X
++ default USB_GADGET
++ select USB_GADGET_SELECTED
++
++config USB_PXA27X_DMA
++ bool # "Use DMA support"
++ depends on USB_GADGET_PXA27X
++ default n
++
+ config USB_GADGET_GOKU
+ boolean "Toshiba TC86C001 'Goku-S'"
+ depends on PCI
+Index: linux-2.6.21gum/drivers/usb/gadget/Makefile
+===================================================================
+--- linux-2.6.21gum.orig/drivers/usb/gadget/Makefile
++++ linux-2.6.21gum/drivers/usb/gadget/Makefile
+@@ -7,6 +7,7 @@ obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o
+ obj-$(CONFIG_USB_GOKU) += goku_udc.o
+ obj-$(CONFIG_USB_OMAP) += omap_udc.o
+ obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o
++obj-$(CONFIG_USB_PXA27X) += pxa27x_udc.o
+ obj-$(CONFIG_USB_AT91) += at91_udc.o
+ obj-$(CONFIG_USB_GADGET_GUMSTIX) += gumstix_gadget.o
+
+Index: linux-2.6.21gum/drivers/usb/gadget/pxa27x_udc.c
+===================================================================
+--- /dev/null
++++ linux-2.6.21gum/drivers/usb/gadget/pxa27x_udc.c
+@@ -0,0 +1,2352 @@
++/*
++ * linux/drivers/usb/gadget/pxa27x_udc.c
++ * Intel PXA2xx and IXP4xx on-chip full speed USB device controllers
++ *
++ * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker)
++ * Copyright (C) 2003 Robert Schwebel, Pengutronix
++ * Copyright (C) 2003 Benedikt Spranger, Pengutronix
++ * Copyright (C) 2003 David Brownell
++ * Copyright (C) 2003 Joshua Wise
++ * Copyright (C) 2004 Intel Corporation
++ * Copyright (C) 2005 SDG Systems, LLC (Aric Blumer)
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#undef DEBUG
++ // #define DEBUG 1
++ //#define VERBOSE DBG_VERBOSE
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/ioport.h>
++#include <linux/types.h>
++#include <linux/version.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/timer.h>
++#include <linux/list.h>
++#include <linux/interrupt.h>
++#include <linux/proc_fs.h>
++#include <linux/mm.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++#include <linux/irq.h>
++
++#include <asm/byteorder.h>
++#include <asm/dma.h>
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/mach-types.h>
++#include <asm/unaligned.h>
++#include <asm/hardware.h>
++#include <asm/mach/irq.h>
++#include <asm/arch/pxa-regs.h>
++
++#include <linux/usb/ch9.h>
++#include <linux/usb_gadget.h>
++
++#include <asm/arch/udc.h>
++
++
++/*
++ * This driver handles the USB Device Controller (UDC) in Intel's PXA 27777777x
++ * series processors.
++ * Such controller drivers work with a gadget driver. The gadget driver
++ * returns descriptors, implements configuration and data protocols used
++ * by the host to interact with this device, and allocates endpoints to
++ * the different protocol interfaces. The controller driver virtualizes
++ * usb hardware so that the gadget drivers will be more portable.
++ *
++ * This UDC hardware wants to implement a bit too much USB protocol, so
++ * it constrains the sorts of USB configuration change events that work.
++ * The errata for these chips are misleading; some "fixed" bugs from
++ * pxa250 a0/a1 b0/b1/b2 sure act like they're still there.
++ */
++
++#define DRIVER_VERSION "21-Jul-2005"
++#define DRIVER_DESC "PXA 27x USB Device Controller driver"
++
++
++static const char driver_name [] = "pxa27x_udc";
++
++static const char ep0name [] = "ep0";
++
++
++#define USE_DMA
++//#define DISABLE_TEST_MODE
++
++#ifdef CONFIG_PROC_FS
++#define UDC_PROC_FILE
++#endif
++
++#include "pxa27x_udc.h"
++
++#if 0
++#ifdef CONFIG_EMBEDDED
++/* few strings, and little code to use them */
++#undef DEBUG
++#undef UDC_PROC_FILE
++#endif
++#endif
++
++#ifdef USE_DMA
++static int use_dma = 1;
++module_param(use_dma, bool, 0);
++MODULE_PARM_DESC (use_dma, "true to use dma");
++
++static void dma_nodesc_handler (int dmach, void *_ep);
++static void kick_dma(struct pxa27x_ep *ep, struct pxa27x_request *req);
++
++#define DMASTR " (dma support)"
++
++#else /* !USE_DMA */
++#define DMASTR " (pio only)"
++#endif
++
++#ifdef CONFIG_USB_PXA27X_SMALL
++#define SIZE_STR " (small)"
++#else
++#define SIZE_STR ""
++#endif
++
++#ifdef DISABLE_TEST_MODE
++/* (mode == 0) == no undocumented chip tweaks
++ * (mode & 1) == double buffer bulk IN
++ * (mode & 2) == double buffer bulk OUT
++ * ... so mode = 3 (or 7, 15, etc) does it for both
++ */
++static ushort fifo_mode = 0;
++module_param(fifo_mode, ushort, 0);
++MODULE_PARM_DESC (fifo_mode, "pxa27x udc fifo mode");
++#endif
++
++#define UDCISR0_IR0 0x3
++#define UDCISR_INT_MASK (UDC_INT_FIFOERROR | UDC_INT_PACKETCMP)
++#define UDCICR_INT_MASK UDCISR_INT_MASK
++
++#define UDCCSR_MASK (UDCCSR_FST | UDCCSR_DME)
++/* ---------------------------------------------------------------------------
++ * endpoint related parts of the api to the usb controller hardware,
++ * used by gadget driver; and the inner talker-to-hardware core.
++ * ---------------------------------------------------------------------------
++ */
++
++static void pxa27x_ep_fifo_flush (struct usb_ep *ep);
++static void nuke (struct pxa27x_ep *, int status);
++
++static void pio_irq_enable(int ep_num)
++{
++ if (ep_num < 16)
++ UDCICR0 |= 3 << (ep_num * 2);
++ else {
++ ep_num -= 16;
++ UDCICR1 |= 3 << (ep_num * 2);
++ }
++}
++
++static void pio_irq_disable(int ep_num)
++{
++ ep_num &= 0xf;
++ if (ep_num < 16)
++ UDCICR0 &= ~(3 << (ep_num * 2));
++ else {
++ ep_num -= 16;
++ UDCICR1 &= ~(3 << (ep_num * 2));
++ }
++}
++
++/* The UDCCR reg contains mask and interrupt status bits,
++ * so using '|=' isn't safe as it may ack an interrupt.
++ */
++#define UDCCR_MASK_BITS (UDCCR_OEN | UDCCR_UDE)
++
++static inline void udc_set_mask_UDCCR(int mask)
++{
++ UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS);
++}
++
++static inline void udc_clear_mask_UDCCR(int mask)
++{
++ UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS);
++}
++
++static inline void udc_ack_int_UDCCR(int mask)
++{
++ /* udccr contains the bits we dont want to change */
++ __u32 udccr = UDCCR & UDCCR_MASK_BITS;
++
++ UDCCR = udccr | (mask & ~UDCCR_MASK_BITS);
++}
++
++/*
++ * endpoint enable/disable
++ *
++ * we need to verify the descriptors used to enable endpoints. since pxa27x
++ * endpoint configurations are fixed, and are pretty much always enabled,
++ * there's not a lot to manage here.
++ *
++ * because pxa27x can't selectively initialize bulk (or interrupt) endpoints,
++ * (resetting endpoint halt and toggle), SET_INTERFACE is unusable except
++ * for a single interface (with only the default altsetting) and for gadget
++ * drivers that don't halt endpoints (not reset by set_interface). that also
++ * means that if you use ISO, you must violate the USB spec rule that all
++ * iso endpoints must be in non-default altsettings.
++ */
++static int pxa27x_ep_enable (struct usb_ep *_ep,
++ const struct usb_endpoint_descriptor *desc)
++{
++ struct pxa27x_ep *ep;
++ struct pxa27x_udc *dev;
++
++ ep = container_of (_ep, struct pxa27x_ep, ep);
++ if (!_ep || !desc || _ep->name == ep0name
++ || desc->bDescriptorType != USB_DT_ENDPOINT
++ || ep->fifo_size < le16_to_cpu(desc->wMaxPacketSize)) {
++ DMSG("%s, bad ep or descriptor\n", __FUNCTION__);
++ return -EINVAL;
++ }
++
++ /* xfer types must match, except that interrupt ~= bulk */
++ if( ep->ep_type != USB_ENDPOINT_XFER_BULK
++ && desc->bmAttributes != USB_ENDPOINT_XFER_INT) {
++ DMSG("%s, %s type mismatch\n", __FUNCTION__, _ep->name);
++ return -EINVAL;
++ }
++
++ /* hardware _could_ do smaller, but driver doesn't */
++ if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
++ && le16_to_cpu (desc->wMaxPacketSize)
++ != BULK_FIFO_SIZE)
++ || !desc->wMaxPacketSize) {
++ DMSG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name);
++ return -ERANGE;
++ }
++
++ dev = ep->dev;
++ if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
++ DMSG("%s, bogus device state\n", __FUNCTION__);
++ return -ESHUTDOWN;
++ }
++
++ ep->desc = desc;
++ ep->dma = -1;
++ ep->stopped = 0;
++ ep->pio_irqs = ep->dma_irqs = 0;
++ ep->ep.maxpacket = le16_to_cpu (desc->wMaxPacketSize);
++
++ /* flush fifo (mostly for OUT buffers) */
++ pxa27x_ep_fifo_flush (_ep);
++
++ /* ... reset halt state too, if we could ... */
++
++#ifdef USE_DMA
++ /* for (some) bulk and ISO endpoints, try to get a DMA channel and
++ * bind it to the endpoint. otherwise use PIO.
++ */
++ DMSG("%s: called attributes=%d\n", __FUNCTION__, ep->ep_type);
++ switch (ep->ep_type) {
++ case USB_ENDPOINT_XFER_ISOC:
++ if (le16_to_cpu(desc->wMaxPacketSize) % 32)
++ break;
++ // fall through
++ case USB_ENDPOINT_XFER_BULK:
++ if (!use_dma || !ep->reg_drcmr)
++ break;
++ ep->dma = pxa_request_dma ((char *)_ep->name,
++ (le16_to_cpu (desc->wMaxPacketSize) > 64)
++ ? DMA_PRIO_MEDIUM /* some iso */
++ : DMA_PRIO_LOW,
++ dma_nodesc_handler, ep);
++ if (ep->dma >= 0) {
++ *ep->reg_drcmr = DRCMR_MAPVLD | ep->dma;
++ DMSG("%s using dma%d\n", _ep->name, ep->dma);
++ }
++ default:
++ break;
++ }
++#endif
++ DBG(DBG_VERBOSE, "enabled %s\n", _ep->name);
++ return 0;
++}
++
++static int pxa27x_ep_disable (struct usb_ep *_ep)
++{
++ struct pxa27x_ep *ep;
++
++ ep = container_of (_ep, struct pxa27x_ep, ep);
++ if (!_ep || !ep->desc) {
++ DMSG("%s, %s not enabled\n", __FUNCTION__,
++ _ep ? ep->ep.name : NULL);
++ return -EINVAL;
++ }
++ nuke (ep, -ESHUTDOWN);
++
++#ifdef USE_DMA
++ if (ep->dma >= 0) {
++ *ep->reg_drcmr = 0;
++ pxa_free_dma (ep->dma);
++ ep->dma = -1;
++ }
++#endif
++
++ /* flush fifo (mostly for IN buffers) */
++ pxa27x_ep_fifo_flush (_ep);
++
++ ep->desc = 0;
++ ep->stopped = 1;
++
++ DBG(DBG_VERBOSE, "%s disabled\n", _ep->name);
++ return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++
++/* for the pxa27x, these can just wrap kmalloc/kfree. gadget drivers
++ * must still pass correctly initialized endpoints, since other controller
++ * drivers may care about how it's currently set up (dma issues etc).
++ */
++
++/*
++ * pxa27x_ep_alloc_request - allocate a request data structure
++ */
++static struct usb_request *
++pxa27x_ep_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
++{
++ struct pxa27x_request *req;
++
++ req = kmalloc (sizeof *req, gfp_flags);
++ if (!req)
++ return 0;
++
++ memset (req, 0, sizeof *req);
++ INIT_LIST_HEAD (&req->queue);
++ return &req->req;
++}
++
++
++/*
++ * pxa27x_ep_free_request - deallocate a request data structure
++ */
++static void
++pxa27x_ep_free_request (struct usb_ep *_ep, struct usb_request *_req)
++{
++ struct pxa27x_request *req;
++
++ req = container_of(_req, struct pxa27x_request, req);
++ WARN_ON (!list_empty (&req->queue));
++ kfree(req);
++}
++
++
++/* PXA cache needs flushing with DMA I/O (it's dma-incoherent), but there's
++ * no device-affinity and the heap works perfectly well for i/o buffers.
++ * It wastes much less memory than dma_alloc_coherent() would, and even
++ * prevents cacheline (32 bytes wide) sharing problems.
++ */
++static void *
++pxa27x_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
++ dma_addr_t *dma, unsigned gfp_flags)
++{
++ char *retval;
++
++ retval = kmalloc (bytes, gfp_flags & ~(__GFP_DMA|__GFP_HIGHMEM));
++ if (retval)
++ *dma = virt_to_bus (retval);
++ return retval;
++}
++
++static void
++pxa27x_ep_free_buffer(struct usb_ep *_ep, void *buf, dma_addr_t dma,
++ unsigned bytes)
++{
++ kfree (buf);
++}
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * done - retire a request; caller blocked irqs
++ */
++static void done(struct pxa27x_ep *ep, struct pxa27x_request *req, int status)
++{
++ list_del_init(&req->queue);
++ if (likely (req->req.status == -EINPROGRESS))
++ req->req.status = status;
++ else
++ status = req->req.status;
++
++ if (status && status != -ESHUTDOWN)
++ DBG(DBG_VERBOSE, "complete %s req %p stat %d len %u/%u\n",
++ ep->ep.name, &req->req, status,
++ req->req.actual, req->req.length);
++
++ /* don't modify queue heads during completion callback */
++ req->req.complete(&ep->ep, &req->req);
++}
++
++
++static inline void ep0_idle (struct pxa27x_udc *dev)
++{
++ dev->ep0state = EP0_IDLE;
++ LED_EP0_OFF;
++}
++
++static int
++write_packet(volatile u32 *uddr, struct pxa27x_request *req, unsigned max)
++{
++ u32 *buf;
++ int length, count, remain;
++
++ buf = (u32*)(req->req.buf + req->req.actual);
++ prefetch(buf);
++
++ /* how big will this packet be? */
++ length = min(req->req.length - req->req.actual, max);
++ req->req.actual += length;
++
++ remain = length & 0x3;
++ count = length & ~(0x3);
++
++ while (likely(count)) {
++ *uddr = *buf++;
++ count -= 4;
++ }
++
++ if (remain) {
++ volatile u8* reg=(u8*)uddr;
++ char *rd =(u8*)buf;
++
++ while (remain--) {
++ *reg=*rd++;
++ }
++ }
++
++ return length;
++}
++
++/*
++ * write to an IN endpoint fifo, as many packets as possible.
++ * irqs will use this to write the rest later.
++ * caller guarantees at least one packet buffer is ready (or a zlp).
++ */
++static int
++write_fifo (struct pxa27x_ep *ep, struct pxa27x_request *req)
++{
++ unsigned max;
++
++ max = le16_to_cpu(ep->desc->wMaxPacketSize);
++ do {
++ int count;
++ int is_last, is_short;
++
++ count = write_packet(ep->reg_udcdr, req, max);
++
++ /* last packet is usually short (or a zlp) */
++ if (unlikely (count != max))
++ is_last = is_short = 1;
++ else {
++ if (likely(req->req.length != req->req.actual)
++ || req->req.zero)
++ is_last = 0;
++ else
++ is_last = 1;
++ /* interrupt/iso maxpacket may not fill the fifo */
++ is_short = unlikely (max < ep->fifo_size);
++ }
++
++ DMSG("wrote %s count:%d bytes%s%s %d left %p\n",
++ ep->ep.name, count,
++ is_last ? "/L" : "", is_short ? "/S" : "",
++ req->req.length - req->req.actual, &req->req);
++
++ /* let loose that packet. maybe try writing another one,
++ * double buffering might work. TSP, TPC, and TFS
++ * bit values are the same for all normal IN endpoints.
++ */
++ *ep->reg_udccsr = UDCCSR_PC;
++ if (is_short)
++ *ep->reg_udccsr = UDCCSR_SP;
++
++ /* requests complete when all IN data is in the FIFO */
++ if (is_last) {
++ done (ep, req, 0);
++ if (list_empty(&ep->queue) || unlikely(ep->dma >= 0)) {
++ pio_irq_disable (ep->ep_num);
++#ifdef USE_DMA
++ /* unaligned data and zlps couldn't use dma */
++ if (unlikely(!list_empty(&ep->queue))) {
++ req = list_entry(ep->queue.next,
++ struct pxa27x_request, queue);
++ kick_dma(ep,req);
++ return 0;
++ }
++#endif
++ }
++ return 1;
++ }
++
++ // TODO experiment: how robust can fifo mode tweaking be?
++ // double buffering is off in the default fifo mode, which
++ // prevents TFS from being set here.
++
++ } while (*ep->reg_udccsr & UDCCSR_FS);
++ return 0;
++}
++
++/* caller asserts req->pending (ep0 irq status nyet cleared); starts
++ * ep0 data stage. these chips want very simple state transitions.
++ */
++static inline
++void ep0start(struct pxa27x_udc *dev, u32 flags, const char *tag)
++{
++ UDCCSR0 = flags|UDCCSR0_SA|UDCCSR0_OPC;
++ UDCISR0 = UDCICR_INT(0, UDC_INT_FIFOERROR | UDC_INT_PACKETCMP);
++ dev->req_pending = 0;
++ DBG(DBG_VERY_NOISY, "%s %s, %02x/%02x\n",
++ __FUNCTION__, tag, UDCCSR0, flags);
++}
++
++static int
++write_ep0_fifo (struct pxa27x_ep *ep, struct pxa27x_request *req)
++{
++ unsigned count;
++ int is_short;
++
++ count = write_packet(&UDCDR0, req, EP0_FIFO_SIZE);
++ ep->dev->stats.write.bytes += count;
++
++ /* last packet "must be" short (or a zlp) */
++ is_short = (count != EP0_FIFO_SIZE);
++
++ DBG(DBG_VERY_NOISY, "ep0in %d bytes %d left %p\n", count,
++ req->req.length - req->req.actual, &req->req);
++
++ if (unlikely (is_short)) {
++ if (ep->dev->req_pending)
++ ep0start(ep->dev, UDCCSR0_IPR, "short IN");
++ else
++ UDCCSR0 = UDCCSR0_IPR;
++
++ count = req->req.length;
++ done (ep, req, 0);
++ ep0_idle(ep->dev);
++#if 0
++ /* This seems to get rid of lost status irqs in some cases:
++ * host responds quickly, or next request involves config
++ * change automagic, or should have been hidden, or ...
++ *
++ * FIXME get rid of all udelays possible...
++ */
++ if (count >= EP0_FIFO_SIZE) {
++ count = 100;
++ do {
++ if ((UDCCSR0 & UDCCSR0_OPC) != 0) {
++ /* clear OPC, generate ack */
++ UDCCSR0 = UDCCSR0_OPC;
++ break;
++ }
++ count--;
++ udelay(1);
++ } while (count);
++ }
++#endif
++ } else if (ep->dev->req_pending)
++ ep0start(ep->dev, 0, "IN");
++ return is_short;
++}
++
++
++/*
++ * read_fifo - unload packet(s) from the fifo we use for usb OUT
++ * transfers and put them into the request. caller should have made
++ * sure there's at least one packet ready.
++ *
++ * returns true if the request completed because of short packet or the
++ * request buffer having filled (and maybe overran till end-of-packet).
++ */
++static int
++read_fifo (struct pxa27x_ep *ep, struct pxa27x_request *req)
++{
++ for (;;) {
++ u32 *buf;
++ int bufferspace, count, is_short;
++
++ /* make sure there's a packet in the FIFO.*/
++ if (unlikely ((*ep->reg_udccsr & UDCCSR_PC) == 0))
++ break;
++ buf =(u32*) (req->req.buf + req->req.actual);
++ prefetchw(buf);
++ bufferspace = req->req.length - req->req.actual;
++
++ /* read all bytes from this packet */
++ if (likely (*ep->reg_udccsr & UDCCSR_BNE)) {
++ count = 0x3ff & *ep->reg_udcbcr;
++ req->req.actual += min (count, bufferspace);
++ } else /* zlp */
++ count = 0;
++
++ is_short = (count < ep->ep.maxpacket);
++ DMSG("read %s udccsr:%02x, count:%d bytes%s req %p %d/%d\n",
++ ep->ep.name, *ep->reg_udccsr, count,
++ is_short ? "/S" : "",
++ &req->req, req->req.actual, req->req.length);
++
++// dump_regs(ep->ep_num );
++ count = min(count, bufferspace);
++ while (likely (count > 0)) {
++ *buf++ = *ep->reg_udcdr;
++ count -= 4;
++ }
++ DMSG("Buf:0x%p\n", req->req.buf);
++
++ *ep->reg_udccsr = UDCCSR_PC;
++ /* RPC/RSP/RNE could now reflect the other packet buffer */
++
++ /* completion */
++ if (is_short || req->req.actual == req->req.length) {
++ done (ep, req, 0);
++ if (list_empty(&ep->queue))
++ pio_irq_disable (ep->ep_num);
++ return 1;
++ }
++
++ /* finished that packet. the next one may be waiting... */
++ }
++ return 0;
++}
++
++/*
++ * special ep0 version of the above. no UBCR0 or double buffering; status
++ * handshaking is magic. most device protocols don't need control-OUT.
++ * CDC vendor commands (and RNDIS), mass storage CB/CBI, and some other
++ * protocols do use them.
++ */
++static int
++read_ep0_fifo (struct pxa27x_ep *ep, struct pxa27x_request *req)
++{
++ u32 *buf, word;
++ unsigned bufferspace;
++
++ buf = (u32*) (req->req.buf + req->req.actual);
++ bufferspace = req->req.length - req->req.actual;
++
++ while (UDCCSR0 & UDCCSR0_RNE) {</