// SPDX-License-Identifier: GPL-2.0
/*
 * Cadence USBHS-DEV Driver - gadget side.
 *
 * Copyright (C) 2023 Cadence Design Systems.
 *
 * Authors: Pawel Laszczak <pawell@cadence.com>
 */

/*
 * Work around 1:
 * At some situations, the controller may get stale data address in TRB
 * at below sequences:
 * 1. Controller read TRB includes data address
 * 2. Software updates TRBs includes data address and Cycle bit
 * 3. Controller read TRB which includes Cycle bit
 * 4. DMA run with stale data address
 *
 * To fix this problem, driver needs to make the first TRB in TD as invalid.
 * After preparing all TRBs driver needs to check the position of DMA and
 * if the DMA point to the first just added TRB and doorbell is 1,
 * then driver must defer making this TRB as valid. This TRB will be make
 * as valid during adding next TRB only if DMA is stopped or at TRBERR
 * interrupt.
 *
 */

#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
#include <linux/interrupt.h>
#include <linux/property.h>
#include <linux/dmapool.h>
#include <linux/iopoll.h>

#include "cdns2-gadget.h"
#include "cdns2-trace.h"

/**
 * set_reg_bit_32 - set bit in given 32 bits register.
 * @ptr: register address.
 * @mask: bits to set.
 */
static void set_reg_bit_32(void __iomem *ptr, u32 mask)
{
	mask = readl(ptr) | mask;
	writel(mask, ptr);
}

/*
 * clear_reg_bit_32 - clear bit in given 32 bits register.
 * @ptr: register address.
 * @mask: bits to clear.
 */
static void clear_reg_bit_32(void __iomem *ptr, u32 mask)
{
	mask = readl(ptr) & ~mask;
	writel(mask, ptr);
}

/* Clear bit in given 8 bits register. */
static void clear_reg_bit_8(void __iomem *ptr, u8 mask)
{
	mask = readb(ptr) & ~mask;
	writeb(mask, ptr);
}

/* Set bit in given 16 bits register. */
void set_reg_bit_8(void __iomem *ptr, u8 mask)
{
	mask = readb(ptr) | mask;
	writeb(mask, ptr);
}

static int cdns2_get_dma_pos(struct cdns2_device *pdev,
			     struct cdns2_endpoint *pep)
{
	int dma_index;

	dma_index = readl(&pdev->adma_regs->ep_traddr) - pep->ring.dma;

	return dma_index / TRB_SIZE;
}

/* Get next private request from list. */
struct cdns2_request *cdns2_next_preq(struct list_head *list)
{
	return list_first_entry_or_null(list, struct cdns2_request, list);
}

void cdns2_select_ep(struct cdns2_device *pdev, u32 ep)
{
	if (pdev->selected_ep == ep)
		return;

	pdev->selected_ep = ep;
	writel(ep, &pdev->adma_regs->ep_sel);
}

dma_addr_t cdns2_trb_virt_to_dma(struct cdns2_endpoint *pep,
				 struct cdns2_trb *trb)
{
	u32 offset = (char *)trb - (char *)pep->ring.trbs;

	return pep->ring.dma + offset;
}

static void cdns2_free_tr_segment(struct cdns2_endpoint *pep)
{
	struct cdns2_device *pdev = pep->pdev;
	struct cdns2_ring *ring = &pep->ring;

	if (pep->ring.trbs) {
		dma_pool_free(pdev->eps_dma_pool, ring->trbs, ring->dma);
		memset(ring, 0, sizeof(*ring));
	}
}

/* Allocates Transfer Ring segment. */
static int cdns2_alloc_tr_segment(struct cdns2_endpoint *pep)
{
	struct cdns2_device *pdev = pep->pdev;
	struct cdns2_trb *link_trb;
	struct cdns2_ring *ring;

	ring = &pep->ring;

	if (!ring->trbs) {
		ring->trbs = dma_pool_alloc(pdev->eps_dma_pool,
					    GFP_DMA32 | GFP_ATOMIC,
					    &ring->dma);
		if (!ring->trbs)
			return -ENOMEM;
	}

	memset(ring->trbs, 0, TR_SEG_SIZE);

	if (!pep->num)
		return 0;

	/* Initialize the last TRB as Link TRB */
	link_trb = (ring->trbs + (TRBS_PER_SEGMENT - 1));
	link_trb->buffer = cpu_to_le32(TRB_BUFFER(ring->dma));
	link_trb->control = cpu_to_le32(TRB_CYCLE | TRB_TYPE(TRB_LINK) |
					TRB_TOGGLE);

	return 0;
}

/*
 * Stalls and flushes selected endpoint.
 * Endpoint must be selected before invoking this function.
 */
static void cdns2_ep_stall_flush(struct cdns2_endpoint *pep)
{
	struct cdns2_device *pdev = pep->pdev;
	int val;

	trace_cdns2_ep_halt(pep, 1, 1);

	writel(DMA_EP_CMD_DFLUSH, &pdev->adma_regs->ep_cmd);

	/* Wait for DFLUSH cleared. */
	readl_poll_timeout_atomic(&pdev->adma_regs->ep_cmd, val,
				  !(val & DMA_EP_CMD_DFLUSH), 1, 1000);
	pep->ep_state |= EP_STALLED;
	pep->ep_state &= ~EP_STALL_PENDING;
}

/*
 * Increment a trb index.
 *
 * The index should never point to the last link TRB in TR. After incrementing,
 * if it point to the link TRB, wrap around to the beginning and revert
 * cycle state bit. The link TRB is always at the last TRB entry.
 */
static void cdns2_ep_inc_trb(int *index, u8 *cs, int trb_in_seg)
{
	(*index)++;
	if (*index == (trb_in_seg - 1)) {
		*index = 0;
		*cs ^=  1;
	}
}

static void cdns2_ep_inc_enq(struct cdns2_ring *ring)
{
	ring->free_trbs--;
	cdns2_ep_inc_trb(&ring->enqueue, &ring->pcs, TRBS_PER_SEGMENT);
}

static void cdns2_ep_inc_deq(struct cdns2_ring *ring)
{
	ring->free_trbs++;
	cdns2_ep_inc_trb(&ring->dequeue, &ring->ccs, TRBS_PER_SEGMENT);
}

/*
 * Enable/disable LPM.
 *
 * If bit USBCS_LPMNYET is not set and device receive Extended Token packet,
 * then controller answer with ACK handshake.
 * If bit USBCS_LPMNYET is set and device receive Extended Token packet,
 * then controller answer with NYET handshake.
 */
static void cdns2_enable_l1(struct cdns2_device *pdev, int enable)
{
	if (enable) {
		clear_reg_bit_8(&pdev->usb_regs->usbcs, USBCS_LPMNYET);
		writeb(LPMCLOCK_SLEEP_ENTRY, &pdev->usb_regs->lpmclock);
	} else {
		set_reg_bit_8(&pdev->usb_regs->usbcs, USBCS_LPMNYET);
	}
}

static enum usb_device_speed cdns2_get_speed(struct cdns2_device *pdev)
{
	u8 speed = readb(&pdev->usb_regs->speedctrl);

	if (speed & SPEEDCTRL_HS)
		return USB_SPEED_HIGH;
	else if (speed & SPEEDCTRL_FS)
		return USB_SPEED_FULL;

	return USB_SPEED_UNKNOWN;
}

static struct cdns2_trb *cdns2_next_trb(struct cdns2_endpoint *pep,
					struct cdns2_trb *trb)
{
	if (trb == (pep->ring.trbs + (TRBS_PER_SEGMENT - 1)))
		return pep->ring.trbs;
	else
		return ++trb;
}

void cdns2_gadget_giveback(struct cdns2_endpoint *pep,
			   struct cdns2_request *preq,
			   int status)
{
	struct usb_request *request = &preq->request;
	struct cdns2_device *pdev = pep->pdev;

	list_del_init(&preq->list);

	if (request->status == -EINPROGRESS)
		request->status = status;

	usb_gadget_unmap_request_by_dev(pdev->dev, request, pep->dir);

	/* All TRBs have finished, clear the counter. */
	preq->finished_trb = 0;

	trace_cdns2_request_giveback(preq);

	if (request->complete) {
		spin_unlock(&pdev->lock);
		usb_gadget_giveback_request(&pep->endpoint, request);
		spin_lock(&pdev->lock);
	}

	if (request->buf == pdev->zlp_buf)
		cdns2_gadget_ep_free_request(&pep->endpoint, request);
}

static void cdns2_wa1_restore_cycle_bit(struct cdns2_endpoint *pep)
{
	/* Work around for stale data address in TRB. */
	if (pep->wa1_set) {
		trace_cdns2_wa1(pep, "restore cycle bit");

		pep->wa1_set = 0;
		pep->wa1_trb_index = 0xFFFF;
		if (pep->wa1_cycle_bit)
			pep->wa1_trb->control |= cpu_to_le32(0x1);
		else
			pep->wa1_trb->control &= cpu_to_le32(~0x1);
	}
}

static int cdns2_wa1_update_guard(struct cdns2_endpoint *pep,
				  struct cdns2_trb *trb)
{
	struct cdns2_device *pdev = pep->pdev;

	if (!pep->wa1_set) {
		u32 doorbell;

		doorbell = !!(readl(&pdev->adma_regs->ep_cmd) & DMA_EP_CMD_DRDY);

		if (doorbell) {
			pep->wa1_cycle_bit = pep->ring.pcs ? TRB_CYCLE : 0;
			pep->wa1_set = 1;
			pep->wa1_trb = trb;
			pep->wa1_trb_index = pep->ring.enqueue;
			trace_cdns2_wa1(pep, "set guard");
			return 0;
		}
	}
	return 1;
}

static void cdns2_wa1_tray_restore_cycle_bit(struct cdns2_device *pdev,
					     struct cdns2_endpoint *pep)
{
	int dma_index;
	u32 doorbell;

	doorbell = !!(readl(&pdev->adma_regs->ep_cmd) & DMA_EP_CMD_DRDY);
	dma_index = cdns2_get_dma_pos(pdev, pep);

	if (!doorbell || dma_index != pep->wa1_trb_index)
		cdns2_wa1_restore_cycle_bit(pep);
}

