// SPDX-License-Identifier: GPL-2.0+
/*
 * Handles the Intel 27x USB Device Controller (UDC)
 *
 * Inspired by original driver by Frank Becker, David Brownell, and others.
 * Copyright (C) 2008 Robert Jarzmik
 *
 * 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.
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/slab.h>
#include <linux/prefetch.h>
#include <linux/byteorder/generic.h>
#include <linux/platform_data/pxa2xx_udc.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>

#include <linux/usb.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/phy.h>

#include "pxa27x_udc.h"

/*
 * This driver handles the USB Device Controller (UDC) in Intel's PXA 27x
 * 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. The
 * biggest issues are:  that the endpoints have to be set up before the
 * controller can be enabled (minor, and not uncommon); and each endpoint
 * can only have one configuration, interface and alternative interface
 * number (major, and very unusual). Once set up, these cannot be changed
 * without a controller reset.
 *
 * The workaround is to setup all combinations necessary for the gadgets which
 * will work with this driver. This is done in pxa_udc structure, statically.
 * See pxa_udc, udc_usb_ep versus pxa_ep, and matching function find_pxa_ep.
 * (You could modify this if needed.  Some drivers have a "fifo_mode" module
 * parameter to facilitate such changes.)
 *
 * The combinations have been tested with these gadgets :
 *  - zero gadget
 *  - file storage gadget
 *  - ether gadget
 *
 * The driver doesn't use DMA, only IO access and IRQ callbacks. No use is
 * made of UDC's double buffering either. USB "On-The-Go" is not implemented.
 *
 * All the requests are handled the same way :
 *  - the drivers tries to handle the request directly to the IO
 *  - if the IO fifo is not big enough, the remaining is send/received in
 *    interrupt handling.
 */

#define	DRIVER_VERSION	"2008-04-18"
#define	DRIVER_DESC	"PXA 27x USB Device Controller driver"

static const char driver_name[] = "pxa27x_udc";
static struct pxa_udc *the_controller;

static void handle_ep(struct pxa_ep *ep);

/*
 * Debug filesystem
 */
#ifdef CONFIG_USB_GADGET_DEBUG_FS

#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/seq_file.h>

static int state_dbg_show(struct seq_file *s, void *p)
{
	struct pxa_udc *udc = s->private;
	u32 tmp;

	if (!udc->driver)
		return -ENODEV;

	/* basic device status */
	seq_printf(s, DRIVER_DESC "\n"
		   "%s version: %s\n"
		   "Gadget driver: %s\n",
		   driver_name, DRIVER_VERSION,
		   udc->driver ? udc->driver->driver.name : "(none)");

	tmp = udc_readl(udc, UDCCR);
	seq_printf(s,
		   "udccr=0x%0x(%s%s%s%s%s%s%s%s%s%s), con=%d,inter=%d,altinter=%d\n",
		   tmp,
		   (tmp & UDCCR_OEN) ? " oen":"",
		   (tmp & UDCCR_AALTHNP) ? " aalthnp":"",
		   (tmp & UDCCR_AHNP) ? " rem" : "",
		   (tmp & UDCCR_BHNP) ? " rstir" : "",
		   (tmp & UDCCR_DWRE) ? " dwre" : "",
		   (tmp & UDCCR_SMAC) ? " smac" : "",
		   (tmp & UDCCR_EMCE) ? " emce" : "",
		   (tmp & UDCCR_UDR) ? " udr" : "",
		   (tmp & UDCCR_UDA) ? " uda" : "",
		   (tmp & UDCCR_UDE) ? " ude" : "",
		   (tmp & UDCCR_ACN) >> UDCCR_ACN_S,
		   (tmp & UDCCR_AIN) >> UDCCR_AIN_S,
		   (tmp & UDCCR_AAISN) >> UDCCR_AAISN_S);
	/* registers for device and ep0 */
	seq_printf(s, "udcicr0=0x%08x udcicr1=0x%08x\n",
		   udc_readl(udc, UDCICR0), udc_readl(udc, UDCICR1));
	seq_printf(s, "udcisr0=0x%08x udcisr1=0x%08x\n",
		   udc_readl(udc, UDCISR0), udc_readl(udc, UDCISR1));
	seq_printf(s, "udcfnr=%d\n", udc_readl(udc, UDCFNR));
	seq_printf(s, "irqs: reset=%lu, suspend=%lu, resume=%lu, reconfig=%lu\n",
		   udc->stats.irqs_reset, udc->stats.irqs_suspend,
		   udc->stats.irqs_resume, udc->stats.irqs_reconfig);

	return 0;
}

static int queues_dbg_show(struct seq_file *s, void *p)
{
	struct pxa_udc *udc = s->private;
	struct pxa_ep *ep;
	struct pxa27x_request *req;
	int i, maxpkt;

	if (!udc->driver)
		return -ENODEV;

	/* dump endpoint queues */
	for (i = 0; i < NR_PXA_ENDPOINTS; i++) {
		ep = &udc->pxa_ep[i];
		maxpkt = ep->fifo_size;
		seq_printf(s,  "%-12s max_pkt=%d %s\n",
			   EPNAME(ep), maxpkt, "pio");

		if (list_empty(&ep->queue)) {
			seq_puts(s, "\t(nothing queued)\n");
			continue;
		}

		list_for_each_entry(req, &ep->queue, queue) {
			seq_printf(s,  "\treq %p len %d/%d buf %p\n",
				   &req->req, req->req.actual,
				   req->req.length, req->req.buf);
		}
	}

	return 0;
}

static int eps_dbg_show(struct seq_file *s, void *p)
{
	struct pxa_udc *udc = s->private;
	struct pxa_ep *ep;
	int i;
	u32 tmp;

	if (!udc->driver)
		return -ENODEV;

	ep = &udc->pxa_ep[0];
	tmp = udc_ep_readl(ep, UDCCSR);
	seq_printf(s, "udccsr0=0x%03x(%s%s%s%s%s%s%s)\n",
		   tmp,
		   (tmp & UDCCSR0_SA) ? " sa" : "",
		   (tmp & UDCCSR0_RNE) ? " rne" : "",
		   (tmp & UDCCSR0_FST) ? " fst" : "",
		   (tmp & UDCCSR0_SST) ? " sst" : "",
		   (tmp & UDCCSR0_DME) ? " dme" : "",
		   (tmp & UDCCSR0_IPR) ? " ipr" : "",
		   (tmp & UDCCSR0_OPC) ? " opc" : "");
	for (i = 0; i < NR_PXA_ENDPOINTS; i++) {
		ep = &udc->pxa_ep[i];
		tmp = i? udc_ep_readl(ep, UDCCR) : udc_readl(udc, UDCCR);
		seq_printf(s, "%-12s: IN %lu(%lu reqs), OUT %lu(%lu reqs), irqs=%lu, udccr=0x%08x, udccsr=0x%03x, udcbcr=%d\n",
			   EPNAME(ep),
			   ep->stats.in_bytes, ep->stats.in_ops,
			   ep->stats.out_bytes, ep->stats.out_ops,
			   ep->stats.irqs,
			   tmp, udc_ep_readl(ep, UDCCSR),
			   udc_ep_readl(ep, UDCBCR));
	}

	return 0;
}

static int eps_dbg_open(struct inode *inode, struct file *file)
{
	return single_open(file, eps_dbg_show, inode->i_private);
}

static int queues_dbg_open(struct inode *inode, struct file *file)
{
	return single_open(file, queues_dbg_show, inode->i_private);
}

static int state_dbg_open(struct inode *inode, struct file *file)
{
	return single_open(file, state_dbg_show, inode->i_private);
}

static const struct file_operations state_dbg_fops = {
	.owner		= THIS_MODULE,
	.open		= state_dbg_open,
	.llseek		= seq_lseek,
	.read		= seq_read,
	.release	= single_release,
};

static const struct file_operations queues_dbg_fops = {
	.owner		= THIS_MODULE,
	.open		= queues_dbg_open,
	.llseek		= seq_lseek,
	.read		= seq_read,
	.release	= single_release,
};

static const struct file_operations eps_dbg_fops = {
	.owner		= THIS_MODULE,
	.open		= eps_dbg_open,
	.llseek		= seq_lseek,
	.read		= seq_read,
	.release	= single_release,
};

static void pxa_init_debugfs(struct pxa_udc *udc)
{
	struct dentry *root, *state, *queues, *eps;

	root = debugfs_create_dir(udc->gadget.name, NULL);
	if (IS_ERR(root) || !root)
		goto err_root;

	state = debugfs_create_file("udcstate", 0400, root, udc,
			&state_dbg_fops);
	if (!state)
		goto err_state;
	queues = debugfs_create_file("queues", 0400, root, udc,
			&queues_dbg_fops);
	if (!queues)
		goto err_queues;
	eps = debugfs_create_file("epstate", 0400, root, udc,
			&eps_dbg_fops);
	if (!eps)
		goto err_eps;

	udc->debugfs_root = root;
	udc->debugfs_state = state;
	udc->debugfs_queues = queues;
	udc->debugfs_eps = eps;
	return;
err_eps:
	debugfs_remove(eps);
err_queues:
	debugfs_remove(queues);
err_state:
	debugfs_remove(root);
err_root:
	dev_err(udc->dev, "debugfs is not available\n");
}

static void pxa_cleanup_debugfs(struct pxa_udc *udc)
{
	debugfs_remove(udc->debugfs_eps);
	debugfs_remove(udc->debugfs_queues);
	debugfs_remove(udc->debugfs_state);
	debugfs_remove(udc->debugfs_root);
	udc->debugfs_eps = NULL;
	udc->debugfs_queues = NULL;
	udc->debugfs_state = NULL;
	udc->debugfs_root = NULL;
}

#else
static inline void pxa_init_debugfs(struct pxa_udc *udc)
{
}

static inline void pxa_cleanup_debugfs(struct pxa_udc *udc)
{
}
#endif

/**
 * is_match_usb_pxa - check if usb_ep and pxa_ep match
 * @udc_usb_ep: usb endpoint
 * @ep: pxa endpoint
 * @config: configuration required in pxa_ep
 * @interface: interface required in pxa_ep
 * @altsetting: altsetting required in pxa_ep
 *
 * Returns 1 if all criteria match between pxa and usb endpoint, 0 otherwise
 */
static int is_match_usb_pxa(struct udc_usb_ep *udc_usb_ep, struct pxa_ep *ep,
		int config, int interface, int altsetting)
{
	if (usb_endpoint_num(&udc_usb_ep->desc) != ep->addr)
		return 0;
	if (usb_endpoint_dir_in(&udc_usb_ep->desc) != ep->dir_in)
		return 0;
	if (usb_endpoint_type(&udc_usb_ep->desc) != ep->type)
		return 0;
	if ((ep->config != config) || (ep->interface != interface)
			|| (ep->alternate != altsetting))
		return 0;
	return 1;
}

