/*
 * amd5536.c -- AMD 5536 UDC high/full speed USB device controller
 *
 * Copyright (C) 2005-2007 AMD (http://www.amd.com)
 * Author: Thomas Dahlmann
 *
 * 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.
 */

/*
 * The AMD5536 UDC is part of the x86 southbridge AMD Geode CS5536.
 * It is a USB Highspeed DMA capable USB device controller. Beside ep0 it
 * provides 4 IN and 4 OUT endpoints (bulk or interrupt type).
 *
 * Make sure that UDC is assigned to port 4 by BIOS settings (port can also
 * be used as host port) and UOC bits PAD_EN and APU are set (should be done
 * by BIOS init).
 *
 * UDC DMA requires 32-bit aligned buffers so DMA with gadget ether does not
 * work without updating NET_IP_ALIGN. Or PIO mode (module param "use_dma=0")
 * can be used with gadget ether.
 */

/* debug control */
/* #define UDC_VERBOSE */

/* Driver strings */
#define UDC_MOD_DESCRIPTION		"AMD 5536 UDC - USB Device Controller"
#define UDC_DRIVER_VERSION_STRING	"01.00.0206"

/* system */
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/ioctl.h>
#include <linux/fs.h>
#include <linux/dmapool.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/prefetch.h>

#include <asm/byteorder.h>
#include <asm/system.h>
#include <asm/unaligned.h>

/* gadget stack */
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>

/* udc specific */
#include "amd5536udc.h"


static void udc_tasklet_disconnect(unsigned long);
static void empty_req_queue(struct udc_ep *);
static int udc_probe(struct udc *dev);
static void udc_basic_init(struct udc *dev);
static void udc_setup_endpoints(struct udc *dev);
static void udc_soft_reset(struct udc *dev);
static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep);
static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq);
static int udc_free_dma_chain(struct udc *dev, struct udc_request *req);
static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req,
				unsigned long buf_len, gfp_t gfp_flags);
static int udc_remote_wakeup(struct udc *dev);
static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
static void udc_pci_remove(struct pci_dev *pdev);

/* description */
static const char mod_desc[] = UDC_MOD_DESCRIPTION;
static const char name[] = "amd5536udc";

/* structure to hold endpoint function pointers */
static const struct usb_ep_ops udc_ep_ops;

/* received setup data */
static union udc_setup_data setup_data;

/* pointer to device object */
static struct udc *udc;

/* irq spin lock for soft reset */
static DEFINE_SPINLOCK(udc_irq_spinlock);
/* stall spin lock */
static DEFINE_SPINLOCK(udc_stall_spinlock);

/*
* slave mode: pending bytes in rx fifo after nyet,
* used if EPIN irq came but no req was available
*/
static unsigned int udc_rxfifo_pending;

/* count soft resets after suspend to avoid loop */
static int soft_reset_occured;
static int soft_reset_after_usbreset_occured;

/* timer */
static struct timer_list udc_timer;
static int stop_timer;

/* set_rde -- Is used to control enabling of RX DMA. Problem is
 * that UDC has only one bit (RDE) to enable/disable RX DMA for
 * all OUT endpoints. So we have to handle race conditions like
 * when OUT data reaches the fifo but no request was queued yet.
 * This cannot be solved by letting the RX DMA disabled until a
 * request gets queued because there may be other OUT packets
 * in the FIFO (important for not blocking control traffic).
 * The value of set_rde controls the correspondig timer.
 *
 * set_rde -1 == not used, means it is alloed to be set to 0 or 1
 * set_rde  0 == do not touch RDE, do no start the RDE timer
 * set_rde  1 == timer function will look whether FIFO has data
 * set_rde  2 == set by timer function to enable RX DMA on next call
 */
static int set_rde = -1;

static DECLARE_COMPLETION(on_exit);
static struct timer_list udc_pollstall_timer;
static int stop_pollstall_timer;
static DECLARE_COMPLETION(on_pollstall_exit);

/* tasklet for usb disconnect */
static DECLARE_TASKLET(disconnect_tasklet, udc_tasklet_disconnect,
		(unsigned long) &udc);


/* endpoint names used for print */
static const char ep0_string[] = "ep0in";
static const char *const ep_string[] = {
	ep0_string,
	"ep1in-int", "ep2in-bulk", "ep3in-bulk", "ep4in-bulk", "ep5in-bulk",
	"ep6in-bulk", "ep7in-bulk", "ep8in-bulk", "ep9in-bulk", "ep10in-bulk",
	"ep11in-bulk", "ep12in-bulk", "ep13in-bulk", "ep14in-bulk",
	"ep15in-bulk", "ep0out", "ep1out-bulk", "ep2out-bulk", "ep3out-bulk",
	"ep4out-bulk", "ep5out-bulk", "ep6out-bulk", "ep7out-bulk",
	"ep8out-bulk", "ep9out-bulk", "ep10out-bulk", "ep11out-bulk",
	"ep12out-bulk", "ep13out-bulk", "ep14out-bulk", "ep15out-bulk"
};

/* DMA usage flag */
static bool use_dma = 1;
/* packet per buffer dma */
static bool use_dma_ppb = 1;
/* with per descr. update */
static bool use_dma_ppb_du;
/* buffer fill mode */
static int use_dma_bufferfill_mode;
/* full speed only mode */
static bool use_fullspeed;
/* tx buffer size for high speed */
static unsigned long hs_tx_buf = UDC_EPIN_BUFF_SIZE;

/* module parameters */
module_param(use_dma, bool, S_IRUGO);
MODULE_PARM_DESC(use_dma, "true for DMA");
module_param(use_dma_ppb, bool, S_IRUGO);
MODULE_PARM_DESC(use_dma_ppb, "true for DMA in packet per buffer mode");
module_param(use_dma_ppb_du, bool, S_IRUGO);
MODULE_PARM_DESC(use_dma_ppb_du,
	"true for DMA in packet per buffer mode with descriptor update");
module_param(use_fullspeed, bool, S_IRUGO);
MODULE_PARM_DESC(use_fullspeed, "true for fullspeed only");

/*---------------------------------------------------------------------------*/
/* Prints UDC device registers and endpoint irq registers */
static void print_regs(struct udc *dev)
{
	DBG(dev, "------- Device registers -------\n");
	DBG(dev, "dev config     = %08x\n", readl(&dev->regs->cfg));
	DBG(dev, "dev control    = %08x\n", readl(&dev->regs->ctl));
	DBG(dev, "dev status     = %08x\n", readl(&dev->regs->sts));
	DBG(dev, "\n");
	DBG(dev, "dev int's      = %08x\n", readl(&dev->regs->irqsts));
	DBG(dev, "dev intmask    = %08x\n", readl(&dev->regs->irqmsk));
	DBG(dev, "\n");
	DBG(dev, "dev ep int's   = %08x\n", readl(&dev->regs->ep_irqsts));
	DBG(dev, "dev ep intmask = %08x\n", readl(&dev->regs->ep_irqmsk));
	DBG(dev, "\n");
	DBG(dev, "USE DMA        = %d\n", use_dma);
	if (use_dma && use_dma_ppb && !use_dma_ppb_du) {
		DBG(dev, "DMA mode       = PPBNDU (packet per buffer "
			"WITHOUT desc. update)\n");
		dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBNDU");
	} else if (use_dma && use_dma_ppb && use_dma_ppb_du) {
		DBG(dev, "DMA mode       = PPBDU (packet per buffer "
			"WITH desc. update)\n");
		dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBDU");
	}
	if (use_dma && use_dma_bufferfill_mode) {
		DBG(dev, "DMA mode       = BF (buffer fill mode)\n");
		dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "BF");
	}
	if (!use_dma)
		dev_info(&dev->pdev->dev, "FIFO mode\n");
	DBG(dev, "-------------------------------------------------------\n");
}

/* Masks unused interrupts */
static int udc_mask_unused_interrupts(struct udc *dev)
{
	u32 tmp;

	/* mask all dev interrupts */
	tmp =	AMD_BIT(UDC_DEVINT_SVC) |
		AMD_BIT(UDC_DEVINT_ENUM) |
		AMD_BIT(UDC_DEVINT_US) |
		AMD_BIT(UDC_DEVINT_UR) |
		AMD_BIT(UDC_DEVINT_ES) |
		AMD_BIT(UDC_DEVINT_SI) |
		AMD_BIT(UDC_DEVINT_SOF)|
		AMD_BIT(UDC_DEVINT_SC);
	writel(tmp, &dev->regs->irqmsk);

	/* mask all ep interrupts */
	writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqmsk);

	return 0;
}

/* Enables endpoint 0 interrupts */
static int udc_enable_ep0_interrupts(struct udc *dev)
{
	u32 tmp;

	DBG(dev, "udc_enable_ep0_interrupts()\n");

	/* read irq mask */
	tmp = readl(&dev->regs->ep_irqmsk);
	/* enable ep0 irq's */
	tmp &= AMD_UNMASK_BIT(UDC_EPINT_IN_EP0)
		& AMD_UNMASK_BIT(UDC_EPINT_OUT_EP0);
	writel(tmp, &dev->regs->ep_irqmsk);

	return 0;
}

/* Enables device interrupts for SET_INTF and SET_CONFIG */
static int udc_enable_dev_setup_interrupts(struct udc *dev)
{
	u32 tmp;

	DBG(dev, "enable device interrupts for setup data\n");

	/* read irq mask */
	tmp = readl(&dev->regs->irqmsk);

	/* enable SET_INTERFACE, SET_CONFIG and other needed irq's */
	tmp &= AMD_UNMASK_BIT(UDC_DEVINT_SI)
		& AMD_UNMASK_BIT(UDC_DEVINT_SC)
		& AMD_UNMASK_BIT(UDC_DEVINT_UR)
		& AMD_UNMASK_BIT(UDC_DEVINT_SVC)
		& AMD_UNMASK_BIT(UDC_DEVINT_ENUM);
	writel(tmp, &dev->regs->irqmsk);

	return 0;
}

/* Calculates fifo start of endpoint based on preceding endpoints */
static int udc_set_txfifo_addr(struct udc_ep *ep)
{
	struct udc	*dev;
	u32 tmp;
	int i;

	if (!ep || !(ep->in))
		return -EINVAL;

	dev = ep->dev;
	ep->txfifo = dev->txfifo;

	/* traverse ep's */
	for (i = 0; i < ep->num; i++) {
		if (dev->ep[i].regs) {
			/* read fifo size */
			tmp = readl(&dev->ep[i].regs->bufin_framenum);
			tmp = AMD_GETBITS(tmp, UDC_EPIN_BUFF_SIZE);
			ep->txfifo += tmp;
		}
	}
	return 0;
}

/* CNAK pending field: bit0 = ep0in, bit16 = ep0out */
static u32 cnak_pending;

static void UDC_QUEUE_CNAK(struct udc_ep *ep, unsigned num)
{
	if (readl(&ep->regs->ctl) & AMD_BIT(UDC_EPCTL_NAK)) {
		DBG(ep->dev, "NAK could not be cleared for ep%d\n", num);
		cnak_pending |= 1 << (num);
		ep->naking = 1;
	} else
		cnak_pending = cnak_pending & (~(1 << (num)));
}


/* Enables endpoint, is called by gadget driver */
static int
udc_ep_enable(struct usb_ep *usbep, const struct usb_endpoint_descriptor *desc)
{
	struct udc_ep		*ep;
	struct udc		*dev;
	u32			tmp;
	unsigned long		iflags;
	u8 udc_csr_epix;
	unsigned		maxpacket;

	if (!usbep
			|| usbep->name == ep0_string
			|| !desc
			|| desc->bDescriptorType != USB_DT_ENDPOINT)
		return -EINVAL;

	ep = container_of(usbep, struct udc_ep, ep);
	dev = ep->dev;

	DBG(dev, "udc_ep_enable() ep %d\n", ep->num);

	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
		return -ESHUTDOWN;

	spin_lock_irqsave(&dev->lock, iflags);
	ep->desc = desc;

	ep->halted = 0;

	/* set traffic type */
	tmp = readl(&dev->ep[ep->num].regs->ctl);
	tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_EPCTL_ET);
	writel(tmp, &dev->ep[ep->num].regs->ctl);

	/* set max packet size */
	maxpacket = usb_endpoint_maxp(desc);
	tmp = readl(&dev->ep[ep->num].regs->bufout_maxpkt);
	tmp = AMD_ADDBITS(tmp, maxpacket, UDC_EP_MAX_PKT_SIZE);
	ep->ep.maxpacket = maxpacket;
	writel(tmp, &dev->ep[ep->num].regs->bufout_maxpkt);

	/* IN ep */
	if (ep->in) {

		/* ep ix in UDC CSR register space */
		udc_csr_epix = ep->num;

		/* set buffer size (tx fifo entries) */
		tmp = readl(&dev->ep[ep->num].regs->bufin_framenum);
		/* double buffering: fifo size = 2 x max packet size */
		tmp = AMD_ADDBITS(
				tmp,
				maxpacket * UDC_EPIN_BUFF_SIZE_MULT
					  / UDC_DWORD_BYTES,
				UDC_EPIN_BUFF_SIZE);
		writel(tmp, &dev->ep[ep->num].regs->bufin_framenum);

		/* calc. tx fifo base addr */
		udc_set_txfifo_addr(ep);

		/* flush fifo */
		tmp = readl(&ep->regs->ctl);
		tmp |= AMD_BIT(UDC_EPCTL_F);
		writel(tmp, &ep->regs->ctl);

	/* OUT ep */
	} else {
		/* ep ix in UDC CSR register space */
		udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS;

		/* set max packet size UDC CSR	*/
		tmp = readl(&dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]);
		tmp = AMD_ADDBITS(tmp, maxpacket,
					UDC_CSR_NE_MAX_PKT);
		writel(tmp, &dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]);

		if (use_dma && !ep->in) {
			/* alloc and init BNA dummy request */
			ep->bna_dummy_req = udc_alloc_bna_dummy(ep);
			ep->bna_occurred = 0;
		}

		if (ep->num != UDC_EP0OUT_IX)
			dev->data_ep_enabled = 1;
	}

	/* set ep values */
	tmp = readl(&dev->csr->ne[udc_csr_epix]);
	/* max packet */
	tmp = AMD_ADDBITS(tmp, maxpacket, UDC_CSR_NE_MAX_PKT);
	/* ep number */
	tmp = AMD_ADDBITS(tmp, desc->bEndpointAddress, UDC_CSR_NE_NUM);
	/* ep direction */
	tmp = AMD_ADDBITS(tmp, ep->in, UDC_CSR_NE_DIR);
	/* ep type */
	tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_CSR_NE_TYPE);
	/* ep config */
	tmp = AMD_ADDBITS(tmp, ep->dev->cur_config, UDC_CSR_NE_CFG);
	/* ep interface */
	tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf, UDC_CSR_NE_INTF);
	/* ep alt */
	tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt, UDC_CSR_NE_ALT);
	/* write reg */
	writel(tmp, &dev->csr->ne[udc_csr_epix]);

	/* enable ep irq */
	tmp = readl(&dev->regs->ep_irqmsk);
	tmp &= AMD_UNMASK_BIT(ep->num);
	writel(tmp, &dev->regs->ep_irqmsk);

	/*
	 * clear NAK by writing CNAK
	 * avoid BNA for OUT DMA, don't clear NAK until DMA desc. written
	 */
	if (!use_dma || ep->in) {
		tmp = readl(&ep->regs->ctl);
		tmp |= AMD_BIT(UDC_EPCTL_CNAK);
		writel(tmp, &ep->regs->ctl);
		ep->naking = 0;
		UDC_QUEUE_CNAK(ep, ep->num);
	}
	tmp = desc->bEndpointAddress;
	DBG(dev, "%s enabled\n", usbep->name);

	spin_unlock_irqrestore(&dev->lock, iflags);
	return 0;
}