static int cdns2_prepare_ring(struct cdns2_device *pdev,
			      struct cdns2_endpoint *pep,
			      int num_trbs)
{
	struct cdns2_trb *link_trb = NULL;
	int doorbell, dma_index;
	struct cdns2_ring *ring;
	u32 ch_bit = 0;

	ring = &pep->ring;

	if (num_trbs > ring->free_trbs) {
		pep->ep_state |= EP_RING_FULL;
		trace_cdns2_no_room_on_ring("Ring full\n");
		return -ENOBUFS;
	}

	if ((ring->enqueue + num_trbs)  >= (TRBS_PER_SEGMENT - 1)) {
		doorbell = !!(readl(&pdev->adma_regs->ep_cmd) & DMA_EP_CMD_DRDY);
		dma_index = cdns2_get_dma_pos(pdev, pep);

		/* Driver can't update LINK TRB if it is current processed. */
		if (doorbell && dma_index == TRBS_PER_SEGMENT - 1) {
			pep->ep_state |= EP_DEFERRED_DRDY;
			return -ENOBUFS;
		}

		/* Update C bt in Link TRB before starting DMA. */
		link_trb = ring->trbs + (TRBS_PER_SEGMENT - 1);

		/*
		 * For TRs size equal 2 enabling TRB_CHAIN for epXin causes
		 * that DMA stuck at the LINK TRB.
		 * On the other hand, removing TRB_CHAIN for longer TRs for
		 * epXout cause that DMA stuck after handling LINK TRB.
		 * To eliminate this strange behavioral driver set TRB_CHAIN
		 * bit only for TR size > 2.
		 */
		if (pep->type == USB_ENDPOINT_XFER_ISOC || TRBS_PER_SEGMENT > 2)
			ch_bit = TRB_CHAIN;

		link_trb->control = cpu_to_le32(((ring->pcs) ? TRB_CYCLE : 0) |
				    TRB_TYPE(TRB_LINK) | TRB_TOGGLE | ch_bit);
	}

	return 0;
}

static void cdns2_dbg_request_trbs(struct cdns2_endpoint *pep,
				   struct cdns2_request *preq)
{
	struct cdns2_trb *link_trb = pep->ring.trbs + (TRBS_PER_SEGMENT - 1);
	struct cdns2_trb *trb = preq->trb;
	int num_trbs = preq->num_of_trb;
	int i = 0;

	while (i < num_trbs) {
		trace_cdns2_queue_trb(pep, trb + i);
		if (trb + i == link_trb) {
			trb = pep->ring.trbs;
			num_trbs = num_trbs - i;
			i = 0;
		} else {
			i++;
		}
	}
}

static unsigned int cdns2_count_trbs(struct cdns2_endpoint *pep,
				     u64 addr, u64 len)
{
	unsigned int num_trbs = 1;

	if (pep->type == USB_ENDPOINT_XFER_ISOC) {
		/*
		 * To speed up DMA performance address should not exceed 4KB.
		 * for high bandwidth transfer and driver will split
		 * such buffer into two TRBs.
		 */
		num_trbs = DIV_ROUND_UP(len +
					(addr & (TRB_MAX_ISO_BUFF_SIZE - 1)),
					TRB_MAX_ISO_BUFF_SIZE);

		if (pep->interval > 1)
			num_trbs = pep->dir ? num_trbs * pep->interval : 1;
	} else if (pep->dir) {
		/*
		 * One extra link trb for IN direction.
		 * Sometimes DMA doesn't want advance to next TD and transfer
		 * hangs. This extra Link TRB force DMA to advance to next TD.
		 */
		num_trbs++;
	}

	return num_trbs;
}

static unsigned int cdns2_count_sg_trbs(struct cdns2_endpoint *pep,
					struct usb_request *req)
{
	unsigned int i, len, full_len, num_trbs = 0;
	struct scatterlist *sg;
	int trb_len = 0;

	full_len = req->length;

	for_each_sg(req->sg, sg, req->num_sgs, i) {
		len = sg_dma_len(sg);
		num_trbs += cdns2_count_trbs(pep, sg_dma_address(sg), len);
		len = min(len, full_len);

		/*
		 * For HS ISO transfer TRBs should not exceed max packet size.
		 * When DMA is working, and data exceed max packet size then
		 * some data will be read in single mode instead burst mode.
		 * This behavior will drastically reduce the copying speed.
		 * To avoid this we need one or two extra TRBs.
		 * This issue occurs for UVC class with sg_supported = 1
		 * because buffers addresses are not aligned to 1024.
		 */
		if (pep->type == USB_ENDPOINT_XFER_ISOC) {
			u8 temp;

			trb_len += len;
			temp = trb_len >> 10;

			if (temp) {
				if (trb_len % 1024)
					num_trbs = num_trbs + temp;
				else
					num_trbs = num_trbs + temp - 1;

				trb_len = trb_len - (temp << 10);
			}
		}

		full_len -= len;
		if (full_len == 0)
			break;
	}

	return num_trbs;
}

/*
 * Function prepares the array with optimized AXI burst value for different
 * transfer lengths. Controller handles the final data which are less
 * then AXI burst size as single byte transactions.
 * e.g.:
 * Let's assume that driver prepares trb with trb->length 700 and burst size
 * will be set to 128. In this case the controller will handle a first 512 as
 * single AXI transaction but the next 188 bytes will be handled
 * as 47 separate AXI transaction.
 * The better solution is to use the burst size equal 16 and then we will
 * have only 25 AXI transaction (10 * 64 + 15 *4).
 */
static void cdsn2_isoc_burst_opt(struct cdns2_device *pdev)
{
	int axi_burst_option[]  =  {1, 2, 4, 8, 16, 32, 64, 128};
	int best_burst;
	int array_size;
	int opt_burst;
	int trb_size;
	int i, j;

	array_size = ARRAY_SIZE(axi_burst_option);

	for (i = 0; i <= MAX_ISO_SIZE; i++) {
		trb_size = i / 4;
		best_burst = trb_size ? trb_size : 1;

		for (j = 0; j < array_size; j++) {
			opt_burst = trb_size / axi_burst_option[j];
			opt_burst += trb_size % axi_burst_option[j];

			if (opt_burst < best_burst) {
				best_burst = opt_burst;
				pdev->burst_opt[i] = axi_burst_option[j];
			}
		}
	}
}

static void cdns2_ep_tx_isoc(struct cdns2_endpoint *pep,
			     struct cdns2_request *preq,
			     int num_trbs)
{
	struct scatterlist *sg = NULL;
	u32 remaining_packet_size = 0;
	struct cdns2_trb *trb;
	bool first_trb = true;
	dma_addr_t trb_dma;
	u32 trb_buff_len;
	u32 block_length;
	int td_idx = 0;
	int split_size;
	u32 full_len;
	int enqd_len;
	int sent_len;
	int sg_iter;
	u32 control;
	int num_tds;
	u32 length;

	/*
	 * For OUT direction 1 TD per interval is enough
	 * because TRBs are not dumped by controller.
	 */
	num_tds = pep->dir ? pep->interval : 1;
	split_size = preq->request.num_sgs ? 1024 : 3072;

	for (td_idx = 0; td_idx < num_tds; td_idx++) {
		if (preq->request.num_sgs) {
			sg = preq->request.sg;
			trb_dma = sg_dma_address(sg);
			block_length = sg_dma_len(sg);
		} else {
			trb_dma = preq->request.dma;
			block_length = preq->request.length;
		}

		full_len = preq->request.length;
		sg_iter = preq->request.num_sgs ? preq->request.num_sgs : 1;
		remaining_packet_size = split_size;

		for (enqd_len = 0;  enqd_len < full_len;
		     enqd_len += trb_buff_len) {
			if (remaining_packet_size == 0)
				remaining_packet_size = split_size;

			/*
			 * Calculate TRB length.- buffer can't across 4KB
			 * and max packet size.
			 */
			trb_buff_len = TRB_BUFF_LEN_UP_TO_BOUNDARY(trb_dma);
			trb_buff_len = min(trb_buff_len, remaining_packet_size);
			trb_buff_len = min(trb_buff_len, block_length);

			if (trb_buff_len > full_len - enqd_len)
				trb_buff_len = full_len - enqd_len;

			control = TRB_TYPE(TRB_NORMAL);

			/*
			 * For IN direction driver has to set the IOC for
			 * last TRB in last TD.
			 * For OUT direction driver must set IOC and ISP
			 * only for last TRB in each TDs.
			 */
			if (enqd_len + trb_buff_len >= full_len || !pep->dir)
				control |= TRB_IOC | TRB_ISP;

			/*
			 * Don't give the first TRB to the hardware (by toggling
			 * the cycle bit) until we've finished creating all the
			 * other TRBs.
			 */
			if (first_trb) {
				first_trb = false;
				if (pep->ring.pcs == 0)
					control |= TRB_CYCLE;
			} else {
				control |= pep->ring.pcs;
			}

			if (enqd_len + trb_buff_len < full_len)
				control |= TRB_CHAIN;

			length = TRB_LEN(trb_buff_len) |
				 TRB_BURST(pep->pdev->burst_opt[trb_buff_len]);

			trb = pep->ring.trbs + pep->ring.enqueue;
			trb->buffer = cpu_to_le32(TRB_BUFFER(trb_dma));
			trb->length = cpu_to_le32(length);
			trb->control = cpu_to_le32(control);

			trb_dma += trb_buff_len;
			sent_len = trb_buff_len;

			if (sg && sent_len >= block_length) {
				/* New sg entry */
				--sg_iter;
				sent_len -= block_length;
				if (sg_iter != 0) {
					sg = sg_next(sg);
					trb_dma = sg_dma_address(sg);
					block_length = sg_dma_len(sg);
				}
			}

			remaining_packet_size -= trb_buff_len;
			block_length -= sent_len;
			preq->end_trb = pep->ring.enqueue;

			cdns2_ep_inc_enq(&pep->ring);
		}
	}
}