/**
 * find_pxa_ep - find pxa_ep structure matching udc_usb_ep
 * @udc: pxa udc
 * @udc_usb_ep: udc_usb_ep structure
 *
 * Match udc_usb_ep and all pxa_ep available, to see if one matches.
 * This is necessary because of the strong pxa hardware restriction requiring
 * that once pxa endpoints are initialized, their configuration is freezed, and
 * no change can be made to their address, direction, or in which configuration,
 * interface or altsetting they are active ... which differs from more usual
 * models which have endpoints be roughly just addressable fifos, and leave
 * configuration events up to gadget drivers (like all control messages).
 *
 * Note that there is still a blurred point here :
 *   - we rely on UDCCR register "active interface" and "active altsetting".
 *     This is a nonsense in regard of USB spec, where multiple interfaces are
 *     active at the same time.
 *   - if we knew for sure that the pxa can handle multiple interface at the
 *     same time, assuming Intel's Developer Guide is wrong, this function
 *     should be reviewed, and a cache of couples (iface, altsetting) should
 *     be kept in the pxa_udc structure. In this case this function would match
 *     against the cache of couples instead of the "last altsetting" set up.
 *
 * Returns the matched pxa_ep structure or NULL if none found
 */
static struct pxa_ep *find_pxa_ep(struct pxa_udc *udc,
		struct udc_usb_ep *udc_usb_ep)
{
	int i;
	struct pxa_ep *ep;
	int cfg = udc->config;
	int iface = udc->last_interface;
	int alt = udc->last_alternate;

	if (udc_usb_ep == &udc->udc_usb_ep[0])
		return &udc->pxa_ep[0];

	for (i = 1; i < NR_PXA_ENDPOINTS; i++) {
		ep = &udc->pxa_ep[i];
		if (is_match_usb_pxa(udc_usb_ep, ep, cfg, iface, alt))
			return ep;
	}
	return NULL;
}

/**
 * update_pxa_ep_matches - update pxa_ep cached values in all udc_usb_ep
 * @udc: pxa udc
 *
 * Context: in_interrupt()
 *
 * Updates all pxa_ep fields in udc_usb_ep structures, if this field was
 * previously set up (and is not NULL). The update is necessary is a
 * configuration change or altsetting change was issued by the USB host.
 */
static void update_pxa_ep_matches(struct pxa_udc *udc)
{
	int i;
	struct udc_usb_ep *udc_usb_ep;

	for (i = 1; i < NR_USB_ENDPOINTS; i++) {
		udc_usb_ep = &udc->udc_usb_ep[i];
		if (udc_usb_ep->pxa_ep)
			udc_usb_ep->pxa_ep = find_pxa_ep(udc, udc_usb_ep);
	}
}

/**
 * pio_irq_enable - Enables irq generation for one endpoint
 * @ep: udc endpoint
 */
static void pio_irq_enable(struct pxa_ep *ep)
{
	struct pxa_udc *udc = ep->dev;
	int index = EPIDX(ep);
	u32 udcicr0 = udc_readl(udc, UDCICR0);
	u32 udcicr1 = udc_readl(udc, UDCICR1);

	if (index < 16)
		udc_writel(udc, UDCICR0, udcicr0 | (3 << (index * 2)));
	else
		udc_writel(udc, UDCICR1, udcicr1 | (3 << ((index - 16) * 2)));
}

/**
 * pio_irq_disable - Disables irq generation for one endpoint
 * @ep: udc endpoint
 */
static void pio_irq_disable(struct pxa_ep *ep)
{
	struct pxa_udc *udc = ep->dev;
	int index = EPIDX(ep);
	u32 udcicr0 = udc_readl(udc, UDCICR0);
	u32 udcicr1 = udc_readl(udc, UDCICR1);

	if (index < 16)
		udc_writel(udc, UDCICR0, udcicr0 & ~(3 << (index * 2)));
	else
		udc_writel(udc, UDCICR1, udcicr1 & ~(3 << ((index - 16) * 2)));
}

/**
 * udc_set_mask_UDCCR - set bits in UDCCR
 * @udc: udc device
 * @mask: bits to set in UDCCR
 *
 * Sets bits in UDCCR, leaving DME and FST bits as they were.
 */
static inline void udc_set_mask_UDCCR(struct pxa_udc *udc, int mask)
{
	u32 udccr = udc_readl(udc, UDCCR);
	udc_writel(udc, UDCCR,
			(udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS));
}

/**
 * udc_clear_mask_UDCCR - clears bits in UDCCR
 * @udc: udc device
 * @mask: bit to clear in UDCCR
 *
 * Clears bits in UDCCR, leaving DME and FST bits as they were.
 */
static inline void udc_clear_mask_UDCCR(struct pxa_udc *udc, int mask)
{
	u32 udccr = udc_readl(udc, UDCCR);
	udc_writel(udc, UDCCR,
			(udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS));
}

/**
 * ep_write_UDCCSR - set bits in UDCCSR
 * @udc: udc device
 * @mask: bits to set in UDCCR
 *
 * Sets bits in UDCCSR (UDCCSR0 and UDCCSR*).
 *
 * A specific case is applied to ep0 : the ACM bit is always set to 1, for
 * SET_INTERFACE and SET_CONFIGURATION.
 */
static inline void ep_write_UDCCSR(struct pxa_ep *ep, int mask)
{
	if (is_ep0(ep))
		mask |= UDCCSR0_ACM;
	udc_ep_writel(ep, UDCCSR, mask);
}

/**
 * ep_count_bytes_remain - get how many bytes in udc endpoint
 * @ep: udc endpoint
 *
 * Returns number of bytes in OUT fifos. Broken for IN fifos (-EOPNOTSUPP)
 */
static int ep_count_bytes_remain(struct pxa_ep *ep)
{
	if (ep->dir_in)
		return -EOPNOTSUPP;
	return udc_ep_readl(ep, UDCBCR) & 0x3ff;
}

/**
 * ep_is_empty - checks if ep has byte ready for reading
 * @ep: udc endpoint
 *
 * If endpoint is the control endpoint, checks if there are bytes in the
 * control endpoint fifo. If endpoint is a data endpoint, checks if bytes
 * are ready for reading on OUT endpoint.
 *
 * Returns 0 if ep not empty, 1 if ep empty, -EOPNOTSUPP if IN endpoint
 */
static int ep_is_empty(struct pxa_ep *ep)
{
	int ret;

	if (!is_ep0(ep) && ep->dir_in)
		return -EOPNOTSUPP;
	if (is_ep0(ep))
		ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR0_RNE);
	else
		ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNE);
	return ret;
}

/**
 * ep_is_full - checks if ep has place to write bytes
 * @ep: udc endpoint
 *
 * If endpoint is not the control endpoint and is an IN endpoint, checks if
 * there is place to write bytes into the endpoint.
 *
 * Returns 0 if ep not full, 1 if ep full, -EOPNOTSUPP if OUT endpoint
 */
static int ep_is_full(struct pxa_ep *ep)
{
	if (is_ep0(ep))
		return (udc_ep_readl(ep, UDCCSR) & UDCCSR0_IPR);
	if (!ep->dir_in)
		return -EOPNOTSUPP;
	return (!(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNF));
}

/**
 * epout_has_pkt - checks if OUT endpoint fifo has a packet available
 * @ep: pxa endpoint
 *
 * Returns 1 if a complete packet is available, 0 if not, -EOPNOTSUPP for IN ep.
 */
static int epout_has_pkt(struct pxa_ep *ep)
{
	if (!is_ep0(ep) && ep->dir_in)
		return -EOPNOTSUPP;
	if (is_ep0(ep))
		return (udc_ep_readl(ep, UDCCSR) & UDCCSR0_OPC);
	return (udc_ep_readl(ep, UDCCSR) & UDCCSR_PC);
}

/**
 * set_ep0state - Set ep0 automata state
 * @dev: udc device
 * @state: state
 */
static void set_ep0state(struct pxa_udc *udc, int state)
{
	struct pxa_ep *ep = &udc->pxa_ep[0];
	char *old_stname = EP0_STNAME(udc);

	udc->ep0state = state;
	ep_dbg(ep, "state=%s->%s, udccsr0=0x%03x, udcbcr=%d\n", old_stname,
		EP0_STNAME(udc), udc_ep_readl(ep, UDCCSR),
		udc_ep_readl(ep, UDCBCR));
}

/**
 * ep0_idle - Put control endpoint into idle state
 * @dev: udc device
 */
static void ep0_idle(struct pxa_udc *dev)
{
	set_ep0state(dev, WAIT_FOR_SETUP);
}

/**
 * inc_ep_stats_reqs - Update ep stats counts
 * @ep: physical endpoint
 * @req: usb request
 * @is_in: ep direction (USB_DIR_IN or 0)
 *
 */
static void inc_ep_stats_reqs(struct pxa_ep *ep, int is_in)
{
	if (is_in)
		ep->stats.in_ops++;
	else
		ep->stats.out_ops++;
}

/**
 * inc_ep_stats_bytes - Update ep stats counts
 * @ep: physical endpoint
 * @count: bytes transferred on endpoint
 * @is_in: ep direction (USB_DIR_IN or 0)
 */
static void inc_ep_stats_bytes(struct pxa_ep *ep, int count, int is_in)
{
	if (is_in)
		ep->stats.in_bytes += count;
	else
		ep->stats.out_bytes += count;
}

/**
 * pxa_ep_setup - Sets up an usb physical endpoint
 * @ep: pxa27x physical endpoint
 *
 * Find the physical pxa27x ep, and setup its UDCCR
 */
static void pxa_ep_setup(struct pxa_ep *ep)
{
	u32 new_udccr;

	new_udccr = ((ep->config << UDCCONR_CN_S) & UDCCONR_CN)
		| ((ep->interface << UDCCONR_IN_S) & UDCCONR_IN)
		| ((ep->alternate << UDCCONR_AISN_S) & UDCCONR_AISN)
		| ((EPADDR(ep) << UDCCONR_EN_S) & UDCCONR_EN)
		| ((EPXFERTYPE(ep) << UDCCONR_ET_S) & UDCCONR_ET)
		| ((ep->dir_in) ? UDCCONR_ED : 0)
		| ((ep->fifo_size << UDCCONR_MPS_S) & UDCCONR_MPS)
		| UDCCONR_EE;

	udc_ep_writel(ep, UDCCR, new_udccr);
}

