162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * USB Peripheral Controller driver for Aeroflex Gaisler GRUSBDC.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * 2013 (c) Aeroflex Gaisler AB
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * This driver supports GRUSBDC USB Device Controller cores available in the
862306a36Sopenharmony_ci * GRLIB VHDL IP core library.
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * Full documentation of the GRUSBDC core can be found here:
1162306a36Sopenharmony_ci * https://www.gaisler.com/products/grlib/grip.pdf
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * Contributors:
1462306a36Sopenharmony_ci * - Andreas Larsson <andreas@gaisler.com>
1562306a36Sopenharmony_ci * - Marko Isomaki
1662306a36Sopenharmony_ci */
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/*
1962306a36Sopenharmony_ci * A GRUSBDC core can have up to 16 IN endpoints and 16 OUT endpoints each
2062306a36Sopenharmony_ci * individually configurable to any of the four USB transfer types. This driver
2162306a36Sopenharmony_ci * only supports cores in DMA mode.
2262306a36Sopenharmony_ci */
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#include <linux/kernel.h>
2562306a36Sopenharmony_ci#include <linux/module.h>
2662306a36Sopenharmony_ci#include <linux/platform_device.h>
2762306a36Sopenharmony_ci#include <linux/slab.h>
2862306a36Sopenharmony_ci#include <linux/spinlock.h>
2962306a36Sopenharmony_ci#include <linux/errno.h>
3062306a36Sopenharmony_ci#include <linux/list.h>
3162306a36Sopenharmony_ci#include <linux/interrupt.h>
3262306a36Sopenharmony_ci#include <linux/device.h>
3362306a36Sopenharmony_ci#include <linux/usb.h>
3462306a36Sopenharmony_ci#include <linux/usb/ch9.h>
3562306a36Sopenharmony_ci#include <linux/usb/gadget.h>
3662306a36Sopenharmony_ci#include <linux/dma-mapping.h>
3762306a36Sopenharmony_ci#include <linux/dmapool.h>
3862306a36Sopenharmony_ci#include <linux/debugfs.h>
3962306a36Sopenharmony_ci#include <linux/seq_file.h>
4062306a36Sopenharmony_ci#include <linux/of.h>
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#include <asm/byteorder.h>
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#include "gr_udc.h"
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci#define	DRIVER_NAME	"gr_udc"
4762306a36Sopenharmony_ci#define	DRIVER_DESC	"Aeroflex Gaisler GRUSBDC USB Peripheral Controller"
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic const char driver_name[] = DRIVER_NAME;
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#define gr_read32(x) (ioread32be((x)))
5262306a36Sopenharmony_ci#define gr_write32(x, v) (iowrite32be((v), (x)))
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* USB speed and corresponding string calculated from status register value */
5562306a36Sopenharmony_ci#define GR_SPEED(status) \
5662306a36Sopenharmony_ci	((status & GR_STATUS_SP) ? USB_SPEED_FULL : USB_SPEED_HIGH)
5762306a36Sopenharmony_ci#define GR_SPEED_STR(status) usb_speed_string(GR_SPEED(status))
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/* Size of hardware buffer calculated from epctrl register value */
6062306a36Sopenharmony_ci#define GR_BUFFER_SIZE(epctrl)					      \
6162306a36Sopenharmony_ci	((((epctrl) & GR_EPCTRL_BUFSZ_MASK) >> GR_EPCTRL_BUFSZ_POS) * \
6262306a36Sopenharmony_ci	 GR_EPCTRL_BUFSZ_SCALER)
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/* ---------------------------------------------------------------------- */
6562306a36Sopenharmony_ci/* Debug printout functionality */
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistatic const char * const gr_modestring[] = {"control", "iso", "bulk", "int"};
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistatic const char *gr_ep0state_string(enum gr_ep0state state)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	static const char *const names[] = {
7262306a36Sopenharmony_ci		[GR_EP0_DISCONNECT] = "disconnect",
7362306a36Sopenharmony_ci		[GR_EP0_SETUP] = "setup",
7462306a36Sopenharmony_ci		[GR_EP0_IDATA] = "idata",
7562306a36Sopenharmony_ci		[GR_EP0_ODATA] = "odata",
7662306a36Sopenharmony_ci		[GR_EP0_ISTATUS] = "istatus",
7762306a36Sopenharmony_ci		[GR_EP0_OSTATUS] = "ostatus",
7862306a36Sopenharmony_ci		[GR_EP0_STALL] = "stall",
7962306a36Sopenharmony_ci		[GR_EP0_SUSPEND] = "suspend",
8062306a36Sopenharmony_ci	};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	if (state < 0 || state >= ARRAY_SIZE(names))
8362306a36Sopenharmony_ci		return "UNKNOWN";
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	return names[state];
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci#ifdef VERBOSE_DEBUG
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_cistatic void gr_dbgprint_request(const char *str, struct gr_ep *ep,
9162306a36Sopenharmony_ci				struct gr_request *req)
9262306a36Sopenharmony_ci{
9362306a36Sopenharmony_ci	int buflen = ep->is_in ? req->req.length : req->req.actual;
9462306a36Sopenharmony_ci	int rowlen = 32;
9562306a36Sopenharmony_ci	int plen = min(rowlen, buflen);
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	dev_dbg(ep->dev->dev, "%s: 0x%p, %d bytes data%s:\n", str, req, buflen,
9862306a36Sopenharmony_ci		(buflen > plen ? " (truncated)" : ""));
9962306a36Sopenharmony_ci	print_hex_dump_debug("   ", DUMP_PREFIX_NONE,
10062306a36Sopenharmony_ci			     rowlen, 4, req->req.buf, plen, false);
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cistatic void gr_dbgprint_devreq(struct gr_udc *dev, u8 type, u8 request,
10462306a36Sopenharmony_ci			       u16 value, u16 index, u16 length)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	dev_vdbg(dev->dev, "REQ: %02x.%02x v%04x i%04x l%04x\n",
10762306a36Sopenharmony_ci		 type, request, value, index, length);
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci#else /* !VERBOSE_DEBUG */
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cistatic void gr_dbgprint_request(const char *str, struct gr_ep *ep,
11262306a36Sopenharmony_ci				struct gr_request *req) {}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistatic void gr_dbgprint_devreq(struct gr_udc *dev, u8 type, u8 request,
11562306a36Sopenharmony_ci			       u16 value, u16 index, u16 length) {}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#endif /* VERBOSE_DEBUG */
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/* ---------------------------------------------------------------------- */
12062306a36Sopenharmony_ci/* Debugfs functionality */
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci#ifdef CONFIG_USB_GADGET_DEBUG_FS
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_cistatic void gr_seq_ep_show(struct seq_file *seq, struct gr_ep *ep)
12562306a36Sopenharmony_ci{
12662306a36Sopenharmony_ci	u32 epctrl = gr_read32(&ep->regs->epctrl);
12762306a36Sopenharmony_ci	u32 epstat = gr_read32(&ep->regs->epstat);
12862306a36Sopenharmony_ci	int mode = (epctrl & GR_EPCTRL_TT_MASK) >> GR_EPCTRL_TT_POS;
12962306a36Sopenharmony_ci	struct gr_request *req;
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	seq_printf(seq, "%s:\n", ep->ep.name);
13262306a36Sopenharmony_ci	seq_printf(seq, "  mode = %s\n", gr_modestring[mode]);
13362306a36Sopenharmony_ci	seq_printf(seq, "  halted: %d\n", !!(epctrl & GR_EPCTRL_EH));
13462306a36Sopenharmony_ci	seq_printf(seq, "  disabled: %d\n", !!(epctrl & GR_EPCTRL_ED));
13562306a36Sopenharmony_ci	seq_printf(seq, "  valid: %d\n", !!(epctrl & GR_EPCTRL_EV));
13662306a36Sopenharmony_ci	seq_printf(seq, "  dma_start = %d\n", ep->dma_start);
13762306a36Sopenharmony_ci	seq_printf(seq, "  stopped = %d\n", ep->stopped);
13862306a36Sopenharmony_ci	seq_printf(seq, "  wedged = %d\n", ep->wedged);
13962306a36Sopenharmony_ci	seq_printf(seq, "  callback = %d\n", ep->callback);
14062306a36Sopenharmony_ci	seq_printf(seq, "  maxpacket = %d\n", ep->ep.maxpacket);
14162306a36Sopenharmony_ci	seq_printf(seq, "  maxpacket_limit = %d\n", ep->ep.maxpacket_limit);
14262306a36Sopenharmony_ci	seq_printf(seq, "  bytes_per_buffer = %d\n", ep->bytes_per_buffer);
14362306a36Sopenharmony_ci	if (mode == 1 || mode == 3)
14462306a36Sopenharmony_ci		seq_printf(seq, "  nt = %d\n",
14562306a36Sopenharmony_ci			   (epctrl & GR_EPCTRL_NT_MASK) >> GR_EPCTRL_NT_POS);
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	seq_printf(seq, "  Buffer 0: %s %s%d\n",
14862306a36Sopenharmony_ci		   epstat & GR_EPSTAT_B0 ? "valid" : "invalid",
14962306a36Sopenharmony_ci		   epstat & GR_EPSTAT_BS ? " " : "selected ",
15062306a36Sopenharmony_ci		   (epstat & GR_EPSTAT_B0CNT_MASK) >> GR_EPSTAT_B0CNT_POS);
15162306a36Sopenharmony_ci	seq_printf(seq, "  Buffer 1: %s %s%d\n",
15262306a36Sopenharmony_ci		   epstat & GR_EPSTAT_B1 ? "valid" : "invalid",
15362306a36Sopenharmony_ci		   epstat & GR_EPSTAT_BS ? "selected " : " ",
15462306a36Sopenharmony_ci		   (epstat & GR_EPSTAT_B1CNT_MASK) >> GR_EPSTAT_B1CNT_POS);
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	if (list_empty(&ep->queue)) {
15762306a36Sopenharmony_ci		seq_puts(seq, "  Queue: empty\n\n");
15862306a36Sopenharmony_ci		return;
15962306a36Sopenharmony_ci	}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	seq_puts(seq, "  Queue:\n");
16262306a36Sopenharmony_ci	list_for_each_entry(req, &ep->queue, queue) {
16362306a36Sopenharmony_ci		struct gr_dma_desc *desc;
16462306a36Sopenharmony_ci		struct gr_dma_desc *next;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci		seq_printf(seq, "    0x%p: 0x%p %d %d\n", req,
16762306a36Sopenharmony_ci			   &req->req.buf, req->req.actual, req->req.length);
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci		next = req->first_desc;
17062306a36Sopenharmony_ci		do {
17162306a36Sopenharmony_ci			desc = next;
17262306a36Sopenharmony_ci			next = desc->next_desc;
17362306a36Sopenharmony_ci			seq_printf(seq, "    %c 0x%p (0x%08x): 0x%05x 0x%08x\n",
17462306a36Sopenharmony_ci				   desc == req->curr_desc ? 'c' : ' ',
17562306a36Sopenharmony_ci				   desc, desc->paddr, desc->ctrl, desc->data);
17662306a36Sopenharmony_ci		} while (desc != req->last_desc);
17762306a36Sopenharmony_ci	}
17862306a36Sopenharmony_ci	seq_puts(seq, "\n");
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_cistatic int gr_dfs_show(struct seq_file *seq, void *v)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	struct gr_udc *dev = seq->private;
18462306a36Sopenharmony_ci	u32 control = gr_read32(&dev->regs->control);
18562306a36Sopenharmony_ci	u32 status = gr_read32(&dev->regs->status);
18662306a36Sopenharmony_ci	struct gr_ep *ep;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	seq_printf(seq, "usb state = %s\n",
18962306a36Sopenharmony_ci		   usb_state_string(dev->gadget.state));
19062306a36Sopenharmony_ci	seq_printf(seq, "address = %d\n",
19162306a36Sopenharmony_ci		   (control & GR_CONTROL_UA_MASK) >> GR_CONTROL_UA_POS);
19262306a36Sopenharmony_ci	seq_printf(seq, "speed = %s\n", GR_SPEED_STR(status));
19362306a36Sopenharmony_ci	seq_printf(seq, "ep0state = %s\n", gr_ep0state_string(dev->ep0state));
19462306a36Sopenharmony_ci	seq_printf(seq, "irq_enabled = %d\n", dev->irq_enabled);
19562306a36Sopenharmony_ci	seq_printf(seq, "remote_wakeup = %d\n", dev->remote_wakeup);
19662306a36Sopenharmony_ci	seq_printf(seq, "test_mode = %d\n", dev->test_mode);
19762306a36Sopenharmony_ci	seq_puts(seq, "\n");
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	list_for_each_entry(ep, &dev->ep_list, ep_list)
20062306a36Sopenharmony_ci		gr_seq_ep_show(seq, ep);
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	return 0;
20362306a36Sopenharmony_ci}
20462306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(gr_dfs);
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_cistatic void gr_dfs_create(struct gr_udc *dev)
20762306a36Sopenharmony_ci{
20862306a36Sopenharmony_ci	const char *name = "gr_udc_state";
20962306a36Sopenharmony_ci	struct dentry *root;
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	root = debugfs_create_dir(dev_name(dev->dev), usb_debug_root);
21262306a36Sopenharmony_ci	debugfs_create_file(name, 0444, root, dev, &gr_dfs_fops);
21362306a36Sopenharmony_ci}
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_cistatic void gr_dfs_delete(struct gr_udc *dev)
21662306a36Sopenharmony_ci{
21762306a36Sopenharmony_ci	debugfs_lookup_and_remove(dev_name(dev->dev), usb_debug_root);
21862306a36Sopenharmony_ci}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci#else /* !CONFIG_USB_GADGET_DEBUG_FS */
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_cistatic void gr_dfs_create(struct gr_udc *dev) {}
22362306a36Sopenharmony_cistatic void gr_dfs_delete(struct gr_udc *dev) {}
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci#endif /* CONFIG_USB_GADGET_DEBUG_FS */
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci/* ---------------------------------------------------------------------- */
22862306a36Sopenharmony_ci/* DMA and request handling */
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci/* Allocates a new struct gr_dma_desc, sets paddr and zeroes the rest */
23162306a36Sopenharmony_cistatic struct gr_dma_desc *gr_alloc_dma_desc(struct gr_ep *ep, gfp_t gfp_flags)
23262306a36Sopenharmony_ci{
23362306a36Sopenharmony_ci	dma_addr_t paddr;
23462306a36Sopenharmony_ci	struct gr_dma_desc *dma_desc;
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	dma_desc = dma_pool_zalloc(ep->dev->desc_pool, gfp_flags, &paddr);
23762306a36Sopenharmony_ci	if (!dma_desc) {
23862306a36Sopenharmony_ci		dev_err(ep->dev->dev, "Could not allocate from DMA pool\n");
23962306a36Sopenharmony_ci		return NULL;
24062306a36Sopenharmony_ci	}
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	dma_desc->paddr = paddr;
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	return dma_desc;
24562306a36Sopenharmony_ci}
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_cistatic inline void gr_free_dma_desc(struct gr_udc *dev,
24862306a36Sopenharmony_ci				    struct gr_dma_desc *desc)
24962306a36Sopenharmony_ci{
25062306a36Sopenharmony_ci	dma_pool_free(dev->desc_pool, desc, (dma_addr_t)desc->paddr);
25162306a36Sopenharmony_ci}
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci/* Frees the chain of struct gr_dma_desc for the given request */
25462306a36Sopenharmony_cistatic void gr_free_dma_desc_chain(struct gr_udc *dev, struct gr_request *req)
25562306a36Sopenharmony_ci{
25662306a36Sopenharmony_ci	struct gr_dma_desc *desc;
25762306a36Sopenharmony_ci	struct gr_dma_desc *next;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	next = req->first_desc;
26062306a36Sopenharmony_ci	if (!next)
26162306a36Sopenharmony_ci		return;
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	do {
26462306a36Sopenharmony_ci		desc = next;
26562306a36Sopenharmony_ci		next = desc->next_desc;
26662306a36Sopenharmony_ci		gr_free_dma_desc(dev, desc);
26762306a36Sopenharmony_ci	} while (desc != req->last_desc);
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	req->first_desc = NULL;
27062306a36Sopenharmony_ci	req->curr_desc = NULL;
27162306a36Sopenharmony_ci	req->last_desc = NULL;
27262306a36Sopenharmony_ci}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_cistatic void gr_ep0_setup(struct gr_udc *dev, struct gr_request *req);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci/*
27762306a36Sopenharmony_ci * Frees allocated resources and calls the appropriate completion function/setup
27862306a36Sopenharmony_ci * package handler for a finished request.
27962306a36Sopenharmony_ci *
28062306a36Sopenharmony_ci * Must be called with dev->lock held and irqs disabled.
28162306a36Sopenharmony_ci */
28262306a36Sopenharmony_cistatic void gr_finish_request(struct gr_ep *ep, struct gr_request *req,
28362306a36Sopenharmony_ci			      int status)
28462306a36Sopenharmony_ci	__releases(&dev->lock)
28562306a36Sopenharmony_ci	__acquires(&dev->lock)
28662306a36Sopenharmony_ci{
28762306a36Sopenharmony_ci	struct gr_udc *dev;
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	list_del_init(&req->queue);
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	if (likely(req->req.status == -EINPROGRESS))
29262306a36Sopenharmony_ci		req->req.status = status;
29362306a36Sopenharmony_ci	else
29462306a36Sopenharmony_ci		status = req->req.status;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	dev = ep->dev;
29762306a36Sopenharmony_ci	usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in);
29862306a36Sopenharmony_ci	gr_free_dma_desc_chain(dev, req);
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	if (ep->is_in) { /* For OUT, req->req.actual gets updated bit by bit */
30162306a36Sopenharmony_ci		req->req.actual = req->req.length;
30262306a36Sopenharmony_ci	} else if (req->oddlen && req->req.actual > req->evenlen) {
30362306a36Sopenharmony_ci		/*
30462306a36Sopenharmony_ci		 * Copy to user buffer in this case where length was not evenly
30562306a36Sopenharmony_ci		 * divisible by ep->ep.maxpacket and the last descriptor was
30662306a36Sopenharmony_ci		 * actually used.
30762306a36Sopenharmony_ci		 */
30862306a36Sopenharmony_ci		char *buftail = ((char *)req->req.buf + req->evenlen);
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci		memcpy(buftail, ep->tailbuf, req->oddlen);
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci		if (req->req.actual > req->req.length) {
31362306a36Sopenharmony_ci			/* We got more data than was requested */
31462306a36Sopenharmony_ci			dev_dbg(ep->dev->dev, "Overflow for ep %s\n",
31562306a36Sopenharmony_ci				ep->ep.name);
31662306a36Sopenharmony_ci			gr_dbgprint_request("OVFL", ep, req);
31762306a36Sopenharmony_ci			req->req.status = -EOVERFLOW;
31862306a36Sopenharmony_ci		}
31962306a36Sopenharmony_ci	}
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	if (!status) {
32262306a36Sopenharmony_ci		if (ep->is_in)
32362306a36Sopenharmony_ci			gr_dbgprint_request("SENT", ep, req);
32462306a36Sopenharmony_ci		else
32562306a36Sopenharmony_ci			gr_dbgprint_request("RECV", ep, req);
32662306a36Sopenharmony_ci	}
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	/* Prevent changes to ep->queue during callback */
32962306a36Sopenharmony_ci	ep->callback = 1;
33062306a36Sopenharmony_ci	if (req == dev->ep0reqo && !status) {
33162306a36Sopenharmony_ci		if (req->setup)
33262306a36Sopenharmony_ci			gr_ep0_setup(dev, req);
33362306a36Sopenharmony_ci		else
33462306a36Sopenharmony_ci			dev_err(dev->dev,
33562306a36Sopenharmony_ci				"Unexpected non setup packet on ep0in\n");
33662306a36Sopenharmony_ci	} else if (req->req.complete) {
33762306a36Sopenharmony_ci		spin_unlock(&dev->lock);
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci		usb_gadget_giveback_request(&ep->ep, &req->req);
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci		spin_lock(&dev->lock);
34262306a36Sopenharmony_ci	}
34362306a36Sopenharmony_ci	ep->callback = 0;
34462306a36Sopenharmony_ci}
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_cistatic struct usb_request *gr_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
34762306a36Sopenharmony_ci{
34862306a36Sopenharmony_ci	struct gr_request *req;
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci	req = kzalloc(sizeof(*req), gfp_flags);
35162306a36Sopenharmony_ci	if (!req)
35262306a36Sopenharmony_ci		return NULL;
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	INIT_LIST_HEAD(&req->queue);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	return &req->req;
35762306a36Sopenharmony_ci}
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci/*
36062306a36Sopenharmony_ci * Starts DMA for endpoint ep if there are requests in the queue.
36162306a36Sopenharmony_ci *
36262306a36Sopenharmony_ci * Must be called with dev->lock held and with !ep->stopped.
36362306a36Sopenharmony_ci */
36462306a36Sopenharmony_cistatic void gr_start_dma(struct gr_ep *ep)
36562306a36Sopenharmony_ci{
36662306a36Sopenharmony_ci	struct gr_request *req;
36762306a36Sopenharmony_ci	u32 dmactrl;
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	if (list_empty(&ep->queue)) {
37062306a36Sopenharmony_ci		ep->dma_start = 0;
37162306a36Sopenharmony_ci		return;
37262306a36Sopenharmony_ci	}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	req = list_first_entry(&ep->queue, struct gr_request, queue);
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci	/* A descriptor should already have been allocated */
37762306a36Sopenharmony_ci	BUG_ON(!req->curr_desc);
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci	/*
38062306a36Sopenharmony_ci	 * The DMA controller can not handle smaller OUT buffers than
38162306a36Sopenharmony_ci	 * ep->ep.maxpacket. It could lead to buffer overruns if an unexpectedly
38262306a36Sopenharmony_ci	 * long packet are received. Therefore an internal bounce buffer gets
38362306a36Sopenharmony_ci	 * used when such a request gets enabled.
38462306a36Sopenharmony_ci	 */
38562306a36Sopenharmony_ci	if (!ep->is_in && req->oddlen)
38662306a36Sopenharmony_ci		req->last_desc->data = ep->tailbuf_paddr;
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	wmb(); /* Make sure all is settled before handing it over to DMA */
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	/* Set the descriptor pointer in the hardware */
39162306a36Sopenharmony_ci	gr_write32(&ep->regs->dmaaddr, req->curr_desc->paddr);
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	/* Announce available descriptors */
39462306a36Sopenharmony_ci	dmactrl = gr_read32(&ep->regs->dmactrl);
39562306a36Sopenharmony_ci	gr_write32(&ep->regs->dmactrl, dmactrl | GR_DMACTRL_DA);
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	ep->dma_start = 1;
39862306a36Sopenharmony_ci}
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci/*
40162306a36Sopenharmony_ci * Finishes the first request in the ep's queue and, if available, starts the
40262306a36Sopenharmony_ci * next request in queue.
40362306a36Sopenharmony_ci *
40462306a36Sopenharmony_ci * Must be called with dev->lock held, irqs disabled and with !ep->stopped.
40562306a36Sopenharmony_ci */
40662306a36Sopenharmony_cistatic void gr_dma_advance(struct gr_ep *ep, int status)
40762306a36Sopenharmony_ci{
40862306a36Sopenharmony_ci	struct gr_request *req;
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci	req = list_first_entry(&ep->queue, struct gr_request, queue);
41162306a36Sopenharmony_ci	gr_finish_request(ep, req, status);
41262306a36Sopenharmony_ci	gr_start_dma(ep); /* Regardless of ep->dma_start */
41362306a36Sopenharmony_ci}
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci/*
41662306a36Sopenharmony_ci * Abort DMA for an endpoint. Sets the abort DMA bit which causes an ongoing DMA
41762306a36Sopenharmony_ci * transfer to be canceled and clears GR_DMACTRL_DA.
41862306a36Sopenharmony_ci *
41962306a36Sopenharmony_ci * Must be called with dev->lock held.
42062306a36Sopenharmony_ci */
42162306a36Sopenharmony_cistatic void gr_abort_dma(struct gr_ep *ep)
42262306a36Sopenharmony_ci{
42362306a36Sopenharmony_ci	u32 dmactrl;
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci	dmactrl = gr_read32(&ep->regs->dmactrl);
42662306a36Sopenharmony_ci	gr_write32(&ep->regs->dmactrl, dmactrl | GR_DMACTRL_AD);
42762306a36Sopenharmony_ci}
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ci/*
43062306a36Sopenharmony_ci * Allocates and sets up a struct gr_dma_desc and putting it on the descriptor
43162306a36Sopenharmony_ci * chain.
43262306a36Sopenharmony_ci *
43362306a36Sopenharmony_ci * Size is not used for OUT endpoints. Hardware can not be instructed to handle
43462306a36Sopenharmony_ci * smaller buffer than MAXPL in the OUT direction.
43562306a36Sopenharmony_ci */
43662306a36Sopenharmony_cistatic int gr_add_dma_desc(struct gr_ep *ep, struct gr_request *req,
43762306a36Sopenharmony_ci			   dma_addr_t data, unsigned size, gfp_t gfp_flags)
43862306a36Sopenharmony_ci{
43962306a36Sopenharmony_ci	struct gr_dma_desc *desc;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	desc = gr_alloc_dma_desc(ep, gfp_flags);
44262306a36Sopenharmony_ci	if (!desc)
44362306a36Sopenharmony_ci		return -ENOMEM;
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci	desc->data = data;
44662306a36Sopenharmony_ci	if (ep->is_in)
44762306a36Sopenharmony_ci		desc->ctrl =
44862306a36Sopenharmony_ci			(GR_DESC_IN_CTRL_LEN_MASK & size) | GR_DESC_IN_CTRL_EN;
44962306a36Sopenharmony_ci	else
45062306a36Sopenharmony_ci		desc->ctrl = GR_DESC_OUT_CTRL_IE;
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci	if (!req->first_desc) {
45362306a36Sopenharmony_ci		req->first_desc = desc;
45462306a36Sopenharmony_ci		req->curr_desc = desc;
45562306a36Sopenharmony_ci	} else {
45662306a36Sopenharmony_ci		req->last_desc->next_desc = desc;
45762306a36Sopenharmony_ci		req->last_desc->next = desc->paddr;
45862306a36Sopenharmony_ci		req->last_desc->ctrl |= GR_DESC_OUT_CTRL_NX;
45962306a36Sopenharmony_ci	}
46062306a36Sopenharmony_ci	req->last_desc = desc;
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci	return 0;
46362306a36Sopenharmony_ci}
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci/*
46662306a36Sopenharmony_ci * Sets up a chain of struct gr_dma_descriptors pointing to buffers that
46762306a36Sopenharmony_ci * together covers req->req.length bytes of the buffer at DMA address
46862306a36Sopenharmony_ci * req->req.dma for the OUT direction.
46962306a36Sopenharmony_ci *
47062306a36Sopenharmony_ci * The first descriptor in the chain is enabled, the rest disabled. The
47162306a36Sopenharmony_ci * interrupt handler will later enable them one by one when needed so we can
47262306a36Sopenharmony_ci * find out when the transfer is finished. For OUT endpoints, all descriptors
47362306a36Sopenharmony_ci * therefore generate interrutps.
47462306a36Sopenharmony_ci */
47562306a36Sopenharmony_cistatic int gr_setup_out_desc_list(struct gr_ep *ep, struct gr_request *req,
47662306a36Sopenharmony_ci				  gfp_t gfp_flags)
47762306a36Sopenharmony_ci{
47862306a36Sopenharmony_ci	u16 bytes_left; /* Bytes left to provide descriptors for */
47962306a36Sopenharmony_ci	u16 bytes_used; /* Bytes accommodated for */
48062306a36Sopenharmony_ci	int ret = 0;
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci	req->first_desc = NULL; /* Signals that no allocation is done yet */
48362306a36Sopenharmony_ci	bytes_left = req->req.length;
48462306a36Sopenharmony_ci	bytes_used = 0;
48562306a36Sopenharmony_ci	while (bytes_left > 0) {
48662306a36Sopenharmony_ci		dma_addr_t start = req->req.dma + bytes_used;
48762306a36Sopenharmony_ci		u16 size = min(bytes_left, ep->bytes_per_buffer);
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci		if (size < ep->bytes_per_buffer) {
49062306a36Sopenharmony_ci			/* Prepare using bounce buffer */
49162306a36Sopenharmony_ci			req->evenlen = req->req.length - bytes_left;
49262306a36Sopenharmony_ci			req->oddlen = size;
49362306a36Sopenharmony_ci		}
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci		ret = gr_add_dma_desc(ep, req, start, size, gfp_flags);
49662306a36Sopenharmony_ci		if (ret)
49762306a36Sopenharmony_ci			goto alloc_err;
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci		bytes_left -= size;
50062306a36Sopenharmony_ci		bytes_used += size;
50162306a36Sopenharmony_ci	}
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci	req->first_desc->ctrl |= GR_DESC_OUT_CTRL_EN;
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci	return 0;
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_cialloc_err:
50862306a36Sopenharmony_ci	gr_free_dma_desc_chain(ep->dev, req);
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci	return ret;
51162306a36Sopenharmony_ci}
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci/*
51462306a36Sopenharmony_ci * Sets up a chain of struct gr_dma_descriptors pointing to buffers that
51562306a36Sopenharmony_ci * together covers req->req.length bytes of the buffer at DMA address
51662306a36Sopenharmony_ci * req->req.dma for the IN direction.
51762306a36Sopenharmony_ci *
51862306a36Sopenharmony_ci * When more data is provided than the maximum payload size, the hardware splits
51962306a36Sopenharmony_ci * this up into several payloads automatically. Moreover, ep->bytes_per_buffer
52062306a36Sopenharmony_ci * is always set to a multiple of the maximum payload (restricted to the valid
52162306a36Sopenharmony_ci * number of maximum payloads during high bandwidth isochronous or interrupt
52262306a36Sopenharmony_ci * transfers)
52362306a36Sopenharmony_ci *
52462306a36Sopenharmony_ci * All descriptors are enabled from the beginning and we only generate an
52562306a36Sopenharmony_ci * interrupt for the last one indicating that the entire request has been pushed
52662306a36Sopenharmony_ci * to hardware.
52762306a36Sopenharmony_ci */
52862306a36Sopenharmony_cistatic int gr_setup_in_desc_list(struct gr_ep *ep, struct gr_request *req,
52962306a36Sopenharmony_ci				 gfp_t gfp_flags)
53062306a36Sopenharmony_ci{
53162306a36Sopenharmony_ci	u16 bytes_left; /* Bytes left in req to provide descriptors for */
53262306a36Sopenharmony_ci	u16 bytes_used; /* Bytes in req accommodated for */
53362306a36Sopenharmony_ci	int ret = 0;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	req->first_desc = NULL; /* Signals that no allocation is done yet */
53662306a36Sopenharmony_ci	bytes_left = req->req.length;
53762306a36Sopenharmony_ci	bytes_used = 0;
53862306a36Sopenharmony_ci	do { /* Allow for zero length packets */
53962306a36Sopenharmony_ci		dma_addr_t start = req->req.dma + bytes_used;
54062306a36Sopenharmony_ci		u16 size = min(bytes_left, ep->bytes_per_buffer);
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci		ret = gr_add_dma_desc(ep, req, start, size, gfp_flags);
54362306a36Sopenharmony_ci		if (ret)
54462306a36Sopenharmony_ci			goto alloc_err;
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci		bytes_left -= size;
54762306a36Sopenharmony_ci		bytes_used += size;
54862306a36Sopenharmony_ci	} while (bytes_left > 0);
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci	/*
55162306a36Sopenharmony_ci	 * Send an extra zero length packet to indicate that no more data is
55262306a36Sopenharmony_ci	 * available when req->req.zero is set and the data length is even
55362306a36Sopenharmony_ci	 * multiples of ep->ep.maxpacket.
55462306a36Sopenharmony_ci	 */
55562306a36Sopenharmony_ci	if (req->req.zero && (req->req.length % ep->ep.maxpacket == 0)) {
55662306a36Sopenharmony_ci		ret = gr_add_dma_desc(ep, req, 0, 0, gfp_flags);
55762306a36Sopenharmony_ci		if (ret)
55862306a36Sopenharmony_ci			goto alloc_err;
55962306a36Sopenharmony_ci	}
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_ci	/*
56262306a36Sopenharmony_ci	 * For IN packets we only want to know when the last packet has been
56362306a36Sopenharmony_ci	 * transmitted (not just put into internal buffers).
56462306a36Sopenharmony_ci	 */
56562306a36Sopenharmony_ci	req->last_desc->ctrl |= GR_DESC_IN_CTRL_PI;
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_ci	return 0;
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_cialloc_err:
57062306a36Sopenharmony_ci	gr_free_dma_desc_chain(ep->dev, req);
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci	return ret;
57362306a36Sopenharmony_ci}
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci/* Must be called with dev->lock held */
57662306a36Sopenharmony_cistatic int gr_queue(struct gr_ep *ep, struct gr_request *req, gfp_t gfp_flags)
57762306a36Sopenharmony_ci{
57862306a36Sopenharmony_ci	struct gr_udc *dev = ep->dev;
57962306a36Sopenharmony_ci	int ret;
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci	if (unlikely(!ep->ep.desc && ep->num != 0)) {
58262306a36Sopenharmony_ci		dev_err(dev->dev, "No ep descriptor for %s\n", ep->ep.name);
58362306a36Sopenharmony_ci		return -EINVAL;
58462306a36Sopenharmony_ci	}
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ci	if (unlikely(!req->req.buf || !list_empty(&req->queue))) {
58762306a36Sopenharmony_ci		dev_err(dev->dev,
58862306a36Sopenharmony_ci			"Invalid request for %s: buf=%p list_empty=%d\n",
58962306a36Sopenharmony_ci			ep->ep.name, req->req.buf, list_empty(&req->queue));
59062306a36Sopenharmony_ci		return -EINVAL;
59162306a36Sopenharmony_ci	}
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci	if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
59462306a36Sopenharmony_ci		dev_err(dev->dev, "-ESHUTDOWN");
59562306a36Sopenharmony_ci		return -ESHUTDOWN;
59662306a36Sopenharmony_ci	}
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ci	/* Can't touch registers when suspended */
59962306a36Sopenharmony_ci	if (dev->ep0state == GR_EP0_SUSPEND) {
60062306a36Sopenharmony_ci		dev_err(dev->dev, "-EBUSY");
60162306a36Sopenharmony_ci		return -EBUSY;
60262306a36Sopenharmony_ci	}
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	/* Set up DMA mapping in case the caller didn't */
60562306a36Sopenharmony_ci	ret = usb_gadget_map_request(&dev->gadget, &req->req, ep->is_in);
60662306a36Sopenharmony_ci	if (ret) {
60762306a36Sopenharmony_ci		dev_err(dev->dev, "usb_gadget_map_request");
60862306a36Sopenharmony_ci		return ret;
60962306a36Sopenharmony_ci	}
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci	if (ep->is_in)
61262306a36Sopenharmony_ci		ret = gr_setup_in_desc_list(ep, req, gfp_flags);
61362306a36Sopenharmony_ci	else
61462306a36Sopenharmony_ci		ret = gr_setup_out_desc_list(ep, req, gfp_flags);
61562306a36Sopenharmony_ci	if (ret)
61662306a36Sopenharmony_ci		return ret;
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci	req->req.status = -EINPROGRESS;
61962306a36Sopenharmony_ci	req->req.actual = 0;
62062306a36Sopenharmony_ci	list_add_tail(&req->queue, &ep->queue);
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	/* Start DMA if not started, otherwise interrupt handler handles it */
62362306a36Sopenharmony_ci	if (!ep->dma_start && likely(!ep->stopped))
62462306a36Sopenharmony_ci		gr_start_dma(ep);
62562306a36Sopenharmony_ci
62662306a36Sopenharmony_ci	return 0;
62762306a36Sopenharmony_ci}
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci/*
63062306a36Sopenharmony_ci * Queue a request from within the driver.
63162306a36Sopenharmony_ci *
63262306a36Sopenharmony_ci * Must be called with dev->lock held.
63362306a36Sopenharmony_ci */
63462306a36Sopenharmony_cistatic inline int gr_queue_int(struct gr_ep *ep, struct gr_request *req,
63562306a36Sopenharmony_ci			       gfp_t gfp_flags)
63662306a36Sopenharmony_ci{
63762306a36Sopenharmony_ci	if (ep->is_in)
63862306a36Sopenharmony_ci		gr_dbgprint_request("RESP", ep, req);
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	return gr_queue(ep, req, gfp_flags);
64162306a36Sopenharmony_ci}
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci/* ---------------------------------------------------------------------- */
64462306a36Sopenharmony_ci/* General helper functions */
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci/*
64762306a36Sopenharmony_ci * Dequeue ALL requests.
64862306a36Sopenharmony_ci *
64962306a36Sopenharmony_ci * Must be called with dev->lock held and irqs disabled.
65062306a36Sopenharmony_ci */
65162306a36Sopenharmony_cistatic void gr_ep_nuke(struct gr_ep *ep)
65262306a36Sopenharmony_ci{
65362306a36Sopenharmony_ci	struct gr_request *req;
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci	ep->stopped = 1;
65662306a36Sopenharmony_ci	ep->dma_start = 0;
65762306a36Sopenharmony_ci	gr_abort_dma(ep);
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	while (!list_empty(&ep->queue)) {
66062306a36Sopenharmony_ci		req = list_first_entry(&ep->queue, struct gr_request, queue);
66162306a36Sopenharmony_ci		gr_finish_request(ep, req, -ESHUTDOWN);
66262306a36Sopenharmony_ci	}
66362306a36Sopenharmony_ci}
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci/*
66662306a36Sopenharmony_ci * Reset the hardware state of this endpoint.
66762306a36Sopenharmony_ci *
66862306a36Sopenharmony_ci * Must be called with dev->lock held.
66962306a36Sopenharmony_ci */
67062306a36Sopenharmony_cistatic void gr_ep_reset(struct gr_ep *ep)
67162306a36Sopenharmony_ci{
67262306a36Sopenharmony_ci	gr_write32(&ep->regs->epctrl, 0);
67362306a36Sopenharmony_ci	gr_write32(&ep->regs->dmactrl, 0);
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci	ep->ep.maxpacket = MAX_CTRL_PL_SIZE;
67662306a36Sopenharmony_ci	ep->ep.desc = NULL;
67762306a36Sopenharmony_ci	ep->stopped = 1;
67862306a36Sopenharmony_ci	ep->dma_start = 0;
67962306a36Sopenharmony_ci}
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_ci/*
68262306a36Sopenharmony_ci * Generate STALL on ep0in/out.
68362306a36Sopenharmony_ci *
68462306a36Sopenharmony_ci * Must be called with dev->lock held.
68562306a36Sopenharmony_ci */
68662306a36Sopenharmony_cistatic void gr_control_stall(struct gr_udc *dev)
68762306a36Sopenharmony_ci{
68862306a36Sopenharmony_ci	u32 epctrl;
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ci	epctrl = gr_read32(&dev->epo[0].regs->epctrl);
69162306a36Sopenharmony_ci	gr_write32(&dev->epo[0].regs->epctrl, epctrl | GR_EPCTRL_CS);
69262306a36Sopenharmony_ci	epctrl = gr_read32(&dev->epi[0].regs->epctrl);
69362306a36Sopenharmony_ci	gr_write32(&dev->epi[0].regs->epctrl, epctrl | GR_EPCTRL_CS);
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ci	dev->ep0state = GR_EP0_STALL;
69662306a36Sopenharmony_ci}
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci/*
69962306a36Sopenharmony_ci * Halts, halts and wedges, or clears halt for an endpoint.
70062306a36Sopenharmony_ci *
70162306a36Sopenharmony_ci * Must be called with dev->lock held.
70262306a36Sopenharmony_ci */
70362306a36Sopenharmony_cistatic int gr_ep_halt_wedge(struct gr_ep *ep, int halt, int wedge, int fromhost)
70462306a36Sopenharmony_ci{
70562306a36Sopenharmony_ci	u32 epctrl;
70662306a36Sopenharmony_ci	int retval = 0;
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_ci	if (ep->num && !ep->ep.desc)
70962306a36Sopenharmony_ci		return -EINVAL;
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci	if (ep->num && ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC)
71262306a36Sopenharmony_ci		return -EOPNOTSUPP;
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	/* Never actually halt ep0, and therefore never clear halt for ep0 */
71562306a36Sopenharmony_ci	if (!ep->num) {
71662306a36Sopenharmony_ci		if (halt && !fromhost) {
71762306a36Sopenharmony_ci			/* ep0 halt from gadget - generate protocol stall */
71862306a36Sopenharmony_ci			gr_control_stall(ep->dev);
71962306a36Sopenharmony_ci			dev_dbg(ep->dev->dev, "EP: stall ep0\n");
72062306a36Sopenharmony_ci			return 0;
72162306a36Sopenharmony_ci		}
72262306a36Sopenharmony_ci		return -EINVAL;
72362306a36Sopenharmony_ci	}
72462306a36Sopenharmony_ci
72562306a36Sopenharmony_ci	dev_dbg(ep->dev->dev, "EP: %s halt %s\n",
72662306a36Sopenharmony_ci		(halt ? (wedge ? "wedge" : "set") : "clear"), ep->ep.name);
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	epctrl = gr_read32(&ep->regs->epctrl);
72962306a36Sopenharmony_ci	if (halt) {
73062306a36Sopenharmony_ci		/* Set HALT */
73162306a36Sopenharmony_ci		gr_write32(&ep->regs->epctrl, epctrl | GR_EPCTRL_EH);
73262306a36Sopenharmony_ci		ep->stopped = 1;
73362306a36Sopenharmony_ci		if (wedge)
73462306a36Sopenharmony_ci			ep->wedged = 1;
73562306a36Sopenharmony_ci	} else {
73662306a36Sopenharmony_ci		gr_write32(&ep->regs->epctrl, epctrl & ~GR_EPCTRL_EH);
73762306a36Sopenharmony_ci		ep->stopped = 0;
73862306a36Sopenharmony_ci		ep->wedged = 0;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci		/* Things might have been queued up in the meantime */
74162306a36Sopenharmony_ci		if (!ep->dma_start)
74262306a36Sopenharmony_ci			gr_start_dma(ep);
74362306a36Sopenharmony_ci	}
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci	return retval;
74662306a36Sopenharmony_ci}
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_ci/* Must be called with dev->lock held */
74962306a36Sopenharmony_cistatic inline void gr_set_ep0state(struct gr_udc *dev, enum gr_ep0state value)
75062306a36Sopenharmony_ci{
75162306a36Sopenharmony_ci	if (dev->ep0state != value)
75262306a36Sopenharmony_ci		dev_vdbg(dev->dev, "STATE:  ep0state=%s\n",
75362306a36Sopenharmony_ci			 gr_ep0state_string(value));
75462306a36Sopenharmony_ci	dev->ep0state = value;
75562306a36Sopenharmony_ci}
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci/*
75862306a36Sopenharmony_ci * Should only be called when endpoints can not generate interrupts.
75962306a36Sopenharmony_ci *
76062306a36Sopenharmony_ci * Must be called with dev->lock held.
76162306a36Sopenharmony_ci */
76262306a36Sopenharmony_cistatic void gr_disable_interrupts_and_pullup(struct gr_udc *dev)
76362306a36Sopenharmony_ci{
76462306a36Sopenharmony_ci	gr_write32(&dev->regs->control, 0);
76562306a36Sopenharmony_ci	wmb(); /* Make sure that we do not deny one of our interrupts */
76662306a36Sopenharmony_ci	dev->irq_enabled = 0;
76762306a36Sopenharmony_ci}
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci/*
77062306a36Sopenharmony_ci * Stop all device activity and disable data line pullup.
77162306a36Sopenharmony_ci *
77262306a36Sopenharmony_ci * Must be called with dev->lock held and irqs disabled.
77362306a36Sopenharmony_ci */
77462306a36Sopenharmony_cistatic void gr_stop_activity(struct gr_udc *dev)
77562306a36Sopenharmony_ci{
77662306a36Sopenharmony_ci	struct gr_ep *ep;
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_ci	list_for_each_entry(ep, &dev->ep_list, ep_list)
77962306a36Sopenharmony_ci		gr_ep_nuke(ep);
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci	gr_disable_interrupts_and_pullup(dev);
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ci	gr_set_ep0state(dev, GR_EP0_DISCONNECT);
78462306a36Sopenharmony_ci	usb_gadget_set_state(&dev->gadget, USB_STATE_NOTATTACHED);
78562306a36Sopenharmony_ci}
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_ci/* ---------------------------------------------------------------------- */
78862306a36Sopenharmony_ci/* ep0 setup packet handling */
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_cistatic void gr_ep0_testmode_complete(struct usb_ep *_ep,
79162306a36Sopenharmony_ci				     struct usb_request *_req)
79262306a36Sopenharmony_ci{
79362306a36Sopenharmony_ci	struct gr_ep *ep;
79462306a36Sopenharmony_ci	struct gr_udc *dev;
79562306a36Sopenharmony_ci	u32 control;
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ci	ep = container_of(_ep, struct gr_ep, ep);
79862306a36Sopenharmony_ci	dev = ep->dev;
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_ci	spin_lock(&dev->lock);
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	control = gr_read32(&dev->regs->control);
80362306a36Sopenharmony_ci	control |= GR_CONTROL_TM | (dev->test_mode << GR_CONTROL_TS_POS);
80462306a36Sopenharmony_ci	gr_write32(&dev->regs->control, control);
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci	spin_unlock(&dev->lock);
80762306a36Sopenharmony_ci}
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_cistatic void gr_ep0_dummy_complete(struct usb_ep *_ep, struct usb_request *_req)
81062306a36Sopenharmony_ci{
81162306a36Sopenharmony_ci	/* Nothing needs to be done here */
81262306a36Sopenharmony_ci}
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci/*
81562306a36Sopenharmony_ci * Queue a response on ep0in.
81662306a36Sopenharmony_ci *
81762306a36Sopenharmony_ci * Must be called with dev->lock held.
81862306a36Sopenharmony_ci */
81962306a36Sopenharmony_cistatic int gr_ep0_respond(struct gr_udc *dev, u8 *buf, int length,
82062306a36Sopenharmony_ci			  void (*complete)(struct usb_ep *ep,
82162306a36Sopenharmony_ci					   struct usb_request *req))
82262306a36Sopenharmony_ci{
82362306a36Sopenharmony_ci	u8 *reqbuf = dev->ep0reqi->req.buf;
82462306a36Sopenharmony_ci	int status;
82562306a36Sopenharmony_ci	int i;
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci	for (i = 0; i < length; i++)
82862306a36Sopenharmony_ci		reqbuf[i] = buf[i];
82962306a36Sopenharmony_ci	dev->ep0reqi->req.length = length;
83062306a36Sopenharmony_ci	dev->ep0reqi->req.complete = complete;
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ci	status = gr_queue_int(&dev->epi[0], dev->ep0reqi, GFP_ATOMIC);
83362306a36Sopenharmony_ci	if (status < 0)
83462306a36Sopenharmony_ci		dev_err(dev->dev,
83562306a36Sopenharmony_ci			"Could not queue ep0in setup response: %d\n", status);
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci	return status;
83862306a36Sopenharmony_ci}
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_ci/*
84162306a36Sopenharmony_ci * Queue a 2 byte response on ep0in.
84262306a36Sopenharmony_ci *
84362306a36Sopenharmony_ci * Must be called with dev->lock held.
84462306a36Sopenharmony_ci */
84562306a36Sopenharmony_cistatic inline int gr_ep0_respond_u16(struct gr_udc *dev, u16 response)
84662306a36Sopenharmony_ci{
84762306a36Sopenharmony_ci	__le16 le_response = cpu_to_le16(response);
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci	return gr_ep0_respond(dev, (u8 *)&le_response, 2,
85062306a36Sopenharmony_ci			      gr_ep0_dummy_complete);
85162306a36Sopenharmony_ci}
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_ci/*
85462306a36Sopenharmony_ci * Queue a ZLP response on ep0in.
85562306a36Sopenharmony_ci *
85662306a36Sopenharmony_ci * Must be called with dev->lock held.
85762306a36Sopenharmony_ci */
85862306a36Sopenharmony_cistatic inline int gr_ep0_respond_empty(struct gr_udc *dev)
85962306a36Sopenharmony_ci{
86062306a36Sopenharmony_ci	return gr_ep0_respond(dev, NULL, 0, gr_ep0_dummy_complete);
86162306a36Sopenharmony_ci}
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci/*
86462306a36Sopenharmony_ci * This is run when a SET_ADDRESS request is received. First writes
86562306a36Sopenharmony_ci * the new address to the control register which is updated internally
86662306a36Sopenharmony_ci * when the next IN packet is ACKED.
86762306a36Sopenharmony_ci *
86862306a36Sopenharmony_ci * Must be called with dev->lock held.
86962306a36Sopenharmony_ci */
87062306a36Sopenharmony_cistatic void gr_set_address(struct gr_udc *dev, u8 address)
87162306a36Sopenharmony_ci{
87262306a36Sopenharmony_ci	u32 control;
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci	control = gr_read32(&dev->regs->control) & ~GR_CONTROL_UA_MASK;
87562306a36Sopenharmony_ci	control |= (address << GR_CONTROL_UA_POS) & GR_CONTROL_UA_MASK;
87662306a36Sopenharmony_ci	control |= GR_CONTROL_SU;
87762306a36Sopenharmony_ci	gr_write32(&dev->regs->control, control);
87862306a36Sopenharmony_ci}
87962306a36Sopenharmony_ci
88062306a36Sopenharmony_ci/*
88162306a36Sopenharmony_ci * Returns negative for STALL, 0 for successful handling and positive for
88262306a36Sopenharmony_ci * delegation.
88362306a36Sopenharmony_ci *
88462306a36Sopenharmony_ci * Must be called with dev->lock held.
88562306a36Sopenharmony_ci */
88662306a36Sopenharmony_cistatic int gr_device_request(struct gr_udc *dev, u8 type, u8 request,
88762306a36Sopenharmony_ci			     u16 value, u16 index)
88862306a36Sopenharmony_ci{
88962306a36Sopenharmony_ci	u16 response;
89062306a36Sopenharmony_ci	u8 test;
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_ci	switch (request) {
89362306a36Sopenharmony_ci	case USB_REQ_SET_ADDRESS:
89462306a36Sopenharmony_ci		dev_dbg(dev->dev, "STATUS: address %d\n", value & 0xff);
89562306a36Sopenharmony_ci		gr_set_address(dev, value & 0xff);
89662306a36Sopenharmony_ci		if (value)
89762306a36Sopenharmony_ci			usb_gadget_set_state(&dev->gadget, USB_STATE_ADDRESS);
89862306a36Sopenharmony_ci		else
89962306a36Sopenharmony_ci			usb_gadget_set_state(&dev->gadget, USB_STATE_DEFAULT);
90062306a36Sopenharmony_ci		return gr_ep0_respond_empty(dev);
90162306a36Sopenharmony_ci
90262306a36Sopenharmony_ci	case USB_REQ_GET_STATUS:
90362306a36Sopenharmony_ci		/* Self powered | remote wakeup */
90462306a36Sopenharmony_ci		response = 0x0001 | (dev->remote_wakeup ? 0x0002 : 0);
90562306a36Sopenharmony_ci		return gr_ep0_respond_u16(dev, response);
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_ci	case USB_REQ_SET_FEATURE:
90862306a36Sopenharmony_ci		switch (value) {
90962306a36Sopenharmony_ci		case USB_DEVICE_REMOTE_WAKEUP:
91062306a36Sopenharmony_ci			/* Allow remote wakeup */
91162306a36Sopenharmony_ci			dev->remote_wakeup = 1;
91262306a36Sopenharmony_ci			return gr_ep0_respond_empty(dev);
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci		case USB_DEVICE_TEST_MODE:
91562306a36Sopenharmony_ci			/* The hardware does not support USB_TEST_FORCE_ENABLE */
91662306a36Sopenharmony_ci			test = index >> 8;
91762306a36Sopenharmony_ci			if (test >= USB_TEST_J && test <= USB_TEST_PACKET) {
91862306a36Sopenharmony_ci				dev->test_mode = test;
91962306a36Sopenharmony_ci				return gr_ep0_respond(dev, NULL, 0,
92062306a36Sopenharmony_ci						      gr_ep0_testmode_complete);
92162306a36Sopenharmony_ci			}
92262306a36Sopenharmony_ci		}
92362306a36Sopenharmony_ci		break;
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci	case USB_REQ_CLEAR_FEATURE:
92662306a36Sopenharmony_ci		switch (value) {
92762306a36Sopenharmony_ci		case USB_DEVICE_REMOTE_WAKEUP:
92862306a36Sopenharmony_ci			/* Disallow remote wakeup */
92962306a36Sopenharmony_ci			dev->remote_wakeup = 0;
93062306a36Sopenharmony_ci			return gr_ep0_respond_empty(dev);
93162306a36Sopenharmony_ci		}
93262306a36Sopenharmony_ci		break;
93362306a36Sopenharmony_ci	}
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_ci	return 1; /* Delegate the rest */
93662306a36Sopenharmony_ci}
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_ci/*
93962306a36Sopenharmony_ci * Returns negative for STALL, 0 for successful handling and positive for
94062306a36Sopenharmony_ci * delegation.
94162306a36Sopenharmony_ci *
94262306a36Sopenharmony_ci * Must be called with dev->lock held.
94362306a36Sopenharmony_ci */
94462306a36Sopenharmony_cistatic int gr_interface_request(struct gr_udc *dev, u8 type, u8 request,
94562306a36Sopenharmony_ci				u16 value, u16 index)
94662306a36Sopenharmony_ci{
94762306a36Sopenharmony_ci	if (dev->gadget.state != USB_STATE_CONFIGURED)
94862306a36Sopenharmony_ci		return -1;
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci	/*
95162306a36Sopenharmony_ci	 * Should return STALL for invalid interfaces, but udc driver does not
95262306a36Sopenharmony_ci	 * know anything about that. However, many gadget drivers do not handle
95362306a36Sopenharmony_ci	 * GET_STATUS so we need to take care of that.
95462306a36Sopenharmony_ci	 */
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	switch (request) {
95762306a36Sopenharmony_ci	case USB_REQ_GET_STATUS:
95862306a36Sopenharmony_ci		return gr_ep0_respond_u16(dev, 0x0000);
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci	case USB_REQ_SET_FEATURE:
96162306a36Sopenharmony_ci	case USB_REQ_CLEAR_FEATURE:
96262306a36Sopenharmony_ci		/*
96362306a36Sopenharmony_ci		 * No possible valid standard requests. Still let gadget drivers
96462306a36Sopenharmony_ci		 * have a go at it.
96562306a36Sopenharmony_ci		 */
96662306a36Sopenharmony_ci		break;
96762306a36Sopenharmony_ci	}
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci	return 1; /* Delegate the rest */
97062306a36Sopenharmony_ci}
97162306a36Sopenharmony_ci
97262306a36Sopenharmony_ci/*
97362306a36Sopenharmony_ci * Returns negative for STALL, 0 for successful handling and positive for
97462306a36Sopenharmony_ci * delegation.
97562306a36Sopenharmony_ci *
97662306a36Sopenharmony_ci * Must be called with dev->lock held.
97762306a36Sopenharmony_ci */
97862306a36Sopenharmony_cistatic int gr_endpoint_request(struct gr_udc *dev, u8 type, u8 request,
97962306a36Sopenharmony_ci			       u16 value, u16 index)
98062306a36Sopenharmony_ci{
98162306a36Sopenharmony_ci	struct gr_ep *ep;
98262306a36Sopenharmony_ci	int status;
98362306a36Sopenharmony_ci	int halted;
98462306a36Sopenharmony_ci	u8 epnum = index & USB_ENDPOINT_NUMBER_MASK;
98562306a36Sopenharmony_ci	u8 is_in = index & USB_ENDPOINT_DIR_MASK;
98662306a36Sopenharmony_ci
98762306a36Sopenharmony_ci	if ((is_in && epnum >= dev->nepi) || (!is_in && epnum >= dev->nepo))
98862306a36Sopenharmony_ci		return -1;
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_ci	if (dev->gadget.state != USB_STATE_CONFIGURED && epnum != 0)
99162306a36Sopenharmony_ci		return -1;
99262306a36Sopenharmony_ci
99362306a36Sopenharmony_ci	ep = (is_in ? &dev->epi[epnum] : &dev->epo[epnum]);
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_ci	switch (request) {
99662306a36Sopenharmony_ci	case USB_REQ_GET_STATUS:
99762306a36Sopenharmony_ci		halted = gr_read32(&ep->regs->epctrl) & GR_EPCTRL_EH;
99862306a36Sopenharmony_ci		return gr_ep0_respond_u16(dev, halted ? 0x0001 : 0);
99962306a36Sopenharmony_ci
100062306a36Sopenharmony_ci	case USB_REQ_SET_FEATURE:
100162306a36Sopenharmony_ci		switch (value) {
100262306a36Sopenharmony_ci		case USB_ENDPOINT_HALT:
100362306a36Sopenharmony_ci			status = gr_ep_halt_wedge(ep, 1, 0, 1);
100462306a36Sopenharmony_ci			if (status >= 0)
100562306a36Sopenharmony_ci				status = gr_ep0_respond_empty(dev);
100662306a36Sopenharmony_ci			return status;
100762306a36Sopenharmony_ci		}
100862306a36Sopenharmony_ci		break;
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci	case USB_REQ_CLEAR_FEATURE:
101162306a36Sopenharmony_ci		switch (value) {
101262306a36Sopenharmony_ci		case USB_ENDPOINT_HALT:
101362306a36Sopenharmony_ci			if (ep->wedged)
101462306a36Sopenharmony_ci				return -1;
101562306a36Sopenharmony_ci			status = gr_ep_halt_wedge(ep, 0, 0, 1);
101662306a36Sopenharmony_ci			if (status >= 0)
101762306a36Sopenharmony_ci				status = gr_ep0_respond_empty(dev);
101862306a36Sopenharmony_ci			return status;
101962306a36Sopenharmony_ci		}
102062306a36Sopenharmony_ci		break;
102162306a36Sopenharmony_ci	}
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	return 1; /* Delegate the rest */
102462306a36Sopenharmony_ci}
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_ci/* Must be called with dev->lock held */
102762306a36Sopenharmony_cistatic void gr_ep0out_requeue(struct gr_udc *dev)
102862306a36Sopenharmony_ci{
102962306a36Sopenharmony_ci	int ret = gr_queue_int(&dev->epo[0], dev->ep0reqo, GFP_ATOMIC);
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_ci	if (ret)
103262306a36Sopenharmony_ci		dev_err(dev->dev, "Could not queue ep0out setup request: %d\n",
103362306a36Sopenharmony_ci			ret);
103462306a36Sopenharmony_ci}
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci/*
103762306a36Sopenharmony_ci * The main function dealing with setup requests on ep0.
103862306a36Sopenharmony_ci *
103962306a36Sopenharmony_ci * Must be called with dev->lock held and irqs disabled
104062306a36Sopenharmony_ci */
104162306a36Sopenharmony_cistatic void gr_ep0_setup(struct gr_udc *dev, struct gr_request *req)
104262306a36Sopenharmony_ci	__releases(&dev->lock)
104362306a36Sopenharmony_ci	__acquires(&dev->lock)
104462306a36Sopenharmony_ci{
104562306a36Sopenharmony_ci	union {
104662306a36Sopenharmony_ci		struct usb_ctrlrequest ctrl;
104762306a36Sopenharmony_ci		u8 raw[8];
104862306a36Sopenharmony_ci		u32 word[2];
104962306a36Sopenharmony_ci	} u;
105062306a36Sopenharmony_ci	u8 type;
105162306a36Sopenharmony_ci	u8 request;
105262306a36Sopenharmony_ci	u16 value;
105362306a36Sopenharmony_ci	u16 index;
105462306a36Sopenharmony_ci	u16 length;
105562306a36Sopenharmony_ci	int i;
105662306a36Sopenharmony_ci	int status;
105762306a36Sopenharmony_ci
105862306a36Sopenharmony_ci	/* Restore from ep0 halt */
105962306a36Sopenharmony_ci	if (dev->ep0state == GR_EP0_STALL) {
106062306a36Sopenharmony_ci		gr_set_ep0state(dev, GR_EP0_SETUP);
106162306a36Sopenharmony_ci		if (!req->req.actual)
106262306a36Sopenharmony_ci			goto out;
106362306a36Sopenharmony_ci	}
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_ci	if (dev->ep0state == GR_EP0_ISTATUS) {
106662306a36Sopenharmony_ci		gr_set_ep0state(dev, GR_EP0_SETUP);
106762306a36Sopenharmony_ci		if (req->req.actual > 0)
106862306a36Sopenharmony_ci			dev_dbg(dev->dev,
106962306a36Sopenharmony_ci				"Unexpected setup packet at state %s\n",
107062306a36Sopenharmony_ci				gr_ep0state_string(GR_EP0_ISTATUS));
107162306a36Sopenharmony_ci		else
107262306a36Sopenharmony_ci			goto out; /* Got expected ZLP */
107362306a36Sopenharmony_ci	} else if (dev->ep0state != GR_EP0_SETUP) {
107462306a36Sopenharmony_ci		dev_info(dev->dev,
107562306a36Sopenharmony_ci			 "Unexpected ep0out request at state %s - stalling\n",
107662306a36Sopenharmony_ci			 gr_ep0state_string(dev->ep0state));
107762306a36Sopenharmony_ci		gr_control_stall(dev);
107862306a36Sopenharmony_ci		gr_set_ep0state(dev, GR_EP0_SETUP);
107962306a36Sopenharmony_ci		goto out;
108062306a36Sopenharmony_ci	} else if (!req->req.actual) {
108162306a36Sopenharmony_ci		dev_dbg(dev->dev, "Unexpected ZLP at state %s\n",
108262306a36Sopenharmony_ci			gr_ep0state_string(dev->ep0state));
108362306a36Sopenharmony_ci		goto out;
108462306a36Sopenharmony_ci	}
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_ci	/* Handle SETUP packet */
108762306a36Sopenharmony_ci	for (i = 0; i < req->req.actual; i++)
108862306a36Sopenharmony_ci		u.raw[i] = ((u8 *)req->req.buf)[i];
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ci	type = u.ctrl.bRequestType;
109162306a36Sopenharmony_ci	request = u.ctrl.bRequest;
109262306a36Sopenharmony_ci	value = le16_to_cpu(u.ctrl.wValue);
109362306a36Sopenharmony_ci	index = le16_to_cpu(u.ctrl.wIndex);
109462306a36Sopenharmony_ci	length = le16_to_cpu(u.ctrl.wLength);
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_ci	gr_dbgprint_devreq(dev, type, request, value, index, length);
109762306a36Sopenharmony_ci
109862306a36Sopenharmony_ci	/* Check for data stage */
109962306a36Sopenharmony_ci	if (length) {
110062306a36Sopenharmony_ci		if (type & USB_DIR_IN)
110162306a36Sopenharmony_ci			gr_set_ep0state(dev, GR_EP0_IDATA);
110262306a36Sopenharmony_ci		else
110362306a36Sopenharmony_ci			gr_set_ep0state(dev, GR_EP0_ODATA);
110462306a36Sopenharmony_ci	}
110562306a36Sopenharmony_ci
110662306a36Sopenharmony_ci	status = 1; /* Positive status flags delegation */
110762306a36Sopenharmony_ci	if ((type & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
110862306a36Sopenharmony_ci		switch (type & USB_RECIP_MASK) {
110962306a36Sopenharmony_ci		case USB_RECIP_DEVICE:
111062306a36Sopenharmony_ci			status = gr_device_request(dev, type, request,
111162306a36Sopenharmony_ci						   value, index);
111262306a36Sopenharmony_ci			break;
111362306a36Sopenharmony_ci		case USB_RECIP_ENDPOINT:
111462306a36Sopenharmony_ci			status =  gr_endpoint_request(dev, type, request,
111562306a36Sopenharmony_ci						      value, index);
111662306a36Sopenharmony_ci			break;
111762306a36Sopenharmony_ci		case USB_RECIP_INTERFACE:
111862306a36Sopenharmony_ci			status = gr_interface_request(dev, type, request,
111962306a36Sopenharmony_ci						      value, index);
112062306a36Sopenharmony_ci			break;
112162306a36Sopenharmony_ci		}
112262306a36Sopenharmony_ci	}
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_ci	if (status > 0) {
112562306a36Sopenharmony_ci		spin_unlock(&dev->lock);
112662306a36Sopenharmony_ci
112762306a36Sopenharmony_ci		dev_vdbg(dev->dev, "DELEGATE\n");
112862306a36Sopenharmony_ci		status = dev->driver->setup(&dev->gadget, &u.ctrl);
112962306a36Sopenharmony_ci
113062306a36Sopenharmony_ci		spin_lock(&dev->lock);
113162306a36Sopenharmony_ci	}
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_ci	/* Generate STALL on both ep0out and ep0in if requested */
113462306a36Sopenharmony_ci	if (unlikely(status < 0)) {
113562306a36Sopenharmony_ci		dev_vdbg(dev->dev, "STALL\n");
113662306a36Sopenharmony_ci		gr_control_stall(dev);
113762306a36Sopenharmony_ci	}
113862306a36Sopenharmony_ci
113962306a36Sopenharmony_ci	if ((type & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
114062306a36Sopenharmony_ci	    request == USB_REQ_SET_CONFIGURATION) {
114162306a36Sopenharmony_ci		if (!value) {
114262306a36Sopenharmony_ci			dev_dbg(dev->dev, "STATUS: deconfigured\n");
114362306a36Sopenharmony_ci			usb_gadget_set_state(&dev->gadget, USB_STATE_ADDRESS);
114462306a36Sopenharmony_ci		} else if (status >= 0) {
114562306a36Sopenharmony_ci			/* Not configured unless gadget OK:s it */
114662306a36Sopenharmony_ci			dev_dbg(dev->dev, "STATUS: configured: %d\n", value);
114762306a36Sopenharmony_ci			usb_gadget_set_state(&dev->gadget,
114862306a36Sopenharmony_ci					     USB_STATE_CONFIGURED);
114962306a36Sopenharmony_ci		}
115062306a36Sopenharmony_ci	}
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci	/* Get ready for next stage */
115362306a36Sopenharmony_ci	if (dev->ep0state == GR_EP0_ODATA)
115462306a36Sopenharmony_ci		gr_set_ep0state(dev, GR_EP0_OSTATUS);
115562306a36Sopenharmony_ci	else if (dev->ep0state == GR_EP0_IDATA)
115662306a36Sopenharmony_ci		gr_set_ep0state(dev, GR_EP0_ISTATUS);
115762306a36Sopenharmony_ci	else
115862306a36Sopenharmony_ci		gr_set_ep0state(dev, GR_EP0_SETUP);
115962306a36Sopenharmony_ci
116062306a36Sopenharmony_ciout:
116162306a36Sopenharmony_ci	gr_ep0out_requeue(dev);
116262306a36Sopenharmony_ci}
116362306a36Sopenharmony_ci
116462306a36Sopenharmony_ci/* ---------------------------------------------------------------------- */
116562306a36Sopenharmony_ci/* VBUS and USB reset handling */
116662306a36Sopenharmony_ci
116762306a36Sopenharmony_ci/* Must be called with dev->lock held and irqs disabled  */
116862306a36Sopenharmony_cistatic void gr_vbus_connected(struct gr_udc *dev, u32 status)
116962306a36Sopenharmony_ci{
117062306a36Sopenharmony_ci	u32 control;
117162306a36Sopenharmony_ci
117262306a36Sopenharmony_ci	dev->gadget.speed = GR_SPEED(status);
117362306a36Sopenharmony_ci	usb_gadget_set_state(&dev->gadget, USB_STATE_POWERED);
117462306a36Sopenharmony_ci
117562306a36Sopenharmony_ci	/* Turn on full interrupts and pullup */
117662306a36Sopenharmony_ci	control = (GR_CONTROL_SI | GR_CONTROL_UI | GR_CONTROL_VI |
117762306a36Sopenharmony_ci		   GR_CONTROL_SP | GR_CONTROL_EP);
117862306a36Sopenharmony_ci	gr_write32(&dev->regs->control, control);
117962306a36Sopenharmony_ci}
118062306a36Sopenharmony_ci
118162306a36Sopenharmony_ci/* Must be called with dev->lock held */
118262306a36Sopenharmony_cistatic void gr_enable_vbus_detect(struct gr_udc *dev)
118362306a36Sopenharmony_ci{
118462306a36Sopenharmony_ci	u32 status;
118562306a36Sopenharmony_ci
118662306a36Sopenharmony_ci	dev->irq_enabled = 1;
118762306a36Sopenharmony_ci	wmb(); /* Make sure we do not ignore an interrupt */
118862306a36Sopenharmony_ci	gr_write32(&dev->regs->control, GR_CONTROL_VI);
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_ci	/* Take care of the case we are already plugged in at this point */
119162306a36Sopenharmony_ci	status = gr_read32(&dev->regs->status);
119262306a36Sopenharmony_ci	if (status & GR_STATUS_VB)
119362306a36Sopenharmony_ci		gr_vbus_connected(dev, status);
119462306a36Sopenharmony_ci}
119562306a36Sopenharmony_ci
119662306a36Sopenharmony_ci/* Must be called with dev->lock held and irqs disabled */
119762306a36Sopenharmony_cistatic void gr_vbus_disconnected(struct gr_udc *dev)
119862306a36Sopenharmony_ci{
119962306a36Sopenharmony_ci	gr_stop_activity(dev);
120062306a36Sopenharmony_ci
120162306a36Sopenharmony_ci	/* Report disconnect */
120262306a36Sopenharmony_ci	if (dev->driver && dev->driver->disconnect) {
120362306a36Sopenharmony_ci		spin_unlock(&dev->lock);
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci		dev->driver->disconnect(&dev->gadget);
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_ci		spin_lock(&dev->lock);
120862306a36Sopenharmony_ci	}
120962306a36Sopenharmony_ci
121062306a36Sopenharmony_ci	gr_enable_vbus_detect(dev);
121162306a36Sopenharmony_ci}
121262306a36Sopenharmony_ci
121362306a36Sopenharmony_ci/* Must be called with dev->lock held and irqs disabled */
121462306a36Sopenharmony_cistatic void gr_udc_usbreset(struct gr_udc *dev, u32 status)
121562306a36Sopenharmony_ci{
121662306a36Sopenharmony_ci	gr_set_address(dev, 0);
121762306a36Sopenharmony_ci	gr_set_ep0state(dev, GR_EP0_SETUP);
121862306a36Sopenharmony_ci	usb_gadget_set_state(&dev->gadget, USB_STATE_DEFAULT);
121962306a36Sopenharmony_ci	dev->gadget.speed = GR_SPEED(status);
122062306a36Sopenharmony_ci
122162306a36Sopenharmony_ci	gr_ep_nuke(&dev->epo[0]);
122262306a36Sopenharmony_ci	gr_ep_nuke(&dev->epi[0]);
122362306a36Sopenharmony_ci	dev->epo[0].stopped = 0;
122462306a36Sopenharmony_ci	dev->epi[0].stopped = 0;
122562306a36Sopenharmony_ci	gr_ep0out_requeue(dev);
122662306a36Sopenharmony_ci}
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ci/* ---------------------------------------------------------------------- */
122962306a36Sopenharmony_ci/* Irq handling */
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_ci/*
123262306a36Sopenharmony_ci * Handles interrupts from in endpoints. Returns whether something was handled.
123362306a36Sopenharmony_ci *
123462306a36Sopenharmony_ci * Must be called with dev->lock held, irqs disabled and with !ep->stopped.
123562306a36Sopenharmony_ci */
123662306a36Sopenharmony_cistatic int gr_handle_in_ep(struct gr_ep *ep)
123762306a36Sopenharmony_ci{
123862306a36Sopenharmony_ci	struct gr_request *req;
123962306a36Sopenharmony_ci
124062306a36Sopenharmony_ci	req = list_first_entry(&ep->queue, struct gr_request, queue);
124162306a36Sopenharmony_ci	if (!req->last_desc)
124262306a36Sopenharmony_ci		return 0;
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci	if (READ_ONCE(req->last_desc->ctrl) & GR_DESC_IN_CTRL_EN)
124562306a36Sopenharmony_ci		return 0; /* Not put in hardware buffers yet */
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci	if (gr_read32(&ep->regs->epstat) & (GR_EPSTAT_B1 | GR_EPSTAT_B0))
124862306a36Sopenharmony_ci		return 0; /* Not transmitted yet, still in hardware buffers */
124962306a36Sopenharmony_ci
125062306a36Sopenharmony_ci	/* Write complete */
125162306a36Sopenharmony_ci	gr_dma_advance(ep, 0);
125262306a36Sopenharmony_ci
125362306a36Sopenharmony_ci	return 1;
125462306a36Sopenharmony_ci}
125562306a36Sopenharmony_ci
125662306a36Sopenharmony_ci/*
125762306a36Sopenharmony_ci * Handles interrupts from out endpoints. Returns whether something was handled.
125862306a36Sopenharmony_ci *
125962306a36Sopenharmony_ci * Must be called with dev->lock held, irqs disabled and with !ep->stopped.
126062306a36Sopenharmony_ci */
126162306a36Sopenharmony_cistatic int gr_handle_out_ep(struct gr_ep *ep)
126262306a36Sopenharmony_ci{
126362306a36Sopenharmony_ci	u32 ep_dmactrl;
126462306a36Sopenharmony_ci	u32 ctrl;
126562306a36Sopenharmony_ci	u16 len;
126662306a36Sopenharmony_ci	struct gr_request *req;
126762306a36Sopenharmony_ci	struct gr_udc *dev = ep->dev;
126862306a36Sopenharmony_ci
126962306a36Sopenharmony_ci	req = list_first_entry(&ep->queue, struct gr_request, queue);
127062306a36Sopenharmony_ci	if (!req->curr_desc)
127162306a36Sopenharmony_ci		return 0;
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci	ctrl = READ_ONCE(req->curr_desc->ctrl);
127462306a36Sopenharmony_ci	if (ctrl & GR_DESC_OUT_CTRL_EN)
127562306a36Sopenharmony_ci		return 0; /* Not received yet */
127662306a36Sopenharmony_ci
127762306a36Sopenharmony_ci	/* Read complete */
127862306a36Sopenharmony_ci	len = ctrl & GR_DESC_OUT_CTRL_LEN_MASK;
127962306a36Sopenharmony_ci	req->req.actual += len;
128062306a36Sopenharmony_ci	if (ctrl & GR_DESC_OUT_CTRL_SE)
128162306a36Sopenharmony_ci		req->setup = 1;
128262306a36Sopenharmony_ci
128362306a36Sopenharmony_ci	if (len < ep->ep.maxpacket || req->req.actual >= req->req.length) {
128462306a36Sopenharmony_ci		/* Short packet or >= expected size - we are done */
128562306a36Sopenharmony_ci
128662306a36Sopenharmony_ci		if ((ep == &dev->epo[0]) && (dev->ep0state == GR_EP0_OSTATUS)) {
128762306a36Sopenharmony_ci			/*
128862306a36Sopenharmony_ci			 * Send a status stage ZLP to ack the DATA stage in the
128962306a36Sopenharmony_ci			 * OUT direction. This needs to be done before
129062306a36Sopenharmony_ci			 * gr_dma_advance as that can lead to a call to
129162306a36Sopenharmony_ci			 * ep0_setup that can change dev->ep0state.
129262306a36Sopenharmony_ci			 */
129362306a36Sopenharmony_ci			gr_ep0_respond_empty(dev);
129462306a36Sopenharmony_ci			gr_set_ep0state(dev, GR_EP0_SETUP);
129562306a36Sopenharmony_ci		}
129662306a36Sopenharmony_ci
129762306a36Sopenharmony_ci		gr_dma_advance(ep, 0);
129862306a36Sopenharmony_ci	} else {
129962306a36Sopenharmony_ci		/* Not done yet. Enable the next descriptor to receive more. */
130062306a36Sopenharmony_ci		req->curr_desc = req->curr_desc->next_desc;
130162306a36Sopenharmony_ci		req->curr_desc->ctrl |= GR_DESC_OUT_CTRL_EN;
130262306a36Sopenharmony_ci
130362306a36Sopenharmony_ci		ep_dmactrl = gr_read32(&ep->regs->dmactrl);
130462306a36Sopenharmony_ci		gr_write32(&ep->regs->dmactrl, ep_dmactrl | GR_DMACTRL_DA);
130562306a36Sopenharmony_ci	}
130662306a36Sopenharmony_ci
130762306a36Sopenharmony_ci	return 1;
130862306a36Sopenharmony_ci}
130962306a36Sopenharmony_ci
131062306a36Sopenharmony_ci/*
131162306a36Sopenharmony_ci * Handle state changes. Returns whether something was handled.
131262306a36Sopenharmony_ci *
131362306a36Sopenharmony_ci * Must be called with dev->lock held and irqs disabled.
131462306a36Sopenharmony_ci */
131562306a36Sopenharmony_cistatic int gr_handle_state_changes(struct gr_udc *dev)
131662306a36Sopenharmony_ci{
131762306a36Sopenharmony_ci	u32 status = gr_read32(&dev->regs->status);
131862306a36Sopenharmony_ci	int handled = 0;
131962306a36Sopenharmony_ci	int powstate = !(dev->gadget.state == USB_STATE_NOTATTACHED ||
132062306a36Sopenharmony_ci			 dev->gadget.state == USB_STATE_ATTACHED);
132162306a36Sopenharmony_ci
132262306a36Sopenharmony_ci	/* VBUS valid detected */
132362306a36Sopenharmony_ci	if (!powstate && (status & GR_STATUS_VB)) {
132462306a36Sopenharmony_ci		dev_dbg(dev->dev, "STATUS: vbus valid detected\n");
132562306a36Sopenharmony_ci		gr_vbus_connected(dev, status);
132662306a36Sopenharmony_ci		handled = 1;
132762306a36Sopenharmony_ci	}
132862306a36Sopenharmony_ci
132962306a36Sopenharmony_ci	/* Disconnect */
133062306a36Sopenharmony_ci	if (powstate && !(status & GR_STATUS_VB)) {
133162306a36Sopenharmony_ci		dev_dbg(dev->dev, "STATUS: vbus invalid detected\n");
133262306a36Sopenharmony_ci		gr_vbus_disconnected(dev);
133362306a36Sopenharmony_ci		handled = 1;
133462306a36Sopenharmony_ci	}
133562306a36Sopenharmony_ci
133662306a36Sopenharmony_ci	/* USB reset detected */
133762306a36Sopenharmony_ci	if (status & GR_STATUS_UR) {
133862306a36Sopenharmony_ci		dev_dbg(dev->dev, "STATUS: USB reset - speed is %s\n",
133962306a36Sopenharmony_ci			GR_SPEED_STR(status));
134062306a36Sopenharmony_ci		gr_write32(&dev->regs->status, GR_STATUS_UR);
134162306a36Sopenharmony_ci		gr_udc_usbreset(dev, status);
134262306a36Sopenharmony_ci		handled = 1;
134362306a36Sopenharmony_ci	}
134462306a36Sopenharmony_ci
134562306a36Sopenharmony_ci	/* Speed change */
134662306a36Sopenharmony_ci	if (dev->gadget.speed != GR_SPEED(status)) {
134762306a36Sopenharmony_ci		dev_dbg(dev->dev, "STATUS: USB Speed change to %s\n",
134862306a36Sopenharmony_ci			GR_SPEED_STR(status));
134962306a36Sopenharmony_ci		dev->gadget.speed = GR_SPEED(status);
135062306a36Sopenharmony_ci		handled = 1;
135162306a36Sopenharmony_ci	}
135262306a36Sopenharmony_ci
135362306a36Sopenharmony_ci	/* Going into suspend */
135462306a36Sopenharmony_ci	if ((dev->ep0state != GR_EP0_SUSPEND) && !(status & GR_STATUS_SU)) {
135562306a36Sopenharmony_ci		dev_dbg(dev->dev, "STATUS: USB suspend\n");
135662306a36Sopenharmony_ci		gr_set_ep0state(dev, GR_EP0_SUSPEND);
135762306a36Sopenharmony_ci		dev->suspended_from = dev->gadget.state;
135862306a36Sopenharmony_ci		usb_gadget_set_state(&dev->gadget, USB_STATE_SUSPENDED);
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ci		if ((dev->gadget.speed != USB_SPEED_UNKNOWN) &&
136162306a36Sopenharmony_ci		    dev->driver && dev->driver->suspend) {
136262306a36Sopenharmony_ci			spin_unlock(&dev->lock);
136362306a36Sopenharmony_ci
136462306a36Sopenharmony_ci			dev->driver->suspend(&dev->gadget);
136562306a36Sopenharmony_ci
136662306a36Sopenharmony_ci			spin_lock(&dev->lock);
136762306a36Sopenharmony_ci		}
136862306a36Sopenharmony_ci		handled = 1;
136962306a36Sopenharmony_ci	}
137062306a36Sopenharmony_ci
137162306a36Sopenharmony_ci	/* Coming out of suspend */
137262306a36Sopenharmony_ci	if ((dev->ep0state == GR_EP0_SUSPEND) && (status & GR_STATUS_SU)) {
137362306a36Sopenharmony_ci		dev_dbg(dev->dev, "STATUS: USB resume\n");
137462306a36Sopenharmony_ci		if (dev->suspended_from == USB_STATE_POWERED)
137562306a36Sopenharmony_ci			gr_set_ep0state(dev, GR_EP0_DISCONNECT);
137662306a36Sopenharmony_ci		else
137762306a36Sopenharmony_ci			gr_set_ep0state(dev, GR_EP0_SETUP);
137862306a36Sopenharmony_ci		usb_gadget_set_state(&dev->gadget, dev->suspended_from);
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_ci		if ((dev->gadget.speed != USB_SPEED_UNKNOWN) &&
138162306a36Sopenharmony_ci		    dev->driver && dev->driver->resume) {
138262306a36Sopenharmony_ci			spin_unlock(&dev->lock);
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_ci			dev->driver->resume(&dev->gadget);
138562306a36Sopenharmony_ci
138662306a36Sopenharmony_ci			spin_lock(&dev->lock);
138762306a36Sopenharmony_ci		}
138862306a36Sopenharmony_ci		handled = 1;
138962306a36Sopenharmony_ci	}
139062306a36Sopenharmony_ci
139162306a36Sopenharmony_ci	return handled;
139262306a36Sopenharmony_ci}
139362306a36Sopenharmony_ci
139462306a36Sopenharmony_ci/* Non-interrupt context irq handler */
139562306a36Sopenharmony_cistatic irqreturn_t gr_irq_handler(int irq, void *_dev)
139662306a36Sopenharmony_ci{
139762306a36Sopenharmony_ci	struct gr_udc *dev = _dev;
139862306a36Sopenharmony_ci	struct gr_ep *ep;
139962306a36Sopenharmony_ci	int handled = 0;
140062306a36Sopenharmony_ci	int i;
140162306a36Sopenharmony_ci	unsigned long flags;
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci	spin_lock_irqsave(&dev->lock, flags);
140462306a36Sopenharmony_ci
140562306a36Sopenharmony_ci	if (!dev->irq_enabled)
140662306a36Sopenharmony_ci		goto out;
140762306a36Sopenharmony_ci
140862306a36Sopenharmony_ci	/*
140962306a36Sopenharmony_ci	 * Check IN ep interrupts. We check these before the OUT eps because
141062306a36Sopenharmony_ci	 * some gadgets reuse the request that might already be currently
141162306a36Sopenharmony_ci	 * outstanding and needs to be completed (mainly setup requests).
141262306a36Sopenharmony_ci	 */
141362306a36Sopenharmony_ci	for (i = 0; i < dev->nepi; i++) {
141462306a36Sopenharmony_ci		ep = &dev->epi[i];
141562306a36Sopenharmony_ci		if (!ep->stopped && !ep->callback && !list_empty(&ep->queue))
141662306a36Sopenharmony_ci			handled = gr_handle_in_ep(ep) || handled;
141762306a36Sopenharmony_ci	}
141862306a36Sopenharmony_ci
141962306a36Sopenharmony_ci	/* Check OUT ep interrupts */
142062306a36Sopenharmony_ci	for (i = 0; i < dev->nepo; i++) {
142162306a36Sopenharmony_ci		ep = &dev->epo[i];
142262306a36Sopenharmony_ci		if (!ep->stopped && !ep->callback && !list_empty(&ep->queue))
142362306a36Sopenharmony_ci			handled = gr_handle_out_ep(ep) || handled;
142462306a36Sopenharmony_ci	}
142562306a36Sopenharmony_ci
142662306a36Sopenharmony_ci	/* Check status interrupts */
142762306a36Sopenharmony_ci	handled = gr_handle_state_changes(dev) || handled;
142862306a36Sopenharmony_ci
142962306a36Sopenharmony_ci	/*
143062306a36Sopenharmony_ci	 * Check AMBA DMA errors. Only check if we didn't find anything else to
143162306a36Sopenharmony_ci	 * handle because this shouldn't happen if we did everything right.
143262306a36Sopenharmony_ci	 */
143362306a36Sopenharmony_ci	if (!handled) {
143462306a36Sopenharmony_ci		list_for_each_entry(ep, &dev->ep_list, ep_list) {
143562306a36Sopenharmony_ci			if (gr_read32(&ep->regs->dmactrl) & GR_DMACTRL_AE) {
143662306a36Sopenharmony_ci				dev_err(dev->dev,
143762306a36Sopenharmony_ci					"AMBA Error occurred for %s\n",
143862306a36Sopenharmony_ci					ep->ep.name);
143962306a36Sopenharmony_ci				handled = 1;
144062306a36Sopenharmony_ci			}
144162306a36Sopenharmony_ci		}
144262306a36Sopenharmony_ci	}
144362306a36Sopenharmony_ci
144462306a36Sopenharmony_ciout:
144562306a36Sopenharmony_ci	spin_unlock_irqrestore(&dev->lock, flags);
144662306a36Sopenharmony_ci
144762306a36Sopenharmony_ci	return handled ? IRQ_HANDLED : IRQ_NONE;
144862306a36Sopenharmony_ci}
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci/* Interrupt context irq handler */
145162306a36Sopenharmony_cistatic irqreturn_t gr_irq(int irq, void *_dev)
145262306a36Sopenharmony_ci{
145362306a36Sopenharmony_ci	struct gr_udc *dev = _dev;
145462306a36Sopenharmony_ci
145562306a36Sopenharmony_ci	if (!dev->irq_enabled)
145662306a36Sopenharmony_ci		return IRQ_NONE;
145762306a36Sopenharmony_ci
145862306a36Sopenharmony_ci	return IRQ_WAKE_THREAD;
145962306a36Sopenharmony_ci}
146062306a36Sopenharmony_ci
146162306a36Sopenharmony_ci/* ---------------------------------------------------------------------- */
146262306a36Sopenharmony_ci/* USB ep ops */
146362306a36Sopenharmony_ci
146462306a36Sopenharmony_ci/* Enable endpoint. Not for ep0in and ep0out that are handled separately. */
146562306a36Sopenharmony_cistatic int gr_ep_enable(struct usb_ep *_ep,
146662306a36Sopenharmony_ci			const struct usb_endpoint_descriptor *desc)
146762306a36Sopenharmony_ci{
146862306a36Sopenharmony_ci	struct gr_udc *dev;
146962306a36Sopenharmony_ci	struct gr_ep *ep;
147062306a36Sopenharmony_ci	u8 mode;
147162306a36Sopenharmony_ci	u8 nt;
147262306a36Sopenharmony_ci	u16 max;
147362306a36Sopenharmony_ci	u16 buffer_size = 0;
147462306a36Sopenharmony_ci	u32 epctrl;
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_ci	ep = container_of(_ep, struct gr_ep, ep);
147762306a36Sopenharmony_ci	if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT)
147862306a36Sopenharmony_ci		return -EINVAL;
147962306a36Sopenharmony_ci
148062306a36Sopenharmony_ci	dev = ep->dev;
148162306a36Sopenharmony_ci
148262306a36Sopenharmony_ci	/* 'ep0' IN and OUT are reserved */
148362306a36Sopenharmony_ci	if (ep == &dev->epo[0] || ep == &dev->epi[0])
148462306a36Sopenharmony_ci		return -EINVAL;
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_ci	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
148762306a36Sopenharmony_ci		return -ESHUTDOWN;
148862306a36Sopenharmony_ci
148962306a36Sopenharmony_ci	/* Make sure we are clear for enabling */
149062306a36Sopenharmony_ci	epctrl = gr_read32(&ep->regs->epctrl);
149162306a36Sopenharmony_ci	if (epctrl & GR_EPCTRL_EV)
149262306a36Sopenharmony_ci		return -EBUSY;
149362306a36Sopenharmony_ci
149462306a36Sopenharmony_ci	/* Check that directions match */
149562306a36Sopenharmony_ci	if (!ep->is_in != !usb_endpoint_dir_in(desc))
149662306a36Sopenharmony_ci		return -EINVAL;
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_ci	/* Check ep num */
149962306a36Sopenharmony_ci	if ((!ep->is_in && ep->num >= dev->nepo) ||
150062306a36Sopenharmony_ci	    (ep->is_in && ep->num >= dev->nepi))
150162306a36Sopenharmony_ci		return -EINVAL;
150262306a36Sopenharmony_ci
150362306a36Sopenharmony_ci	if (usb_endpoint_xfer_control(desc)) {
150462306a36Sopenharmony_ci		mode = 0;
150562306a36Sopenharmony_ci	} else if (usb_endpoint_xfer_isoc(desc)) {
150662306a36Sopenharmony_ci		mode = 1;
150762306a36Sopenharmony_ci	} else if (usb_endpoint_xfer_bulk(desc)) {
150862306a36Sopenharmony_ci		mode = 2;
150962306a36Sopenharmony_ci	} else if (usb_endpoint_xfer_int(desc)) {
151062306a36Sopenharmony_ci		mode = 3;
151162306a36Sopenharmony_ci	} else {
151262306a36Sopenharmony_ci		dev_err(dev->dev, "Unknown transfer type for %s\n",
151362306a36Sopenharmony_ci			ep->ep.name);
151462306a36Sopenharmony_ci		return -EINVAL;
151562306a36Sopenharmony_ci	}
151662306a36Sopenharmony_ci
151762306a36Sopenharmony_ci	/*
151862306a36Sopenharmony_ci	 * Bits 10-0 set the max payload. 12-11 set the number of
151962306a36Sopenharmony_ci	 * additional transactions.
152062306a36Sopenharmony_ci	 */
152162306a36Sopenharmony_ci	max = usb_endpoint_maxp(desc);
152262306a36Sopenharmony_ci	nt = usb_endpoint_maxp_mult(desc) - 1;
152362306a36Sopenharmony_ci	buffer_size = GR_BUFFER_SIZE(epctrl);
152462306a36Sopenharmony_ci	if (nt && (mode == 0 || mode == 2)) {
152562306a36Sopenharmony_ci		dev_err(dev->dev,
152662306a36Sopenharmony_ci			"%s mode: multiple trans./microframe not valid\n",
152762306a36Sopenharmony_ci			(mode == 2 ? "Bulk" : "Control"));
152862306a36Sopenharmony_ci		return -EINVAL;
152962306a36Sopenharmony_ci	} else if (nt == 0x3) {
153062306a36Sopenharmony_ci		dev_err(dev->dev,
153162306a36Sopenharmony_ci			"Invalid value 0x3 for additional trans./microframe\n");
153262306a36Sopenharmony_ci		return -EINVAL;
153362306a36Sopenharmony_ci	} else if ((nt + 1) * max > buffer_size) {
153462306a36Sopenharmony_ci		dev_err(dev->dev, "Hw buffer size %d < max payload %d * %d\n",
153562306a36Sopenharmony_ci			buffer_size, (nt + 1), max);
153662306a36Sopenharmony_ci		return -EINVAL;
153762306a36Sopenharmony_ci	} else if (max == 0) {
153862306a36Sopenharmony_ci		dev_err(dev->dev, "Max payload cannot be set to 0\n");
153962306a36Sopenharmony_ci		return -EINVAL;
154062306a36Sopenharmony_ci	} else if (max > ep->ep.maxpacket_limit) {
154162306a36Sopenharmony_ci		dev_err(dev->dev, "Requested max payload %d > limit %d\n",
154262306a36Sopenharmony_ci			max, ep->ep.maxpacket_limit);
154362306a36Sopenharmony_ci		return -EINVAL;
154462306a36Sopenharmony_ci	}
154562306a36Sopenharmony_ci
154662306a36Sopenharmony_ci	spin_lock(&ep->dev->lock);
154762306a36Sopenharmony_ci
154862306a36Sopenharmony_ci	if (!ep->stopped) {
154962306a36Sopenharmony_ci		spin_unlock(&ep->dev->lock);
155062306a36Sopenharmony_ci		return -EBUSY;
155162306a36Sopenharmony_ci	}
155262306a36Sopenharmony_ci
155362306a36Sopenharmony_ci	ep->stopped = 0;
155462306a36Sopenharmony_ci	ep->wedged = 0;
155562306a36Sopenharmony_ci	ep->ep.desc = desc;
155662306a36Sopenharmony_ci	ep->ep.maxpacket = max;
155762306a36Sopenharmony_ci	ep->dma_start = 0;
155862306a36Sopenharmony_ci
155962306a36Sopenharmony_ci
156062306a36Sopenharmony_ci	if (nt) {
156162306a36Sopenharmony_ci		/*
156262306a36Sopenharmony_ci		 * Maximum possible size of all payloads in one microframe
156362306a36Sopenharmony_ci		 * regardless of direction when using high-bandwidth mode.
156462306a36Sopenharmony_ci		 */
156562306a36Sopenharmony_ci		ep->bytes_per_buffer = (nt + 1) * max;
156662306a36Sopenharmony_ci	} else if (ep->is_in) {
156762306a36Sopenharmony_ci		/*
156862306a36Sopenharmony_ci		 * The biggest multiple of maximum packet size that fits into
156962306a36Sopenharmony_ci		 * the buffer. The hardware will split up into many packets in
157062306a36Sopenharmony_ci		 * the IN direction.
157162306a36Sopenharmony_ci		 */
157262306a36Sopenharmony_ci		ep->bytes_per_buffer = (buffer_size / max) * max;
157362306a36Sopenharmony_ci	} else {
157462306a36Sopenharmony_ci		/*
157562306a36Sopenharmony_ci		 * Only single packets will be placed the buffers in the OUT
157662306a36Sopenharmony_ci		 * direction.
157762306a36Sopenharmony_ci		 */
157862306a36Sopenharmony_ci		ep->bytes_per_buffer = max;
157962306a36Sopenharmony_ci	}
158062306a36Sopenharmony_ci
158162306a36Sopenharmony_ci	epctrl = (max << GR_EPCTRL_MAXPL_POS)
158262306a36Sopenharmony_ci		| (nt << GR_EPCTRL_NT_POS)
158362306a36Sopenharmony_ci		| (mode << GR_EPCTRL_TT_POS)
158462306a36Sopenharmony_ci		| GR_EPCTRL_EV;
158562306a36Sopenharmony_ci	if (ep->is_in)
158662306a36Sopenharmony_ci		epctrl |= GR_EPCTRL_PI;
158762306a36Sopenharmony_ci	gr_write32(&ep->regs->epctrl, epctrl);
158862306a36Sopenharmony_ci
158962306a36Sopenharmony_ci	gr_write32(&ep->regs->dmactrl, GR_DMACTRL_IE | GR_DMACTRL_AI);
159062306a36Sopenharmony_ci
159162306a36Sopenharmony_ci	spin_unlock(&ep->dev->lock);
159262306a36Sopenharmony_ci
159362306a36Sopenharmony_ci	dev_dbg(ep->dev->dev, "EP: %s enabled - %s with %d bytes/buffer\n",
159462306a36Sopenharmony_ci		ep->ep.name, gr_modestring[mode], ep->bytes_per_buffer);
159562306a36Sopenharmony_ci	return 0;
159662306a36Sopenharmony_ci}
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci/* Disable endpoint. Not for ep0in and ep0out that are handled separately. */
159962306a36Sopenharmony_cistatic int gr_ep_disable(struct usb_ep *_ep)
160062306a36Sopenharmony_ci{
160162306a36Sopenharmony_ci	struct gr_ep *ep;
160262306a36Sopenharmony_ci	struct gr_udc *dev;
160362306a36Sopenharmony_ci	unsigned long flags;
160462306a36Sopenharmony_ci
160562306a36Sopenharmony_ci	ep = container_of(_ep, struct gr_ep, ep);
160662306a36Sopenharmony_ci	if (!_ep || !ep->ep.desc)
160762306a36Sopenharmony_ci		return -ENODEV;
160862306a36Sopenharmony_ci
160962306a36Sopenharmony_ci	dev = ep->dev;
161062306a36Sopenharmony_ci
161162306a36Sopenharmony_ci	/* 'ep0' IN and OUT are reserved */
161262306a36Sopenharmony_ci	if (ep == &dev->epo[0] || ep == &dev->epi[0])
161362306a36Sopenharmony_ci		return -EINVAL;
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_ci	if (dev->ep0state == GR_EP0_SUSPEND)
161662306a36Sopenharmony_ci		return -EBUSY;
161762306a36Sopenharmony_ci
161862306a36Sopenharmony_ci	dev_dbg(ep->dev->dev, "EP: disable %s\n", ep->ep.name);
161962306a36Sopenharmony_ci
162062306a36Sopenharmony_ci	spin_lock_irqsave(&dev->lock, flags);
162162306a36Sopenharmony_ci
162262306a36Sopenharmony_ci	gr_ep_nuke(ep);
162362306a36Sopenharmony_ci	gr_ep_reset(ep);
162462306a36Sopenharmony_ci	ep->ep.desc = NULL;
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ci	spin_unlock_irqrestore(&dev->lock, flags);
162762306a36Sopenharmony_ci
162862306a36Sopenharmony_ci	return 0;
162962306a36Sopenharmony_ci}
163062306a36Sopenharmony_ci
163162306a36Sopenharmony_ci/*
163262306a36Sopenharmony_ci * Frees a request, but not any DMA buffers associated with it
163362306a36Sopenharmony_ci * (gr_finish_request should already have taken care of that).
163462306a36Sopenharmony_ci */
163562306a36Sopenharmony_cistatic void gr_free_request(struct usb_ep *_ep, struct usb_request *_req)
163662306a36Sopenharmony_ci{
163762306a36Sopenharmony_ci	struct gr_request *req;
163862306a36Sopenharmony_ci
163962306a36Sopenharmony_ci	if (!_ep || !_req)
164062306a36Sopenharmony_ci		return;
164162306a36Sopenharmony_ci	req = container_of(_req, struct gr_request, req);
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_ci	/* Leads to memory leak */
164462306a36Sopenharmony_ci	WARN(!list_empty(&req->queue),
164562306a36Sopenharmony_ci	     "request not dequeued properly before freeing\n");
164662306a36Sopenharmony_ci
164762306a36Sopenharmony_ci	kfree(req);
164862306a36Sopenharmony_ci}
164962306a36Sopenharmony_ci
165062306a36Sopenharmony_ci/* Queue a request from the gadget */
165162306a36Sopenharmony_cistatic int gr_queue_ext(struct usb_ep *_ep, struct usb_request *_req,
165262306a36Sopenharmony_ci			gfp_t gfp_flags)
165362306a36Sopenharmony_ci{
165462306a36Sopenharmony_ci	struct gr_ep *ep;
165562306a36Sopenharmony_ci	struct gr_request *req;
165662306a36Sopenharmony_ci	struct gr_udc *dev;
165762306a36Sopenharmony_ci	int ret;
165862306a36Sopenharmony_ci
165962306a36Sopenharmony_ci	if (unlikely(!_ep || !_req))
166062306a36Sopenharmony_ci		return -EINVAL;
166162306a36Sopenharmony_ci
166262306a36Sopenharmony_ci	ep = container_of(_ep, struct gr_ep, ep);
166362306a36Sopenharmony_ci	req = container_of(_req, struct gr_request, req);
166462306a36Sopenharmony_ci	dev = ep->dev;
166562306a36Sopenharmony_ci
166662306a36Sopenharmony_ci	spin_lock(&ep->dev->lock);
166762306a36Sopenharmony_ci
166862306a36Sopenharmony_ci	/*
166962306a36Sopenharmony_ci	 * The ep0 pointer in the gadget struct is used both for ep0in and
167062306a36Sopenharmony_ci	 * ep0out. In a data stage in the out direction ep0out needs to be used
167162306a36Sopenharmony_ci	 * instead of the default ep0in. Completion functions might use
167262306a36Sopenharmony_ci	 * driver_data, so that needs to be copied as well.
167362306a36Sopenharmony_ci	 */
167462306a36Sopenharmony_ci	if ((ep == &dev->epi[0]) && (dev->ep0state == GR_EP0_ODATA)) {
167562306a36Sopenharmony_ci		ep = &dev->epo[0];
167662306a36Sopenharmony_ci		ep->ep.driver_data = dev->epi[0].ep.driver_data;
167762306a36Sopenharmony_ci	}
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_ci	if (ep->is_in)
168062306a36Sopenharmony_ci		gr_dbgprint_request("EXTERN", ep, req);
168162306a36Sopenharmony_ci
168262306a36Sopenharmony_ci	ret = gr_queue(ep, req, GFP_ATOMIC);
168362306a36Sopenharmony_ci
168462306a36Sopenharmony_ci	spin_unlock(&ep->dev->lock);
168562306a36Sopenharmony_ci
168662306a36Sopenharmony_ci	return ret;
168762306a36Sopenharmony_ci}
168862306a36Sopenharmony_ci
168962306a36Sopenharmony_ci/* Dequeue JUST ONE request */
169062306a36Sopenharmony_cistatic int gr_dequeue(struct usb_ep *_ep, struct usb_request *_req)
169162306a36Sopenharmony_ci{
169262306a36Sopenharmony_ci	struct gr_request *req = NULL, *iter;
169362306a36Sopenharmony_ci	struct gr_ep *ep;
169462306a36Sopenharmony_ci	struct gr_udc *dev;
169562306a36Sopenharmony_ci	int ret = 0;
169662306a36Sopenharmony_ci	unsigned long flags;
169762306a36Sopenharmony_ci
169862306a36Sopenharmony_ci	ep = container_of(_ep, struct gr_ep, ep);
169962306a36Sopenharmony_ci	if (!_ep || !_req || (!ep->ep.desc && ep->num != 0))
170062306a36Sopenharmony_ci		return -EINVAL;
170162306a36Sopenharmony_ci	dev = ep->dev;
170262306a36Sopenharmony_ci	if (!dev->driver)
170362306a36Sopenharmony_ci		return -ESHUTDOWN;
170462306a36Sopenharmony_ci
170562306a36Sopenharmony_ci	/* We can't touch (DMA) registers when suspended */
170662306a36Sopenharmony_ci	if (dev->ep0state == GR_EP0_SUSPEND)
170762306a36Sopenharmony_ci		return -EBUSY;
170862306a36Sopenharmony_ci
170962306a36Sopenharmony_ci	spin_lock_irqsave(&dev->lock, flags);
171062306a36Sopenharmony_ci
171162306a36Sopenharmony_ci	/* Make sure it's actually queued on this endpoint */
171262306a36Sopenharmony_ci	list_for_each_entry(iter, &ep->queue, queue) {
171362306a36Sopenharmony_ci		if (&iter->req != _req)
171462306a36Sopenharmony_ci			continue;
171562306a36Sopenharmony_ci		req = iter;
171662306a36Sopenharmony_ci		break;
171762306a36Sopenharmony_ci	}
171862306a36Sopenharmony_ci	if (!req) {
171962306a36Sopenharmony_ci		ret = -EINVAL;
172062306a36Sopenharmony_ci		goto out;
172162306a36Sopenharmony_ci	}
172262306a36Sopenharmony_ci
172362306a36Sopenharmony_ci	if (list_first_entry(&ep->queue, struct gr_request, queue) == req) {
172462306a36Sopenharmony_ci		/* This request is currently being processed */
172562306a36Sopenharmony_ci		gr_abort_dma(ep);
172662306a36Sopenharmony_ci		if (ep->stopped)
172762306a36Sopenharmony_ci			gr_finish_request(ep, req, -ECONNRESET);
172862306a36Sopenharmony_ci		else
172962306a36Sopenharmony_ci			gr_dma_advance(ep, -ECONNRESET);
173062306a36Sopenharmony_ci	} else if (!list_empty(&req->queue)) {
173162306a36Sopenharmony_ci		/* Not being processed - gr_finish_request dequeues it */
173262306a36Sopenharmony_ci		gr_finish_request(ep, req, -ECONNRESET);
173362306a36Sopenharmony_ci	} else {
173462306a36Sopenharmony_ci		ret = -EOPNOTSUPP;
173562306a36Sopenharmony_ci	}
173662306a36Sopenharmony_ci
173762306a36Sopenharmony_ciout:
173862306a36Sopenharmony_ci	spin_unlock_irqrestore(&dev->lock, flags);
173962306a36Sopenharmony_ci
174062306a36Sopenharmony_ci	return ret;
174162306a36Sopenharmony_ci}
174262306a36Sopenharmony_ci
174362306a36Sopenharmony_ci/* Helper for gr_set_halt and gr_set_wedge */
174462306a36Sopenharmony_cistatic int gr_set_halt_wedge(struct usb_ep *_ep, int halt, int wedge)
174562306a36Sopenharmony_ci{
174662306a36Sopenharmony_ci	int ret;
174762306a36Sopenharmony_ci	struct gr_ep *ep;
174862306a36Sopenharmony_ci
174962306a36Sopenharmony_ci	if (!_ep)
175062306a36Sopenharmony_ci		return -ENODEV;
175162306a36Sopenharmony_ci	ep = container_of(_ep, struct gr_ep, ep);
175262306a36Sopenharmony_ci
175362306a36Sopenharmony_ci	spin_lock(&ep->dev->lock);
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_ci	/* Halting an IN endpoint should fail if queue is not empty */
175662306a36Sopenharmony_ci	if (halt && ep->is_in && !list_empty(&ep->queue)) {
175762306a36Sopenharmony_ci		ret = -EAGAIN;
175862306a36Sopenharmony_ci		goto out;
175962306a36Sopenharmony_ci	}
176062306a36Sopenharmony_ci
176162306a36Sopenharmony_ci	ret = gr_ep_halt_wedge(ep, halt, wedge, 0);
176262306a36Sopenharmony_ci
176362306a36Sopenharmony_ciout:
176462306a36Sopenharmony_ci	spin_unlock(&ep->dev->lock);
176562306a36Sopenharmony_ci
176662306a36Sopenharmony_ci	return ret;
176762306a36Sopenharmony_ci}
176862306a36Sopenharmony_ci
176962306a36Sopenharmony_ci/* Halt endpoint */
177062306a36Sopenharmony_cistatic int gr_set_halt(struct usb_ep *_ep, int halt)
177162306a36Sopenharmony_ci{
177262306a36Sopenharmony_ci	return gr_set_halt_wedge(_ep, halt, 0);
177362306a36Sopenharmony_ci}
177462306a36Sopenharmony_ci
177562306a36Sopenharmony_ci/* Halt and wedge endpoint */
177662306a36Sopenharmony_cistatic int gr_set_wedge(struct usb_ep *_ep)
177762306a36Sopenharmony_ci{
177862306a36Sopenharmony_ci	return gr_set_halt_wedge(_ep, 1, 1);
177962306a36Sopenharmony_ci}
178062306a36Sopenharmony_ci
178162306a36Sopenharmony_ci/*
178262306a36Sopenharmony_ci * Return the total number of bytes currently stored in the internal buffers of
178362306a36Sopenharmony_ci * the endpoint.
178462306a36Sopenharmony_ci */
178562306a36Sopenharmony_cistatic int gr_fifo_status(struct usb_ep *_ep)
178662306a36Sopenharmony_ci{
178762306a36Sopenharmony_ci	struct gr_ep *ep;
178862306a36Sopenharmony_ci	u32 epstat;
178962306a36Sopenharmony_ci	u32 bytes = 0;
179062306a36Sopenharmony_ci
179162306a36Sopenharmony_ci	if (!_ep)
179262306a36Sopenharmony_ci		return -ENODEV;
179362306a36Sopenharmony_ci	ep = container_of(_ep, struct gr_ep, ep);
179462306a36Sopenharmony_ci
179562306a36Sopenharmony_ci	epstat = gr_read32(&ep->regs->epstat);
179662306a36Sopenharmony_ci
179762306a36Sopenharmony_ci	if (epstat & GR_EPSTAT_B0)
179862306a36Sopenharmony_ci		bytes += (epstat & GR_EPSTAT_B0CNT_MASK) >> GR_EPSTAT_B0CNT_POS;
179962306a36Sopenharmony_ci	if (epstat & GR_EPSTAT_B1)
180062306a36Sopenharmony_ci		bytes += (epstat & GR_EPSTAT_B1CNT_MASK) >> GR_EPSTAT_B1CNT_POS;
180162306a36Sopenharmony_ci
180262306a36Sopenharmony_ci	return bytes;
180362306a36Sopenharmony_ci}
180462306a36Sopenharmony_ci
180562306a36Sopenharmony_ci
180662306a36Sopenharmony_ci/* Empty data from internal buffers of an endpoint. */
180762306a36Sopenharmony_cistatic void gr_fifo_flush(struct usb_ep *_ep)
180862306a36Sopenharmony_ci{
180962306a36Sopenharmony_ci	struct gr_ep *ep;
181062306a36Sopenharmony_ci	u32 epctrl;
181162306a36Sopenharmony_ci
181262306a36Sopenharmony_ci	if (!_ep)
181362306a36Sopenharmony_ci		return;
181462306a36Sopenharmony_ci	ep = container_of(_ep, struct gr_ep, ep);
181562306a36Sopenharmony_ci	dev_vdbg(ep->dev->dev, "EP: flush fifo %s\n", ep->ep.name);
181662306a36Sopenharmony_ci
181762306a36Sopenharmony_ci	spin_lock(&ep->dev->lock);
181862306a36Sopenharmony_ci
181962306a36Sopenharmony_ci	epctrl = gr_read32(&ep->regs->epctrl);
182062306a36Sopenharmony_ci	epctrl |= GR_EPCTRL_CB;
182162306a36Sopenharmony_ci	gr_write32(&ep->regs->epctrl, epctrl);
182262306a36Sopenharmony_ci
182362306a36Sopenharmony_ci	spin_unlock(&ep->dev->lock);
182462306a36Sopenharmony_ci}
182562306a36Sopenharmony_ci
182662306a36Sopenharmony_cistatic const struct usb_ep_ops gr_ep_ops = {
182762306a36Sopenharmony_ci	.enable		= gr_ep_enable,
182862306a36Sopenharmony_ci	.disable	= gr_ep_disable,
182962306a36Sopenharmony_ci
183062306a36Sopenharmony_ci	.alloc_request	= gr_alloc_request,
183162306a36Sopenharmony_ci	.free_request	= gr_free_request,
183262306a36Sopenharmony_ci
183362306a36Sopenharmony_ci	.queue		= gr_queue_ext,
183462306a36Sopenharmony_ci	.dequeue	= gr_dequeue,
183562306a36Sopenharmony_ci
183662306a36Sopenharmony_ci	.set_halt	= gr_set_halt,
183762306a36Sopenharmony_ci	.set_wedge	= gr_set_wedge,
183862306a36Sopenharmony_ci	.fifo_status	= gr_fifo_status,
183962306a36Sopenharmony_ci	.fifo_flush	= gr_fifo_flush,
184062306a36Sopenharmony_ci};
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ci/* ---------------------------------------------------------------------- */
184362306a36Sopenharmony_ci/* USB Gadget ops */
184462306a36Sopenharmony_ci
184562306a36Sopenharmony_cistatic int gr_get_frame(struct usb_gadget *_gadget)
184662306a36Sopenharmony_ci{
184762306a36Sopenharmony_ci	struct gr_udc *dev;
184862306a36Sopenharmony_ci
184962306a36Sopenharmony_ci	if (!_gadget)
185062306a36Sopenharmony_ci		return -ENODEV;
185162306a36Sopenharmony_ci	dev = container_of(_gadget, struct gr_udc, gadget);
185262306a36Sopenharmony_ci	return gr_read32(&dev->regs->status) & GR_STATUS_FN_MASK;
185362306a36Sopenharmony_ci}
185462306a36Sopenharmony_ci
185562306a36Sopenharmony_cistatic int gr_wakeup(struct usb_gadget *_gadget)
185662306a36Sopenharmony_ci{
185762306a36Sopenharmony_ci	struct gr_udc *dev;
185862306a36Sopenharmony_ci
185962306a36Sopenharmony_ci	if (!_gadget)
186062306a36Sopenharmony_ci		return -ENODEV;
186162306a36Sopenharmony_ci	dev = container_of(_gadget, struct gr_udc, gadget);
186262306a36Sopenharmony_ci
186362306a36Sopenharmony_ci	/* Remote wakeup feature not enabled by host*/
186462306a36Sopenharmony_ci	if (!dev->remote_wakeup)
186562306a36Sopenharmony_ci		return -EINVAL;
186662306a36Sopenharmony_ci
186762306a36Sopenharmony_ci	spin_lock(&dev->lock);
186862306a36Sopenharmony_ci
186962306a36Sopenharmony_ci	gr_write32(&dev->regs->control,
187062306a36Sopenharmony_ci		   gr_read32(&dev->regs->control) | GR_CONTROL_RW);
187162306a36Sopenharmony_ci
187262306a36Sopenharmony_ci	spin_unlock(&dev->lock);
187362306a36Sopenharmony_ci
187462306a36Sopenharmony_ci	return 0;
187562306a36Sopenharmony_ci}
187662306a36Sopenharmony_ci
187762306a36Sopenharmony_cistatic int gr_pullup(struct usb_gadget *_gadget, int is_on)
187862306a36Sopenharmony_ci{
187962306a36Sopenharmony_ci	struct gr_udc *dev;
188062306a36Sopenharmony_ci	u32 control;
188162306a36Sopenharmony_ci
188262306a36Sopenharmony_ci	if (!_gadget)
188362306a36Sopenharmony_ci		return -ENODEV;
188462306a36Sopenharmony_ci	dev = container_of(_gadget, struct gr_udc, gadget);
188562306a36Sopenharmony_ci
188662306a36Sopenharmony_ci	spin_lock(&dev->lock);
188762306a36Sopenharmony_ci
188862306a36Sopenharmony_ci	control = gr_read32(&dev->regs->control);
188962306a36Sopenharmony_ci	if (is_on)
189062306a36Sopenharmony_ci		control |= GR_CONTROL_EP;
189162306a36Sopenharmony_ci	else
189262306a36Sopenharmony_ci		control &= ~GR_CONTROL_EP;
189362306a36Sopenharmony_ci	gr_write32(&dev->regs->control, control);
189462306a36Sopenharmony_ci
189562306a36Sopenharmony_ci	spin_unlock(&dev->lock);
189662306a36Sopenharmony_ci
189762306a36Sopenharmony_ci	return 0;
189862306a36Sopenharmony_ci}
189962306a36Sopenharmony_ci
190062306a36Sopenharmony_cistatic int gr_udc_start(struct usb_gadget *gadget,
190162306a36Sopenharmony_ci			struct usb_gadget_driver *driver)
190262306a36Sopenharmony_ci{
190362306a36Sopenharmony_ci	struct gr_udc *dev = to_gr_udc(gadget);
190462306a36Sopenharmony_ci
190562306a36Sopenharmony_ci	spin_lock(&dev->lock);
190662306a36Sopenharmony_ci
190762306a36Sopenharmony_ci	/* Hook up the driver */
190862306a36Sopenharmony_ci	dev->driver = driver;
190962306a36Sopenharmony_ci
191062306a36Sopenharmony_ci	/* Get ready for host detection */
191162306a36Sopenharmony_ci	gr_enable_vbus_detect(dev);
191262306a36Sopenharmony_ci
191362306a36Sopenharmony_ci	spin_unlock(&dev->lock);
191462306a36Sopenharmony_ci
191562306a36Sopenharmony_ci	return 0;
191662306a36Sopenharmony_ci}
191762306a36Sopenharmony_ci
191862306a36Sopenharmony_cistatic int gr_udc_stop(struct usb_gadget *gadget)
191962306a36Sopenharmony_ci{
192062306a36Sopenharmony_ci	struct gr_udc *dev = to_gr_udc(gadget);
192162306a36Sopenharmony_ci	unsigned long flags;
192262306a36Sopenharmony_ci
192362306a36Sopenharmony_ci	spin_lock_irqsave(&dev->lock, flags);
192462306a36Sopenharmony_ci
192562306a36Sopenharmony_ci	dev->driver = NULL;
192662306a36Sopenharmony_ci	gr_stop_activity(dev);
192762306a36Sopenharmony_ci
192862306a36Sopenharmony_ci	spin_unlock_irqrestore(&dev->lock, flags);
192962306a36Sopenharmony_ci
193062306a36Sopenharmony_ci	return 0;
193162306a36Sopenharmony_ci}
193262306a36Sopenharmony_ci
193362306a36Sopenharmony_cistatic const struct usb_gadget_ops gr_ops = {
193462306a36Sopenharmony_ci	.get_frame	= gr_get_frame,
193562306a36Sopenharmony_ci	.wakeup         = gr_wakeup,
193662306a36Sopenharmony_ci	.pullup         = gr_pullup,
193762306a36Sopenharmony_ci	.udc_start	= gr_udc_start,
193862306a36Sopenharmony_ci	.udc_stop	= gr_udc_stop,
193962306a36Sopenharmony_ci	/* Other operations not supported */
194062306a36Sopenharmony_ci};
194162306a36Sopenharmony_ci
194262306a36Sopenharmony_ci/* ---------------------------------------------------------------------- */
194362306a36Sopenharmony_ci/* Module probe, removal and of-matching */
194462306a36Sopenharmony_ci
194562306a36Sopenharmony_cistatic const char * const onames[] = {
194662306a36Sopenharmony_ci	"ep0out", "ep1out", "ep2out", "ep3out", "ep4out", "ep5out",
194762306a36Sopenharmony_ci	"ep6out", "ep7out", "ep8out", "ep9out", "ep10out", "ep11out",
194862306a36Sopenharmony_ci	"ep12out", "ep13out", "ep14out", "ep15out"
194962306a36Sopenharmony_ci};
195062306a36Sopenharmony_ci
195162306a36Sopenharmony_cistatic const char * const inames[] = {
195262306a36Sopenharmony_ci	"ep0in", "ep1in", "ep2in", "ep3in", "ep4in", "ep5in",
195362306a36Sopenharmony_ci	"ep6in", "ep7in", "ep8in", "ep9in", "ep10in", "ep11in",
195462306a36Sopenharmony_ci	"ep12in", "ep13in", "ep14in", "ep15in"
195562306a36Sopenharmony_ci};
195662306a36Sopenharmony_ci
195762306a36Sopenharmony_ci/* Must be called with dev->lock held */
195862306a36Sopenharmony_cistatic int gr_ep_init(struct gr_udc *dev, int num, int is_in, u32 maxplimit)
195962306a36Sopenharmony_ci{
196062306a36Sopenharmony_ci	struct gr_ep *ep;
196162306a36Sopenharmony_ci	struct gr_request *req;
196262306a36Sopenharmony_ci	struct usb_request *_req;
196362306a36Sopenharmony_ci	void *buf;
196462306a36Sopenharmony_ci
196562306a36Sopenharmony_ci	if (is_in) {
196662306a36Sopenharmony_ci		ep = &dev->epi[num];
196762306a36Sopenharmony_ci		ep->ep.name = inames[num];
196862306a36Sopenharmony_ci		ep->regs = &dev->regs->epi[num];
196962306a36Sopenharmony_ci	} else {
197062306a36Sopenharmony_ci		ep = &dev->epo[num];
197162306a36Sopenharmony_ci		ep->ep.name = onames[num];
197262306a36Sopenharmony_ci		ep->regs = &dev->regs->epo[num];
197362306a36Sopenharmony_ci	}
197462306a36Sopenharmony_ci
197562306a36Sopenharmony_ci	gr_ep_reset(ep);
197662306a36Sopenharmony_ci	ep->num = num;
197762306a36Sopenharmony_ci	ep->is_in = is_in;
197862306a36Sopenharmony_ci	ep->dev = dev;
197962306a36Sopenharmony_ci	ep->ep.ops = &gr_ep_ops;
198062306a36Sopenharmony_ci	INIT_LIST_HEAD(&ep->queue);
198162306a36Sopenharmony_ci
198262306a36Sopenharmony_ci	if (num == 0) {
198362306a36Sopenharmony_ci		_req = gr_alloc_request(&ep->ep, GFP_ATOMIC);
198462306a36Sopenharmony_ci		if (!_req)
198562306a36Sopenharmony_ci			return -ENOMEM;
198662306a36Sopenharmony_ci
198762306a36Sopenharmony_ci		buf = devm_kzalloc(dev->dev, PAGE_SIZE, GFP_DMA | GFP_ATOMIC);
198862306a36Sopenharmony_ci		if (!buf) {
198962306a36Sopenharmony_ci			gr_free_request(&ep->ep, _req);
199062306a36Sopenharmony_ci			return -ENOMEM;
199162306a36Sopenharmony_ci		}
199262306a36Sopenharmony_ci
199362306a36Sopenharmony_ci		req = container_of(_req, struct gr_request, req);
199462306a36Sopenharmony_ci		req->req.buf = buf;
199562306a36Sopenharmony_ci		req->req.length = MAX_CTRL_PL_SIZE;
199662306a36Sopenharmony_ci
199762306a36Sopenharmony_ci		if (is_in)
199862306a36Sopenharmony_ci			dev->ep0reqi = req; /* Complete gets set as used */
199962306a36Sopenharmony_ci		else
200062306a36Sopenharmony_ci			dev->ep0reqo = req; /* Completion treated separately */
200162306a36Sopenharmony_ci
200262306a36Sopenharmony_ci		usb_ep_set_maxpacket_limit(&ep->ep, MAX_CTRL_PL_SIZE);
200362306a36Sopenharmony_ci		ep->bytes_per_buffer = MAX_CTRL_PL_SIZE;
200462306a36Sopenharmony_ci
200562306a36Sopenharmony_ci		ep->ep.caps.type_control = true;
200662306a36Sopenharmony_ci	} else {
200762306a36Sopenharmony_ci		usb_ep_set_maxpacket_limit(&ep->ep, (u16)maxplimit);
200862306a36Sopenharmony_ci		list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
200962306a36Sopenharmony_ci
201062306a36Sopenharmony_ci		ep->ep.caps.type_iso = true;
201162306a36Sopenharmony_ci		ep->ep.caps.type_bulk = true;
201262306a36Sopenharmony_ci		ep->ep.caps.type_int = true;
201362306a36Sopenharmony_ci	}
201462306a36Sopenharmony_ci	list_add_tail(&ep->ep_list, &dev->ep_list);
201562306a36Sopenharmony_ci
201662306a36Sopenharmony_ci	if (is_in)
201762306a36Sopenharmony_ci		ep->ep.caps.dir_in = true;
201862306a36Sopenharmony_ci	else
201962306a36Sopenharmony_ci		ep->ep.caps.dir_out = true;
202062306a36Sopenharmony_ci
202162306a36Sopenharmony_ci	ep->tailbuf = dma_alloc_coherent(dev->dev, ep->ep.maxpacket_limit,
202262306a36Sopenharmony_ci					 &ep->tailbuf_paddr, GFP_ATOMIC);
202362306a36Sopenharmony_ci	if (!ep->tailbuf)
202462306a36Sopenharmony_ci		return -ENOMEM;
202562306a36Sopenharmony_ci
202662306a36Sopenharmony_ci	return 0;
202762306a36Sopenharmony_ci}
202862306a36Sopenharmony_ci
202962306a36Sopenharmony_ci/* Must be called with dev->lock held */
203062306a36Sopenharmony_cistatic int gr_udc_init(struct gr_udc *dev)
203162306a36Sopenharmony_ci{
203262306a36Sopenharmony_ci	struct device_node *np = dev->dev->of_node;
203362306a36Sopenharmony_ci	u32 epctrl_val;
203462306a36Sopenharmony_ci	u32 dmactrl_val;
203562306a36Sopenharmony_ci	int i;
203662306a36Sopenharmony_ci	int ret = 0;
203762306a36Sopenharmony_ci	u32 bufsize;
203862306a36Sopenharmony_ci
203962306a36Sopenharmony_ci	gr_set_address(dev, 0);
204062306a36Sopenharmony_ci
204162306a36Sopenharmony_ci	INIT_LIST_HEAD(&dev->gadget.ep_list);
204262306a36Sopenharmony_ci	dev->gadget.speed = USB_SPEED_UNKNOWN;
204362306a36Sopenharmony_ci	dev->gadget.ep0 = &dev->epi[0].ep;
204462306a36Sopenharmony_ci
204562306a36Sopenharmony_ci	INIT_LIST_HEAD(&dev->ep_list);
204662306a36Sopenharmony_ci	gr_set_ep0state(dev, GR_EP0_DISCONNECT);
204762306a36Sopenharmony_ci
204862306a36Sopenharmony_ci	for (i = 0; i < dev->nepo; i++) {
204962306a36Sopenharmony_ci		if (of_property_read_u32_index(np, "epobufsizes", i, &bufsize))
205062306a36Sopenharmony_ci			bufsize = 1024;
205162306a36Sopenharmony_ci		ret = gr_ep_init(dev, i, 0, bufsize);
205262306a36Sopenharmony_ci		if (ret)
205362306a36Sopenharmony_ci			return ret;
205462306a36Sopenharmony_ci	}
205562306a36Sopenharmony_ci
205662306a36Sopenharmony_ci	for (i = 0; i < dev->nepi; i++) {
205762306a36Sopenharmony_ci		if (of_property_read_u32_index(np, "epibufsizes", i, &bufsize))
205862306a36Sopenharmony_ci			bufsize = 1024;
205962306a36Sopenharmony_ci		ret = gr_ep_init(dev, i, 1, bufsize);
206062306a36Sopenharmony_ci		if (ret)
206162306a36Sopenharmony_ci			return ret;
206262306a36Sopenharmony_ci	}
206362306a36Sopenharmony_ci
206462306a36Sopenharmony_ci	/* Must be disabled by default */
206562306a36Sopenharmony_ci	dev->remote_wakeup = 0;
206662306a36Sopenharmony_ci
206762306a36Sopenharmony_ci	/* Enable ep0out and ep0in */
206862306a36Sopenharmony_ci	epctrl_val = (MAX_CTRL_PL_SIZE << GR_EPCTRL_MAXPL_POS) | GR_EPCTRL_EV;
206962306a36Sopenharmony_ci	dmactrl_val = GR_DMACTRL_IE | GR_DMACTRL_AI;
207062306a36Sopenharmony_ci	gr_write32(&dev->epo[0].regs->epctrl, epctrl_val);
207162306a36Sopenharmony_ci	gr_write32(&dev->epi[0].regs->epctrl, epctrl_val | GR_EPCTRL_PI);
207262306a36Sopenharmony_ci	gr_write32(&dev->epo[0].regs->dmactrl, dmactrl_val);
207362306a36Sopenharmony_ci	gr_write32(&dev->epi[0].regs->dmactrl, dmactrl_val);
207462306a36Sopenharmony_ci
207562306a36Sopenharmony_ci	return 0;
207662306a36Sopenharmony_ci}
207762306a36Sopenharmony_ci
207862306a36Sopenharmony_cistatic void gr_ep_remove(struct gr_udc *dev, int num, int is_in)
207962306a36Sopenharmony_ci{
208062306a36Sopenharmony_ci	struct gr_ep *ep;
208162306a36Sopenharmony_ci
208262306a36Sopenharmony_ci	if (is_in)
208362306a36Sopenharmony_ci		ep = &dev->epi[num];
208462306a36Sopenharmony_ci	else
208562306a36Sopenharmony_ci		ep = &dev->epo[num];
208662306a36Sopenharmony_ci
208762306a36Sopenharmony_ci	if (ep->tailbuf)
208862306a36Sopenharmony_ci		dma_free_coherent(dev->dev, ep->ep.maxpacket_limit,
208962306a36Sopenharmony_ci				  ep->tailbuf, ep->tailbuf_paddr);
209062306a36Sopenharmony_ci}
209162306a36Sopenharmony_ci
209262306a36Sopenharmony_cistatic int gr_remove(struct platform_device *pdev)
209362306a36Sopenharmony_ci{
209462306a36Sopenharmony_ci	struct gr_udc *dev = platform_get_drvdata(pdev);
209562306a36Sopenharmony_ci	int i;
209662306a36Sopenharmony_ci
209762306a36Sopenharmony_ci	if (dev->added)
209862306a36Sopenharmony_ci		usb_del_gadget_udc(&dev->gadget); /* Shuts everything down */
209962306a36Sopenharmony_ci	if (dev->driver)
210062306a36Sopenharmony_ci		return -EBUSY;
210162306a36Sopenharmony_ci
210262306a36Sopenharmony_ci	gr_dfs_delete(dev);
210362306a36Sopenharmony_ci	dma_pool_destroy(dev->desc_pool);
210462306a36Sopenharmony_ci	platform_set_drvdata(pdev, NULL);
210562306a36Sopenharmony_ci
210662306a36Sopenharmony_ci	gr_free_request(&dev->epi[0].ep, &dev->ep0reqi->req);
210762306a36Sopenharmony_ci	gr_free_request(&dev->epo[0].ep, &dev->ep0reqo->req);
210862306a36Sopenharmony_ci
210962306a36Sopenharmony_ci	for (i = 0; i < dev->nepo; i++)
211062306a36Sopenharmony_ci		gr_ep_remove(dev, i, 0);
211162306a36Sopenharmony_ci	for (i = 0; i < dev->nepi; i++)
211262306a36Sopenharmony_ci		gr_ep_remove(dev, i, 1);
211362306a36Sopenharmony_ci
211462306a36Sopenharmony_ci	return 0;
211562306a36Sopenharmony_ci}
211662306a36Sopenharmony_cistatic int gr_request_irq(struct gr_udc *dev, int irq)
211762306a36Sopenharmony_ci{
211862306a36Sopenharmony_ci	return devm_request_threaded_irq(dev->dev, irq, gr_irq, gr_irq_handler,
211962306a36Sopenharmony_ci					 IRQF_SHARED, driver_name, dev);
212062306a36Sopenharmony_ci}
212162306a36Sopenharmony_ci
212262306a36Sopenharmony_cistatic int gr_probe(struct platform_device *pdev)
212362306a36Sopenharmony_ci{
212462306a36Sopenharmony_ci	struct gr_udc *dev;
212562306a36Sopenharmony_ci	struct gr_regs __iomem *regs;
212662306a36Sopenharmony_ci	int retval;
212762306a36Sopenharmony_ci	u32 status;
212862306a36Sopenharmony_ci
212962306a36Sopenharmony_ci	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
213062306a36Sopenharmony_ci	if (!dev)
213162306a36Sopenharmony_ci		return -ENOMEM;
213262306a36Sopenharmony_ci	dev->dev = &pdev->dev;
213362306a36Sopenharmony_ci
213462306a36Sopenharmony_ci	regs = devm_platform_ioremap_resource(pdev, 0);
213562306a36Sopenharmony_ci	if (IS_ERR(regs))
213662306a36Sopenharmony_ci		return PTR_ERR(regs);
213762306a36Sopenharmony_ci
213862306a36Sopenharmony_ci	dev->irq = platform_get_irq(pdev, 0);
213962306a36Sopenharmony_ci	if (dev->irq < 0)
214062306a36Sopenharmony_ci		return dev->irq;
214162306a36Sopenharmony_ci
214262306a36Sopenharmony_ci	/* Some core configurations has separate irqs for IN and OUT events */
214362306a36Sopenharmony_ci	dev->irqi = platform_get_irq(pdev, 1);
214462306a36Sopenharmony_ci	if (dev->irqi > 0) {
214562306a36Sopenharmony_ci		dev->irqo = platform_get_irq(pdev, 2);
214662306a36Sopenharmony_ci		if (dev->irqo < 0)
214762306a36Sopenharmony_ci			return dev->irqo;
214862306a36Sopenharmony_ci	} else {
214962306a36Sopenharmony_ci		dev->irqi = 0;
215062306a36Sopenharmony_ci	}
215162306a36Sopenharmony_ci
215262306a36Sopenharmony_ci	dev->gadget.name = driver_name;
215362306a36Sopenharmony_ci	dev->gadget.max_speed = USB_SPEED_HIGH;
215462306a36Sopenharmony_ci	dev->gadget.ops = &gr_ops;
215562306a36Sopenharmony_ci
215662306a36Sopenharmony_ci	spin_lock_init(&dev->lock);
215762306a36Sopenharmony_ci	dev->regs = regs;
215862306a36Sopenharmony_ci
215962306a36Sopenharmony_ci	platform_set_drvdata(pdev, dev);
216062306a36Sopenharmony_ci
216162306a36Sopenharmony_ci	/* Determine number of endpoints and data interface mode */
216262306a36Sopenharmony_ci	status = gr_read32(&dev->regs->status);
216362306a36Sopenharmony_ci	dev->nepi = ((status & GR_STATUS_NEPI_MASK) >> GR_STATUS_NEPI_POS) + 1;
216462306a36Sopenharmony_ci	dev->nepo = ((status & GR_STATUS_NEPO_MASK) >> GR_STATUS_NEPO_POS) + 1;
216562306a36Sopenharmony_ci
216662306a36Sopenharmony_ci	if (!(status & GR_STATUS_DM)) {
216762306a36Sopenharmony_ci		dev_err(dev->dev, "Slave mode cores are not supported\n");
216862306a36Sopenharmony_ci		return -ENODEV;
216962306a36Sopenharmony_ci	}
217062306a36Sopenharmony_ci
217162306a36Sopenharmony_ci	/* --- Effects of the following calls might need explicit cleanup --- */
217262306a36Sopenharmony_ci
217362306a36Sopenharmony_ci	/* Create DMA pool for descriptors */
217462306a36Sopenharmony_ci	dev->desc_pool = dma_pool_create("desc_pool", dev->dev,
217562306a36Sopenharmony_ci					 sizeof(struct gr_dma_desc), 4, 0);
217662306a36Sopenharmony_ci	if (!dev->desc_pool) {
217762306a36Sopenharmony_ci		dev_err(dev->dev, "Could not allocate DMA pool");
217862306a36Sopenharmony_ci		return -ENOMEM;
217962306a36Sopenharmony_ci	}
218062306a36Sopenharmony_ci
218162306a36Sopenharmony_ci	/* Inside lock so that no gadget can use this udc until probe is done */
218262306a36Sopenharmony_ci	retval = usb_add_gadget_udc(dev->dev, &dev->gadget);
218362306a36Sopenharmony_ci	if (retval) {
218462306a36Sopenharmony_ci		dev_err(dev->dev, "Could not add gadget udc");
218562306a36Sopenharmony_ci		goto out;
218662306a36Sopenharmony_ci	}
218762306a36Sopenharmony_ci	dev->added = 1;
218862306a36Sopenharmony_ci
218962306a36Sopenharmony_ci	spin_lock(&dev->lock);
219062306a36Sopenharmony_ci
219162306a36Sopenharmony_ci	retval = gr_udc_init(dev);
219262306a36Sopenharmony_ci	if (retval) {
219362306a36Sopenharmony_ci		spin_unlock(&dev->lock);
219462306a36Sopenharmony_ci		goto out;
219562306a36Sopenharmony_ci	}
219662306a36Sopenharmony_ci
219762306a36Sopenharmony_ci	/* Clear all interrupt enables that might be left on since last boot */
219862306a36Sopenharmony_ci	gr_disable_interrupts_and_pullup(dev);
219962306a36Sopenharmony_ci
220062306a36Sopenharmony_ci	spin_unlock(&dev->lock);
220162306a36Sopenharmony_ci
220262306a36Sopenharmony_ci	gr_dfs_create(dev);
220362306a36Sopenharmony_ci
220462306a36Sopenharmony_ci	retval = gr_request_irq(dev, dev->irq);
220562306a36Sopenharmony_ci	if (retval) {
220662306a36Sopenharmony_ci		dev_err(dev->dev, "Failed to request irq %d\n", dev->irq);
220762306a36Sopenharmony_ci		goto out;
220862306a36Sopenharmony_ci	}
220962306a36Sopenharmony_ci
221062306a36Sopenharmony_ci	if (dev->irqi) {
221162306a36Sopenharmony_ci		retval = gr_request_irq(dev, dev->irqi);
221262306a36Sopenharmony_ci		if (retval) {
221362306a36Sopenharmony_ci			dev_err(dev->dev, "Failed to request irqi %d\n",
221462306a36Sopenharmony_ci				dev->irqi);
221562306a36Sopenharmony_ci			goto out;
221662306a36Sopenharmony_ci		}
221762306a36Sopenharmony_ci		retval = gr_request_irq(dev, dev->irqo);
221862306a36Sopenharmony_ci		if (retval) {
221962306a36Sopenharmony_ci			dev_err(dev->dev, "Failed to request irqo %d\n",
222062306a36Sopenharmony_ci				dev->irqo);
222162306a36Sopenharmony_ci			goto out;
222262306a36Sopenharmony_ci		}
222362306a36Sopenharmony_ci	}
222462306a36Sopenharmony_ci
222562306a36Sopenharmony_ci	if (dev->irqi)
222662306a36Sopenharmony_ci		dev_info(dev->dev, "regs: %p, irqs %d, %d, %d\n", dev->regs,
222762306a36Sopenharmony_ci			 dev->irq, dev->irqi, dev->irqo);
222862306a36Sopenharmony_ci	else
222962306a36Sopenharmony_ci		dev_info(dev->dev, "regs: %p, irq %d\n", dev->regs, dev->irq);
223062306a36Sopenharmony_ci
223162306a36Sopenharmony_ciout:
223262306a36Sopenharmony_ci	if (retval)
223362306a36Sopenharmony_ci		gr_remove(pdev);
223462306a36Sopenharmony_ci
223562306a36Sopenharmony_ci	return retval;
223662306a36Sopenharmony_ci}
223762306a36Sopenharmony_ci
223862306a36Sopenharmony_cistatic const struct of_device_id gr_match[] = {
223962306a36Sopenharmony_ci	{.name = "GAISLER_USBDC"},
224062306a36Sopenharmony_ci	{.name = "01_021"},
224162306a36Sopenharmony_ci	{},
224262306a36Sopenharmony_ci};
224362306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, gr_match);
224462306a36Sopenharmony_ci
224562306a36Sopenharmony_cistatic struct platform_driver gr_driver = {
224662306a36Sopenharmony_ci	.driver = {
224762306a36Sopenharmony_ci		.name = DRIVER_NAME,
224862306a36Sopenharmony_ci		.of_match_table = gr_match,
224962306a36Sopenharmony_ci	},
225062306a36Sopenharmony_ci	.probe = gr_probe,
225162306a36Sopenharmony_ci	.remove = gr_remove,
225262306a36Sopenharmony_ci};
225362306a36Sopenharmony_cimodule_platform_driver(gr_driver);
225462306a36Sopenharmony_ci
225562306a36Sopenharmony_ciMODULE_AUTHOR("Aeroflex Gaisler AB.");
225662306a36Sopenharmony_ciMODULE_DESCRIPTION(DRIVER_DESC);
225762306a36Sopenharmony_ciMODULE_LICENSE("GPL");
2258