static void cdns2_ep_tx_bulk(struct cdns2_endpoint *pep,
			     struct cdns2_request *preq,
			     int trbs_per_td)
{
	struct scatterlist *sg = NULL;
	struct cdns2_ring *ring;
	struct cdns2_trb *trb;
	dma_addr_t trb_dma;
	int sg_iter = 0;
	u32 control;
	u32 length;

	if (preq->request.num_sgs) {
		sg = preq->request.sg;
		trb_dma = sg_dma_address(sg);
		length = sg_dma_len(sg);
	} else {
		trb_dma = preq->request.dma;
		length = preq->request.length;
	}

	ring = &pep->ring;

	for (sg_iter = 0; sg_iter < trbs_per_td; sg_iter++) {
		control = TRB_TYPE(TRB_NORMAL) | ring->pcs | TRB_ISP;
		trb = pep->ring.trbs + ring->enqueue;

		if (pep->dir && sg_iter == trbs_per_td - 1) {
			preq->end_trb = ring->enqueue;
			control = ring->pcs | TRB_TYPE(TRB_LINK) | TRB_CHAIN
				  | TRB_IOC;
			cdns2_ep_inc_enq(&pep->ring);

			if (ring->enqueue == 0)
				control |= TRB_TOGGLE;

			/* Point to next bad TRB. */
			trb->buffer = cpu_to_le32(pep->ring.dma +
						  (ring->enqueue * TRB_SIZE));
			trb->length = 0;
			trb->control = cpu_to_le32(control);
			break;
		}

		/*
		 * Don't give the first TRB to the hardware (by toggling
		 * the cycle bit) until we've finished creating all the
		 * other TRBs.
		 */
		if (sg_iter == 0)
			control = control ^ TRB_CYCLE;

		/* For last TRB in TD. */
		if (sg_iter == (trbs_per_td - (pep->dir ? 2 : 1)))
			control |= TRB_IOC;
		else
			control |= TRB_CHAIN;

		trb->buffer = cpu_to_le32(trb_dma);
		trb->length = cpu_to_le32(TRB_BURST(pep->trb_burst_size) |
					   TRB_LEN(length));
		trb->control = cpu_to_le32(control);

		if (sg && sg_iter < (trbs_per_td - 1)) {
			sg = sg_next(sg);
			trb_dma = sg_dma_address(sg);
			length = sg_dma_len(sg);
		}

		preq->end_trb = ring->enqueue;
		cdns2_ep_inc_enq(&pep->ring);
	}
}

static void cdns2_set_drdy(struct cdns2_device *pdev,
			   struct cdns2_endpoint *pep)
{
	trace_cdns2_ring(pep);

	/*
	 * Memory barrier - Cycle Bit must be set before doorbell.
	 */
	dma_wmb();

	/* Clearing TRBERR and DESCMIS before setting DRDY. */
	writel(DMA_EP_STS_TRBERR | DMA_EP_STS_DESCMIS,
	       &pdev->adma_regs->ep_sts);
	writel(DMA_EP_CMD_DRDY, &pdev->adma_regs->ep_cmd);

	if (readl(&pdev->adma_regs->ep_sts) & DMA_EP_STS_TRBERR) {
		writel(DMA_EP_STS_TRBERR, &pdev->adma_regs->ep_sts);
		writel(DMA_EP_CMD_DRDY, &pdev->adma_regs->ep_cmd);
	}

	trace_cdns2_doorbell_epx(pep, readl(&pdev->adma_regs->ep_traddr));
}

static int cdns2_prepare_first_isoc_transfer(struct cdns2_device *pdev,
					     struct cdns2_endpoint *pep)
{
	struct cdns2_trb *trb;
	u32 buffer;
	u8 hw_ccs;

	if ((readl(&pdev->adma_regs->ep_cmd) & DMA_EP_CMD_DRDY))
		return -EBUSY;

	if (!pep->dir) {
		set_reg_bit_32(&pdev->adma_regs->ep_cfg, DMA_EP_CFG_ENABLE);
		writel(pep->ring.dma + pep->ring.dequeue,
		       &pdev->adma_regs->ep_traddr);
		return 0;
	}

	/*
	 * The first packet after doorbell can be corrupted so,
	 * driver prepares 0 length packet as first packet.
	 */
	buffer = pep->ring.dma + pep->ring.dequeue * TRB_SIZE;
	hw_ccs = !!DMA_EP_STS_CCS(readl(&pdev->adma_regs->ep_sts));

	trb = &pep->ring.trbs[TRBS_PER_SEGMENT];
	trb->length = 0;
	trb->buffer = cpu_to_le32(TRB_BUFFER(buffer));
	trb->control = cpu_to_le32((hw_ccs ? TRB_CYCLE : 0) | TRB_TYPE(TRB_NORMAL));

	/*
	 * LINK TRB is used to force updating cycle bit in controller and
	 * move to correct place in transfer ring.
	 */
	trb++;
	trb->length = 0;
	trb->buffer = cpu_to_le32(TRB_BUFFER(buffer));
	trb->control = cpu_to_le32((hw_ccs ? TRB_CYCLE : 0) |
				    TRB_TYPE(TRB_LINK) | TRB_CHAIN);

	if (hw_ccs !=  pep->ring.ccs)
		trb->control |= cpu_to_le32(TRB_TOGGLE);

	set_reg_bit_32(&pdev->adma_regs->ep_cfg, DMA_EP_CFG_ENABLE);
	writel(pep->ring.dma + (TRBS_PER_SEGMENT * TRB_SIZE),
	       &pdev->adma_regs->ep_traddr);

	return 0;
}

/* Prepare and start transfer on no-default endpoint. */
static int cdns2_ep_run_transfer(struct cdns2_endpoint *pep,
				 struct cdns2_request *preq)
{
	struct cdns2_device *pdev = pep->pdev;
	struct cdns2_ring *ring;
	u32 togle_pcs = 1;
	int num_trbs;
	int ret;

	cdns2_select_ep(pdev, pep->endpoint.address);

	if (preq->request.sg)
		num_trbs = cdns2_count_sg_trbs(pep, &preq->request);
	else
		num_trbs = cdns2_count_trbs(pep, preq->request.dma,
					    preq->request.length);

	ret = cdns2_prepare_ring(pdev, pep, num_trbs);
	if (ret)
		return ret;

	ring = &pep->ring;
	preq->start_trb = ring->enqueue;
	preq->trb = ring->trbs + ring->enqueue;

	if (usb_endpoint_xfer_isoc(pep->endpoint.desc)) {
		cdns2_ep_tx_isoc(pep, preq, num_trbs);
	} else {
		togle_pcs = cdns2_wa1_update_guard(pep, ring->trbs + ring->enqueue);
		cdns2_ep_tx_bulk(pep, preq, num_trbs);
	}

	preq->num_of_trb = num_trbs;

	/*
	 * Memory barrier - cycle bit must be set as the last operation.
	 */
	dma_wmb();

	/* Give the TD to the consumer. */
	if (togle_pcs)
		preq->trb->control = preq->trb->control ^ cpu_to_le32(1);

	cdns2_wa1_tray_restore_cycle_bit(pdev, pep);
	cdns2_dbg_request_trbs(pep, preq);

	if (!pep->wa1_set && !(pep->ep_state & EP_STALLED) && !pep->skip) {
		if (pep->type == USB_ENDPOINT_XFER_ISOC) {
			ret = cdns2_prepare_first_isoc_transfer(pdev, pep);
			if (ret)
				return 0;
		}

		cdns2_set_drdy(pdev, pep);
	}

	return 0;
}

/* Prepare and start transfer for all not started requests. */
static int cdns2_start_all_request(struct cdns2_device *pdev,
				   struct cdns2_endpoint *pep)
{
	struct cdns2_request *preq;
	int ret;

	while (!list_empty(&pep->deferred_list)) {
		preq = cdns2_next_preq(&pep->deferred_list);

		ret = cdns2_ep_run_transfer(pep, preq);
		if (ret)
			return ret;

		list_move_tail(&preq->list, &pep->pending_list);
	}

	pep->ep_state &= ~EP_RING_FULL;

	return 0;
}

/*
 * Check whether trb has been handled by DMA.
 *
 * Endpoint must be selected before invoking this function.
 *
 * Returns false if request has not been handled by DMA, else returns true.
 *
 * SR - start ring
 * ER - end ring
 * DQ = ring->dequeue - dequeue position
 * EQ = ring->enqueue - enqueue position
 * ST = preq->start_trb - index of first TRB in transfer ring
 * ET = preq->end_trb - index of last TRB in transfer ring
 * CI = current_index - index of processed TRB by DMA.
 *
 * As first step, we check if the TRB between the ST and ET.
 * Then, we check if cycle bit for index pep->dequeue
 * is correct.
 *
 * some rules:
 * 1. ring->dequeue never equals to current_index.
 * 2  ring->enqueue never exceed ring->dequeue
 * 3. exception: ring->enqueue == ring->dequeue
 *    and ring->free_trbs is zero.
 *    This case indicate that TR is full.
 *
 * At below two cases, the request have been handled.
 * Case 1 - ring->dequeue < current_index
 *      SR ... EQ ... DQ ... CI ... ER
 *      SR ... DQ ... CI ... EQ ... ER
 *
 * Case 2 - ring->dequeue > current_index
 * This situation takes place when CI go through the LINK TRB at the end of
 * transfer ring.
 *      SR ... CI ... EQ ... DQ ... ER
 */
static bool cdns2_trb_handled(struct cdns2_endpoint *pep,
			      struct cdns2_request *preq)
{
	struct cdns2_device *pdev = pep->pdev;
	struct cdns2_ring *ring;
	struct cdns2_trb *trb;
	int current_index = 0;
	int handled = 0;
	int doorbell;

	ring = &pep->ring;
	current_index = cdns2_get_dma_pos(pdev, pep);
	doorbell = !!(readl(&pdev->adma_regs->ep_cmd) & DMA_EP_CMD_DRDY);

	/*
	 * Only ISO transfer can use 2 entries outside the standard
	 * Transfer Ring. First of them is used as zero length packet and the
	 * second as LINK TRB.
	 */
	if (current_index >= TRBS_PER_SEGMENT)
		goto finish;

	/* Current trb doesn't belong to this request. */
	if (preq->start_trb < preq->end_trb) {
		if (ring->dequeue > preq->end_trb)
			goto finish;

		if (ring->dequeue < preq->start_trb)
			goto finish;
	}

	if (preq->start_trb > preq->end_trb && ring->dequeue > preq->end_trb &&
	    ring->dequeue < preq->start_trb)
		goto finish;

	if (preq->start_trb == preq->end_trb && ring->dequeue != preq->end_trb)
		goto finish;

	trb = &ring->trbs[ring->dequeue];

	if ((le32_to_cpu(trb->control) & TRB_CYCLE) != ring->ccs)
		goto finish;

	if (doorbell == 1 && current_index == ring->dequeue)
		goto finish;

	/* The corner case for TRBS_PER_SEGMENT equal 2). */
	if (TRBS_PER_SEGMENT == 2 && pep->type != USB_ENDPOINT_XFER_ISOC) {
		handled = 1;
		goto finish;
	}

	if (ring->enqueue == ring->dequeue &&
	    ring->free_trbs == 0) {
		handled = 1;
	} else if (ring->dequeue < current_index) {
		if ((current_index == (TRBS_PER_SEGMENT - 1)) &&
		    !ring->dequeue)
			goto finish;

		handled = 1;
	} else if (ring->dequeue  > current_index) {
		handled = 1;
	}

finish:
	trace_cdns2_request_handled(preq, current_index, handled);