/**
 * pxa_eps_setup - Sets up all usb physical endpoints
 * @dev: udc device
 *
 * Setup all pxa physical endpoints, except ep0
 */
static void pxa_eps_setup(struct pxa_udc *dev)
{
	unsigned int i;

	dev_dbg(dev->dev, "%s: dev=%p\n", __func__, dev);

	for (i = 1; i < NR_PXA_ENDPOINTS; i++)
		pxa_ep_setup(&dev->pxa_ep[i]);
}

/**
 * pxa_ep_alloc_request - Allocate usb request
 * @_ep: usb endpoint
 * @gfp_flags:
 *
 * 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).
  */
static struct usb_request *
pxa_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
{
	struct pxa27x_request *req;

	req = kzalloc(sizeof *req, gfp_flags);
	if (!req)
		return NULL;

	INIT_LIST_HEAD(&req->queue);
	req->in_use = 0;
	req->udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);

	return &req->req;
}

/**
 * pxa_ep_free_request - Free usb request
 * @_ep: usb endpoint
 * @_req: usb request
 *
 * Wrapper around kfree to free _req
 */
static void pxa_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);
}

/**
 * ep_add_request - add a request to the endpoint's queue
 * @ep: usb endpoint
 * @req: usb request
 *
 * Context: ep->lock held
 *
 * Queues the request in the endpoint's queue, and enables the interrupts
 * on the endpoint.
 */
static void ep_add_request(struct pxa_ep *ep, struct pxa27x_request *req)
{
	if (unlikely(!req))
		return;
	ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req,
		req->req.length, udc_ep_readl(ep, UDCCSR));

	req->in_use = 1;
	list_add_tail(&req->queue, &ep->queue);
	pio_irq_enable(ep);
}

/**
 * ep_del_request - removes a request from the endpoint's queue
 * @ep: usb endpoint
 * @req: usb request
 *
 * Context: ep->lock held
 *
 * Unqueue the request from the endpoint's queue. If there are no more requests
 * on the endpoint, and if it's not the control endpoint, interrupts are
 * disabled on the endpoint.
 */
static void ep_del_request(struct pxa_ep *ep, struct pxa27x_request *req)
{
	if (unlikely(!req))
		return;
	ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req,
		req->req.length, udc_ep_readl(ep, UDCCSR));

	list_del_init(&req->queue);
	req->in_use = 0;
	if (!is_ep0(ep) && list_empty(&ep->queue))
		pio_irq_disable(ep);
}

/**
 * req_done - Complete an usb request
 * @ep: pxa physical endpoint
 * @req: pxa request
 * @status: usb request status sent to gadget API
 * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held
 *
 * Context: ep->lock held if flags not NULL, else ep->lock released
 *
 * Retire a pxa27x usb request. Endpoint must be locked.
 */
static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status,
	unsigned long *pflags)
{
	unsigned long	flags;

	ep_del_request(ep, req);
	if (likely(req->req.status == -EINPROGRESS))
		req->req.status = status;
	else
		status = req->req.status;

	if (status && status != -ESHUTDOWN)
		ep_dbg(ep, "complete req %p stat %d len %u/%u\n",
			&req->req, status,
			req->req.actual, req->req.length);

	if (pflags)
		spin_unlock_irqrestore(&ep->lock, *pflags);
	local_irq_save(flags);
	usb_gadget_giveback_request(&req->udc_usb_ep->usb_ep, &req->req);
	local_irq_restore(flags);
	if (pflags)
		spin_lock_irqsave(&ep->lock, *pflags);
}

/**
 * ep_end_out_req - Ends endpoint OUT request
 * @ep: physical endpoint
 * @req: pxa request
 * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held
 *
 * Context: ep->lock held or released (see req_done())
 *
 * Ends endpoint OUT request (completes usb request).
 */
static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req,
	unsigned long *pflags)
{
	inc_ep_stats_reqs(ep, !USB_DIR_IN);
	req_done(ep, req, 0, pflags);
}

/**
 * ep0_end_out_req - Ends control endpoint OUT request (ends data stage)
 * @ep: physical endpoint
 * @req: pxa request
 * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held
 *
 * Context: ep->lock held or released (see req_done())
 *
 * Ends control endpoint OUT request (completes usb request), and puts
 * control endpoint into idle state
 */
static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req,
	unsigned long *pflags)
{
	set_ep0state(ep->dev, OUT_STATUS_STAGE);
	ep_end_out_req(ep, req, pflags);
	ep0_idle(ep->dev);
}

/**
 * ep_end_in_req - Ends endpoint IN request
 * @ep: physical endpoint
 * @req: pxa request
 * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held
 *
 * Context: ep->lock held or released (see req_done())
 *
 * Ends endpoint IN request (completes usb request).
 */
static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req,
	unsigned long *pflags)
{
	inc_ep_stats_reqs(ep, USB_DIR_IN);
	req_done(ep, req, 0, pflags);
}

/**
 * ep0_end_in_req - Ends control endpoint IN request (ends data stage)
 * @ep: physical endpoint
 * @req: pxa request
 * @pflags: flags of previous spinlock_irq_save() or NULL if no lock held
 *
 * Context: ep->lock held or released (see req_done())
 *
 * Ends control endpoint IN request (completes usb request), and puts
 * control endpoint into status state
 */
static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req,
	unsigned long *pflags)
{
	set_ep0state(ep->dev, IN_STATUS_STAGE);
	ep_end_in_req(ep, req, pflags);
}

/**
 * nuke - Dequeue all requests
 * @ep: pxa endpoint
 * @status: usb request status
 *
 * Context: ep->lock released
 *
 * Dequeues all requests on an endpoint. As a side effect, interrupts will be
 * disabled on that endpoint (because no more requests).
 */
static void nuke(struct pxa_ep *ep, int status)
{
	struct pxa27x_request	*req;
	unsigned long		flags;

	spin_lock_irqsave(&ep->lock, flags);
	while (!list_empty(&ep->queue)) {
		req = list_entry(ep->queue.next, struct pxa27x_request, queue);
		req_done(ep, req, status, &flags);
	}
	spin_unlock_irqrestore(&ep->lock, flags);
}

/**
 * read_packet - transfer 1 packet from an OUT endpoint into request
 * @ep: pxa physical endpoint
 * @req: usb request
 *
 * Takes bytes from OUT endpoint and transfers them info the usb request.
 * If there is less space in request than bytes received in OUT endpoint,
 * bytes are left in the OUT endpoint.
 *
 * Returns how many bytes were actually transferred
 */
static int read_packet(struct pxa_ep *ep, struct pxa27x_request *req)
{
	u32 *buf;
	int bytes_ep, bufferspace, count, i;

	bytes_ep = ep_count_bytes_remain(ep);
	bufferspace = req->req.length - req->req.actual;

	buf = (u32 *)(req->req.buf + req->req.actual);
	prefetchw(buf);

	if (likely(!ep_is_empty(ep)))
		count = min(bytes_ep, bufferspace);
	else /* zlp */
		count = 0;

	for (i = count; i > 0; i -= 4)
		*buf++ = udc_ep_readl(ep, UDCDR);
	req->req.actual += count;

	ep_write_UDCCSR(ep, UDCCSR_PC);

	return count;
}

/**
 * write_packet - transfer 1 packet from request into an IN endpoint
 * @ep: pxa physical endpoint
 * @req: usb request
 * @max: max bytes that fit into endpoint
 *
 * Takes bytes from usb request, and transfers them into the physical
 * endpoint. If there are no bytes to transfer, doesn't write anything
 * to physical endpoint.
 *
 * Returns how many bytes were actually transferred.
 */
static int write_packet(struct pxa_ep *ep, struct pxa27x_request *req,
			unsigned int max)
{
	int length, count, remain, i;
	u32 *buf;
	u8 *buf_8;

	buf = (u32 *)(req->req.buf + req->req.actual);
	prefetch(buf);

	length = min(req->req.length - req->req.actual, max);
	req->req.actual += length;

	remain = length & 0x3;
	count = length & ~(0x3);
	for (i = count; i > 0 ; i -= 4)
		udc_ep_writel(ep, UDCDR, *buf++);

	buf_8 = (u8 *)buf;
	for (i = remain; i > 0; i--)
		udc_ep_writeb(ep, UDCDR, *buf_8++);

	ep_vdbg(ep, "length=%d+%d, udccsr=0x%03x\n", count, remain,
		udc_ep_readl(ep, UDCCSR));

	return length;
}

/**
 * read_fifo - Transfer packets from OUT endpoint into usb request
 * @ep: pxa physical endpoint
 * @req: usb request
 *
 * Context: callable when in_interrupt()
 *
 * Unload as many packets as possible 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.
 * Doesn't complete the request, that's the caller's job
 *
 * Returns 1 if the request completed, 0 otherwise
 */
static int read_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
{
	int count, is_short, completed = 0;

	while (epout_has_pkt(ep)) {
		count = read_packet(ep, req);
		inc_ep_stats_bytes(ep, count, !USB_DIR_IN);

		is_short = (count < ep->fifo_size);
		ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n",
			udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "",
			&req->req, req->req.actual, req->req.length);

		/* completion */
		if (is_short || req->req.actual == req->req.length) {
			completed = 1;
			break;
		}
		/* finished that packet.  the next one may be waiting... */
	}
	return completed;
}

/**
 * write_fifo - transfer packets from usb request into an IN endpoint
 * @ep: pxa physical endpoint
 * @req: pxa usb request
 *
 * 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).
 * Doesn't complete the request, that's the caller's job
 *
 * Returns 1 if request fully transferred, 0 if partial transfer
 */
static int write_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
{
	unsigned max;
	int count, is_short, is_last = 0, completed = 0, totcount = 0;
	u32 udccsr;

	max = ep->fifo_size;
	do {
		is_short = 0;

		udccsr = udc_ep_readl(ep, UDCCSR);
		if (udccsr & UDCCSR_PC) {
			ep_vdbg(ep, "Clearing Transmit Complete, udccsr=%x\n",
				udccsr);
			ep_write_UDCCSR(ep, UDCCSR_PC);
		}
		if (udccsr & UDCCSR_TRN) {
			ep_vdbg(ep, "Clearing Underrun on, udccsr=%x\n",
				udccsr);
			ep_write_UDCCSR(ep, UDCCSR_TRN);
		}

		count = write_packet(ep, req, max);
		inc_ep_stats_bytes(ep, count, USB_DIR_IN);
		totcount += count;

		/* last packet is usually short (or a zlp) */
		if (unlikely(count < max)) {
			is_last = 1;
			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);
		}

		if (is_short)
			ep_write_UDCCSR(ep, UDCCSR_SP);

		/* requests complete when all IN data is in the FIFO */
		if (is_last) {
			completed = 1;
			break;
		}
	} while (!ep_is_full(ep));

	ep_dbg(ep, "wrote count:%d bytes%s%s, left:%d req=%p\n",
			totcount, is_last ? "/L" : "", is_short ? "/S" : "",
			req->req.length - req->req.actual, &req->req);

	return completed;
}