/* Resets endpoint */
static void ep_init(struct udc_regs __iomem *regs, struct udc_ep *ep)
{
	u32		tmp;

	VDBG(ep->dev, "ep-%d reset\n", ep->num);
	ep->desc = NULL;
	ep->ep.desc = NULL;
	ep->ep.ops = &udc_ep_ops;
	INIT_LIST_HEAD(&ep->queue);

	ep->ep.maxpacket = (u16) ~0;
	/* set NAK */
	tmp = readl(&ep->regs->ctl);
	tmp |= AMD_BIT(UDC_EPCTL_SNAK);
	writel(tmp, &ep->regs->ctl);
	ep->naking = 1;

	/* disable interrupt */
	tmp = readl(&regs->ep_irqmsk);
	tmp |= AMD_BIT(ep->num);
	writel(tmp, &regs->ep_irqmsk);

	if (ep->in) {
		/* unset P and IN bit of potential former DMA */
		tmp = readl(&ep->regs->ctl);
		tmp &= AMD_UNMASK_BIT(UDC_EPCTL_P);
		writel(tmp, &ep->regs->ctl);

		tmp = readl(&ep->regs->sts);
		tmp |= AMD_BIT(UDC_EPSTS_IN);
		writel(tmp, &ep->regs->sts);

		/* flush the fifo */
		tmp = readl(&ep->regs->ctl);
		tmp |= AMD_BIT(UDC_EPCTL_F);
		writel(tmp, &ep->regs->ctl);

	}
	/* reset desc pointer */
	writel(0, &ep->regs->desptr);
}

/* Disables endpoint, is called by gadget driver */
static int udc_ep_disable(struct usb_ep *usbep)
{
	struct udc_ep	*ep = NULL;
	unsigned long	iflags;

	if (!usbep)
		return -EINVAL;

	ep = container_of(usbep, struct udc_ep, ep);
	if (usbep->name == ep0_string || !ep->desc)
		return -EINVAL;

	DBG(ep->dev, "Disable ep-%d\n", ep->num);

	spin_lock_irqsave(&ep->dev->lock, iflags);
	udc_free_request(&ep->ep, &ep->bna_dummy_req->req);
	empty_req_queue(ep);
	ep_init(ep->dev->regs, ep);
	spin_unlock_irqrestore(&ep->dev->lock, iflags);

	return 0;
}

/* Allocates request packet, called by gadget driver */
static struct usb_request *
udc_alloc_request(struct usb_ep *usbep, gfp_t gfp)
{
	struct udc_request	*req;
	struct udc_data_dma	*dma_desc;
	struct udc_ep	*ep;

	if (!usbep)
		return NULL;

	ep = container_of(usbep, struct udc_ep, ep);

	VDBG(ep->dev, "udc_alloc_req(): ep%d\n", ep->num);
	req = kzalloc(sizeof(struct udc_request), gfp);
	if (!req)
		return NULL;

	req->req.dma = DMA_DONT_USE;
	INIT_LIST_HEAD(&req->queue);

	if (ep->dma) {
		/* ep0 in requests are allocated from data pool here */
		dma_desc = pci_pool_alloc(ep->dev->data_requests, gfp,
						&req->td_phys);
		if (!dma_desc) {
			kfree(req);
			return NULL;
		}

		VDBG(ep->dev, "udc_alloc_req: req = %p dma_desc = %p, "
				"td_phys = %lx\n",
				req, dma_desc,
				(unsigned long)req->td_phys);
		/* prevent from using desc. - set HOST BUSY */
		dma_desc->status = AMD_ADDBITS(dma_desc->status,
						UDC_DMA_STP_STS_BS_HOST_BUSY,
						UDC_DMA_STP_STS_BS);
		dma_desc->bufptr = cpu_to_le32(DMA_DONT_USE);
		req->td_data = dma_desc;
		req->td_data_last = NULL;
		req->chain_len = 1;
	}

	return &req->req;
}

/* Frees request packet, called by gadget driver */
static void
udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq)
{
	struct udc_ep	*ep;
	struct udc_request	*req;

	if (!usbep || !usbreq)
		return;

	ep = container_of(usbep, struct udc_ep, ep);
	req = container_of(usbreq, struct udc_request, req);
	VDBG(ep->dev, "free_req req=%p\n", req);
	BUG_ON(!list_empty(&req->queue));
	if (req->td_data) {
		VDBG(ep->dev, "req->td_data=%p\n", req->td_data);

		/* free dma chain if created */
		if (req->chain_len > 1)
			udc_free_dma_chain(ep->dev, req);

		pci_pool_free(ep->dev->data_requests, req->td_data,
							req->td_phys);
	}
	kfree(req);
}

/* Init BNA dummy descriptor for HOST BUSY and pointing to itself */
static void udc_init_bna_dummy(struct udc_request *req)
{
	if (req) {
		/* set last bit */
		req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L);
		/* set next pointer to itself */
		req->td_data->next = req->td_phys;
		/* set HOST BUSY */
		req->td_data->status
			= AMD_ADDBITS(req->td_data->status,
					UDC_DMA_STP_STS_BS_DMA_DONE,
					UDC_DMA_STP_STS_BS);
#ifdef UDC_VERBOSE
		pr_debug("bna desc = %p, sts = %08x\n",
			req->td_data, req->td_data->status);
#endif
	}
}

/* Allocate BNA dummy descriptor */
static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep)
{
	struct udc_request *req = NULL;
	struct usb_request *_req = NULL;

	/* alloc the dummy request */
	_req = udc_alloc_request(&ep->ep, GFP_ATOMIC);
	if (_req) {
		req = container_of(_req, struct udc_request, req);
		ep->bna_dummy_req = req;
		udc_init_bna_dummy(req);
	}
	return req;
}

/* Write data to TX fifo for IN packets */
static void
udc_txfifo_write(struct udc_ep *ep, struct usb_request *req)
{
	u8			*req_buf;
	u32			*buf;
	int			i, j;
	unsigned		bytes = 0;
	unsigned		remaining = 0;

	if (!req || !ep)
		return;

	req_buf = req->buf + req->actual;
	prefetch(req_buf);
	remaining = req->length - req->actual;

	buf = (u32 *) req_buf;

	bytes = ep->ep.maxpacket;
	if (bytes > remaining)
		bytes = remaining;

	/* dwords first */
	for (i = 0; i < bytes / UDC_DWORD_BYTES; i++)
		writel(*(buf + i), ep->txfifo);

	/* remaining bytes must be written by byte access */
	for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) {
		writeb((u8)(*(buf + i) >> (j << UDC_BITS_PER_BYTE_SHIFT)),
							ep->txfifo);
	}

	/* dummy write confirm */
	writel(0, &ep->regs->confirm);
}

/* Read dwords from RX fifo for OUT transfers */
static int udc_rxfifo_read_dwords(struct udc *dev, u32 *buf, int dwords)
{
	int i;

	VDBG(dev, "udc_read_dwords(): %d dwords\n", dwords);

	for (i = 0; i < dwords; i++)
		*(buf + i) = readl(dev->rxfifo);
	return 0;
}

/* Read bytes from RX fifo for OUT transfers */
static int udc_rxfifo_read_bytes(struct udc *dev, u8 *buf, int bytes)
{
	int i, j;
	u32 tmp;

	VDBG(dev, "udc_read_bytes(): %d bytes\n", bytes);

	/* dwords first */
	for (i = 0; i < bytes / UDC_DWORD_BYTES; i++)
		*((u32 *)(buf + (i<<2))) = readl(dev->rxfifo);

	/* remaining bytes must be read by byte access */
	if (bytes % UDC_DWORD_BYTES) {
		tmp = readl(dev->rxfifo);
		for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) {
			*(buf + (i<<2) + j) = (u8)(tmp & UDC_BYTE_MASK);
			tmp = tmp >> UDC_BITS_PER_BYTE;
		}
	}

	return 0;
}

/* Read data from RX fifo for OUT transfers */
static int
udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req)
{
	u8 *buf;
	unsigned buf_space;
	unsigned bytes = 0;
	unsigned finished = 0;

	/* received number bytes */
	bytes = readl(&ep->regs->sts);
	bytes = AMD_GETBITS(bytes, UDC_EPSTS_RX_PKT_SIZE);

	buf_space = req->req.length - req->req.actual;
	buf = req->req.buf + req->req.actual;
	if (bytes > buf_space) {
		if ((buf_space % ep->ep.maxpacket) != 0) {
			DBG(ep->dev,
				"%s: rx %d bytes, rx-buf space = %d bytesn\n",
				ep->ep.name, bytes, buf_space);
			req->req.status = -EOVERFLOW;
		}
		bytes = buf_space;
	}
	req->req.actual += bytes;

	/* last packet ? */
	if (((bytes % ep->ep.maxpacket) != 0) || (!bytes)
		|| ((req->req.actual == req->req.length) && !req->req.zero))
		finished = 1;

	/* read rx fifo bytes */
	VDBG(ep->dev, "ep %s: rxfifo read %d bytes\n", ep->ep.name, bytes);
	udc_rxfifo_read_bytes(ep->dev, buf, bytes);

	return finished;
}

/* create/re-init a DMA descriptor or a DMA descriptor chain */
static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp)
{
	int	retval = 0;
	u32	tmp;

	VDBG(ep->dev, "prep_dma\n");
	VDBG(ep->dev, "prep_dma ep%d req->td_data=%p\n",
			ep->num, req->td_data);

	/* set buffer pointer */
	req->td_data->bufptr = req->req.dma;

	/* set last bit */
	req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L);

	/* build/re-init dma chain if maxpkt scatter mode, not for EP0 */
	if (use_dma_ppb) {

		retval = udc_create_dma_chain(ep, req, ep->ep.maxpacket, gfp);
		if (retval != 0) {
			if (retval == -ENOMEM)
				DBG(ep->dev, "Out of DMA memory\n");
			return retval;
		}
		if (ep->in) {
			if (req->req.length == ep->ep.maxpacket) {
				/* write tx bytes */
				req->td_data->status =
					AMD_ADDBITS(req->td_data->status,
						ep->ep.maxpacket,
						UDC_DMA_IN_STS_TXBYTES);

			}
		}

	}

	if (ep->in) {
		VDBG(ep->dev, "IN: use_dma_ppb=%d req->req.len=%d "
				"maxpacket=%d ep%d\n",
				use_dma_ppb, req->req.length,
				ep->ep.maxpacket, ep->num);
		/*
		 * if bytes < max packet then tx bytes must
		 * be written in packet per buffer mode
		 */
		if (!use_dma_ppb || req->req.length < ep->ep.maxpacket
				|| ep->num == UDC_EP0OUT_IX
				|| ep->num == UDC_EP0IN_IX) {
			/* write tx bytes */
			req->td_data->status =
				AMD_ADDBITS(req->td_data->status,
						req->req.length,
						UDC_DMA_IN_STS_TXBYTES);
			/* reset frame num */
			req->td_data->status =
				AMD_ADDBITS(req->td_data->status,
						0,
						UDC_DMA_IN_STS_FRAMENUM);
		}
		/* set HOST BUSY */
		req->td_data->status =
			AMD_ADDBITS(req->td_data->status,
				UDC_DMA_STP_STS_BS_HOST_BUSY,
				UDC_DMA_STP_STS_BS);
	} else {
		VDBG(ep->dev, "OUT set host ready\n");
		/* set HOST READY */
		req->td_data->status =
			AMD_ADDBITS(req->td_data->status,
				UDC_DMA_STP_STS_BS_HOST_READY,
				UDC_DMA_STP_STS_BS);


			/* clear NAK by writing CNAK */
			if (ep->naking) {
				tmp = readl(&ep->regs->ctl);
				tmp |= AMD_BIT(UDC_EPCTL_CNAK);
				writel(tmp, &ep->regs->ctl);
				ep->naking = 0;
				UDC_QUEUE_CNAK(ep, ep->num);
			}

	}

	return retval;
}