	return handled;
}

static void cdns2_skip_isoc_td(struct cdns2_device *pdev,
			       struct cdns2_endpoint *pep,
			       struct cdns2_request *preq)
{
	struct cdns2_trb *trb;
	int i;

	trb = pep->ring.trbs + pep->ring.dequeue;

	for (i = preq->finished_trb ; i < preq->num_of_trb; i++) {
		preq->finished_trb++;
		trace_cdns2_complete_trb(pep, trb);
		cdns2_ep_inc_deq(&pep->ring);
		trb = cdns2_next_trb(pep, trb);
	}

	cdns2_gadget_giveback(pep, preq, 0);
	cdns2_prepare_first_isoc_transfer(pdev, pep);
	pep->skip = false;
	cdns2_set_drdy(pdev, pep);
}

static void cdns2_transfer_completed(struct cdns2_device *pdev,
				     struct cdns2_endpoint *pep)
{
	struct cdns2_request *preq = NULL;
	bool request_handled = false;
	struct cdns2_trb *trb;

	while (!list_empty(&pep->pending_list)) {
		preq = cdns2_next_preq(&pep->pending_list);
		trb = pep->ring.trbs + pep->ring.dequeue;

		/*
		 * The TRB was changed as link TRB, and the request
		 * was handled at ep_dequeue.
		 */
		while (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK &&
		       le32_to_cpu(trb->length)) {
			trace_cdns2_complete_trb(pep, trb);
			cdns2_ep_inc_deq(&pep->ring);
			trb = pep->ring.trbs + pep->ring.dequeue;
		}

		/*
		 * Re-select endpoint. It could be changed by other CPU
		 * during handling usb_gadget_giveback_request.
		 */
		cdns2_select_ep(pdev, pep->endpoint.address);

		while (cdns2_trb_handled(pep, preq)) {
			preq->finished_trb++;

			if (preq->finished_trb >= preq->num_of_trb)
				request_handled = true;

			trb = pep->ring.trbs + pep->ring.dequeue;
			trace_cdns2_complete_trb(pep, trb);

			if (pep->dir && pep->type == USB_ENDPOINT_XFER_ISOC)
				/*
				 * For ISOC IN controller doens't update the
				 * trb->length.
				 */
				preq->request.actual = preq->request.length;
			else
				preq->request.actual +=
					TRB_LEN(le32_to_cpu(trb->length));

			cdns2_ep_inc_deq(&pep->ring);
		}

		if (request_handled) {
			cdns2_gadget_giveback(pep, preq, 0);
			request_handled = false;
		} else {
			goto prepare_next_td;
		}

		if (pep->type != USB_ENDPOINT_XFER_ISOC &&
		    TRBS_PER_SEGMENT == 2)
			break;
	}

prepare_next_td:
	if (pep->skip && preq)
		cdns2_skip_isoc_td(pdev, pep, preq);

	if (!(pep->ep_state & EP_STALLED) &&
	    !(pep->ep_state & EP_STALL_PENDING))
		cdns2_start_all_request(pdev, pep);
}

static void cdns2_wakeup(struct cdns2_device *pdev)
{
	if (!pdev->may_wakeup)
		return;

	/* Start driving resume signaling to indicate remote wakeup. */
	set_reg_bit_8(&pdev->usb_regs->usbcs, USBCS_SIGRSUME);
}

static void cdns2_rearm_transfer(struct cdns2_endpoint *pep, u8 rearm)
{
	struct cdns2_device *pdev = pep->pdev;

	cdns2_wa1_restore_cycle_bit(pep);

	if (rearm) {
		trace_cdns2_ring(pep);

		/* Cycle Bit must be updated before arming DMA. */
		dma_wmb();

		writel(DMA_EP_CMD_DRDY, &pdev->adma_regs->ep_cmd);

		cdns2_wakeup(pdev);

		trace_cdns2_doorbell_epx(pep,
					 readl(&pdev->adma_regs->ep_traddr));
	}
}

static void cdns2_handle_epx_interrupt(struct cdns2_endpoint *pep)
{
	struct cdns2_device *pdev = pep->pdev;
	u8 isoerror = 0;
	u32 ep_sts_reg;
	u32 val;

	cdns2_select_ep(pdev, pep->endpoint.address);

	trace_cdns2_epx_irq(pdev, pep);

	ep_sts_reg = readl(&pdev->adma_regs->ep_sts);
	writel(ep_sts_reg, &pdev->adma_regs->ep_sts);

	if (pep->type == USB_ENDPOINT_XFER_ISOC) {
		u8 mult;
		u8 cs;

		mult = USB_EP_MAXP_MULT(pep->endpoint.desc->wMaxPacketSize);
		cs = pep->dir ? readb(&pdev->epx_regs->ep[pep->num - 1].txcs) :
				readb(&pdev->epx_regs->ep[pep->num - 1].rxcs);
		if (mult > 0)
			isoerror = EPX_CS_ERR(cs);
	}

	/*
	 * Sometimes ISO Error for mult=1 or mult=2 is not propagated on time
	 * from USB module to DMA module. To protect against this driver
	 * checks also the txcs/rxcs registers.
	 */
	if ((ep_sts_reg & DMA_EP_STS_ISOERR) || isoerror) {
		clear_reg_bit_32(&pdev->adma_regs->ep_cfg, DMA_EP_CFG_ENABLE);

		/* Wait for DBUSY cleared. */
		readl_poll_timeout_atomic(&pdev->adma_regs->ep_sts, val,
					  !(val & DMA_EP_STS_DBUSY), 1, 125);

		writel(DMA_EP_CMD_DFLUSH, &pep->pdev->adma_regs->ep_cmd);

		/* Wait for DFLUSH cleared. */
		readl_poll_timeout_atomic(&pep->pdev->adma_regs->ep_cmd, val,
					  !(val & DMA_EP_CMD_DFLUSH), 1, 10);

		pep->skip = true;
	}

	if (ep_sts_reg & DMA_EP_STS_TRBERR || pep->skip) {
		if (pep->ep_state & EP_STALL_PENDING &&
		    !(ep_sts_reg & DMA_EP_STS_DESCMIS))
			cdns2_ep_stall_flush(pep);

		/*
		 * For isochronous transfer driver completes request on
		 * IOC or on TRBERR. IOC appears only when device receive
		 * OUT data packet. If host disable stream or lost some packet
		 * then the only way to finish all queued transfer is to do it
		 * on TRBERR event.
		 */
		if (pep->type == USB_ENDPOINT_XFER_ISOC && !pep->wa1_set) {
			if (!pep->dir)
				clear_reg_bit_32(&pdev->adma_regs->ep_cfg,
						 DMA_EP_CFG_ENABLE);

			cdns2_transfer_completed(pdev, pep);
			if (pep->ep_state & EP_DEFERRED_DRDY) {
				pep->ep_state &= ~EP_DEFERRED_DRDY;
				cdns2_set_drdy(pdev, pep);
			}

			return;
		}

		cdns2_transfer_completed(pdev, pep);

		if (!(pep->ep_state & EP_STALLED) &&
		    !(pep->ep_state & EP_STALL_PENDING)) {
			if (pep->ep_state & EP_DEFERRED_DRDY) {
				pep->ep_state &= ~EP_DEFERRED_DRDY;
				cdns2_start_all_request(pdev, pep);
			} else {
				cdns2_rearm_transfer(pep, pep->wa1_set);
			}
		}

		return;
	}

	if ((ep_sts_reg & DMA_EP_STS_IOC) || (ep_sts_reg & DMA_EP_STS_ISP))
		cdns2_transfer_completed(pdev, pep);
}

static void cdns2_disconnect_gadget(struct cdns2_device *pdev)
{
	if (pdev->gadget_driver && pdev->gadget_driver->disconnect)
		pdev->gadget_driver->disconnect(&pdev->gadget);
}

static irqreturn_t cdns2_usb_irq_handler(int irq, void *data)
{
	struct cdns2_device *pdev = data;
	unsigned long reg_ep_ists;
	u8 reg_usb_irq_m;
	u8 reg_ext_irq_m;
	u8 reg_usb_irq;
	u8 reg_ext_irq;

	if (pdev->in_lpm)
		return IRQ_NONE;

	reg_usb_irq_m = readb(&pdev->interrupt_regs->usbien);
	reg_ext_irq_m = readb(&pdev->interrupt_regs->extien);

	/* Mask all sources of interrupt. */
	writeb(0, &pdev->interrupt_regs->usbien);
	writeb(0, &pdev->interrupt_regs->extien);
	writel(0, &pdev->adma_regs->ep_ien);

	/* Clear interrupt sources. */
	writel(0, &pdev->adma_regs->ep_sts);
	writeb(0, &pdev->interrupt_regs->usbirq);
	writeb(0, &pdev->interrupt_regs->extirq);

	reg_ep_ists = readl(&pdev->adma_regs->ep_ists);
	reg_usb_irq = readb(&pdev->interrupt_regs->usbirq);
	reg_ext_irq = readb(&pdev->interrupt_regs->extirq);

	if (reg_ep_ists || (reg_usb_irq & reg_usb_irq_m) ||
	    (reg_ext_irq & reg_ext_irq_m))
		return IRQ_WAKE_THREAD;

	writeb(USB_IEN_INIT, &pdev->interrupt_regs->usbien);
	writeb(EXTIRQ_WAKEUP, &pdev->interrupt_regs->extien);
	writel(~0, &pdev->adma_regs->ep_ien);

	return IRQ_NONE;
}