/**
 * read_ep0_fifo - Transfer packets from control endpoint into usb request
 * @ep: control endpoint
 * @req: pxa usb request
 *
 * Special ep0 version of the above read_fifo. Reads as many bytes from control
 * endpoint as can be read, and stores them into usb request (limited by request
 * maximum length).
 *
 * Returns 0 if usb request only partially filled, 1 if fully filled
 */
static int read_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
{
	int count, is_short, completed = 0;

	while (epout_has_pkt(ep)) {
		count = read_packet(ep, req);
		ep_write_UDCCSR(ep, UDCCSR0_OPC);
		inc_ep_stats_bytes(ep, count, !USB_DIR_IN);

		is_short = (count < ep->fifo_size);
		ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n",
			udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "",
			&req->req, req->req.actual, req->req.length);

		if (is_short || req->req.actual >= req->req.length) {
			completed = 1;
			break;
		}
	}

	return completed;
}

/**
 * write_ep0_fifo - Send a request to control endpoint (ep0 in)
 * @ep: control endpoint
 * @req: request
 *
 * Context: callable when in_interrupt()
 *
 * Sends a request (or a part of the request) to the control endpoint (ep0 in).
 * If the request doesn't fit, the remaining part will be sent from irq.
 * The request is considered fully written only if either :
 *   - last write transferred all remaining bytes, but fifo was not fully filled
 *   - last write was a 0 length write
 *
 * Returns 1 if request fully written, 0 if request only partially sent
 */
static int write_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
{
	unsigned	count;
	int		is_last, is_short;

	count = write_packet(ep, req, EP0_FIFO_SIZE);
	inc_ep_stats_bytes(ep, count, USB_DIR_IN);

	is_short = (count < EP0_FIFO_SIZE);
	is_last = ((count == 0) || (count < EP0_FIFO_SIZE));

	/* Sends either a short packet or a 0 length packet */
	if (unlikely(is_short))
		ep_write_UDCCSR(ep, UDCCSR0_IPR);

	ep_dbg(ep, "in %d bytes%s%s, %d left, req=%p, udccsr0=0x%03x\n",
		count, is_short ? "/S" : "", is_last ? "/L" : "",
		req->req.length - req->req.actual,
		&req->req, udc_ep_readl(ep, UDCCSR));

	return is_last;
}

/**
 * pxa_ep_queue - Queue a request into an IN endpoint
 * @_ep: usb endpoint
 * @_req: usb request
 * @gfp_flags: flags
 *
 * Context: normally called when !in_interrupt, but callable when in_interrupt()
 * in the special case of ep0 setup :
 *   (irq->handle_ep0_ctrl_req->gadget_setup->pxa_ep_queue)
 *
 * Returns 0 if succedeed, error otherwise
 */
static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
			gfp_t gfp_flags)
{
	struct udc_usb_ep	*udc_usb_ep;
	struct pxa_ep		*ep;
	struct pxa27x_request	*req;
	struct pxa_udc		*dev;
	unsigned long		flags;
	int			rc = 0;
	int			is_first_req;
	unsigned		length;
	int			recursion_detected;

	req = container_of(_req, struct pxa27x_request, req);
	udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);

	if (unlikely(!_req || !_req->complete || !_req->buf))
		return -EINVAL;

	if (unlikely(!_ep))
		return -EINVAL;

	dev = udc_usb_ep->dev;
	ep = udc_usb_ep->pxa_ep;
	if (unlikely(!ep))
		return -EINVAL;

	dev = ep->dev;
	if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
		ep_dbg(ep, "bogus device state\n");
		return -ESHUTDOWN;
	}

	/* iso is always one packet per request, that's the only way
	 * we can report per-packet status.  that also helps with dma.
	 */
	if (unlikely(EPXFERTYPE_is_ISO(ep)
			&& req->req.length > ep->fifo_size))
		return -EMSGSIZE;

	spin_lock_irqsave(&ep->lock, flags);
	recursion_detected = ep->in_handle_ep;

	is_first_req = list_empty(&ep->queue);
	ep_dbg(ep, "queue req %p(first=%s), len %d buf %p\n",
			_req, is_first_req ? "yes" : "no",
			_req->length, _req->buf);

	if (!ep->enabled) {
		_req->status = -ESHUTDOWN;
		rc = -ESHUTDOWN;
		goto out_locked;
	}

	if (req->in_use) {
		ep_err(ep, "refusing to queue req %p (already queued)\n", req);
		goto out_locked;
	}

	length = _req->length;
	_req->status = -EINPROGRESS;
	_req->actual = 0;

	ep_add_request(ep, req);
	spin_unlock_irqrestore(&ep->lock, flags);

	if (is_ep0(ep)) {
		switch (dev->ep0state) {
		case WAIT_ACK_SET_CONF_INTERF:
			if (length == 0) {
				ep_end_in_req(ep, req, NULL);
			} else {
				ep_err(ep, "got a request of %d bytes while"
					"in state WAIT_ACK_SET_CONF_INTERF\n",
					length);
				ep_del_request(ep, req);
				rc = -EL2HLT;
			}
			ep0_idle(ep->dev);
			break;
		case IN_DATA_STAGE:
			if (!ep_is_full(ep))
				if (write_ep0_fifo(ep, req))
					ep0_end_in_req(ep, req, NULL);
			break;
		case OUT_DATA_STAGE:
			if ((length == 0) || !epout_has_pkt(ep))
				if (read_ep0_fifo(ep, req))
					ep0_end_out_req(ep, req, NULL);
			break;
		default:
			ep_err(ep, "odd state %s to send me a request\n",
				EP0_STNAME(ep->dev));
			ep_del_request(ep, req);
			rc = -EL2HLT;
			break;
		}
	} else {
		if (!recursion_detected)
			handle_ep(ep);
	}

out:
	return rc;
out_locked:
	spin_unlock_irqrestore(&ep->lock, flags);
	goto out;
}

/**
 * pxa_ep_dequeue - Dequeue one request
 * @_ep: usb endpoint
 * @_req: usb request
 *
 * Return 0 if no error, -EINVAL or -ECONNRESET otherwise
 */
static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
{
	struct pxa_ep		*ep;
	struct udc_usb_ep	*udc_usb_ep;
	struct pxa27x_request	*req;
	unsigned long		flags;
	int			rc = -EINVAL;

	if (!_ep)
		return rc;
	udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
	ep = udc_usb_ep->pxa_ep;
	if (!ep || is_ep0(ep))
		return rc;

	spin_lock_irqsave(&ep->lock, flags);

	/* make sure it's actually queued on this endpoint */
	list_for_each_entry(req, &ep->queue, queue) {
		if (&req->req == _req) {
			rc = 0;
			break;
		}
	}

	spin_unlock_irqrestore(&ep->lock, flags);
	if (!rc)
		req_done(ep, req, -ECONNRESET, NULL);
	return rc;
}

/**
 * pxa_ep_set_halt - Halts operations on one endpoint
 * @_ep: usb endpoint
 * @value:
 *
 * Returns 0 if no error, -EINVAL, -EROFS, -EAGAIN otherwise
 */
static int pxa_ep_set_halt(struct usb_ep *_ep, int value)
{
	struct pxa_ep		*ep;
	struct udc_usb_ep	*udc_usb_ep;
	unsigned long flags;
	int rc;


	if (!_ep)
		return -EINVAL;
	udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
	ep = udc_usb_ep->pxa_ep;
	if (!ep || is_ep0(ep))
		return -EINVAL;

	if (value == 0) {
		/*
		 * This path (reset toggle+halt) is needed to implement
		 * SET_INTERFACE on normal hardware.  but it can't be
		 * done from software on the PXA UDC, and the hardware
		 * forgets to do it as part of SET_INTERFACE automagic.
		 */
		ep_dbg(ep, "only host can clear halt\n");
		return -EROFS;
	}

	spin_lock_irqsave(&ep->lock, flags);

	rc = -EAGAIN;
	if (ep->dir_in	&& (ep_is_full(ep) || !list_empty(&ep->queue)))
		goto out;

	/* FST, FEF bits are the same for control and non control endpoints */
	rc = 0;
	ep_write_UDCCSR(ep, UDCCSR_FST | UDCCSR_FEF);
	if (is_ep0(ep))
		set_ep0state(ep->dev, STALL);

out:
	spin_unlock_irqrestore(&ep->lock, flags);
	return rc;
}

/**
 * pxa_ep_fifo_status - Get how many bytes in physical endpoint
 * @_ep: usb endpoint
 *
 * Returns number of bytes in OUT fifos. Broken for IN fifos.
 */
static int pxa_ep_fifo_status(struct usb_ep *_ep)
{
	struct pxa_ep		*ep;
	struct udc_usb_ep	*udc_usb_ep;

	if (!_ep)
		return -ENODEV;
	udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
	ep = udc_usb_ep->pxa_ep;
	if (!ep || is_ep0(ep))
		return -ENODEV;

	if (ep->dir_in)
		return -EOPNOTSUPP;
	if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN || ep_is_empty(ep))
		return 0;
	else
		return ep_count_bytes_remain(ep) + 1;
}

/**
 * pxa_ep_fifo_flush - Flushes one endpoint
 * @_ep: usb endpoint
 *
 * Discards all data in one endpoint(IN or OUT), except control endpoint.
 */
static void pxa_ep_fifo_flush(struct usb_ep *_ep)
{
	struct pxa_ep		*ep;
	struct udc_usb_ep	*udc_usb_ep;
	unsigned long		flags;

	if (!_ep)
		return;
	udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
	ep = udc_usb_ep->pxa_ep;
	if (!ep || is_ep0(ep))
		return;

	spin_lock_irqsave(&ep->lock, flags);

	if (unlikely(!list_empty(&ep->queue)))
		ep_dbg(ep, "called while queue list not empty\n");
	ep_dbg(ep, "called\n");

	/* for OUT, just read and discard the FIFO contents. */
	if (!ep->dir_in) {
		while (!ep_is_empty(ep))
			udc_ep_readl(ep, UDCDR);
	} else {
		/* most IN status is the same, but ISO can't stall */
		ep_write_UDCCSR(ep,
				UDCCSR_PC | UDCCSR_FEF | UDCCSR_TRN
				| (EPXFERTYPE_is_ISO(ep) ? 0 : UDCCSR_SST));
	}

	spin_unlock_irqrestore(&ep->lock, flags);
}