/* Completes request packet ... caller MUST hold lock */
static void
complete_req(struct udc_ep *ep, struct udc_request *req, int sts)
__releases(ep->dev->lock)
__acquires(ep->dev->lock)
{
	struct udc		*dev;
	unsigned		halted;

	VDBG(ep->dev, "complete_req(): ep%d\n", ep->num);

	dev = ep->dev;
	/* unmap DMA */
	if (ep->dma)
		usb_gadget_unmap_request(&dev->gadget, &req->req, ep->in);

	halted = ep->halted;
	ep->halted = 1;

	/* set new status if pending */
	if (req->req.status == -EINPROGRESS)
		req->req.status = sts;

	/* remove from ep queue */
	list_del_init(&req->queue);

	VDBG(ep->dev, "req %p => complete %d bytes at %s with sts %d\n",
		&req->req, req->req.length, ep->ep.name, sts);

	spin_unlock(&dev->lock);
	req->req.complete(&ep->ep, &req->req);
	spin_lock(&dev->lock);
	ep->halted = halted;
}

/* frees pci pool descriptors of a DMA chain */
static int udc_free_dma_chain(struct udc *dev, struct udc_request *req)
{

	int ret_val = 0;
	struct udc_data_dma	*td;
	struct udc_data_dma	*td_last = NULL;
	unsigned int i;

	DBG(dev, "free chain req = %p\n", req);

	/* do not free first desc., will be done by free for request */
	td_last = req->td_data;
	td = phys_to_virt(td_last->next);

	for (i = 1; i < req->chain_len; i++) {

		pci_pool_free(dev->data_requests, td,
				(dma_addr_t) td_last->next);
		td_last = td;
		td = phys_to_virt(td_last->next);
	}

	return ret_val;
}

/* Iterates to the end of a DMA chain and returns last descriptor */
static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req)
{
	struct udc_data_dma	*td;

	td = req->td_data;
	while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L)))
		td = phys_to_virt(td->next);

	return td;

}

/* Iterates to the end of a DMA chain and counts bytes received */
static u32 udc_get_ppbdu_rxbytes(struct udc_request *req)
{
	struct udc_data_dma	*td;
	u32 count;

	td = req->td_data;
	/* received number bytes */
	count = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_RXBYTES);

	while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) {
		td = phys_to_virt(td->next);
		/* received number bytes */
		if (td) {
			count += AMD_GETBITS(td->status,
				UDC_DMA_OUT_STS_RXBYTES);
		}
	}

	return count;

}

/* Creates or re-inits a DMA chain */
static int udc_create_dma_chain(
	struct udc_ep *ep,
	struct udc_request *req,
	unsigned long buf_len, gfp_t gfp_flags
)
{
	unsigned long bytes = req->req.length;
	unsigned int i;
	dma_addr_t dma_addr;
	struct udc_data_dma	*td = NULL;
	struct udc_data_dma	*last = NULL;
	unsigned long txbytes;
	unsigned create_new_chain = 0;
	unsigned len;

	VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n",
			bytes, buf_len);
	dma_addr = DMA_DONT_USE;

	/* unset L bit in first desc for OUT */
	if (!ep->in)
		req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L);

	/* alloc only new desc's if not already available */
	len = req->req.length / ep->ep.maxpacket;
	if (req->req.length % ep->ep.maxpacket)
		len++;

	if (len > req->chain_len) {
		/* shorter chain already allocated before */
		if (req->chain_len > 1)
			udc_free_dma_chain(ep->dev, req);
		req->chain_len = len;
		create_new_chain = 1;
	}

	td = req->td_data;
	/* gen. required number of descriptors and buffers */
	for (i = buf_len; i < bytes; i += buf_len) {
		/* create or determine next desc. */
		if (create_new_chain) {

			td = pci_pool_alloc(ep->dev->data_requests,
					gfp_flags, &dma_addr);
			if (!td)
				return -ENOMEM;

			td->status = 0;
		} else if (i == buf_len) {
			/* first td */
			td = (struct udc_data_dma *) phys_to_virt(
						req->td_data->next);
			td->status = 0;
		} else {
			td = (struct udc_data_dma *) phys_to_virt(last->next);
			td->status = 0;
		}


		if (td)
			td->bufptr = req->req.dma + i; /* assign buffer */
		else
			break;

		/* short packet ? */
		if ((bytes - i) >= buf_len) {
			txbytes = buf_len;
		} else {
			/* short packet */
			txbytes = bytes - i;
		}

		/* link td and assign tx bytes */
		if (i == buf_len) {
			if (create_new_chain)
				req->td_data->next = dma_addr;
			/*
			else
				req->td_data->next = virt_to_phys(td);
			*/
			/* write tx bytes */
			if (ep->in) {
				/* first desc */
				req->td_data->status =
					AMD_ADDBITS(req->td_data->status,
							ep->ep.maxpacket,
							UDC_DMA_IN_STS_TXBYTES);
				/* second desc */
				td->status = AMD_ADDBITS(td->status,
							txbytes,
							UDC_DMA_IN_STS_TXBYTES);
			}
		} else {
			if (create_new_chain)
				last->next = dma_addr;
			/*
			else
				last->next = virt_to_phys(td);
			*/
			if (ep->in) {
				/* write tx bytes */
				td->status = AMD_ADDBITS(td->status,
							txbytes,
							UDC_DMA_IN_STS_TXBYTES);
			}
		}
		last = td;
	}
	/* set last bit */
	if (td) {
		td->status |= AMD_BIT(UDC_DMA_IN_STS_L);
		/* last desc. points to itself */
		req->td_data_last = td;
	}

	return 0;
}

/* Enabling RX DMA */
static void udc_set_rde(struct udc *dev)
{
	u32 tmp;

	VDBG(dev, "udc_set_rde()\n");
	/* stop RDE timer */
	if (timer_pending(&udc_timer)) {
		set_rde = 0;
		mod_timer(&udc_timer, jiffies - 1);
	}
	/* set RDE */
	tmp = readl(&dev->regs->ctl);
	tmp |= AMD_BIT(UDC_DEVCTL_RDE);
	writel(tmp, &dev->regs->ctl);
}

/* Queues a request packet, called by gadget driver */
static int
udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp)
{
	int			retval = 0;
	u8			open_rxfifo = 0;
	unsigned long		iflags;
	struct udc_ep		*ep;
	struct udc_request	*req;
	struct udc		*dev;
	u32			tmp;

	/* check the inputs */
	req = container_of(usbreq, struct udc_request, req);

	if (!usbep || !usbreq || !usbreq->complete || !usbreq->buf
			|| !list_empty(&req->queue))
		return -EINVAL;

	ep = container_of(usbep, struct udc_ep, ep);
	if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
		return -EINVAL;

	VDBG(ep->dev, "udc_queue(): ep%d-in=%d\n", ep->num, ep->in);
	dev = ep->dev;

	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
		return -ESHUTDOWN;

	/* map dma (usually done before) */
	if (ep->dma) {
		VDBG(dev, "DMA map req %p\n", req);
		retval = usb_gadget_map_request(&udc->gadget, usbreq, ep->in);
		if (retval)
			return retval;
	}

	VDBG(dev, "%s queue req %p, len %d req->td_data=%p buf %p\n",
			usbep->name, usbreq, usbreq->length,
			req->td_data, usbreq->buf);

	spin_lock_irqsave(&dev->lock, iflags);
	usbreq->actual = 0;
	usbreq->status = -EINPROGRESS;
	req->dma_done = 0;

	/* on empty queue just do first transfer */
	if (list_empty(&ep->queue)) {
		/* zlp */
		if (usbreq->length == 0) {
			/* IN zlp's are handled by hardware */
			complete_req(ep, req, 0);
			VDBG(dev, "%s: zlp\n", ep->ep.name);
			/*
			 * if set_config or set_intf is waiting for ack by zlp
			 * then set CSR_DONE
			 */
			if (dev->set_cfg_not_acked) {
				tmp = readl(&dev->regs->ctl);
				tmp |= AMD_BIT(UDC_DEVCTL_CSR_DONE);
				writel(tmp, &dev->regs->ctl);
				dev->set_cfg_not_acked = 0;
			}
			/* setup command is ACK'ed now by zlp */
			if (dev->waiting_zlp_ack_ep0in) {
				/* clear NAK by writing CNAK in EP0_IN */
				tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl);
				tmp |= AMD_BIT(UDC_EPCTL_CNAK);
				writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl);
				dev->ep[UDC_EP0IN_IX].naking = 0;
				UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX],
							UDC_EP0IN_IX);
				dev->waiting_zlp_ack_ep0in = 0;
			}
			goto finished;
		}
		if (ep->dma) {
			retval = prep_dma(ep, req, gfp);
			if (retval != 0)
				goto finished;
			/* write desc pointer to enable DMA */
			if (ep->in) {
				/* set HOST READY */
				req->td_data->status =
					AMD_ADDBITS(req->td_data->status,
						UDC_DMA_IN_STS_BS_HOST_READY,
						UDC_DMA_IN_STS_BS);
			}

			/* disabled rx dma while descriptor update */
			if (!ep->in) {
				/* stop RDE timer */
				if (timer_pending(&udc_timer)) {
					set_rde = 0;
					mod_timer(&udc_timer, jiffies - 1);
				}
				/* clear RDE */
				tmp = readl(&dev->regs->ctl);
				tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE);
				writel(tmp, &dev->regs->ctl);
				open_rxfifo = 1;

				/*
				 * if BNA occurred then let BNA dummy desc.
				 * point to current desc.
				 */
				if (ep->bna_occurred) {
					VDBG(dev, "copy to BNA dummy desc.\n");
					memcpy(ep->bna_dummy_req->td_data,
						req->td_data,
						sizeof(struct udc_data_dma));
				}
			}
			/* write desc pointer */
			writel(req->td_phys, &ep->regs->desptr);

			/* clear NAK by writing CNAK */
			if (ep->naking) {
				tmp = readl(&ep->regs->ctl);
				tmp |= AMD_BIT(UDC_EPCTL_CNAK);
				writel(tmp, &ep->regs->ctl);
				ep->naking = 0;
				UDC_QUEUE_CNAK(ep, ep->num);
			}

			if (ep->in) {
				/* enable ep irq */
				tmp = readl(&dev->regs->ep_irqmsk);
				tmp &= AMD_UNMASK_BIT(ep->num);
				writel(tmp, &dev->regs->ep_irqmsk);
			}
		} else if (ep->in) {
				/* enable ep irq */
				tmp = readl(&dev->regs->ep_irqmsk);
				tmp &= AMD_UNMASK_BIT(ep->num);
				writel(tmp, &dev->regs->ep_irqmsk);
			}

	} else if (ep->dma) {

		/*
		 * prep_dma not used for OUT ep's, this is not possible
		 * for PPB modes, because of chain creation reasons
		 */
		if (ep->in) {
			retval = prep_dma(ep, req, gfp);
			if (retval != 0)
				goto finished;
		}
	}
	VDBG(dev, "list_add\n");
	/* add request to ep queue */
	if (req) {

		list_add_tail(&req->queue, &ep->queue);

		/* open rxfifo if out data queued */
		if (open_rxfifo) {
			/* enable DMA */
			req->dma_going = 1;
			udc_set_rde(dev);
			if (ep->num != UDC_EP0OUT_IX)
				dev->data_ep_queued = 1;
		}
		/* stop OUT naking */
		if (!ep->in) {
			if (!use_dma && udc_rxfifo_pending) {
				DBG(dev, "udc_queue(): pending bytes in "
					"rxfifo after nyet\n");
				/*
				 * read pending bytes afer nyet:
				 * referring to isr
				 */
				if (udc_rxfifo_read(ep, req)) {
					/* finish */
					complete_req(ep, req, 0);
				}
				udc_rxfifo_pending = 0;

			}
		}
	}

finished:
	spin_unlock_irqrestore(&dev->lock, iflags);
	return retval;
}

/* Empty request queue of an endpoint; caller holds spinlock */
static void empty_req_queue(struct udc_ep *ep)
{
	struct udc_request	*req;

	ep->halted = 1;
	while (!list_empty(&ep->queue)) {
		req = list_entry(ep->queue.next,
			struct udc_request,
			queue);
		complete_req(ep, req, -ESHUTDOWN);
	}
}

/* Dequeues a request packet, called by gadget driver */
static int udc_dequeue(struct usb_ep *usbep, struct usb_request *usbreq)
{
	struct udc_ep		*ep;
	struct udc_request	*req;
	unsigned		halted;
	unsigned long		iflags;

	ep = container_of(usbep, struct udc_ep, ep);
	if (!usbep || !usbreq || (!ep->desc && (ep->num != 0
				&& ep->num != UDC_EP0OUT_IX)))
		return -EINVAL;

	req = container_of(usbreq, struct udc_request, req);

	spin_lock_irqsave(&ep->dev->lock, iflags);
	halted = ep->halted;
	ep->halted = 1;
	/* request in processing or next one */
	if (ep->queue.next == &req->queue) {
		if (ep->dma && req->dma_going) {
			if (ep->in)
				ep->cancel_transfer = 1;
			else {
				u32 tmp;
				u32 dma_sts;
				/* stop potential receive DMA */
				tmp = readl(&udc->regs->ctl);
				writel(tmp & AMD_UNMASK_BIT(UDC_DEVCTL_RDE),
							&udc->regs->ctl);
				/*
				 * Cancel transfer later in ISR
				 * if descriptor was touched.
				 */
				dma_sts = AMD_GETBITS(req->td_data->status,
							UDC_DMA_OUT_STS_BS);
				if (dma_sts != UDC_DMA_OUT_STS_BS_HOST_READY)
					ep->cancel_transfer = 1;
				else {
					udc_init_bna_dummy(ep->req);
					writel(ep->bna_dummy_req->td_phys,
						&ep->regs->desptr);
				}
				writel(tmp, &udc->regs->ctl);
			}
		}
	}
	complete_req(ep, req, -ECONNRESET);
	ep->halted = halted;

	spin_unlock_irqrestore(&ep->dev->lock, iflags);
	return 0;
}