static irqreturn_t cdns2_thread_usb_irq_handler(struct cdns2_device *pdev)
{
	u8 usb_irq, ext_irq;
	int speed;
	int i;

	ext_irq = readb(&pdev->interrupt_regs->extirq) & EXTIRQ_WAKEUP;
	writeb(ext_irq, &pdev->interrupt_regs->extirq);

	usb_irq = readb(&pdev->interrupt_regs->usbirq) & USB_IEN_INIT;
	writeb(usb_irq, &pdev->interrupt_regs->usbirq);

	if (!ext_irq && !usb_irq)
		return IRQ_NONE;

	trace_cdns2_usb_irq(usb_irq, ext_irq);

	if (ext_irq & EXTIRQ_WAKEUP) {
		if (pdev->gadget_driver && pdev->gadget_driver->resume) {
			spin_unlock(&pdev->lock);
			pdev->gadget_driver->resume(&pdev->gadget);
			spin_lock(&pdev->lock);
		}
	}

	if (usb_irq & USBIRQ_LPM) {
		u8 reg = readb(&pdev->usb_regs->lpmctrl);

		/* LPM1 enter */
		if (!(reg & LPMCTRLLH_LPMNYET))
			writeb(0, &pdev->usb_regs->sleep_clkgate);
	}

	if (usb_irq & USBIRQ_SUSPEND) {
		if (pdev->gadget_driver && pdev->gadget_driver->suspend) {
			spin_unlock(&pdev->lock);
			pdev->gadget_driver->suspend(&pdev->gadget);
			spin_lock(&pdev->lock);
		}
	}

	if (usb_irq & USBIRQ_URESET) {
		if (pdev->gadget_driver) {
			pdev->dev_address = 0;

			spin_unlock(&pdev->lock);
			usb_gadget_udc_reset(&pdev->gadget,
					     pdev->gadget_driver);
			spin_lock(&pdev->lock);

			/*
			 * The USBIRQ_URESET is reported at the beginning of
			 * reset signal. 100ms is enough time to finish reset
			 * process. For high-speed reset procedure is completed
			 * when controller detect HS mode.
			 */
			for (i = 0; i < 100; i++) {
				mdelay(1);
				speed = cdns2_get_speed(pdev);
				if (speed == USB_SPEED_HIGH)
					break;
			}

			pdev->gadget.speed = speed;
			cdns2_enable_l1(pdev, 0);
			cdns2_ep0_config(pdev);
			pdev->may_wakeup = 0;
		}
	}

	if (usb_irq & USBIRQ_SUDAV) {
		pdev->ep0_stage = CDNS2_SETUP_STAGE;
		cdns2_handle_setup_packet(pdev);
	}

	return IRQ_HANDLED;
}

/* Deferred USB interrupt handler. */
static irqreturn_t cdns2_thread_irq_handler(int irq, void *data)
{
	struct cdns2_device *pdev = data;
	unsigned long  dma_ep_ists;
	unsigned long flags;
	unsigned int bit;

	local_bh_disable();
	spin_lock_irqsave(&pdev->lock, flags);

	cdns2_thread_usb_irq_handler(pdev);

	dma_ep_ists = readl(&pdev->adma_regs->ep_ists);
	if (!dma_ep_ists)
		goto unlock;

	trace_cdns2_dma_ep_ists(dma_ep_ists);

	/* Handle default endpoint OUT. */
	if (dma_ep_ists & DMA_EP_ISTS_EP_OUT0)
		cdns2_handle_ep0_interrupt(pdev, USB_DIR_OUT);

	/* Handle default endpoint IN. */
	if (dma_ep_ists & DMA_EP_ISTS_EP_IN0)
		cdns2_handle_ep0_interrupt(pdev, USB_DIR_IN);

	dma_ep_ists &= ~(DMA_EP_ISTS_EP_OUT0 | DMA_EP_ISTS_EP_IN0);

	for_each_set_bit(bit, &dma_ep_ists, sizeof(u32) * BITS_PER_BYTE) {
		u8 ep_idx = bit > 16 ? (bit - 16) * 2 : (bit * 2) - 1;

		/*
		 * Endpoints in pdev->eps[] are held in order:
		 * ep0, ep1out, ep1in, ep2out, ep2in... ep15out, ep15in.
		 * but in dma_ep_ists in order:
		 * ep0 ep1out ep2out ... ep15out ep0in ep1in .. ep15in
		 */
		cdns2_handle_epx_interrupt(&pdev->eps[ep_idx]);
	}

unlock:
	writel(~0, &pdev->adma_regs->ep_ien);
	writeb(USB_IEN_INIT, &pdev->interrupt_regs->usbien);
	writeb(EXTIRQ_WAKEUP, &pdev->interrupt_regs->extien);

	spin_unlock_irqrestore(&pdev->lock, flags);
	local_bh_enable();

	return IRQ_HANDLED;
}

/* Calculates and assigns onchip memory for endpoints. */
static void cdns2_eps_onchip_buffer_init(struct cdns2_device *pdev)
{
	struct cdns2_endpoint *pep;
	int min_buf_tx = 0;
	int min_buf_rx = 0;
	u16 tx_offset = 0;
	u16 rx_offset = 0;
	int free;
	int i;

	for (i = 0; i < CDNS2_ENDPOINTS_NUM; i++) {
		pep = &pdev->eps[i];

		if (!(pep->ep_state & EP_CLAIMED))
			continue;

		if (pep->dir)
			min_buf_tx += pep->buffering;
		else
			min_buf_rx += pep->buffering;
	}

	for (i = 0; i < CDNS2_ENDPOINTS_NUM; i++) {
		pep = &pdev->eps[i];

		if (!(pep->ep_state & EP_CLAIMED))
			continue;

		if (pep->dir) {
			free = pdev->onchip_tx_buf - min_buf_tx;

			if (free + pep->buffering >= 4)
				free = 4;
			else
				free = free + pep->buffering;

			min_buf_tx = min_buf_tx - pep->buffering + free;

			pep->buffering = free;

			writel(tx_offset,
			       &pdev->epx_regs->txstaddr[pep->num - 1]);
			pdev->epx_regs->txstaddr[pep->num - 1] = tx_offset;

			dev_dbg(pdev->dev, "%s onchip address %04x, buffering: %d\n",
				pep->name, tx_offset, pep->buffering);

			tx_offset += pep->buffering * 1024;
		} else {
			free = pdev->onchip_rx_buf - min_buf_rx;

			if (free + pep->buffering >= 4)
				free = 4;
			else
				free = free + pep->buffering;

			min_buf_rx = min_buf_rx - pep->buffering + free;

			pep->buffering = free;
			writel(rx_offset,
			       &pdev->epx_regs->rxstaddr[pep->num - 1]);

			dev_dbg(pdev->dev, "%s onchip address %04x, buffering: %d\n",
				pep->name, rx_offset, pep->buffering);

			rx_offset += pep->buffering * 1024;
		}
	}
}

/* Configure hardware endpoint. */
static int cdns2_ep_config(struct cdns2_endpoint *pep, bool enable)
{
	bool is_iso_ep = (pep->type == USB_ENDPOINT_XFER_ISOC);
	struct cdns2_device *pdev = pep->pdev;
	u32 max_packet_size;
	u8 dir = 0;
	u8 ep_cfg;
	u8 mult;
	u32 val;
	int ret;

	switch (pep->type) {
	case USB_ENDPOINT_XFER_INT:
		ep_cfg = EPX_CON_TYPE_INT;
		break;
	case USB_ENDPOINT_XFER_BULK:
		ep_cfg = EPX_CON_TYPE_BULK;
		break;
	default:
		mult = USB_EP_MAXP_MULT(pep->endpoint.desc->wMaxPacketSize);
		ep_cfg = mult << EPX_CON_ISOD_SHIFT;
		ep_cfg |= EPX_CON_TYPE_ISOC;

		if (pep->dir) {
			set_reg_bit_8(&pdev->epx_regs->isoautoarm, BIT(pep->num));
			set_reg_bit_8(&pdev->epx_regs->isoautodump, BIT(pep->num));
			set_reg_bit_8(&pdev->epx_regs->isodctrl, BIT(pep->num));
		}
	}

	switch (pdev->gadget.speed) {
	case USB_SPEED_FULL:
		max_packet_size = is_iso_ep ? 1023 : 64;
		break;
	case USB_SPEED_HIGH:
		max_packet_size = is_iso_ep ? 1024 : 512;
		break;
	default:
		/* All other speed are not supported. */
		return -EINVAL;
	}

	ep_cfg |= (EPX_CON_VAL | (pep->buffering - 1));

	if (pep->dir) {
		dir = FIFOCTRL_IO_TX;
		writew(max_packet_size, &pdev->epx_regs->txmaxpack[pep->num - 1]);
		writeb(ep_cfg, &pdev->epx_regs->ep[pep->num - 1].txcon);
	} else {
		writew(max_packet_size, &pdev->epx_regs->rxmaxpack[pep->num - 1]);
		writeb(ep_cfg, &pdev->epx_regs->ep[pep->num - 1].rxcon);
	}

	writeb(pep->num | dir | FIFOCTRL_FIFOAUTO,
	       &pdev->usb_regs->fifoctrl);
	writeb(pep->num | dir, &pdev->epx_regs->endprst);
	writeb(pep->num | ENDPRST_FIFORST | ENDPRST_TOGRST | dir,
	       &pdev->epx_regs->endprst);

	if (max_packet_size == 1024)
		pep->trb_burst_size = 128;
	else if (max_packet_size >= 512)
		pep->trb_burst_size = 64;
	else
		pep->trb_burst_size = 16;

	cdns2_select_ep(pdev, pep->num | pep->dir);
	writel(DMA_EP_CMD_EPRST | DMA_EP_CMD_DFLUSH, &pdev->adma_regs->ep_cmd);

	ret = readl_poll_timeout_atomic(&pdev->adma_regs->ep_cmd, val,
					!(val & (DMA_EP_CMD_DFLUSH |
					DMA_EP_CMD_EPRST)),
					1, 1000);

	if (ret)
		return ret;

	writel(DMA_EP_STS_TRBERR | DMA_EP_STS_ISOERR, &pdev->adma_regs->ep_sts_en);

	if (enable)
		writel(DMA_EP_CFG_ENABLE, &pdev->adma_regs->ep_cfg);

	trace_cdns2_epx_hw_cfg(pdev, pep);

	dev_dbg(pdev->dev, "Configure %s: with MPS: %08x, ep con: %02x\n",
		pep->name, max_packet_size, ep_cfg);

	return 0;
}

struct usb_request *cdns2_gadget_ep_alloc_request(struct usb_ep *ep,
						  gfp_t gfp_flags)
{
	struct cdns2_endpoint *pep = ep_to_cdns2_ep(ep);
	struct cdns2_request *preq;

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

	preq->pep = pep;

	trace_cdns2_alloc_request(preq);

	return &preq->request;
}

void cdns2_gadget_ep_free_request(struct usb_ep *ep,
				  struct usb_request *request)
{
	struct cdns2_request *preq = to_cdns2_request(request);

	trace_cdns2_free_request(preq);
	kfree(preq);
}