/**
 * pxa_ep_enable - Enables usb endpoint
 * @_ep: usb endpoint
 * @desc: usb endpoint descriptor
 *
 * Nothing much to do here, as ep configuration is done once and for all
 * before udc is enabled. After udc enable, no physical endpoint configuration
 * can be changed.
 * Function makes sanity checks and flushes the endpoint.
 */
static int pxa_ep_enable(struct usb_ep *_ep,
	const struct usb_endpoint_descriptor *desc)
{
	struct pxa_ep		*ep;
	struct udc_usb_ep	*udc_usb_ep;
	struct pxa_udc		*udc;

	if (!_ep || !desc)
		return -EINVAL;

	udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
	if (udc_usb_ep->pxa_ep) {
		ep = udc_usb_ep->pxa_ep;
		ep_warn(ep, "usb_ep %s already enabled, doing nothing\n",
			_ep->name);
	} else {
		ep = find_pxa_ep(udc_usb_ep->dev, udc_usb_ep);
	}

	if (!ep || is_ep0(ep)) {
		dev_err(udc_usb_ep->dev->dev,
			"unable to match pxa_ep for ep %s\n",
			_ep->name);
		return -EINVAL;
	}

	if ((desc->bDescriptorType != USB_DT_ENDPOINT)
			|| (ep->type != usb_endpoint_type(desc))) {
		ep_err(ep, "type mismatch\n");
		return -EINVAL;
	}

	if (ep->fifo_size < usb_endpoint_maxp(desc)) {
		ep_err(ep, "bad maxpacket\n");
		return -ERANGE;
	}

	udc_usb_ep->pxa_ep = ep;
	udc = ep->dev;

	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
		ep_err(ep, "bogus device state\n");
		return -ESHUTDOWN;
	}

	ep->enabled = 1;

	/* flush fifo (mostly for OUT buffers) */
	pxa_ep_fifo_flush(_ep);

	ep_dbg(ep, "enabled\n");
	return 0;
}

/**
 * pxa_ep_disable - Disable usb endpoint
 * @_ep: usb endpoint
 *
 * Same as for pxa_ep_enable, no physical endpoint configuration can be
 * changed.
 * Function flushes the endpoint and related requests.
 */
static int pxa_ep_disable(struct usb_ep *_ep)
{
	struct pxa_ep		*ep;
	struct udc_usb_ep	*udc_usb_ep;

	if (!_ep)
		return -EINVAL;

	udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
	ep = udc_usb_ep->pxa_ep;
	if (!ep || is_ep0(ep) || !list_empty(&ep->queue))
		return -EINVAL;

	ep->enabled = 0;
	nuke(ep, -ESHUTDOWN);

	pxa_ep_fifo_flush(_ep);
	udc_usb_ep->pxa_ep = NULL;

	ep_dbg(ep, "disabled\n");
	return 0;
}

static const struct usb_ep_ops pxa_ep_ops = {
	.enable		= pxa_ep_enable,
	.disable	= pxa_ep_disable,

	.alloc_request	= pxa_ep_alloc_request,
	.free_request	= pxa_ep_free_request,

	.queue		= pxa_ep_queue,
	.dequeue	= pxa_ep_dequeue,

	.set_halt	= pxa_ep_set_halt,
	.fifo_status	= pxa_ep_fifo_status,
	.fifo_flush	= pxa_ep_fifo_flush,
};

/**
 * dplus_pullup - Connect or disconnect pullup resistor to D+ pin
 * @udc: udc device
 * @on: 0 if disconnect pullup resistor, 1 otherwise
 * Context: any
 *
 * Handle D+ pullup resistor, make the device visible to the usb bus, and
 * declare it as a full speed usb device
 */
static void dplus_pullup(struct pxa_udc *udc, int on)
{
	if (udc->gpiod) {
		gpiod_set_value(udc->gpiod, on);
	} else if (udc->udc_command) {
		if (on)
			udc->udc_command(PXA2XX_UDC_CMD_CONNECT);
		else
			udc->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
	}
	udc->pullup_on = on;
}

/**
 * pxa_udc_get_frame - Returns usb frame number
 * @_gadget: usb gadget
 */
static int pxa_udc_get_frame(struct usb_gadget *_gadget)
{
	struct pxa_udc *udc = to_gadget_udc(_gadget);

	return (udc_readl(udc, UDCFNR) & 0x7ff);
}

/**
 * pxa_udc_wakeup - Force udc device out of suspend
 * @_gadget: usb gadget
 *
 * Returns 0 if successful, error code otherwise
 */
static int pxa_udc_wakeup(struct usb_gadget *_gadget)
{
	struct pxa_udc *udc = to_gadget_udc(_gadget);

	/* host may not have enabled remote wakeup */
	if ((udc_readl(udc, UDCCR) & UDCCR_DWRE) == 0)
		return -EHOSTUNREACH;
	udc_set_mask_UDCCR(udc, UDCCR_UDR);
	return 0;
}

static void udc_enable(struct pxa_udc *udc);
static void udc_disable(struct pxa_udc *udc);

/**
 * should_enable_udc - Tells if UDC should be enabled
 * @udc: udc device
 * Context: any
 *
 * The UDC should be enabled if :

 *  - the pullup resistor is connected
 *  - and a gadget driver is bound
 *  - and vbus is sensed (or no vbus sense is available)
 *
 * Returns 1 if UDC should be enabled, 0 otherwise
 */
static int should_enable_udc(struct pxa_udc *udc)
{
	int put_on;

	put_on = ((udc->pullup_on) && (udc->driver));
	put_on &= ((udc->vbus_sensed) || (IS_ERR_OR_NULL(udc->transceiver)));
	return put_on;
}

/**
 * should_disable_udc - Tells if UDC should be disabled
 * @udc: udc device
 * Context: any
 *
 * The UDC should be disabled if :
 *  - the pullup resistor is not connected
 *  - or no gadget driver is bound
 *  - or no vbus is sensed (when vbus sesing is available)
 *
 * Returns 1 if UDC should be disabled
 */
static int should_disable_udc(struct pxa_udc *udc)
{
	int put_off;

	put_off = ((!udc->pullup_on) || (!udc->driver));
	put_off |= ((!udc->vbus_sensed) && (!IS_ERR_OR_NULL(udc->transceiver)));
	return put_off;
}

/**
 * pxa_udc_pullup - Offer manual D+ pullup control
 * @_gadget: usb gadget using the control
 * @is_active: 0 if disconnect, else connect D+ pullup resistor
 * Context: !in_interrupt()
 *
 * Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup
 */
static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active)
{
	struct pxa_udc *udc = to_gadget_udc(_gadget);

	if (!udc->gpiod && !udc->udc_command)
		return -EOPNOTSUPP;

	dplus_pullup(udc, is_active);

	if (should_enable_udc(udc))
		udc_enable(udc);
	if (should_disable_udc(udc))
		udc_disable(udc);
	return 0;
}

/**
 * pxa_udc_vbus_session - Called by external transceiver to enable/disable udc
 * @_gadget: usb gadget
 * @is_active: 0 if should disable the udc, 1 if should enable
 *
 * Enables the udc, and optionnaly activates D+ pullup resistor. Or disables the
 * udc, and deactivates D+ pullup resistor.
 *
 * Returns 0
 */
static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
{
	struct pxa_udc *udc = to_gadget_udc(_gadget);

	udc->vbus_sensed = is_active;
	if (should_enable_udc(udc))
		udc_enable(udc);
	if (should_disable_udc(udc))
		udc_disable(udc);

	return 0;
}

/**
 * pxa_udc_vbus_draw - Called by gadget driver after SET_CONFIGURATION completed
 * @_gadget: usb gadget
 * @mA: current drawn
 *
 * Context: !in_interrupt()
 *
 * Called after a configuration was chosen by a USB host, to inform how much
 * current can be drawn by the device from VBus line.
 *
 * Returns 0 or -EOPNOTSUPP if no transceiver is handling the udc
 */
static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
{
	struct pxa_udc *udc;

	udc = to_gadget_udc(_gadget);
	if (!IS_ERR_OR_NULL(udc->transceiver))
		return usb_phy_set_power(udc->transceiver, mA);
	return -EOPNOTSUPP;
}

/**
 * pxa_udc_phy_event - Called by phy upon VBus event
 * @nb: notifier block
 * @action: phy action, is vbus connect or disconnect
 * @data: the usb_gadget structure in pxa_udc
 *
 * Called by the USB Phy when a cable connect or disconnect is sensed.
 *
 * Returns 0
 */
static int pxa_udc_phy_event(struct notifier_block *nb, unsigned long action,
			     void *data)
{
	struct usb_gadget *gadget = data;

	switch (action) {
	case USB_EVENT_VBUS:
		usb_gadget_vbus_connect(gadget);
		return NOTIFY_OK;
	case USB_EVENT_NONE:
		usb_gadget_vbus_disconnect(gadget);
		return NOTIFY_OK;
	default:
		return NOTIFY_DONE;
	}
}

static struct notifier_block pxa27x_udc_phy = {
	.notifier_call = pxa_udc_phy_event,
};

static int pxa27x_udc_start(struct usb_gadget *g,
		struct usb_gadget_driver *driver);
static int pxa27x_udc_stop(struct usb_gadget *g);

static const struct usb_gadget_ops pxa_udc_ops = {
	.get_frame	= pxa_udc_get_frame,
	.wakeup		= pxa_udc_wakeup,
	.pullup		= pxa_udc_pullup,
	.vbus_session	= pxa_udc_vbus_session,
	.vbus_draw	= pxa_udc_vbus_draw,
	.udc_start	= pxa27x_udc_start,
	.udc_stop	= pxa27x_udc_stop,
};

/**
 * udc_disable - disable udc device controller
 * @udc: udc device
 * Context: any
 *
 * Disables the udc device : disables clocks, udc interrupts, control endpoint
 * interrupts.
 */
static void udc_disable(struct pxa_udc *udc)
{
	if (!udc->enabled)
		return;

	udc_writel(udc, UDCICR0, 0);
	udc_writel(udc, UDCICR1, 0);

	udc_clear_mask_UDCCR(udc, UDCCR_UDE);

	ep0_idle(udc);
	udc->gadget.speed = USB_SPEED_UNKNOWN;
	clk_disable(udc->clk);

	udc->enabled = 0;
}