/* Halt or clear halt of endpoint */
static int
udc_set_halt(struct usb_ep *usbep, int halt)
{
	struct udc_ep	*ep;
	u32 tmp;
	unsigned long iflags;
	int retval = 0;

	if (!usbep)
		return -EINVAL;

	pr_debug("set_halt %s: halt=%d\n", usbep->name, halt);

	ep = container_of(usbep, struct udc_ep, ep);
	if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX))
		return -EINVAL;
	if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
		return -ESHUTDOWN;

	spin_lock_irqsave(&udc_stall_spinlock, iflags);
	/* halt or clear halt */
	if (halt) {
		if (ep->num == 0)
			ep->dev->stall_ep0in = 1;
		else {
			/*
			 * set STALL
			 * rxfifo empty not taken into acount
			 */
			tmp = readl(&ep->regs->ctl);
			tmp |= AMD_BIT(UDC_EPCTL_S);
			writel(tmp, &ep->regs->ctl);
			ep->halted = 1;

			/* setup poll timer */
			if (!timer_pending(&udc_pollstall_timer)) {
				udc_pollstall_timer.expires = jiffies +
					HZ * UDC_POLLSTALL_TIMER_USECONDS
					/ (1000 * 1000);
				if (!stop_pollstall_timer) {
					DBG(ep->dev, "start polltimer\n");
					add_timer(&udc_pollstall_timer);
				}
			}
		}
	} else {
		/* ep is halted by set_halt() before */
		if (ep->halted) {
			tmp = readl(&ep->regs->ctl);
			/* clear stall bit */
			tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S);
			/* clear NAK by writing CNAK */
			tmp |= AMD_BIT(UDC_EPCTL_CNAK);
			writel(tmp, &ep->regs->ctl);
			ep->halted = 0;
			UDC_QUEUE_CNAK(ep, ep->num);
		}
	}
	spin_unlock_irqrestore(&udc_stall_spinlock, iflags);
	return retval;
}

/* gadget interface */
static const struct usb_ep_ops udc_ep_ops = {
	.enable		= udc_ep_enable,
	.disable	= udc_ep_disable,

	.alloc_request	= udc_alloc_request,
	.free_request	= udc_free_request,

	.queue		= udc_queue,
	.dequeue	= udc_dequeue,

	.set_halt	= udc_set_halt,
	/* fifo ops not implemented */
};

/*-------------------------------------------------------------------------*/

/* Get frame counter (not implemented) */
static int udc_get_frame(struct usb_gadget *gadget)
{
	return -EOPNOTSUPP;
}

/* Remote wakeup gadget interface */
static int udc_wakeup(struct usb_gadget *gadget)
{
	struct udc		*dev;

	if (!gadget)
		return -EINVAL;
	dev = container_of(gadget, struct udc, gadget);
	udc_remote_wakeup(dev);

	return 0;
}

static int amd5536_start(struct usb_gadget_driver *driver,
		int (*bind)(struct usb_gadget *));
static int amd5536_stop(struct usb_gadget_driver *driver);
/* gadget operations */
static const struct usb_gadget_ops udc_ops = {
	.wakeup		= udc_wakeup,
	.get_frame	= udc_get_frame,
	.start		= amd5536_start,
	.stop		= amd5536_stop,
};

/* Setups endpoint parameters, adds endpoints to linked list */
static void make_ep_lists(struct udc *dev)
{
	/* make gadget ep lists */
	INIT_LIST_HEAD(&dev->gadget.ep_list);
	list_add_tail(&dev->ep[UDC_EPIN_STATUS_IX].ep.ep_list,
						&dev->gadget.ep_list);
	list_add_tail(&dev->ep[UDC_EPIN_IX].ep.ep_list,
						&dev->gadget.ep_list);
	list_add_tail(&dev->ep[UDC_EPOUT_IX].ep.ep_list,
						&dev->gadget.ep_list);

	/* fifo config */
	dev->ep[UDC_EPIN_STATUS_IX].fifo_depth = UDC_EPIN_SMALLINT_BUFF_SIZE;
	if (dev->gadget.speed == USB_SPEED_FULL)
		dev->ep[UDC_EPIN_IX].fifo_depth = UDC_FS_EPIN_BUFF_SIZE;
	else if (dev->gadget.speed == USB_SPEED_HIGH)
		dev->ep[UDC_EPIN_IX].fifo_depth = hs_tx_buf;
	dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE;
}

/* init registers at driver load time */
static int startup_registers(struct udc *dev)
{
	u32 tmp;

	/* init controller by soft reset */
	udc_soft_reset(dev);

	/* mask not needed interrupts */
	udc_mask_unused_interrupts(dev);

	/* put into initial config */
	udc_basic_init(dev);
	/* link up all endpoints */
	udc_setup_endpoints(dev);

	/* program speed */
	tmp = readl(&dev->regs->cfg);
	if (use_fullspeed)
		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD);
	else
		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD);
	writel(tmp, &dev->regs->cfg);

	return 0;
}

/* Inits UDC context */
static void udc_basic_init(struct udc *dev)
{
	u32	tmp;

	DBG(dev, "udc_basic_init()\n");

	dev->gadget.speed = USB_SPEED_UNKNOWN;

	/* stop RDE timer */
	if (timer_pending(&udc_timer)) {
		set_rde = 0;
		mod_timer(&udc_timer, jiffies - 1);
	}
	/* stop poll stall timer */
	if (timer_pending(&udc_pollstall_timer))
		mod_timer(&udc_pollstall_timer, jiffies - 1);
	/* disable DMA */
	tmp = readl(&dev->regs->ctl);
	tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE);
	tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_TDE);
	writel(tmp, &dev->regs->ctl);

	/* enable dynamic CSR programming */
	tmp = readl(&dev->regs->cfg);
	tmp |= AMD_BIT(UDC_DEVCFG_CSR_PRG);
	/* set self powered */
	tmp |= AMD_BIT(UDC_DEVCFG_SP);
	/* set remote wakeupable */
	tmp |= AMD_BIT(UDC_DEVCFG_RWKP);
	writel(tmp, &dev->regs->cfg);

	make_ep_lists(dev);

	dev->data_ep_enabled = 0;
	dev->data_ep_queued = 0;
}

/* Sets initial endpoint parameters */
static void udc_setup_endpoints(struct udc *dev)
{
	struct udc_ep	*ep;
	u32	tmp;
	u32	reg;

	DBG(dev, "udc_setup_endpoints()\n");

	/* read enum speed */
	tmp = readl(&dev->regs->sts);
	tmp = AMD_GETBITS(tmp, UDC_DEVSTS_ENUM_SPEED);
	if (tmp == UDC_DEVSTS_ENUM_SPEED_HIGH)
		dev->gadget.speed = USB_SPEED_HIGH;
	else if (tmp == UDC_DEVSTS_ENUM_SPEED_FULL)
		dev->gadget.speed = USB_SPEED_FULL;

	/* set basic ep parameters */
	for (tmp = 0; tmp < UDC_EP_NUM; tmp++) {
		ep = &dev->ep[tmp];
		ep->dev = dev;
		ep->ep.name = ep_string[tmp];
		ep->num = tmp;
		/* txfifo size is calculated at enable time */
		ep->txfifo = dev->txfifo;

		/* fifo size */
		if (tmp < UDC_EPIN_NUM) {
			ep->fifo_depth = UDC_TXFIFO_SIZE;
			ep->in = 1;
		} else {
			ep->fifo_depth = UDC_RXFIFO_SIZE;
			ep->in = 0;

		}
		ep->regs = &dev->ep_regs[tmp];
		/*
		 * ep will be reset only if ep was not enabled before to avoid
		 * disabling ep interrupts when ENUM interrupt occurs but ep is
		 * not enabled by gadget driver
		 */
		if (!ep->desc)
			ep_init(dev->regs, ep);

		if (use_dma) {
			/*
			 * ep->dma is not really used, just to indicate that
			 * DMA is active: remove this
			 * dma regs = dev control regs
			 */
			ep->dma = &dev->regs->ctl;

			/* nak OUT endpoints until enable - not for ep0 */
			if (tmp != UDC_EP0IN_IX && tmp != UDC_EP0OUT_IX
						&& tmp > UDC_EPIN_NUM) {
				/* set NAK */
				reg = readl(&dev->ep[tmp].regs->ctl);
				reg |= AMD_BIT(UDC_EPCTL_SNAK);
				writel(reg, &dev->ep[tmp].regs->ctl);
				dev->ep[tmp].naking = 1;

			}
		}
	}
	/* EP0 max packet */
	if (dev->gadget.speed == USB_SPEED_FULL) {
		dev->ep[UDC_EP0IN_IX].ep.maxpacket = UDC_FS_EP0IN_MAX_PKT_SIZE;
		dev->ep[UDC_EP0OUT_IX].ep.maxpacket =
						UDC_FS_EP0OUT_MAX_PKT_SIZE;
	} else if (dev->gadget.speed == USB_SPEED_HIGH) {
		dev->ep[UDC_EP0IN_IX].ep.maxpacket = UDC_EP0IN_MAX_PKT_SIZE;
		dev->ep[UDC_EP0OUT_IX].ep.maxpacket = UDC_EP0OUT_MAX_PKT_SIZE;
	}

	/*
	 * with suspend bug workaround, ep0 params for gadget driver
	 * are set at gadget driver bind() call
	 */
	dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IX].ep;
	dev->ep[UDC_EP0IN_IX].halted = 0;
	INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);

	/* init cfg/alt/int */
	dev->cur_config = 0;
	dev->cur_intf = 0;
	dev->cur_alt = 0;
}

/* Bringup after Connect event, initial bringup to be ready for ep0 events */
static void usb_connect(struct udc *dev)
{

	dev_info(&dev->pdev->dev, "USB Connect\n");

	dev->connected = 1;

	/* put into initial config */
	udc_basic_init(dev);

	/* enable device setup interrupts */
	udc_enable_dev_setup_interrupts(dev);
}

/*
 * Calls gadget with disconnect event and resets the UDC and makes
 * initial bringup to be ready for ep0 events
 */
static void usb_disconnect(struct udc *dev)
{

	dev_info(&dev->pdev->dev, "USB Disconnect\n");

	dev->connected = 0;

	/* mask interrupts */
	udc_mask_unused_interrupts(dev);

	/* REVISIT there doesn't seem to be a point to having this
	 * talk to a tasklet ... do it directly, we already hold
	 * the spinlock needed to process the disconnect.
	 */

	tasklet_schedule(&disconnect_tasklet);
}

/* Tasklet for disconnect to be outside of interrupt context */
static void udc_tasklet_disconnect(unsigned long par)
{
	struct udc *dev = (struct udc *)(*((struct udc **) par));
	u32 tmp;

	DBG(dev, "Tasklet disconnect\n");
	spin_lock_irq(&dev->lock);

	if (dev->driver) {
		spin_unlock(&dev->lock);
		dev->driver->disconnect(&dev->gadget);
		spin_lock(&dev->lock);

		/* empty queues */
		for (tmp = 0; tmp < UDC_EP_NUM; tmp++)
			empty_req_queue(&dev->ep[tmp]);

	}

	/* disable ep0 */
	ep_init(dev->regs,
			&dev->ep[UDC_EP0IN_IX]);


	if (!soft_reset_occured) {
		/* init controller by soft reset */
		udc_soft_reset(dev);
		soft_reset_occured++;
	}

	/* re-enable dev interrupts */
	udc_enable_dev_setup_interrupts(dev);
	/* back to full speed ? */
	if (use_fullspeed) {
		tmp = readl(&dev->regs->cfg);
		tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD);
		writel(tmp, &dev->regs->cfg);
	}

	spin_unlock_irq(&dev->lock);
}

/* Reset the UDC core */
static void udc_soft_reset(struct udc *dev)
{
	unsigned long	flags;

	DBG(dev, "Soft reset\n");
	/*
	 * reset possible waiting interrupts, because int.
	 * status is lost after soft reset,
	 * ep int. status reset
	 */
	writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqsts);
	/* device int. status reset */
	writel(UDC_DEV_MSK_DISABLE, &dev->regs->irqsts);

	spin_lock_irqsave(&udc_irq_spinlock, flags);
	writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg);
	readl(&dev->regs->cfg);
	spin_unlock_irqrestore(&udc_irq_spinlock, flags);

}

/* RDE timer callback to set RDE bit */
static void udc_timer_function(unsigned long v)
{
	u32 tmp;

	spin_lock_irq(&udc_irq_spinlock);

	if (set_rde > 0) {
		/*
		 * open the fifo if fifo was filled on last timer call
		 * conditionally
		 */
		if (set_rde > 1) {
			/* set RDE to receive setup data */
			tmp = readl(&udc->regs->ctl);
			tmp |= AMD_BIT(UDC_DEVCTL_RDE);
			writel(tmp, &udc->regs->ctl);
			set_rde = -1;
		} else if (readl(&udc->regs->sts)
				& AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) {
			/*
			 * if fifo empty setup polling, do not just
			 * open the fifo
			 */
			udc_timer.expires = jiffies + HZ/UDC_RDE_TIMER_DIV;
			if (!stop_timer)
				add_timer(&udc_timer);
		} else {
			/*
			 * fifo contains data now, setup timer for opening
			 * the fifo when timer expires to be able to receive
			 * setup packets, when data packets gets queued by
			 * gadget layer then timer will forced to expire with
			 * set_rde=0 (RDE is set in udc_queue())
			 */
			set_rde++;
			/* debug: lhadmot_timer_start = 221070 */
			udc_timer.expires = jiffies + HZ*UDC_RDE_TIMER_SECONDS;
			if (!stop_timer)
				add_timer(&udc_timer);
		}

	} else
		set_rde = -1; /* RDE was set by udc_queue() */
	spin_unlock_irq(&udc_irq_spinlock);
	if (stop_timer)
		complete(&on_exit);

}