static int cdns2_gadget_ep_enable(struct usb_ep *ep,
				  const struct usb_endpoint_descriptor *desc)
{
	u32 reg = DMA_EP_STS_EN_TRBERREN;
	struct cdns2_endpoint *pep;
	struct cdns2_device *pdev;
	unsigned long flags;
	int enable = 1;
	int ret = 0;

	if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT ||
	    !desc->wMaxPacketSize) {
		return -EINVAL;
	}

	pep = ep_to_cdns2_ep(ep);
	pdev = pep->pdev;

	if (dev_WARN_ONCE(pdev->dev, pep->ep_state & EP_ENABLED,
			  "%s is already enabled\n", pep->name))
		return 0;

	spin_lock_irqsave(&pdev->lock, flags);

	pep->type = usb_endpoint_type(desc);
	pep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0;

	if (pdev->gadget.speed == USB_SPEED_FULL)
		if (pep->type == USB_ENDPOINT_XFER_INT)
			pep->interval = desc->bInterval;

	if (pep->interval > ISO_MAX_INTERVAL &&
	    pep->type == USB_ENDPOINT_XFER_ISOC) {
		dev_err(pdev->dev, "ISO period is limited to %d (current: %d)\n",
			ISO_MAX_INTERVAL, pep->interval);

		ret =  -EINVAL;
		goto exit;
	}

	/*
	 * During ISO OUT traffic DMA reads Transfer Ring for the EP which has
	 * never got doorbell.
	 * This issue was detected only on simulation, but to avoid this issue
	 * driver add protection against it. To fix it driver enable ISO OUT
	 * endpoint before setting DRBL. This special treatment of ISO OUT
	 * endpoints are recommended by controller specification.
	 */
	if (pep->type == USB_ENDPOINT_XFER_ISOC  && !pep->dir)
		enable = 0;

	ret = cdns2_alloc_tr_segment(pep);
	if (ret)
		goto exit;

	ret = cdns2_ep_config(pep, enable);
	if (ret) {
		cdns2_free_tr_segment(pep);
		ret =  -EINVAL;
		goto exit;
	}

	trace_cdns2_gadget_ep_enable(pep);

	pep->ep_state &= ~(EP_STALLED | EP_STALL_PENDING);
	pep->ep_state |= EP_ENABLED;
	pep->wa1_set = 0;
	pep->ring.enqueue = 0;
	pep->ring.dequeue = 0;
	reg = readl(&pdev->adma_regs->ep_sts);
	pep->ring.pcs = !!DMA_EP_STS_CCS(reg);
	pep->ring.ccs = !!DMA_EP_STS_CCS(reg);

	writel(pep->ring.dma, &pdev->adma_regs->ep_traddr);

	/* one TRB is reserved for link TRB used in DMULT mode*/
	pep->ring.free_trbs = TRBS_PER_SEGMENT - 1;

exit:
	spin_unlock_irqrestore(&pdev->lock, flags);

	return ret;
}

static int cdns2_gadget_ep_disable(struct usb_ep *ep)
{
	struct cdns2_endpoint *pep;
	struct cdns2_request *preq;
	struct cdns2_device *pdev;
	unsigned long flags;
	int val;

	if (!ep)
		return -EINVAL;

	pep = ep_to_cdns2_ep(ep);
	pdev = pep->pdev;

	if (dev_WARN_ONCE(pdev->dev, !(pep->ep_state & EP_ENABLED),
			  "%s is already disabled\n", pep->name))
		return 0;

	spin_lock_irqsave(&pdev->lock, flags);

	trace_cdns2_gadget_ep_disable(pep);

	cdns2_select_ep(pdev, ep->desc->bEndpointAddress);

	clear_reg_bit_32(&pdev->adma_regs->ep_cfg, DMA_EP_CFG_ENABLE);

	/*
	 * Driver needs some time before resetting endpoint.
	 * It need waits for clearing DBUSY bit or for timeout expired.
	 * 10us is enough time for controller to stop transfer.
	 */
	readl_poll_timeout_atomic(&pdev->adma_regs->ep_sts, val,
				  !(val & DMA_EP_STS_DBUSY), 1, 10);
	writel(DMA_EP_CMD_EPRST, &pdev->adma_regs->ep_cmd);

	readl_poll_timeout_atomic(&pdev->adma_regs->ep_cmd, val,
				  !(val & (DMA_EP_CMD_DFLUSH | DMA_EP_CMD_EPRST)),
				  1, 1000);

	while (!list_empty(&pep->pending_list)) {
		preq = cdns2_next_preq(&pep->pending_list);
		cdns2_gadget_giveback(pep, preq, -ESHUTDOWN);
	}

	while (!list_empty(&pep->deferred_list)) {
		preq = cdns2_next_preq(&pep->deferred_list);
		cdns2_gadget_giveback(pep, preq, -ESHUTDOWN);
	}

	ep->desc = NULL;
	pep->ep_state &= ~EP_ENABLED;

	spin_unlock_irqrestore(&pdev->lock, flags);

	return 0;
}

static int cdns2_ep_enqueue(struct cdns2_endpoint *pep,
			    struct cdns2_request *preq,
			    gfp_t gfp_flags)
{
	struct cdns2_device *pdev = pep->pdev;
	struct usb_request *request;
	int ret;

	request = &preq->request;
	request->actual = 0;
	request->status = -EINPROGRESS;

	ret = usb_gadget_map_request_by_dev(pdev->dev, request, pep->dir);
	if (ret) {
		trace_cdns2_request_enqueue_error(preq);
		return ret;
	}

	list_add_tail(&preq->list, &pep->deferred_list);
	trace_cdns2_request_enqueue(preq);

	if (!(pep->ep_state & EP_STALLED) && !(pep->ep_state & EP_STALL_PENDING))
		cdns2_start_all_request(pdev, pep);

	return 0;
}

static int cdns2_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
				 gfp_t gfp_flags)
{
	struct usb_request *zlp_request;
	struct cdns2_request *preq;
	struct cdns2_endpoint *pep;
	struct cdns2_device *pdev;
	unsigned long flags;
	int ret;

	if (!request || !ep)
		return -EINVAL;

	pep = ep_to_cdns2_ep(ep);
	pdev = pep->pdev;

	if (!(pep->ep_state & EP_ENABLED)) {
		dev_err(pdev->dev, "%s: can't queue to disabled endpoint\n",
			pep->name);
		return -EINVAL;
	}

	spin_lock_irqsave(&pdev->lock, flags);

	preq =  to_cdns2_request(request);
	ret = cdns2_ep_enqueue(pep, preq, gfp_flags);

	if (ret == 0 && request->zero && request->length &&
	    (request->length % ep->maxpacket == 0)) {
		struct cdns2_request *preq;

		zlp_request = cdns2_gadget_ep_alloc_request(ep, GFP_ATOMIC);
		zlp_request->buf = pdev->zlp_buf;
		zlp_request->length = 0;

		preq = to_cdns2_request(zlp_request);
		ret = cdns2_ep_enqueue(pep, preq, gfp_flags);
	}

	spin_unlock_irqrestore(&pdev->lock, flags);
	return ret;
}

int cdns2_gadget_ep_dequeue(struct usb_ep *ep,
			    struct usb_request *request)
{
	struct cdns2_request *preq, *preq_temp, *cur_preq;
	struct cdns2_endpoint *pep;
	struct cdns2_trb *link_trb;
	u8 req_on_hw_ring = 0;
	unsigned long flags;
	u32 buffer;
	int val, i;

	if (!ep || !request || !ep->desc)
		return -EINVAL;

	pep = ep_to_cdns2_ep(ep);
	if (!pep->endpoint.desc) {
		dev_err(pep->pdev->dev, "%s: can't dequeue to disabled endpoint\n",
			pep->name);
		return -ESHUTDOWN;
	}

	/* Requests has been dequeued during disabling endpoint. */
	if (!(pep->ep_state & EP_ENABLED))
		return 0;

	spin_lock_irqsave(&pep->pdev->lock, flags);

	cur_preq = to_cdns2_request(request);
	trace_cdns2_request_dequeue(cur_preq);

	list_for_each_entry_safe(preq, preq_temp, &pep->pending_list, list) {
		if (cur_preq == preq) {
			req_on_hw_ring = 1;
			goto found;
		}
	}

	list_for_each_entry_safe(preq, preq_temp, &pep->deferred_list, list) {
		if (cur_preq == preq)
			goto found;
	}

	goto not_found;

found:
	link_trb = preq->trb;

	/* Update ring only if removed request is on pending_req_list list. */
	if (req_on_hw_ring && link_trb) {
		/* Stop DMA */
		writel(DMA_EP_CMD_DFLUSH, &pep->pdev->adma_regs->ep_cmd);

		/* Wait for DFLUSH cleared. */
		readl_poll_timeout_atomic(&pep->pdev->adma_regs->ep_cmd, val,
					  !(val & DMA_EP_CMD_DFLUSH), 1, 1000);

		buffer = cpu_to_le32(TRB_BUFFER(pep->ring.dma +
				    ((preq->end_trb + 1) * TRB_SIZE)));

		for (i = 0; i < preq->num_of_trb; i++) {
			link_trb->buffer = buffer;
			link_trb->control = cpu_to_le32((le32_to_cpu(link_trb->control)
					    & TRB_CYCLE) | TRB_CHAIN |
					    TRB_TYPE(TRB_LINK));

			trace_cdns2_queue_trb(pep, link_trb);
			link_trb = cdns2_next_trb(pep, link_trb);
		}

		if (pep->wa1_trb == preq->trb)
			cdns2_wa1_restore_cycle_bit(pep);
	}

	cdns2_gadget_giveback(pep, cur_preq, -ECONNRESET);

	preq = cdns2_next_preq(&pep->pending_list);
	if (preq)
		cdns2_rearm_transfer(pep, 1);

not_found:
	spin_unlock_irqrestore(&pep->pdev->lock, flags);
	return 0;
}

int cdns2_halt_endpoint(struct cdns2_device *pdev,
			struct cdns2_endpoint *pep,
			int value)
{
	u8 __iomem *conf;
	int dir = 0;

	if (!(pep->ep_state & EP_ENABLED))
		return -EPERM;

	if (pep->dir) {
		dir = ENDPRST_IO_TX;
		conf = &pdev->epx_regs->ep[pep->num - 1].txcon;
	} else {
		conf = &pdev->epx_regs->ep[pep->num - 1].rxcon;
	}

	if (!value) {
		struct cdns2_trb *trb = NULL;
		struct cdns2_request *preq;
		struct cdns2_trb trb_tmp;

		preq = cdns2_next_preq(&pep->pending_list);
		if (preq) {
			trb = preq->trb;
			if (trb) {
				trb_tmp = *trb;
				trb->control = trb->control ^ cpu_to_le32(TRB_CYCLE);
			}
		}

		trace_cdns2_ep_halt(pep, 0, 0);

		/* Resets Sequence Number */
		writeb(dir | pep->num, &pdev->epx_regs->endprst);
		writeb(dir | ENDPRST_TOGRST | pep->num,
		       &pdev->epx_regs->endprst);

		clear_reg_bit_8(conf, EPX_CON_STALL);

		pep->ep_state &= ~(EP_STALLED | EP_STALL_PENDING);

		if (preq) {
			if (trb)
				*trb = trb_tmp;

			cdns2_rearm_transfer(pep, 1);
		}

		cdns2_start_all_request(pdev, pep);
	} else {
		trace_cdns2_ep_halt(pep, 1, 0);
		set_reg_bit_8(conf, EPX_CON_STALL);
		writeb(dir | pep->num, &pdev->epx_regs->endprst);
		writeb(dir | ENDPRST_FIFORST | pep->num,
		       &pdev->epx_regs->endprst);
		pep->ep_state |= EP_STALLED;
	}

	return 0;
}