/**
 * udc_init_data - Initialize udc device data structures
 * @dev: udc device
 *
 * Initializes gadget endpoint list, endpoints locks. No action is taken
 * on the hardware.
 */
static void udc_init_data(struct pxa_udc *dev)
{
	int i;
	struct pxa_ep *ep;

	/* device/ep0 records init */
	INIT_LIST_HEAD(&dev->gadget.ep_list);
	INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
	dev->udc_usb_ep[0].pxa_ep = &dev->pxa_ep[0];
	dev->gadget.quirk_altset_not_supp = 1;
	ep0_idle(dev);

	/* PXA endpoints init */
	for (i = 0; i < NR_PXA_ENDPOINTS; i++) {
		ep = &dev->pxa_ep[i];

		ep->enabled = is_ep0(ep);
		INIT_LIST_HEAD(&ep->queue);
		spin_lock_init(&ep->lock);
	}

	/* USB endpoints init */
	for (i = 1; i < NR_USB_ENDPOINTS; i++) {
		list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
				&dev->gadget.ep_list);
		usb_ep_set_maxpacket_limit(&dev->udc_usb_ep[i].usb_ep,
					   dev->udc_usb_ep[i].usb_ep.maxpacket);
	}
}

/**
 * udc_enable - Enables the udc device
 * @dev: udc device
 *
 * Enables the udc device : enables clocks, udc interrupts, control endpoint
 * interrupts, sets usb as UDC client and setups endpoints.
 */
static void udc_enable(struct pxa_udc *udc)
{
	if (udc->enabled)
		return;

	clk_enable(udc->clk);
	udc_writel(udc, UDCICR0, 0);
	udc_writel(udc, UDCICR1, 0);
	udc_clear_mask_UDCCR(udc, UDCCR_UDE);

	ep0_idle(udc);
	udc->gadget.speed = USB_SPEED_FULL;
	memset(&udc->stats, 0, sizeof(udc->stats));

	pxa_eps_setup(udc);
	udc_set_mask_UDCCR(udc, UDCCR_UDE);
	ep_write_UDCCSR(&udc->pxa_ep[0], UDCCSR0_ACM);
	udelay(2);
	if (udc_readl(udc, UDCCR) & UDCCR_EMCE)
		dev_err(udc->dev, "Configuration errors, udc disabled\n");

	/*
	 * Caller must be able to sleep in order to cope with startup transients
	 */
	msleep(100);

	/* enable suspend/resume and reset irqs */
	udc_writel(udc, UDCICR1,
			UDCICR1_IECC | UDCICR1_IERU
			| UDCICR1_IESU | UDCICR1_IERS);

	/* enable ep0 irqs */
	pio_irq_enable(&udc->pxa_ep[0]);

	udc->enabled = 1;
}

/**
 * pxa27x_start - Register gadget driver
 * @driver: gadget driver
 * @bind: bind function
 *
 * When a driver is successfully registered, it will receive control requests
 * including set_configuration(), which enables non-control requests.  Then
 * usb traffic follows until a disconnect is reported.  Then a host may connect
 * again, or the driver might get unbound.
 *
 * Note that the udc is not automatically enabled. Check function
 * should_enable_udc().
 *
 * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
 */
static int pxa27x_udc_start(struct usb_gadget *g,
		struct usb_gadget_driver *driver)
{
	struct pxa_udc *udc = to_pxa(g);
	int retval;

	/* first hook up the driver ... */
	udc->driver = driver;

	if (!IS_ERR_OR_NULL(udc->transceiver)) {
		retval = otg_set_peripheral(udc->transceiver->otg,
						&udc->gadget);
		if (retval) {
			dev_err(udc->dev, "can't bind to transceiver\n");
			goto fail;
		}
	}

	if (should_enable_udc(udc))
		udc_enable(udc);
	return 0;

fail:
	udc->driver = NULL;
	return retval;
}

/**
 * stop_activity - Stops udc endpoints
 * @udc: udc device
 * @driver: gadget driver
 *
 * Disables all udc endpoints (even control endpoint), report disconnect to
 * the gadget user.
 */
static void stop_activity(struct pxa_udc *udc)
{
	int i;

	udc->gadget.speed = USB_SPEED_UNKNOWN;

	for (i = 0; i < NR_USB_ENDPOINTS; i++)
		pxa_ep_disable(&udc->udc_usb_ep[i].usb_ep);
}

/**
 * pxa27x_udc_stop - Unregister the gadget driver
 * @driver: gadget driver
 *
 * Returns 0 if no error, -ENODEV, -EINVAL otherwise
 */
static int pxa27x_udc_stop(struct usb_gadget *g)
{
	struct pxa_udc *udc = to_pxa(g);

	stop_activity(udc);
	udc_disable(udc);

	udc->driver = NULL;

	if (!IS_ERR_OR_NULL(udc->transceiver))
		return otg_set_peripheral(udc->transceiver->otg, NULL);
	return 0;
}

/**
 * handle_ep0_ctrl_req - handle control endpoint control request
 * @udc: udc device
 * @req: control request
 */
static void handle_ep0_ctrl_req(struct pxa_udc *udc,
				struct pxa27x_request *req)
{
	struct pxa_ep *ep = &udc->pxa_ep[0];
	union {
		struct usb_ctrlrequest	r;
		u32			word[2];
	} u;
	int i;
	int have_extrabytes = 0;
	unsigned long flags;

	nuke(ep, -EPROTO);
	spin_lock_irqsave(&ep->lock, flags);

	/*
	 * In the PXA320 manual, in the section about Back-to-Back setup
	 * packets, it describes this situation.  The solution is to set OPC to
	 * get rid of the status packet, and then continue with the setup
	 * packet. Generalize to pxa27x CPUs.
	 */
	if (epout_has_pkt(ep) && (ep_count_bytes_remain(ep) == 0))
		ep_write_UDCCSR(ep, UDCCSR0_OPC);

	/* read SETUP packet */
	for (i = 0; i < 2; i++) {
		if (unlikely(ep_is_empty(ep)))
			goto stall;
		u.word[i] = udc_ep_readl(ep, UDCDR);
	}

	have_extrabytes = !ep_is_empty(ep);
	while (!ep_is_empty(ep)) {
		i = udc_ep_readl(ep, UDCDR);
		ep_err(ep, "wrong to have extra bytes for setup : 0x%08x\n", i);
	}

	ep_dbg(ep, "SETUP %02x.%02x v%04x i%04x l%04x\n",
		u.r.bRequestType, u.r.bRequest,
		le16_to_cpu(u.r.wValue), le16_to_cpu(u.r.wIndex),
		le16_to_cpu(u.r.wLength));
	if (unlikely(have_extrabytes))
		goto stall;

	if (u.r.bRequestType & USB_DIR_IN)
		set_ep0state(udc, IN_DATA_STAGE);
	else
		set_ep0state(udc, OUT_DATA_STAGE);

	/* Tell UDC to enter Data Stage */
	ep_write_UDCCSR(ep, UDCCSR0_SA | UDCCSR0_OPC);

	spin_unlock_irqrestore(&ep->lock, flags);
	i = udc->driver->setup(&udc->gadget, &u.r);
	spin_lock_irqsave(&ep->lock, flags);
	if (i < 0)
		goto stall;
out:
	spin_unlock_irqrestore(&ep->lock, flags);
	return;
stall:
	ep_dbg(ep, "protocol STALL, udccsr0=%03x err %d\n",
		udc_ep_readl(ep, UDCCSR), i);
	ep_write_UDCCSR(ep, UDCCSR0_FST | UDCCSR0_FTF);
	set_ep0state(udc, STALL);
	goto out;
}

/**
 * handle_ep0 - Handle control endpoint data transfers
 * @udc: udc device
 * @fifo_irq: 1 if triggered by fifo service type irq
 * @opc_irq: 1 if triggered by output packet complete type irq
 *
 * Context : when in_interrupt() or with ep->lock held
 *
 * Tries to transfer all pending request data into the endpoint and/or
 * transfer all pending data in the endpoint into usb requests.
 * Handles states of ep0 automata.
 *
 * PXA27x hardware handles several standard usb control requests without
 * driver notification.  The requests fully handled by hardware are :
 *  SET_ADDRESS, SET_FEATURE, CLEAR_FEATURE, GET_CONFIGURATION, GET_INTERFACE,
 *  GET_STATUS
 * The requests handled by hardware, but with irq notification are :
 *  SYNCH_FRAME, SET_CONFIGURATION, SET_INTERFACE
 * The remaining standard requests really handled by handle_ep0 are :
 *  GET_DESCRIPTOR, SET_DESCRIPTOR, specific requests.
 * Requests standardized outside of USB 2.0 chapter 9 are handled more
 * uniformly, by gadget drivers.
 *
 * The control endpoint state machine is _not_ USB spec compliant, it's even
 * hardly compliant with Intel PXA270 developers guide.
 * The key points which inferred this state machine are :
 *   - on every setup token, bit UDCCSR0_SA is raised and held until cleared by
 *     software.
 *   - on every OUT packet received, UDCCSR0_OPC is raised and held until
 *     cleared by software.
 *   - clearing UDCCSR0_OPC always flushes ep0. If in setup stage, never do it
 *     before reading ep0.
 *     This is true only for PXA27x. This is not true anymore for PXA3xx family
 *     (check Back-to-Back setup packet in developers guide).
 *   - irq can be called on a "packet complete" event (opc_irq=1), while
 *     UDCCSR0_OPC is not yet raised (delta can be as big as 100ms
 *     from experimentation).
 *   - as UDCCSR0_SA can be activated while in irq handling, and clearing
 *     UDCCSR0_OPC would flush the setup data, we almost never clear UDCCSR0_OPC
 *     => we never actually read the "status stage" packet of an IN data stage
 *     => this is not documented in Intel documentation
 *   - hardware as no idea of STATUS STAGE, it only handle SETUP STAGE and DATA
 *     STAGE. The driver add STATUS STAGE to send last zero length packet in
 *     OUT_STATUS_STAGE.
 *   - special attention was needed for IN_STATUS_STAGE. If a packet complete
 *     event is detected, we terminate the status stage without ackowledging the
 *     packet (not to risk to loose a potential SETUP packet)
 */