/* Handle halt state, used in stall poll timer */
static void udc_handle_halt_state(struct udc_ep *ep)
{
	u32 tmp;
	/* set stall as long not halted */
	if (ep->halted == 1) {
		tmp = readl(&ep->regs->ctl);
		/* STALL cleared ? */
		if (!(tmp & AMD_BIT(UDC_EPCTL_S))) {
			/*
			 * FIXME: MSC spec requires that stall remains
			 * even on receivng of CLEAR_FEATURE HALT. So
			 * we would set STALL again here to be compliant.
			 * But with current mass storage drivers this does
			 * not work (would produce endless host retries).
			 * So we clear halt on CLEAR_FEATURE.
			 *
			DBG(ep->dev, "ep %d: set STALL again\n", ep->num);
			tmp |= AMD_BIT(UDC_EPCTL_S);
			writel(tmp, &ep->regs->ctl);*/

			/* clear NAK by writing CNAK */
			tmp |= AMD_BIT(UDC_EPCTL_CNAK);
			writel(tmp, &ep->regs->ctl);
			ep->halted = 0;
			UDC_QUEUE_CNAK(ep, ep->num);
		}
	}
}

/* Stall timer callback to poll S bit and set it again after */
static void udc_pollstall_timer_function(unsigned long v)
{
	struct udc_ep *ep;
	int halted = 0;

	spin_lock_irq(&udc_stall_spinlock);
	/*
	 * only one IN and OUT endpoints are handled
	 * IN poll stall
	 */
	ep = &udc->ep[UDC_EPIN_IX];
	udc_handle_halt_state(ep);
	if (ep->halted)
		halted = 1;
	/* OUT poll stall */
	ep = &udc->ep[UDC_EPOUT_IX];
	udc_handle_halt_state(ep);
	if (ep->halted)
		halted = 1;

	/* setup timer again when still halted */
	if (!stop_pollstall_timer && halted) {
		udc_pollstall_timer.expires = jiffies +
					HZ * UDC_POLLSTALL_TIMER_USECONDS
					/ (1000 * 1000);
		add_timer(&udc_pollstall_timer);
	}
	spin_unlock_irq(&udc_stall_spinlock);

	if (stop_pollstall_timer)
		complete(&on_pollstall_exit);
}

/* Inits endpoint 0 so that SETUP packets are processed */
static void activate_control_endpoints(struct udc *dev)
{
	u32 tmp;

	DBG(dev, "activate_control_endpoints\n");

	/* flush fifo */
	tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl);
	tmp |= AMD_BIT(UDC_EPCTL_F);
	writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl);

	/* set ep0 directions */
	dev->ep[UDC_EP0IN_IX].in = 1;
	dev->ep[UDC_EP0OUT_IX].in = 0;

	/* set buffer size (tx fifo entries) of EP0_IN */
	tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->bufin_framenum);
	if (dev->gadget.speed == USB_SPEED_FULL)
		tmp = AMD_ADDBITS(tmp, UDC_FS_EPIN0_BUFF_SIZE,
					UDC_EPIN_BUFF_SIZE);
	else if (dev->gadget.speed == USB_SPEED_HIGH)
		tmp = AMD_ADDBITS(tmp, UDC_EPIN0_BUFF_SIZE,
					UDC_EPIN_BUFF_SIZE);
	writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->bufin_framenum);

	/* set max packet size of EP0_IN */
	tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->bufout_maxpkt);
	if (dev->gadget.speed == USB_SPEED_FULL)
		tmp = AMD_ADDBITS(tmp, UDC_FS_EP0IN_MAX_PKT_SIZE,
					UDC_EP_MAX_PKT_SIZE);
	else if (dev->gadget.speed == USB_SPEED_HIGH)
		tmp = AMD_ADDBITS(tmp, UDC_EP0IN_MAX_PKT_SIZE,
				UDC_EP_MAX_PKT_SIZE);
	writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->bufout_maxpkt);

	/* set max packet size of EP0_OUT */
	tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->bufout_maxpkt);
	if (dev->gadget.speed == USB_SPEED_FULL)
		tmp = AMD_ADDBITS(tmp, UDC_FS_EP0OUT_MAX_PKT_SIZE,
					UDC_EP_MAX_PKT_SIZE);
	else if (dev->gadget.speed == USB_SPEED_HIGH)
		tmp = AMD_ADDBITS(tmp, UDC_EP0OUT_MAX_PKT_SIZE,
					UDC_EP_MAX_PKT_SIZE);
	writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->bufout_maxpkt);

	/* set max packet size of EP0 in UDC CSR */
	tmp = readl(&dev->csr->ne[0]);
	if (dev->gadget.speed == USB_SPEED_FULL)
		tmp = AMD_ADDBITS(tmp, UDC_FS_EP0OUT_MAX_PKT_SIZE,
					UDC_CSR_NE_MAX_PKT);
	else if (dev->gadget.speed == USB_SPEED_HIGH)
		tmp = AMD_ADDBITS(tmp, UDC_EP0OUT_MAX_PKT_SIZE,
					UDC_CSR_NE_MAX_PKT);
	writel(tmp, &dev->csr->ne[0]);

	if (use_dma) {
		dev->ep[UDC_EP0OUT_IX].td->status |=
			AMD_BIT(UDC_DMA_OUT_STS_L);
		/* write dma desc address */
		writel(dev->ep[UDC_EP0OUT_IX].td_stp_dma,
			&dev->ep[UDC_EP0OUT_IX].regs->subptr);
		writel(dev->ep[UDC_EP0OUT_IX].td_phys,
			&dev->ep[UDC_EP0OUT_IX].regs->desptr);
		/* stop RDE timer */
		if (timer_pending(&udc_timer)) {
			set_rde = 0;
			mod_timer(&udc_timer, jiffies - 1);
		}
		/* stop pollstall timer */
		if (timer_pending(&udc_pollstall_timer))
			mod_timer(&udc_pollstall_timer, jiffies - 1);
		/* enable DMA */
		tmp = readl(&dev->regs->ctl);
		tmp |= AMD_BIT(UDC_DEVCTL_MODE)
				| AMD_BIT(UDC_DEVCTL_RDE)
				| AMD_BIT(UDC_DEVCTL_TDE);
		if (use_dma_bufferfill_mode)
			tmp |= AMD_BIT(UDC_DEVCTL_BF);
		else if (use_dma_ppb_du)
			tmp |= AMD_BIT(UDC_DEVCTL_DU);
		writel(tmp, &dev->regs->ctl);
	}

	/* clear NAK by writing CNAK for EP0IN */
	tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl);
	tmp |= AMD_BIT(UDC_EPCTL_CNAK);
	writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl);
	dev->ep[UDC_EP0IN_IX].naking = 0;
	UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], UDC_EP0IN_IX);

	/* clear NAK by writing CNAK for EP0OUT */
	tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl);
	tmp |= AMD_BIT(UDC_EPCTL_CNAK);
	writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->ctl);
	dev->ep[UDC_EP0OUT_IX].naking = 0;
	UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], UDC_EP0OUT_IX);
}

/* Make endpoint 0 ready for control traffic */
static int setup_ep0(struct udc *dev)
{
	activate_control_endpoints(dev);
	/* enable ep0 interrupts */
	udc_enable_ep0_interrupts(dev);
	/* enable device setup interrupts */
	udc_enable_dev_setup_interrupts(dev);

	return 0;
}

/* Called by gadget driver to register itself */
static int amd5536_start(struct usb_gadget_driver *driver,
		int (*bind)(struct usb_gadget *))
{
	struct udc		*dev = udc;
	int			retval;
	u32 tmp;

	if (!driver || !bind || !driver->setup
			|| driver->max_speed < USB_SPEED_HIGH)
		return -EINVAL;
	if (!dev)
		return -ENODEV;
	if (dev->driver)
		return -EBUSY;

	driver->driver.bus = NULL;
	dev->driver = driver;
	dev->gadget.dev.driver = &driver->driver;

	retval = bind(&dev->gadget);

	/* Some gadget drivers use both ep0 directions.
	 * NOTE: to gadget driver, ep0 is just one endpoint...
	 */
	dev->ep[UDC_EP0OUT_IX].ep.driver_data =
		dev->ep[UDC_EP0IN_IX].ep.driver_data;

	if (retval) {
		DBG(dev, "binding to %s returning %d\n",
				driver->driver.name, retval);
		dev->driver = NULL;
		dev->gadget.dev.driver = NULL;
		return retval;
	}

	/* get ready for ep0 traffic */
	setup_ep0(dev);

	/* clear SD */
	tmp = readl(&dev->regs->ctl);
	tmp = tmp & AMD_CLEAR_BIT(UDC_DEVCTL_SD);
	writel(tmp, &dev->regs->ctl);

	usb_connect(dev);

	return 0;
}

/* shutdown requests and disconnect from gadget */
static void
shutdown(struct udc *dev, struct usb_gadget_driver *driver)
__releases(dev->lock)
__acquires(dev->lock)
{
	int tmp;

	if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
		spin_unlock(&dev->lock);
		driver->disconnect(&dev->gadget);
		spin_lock(&dev->lock);
	}

	/* empty queues and init hardware */
	udc_basic_init(dev);
	for (tmp = 0; tmp < UDC_EP_NUM; tmp++)
		empty_req_queue(&dev->ep[tmp]);

	udc_setup_endpoints(dev);
}

/* Called by gadget driver to unregister itself */
static int amd5536_stop(struct usb_gadget_driver *driver)
{
	struct udc	*dev = udc;
	unsigned long	flags;
	u32 tmp;

	if (!dev)
		return -ENODEV;
	if (!driver || driver != dev->driver || !driver->unbind)
		return -EINVAL;

	spin_lock_irqsave(&dev->lock, flags);
	udc_mask_unused_interrupts(dev);
	shutdown(dev, driver);
	spin_unlock_irqrestore(&dev->lock, flags);

	driver->unbind(&dev->gadget);
	dev->gadget.dev.driver = NULL;
	dev->driver = NULL;

	/* set SD */
	tmp = readl(&dev->regs->ctl);
	tmp |= AMD_BIT(UDC_DEVCTL_SD);
	writel(tmp, &dev->regs->ctl);


	DBG(dev, "%s: unregistered\n", driver->driver.name);

	return 0;
}

/* Clear pending NAK bits */
static void udc_process_cnak_queue(struct udc *dev)
{
	u32 tmp;
	u32 reg;

	/* check epin's */
	DBG(dev, "CNAK pending queue processing\n");
	for (tmp = 0; tmp < UDC_EPIN_NUM_USED; tmp++) {
		if (cnak_pending & (1 << tmp)) {
			DBG(dev, "CNAK pending for ep%d\n", tmp);
			/* clear NAK by writing CNAK */
			reg = readl(&dev->ep[tmp].regs->ctl);
			reg |= AMD_BIT(UDC_EPCTL_CNAK);
			writel(reg, &dev->ep[tmp].regs->ctl);
			dev->ep[tmp].naking = 0;
			UDC_QUEUE_CNAK(&dev->ep[tmp], dev->ep[tmp].num);
		}
	}
	/* ...	and ep0out */
	if (cnak_pending & (1 << UDC_EP0OUT_IX)) {
		DBG(dev, "CNAK pending for ep%d\n", UDC_EP0OUT_IX);
		/* clear NAK by writing CNAK */
		reg = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl);
		reg |= AMD_BIT(UDC_EPCTL_CNAK);
		writel(reg, &dev->ep[UDC_EP0OUT_IX].regs->ctl);
		dev->ep[UDC_EP0OUT_IX].naking = 0;
		UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX],
				dev->ep[UDC_EP0OUT_IX].num);
	}
}

/* Enabling RX DMA after setup packet */
static void udc_ep0_set_rde(struct udc *dev)
{
	if (use_dma) {
		/*
		 * only enable RXDMA when no data endpoint enabled
		 * or data is queued
		 */
		if (!dev->data_ep_enabled || dev->data_ep_queued) {
			udc_set_rde(dev);
		} else {
			/*
			 * setup timer for enabling RDE (to not enable
			 * RXFIFO DMA for data endpoints to early)
			 */
			if (set_rde != 0 && !timer_pending(&udc_timer)) {
				udc_timer.expires =
					jiffies + HZ/UDC_RDE_TIMER_DIV;
				set_rde = 1;
				if (!stop_timer)
					add_timer(&udc_timer);
			}
		}
	}
}