/* Sets/clears stall on selected endpoint. */
static int cdns2_gadget_ep_set_halt(struct usb_ep *ep, int value)
{
	struct cdns2_endpoint *pep = ep_to_cdns2_ep(ep);
	struct cdns2_device *pdev = pep->pdev;
	struct cdns2_request *preq;
	unsigned long flags = 0;
	int ret;

	spin_lock_irqsave(&pdev->lock, flags);

	preq = cdns2_next_preq(&pep->pending_list);
	if (value && preq) {
		trace_cdns2_ep_busy_try_halt_again(pep);
		ret = -EAGAIN;
		goto done;
	}

	if (!value)
		pep->ep_state &= ~EP_WEDGE;

	ret = cdns2_halt_endpoint(pdev, pep, value);

done:
	spin_unlock_irqrestore(&pdev->lock, flags);
	return ret;
}

static int cdns2_gadget_ep_set_wedge(struct usb_ep *ep)
{
	struct cdns2_endpoint *pep = ep_to_cdns2_ep(ep);

	cdns2_gadget_ep_set_halt(ep, 1);
	pep->ep_state |= EP_WEDGE;

	return 0;
}

static struct
cdns2_endpoint *cdns2_find_available_ep(struct cdns2_device *pdev,
					struct usb_endpoint_descriptor *desc)
{
	struct cdns2_endpoint *pep;
	struct usb_ep *ep;
	int ep_correct;

	list_for_each_entry(ep, &pdev->gadget.ep_list, ep_list) {
		unsigned long num;
		int ret;
		/* ep name pattern likes epXin or epXout. */
		char c[2] = {ep->name[2], '\0'};

		ret = kstrtoul(c, 10, &num);
		if (ret)
			return ERR_PTR(ret);
		pep = ep_to_cdns2_ep(ep);

		if (pep->num != num)
			continue;

		ep_correct = (pep->endpoint.caps.dir_in &&
			      usb_endpoint_dir_in(desc)) ||
			     (pep->endpoint.caps.dir_out &&
			      usb_endpoint_dir_out(desc));

		if (ep_correct && !(pep->ep_state & EP_CLAIMED))
			return pep;
	}

	return ERR_PTR(-ENOENT);
}

/*
 * Function used to recognize which endpoints will be used to optimize
 * on-chip memory usage.
 */
static struct
usb_ep *cdns2_gadget_match_ep(struct usb_gadget *gadget,
			      struct usb_endpoint_descriptor *desc,
			      struct usb_ss_ep_comp_descriptor *comp_desc)
{
	struct cdns2_device *pdev = gadget_to_cdns2_device(gadget);
	struct cdns2_endpoint *pep;
	unsigned long flags;

	pep = cdns2_find_available_ep(pdev, desc);
	if (IS_ERR(pep)) {
		dev_err(pdev->dev, "no available ep\n");
		return NULL;
	}

	spin_lock_irqsave(&pdev->lock, flags);

	if (usb_endpoint_type(desc) == USB_ENDPOINT_XFER_ISOC)
		pep->buffering = 4;
	else
		pep->buffering = 1;

	pep->ep_state |= EP_CLAIMED;
	spin_unlock_irqrestore(&pdev->lock, flags);

	return &pep->endpoint;
}

static const struct usb_ep_ops cdns2_gadget_ep_ops = {
	.enable = cdns2_gadget_ep_enable,
	.disable = cdns2_gadget_ep_disable,
	.alloc_request = cdns2_gadget_ep_alloc_request,
	.free_request = cdns2_gadget_ep_free_request,
	.queue = cdns2_gadget_ep_queue,
	.dequeue = cdns2_gadget_ep_dequeue,
	.set_halt = cdns2_gadget_ep_set_halt,
	.set_wedge = cdns2_gadget_ep_set_wedge,
};

static int cdns2_gadget_get_frame(struct usb_gadget *gadget)
{
	struct cdns2_device *pdev = gadget_to_cdns2_device(gadget);

	return readw(&pdev->usb_regs->frmnr);
}

static int cdns2_gadget_wakeup(struct usb_gadget *gadget)
{
	struct cdns2_device *pdev = gadget_to_cdns2_device(gadget);
	unsigned long flags;

	spin_lock_irqsave(&pdev->lock, flags);
	cdns2_wakeup(pdev);
	spin_unlock_irqrestore(&pdev->lock, flags);

	return 0;
}

static int cdns2_gadget_set_selfpowered(struct usb_gadget *gadget,
					int is_selfpowered)
{
	struct cdns2_device *pdev = gadget_to_cdns2_device(gadget);
	unsigned long flags;

	spin_lock_irqsave(&pdev->lock, flags);
	pdev->is_selfpowered = !!is_selfpowered;
	spin_unlock_irqrestore(&pdev->lock, flags);
	return 0;
}

/*  Disable interrupts and begin the controller halting process. */
static void cdns2_quiesce(struct cdns2_device *pdev)
{
	set_reg_bit_8(&pdev->usb_regs->usbcs, USBCS_DISCON);

	/* Disable interrupt. */
	writeb(0, &pdev->interrupt_regs->extien),
	writeb(0, &pdev->interrupt_regs->usbien),
	writew(0, &pdev->adma_regs->ep_ien);

	/* Clear interrupt line. */
	writeb(0x0, &pdev->interrupt_regs->usbirq);
}

static void cdns2_gadget_config(struct cdns2_device *pdev)
{
	cdns2_ep0_config(pdev);

	/* Enable DMA interrupts for all endpoints. */
	writel(~0x0, &pdev->adma_regs->ep_ien);
	cdns2_enable_l1(pdev, 0);
	writeb(USB_IEN_INIT, &pdev->interrupt_regs->usbien);
	writeb(EXTIRQ_WAKEUP, &pdev->interrupt_regs->extien);
	writel(DMA_CONF_DMULT, &pdev->adma_regs->conf);
}

static int cdns2_gadget_pullup(struct usb_gadget *gadget, int is_on)
{
	struct cdns2_device *pdev = gadget_to_cdns2_device(gadget);
	unsigned long flags;

	trace_cdns2_pullup(is_on);

	/*
	 * Disable events handling while controller is being
	 * enabled/disabled.
	 */
	disable_irq(pdev->irq);
	spin_lock_irqsave(&pdev->lock, flags);

	if (is_on) {
		cdns2_gadget_config(pdev);
		clear_reg_bit_8(&pdev->usb_regs->usbcs, USBCS_DISCON);
	} else {
		cdns2_quiesce(pdev);
	}

	spin_unlock_irqrestore(&pdev->lock, flags);
	enable_irq(pdev->irq);

	return 0;
}

static int cdns2_gadget_udc_start(struct usb_gadget *gadget,
				  struct usb_gadget_driver *driver)
{
	struct cdns2_device *pdev = gadget_to_cdns2_device(gadget);
	enum usb_device_speed max_speed = driver->max_speed;
	unsigned long flags;

	spin_lock_irqsave(&pdev->lock, flags);
	pdev->gadget_driver = driver;

	/* Limit speed if necessary. */
	max_speed = min(driver->max_speed, gadget->max_speed);

	switch (max_speed) {
	case USB_SPEED_FULL:
		writeb(SPEEDCTRL_HSDISABLE, &pdev->usb_regs->speedctrl);
		break;
	case USB_SPEED_HIGH:
		writeb(0, &pdev->usb_regs->speedctrl);
		break;
	default:
		dev_err(pdev->dev, "invalid maximum_speed parameter %d\n",
			max_speed);
		fallthrough;
	case USB_SPEED_UNKNOWN:
		/* Default to highspeed. */
		max_speed = USB_SPEED_HIGH;
		break;
	}

	/* Reset all USB endpoints. */
	writeb(ENDPRST_IO_TX, &pdev->usb_regs->endprst);
	writeb(ENDPRST_FIFORST | ENDPRST_TOGRST | ENDPRST_IO_TX,
	       &pdev->usb_regs->endprst);
	writeb(ENDPRST_FIFORST | ENDPRST_TOGRST, &pdev->usb_regs->endprst);

	cdns2_eps_onchip_buffer_init(pdev);

	cdns2_gadget_config(pdev);
	spin_unlock_irqrestore(&pdev->lock, flags);

	return 0;
}

static int cdns2_gadget_udc_stop(struct usb_gadget *gadget)
{
	struct cdns2_device *pdev = gadget_to_cdns2_device(gadget);
	struct cdns2_endpoint *pep;
	u32 bEndpointAddress;
	struct usb_ep *ep;
	int val;

	pdev->gadget_driver = NULL;
	pdev->gadget.speed = USB_SPEED_UNKNOWN;

	list_for_each_entry(ep, &pdev->gadget.ep_list, ep_list) {
		pep = ep_to_cdns2_ep(ep);
		bEndpointAddress = pep->num | pep->dir;
		cdns2_select_ep(pdev, bEndpointAddress);
		writel(DMA_EP_CMD_EPRST, &pdev->adma_regs->ep_cmd);
		readl_poll_timeout_atomic(&pdev->adma_regs->ep_cmd, val,
					  !(val & DMA_EP_CMD_EPRST), 1, 100);
	}

	cdns2_quiesce(pdev);

	writeb(ENDPRST_IO_TX, &pdev->usb_regs->endprst);
	writeb(ENDPRST_FIFORST | ENDPRST_TOGRST | ENDPRST_IO_TX,
	       &pdev->epx_regs->endprst);
	writeb(ENDPRST_FIFORST | ENDPRST_TOGRST, &pdev->epx_regs->endprst);

	return 0;
}

static const struct usb_gadget_ops cdns2_gadget_ops = {
	.get_frame = cdns2_gadget_get_frame,
	.wakeup = cdns2_gadget_wakeup,
	.set_selfpowered = cdns2_gadget_set_selfpowered,
	.pullup = cdns2_gadget_pullup,
	.udc_start = cdns2_gadget_udc_start,
	.udc_stop = cdns2_gadget_udc_stop,
	.match_ep = cdns2_gadget_match_ep,
};