static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq)
{
	u32			udccsr0;
	struct pxa_ep		*ep = &udc->pxa_ep[0];
	struct pxa27x_request	*req = NULL;
	int			completed = 0;

	if (!list_empty(&ep->queue))
		req = list_entry(ep->queue.next, struct pxa27x_request, queue);

	udccsr0 = udc_ep_readl(ep, UDCCSR);
	ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n",
		EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR),
		(fifo_irq << 1 | opc_irq));

	if (udccsr0 & UDCCSR0_SST) {
		ep_dbg(ep, "clearing stall status\n");
		nuke(ep, -EPIPE);
		ep_write_UDCCSR(ep, UDCCSR0_SST);
		ep0_idle(udc);
	}

	if (udccsr0 & UDCCSR0_SA) {
		nuke(ep, 0);
		set_ep0state(udc, SETUP_STAGE);
	}

	switch (udc->ep0state) {
	case WAIT_FOR_SETUP:
		/*
		 * Hardware bug : beware, we cannot clear OPC, since we would
		 * miss a potential OPC irq for a setup packet.
		 * So, we only do ... nothing, and hope for a next irq with
		 * UDCCSR0_SA set.
		 */
		break;
	case SETUP_STAGE:
		udccsr0 &= UDCCSR0_CTRL_REQ_MASK;
		if (likely(udccsr0 == UDCCSR0_CTRL_REQ_MASK))
			handle_ep0_ctrl_req(udc, req);
		break;
	case IN_DATA_STAGE:			/* GET_DESCRIPTOR */
		if (epout_has_pkt(ep))
			ep_write_UDCCSR(ep, UDCCSR0_OPC);
		if (req && !ep_is_full(ep))
			completed = write_ep0_fifo(ep, req);
		if (completed)
			ep0_end_in_req(ep, req, NULL);
		break;
	case OUT_DATA_STAGE:			/* SET_DESCRIPTOR */
		if (epout_has_pkt(ep) && req)
			completed = read_ep0_fifo(ep, req);
		if (completed)
			ep0_end_out_req(ep, req, NULL);
		break;
	case STALL:
		ep_write_UDCCSR(ep, UDCCSR0_FST);
		break;
	case IN_STATUS_STAGE:
		/*
		 * Hardware bug : beware, we cannot clear OPC, since we would
		 * miss a potential PC irq for a setup packet.
		 * So, we only put the ep0 into WAIT_FOR_SETUP state.
		 */
		if (opc_irq)
			ep0_idle(udc);
		break;
	case OUT_STATUS_STAGE:
	case WAIT_ACK_SET_CONF_INTERF:
		ep_warn(ep, "should never get in %s state here!!!\n",
				EP0_STNAME(ep->dev));
		ep0_idle(udc);
		break;
	}
}

/**
 * handle_ep - Handle endpoint data tranfers
 * @ep: pxa physical endpoint
 *
 * Tries to transfer all pending request data into the endpoint and/or
 * transfer all pending data in the endpoint into usb requests.
 *
 * Is always called when in_interrupt() and with ep->lock released.
 */
static void handle_ep(struct pxa_ep *ep)
{
	struct pxa27x_request	*req;
	int completed;
	u32 udccsr;
	int is_in = ep->dir_in;
	int loop = 0;
	unsigned long		flags;

	spin_lock_irqsave(&ep->lock, flags);
	if (ep->in_handle_ep)
		goto recursion_detected;
	ep->in_handle_ep = 1;

	do {
		completed = 0;
		udccsr = udc_ep_readl(ep, UDCCSR);

		if (likely(!list_empty(&ep->queue)))
			req = list_entry(ep->queue.next,
					struct pxa27x_request, queue);
		else
			req = NULL;

		ep_dbg(ep, "req:%p, udccsr 0x%03x loop=%d\n",
				req, udccsr, loop++);

		if (unlikely(udccsr & (UDCCSR_SST | UDCCSR_TRN)))
			udc_ep_writel(ep, UDCCSR,
					udccsr & (UDCCSR_SST | UDCCSR_TRN));
		if (!req)
			break;

		if (unlikely(is_in)) {
			if (likely(!ep_is_full(ep)))
				completed = write_fifo(ep, req);
		} else {
			if (likely(epout_has_pkt(ep)))
				completed = read_fifo(ep, req);
		}

		if (completed) {
			if (is_in)
				ep_end_in_req(ep, req, &flags);
			else
				ep_end_out_req(ep, req, &flags);
		}
	} while (completed);

	ep->in_handle_ep = 0;
recursion_detected:
	spin_unlock_irqrestore(&ep->lock, flags);
}

/**
 * pxa27x_change_configuration - Handle SET_CONF usb request notification
 * @udc: udc device
 * @config: usb configuration
 *
 * Post the request to upper level.
 * Don't use any pxa specific harware configuration capabilities
 */
static void pxa27x_change_configuration(struct pxa_udc *udc, int config)
{
	struct usb_ctrlrequest req ;

	dev_dbg(udc->dev, "config=%d\n", config);

	udc->config = config;
	udc->last_interface = 0;
	udc->last_alternate = 0;

	req.bRequestType = 0;
	req.bRequest = USB_REQ_SET_CONFIGURATION;
	req.wValue = config;
	req.wIndex = 0;
	req.wLength = 0;

	set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF);
	udc->driver->setup(&udc->gadget, &req);
	ep_write_UDCCSR(&udc->pxa_ep[0], UDCCSR0_AREN);
}

/**
 * pxa27x_change_interface - Handle SET_INTERF usb request notification
 * @udc: udc device
 * @iface: interface number
 * @alt: alternate setting number
 *
 * Post the request to upper level.
 * Don't use any pxa specific harware configuration capabilities
 */
static void pxa27x_change_interface(struct pxa_udc *udc, int iface, int alt)
{
	struct usb_ctrlrequest  req;

	dev_dbg(udc->dev, "interface=%d, alternate setting=%d\n", iface, alt);

	udc->last_interface = iface;
	udc->last_alternate = alt;

	req.bRequestType = USB_RECIP_INTERFACE;
	req.bRequest = USB_REQ_SET_INTERFACE;
	req.wValue = alt;
	req.wIndex = iface;
	req.wLength = 0;

	set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF);
	udc->driver->setup(&udc->gadget, &req);
	ep_write_UDCCSR(&udc->pxa_ep[0], UDCCSR0_AREN);
}

/*
 * irq_handle_data - Handle data transfer
 * @irq: irq IRQ number
 * @udc: dev pxa_udc device structure
 *
 * Called from irq handler, transferts data to or from endpoint to queue
 */
static void irq_handle_data(int irq, struct pxa_udc *udc)
{
	int i;
	struct pxa_ep *ep;
	u32 udcisr0 = udc_readl(udc, UDCISR0) & UDCCISR0_EP_MASK;
	u32 udcisr1 = udc_readl(udc, UDCISR1) & UDCCISR1_EP_MASK;

	if (udcisr0 & UDCISR_INT_MASK) {
		udc->pxa_ep[0].stats.irqs++;
		udc_writel(udc, UDCISR0, UDCISR_INT(0, UDCISR_INT_MASK));
		handle_ep0(udc, !!(udcisr0 & UDCICR_FIFOERR),
				!!(udcisr0 & UDCICR_PKTCOMPL));
	}

	udcisr0 >>= 2;
	for (i = 1; udcisr0 != 0 && i < 16; udcisr0 >>= 2, i++) {
		if (!(udcisr0 & UDCISR_INT_MASK))
			continue;

		udc_writel(udc, UDCISR0, UDCISR_INT(i, UDCISR_INT_MASK));

		WARN_ON(i >= ARRAY_SIZE(udc->pxa_ep));
		if (i < ARRAY_SIZE(udc->pxa_ep)) {
			ep = &udc->pxa_ep[i];
			ep->stats.irqs++;
			handle_ep(ep);
		}
	}

	for (i = 16; udcisr1 != 0 && i < 24; udcisr1 >>= 2, i++) {
		udc_writel(udc, UDCISR1, UDCISR_INT(i - 16, UDCISR_INT_MASK));
		if (!(udcisr1 & UDCISR_INT_MASK))
			continue;

		WARN_ON(i >= ARRAY_SIZE(udc->pxa_ep));
		if (i < ARRAY_SIZE(udc->pxa_ep)) {
			ep = &udc->pxa_ep[i];
			ep->stats.irqs++;
			handle_ep(ep);
		}
	}

}

/**
 * irq_udc_suspend - Handle IRQ "UDC Suspend"
 * @udc: udc device
 */
static void irq_udc_suspend(struct pxa_udc *udc)
{
	udc_writel(udc, UDCISR1, UDCISR1_IRSU);
	udc->stats.irqs_suspend++;

	if (udc->gadget.speed != USB_SPEED_UNKNOWN
			&& udc->driver && udc->driver->suspend)
		udc->driver->suspend(&udc->gadget);
	ep0_idle(udc);
}

/**
  * irq_udc_resume - Handle IRQ "UDC Resume"
  * @udc: udc device
  */
static void irq_udc_resume(struct pxa_udc *udc)
{
	udc_writel(udc, UDCISR1, UDCISR1_IRRU);
	udc->stats.irqs_resume++;

	if (udc->gadget.speed != USB_SPEED_UNKNOWN
			&& udc->driver && udc->driver->resume)
		udc->driver->resume(&udc->gadget);
}

/**
 * irq_udc_reconfig - Handle IRQ "UDC Change Configuration"
 * @udc: udc device
 */
static void irq_udc_reconfig(struct pxa_udc *udc)
{
	unsigned config, interface, alternate, config_change;
	u32 udccr = udc_readl(udc, UDCCR);

	udc_writel(udc, UDCISR1, UDCISR1_IRCC);
	udc->stats.irqs_reconfig++;

	config = (udccr & UDCCR_ACN) >> UDCCR_ACN_S;
	config_change = (config != udc->config);
	pxa27x_change_configuration(udc, config);

	interface = (udccr & UDCCR_AIN) >> UDCCR_AIN_S;
	alternate = (udccr & UDCCR_AAISN) >> UDCCR_AAISN_S;
	pxa27x_change_interface(udc, interface, alternate);

	if (config_change)
		update_pxa_ep_matches(udc);
	udc_set_mask_UDCCR(udc, UDCCR_SMAC);
}

/**
 * irq_udc_reset - Handle IRQ "UDC Reset"
 * @udc: udc device
 */
static void irq_udc_reset(struct pxa_udc *udc)
{
	u32 udccr = udc_readl(udc, UDCCR);
	struct pxa_ep *ep = &udc->pxa_ep[0];

	dev_info(udc->dev, "USB reset\n");
	udc_writel(udc, UDCISR1, UDCISR1_IRRS);
	udc->stats.irqs_reset++;

	if ((udccr & UDCCR_UDA) == 0) {
		dev_dbg(udc->dev, "USB reset start\n");
		stop_activity(udc);
	}
	udc->gadget.speed = USB_SPEED_FULL;
	memset(&udc->stats, 0, sizeof udc->stats);

	nuke(ep, -EPROTO);
	ep_write_UDCCSR(ep, UDCCSR0_FTF | UDCCSR0_OPC);
	ep0_idle(udc);
}