/* Interrupt handler for data OUT traffic */
static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix)
{
	irqreturn_t		ret_val = IRQ_NONE;
	u32			tmp;
	struct udc_ep		*ep;
	struct udc_request	*req;
	unsigned int		count;
	struct udc_data_dma	*td = NULL;
	unsigned		dma_done;

	VDBG(dev, "ep%d irq\n", ep_ix);
	ep = &dev->ep[ep_ix];

	tmp = readl(&ep->regs->sts);
	if (use_dma) {
		/* BNA event ? */
		if (tmp & AMD_BIT(UDC_EPSTS_BNA)) {
			DBG(dev, "BNA ep%dout occurred - DESPTR = %x\n",
					ep->num, readl(&ep->regs->desptr));
			/* clear BNA */
			writel(tmp | AMD_BIT(UDC_EPSTS_BNA), &ep->regs->sts);
			if (!ep->cancel_transfer)
				ep->bna_occurred = 1;
			else
				ep->cancel_transfer = 0;
			ret_val = IRQ_HANDLED;
			goto finished;
		}
	}
	/* HE event ? */
	if (tmp & AMD_BIT(UDC_EPSTS_HE)) {
		dev_err(&dev->pdev->dev, "HE ep%dout occurred\n", ep->num);

		/* clear HE */
		writel(tmp | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts);
		ret_val = IRQ_HANDLED;
		goto finished;
	}

	if (!list_empty(&ep->queue)) {

		/* next request */
		req = list_entry(ep->queue.next,
			struct udc_request, queue);
	} else {
		req = NULL;
		udc_rxfifo_pending = 1;
	}
	VDBG(dev, "req = %p\n", req);
	/* fifo mode */
	if (!use_dma) {

		/* read fifo */
		if (req && udc_rxfifo_read(ep, req)) {
			ret_val = IRQ_HANDLED;

			/* finish */
			complete_req(ep, req, 0);
			/* next request */
			if (!list_empty(&ep->queue) && !ep->halted) {
				req = list_entry(ep->queue.next,
					struct udc_request, queue);
			} else
				req = NULL;
		}

	/* DMA */
	} else if (!ep->cancel_transfer && req != NULL) {
		ret_val = IRQ_HANDLED;

		/* check for DMA done */
		if (!use_dma_ppb) {
			dma_done = AMD_GETBITS(req->td_data->status,
						UDC_DMA_OUT_STS_BS);
		/* packet per buffer mode - rx bytes */
		} else {
			/*
			 * if BNA occurred then recover desc. from
			 * BNA dummy desc.
			 */
			if (ep->bna_occurred) {
				VDBG(dev, "Recover desc. from BNA dummy\n");
				memcpy(req->td_data, ep->bna_dummy_req->td_data,
						sizeof(struct udc_data_dma));
				ep->bna_occurred = 0;
				udc_init_bna_dummy(ep->req);
			}
			td = udc_get_last_dma_desc(req);
			dma_done = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_BS);
		}
		if (dma_done == UDC_DMA_OUT_STS_BS_DMA_DONE) {
			/* buffer fill mode - rx bytes */
			if (!use_dma_ppb) {
				/* received number bytes */
				count = AMD_GETBITS(req->td_data->status,
						UDC_DMA_OUT_STS_RXBYTES);
				VDBG(dev, "rx bytes=%u\n", count);
			/* packet per buffer mode - rx bytes */
			} else {
				VDBG(dev, "req->td_data=%p\n", req->td_data);
				VDBG(dev, "last desc = %p\n", td);
				/* received number bytes */
				if (use_dma_ppb_du) {
					/* every desc. counts bytes */
					count = udc_get_ppbdu_rxbytes(req);
				} else {
					/* last desc. counts bytes */
					count = AMD_GETBITS(td->status,
						UDC_DMA_OUT_STS_RXBYTES);
					if (!count && req->req.length
						== UDC_DMA_MAXPACKET) {
						/*
						 * on 64k packets the RXBYTES
						 * field is zero
						 */
						count = UDC_DMA_MAXPACKET;
					}
				}
				VDBG(dev, "last desc rx bytes=%u\n", count);
			}

			tmp = req->req.length - req->req.actual;
			if (count > tmp) {
				if ((tmp % ep->ep.maxpacket) != 0) {
					DBG(dev, "%s: rx %db, space=%db\n",
						ep->ep.name, count, tmp);
					req->req.status = -EOVERFLOW;
				}
				count = tmp;
			}
			req->req.actual += count;
			req->dma_going = 0;
			/* complete request */
			complete_req(ep, req, 0);

			/* next request */
			if (!list_empty(&ep->queue) && !ep->halted) {
				req = list_entry(ep->queue.next,
					struct udc_request,
					queue);
				/*
				 * DMA may be already started by udc_queue()
				 * called by gadget drivers completion
				 * routine. This happens when queue
				 * holds one request only.
				 */
				if (req->dma_going == 0) {
					/* next dma */
					if (prep_dma(ep, req, GFP_ATOMIC) != 0)
						goto finished;
					/* write desc pointer */
					writel(req->td_phys,
						&ep->regs->desptr);
					req->dma_going = 1;
					/* enable DMA */
					udc_set_rde(dev);
				}
			} else {
				/*
				 * implant BNA dummy descriptor to allow
				 * RXFIFO opening by RDE
				 */
				if (ep->bna_dummy_req) {
					/* write desc pointer */
					writel(ep->bna_dummy_req->td_phys,
						&ep->regs->desptr);
					ep->bna_occurred = 0;
				}

				/*
				 * schedule timer for setting RDE if queue
				 * remains empty to allow ep0 packets pass
				 * through
				 */
				if (set_rde != 0
						&& !timer_pending(&udc_timer)) {
					udc_timer.expires =
						jiffies
						+ HZ*UDC_RDE_TIMER_SECONDS;
					set_rde = 1;
					if (!stop_timer)
						add_timer(&udc_timer);
				}
				if (ep->num != UDC_EP0OUT_IX)
					dev->data_ep_queued = 0;
			}

		} else {
			/*
			* RX DMA must be reenabled for each desc in PPBDU mode
			* and must be enabled for PPBNDU mode in case of BNA
			*/
			udc_set_rde(dev);
		}

	} else if (ep->cancel_transfer) {
		ret_val = IRQ_HANDLED;
		ep->cancel_transfer = 0;
	}

	/* check pending CNAKS */
	if (cnak_pending) {
		/* CNAk processing when rxfifo empty only */
		if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY))
			udc_process_cnak_queue(dev);
	}

	/* clear OUT bits in ep status */
	writel(UDC_EPSTS_OUT_CLEAR, &ep->regs->sts);
finished:
	return ret_val;
}

/* Interrupt handler for data IN traffic */
static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix)
{
	irqreturn_t ret_val = IRQ_NONE;
	u32 tmp;
	u32 epsts;
	struct udc_ep *ep;
	struct udc_request *req;
	struct udc_data_dma *td;
	unsigned dma_done;
	unsigned len;

	ep = &dev->ep[ep_ix];

	epsts = readl(&ep->regs->sts);
	if (use_dma) {
		/* BNA ? */
		if (epsts & AMD_BIT(UDC_EPSTS_BNA)) {
			dev_err(&dev->pdev->dev,
				"BNA ep%din occurred - DESPTR = %08lx\n",
				ep->num,
				(unsigned long) readl(&ep->regs->desptr));

			/* clear BNA */
			writel(epsts, &ep->regs->sts);
			ret_val = IRQ_HANDLED;
			goto finished;
		}
	}
	/* HE event ? */
	if (epsts & AMD_BIT(UDC_EPSTS_HE)) {
		dev_err(&dev->pdev->dev,
			"HE ep%dn occurred - DESPTR = %08lx\n",
			ep->num, (unsigned long) readl(&ep->regs->desptr));

		/* clear HE */
		writel(epsts | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts);
		ret_val = IRQ_HANDLED;
		goto finished;
	}

	/* DMA completion */
	if (epsts & AMD_BIT(UDC_EPSTS_TDC)) {
		VDBG(dev, "TDC set- completion\n");
		ret_val = IRQ_HANDLED;
		if (!ep->cancel_transfer && !list_empty(&ep->queue)) {
			req = list_entry(ep->queue.next,
					struct udc_request, queue);
			/*
			 * length bytes transferred
			 * check dma done of last desc. in PPBDU mode
			 */
			if (use_dma_ppb_du) {
				td = udc_get_last_dma_desc(req);
				if (td) {
					dma_done =
						AMD_GETBITS(td->status,
						UDC_DMA_IN_STS_BS);
					/* don't care DMA done */
					req->req.actual = req->req.length;
				}
			} else {
				/* assume all bytes transferred */
				req->req.actual = req->req.length;
			}

			if (req->req.actual == req->req.length) {
				/* complete req */
				complete_req(ep, req, 0);
				req->dma_going = 0;
				/* further request available ? */
				if (list_empty(&ep->queue)) {
					/* disable interrupt */
					tmp = readl(&dev->regs->ep_irqmsk);
					tmp |= AMD_BIT(ep->num);
					writel(tmp, &dev->regs->ep_irqmsk);
				}
			}
		}
		ep->cancel_transfer = 0;

	}
	/*
	 * status reg has IN bit set and TDC not set (if TDC was handled,
	 * IN must not be handled (UDC defect) ?
	 */
	if ((epsts & AMD_BIT(UDC_EPSTS_IN))
			&& !(epsts & AMD_BIT(UDC_EPSTS_TDC))) {
		ret_val = IRQ_HANDLED;
		if (!list_empty(&ep->queue)) {
			/* next request */
			req = list_entry(ep->queue.next,
					struct udc_request, queue);
			/* FIFO mode */
			if (!use_dma) {
				/* write fifo */
				udc_txfifo_write(ep, &req->req);
				len = req->req.length - req->req.actual;
				if (len > ep->ep.maxpacket)
					len = ep->ep.maxpacket;
				req->req.actual += len;
				if (req->req.actual == req->req.length
					|| (len != ep->ep.maxpacket)) {
					/* complete req */
					complete_req(ep, req, 0);
				}
			/* DMA */
			} else if (req && !req->dma_going) {
				VDBG(dev, "IN DMA : req=%p req->td_data=%p\n",
					req, req->td_data);
				if (req->td_data) {

					req->dma_going = 1;

					/*
					 * unset L bit of first desc.
					 * for chain
					 */
					if (use_dma_ppb && req->req.length >
							ep->ep.maxpacket) {
						req->td_data->status &=
							AMD_CLEAR_BIT(
							UDC_DMA_IN_STS_L);
					}

					/* write desc pointer */
					writel(req->td_phys, &ep->regs->desptr);

					/* set HOST READY */
					req->td_data->status =
						AMD_ADDBITS(
						req->td_data->status,
						UDC_DMA_IN_STS_BS_HOST_READY,
						UDC_DMA_IN_STS_BS);

					/* set poll demand bit */
					tmp = readl(&ep->regs->ctl);
					tmp |= AMD_BIT(UDC_EPCTL_P);
					writel(tmp, &ep->regs->ctl);
				}
			}

		} else if (!use_dma && ep->in) {
			/* disable interrupt */
			tmp = readl(
				&dev->regs->ep_irqmsk);
			tmp |= AMD_BIT(ep->num);
			writel(tmp,
				&dev->regs->ep_irqmsk);
		}
	}
	/* clear status bits */
	writel(epsts, &ep->regs->sts);

finished:
	return ret_val;

}