static void cdns2_free_all_eps(struct cdns2_device *pdev)
{
	int i;

	for (i = 0; i < CDNS2_ENDPOINTS_NUM; i++)
		cdns2_free_tr_segment(&pdev->eps[i]);
}

/* Initializes software endpoints of gadget. */
static int cdns2_init_eps(struct cdns2_device *pdev)
{
	struct cdns2_endpoint *pep;
	int i;

	for (i = 0; i < CDNS2_ENDPOINTS_NUM; i++) {
		bool direction = !(i & 1); /* Start from OUT endpoint. */
		u8 epnum = ((i + 1) >> 1);

		/*
		 * Endpoints are being held in pdev->eps[] in form:
		 * ep0, ep1out, ep1in ... ep15out, ep15in.
		 */
		if (!CDNS2_IF_EP_EXIST(pdev, epnum, direction))
			continue;

		pep = &pdev->eps[i];
		pep->pdev = pdev;
		pep->num = epnum;
		/* 0 for OUT, 1 for IN. */
		pep->dir = direction ? USB_DIR_IN : USB_DIR_OUT;
		pep->idx = i;

		/* Ep0in and ep0out are represented by pdev->eps[0]. */
		if (!epnum) {
			int ret;

			snprintf(pep->name, sizeof(pep->name), "ep%d%s",
				 epnum, "BiDir");

			cdns2_init_ep0(pdev, pep);

			ret = cdns2_alloc_tr_segment(pep);
			if (ret) {
				dev_err(pdev->dev, "Failed to init ep0\n");
				return ret;
			}
		} else {
			snprintf(pep->name, sizeof(pep->name), "ep%d%s",
				 epnum, !!direction ? "in" : "out");
			pep->endpoint.name = pep->name;

			usb_ep_set_maxpacket_limit(&pep->endpoint, 1024);
			pep->endpoint.ops = &cdns2_gadget_ep_ops;
			list_add_tail(&pep->endpoint.ep_list, &pdev->gadget.ep_list);

			pep->endpoint.caps.dir_in = direction;
			pep->endpoint.caps.dir_out = !direction;

			pep->endpoint.caps.type_iso = 1;
			pep->endpoint.caps.type_bulk = 1;
			pep->endpoint.caps.type_int = 1;
		}

		pep->endpoint.name = pep->name;
		pep->ep_state = 0;

		dev_dbg(pdev->dev, "Init %s, SupType: CTRL: %s, INT: %s, "
			"BULK: %s, ISOC %s, SupDir IN: %s, OUT: %s\n",
			pep->name,
			(pep->endpoint.caps.type_control) ? "yes" : "no",
			(pep->endpoint.caps.type_int) ? "yes" : "no",
			(pep->endpoint.caps.type_bulk) ? "yes" : "no",
			(pep->endpoint.caps.type_iso) ? "yes" : "no",
			(pep->endpoint.caps.dir_in) ? "yes" : "no",
			(pep->endpoint.caps.dir_out) ? "yes" : "no");

		INIT_LIST_HEAD(&pep->pending_list);
		INIT_LIST_HEAD(&pep->deferred_list);
	}

	return 0;
}

static int cdns2_gadget_start(struct cdns2_device *pdev)
{
	u32 max_speed;
	void *buf;
	int val;
	int ret;

	pdev->usb_regs = pdev->regs;
	pdev->ep0_regs = pdev->regs;
	pdev->epx_regs = pdev->regs;
	pdev->interrupt_regs = pdev->regs;
	pdev->adma_regs = pdev->regs + CDNS2_ADMA_REGS_OFFSET;

	/* Reset controller. */
	set_reg_bit_8(&pdev->usb_regs->cpuctrl, CPUCTRL_SW_RST);

	ret = readl_poll_timeout_atomic(&pdev->usb_regs->cpuctrl, val,
					!(val & CPUCTRL_SW_RST), 1, 10000);
	if (ret) {
		dev_err(pdev->dev, "Error: reset controller timeout\n");
		return -EINVAL;
	}

	usb_initialize_gadget(pdev->dev, &pdev->gadget, NULL);

	device_property_read_u16(pdev->dev, "cdns,on-chip-tx-buff-size",
				 &pdev->onchip_tx_buf);
	device_property_read_u16(pdev->dev, "cdns,on-chip-rx-buff-size",
				 &pdev->onchip_rx_buf);
	device_property_read_u32(pdev->dev, "cdns,avail-endpoints",
				 &pdev->eps_supported);

	/*
	 * Driver assumes that each USBHS controller has at least
	 * one IN and one OUT non control endpoint.
	 */
	if (!pdev->onchip_tx_buf && !pdev->onchip_rx_buf) {
		ret = -EINVAL;
		dev_err(pdev->dev, "Invalid on-chip memory configuration\n");
		goto put_gadget;
	}

	if (!(pdev->eps_supported & ~0x00010001)) {
		ret = -EINVAL;
		dev_err(pdev->dev, "No hardware endpoints available\n");
		goto put_gadget;
	}

	max_speed = usb_get_maximum_speed(pdev->dev);

	switch (max_speed) {
	case USB_SPEED_FULL:
	case USB_SPEED_HIGH:
		break;
	default:
		dev_err(pdev->dev, "invalid maximum_speed parameter %d\n",
			max_speed);
		fallthrough;
	case USB_SPEED_UNKNOWN:
		max_speed = USB_SPEED_HIGH;
		break;
	}

	pdev->gadget.max_speed = max_speed;
	pdev->gadget.speed = USB_SPEED_UNKNOWN;
	pdev->gadget.ops = &cdns2_gadget_ops;
	pdev->gadget.name = "usbhs-gadget";
	pdev->gadget.quirk_avoids_skb_reserve = 1;
	pdev->gadget.irq = pdev->irq;

	spin_lock_init(&pdev->lock);
	INIT_WORK(&pdev->pending_status_wq, cdns2_pending_setup_status_handler);

	/* Initialize endpoint container. */
	INIT_LIST_HEAD(&pdev->gadget.ep_list);
	pdev->eps_dma_pool = dma_pool_create("cdns2_eps_dma_pool", pdev->dev,
					     TR_SEG_SIZE, 8, 0);
	if (!pdev->eps_dma_pool) {
		dev_err(pdev->dev, "Failed to create TRB dma pool\n");
		ret = -ENOMEM;
		goto put_gadget;
	}

	ret = cdns2_init_eps(pdev);
	if (ret) {
		dev_err(pdev->dev, "Failed to create endpoints\n");
		goto destroy_dma_pool;
	}

	pdev->gadget.sg_supported = 1;

	pdev->zlp_buf = kzalloc(CDNS2_EP_ZLP_BUF_SIZE, GFP_KERNEL);
	if (!pdev->zlp_buf) {
		ret = -ENOMEM;
		goto destroy_dma_pool;
	}

	/* Allocate memory for setup packet buffer. */
	buf = dma_alloc_coherent(pdev->dev, 8, &pdev->ep0_preq.request.dma,
				 GFP_DMA);
	pdev->ep0_preq.request.buf = buf;

	if (!pdev->ep0_preq.request.buf) {
		ret = -ENOMEM;
		goto free_zlp_buf;
	}

	/* Add USB gadget device. */
	ret = usb_add_gadget(&pdev->gadget);
	if (ret < 0) {
		dev_err(pdev->dev, "Failed to add gadget\n");
		goto free_ep0_buf;
	}

	return 0;

free_ep0_buf:
	dma_free_coherent(pdev->dev, 8, pdev->ep0_preq.request.buf,
			  pdev->ep0_preq.request.dma);
free_zlp_buf:
	kfree(pdev->zlp_buf);
destroy_dma_pool:
	dma_pool_destroy(pdev->eps_dma_pool);
put_gadget:
	usb_put_gadget(&pdev->gadget);

	return ret;
}

int cdns2_gadget_suspend(struct cdns2_device *pdev)
{
	unsigned long flags;

	cdns2_disconnect_gadget(pdev);

	spin_lock_irqsave(&pdev->lock, flags);
	pdev->gadget.speed = USB_SPEED_UNKNOWN;

	trace_cdns2_device_state("notattached");
	usb_gadget_set_state(&pdev->gadget, USB_STATE_NOTATTACHED);
	cdns2_enable_l1(pdev, 0);

	/* Disable interrupt for device. */
	writeb(0, &pdev->interrupt_regs->usbien);
	writel(0, &pdev->adma_regs->ep_ien);
	spin_unlock_irqrestore(&pdev->lock, flags);

	return 0;
}

int cdns2_gadget_resume(struct cdns2_device *pdev, bool hibernated)
{
	unsigned long flags;

	spin_lock_irqsave(&pdev->lock, flags);

	if (!pdev->gadget_driver) {
		spin_unlock_irqrestore(&pdev->lock, flags);
		return 0;
	}

	cdns2_gadget_config(pdev);

	if (hibernated)
		clear_reg_bit_8(&pdev->usb_regs->usbcs, USBCS_DISCON);

	spin_unlock_irqrestore(&pdev->lock, flags);

	return 0;
}

void cdns2_gadget_remove(struct cdns2_device *pdev)
{
	pm_runtime_mark_last_busy(pdev->dev);
	pm_runtime_put_autosuspend(pdev->dev);

	usb_del_gadget(&pdev->gadget);
	cdns2_free_all_eps(pdev);

	dma_pool_destroy(pdev->eps_dma_pool);
	kfree(pdev->zlp_buf);
	usb_put_gadget(&pdev->gadget);
}

int cdns2_gadget_init(struct cdns2_device *pdev)
{
	int ret;

	/* Ensure 32-bit DMA Mask. */
	ret = dma_set_mask_and_coherent(pdev->dev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(pdev->dev, "Failed to set dma mask: %d\n", ret);
		return ret;
	}

	pm_runtime_get_sync(pdev->dev);

	cdsn2_isoc_burst_opt(pdev);

	ret = cdns2_gadget_start(pdev);
	if (ret) {
		pm_runtime_put_sync(pdev->dev);
		return ret;
	}

	/*
	 * Because interrupt line can be shared with other components in
	 * driver it can't use IRQF_ONESHOT flag here.
	 */
	ret = devm_request_threaded_irq(pdev->dev, pdev->irq,
					cdns2_usb_irq_handler,
					cdns2_thread_irq_handler,
					IRQF_SHARED,
					dev_name(pdev->dev),
					pdev);
	if (ret)
		goto err0;

	return 0;

err0:
	cdns2_gadget_remove(pdev);

	return ret;
}