/**
 * pxa_udc_irq - Main irq handler
 * @irq: irq number
 * @_dev: udc device
 *
 * Handles all udc interrupts
 */
static irqreturn_t pxa_udc_irq(int irq, void *_dev)
{
	struct pxa_udc *udc = _dev;
	u32 udcisr0 = udc_readl(udc, UDCISR0);
	u32 udcisr1 = udc_readl(udc, UDCISR1);
	u32 udccr = udc_readl(udc, UDCCR);
	u32 udcisr1_spec;

	dev_vdbg(udc->dev, "Interrupt, UDCISR0:0x%08x, UDCISR1:0x%08x, "
		 "UDCCR:0x%08x\n", udcisr0, udcisr1, udccr);

	udcisr1_spec = udcisr1 & 0xf8000000;
	if (unlikely(udcisr1_spec & UDCISR1_IRSU))
		irq_udc_suspend(udc);
	if (unlikely(udcisr1_spec & UDCISR1_IRRU))
		irq_udc_resume(udc);
	if (unlikely(udcisr1_spec & UDCISR1_IRCC))
		irq_udc_reconfig(udc);
	if (unlikely(udcisr1_spec & UDCISR1_IRRS))
		irq_udc_reset(udc);

	if ((udcisr0 & UDCCISR0_EP_MASK) | (udcisr1 & UDCCISR1_EP_MASK))
		irq_handle_data(irq, udc);

	return IRQ_HANDLED;
}

static struct pxa_udc memory = {
	.gadget = {
		.ops		= &pxa_udc_ops,
		.ep0		= &memory.udc_usb_ep[0].usb_ep,
		.name		= driver_name,
		.dev = {
			.init_name	= "gadget",
		},
	},

	.udc_usb_ep = {
		USB_EP_CTRL,
		USB_EP_OUT_BULK(1),
		USB_EP_IN_BULK(2),
		USB_EP_IN_ISO(3),
		USB_EP_OUT_ISO(4),
		USB_EP_IN_INT(5),
	},

	.pxa_ep = {
		PXA_EP_CTRL,
		/* Endpoints for gadget zero */
		PXA_EP_OUT_BULK(1, 1, 3, 0, 0),
		PXA_EP_IN_BULK(2,  2, 3, 0, 0),
		/* Endpoints for ether gadget, file storage gadget */
		PXA_EP_OUT_BULK(3, 1, 1, 0, 0),
		PXA_EP_IN_BULK(4,  2, 1, 0, 0),
		PXA_EP_IN_ISO(5,   3, 1, 0, 0),
		PXA_EP_OUT_ISO(6,  4, 1, 0, 0),
		PXA_EP_IN_INT(7,   5, 1, 0, 0),
		/* Endpoints for RNDIS, serial */
		PXA_EP_OUT_BULK(8, 1, 2, 0, 0),
		PXA_EP_IN_BULK(9,  2, 2, 0, 0),
		PXA_EP_IN_INT(10,  5, 2, 0, 0),
		/*
		 * All the following endpoints are only for completion.  They
		 * won't never work, as multiple interfaces are really broken on
		 * the pxa.
		*/
		PXA_EP_OUT_BULK(11, 1, 2, 1, 0),
		PXA_EP_IN_BULK(12,  2, 2, 1, 0),
		/* Endpoint for CDC Ether */
		PXA_EP_OUT_BULK(13, 1, 1, 1, 1),
		PXA_EP_IN_BULK(14,  2, 1, 1, 1),
	}
};

#if defined(CONFIG_OF)
static const struct of_device_id udc_pxa_dt_ids[] = {
	{ .compatible = "marvell,pxa270-udc" },
	{}
};
MODULE_DEVICE_TABLE(of, udc_pxa_dt_ids);
#endif

/**
 * pxa_udc_probe - probes the udc device
 * @_dev: platform device
 *
 * Perform basic init : allocates udc clock, creates sysfs files, requests
 * irq.
 */
static int pxa_udc_probe(struct platform_device *pdev)
{
	struct resource *regs;
	struct pxa_udc *udc = &memory;
	int retval = 0, gpio;
	struct pxa2xx_udc_mach_info *mach = dev_get_platdata(&pdev->dev);
	unsigned long gpio_flags;

	if (mach) {
		gpio_flags = mach->gpio_pullup_inverted ? GPIOF_ACTIVE_LOW : 0;
		gpio = mach->gpio_pullup;
		if (gpio_is_valid(gpio)) {
			retval = devm_gpio_request_one(&pdev->dev, gpio,
						       gpio_flags,
						       "USB D+ pullup");
			if (retval)
				return retval;
			udc->gpiod = gpio_to_desc(mach->gpio_pullup);
		}
		udc->udc_command = mach->udc_command;
	} else {
		udc->gpiod = devm_gpiod_get(&pdev->dev, NULL, GPIOD_ASIS);
	}

	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	udc->regs = devm_ioremap_resource(&pdev->dev, regs);
	if (IS_ERR(udc->regs))
		return PTR_ERR(udc->regs);
	udc->irq = platform_get_irq(pdev, 0);
	if (udc->irq < 0)
		return udc->irq;

	udc->dev = &pdev->dev;
	if (of_have_populated_dt()) {
		udc->transceiver =
			devm_usb_get_phy_by_phandle(udc->dev, "phys", 0);
		if (IS_ERR(udc->transceiver))
			return PTR_ERR(udc->transceiver);
	} else {
		udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
	}

	if (IS_ERR(udc->gpiod)) {
		dev_err(&pdev->dev, "Couldn't find or request D+ gpio : %ld\n",
			PTR_ERR(udc->gpiod));
		return PTR_ERR(udc->gpiod);
	}
	if (udc->gpiod)
		gpiod_direction_output(udc->gpiod, 0);

	udc->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(udc->clk))
		return PTR_ERR(udc->clk);

	retval = clk_prepare(udc->clk);
	if (retval)
		return retval;

	udc->vbus_sensed = 0;

	the_controller = udc;
	platform_set_drvdata(pdev, udc);
	udc_init_data(udc);

	/* irq setup after old hardware state is cleaned up */
	retval = devm_request_irq(&pdev->dev, udc->irq, pxa_udc_irq,
				  IRQF_SHARED, driver_name, udc);
	if (retval != 0) {
		dev_err(udc->dev, "%s: can't get irq %i, err %d\n",
			driver_name, udc->irq, retval);
		goto err;
	}

	if (!IS_ERR_OR_NULL(udc->transceiver))
		usb_register_notifier(udc->transceiver, &pxa27x_udc_phy);
	retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
	if (retval)
		goto err_add_gadget;

	pxa_init_debugfs(udc);
	if (should_enable_udc(udc))
		udc_enable(udc);
	return 0;

err_add_gadget:
	if (!IS_ERR_OR_NULL(udc->transceiver))
		usb_unregister_notifier(udc->transceiver, &pxa27x_udc_phy);
err:
	clk_unprepare(udc->clk);
	return retval;
}

/**
 * pxa_udc_remove - removes the udc device driver
 * @_dev: platform device
 */
static int pxa_udc_remove(struct platform_device *_dev)
{
	struct pxa_udc *udc = platform_get_drvdata(_dev);

	usb_del_gadget_udc(&udc->gadget);
	pxa_cleanup_debugfs(udc);

	if (!IS_ERR_OR_NULL(udc->transceiver)) {
		usb_unregister_notifier(udc->transceiver, &pxa27x_udc_phy);
		usb_put_phy(udc->transceiver);
	}

	udc->transceiver = NULL;
	the_controller = NULL;
	clk_unprepare(udc->clk);

	return 0;
}

static void pxa_udc_shutdown(struct platform_device *_dev)
{
	struct pxa_udc *udc = platform_get_drvdata(_dev);

	if (udc_readl(udc, UDCCR) & UDCCR_UDE)
		udc_disable(udc);
}

#ifdef CONFIG_PXA27x
extern void pxa27x_clear_otgph(void);
#else
#define pxa27x_clear_otgph()   do {} while (0)
#endif

#ifdef CONFIG_PM
/**
 * pxa_udc_suspend - Suspend udc device
 * @_dev: platform device
 * @state: suspend state
 *
 * Suspends udc : saves configuration registers (UDCCR*), then disables the udc
 * device.
 */
static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state)
{
	struct pxa_udc *udc = platform_get_drvdata(_dev);
	struct pxa_ep *ep;

	ep = &udc->pxa_ep[0];
	udc->udccsr0 = udc_ep_readl(ep, UDCCSR);

	udc_disable(udc);
	udc->pullup_resume = udc->pullup_on;
	dplus_pullup(udc, 0);

	if (udc->driver)
		udc->driver->disconnect(&udc->gadget);

	return 0;
}

/**
 * pxa_udc_resume - Resume udc device
 * @_dev: platform device
 *
 * Resumes udc : restores configuration registers (UDCCR*), then enables the udc
 * device.
 */
static int pxa_udc_resume(struct platform_device *_dev)
{
	struct pxa_udc *udc = platform_get_drvdata(_dev);
	struct pxa_ep *ep;

	ep = &udc->pxa_ep[0];
	udc_ep_writel(ep, UDCCSR, udc->udccsr0 & (UDCCSR0_FST | UDCCSR0_DME));

	dplus_pullup(udc, udc->pullup_resume);
	if (should_enable_udc(udc))
		udc_enable(udc);
	/*
	 * We do not handle OTG yet.
	 *
	 * OTGPH bit is set when sleep mode is entered.
	 * it indicates that OTG pad is retaining its state.
	 * Upon exit from sleep mode and before clearing OTGPH,
	 * Software must configure the USB OTG pad, UDC, and UHC
	 * to the state they were in before entering sleep mode.
	 */
	pxa27x_clear_otgph();

	return 0;
}
#endif

/* work with hotplug and coldplug */
MODULE_ALIAS("platform:pxa27x-udc");

static struct platform_driver udc_driver = {
	.driver		= {
		.name	= "pxa27x-udc",
		.of_match_table = of_match_ptr(udc_pxa_dt_ids),
	},
	.probe		= pxa_udc_probe,
	.remove		= pxa_udc_remove,
	.shutdown	= pxa_udc_shutdown,
#ifdef CONFIG_PM
	.suspend	= pxa_udc_suspend,
	.resume		= pxa_udc_resume
#endif
};

module_platform_driver(udc_driver);

MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR("Robert Jarzmik");
MODULE_LICENSE("GPL");