/* Interrupt handler for Control OUT traffic */
static irqreturn_t udc_control_out_isr(struct udc *dev)
__releases(dev->lock)
__acquires(dev->lock)
{
	irqreturn_t ret_val = IRQ_NONE;
	u32 tmp;
	int setup_supported;
	u32 count;
	int set = 0;
	struct udc_ep	*ep;
	struct udc_ep	*ep_tmp;

	ep = &dev->ep[UDC_EP0OUT_IX];

	/* clear irq */
	writel(AMD_BIT(UDC_EPINT_OUT_EP0), &dev->regs->ep_irqsts);

	tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->sts);
	/* check BNA and clear if set */
	if (tmp & AMD_BIT(UDC_EPSTS_BNA)) {
		VDBG(dev, "ep0: BNA set\n");
		writel(AMD_BIT(UDC_EPSTS_BNA),
			&dev->ep[UDC_EP0OUT_IX].regs->sts);
		ep->bna_occurred = 1;
		ret_val = IRQ_HANDLED;
		goto finished;
	}

	/* type of data: SETUP or DATA 0 bytes */
	tmp = AMD_GETBITS(tmp, UDC_EPSTS_OUT);
	VDBG(dev, "data_typ = %x\n", tmp);

	/* setup data */
	if (tmp == UDC_EPSTS_OUT_SETUP) {
		ret_val = IRQ_HANDLED;

		ep->dev->stall_ep0in = 0;
		dev->waiting_zlp_ack_ep0in = 0;

		/* set NAK for EP0_IN */
		tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl);
		tmp |= AMD_BIT(UDC_EPCTL_SNAK);
		writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl);
		dev->ep[UDC_EP0IN_IX].naking = 1;
		/* get setup data */
		if (use_dma) {

			/* clear OUT bits in ep status */
			writel(UDC_EPSTS_OUT_CLEAR,
				&dev->ep[UDC_EP0OUT_IX].regs->sts);

			setup_data.data[0] =
				dev->ep[UDC_EP0OUT_IX].td_stp->data12;
			setup_data.data[1] =
				dev->ep[UDC_EP0OUT_IX].td_stp->data34;
			/* set HOST READY */
			dev->ep[UDC_EP0OUT_IX].td_stp->status =
					UDC_DMA_STP_STS_BS_HOST_READY;
		} else {
			/* read fifo */
			udc_rxfifo_read_dwords(dev, setup_data.data, 2);
		}

		/* determine direction of control data */
		if ((setup_data.request.bRequestType & USB_DIR_IN) != 0) {
			dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IX].ep;
			/* enable RDE */
			udc_ep0_set_rde(dev);
			set = 0;
		} else {
			dev->gadget.ep0 = &dev->ep[UDC_EP0OUT_IX].ep;
			/*
			 * implant BNA dummy descriptor to allow RXFIFO opening
			 * by RDE
			 */
			if (ep->bna_dummy_req) {
				/* write desc pointer */
				writel(ep->bna_dummy_req->td_phys,
					&dev->ep[UDC_EP0OUT_IX].regs->desptr);
				ep->bna_occurred = 0;
			}

			set = 1;
			dev->ep[UDC_EP0OUT_IX].naking = 1;
			/*
			 * setup timer for enabling RDE (to not enable
			 * RXFIFO DMA for data to early)
			 */
			set_rde = 1;
			if (!timer_pending(&udc_timer)) {
				udc_timer.expires = jiffies +
							HZ/UDC_RDE_TIMER_DIV;
				if (!stop_timer)
					add_timer(&udc_timer);
			}
		}

		/*
		 * mass storage reset must be processed here because
		 * next packet may be a CLEAR_FEATURE HALT which would not
		 * clear the stall bit when no STALL handshake was received
		 * before (autostall can cause this)
		 */
		if (setup_data.data[0] == UDC_MSCRES_DWORD0
				&& setup_data.data[1] == UDC_MSCRES_DWORD1) {
			DBG(dev, "MSC Reset\n");
			/*
			 * clear stall bits
			 * only one IN and OUT endpoints are handled
			 */
			ep_tmp = &udc->ep[UDC_EPIN_IX];
			udc_set_halt(&ep_tmp->ep, 0);
			ep_tmp = &udc->ep[UDC_EPOUT_IX];
			udc_set_halt(&ep_tmp->ep, 0);
		}

		/* call gadget with setup data received */
		spin_unlock(&dev->lock);
		setup_supported = dev->driver->setup(&dev->gadget,
						&setup_data.request);
		spin_lock(&dev->lock);

		tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl);
		/* ep0 in returns data (not zlp) on IN phase */
		if (setup_supported >= 0 && setup_supported <
				UDC_EP0IN_MAXPACKET) {
			/* clear NAK by writing CNAK in EP0_IN */
			tmp |= AMD_BIT(UDC_EPCTL_CNAK);
			writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl);
			dev->ep[UDC_EP0IN_IX].naking = 0;
			UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], UDC_EP0IN_IX);

		/* if unsupported request then stall */
		} else if (setup_supported < 0) {
			tmp |= AMD_BIT(UDC_EPCTL_S);
			writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl);
		} else
			dev->waiting_zlp_ack_ep0in = 1;


		/* clear NAK by writing CNAK in EP0_OUT */
		if (!set) {
			tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl);
			tmp |= AMD_BIT(UDC_EPCTL_CNAK);
			writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->ctl);
			dev->ep[UDC_EP0OUT_IX].naking = 0;
			UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], UDC_EP0OUT_IX);
		}

		if (!use_dma) {
			/* clear OUT bits in ep status */
			writel(UDC_EPSTS_OUT_CLEAR,
				&dev->ep[UDC_EP0OUT_IX].regs->sts);
		}

	/* data packet 0 bytes */
	} else if (tmp == UDC_EPSTS_OUT_DATA) {
		/* clear OUT bits in ep status */
		writel(UDC_EPSTS_OUT_CLEAR, &dev->ep[UDC_EP0OUT_IX].regs->sts);

		/* get setup data: only 0 packet */
		if (use_dma) {
			/* no req if 0 packet, just reactivate */
			if (list_empty(&dev->ep[UDC_EP0OUT_IX].queue)) {
				VDBG(dev, "ZLP\n");

				/* set HOST READY */
				dev->ep[UDC_EP0OUT_IX].td->status =
					AMD_ADDBITS(
					dev->ep[UDC_EP0OUT_IX].td->status,
					UDC_DMA_OUT_STS_BS_HOST_READY,
					UDC_DMA_OUT_STS_BS);
				/* enable RDE */
				udc_ep0_set_rde(dev);
				ret_val = IRQ_HANDLED;

			} else {
				/* control write */
				ret_val |= udc_data_out_isr(dev, UDC_EP0OUT_IX);
				/* re-program desc. pointer for possible ZLPs */
				writel(dev->ep[UDC_EP0OUT_IX].td_phys,
					&dev->ep[UDC_EP0OUT_IX].regs->desptr);
				/* enable RDE */
				udc_ep0_set_rde(dev);
			}
		} else {

			/* received number bytes */
			count = readl(&dev->ep[UDC_EP0OUT_IX].regs->sts);
			count = AMD_GETBITS(count, UDC_EPSTS_RX_PKT_SIZE);
			/* out data for fifo mode not working */
			count = 0;

			/* 0 packet or real data ? */
			if (count != 0) {
				ret_val |= udc_data_out_isr(dev, UDC_EP0OUT_IX);
			} else {
				/* dummy read confirm */
				readl(&dev->ep[UDC_EP0OUT_IX].regs->confirm);
				ret_val = IRQ_HANDLED;
			}
		}
	}

	/* check pending CNAKS */
	if (cnak_pending) {
		/* CNAk processing when rxfifo empty only */
		if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY))
			udc_process_cnak_queue(dev);
	}

finished:
	return ret_val;
}

/* Interrupt handler for Control IN traffic */
static irqreturn_t udc_control_in_isr(struct udc *dev)
{
	irqreturn_t ret_val = IRQ_NONE;
	u32 tmp;
	struct udc_ep *ep;
	struct udc_request *req;
	unsigned len;

	ep = &dev->ep[UDC_EP0IN_IX];

	/* clear irq */
	writel(AMD_BIT(UDC_EPINT_IN_EP0), &dev->regs->ep_irqsts);

	tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->sts);
	/* DMA completion */
	if (tmp & AMD_BIT(UDC_EPSTS_TDC)) {
		VDBG(dev, "isr: TDC clear\n");
		ret_val = IRQ_HANDLED;

		/* clear TDC bit */
		writel(AMD_BIT(UDC_EPSTS_TDC),
				&dev->ep[UDC_EP0IN_IX].regs->sts);

	/* status reg has IN bit set ? */
	} else if (tmp & AMD_BIT(UDC_EPSTS_IN)) {
		ret_val = IRQ_HANDLED;

		if (ep->dma) {
			/* clear IN bit */
			writel(AMD_BIT(UDC_EPSTS_IN),
				&dev->ep[UDC_EP0IN_IX].regs->sts);
		}
		if (dev->stall_ep0in) {
			DBG(dev, "stall ep0in\n");
			/* halt ep0in */
			tmp = readl(&ep->regs->ctl);
			tmp |= AMD_BIT(UDC_EPCTL_S);
			writel(tmp, &ep->regs->ctl);
		} else {
			if (!list_empty(&ep->queue)) {
				/* next request */
				req = list_entry(ep->queue.next,
						struct udc_request, queue);

				if (ep->dma) {
					/* write desc pointer */
					writel(req->td_phys, &ep->regs->desptr);
					/* set HOST READY */
					req->td_data->status =
						AMD_ADDBITS(
						req->td_data->status,
						UDC_DMA_STP_STS_BS_HOST_READY,
						UDC_DMA_STP_STS_BS);

					/* set poll demand bit */
					tmp =
					readl(&dev->ep[UDC_EP0IN_IX].regs->ctl);
					tmp |= AMD_BIT(UDC_EPCTL_P);
					writel(tmp,
					&dev->ep[UDC_EP0IN_IX].regs->ctl);

					/* all bytes will be transferred */
					req->req.actual = req->req.length;

					/* complete req */
					complete_req(ep, req, 0);

				} else {
					/* write fifo */
					udc_txfifo_write(ep, &req->req);

					/* lengh bytes transferred */
					len = req->req.length - req->req.actual;
					if (len > ep->ep.maxpacket)
						len = ep->ep.maxpacket;

					req->req.actual += len;
					if (req->req.actual == req->req.length
						|| (len != ep->ep.maxpacket)) {
						/* complete req */
						complete_req(ep, req, 0);
					}
				}

			}
		}
		ep->halted = 0;
		dev->stall_ep0in = 0;
		if (!ep->dma) {
			/* clear IN bit */
			writel(AMD_BIT(UDC_EPSTS_IN),
				&dev->ep[UDC_EP0IN_IX].regs->sts);
		}
	}

	return ret_val;
}


/* Interrupt handler for global device events */
static irqreturn_t udc_dev_isr(struct udc *dev, u32 dev_irq)
__releases(dev->lock)
__acquires(dev->lock)
{
	irqreturn_t ret_val = IRQ_NONE;
	u32 tmp;
	u32 cfg;
	struct udc_ep *ep;
	u16 i;
	u8 udc_csr_epix;

	/* SET_CONFIG irq ? */
	if (dev_irq & AMD_BIT(UDC_DEVINT_SC)) {
		ret_val = IRQ_HANDLED;

		/* read config value */
		tmp = readl(&dev->regs->sts);
		cfg = AMD_GETBITS(tmp, UDC_DEVSTS_CFG);
		DBG(dev, "SET_CONFIG interrupt: config=%d\n", cfg);
		dev->cur_config = cfg;
		dev->set_cfg_not_acked = 1;

		/* make usb request for gadget driver */
		memset(&setup_data, 0 , sizeof(union udc_setup_data));
		setup_data.request.bRequest = USB_REQ_SET_CONFIGURATION;
		setup_data.request.wValue = cpu_to_le16(dev->cur_config);

		/* programm the NE registers */
		for (i = 0; i < UDC_EP_NUM; i++) {
			ep = &dev->ep[i];
			if (ep->in) {

				/* ep ix in UDC CSR register space */
				udc_csr_epix = ep->num;


			/* OUT ep */
			} else {
				/* ep ix in UDC CSR register space */
				udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS;
			}

			tmp = readl(&dev->csr->ne[udc_csr_epix]);
			/* ep cfg */
			tmp = AMD_ADDBITS(tmp, ep->dev->cur_config,
						UDC_CSR_NE_CFG);
			/* write reg */
			writel(tmp, &dev->csr->ne[udc_csr_epix]);

			/* clear stall bits */
			ep->halted = 0;
			tmp = readl(&ep->regs->ctl);
			tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S);
			writel(tmp, &ep->regs->ctl);
		}
		/* call gadget zero with setup data received */
		spin_unlock(&dev->lock);
		tmp = dev->driver->setup(&dev->gadget, &setup_data.request);
		spin_lock(&dev->lock);

	} /* SET_INTERFACE ? */
	if (dev_irq & AMD_BIT(UDC_DEVINT_SI)) {
		ret_val = IRQ_HANDLED;

		dev->set_cfg_not_acked = 1;
		/* read interface and alt setting values */
		tmp = readl(&dev->regs->sts);
		dev->cur_alt = AMD_GETBITS(tmp, UDC_DEVSTS_ALT);
		dev->cur_intf = AMD_GETBITS(tmp, UDC_DEVSTS_INTF);

		/* make usb request for gadget driver */
		memset(&setup_data, 0 , sizeof(union udc_setup_data));
		setup_data.request.bRequest = USB_REQ_SET_INTERFACE;
		setup_data.request.bRequestType = USB_RECIP_INTERFACE;
		setup_data.request.wValue = cpu_to_le16(dev->cur_alt);
		setup_data.request.wIndex = cpu_to_le16(dev->cur_intf);

		DBG(dev, "SET_INTERFACE interrupt: alt=%d intf=%d\n",
				dev->cur_alt, dev->cur_intf);

		/* programm the NE registers */
		for (i = 0; i < UDC_EP_NUM; i++) {
			ep = &dev->ep[i];
			if (ep->in) {

				/* ep ix in UDC CSR register space */
				udc_csr_epix = ep->num;


			/* OUT ep */
			} else {
				/* ep ix in UDC CSR register space */
				udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS;
			}

			/* UDC CSR reg */
			/* set ep values */
			tmp = readl(&dev->csr->ne[udc_csr_epix]);
			/* ep interface */
			tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf,
						UDC_CSR_NE_INTF);
			/* tmp = AMD_ADDBITS(tmp, 2, UDC_CSR_NE_INTF); */
			/* ep alt */
			tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt,
						UDC_CSR_NE_ALT);
			/* write reg */
			writel(tmp, &dev->csr->ne[udc_csr_epix]);

			/* clear stall bits */
			ep->halted = 0;
			tmp = readl(&ep->regs->ctl);
			tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S);
			writel(tmp, &ep->regs->ctl);
		}

		/* call gadget zero with setup data received */
		spin_unlock(&dev->lock);
		tmp = dev->driver->setup(&dev->gadget, &setup_data.request);
		spin_lock(&dev->lock);

	} /* USB reset */
	if (dev_irq & AMD_BIT(UDC_DEVINT_UR)) {
		DBG(dev, "USB Reset interrupt\n");
		ret_val = IRQ_HANDLED;

		/* allow soft reset when suspend occurs */
		soft_reset_occured = 0;

		dev->waiting_zlp_ack_ep0in = 0;
		dev->set_cfg_not_acked = 0;

		/* mask not needed interrupts */
		udc_mask_unused_interrupts(dev);

		/* call gadget to resume and reset configs etc. */
		spin_unlock(&dev->lock);
		if (dev->sys_suspended && dev->driver->resume) {
			dev->driver->resume(&dev->gadget);
			dev->sys_suspended = 0;
		}
		dev->driver->disconnect(&dev->gadget);
		spin_lock(&dev->lock);

		/* disable ep0 to empty req queue */
		empty_req_queue(&dev->ep[UDC_EP0IN_IX]);
		ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]);

		/* soft reset when rxfifo not empty */
		tmp = readl(&dev->regs->sts);
		if (!(tmp & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY))
				&& !soft_reset_after_usbreset_occured) {
			udc_soft_reset(dev);
			soft_reset_after_usbreset_occured++;
		}

		/*
		 * DMA reset to kill potential old DMA hw hang,
		 * POLL bit is already reset by ep_init() through
		 * disconnect()
		 */
		DBG(dev, "DMA machine reset\n");
		tmp = readl(&dev->regs->cfg);
		writel(tmp | AMD_BIT(UDC_DEVCFG_DMARST), &dev->regs->cfg);
		writel(tmp, &dev->regs->cfg);

		/* put into initial config */
		udc_basic_init(dev);

		/* enable device setup interrupts */
		udc_enable_dev_setup_interrupts(dev);

		/* enable suspend interrupt */
		tmp = readl(&dev->regs->irqmsk);
		tmp &= AMD_UNMASK_BIT(UDC_DEVINT_US);
		writel(tmp, &dev->regs->irqmsk);

	} /* USB suspend */
	if (dev_irq & AMD_BIT(UDC_DEVINT_US)) {
		DBG(dev, "USB Suspend interrupt\n");
		ret_val = IRQ_HANDLED;
		if (dev->driver->suspend) {
			spin_unlock(&dev->lock);
			dev->sys_suspended = 1;
			dev->driver->suspend(&dev->gadget);
			spin_lock(&dev->lock);
		}
	} /* new speed ? */
	if (dev_irq & AMD_BIT(UDC_DEVINT_ENUM)) {
		DBG(dev, "ENUM interrupt\n");
		ret_val = IRQ_HANDLED;
		soft_reset_after_usbreset_occured = 0;

		/* disable ep0 to empty req queue */
		empty_req_queue(&dev->ep[UDC_EP0IN_IX]);
		ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]);

		/* link up all endpoints */
		udc_setup_endpoints(dev);
		dev_info(&dev->pdev->dev, "Connect: %s\n",
			 usb_speed_string(dev->gadget.speed));

		/* init ep 0 */
		activate_control_endpoints(dev);

		/* enable ep0 interrupts */
		udc_enable_ep0_interrupts(dev);
	}
	/* session valid change interrupt */
	if (dev_irq & AMD_BIT(UDC_DEVINT_SVC)) {
		DBG(dev, "USB SVC interrupt\n");
		ret_val = IRQ_HANDLED;

		/* check that session is not valid to detect disconnect */
		tmp = readl(&dev->regs->sts);
		if (!(tmp & AMD_BIT(UDC_DEVSTS_SESSVLD))) {
			/* disable suspend interrupt */
			tmp = readl(&dev->regs->irqmsk);
			tmp |= AMD_BIT(UDC_DEVINT_US);
			writel(tmp, &dev->regs->irqmsk);
			DBG(dev, "USB Disconnect (session valid low)\n");
			/* cleanup on disconnect */
			usb_disconnect(udc);
		}

	}

	return ret_val;
}

/* Interrupt Service Routine, see Linux Kernel Doc for parameters */
static irqreturn_t udc_irq(int irq, void *pdev)
{
	struct udc *dev = pdev;
	u32 reg;
	u16 i;
	u32 ep_irq;
	irqreturn_t ret_val = IRQ_NONE;

	spin_lock(&dev->lock);

	/* check for ep irq */
	reg = readl(&dev->regs->ep_irqsts);
	if (reg) {
		if (reg & AMD_BIT(UDC_EPINT_OUT_EP0))
			ret_val |= udc_control_out_isr(dev);
		if (reg & AMD_BIT(UDC_EPINT_IN_EP0))
			ret_val |= udc_control_in_isr(dev);

		/*
		 * data endpoint
		 * iterate ep's
		 */
		for (i = 1; i < UDC_EP_NUM; i++) {
			ep_irq = 1 << i;
			if (!(reg & ep_irq) || i == UDC_EPINT_OUT_EP0)
				continue;

			/* clear irq status */
			writel(ep_irq, &dev->regs->ep_irqsts);

			/* irq for out ep ? */
			if (i > UDC_EPIN_NUM)
				ret_val |= udc_data_out_isr(dev, i);
			else
				ret_val |= udc_data_in_isr(dev, i);
		}

	}


	/* check for dev irq */
	reg = readl(&dev->regs->irqsts);
	if (reg) {
		/* clear irq */
		writel(reg, &dev->regs->irqsts);
		ret_val |= udc_dev_isr(dev, reg);
	}


	spin_unlock(&dev->lock);
	return ret_val;
}

/* Tears down device */
static void gadget_release(struct device *pdev)
{
	struct amd5536udc *dev = dev_get_drvdata(pdev);
	kfree(dev);
}

/* Cleanup on device remove */
static void udc_remove(struct udc *dev)
{
	/* remove timer */
	stop_timer++;
	if (timer_pending(&udc_timer))
		wait_for_completion(&on_exit);
	if (udc_timer.data)
		del_timer_sync(&udc_timer);
	/* remove pollstall timer */
	stop_pollstall_timer++;
	if (timer_pending(&udc_pollstall_timer))
		wait_for_completion(&on_pollstall_exit);
	if (udc_pollstall_timer.data)
		del_timer_sync(&udc_pollstall_timer);
	udc = NULL;
}

/* Reset all pci context */
static void udc_pci_remove(struct pci_dev *pdev)
{
	struct udc		*dev;

	dev = pci_get_drvdata(pdev);

	usb_del_gadget_udc(&udc->gadget);
	/* gadget driver must not be registered */
	BUG_ON(dev->driver != NULL);

	/* dma pool cleanup */
	if (dev->data_requests)
		pci_pool_destroy(dev->data_requests);

	if (dev->stp_requests) {
		/* cleanup DMA desc's for ep0in */
		pci_pool_free(dev->stp_requests,
			dev->ep[UDC_EP0OUT_IX].td_stp,
			dev->ep[UDC_EP0OUT_IX].td_stp_dma);
		pci_pool_free(dev->stp_requests,
			dev->ep[UDC_EP0OUT_IX].td,
			dev->ep[UDC_EP0OUT_IX].td_phys);

		pci_pool_destroy(dev->stp_requests);
	}

	/* reset controller */
	writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg);
	if (dev->irq_registered)
		free_irq(pdev->irq, dev);
	if (dev->regs)
		iounmap(dev->regs);
	if (dev->mem_region)
		release_mem_region(pci_resource_start(pdev, 0),
				pci_resource_len(pdev, 0));
	if (dev->active)
		pci_disable_device(pdev);

	device_unregister(&dev->gadget.dev);
	pci_set_drvdata(pdev, NULL);

	udc_remove(dev);
}

/* create dma pools on init */
static int init_dma_pools(struct udc *dev)
{
	struct udc_stp_dma	*td_stp;
	struct udc_data_dma	*td_data;
	int retval;

	/* consistent DMA mode setting ? */
	if (use_dma_ppb) {
		use_dma_bufferfill_mode = 0;
	} else {
		use_dma_ppb_du = 0;
		use_dma_bufferfill_mode = 1;
	}

	/* DMA setup */
	dev->data_requests = dma_pool_create("data_requests", NULL,
		sizeof(struct udc_data_dma), 0, 0);
	if (!dev->data_requests) {
		DBG(dev, "can't get request data pool\n");
		retval = -ENOMEM;
		goto finished;
	}

	/* EP0 in dma regs = dev control regs */
	dev->ep[UDC_EP0IN_IX].dma = &dev->regs->ctl;

	/* dma desc for setup data */
	dev->stp_requests = dma_pool_create("setup requests", NULL,
		sizeof(struct udc_stp_dma), 0, 0);
	if (!dev->stp_requests) {
		DBG(dev, "can't get stp request pool\n");
		retval = -ENOMEM;
		goto finished;
	}
	/* setup */
	td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL,
				&dev->ep[UDC_EP0OUT_IX].td_stp_dma);
	if (td_stp == NULL) {
		retval = -ENOMEM;
		goto finished;
	}
	dev->ep[UDC_EP0OUT_IX].td_stp = td_stp;

	/* data: 0 packets !? */
	td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL,
				&dev->ep[UDC_EP0OUT_IX].td_phys);
	if (td_data == NULL) {
		retval = -ENOMEM;
		goto finished;
	}
	dev->ep[UDC_EP0OUT_IX].td = td_data;
	return 0;

finished:
	return retval;
}

/* Called by pci bus driver to init pci context */
static int udc_pci_probe(
	struct pci_dev *pdev,
	const struct pci_device_id *id
)
{
	struct udc		*dev;
	unsigned long		resource;
	unsigned long		len;
	int			retval = 0;

	/* one udc only */
	if (udc) {
		dev_dbg(&pdev->dev, "already probed\n");
		return -EBUSY;
	}

	/* init */
	dev = kzalloc(sizeof(struct udc), GFP_KERNEL);
	if (!dev) {
		retval = -ENOMEM;
		goto finished;
	}

	/* pci setup */
	if (pci_enable_device(pdev) < 0) {
		kfree(dev);
		dev = NULL;
		retval = -ENODEV;
		goto finished;
	}
	dev->active = 1;

	/* PCI resource allocation */
	resource = pci_resource_start(pdev, 0);
	len = pci_resource_len(pdev, 0);

	if (!request_mem_region(resource, len, name)) {
		dev_dbg(&pdev->dev, "pci device used already\n");
		kfree(dev);
		dev = NULL;
		retval = -EBUSY;
		goto finished;
	}
	dev->mem_region = 1;

	dev->virt_addr = ioremap_nocache(resource, len);
	if (dev->virt_addr == NULL) {
		dev_dbg(&pdev->dev, "start address cannot be mapped\n");
		kfree(dev);
		dev = NULL;
		retval = -EFAULT;
		goto finished;
	}

	if (!pdev->irq) {
		dev_err(&dev->pdev->dev, "irq not set\n");
		kfree(dev);
		dev = NULL;
		retval = -ENODEV;
		goto finished;
	}

	spin_lock_init(&dev->lock);
	/* udc csr registers base */
	dev->csr = dev->virt_addr + UDC_CSR_ADDR;
	/* dev registers base */
	dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
	/* ep registers base */
	dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
	/* fifo's base */
	dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
	dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);

	if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
		dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
		kfree(dev);
		dev = NULL;
		retval = -EBUSY;
		goto finished;
	}
	dev->irq_registered = 1;

	pci_set_drvdata(pdev, dev);

	/* chip revision for Hs AMD5536 */
	dev->chiprev = pdev->revision;

	pci_set_master(pdev);
	pci_try_set_mwi(pdev);

	/* init dma pools */
	if (use_dma) {
		retval = init_dma_pools(dev);
		if (retval != 0)
			goto finished;
	}

	dev->phys_addr = resource;
	dev->irq = pdev->irq;
	dev->pdev = pdev;
	dev->gadget.dev.parent = &pdev->dev;
	dev->gadget.dev.dma_mask = pdev->dev.dma_mask;

	/* general probing */
	if (udc_probe(dev) == 0)
		return 0;

finished:
	if (dev)
		udc_pci_remove(pdev);
	return retval;
}

/* general probe */
static int udc_probe(struct udc *dev)
{
	char		tmp[128];
	u32		reg;
	int		retval;

	/* mark timer as not initialized */
	udc_timer.data = 0;
	udc_pollstall_timer.data = 0;

	/* device struct setup */
	dev->gadget.ops = &udc_ops;

	dev_set_name(&dev->gadget.dev, "gadget");
	dev->gadget.dev.release = gadget_release;
	dev->gadget.name = name;
	dev->gadget.max_speed = USB_SPEED_HIGH;

	/* init registers, interrupts, ... */
	startup_registers(dev);

	dev_info(&dev->pdev->dev, "%s\n", mod_desc);

	snprintf(tmp, sizeof tmp, "%d", dev->irq);
	dev_info(&dev->pdev->dev,
		"irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n",
		tmp, dev->phys_addr, dev->chiprev,
		(dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1");
	strcpy(tmp, UDC_DRIVER_VERSION_STRING);
	if (dev->chiprev == UDC_HSA0_REV) {
		dev_err(&dev->pdev->dev, "chip revision is A0; too old\n");
		retval = -ENODEV;
		goto finished;
	}
	dev_info(&dev->pdev->dev,
		"driver version: %s(for Geode5536 B1)\n", tmp);
	udc = dev;

	retval = usb_add_gadget_udc(&udc->pdev->dev, &dev->gadget);
	if (retval)
		goto finished;

	retval = device_register(&dev->gadget.dev);
	if (retval) {
		usb_del_gadget_udc(&dev->gadget);
		put_device(&dev->gadget.dev);
		goto finished;
	}

	/* timer init */
	init_timer(&udc_timer);
	udc_timer.function = udc_timer_function;
	udc_timer.data = 1;
	/* timer pollstall init */
	init_timer(&udc_pollstall_timer);
	udc_pollstall_timer.function = udc_pollstall_timer_function;
	udc_pollstall_timer.data = 1;

	/* set SD */
	reg = readl(&dev->regs->ctl);
	reg |= AMD_BIT(UDC_DEVCTL_SD);
	writel(reg, &dev->regs->ctl);

	/* print dev register info */
	print_regs(dev);

	return 0;

finished:
	return retval;
}

/* Initiates a remote wakeup */
static int udc_remote_wakeup(struct udc *dev)
{
	unsigned long flags;
	u32 tmp;

	DBG(dev, "UDC initiates remote wakeup\n");

	spin_lock_irqsave(&dev->lock, flags);

	tmp = readl(&dev->regs->ctl);
	tmp |= AMD_BIT(UDC_DEVCTL_RES);
	writel(tmp, &dev->regs->ctl);
	tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES);
	writel(tmp, &dev->regs->ctl);

	spin_unlock_irqrestore(&dev->lock, flags);
	return 0;
}

/* PCI device parameters */
static DEFINE_PCI_DEVICE_TABLE(pci_id) = {
	{
		PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x2096),
		.class =	(PCI_CLASS_SERIAL_USB << 8) | 0xfe,
		.class_mask =	0xffffffff,
	},
	{},
};
MODULE_DEVICE_TABLE(pci, pci_id);

/* PCI functions */
static struct pci_driver udc_pci_driver = {
	.name =		(char *) name,
	.id_table =	pci_id,
	.probe =	udc_pci_probe,
	.remove =	udc_pci_remove,
};

/* Inits driver */
static int __init init(void)
{
	return pci_register_driver(&udc_pci_driver);
}
module_init(init);

/* Cleans driver */
static void __exit cleanup(void)
{
	pci_unregister_driver(&udc_pci_driver);
}
module_exit(cleanup);

MODULE_DESCRIPTION(UDC_MOD_DESCRIPTION);
MODULE_AUTHOR("Thomas Dahlmann");
MODULE_LICENSE("GPL");

