// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for the NXP ISP1760 chip
 *
 * However, the code might contain some bugs. What doesn't work for sure is:
 * - ISO
 * - OTG
 e The interrupt line is configured as active low, level.
 *
 * (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
 *
 * (c) 2011 Arvid Brodin <arvid.brodin@enea.com>
 *
 * Copyright 2021 Linaro, Rui Miguel Silva <rui.silva@linaro.org>
 *
 */
#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/mm.h>
#include <linux/timer.h>
#include <asm/unaligned.h>
#include <asm/cacheflush.h>

#include "isp1760-core.h"
#include "isp1760-hcd.h"
#include "isp1760-regs.h"

static struct kmem_cache *qtd_cachep;
static struct kmem_cache *qh_cachep;
static struct kmem_cache *urb_listitem_cachep;

typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh,
		struct isp1760_qtd *qtd);

static inline struct isp1760_hcd *hcd_to_priv(struct usb_hcd *hcd)
{
	return *(struct isp1760_hcd **)hcd->hcd_priv;
}

#define dw_to_le32(x)	(cpu_to_le32((__force u32)x))
#define le32_to_dw(x)	((__force __dw)(le32_to_cpu(x)))

/* urb state*/
#define DELETE_URB		(0x0008)
#define NO_TRANSFER_ACTIVE	(0xffffffff)

/* Philips Proprietary Transfer Descriptor (PTD) */
typedef __u32 __bitwise __dw;
struct ptd {
	__dw dw0;
	__dw dw1;
	__dw dw2;
	__dw dw3;
	__dw dw4;
	__dw dw5;
	__dw dw6;
	__dw dw7;
};

struct ptd_le32 {
	__le32 dw0;
	__le32 dw1;
	__le32 dw2;
	__le32 dw3;
	__le32 dw4;
	__le32 dw5;
	__le32 dw6;
	__le32 dw7;
};

#define PTD_OFFSET		0x0400
#define ISO_PTD_OFFSET		0x0400
#define INT_PTD_OFFSET		0x0800
#define ATL_PTD_OFFSET		0x0c00
#define PAYLOAD_OFFSET		0x1000

#define ISP_BANK_0		0x00
#define ISP_BANK_1		0x01
#define ISP_BANK_2		0x02
#define ISP_BANK_3		0x03

#define TO_DW(x)	((__force __dw)x)
#define TO_U32(x)	((__force u32)x)

 /* ATL */
 /* DW0 */
#define DW0_VALID_BIT			TO_DW(1)
#define FROM_DW0_VALID(x)		(TO_U32(x) & 0x01)
#define TO_DW0_LENGTH(x)		TO_DW((((u32)x) << 3))
#define TO_DW0_MAXPACKET(x)		TO_DW((((u32)x) << 18))
#define TO_DW0_MULTI(x)			TO_DW((((u32)x) << 29))
#define TO_DW0_ENDPOINT(x)		TO_DW((((u32)x) << 31))
/* DW1 */
#define TO_DW1_DEVICE_ADDR(x)		TO_DW((((u32)x) << 3))
#define TO_DW1_PID_TOKEN(x)		TO_DW((((u32)x) << 10))
#define DW1_TRANS_BULK			TO_DW(((u32)2 << 12))
#define DW1_TRANS_INT			TO_DW(((u32)3 << 12))
#define DW1_TRANS_SPLIT			TO_DW(((u32)1 << 14))
#define DW1_SE_USB_LOSPEED		TO_DW(((u32)2 << 16))
#define TO_DW1_PORT_NUM(x)		TO_DW((((u32)x) << 18))
#define TO_DW1_HUB_NUM(x)		TO_DW((((u32)x) << 25))
/* DW2 */
#define TO_DW2_DATA_START_ADDR(x)	TO_DW((((u32)x) << 8))
#define TO_DW2_RL(x)			TO_DW(((x) << 25))
#define FROM_DW2_RL(x)			((TO_U32(x) >> 25) & 0xf)
/* DW3 */
#define FROM_DW3_NRBYTESTRANSFERRED(x)		TO_U32((x) & 0x3fff)
#define FROM_DW3_SCS_NRBYTESTRANSFERRED(x)	TO_U32((x) & 0x07ff)
#define TO_DW3_NAKCOUNT(x)		TO_DW(((x) << 19))
#define FROM_DW3_NAKCOUNT(x)		((TO_U32(x) >> 19) & 0xf)
#define TO_DW3_CERR(x)			TO_DW(((x) << 23))
#define FROM_DW3_CERR(x)		((TO_U32(x) >> 23) & 0x3)
#define TO_DW3_DATA_TOGGLE(x)		TO_DW(((x) << 25))
#define FROM_DW3_DATA_TOGGLE(x)		((TO_U32(x) >> 25) & 0x1)
#define TO_DW3_PING(x)			TO_DW(((x) << 26))
#define FROM_DW3_PING(x)		((TO_U32(x) >> 26) & 0x1)
#define DW3_ERROR_BIT			TO_DW((1 << 28))
#define DW3_BABBLE_BIT			TO_DW((1 << 29))
#define DW3_HALT_BIT			TO_DW((1 << 30))
#define DW3_ACTIVE_BIT			TO_DW((1 << 31))
#define FROM_DW3_ACTIVE(x)		((TO_U32(x) >> 31) & 0x01)

#define INT_UNDERRUN			(1 << 2)
#define INT_BABBLE			(1 << 1)
#define INT_EXACT			(1 << 0)

#define SETUP_PID	(2)
#define IN_PID		(1)
#define OUT_PID		(0)

/* Errata 1 */
#define RL_COUNTER	(0)
#define NAK_COUNTER	(0)
#define ERR_COUNTER	(3)

struct isp1760_qtd {
	u8 packet_type;
	void *data_buffer;
	u32 payload_addr;

	/* the rest is HCD-private */
	struct list_head qtd_list;
	struct urb *urb;
	size_t length;
	size_t actual_length;

	/* QTD_ENQUEUED:	waiting for transfer (inactive) */
	/* QTD_PAYLOAD_ALLOC:	chip mem has been allocated for payload */
	/* QTD_XFER_STARTED:	valid ptd has been written to isp176x - only
				interrupt handler may touch this qtd! */
	/* QTD_XFER_COMPLETE:	payload has been transferred successfully */
	/* QTD_RETIRE:		transfer error/abort qtd */
#define QTD_ENQUEUED		0
#define QTD_PAYLOAD_ALLOC	1
#define QTD_XFER_STARTED	2
#define QTD_XFER_COMPLETE	3
#define QTD_RETIRE		4
	u32 status;
};

/* Queue head, one for each active endpoint */
struct isp1760_qh {
	struct list_head qh_list;
	struct list_head qtd_list;
	u32 toggle;
	u32 ping;
	int slot;
	int tt_buffer_dirty;	/* See USB2.0 spec section 11.17.5 */
};

struct urb_listitem {
	struct list_head urb_list;
	struct urb *urb;
};

static const u32 isp1763_hc_portsc1_fields[] = {
	[PORT_OWNER]		= BIT(13),
	[PORT_POWER]		= BIT(12),
	[PORT_LSTATUS]		= BIT(10),
	[PORT_RESET]		= BIT(8),
	[PORT_SUSPEND]		= BIT(7),
	[PORT_RESUME]		= BIT(6),
	[PORT_PE]		= BIT(2),
	[PORT_CSC]		= BIT(1),
	[PORT_CONNECT]		= BIT(0),
};

/*
 * Access functions for isp176x registers regmap fields
 */
static u32 isp1760_hcd_read(struct usb_hcd *hcd, u32 field)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	return isp1760_field_read(priv->fields, field);
}

/*
 * We need, in isp1763, to write directly the values to the portsc1
 * register so it will make the other values to trigger.
 */
static void isp1760_hcd_portsc1_set_clear(struct isp1760_hcd *priv, u32 field,
					  u32 val)
{
	u32 bit = isp1763_hc_portsc1_fields[field];
	u32 port_status = readl(priv->base + ISP1763_HC_PORTSC1);

	if (val)
		writel(port_status | bit, priv->base + ISP1763_HC_PORTSC1);
	else
		writel(port_status & ~bit, priv->base + ISP1763_HC_PORTSC1);
}

static void isp1760_hcd_write(struct usb_hcd *hcd, u32 field, u32 val)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	if (unlikely(priv->is_isp1763 &&
		     (field >= PORT_OWNER && field <= PORT_CONNECT)))
		return isp1760_hcd_portsc1_set_clear(priv, field, val);

	isp1760_field_write(priv->fields, field, val);
}

static void isp1760_hcd_set(struct usb_hcd *hcd, u32 field)
{
	isp1760_hcd_write(hcd, field, 0xFFFFFFFF);
}

static void isp1760_hcd_clear(struct usb_hcd *hcd, u32 field)
{
	isp1760_hcd_write(hcd, field, 0);
}

static int isp1760_hcd_set_and_wait(struct usb_hcd *hcd, u32 field,
				    u32 timeout_us)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	u32 val;

	isp1760_hcd_set(hcd, field);

	return regmap_field_read_poll_timeout(priv->fields[field], val,
					      val, 10, timeout_us);
}

static int isp1760_hcd_set_and_wait_swap(struct usb_hcd *hcd, u32 field,
					 u32 timeout_us)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	u32 val;

	isp1760_hcd_set(hcd, field);

	return regmap_field_read_poll_timeout(priv->fields[field], val,
					      !val, 10, timeout_us);
}

static int isp1760_hcd_clear_and_wait(struct usb_hcd *hcd, u32 field,
				      u32 timeout_us)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	u32 val;

	isp1760_hcd_clear(hcd, field);

	return regmap_field_read_poll_timeout(priv->fields[field], val,
					      !val, 10, timeout_us);
}

static bool isp1760_hcd_is_set(struct usb_hcd *hcd, u32 field)
{
	return !!isp1760_hcd_read(hcd, field);
}

static bool isp1760_hcd_ppc_is_set(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	if (priv->is_isp1763)
		return true;

	return isp1760_hcd_is_set(hcd, HCS_PPC);
}

static u32 isp1760_hcd_n_ports(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	if (priv->is_isp1763)
		return 1;

	return isp1760_hcd_read(hcd, HCS_N_PORTS);
}

/*
 * Access functions for isp176x memory (offset >= 0x0400).
 *
 * bank_reads8() reads memory locations prefetched by an earlier write to
 * HC_MEMORY_REG (see isp176x datasheet). Unless you want to do fancy multi-
 * bank optimizations, you should use the more generic mem_read() below.
 *
 * For access to ptd memory, use the specialized ptd_read() and ptd_write()
 * below.
 *
 * These functions copy via MMIO data to/from the device. memcpy_{to|from}io()
 * doesn't quite work because some people have to enforce 32-bit access
 */
static void bank_reads8(void __iomem *src_base, u32 src_offset, u32 bank_addr,
							__u32 *dst, u32 bytes)
{
	__u32 __iomem *src;
	u32 val;
	__u8 *src_byteptr;
	__u8 *dst_byteptr;

	src = src_base + (bank_addr | src_offset);

	if (src_offset < PAYLOAD_OFFSET) {
		while (bytes >= 4) {
			*dst = readl_relaxed(src);
			bytes -= 4;
			src++;
			dst++;
		}
	} else {
		while (bytes >= 4) {
			*dst = __raw_readl(src);
			bytes -= 4;
			src++;
			dst++;
		}
	}

	if (!bytes)
		return;

	/* in case we have 3, 2 or 1 by left. The dst buffer may not be fully
	 * allocated.
	 */
	if (src_offset < PAYLOAD_OFFSET)
		val = readl_relaxed(src);
	else
		val = __raw_readl(src);

	dst_byteptr = (void *) dst;
	src_byteptr = (void *) &val;
	while (bytes > 0) {
		*dst_byteptr = *src_byteptr;
		dst_byteptr++;
		src_byteptr++;
		bytes--;
	}
}

static void isp1760_mem_read(struct usb_hcd *hcd, u32 src_offset, void *dst,
			     u32 bytes)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	isp1760_hcd_write(hcd, MEM_BANK_SEL, ISP_BANK_0);
	isp1760_hcd_write(hcd, MEM_START_ADDR, src_offset);
	ndelay(100);

	bank_reads8(priv->base, src_offset, ISP_BANK_0, dst, bytes);
}

/*
 * ISP1763 does not have the banks direct host controller memory access,
 * needs to use the HC_DATA register. Add data read/write according to this,
 * and also adjust 16bit access.
 */
static void isp1763_mem_read(struct usb_hcd *hcd, u16 srcaddr,
			     u16 *dstptr, u32 bytes)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	/* Write the starting device address to the hcd memory register */
	isp1760_reg_write(priv->regs, ISP1763_HC_MEMORY, srcaddr);
	ndelay(100); /* Delay between consecutive access */

	/* As long there are at least 16-bit to read ... */
	while (bytes >= 2) {
		*dstptr = __raw_readw(priv->base + ISP1763_HC_DATA);
		bytes -= 2;
		dstptr++;
	}

	/* If there are no more bytes to read, return */
	if (bytes <= 0)
		return;

	*((u8 *)dstptr) = (u8)(readw(priv->base + ISP1763_HC_DATA) & 0xFF);
}

static void mem_read(struct usb_hcd *hcd, u32 src_offset, __u32 *dst,
		     u32 bytes)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	if (!priv->is_isp1763)
		return isp1760_mem_read(hcd, src_offset, (u16 *)dst, bytes);

	isp1763_mem_read(hcd, (u16)src_offset, (u16 *)dst, bytes);
}

static void isp1760_mem_write(void __iomem *dst_base, u32 dst_offset,
			      __u32 const *src, u32 bytes)
{
	__u32 __iomem *dst;

	dst = dst_base + dst_offset;

	if (dst_offset < PAYLOAD_OFFSET) {
		while (bytes >= 4) {
			writel_relaxed(*src, dst);
			bytes -= 4;
			src++;
			dst++;
		}
	} else {
		while (bytes >= 4) {
			__raw_writel(*src, dst);
			bytes -= 4;
			src++;
			dst++;
		}
	}

	if (!bytes)
		return;
	/* in case we have 3, 2 or 1 bytes left. The buffer is allocated and the
	 * extra bytes should not be read by the HW.
	 */

	if (dst_offset < PAYLOAD_OFFSET)
		writel_relaxed(*src, dst);
	else
		__raw_writel(*src, dst);
}

static void isp1763_mem_write(struct usb_hcd *hcd, u16 dstaddr, u16 *src,
			      u32 bytes)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	/* Write the starting device address to the hcd memory register */
	isp1760_reg_write(priv->regs, ISP1763_HC_MEMORY, dstaddr);
	ndelay(100); /* Delay between consecutive access */

	while (bytes >= 2) {
		/* Get and write the data; then adjust the data ptr and len */
		__raw_writew(*src, priv->base + ISP1763_HC_DATA);
		bytes -= 2;
		src++;
	}

	/* If there are no more bytes to process, return */
	if (bytes <= 0)
		return;

	/*
	 * The only way to get here is if there is a single byte left,
	 * get it and write it to the data reg;
	 */
	writew(*((u8 *)src), priv->base + ISP1763_HC_DATA);
}

static void mem_write(struct usb_hcd *hcd, u32 dst_offset, __u32 *src,
		      u32 bytes)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	if (!priv->is_isp1763)
		return isp1760_mem_write(priv->base, dst_offset, src, bytes);

	isp1763_mem_write(hcd, dst_offset, (u16 *)src, bytes);
}

/*
 * Read and write ptds. 'ptd_offset' should be one of ISO_PTD_OFFSET,
 * INT_PTD_OFFSET, and ATL_PTD_OFFSET. 'slot' should be less than 32.
 */
static void isp1760_ptd_read(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
			     struct ptd *ptd)
{
	u16 src_offset = ptd_offset + slot * sizeof(*ptd);
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	isp1760_hcd_write(hcd, MEM_BANK_SEL, ISP_BANK_0);
	isp1760_hcd_write(hcd, MEM_START_ADDR, src_offset);
	ndelay(90);

	bank_reads8(priv->base, src_offset, ISP_BANK_0, (void *)ptd,
		    sizeof(*ptd));
}

static void isp1763_ptd_read(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
			     struct ptd *ptd)
{
	u16 src_offset = ptd_offset + slot * sizeof(*ptd);
	struct ptd_le32 le32_ptd;

	isp1763_mem_read(hcd, src_offset, (u16 *)&le32_ptd, sizeof(le32_ptd));
	/* Normalize the data obtained */
	ptd->dw0 = le32_to_dw(le32_ptd.dw0);
	ptd->dw1 = le32_to_dw(le32_ptd.dw1);
	ptd->dw2 = le32_to_dw(le32_ptd.dw2);
	ptd->dw3 = le32_to_dw(le32_ptd.dw3);
	ptd->dw4 = le32_to_dw(le32_ptd.dw4);
	ptd->dw5 = le32_to_dw(le32_ptd.dw5);
	ptd->dw6 = le32_to_dw(le32_ptd.dw6);
	ptd->dw7 = le32_to_dw(le32_ptd.dw7);
}

static void ptd_read(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
		     struct ptd *ptd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	if (!priv->is_isp1763)
		return isp1760_ptd_read(hcd, ptd_offset, slot, ptd);

	isp1763_ptd_read(hcd, ptd_offset, slot, ptd);
}

static void isp1763_ptd_write(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
			      struct ptd *cpu_ptd)
{
	u16 dst_offset = ptd_offset + slot * sizeof(*cpu_ptd);
	struct ptd_le32 ptd;

	ptd.dw0 = dw_to_le32(cpu_ptd->dw0);
	ptd.dw1 = dw_to_le32(cpu_ptd->dw1);
	ptd.dw2 = dw_to_le32(cpu_ptd->dw2);
	ptd.dw3 = dw_to_le32(cpu_ptd->dw3);
	ptd.dw4 = dw_to_le32(cpu_ptd->dw4);
	ptd.dw5 = dw_to_le32(cpu_ptd->dw5);
	ptd.dw6 = dw_to_le32(cpu_ptd->dw6);
	ptd.dw7 = dw_to_le32(cpu_ptd->dw7);

	isp1763_mem_write(hcd, dst_offset,  (u16 *)&ptd.dw0,
			  8 * sizeof(ptd.dw0));
}

static void isp1760_ptd_write(void __iomem *base, u32 ptd_offset, u32 slot,
			      struct ptd *ptd)
{
	u32 dst_offset = ptd_offset + slot * sizeof(*ptd);

	/*
	 * Make sure dw0 gets written last (after other dw's and after payload)
	 *  since it contains the enable bit
	 */
	isp1760_mem_write(base, dst_offset + sizeof(ptd->dw0),
			  (__force u32 *)&ptd->dw1, 7 * sizeof(ptd->dw1));
	wmb();
	isp1760_mem_write(base, dst_offset, (__force u32 *)&ptd->dw0,
			  sizeof(ptd->dw0));
}

static void ptd_write(struct usb_hcd *hcd, u32 ptd_offset, u32 slot,
		      struct ptd *ptd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	if (!priv->is_isp1763)
		return isp1760_ptd_write(priv->base, ptd_offset, slot, ptd);

	isp1763_ptd_write(hcd, ptd_offset, slot, ptd);
}

/* memory management of the 60kb on the chip from 0x1000 to 0xffff */
static void init_memory(struct isp1760_hcd *priv)
{
	const struct isp1760_memory_layout *mem = priv->memory_layout;
	int i, j, curr;
	u32 payload_addr;

	payload_addr = PAYLOAD_OFFSET;

	for (i = 0, curr = 0; i < ARRAY_SIZE(mem->blocks); i++) {
		for (j = 0; j < mem->blocks[i]; j++, curr++) {
			priv->memory_pool[curr + j].start = payload_addr;
			priv->memory_pool[curr + j].size = mem->blocks_size[i];
			priv->memory_pool[curr + j].free = 1;
			payload_addr += priv->memory_pool[curr + j].size;
		}
	}

	WARN_ON(payload_addr - priv->memory_pool[0].start >
		mem->payload_area_size);
}

static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	const struct isp1760_memory_layout *mem = priv->memory_layout;
	int i;

	WARN_ON(qtd->payload_addr);

	if (!qtd->length)
		return;

	for (i = 0; i < mem->payload_blocks; i++) {
		if (priv->memory_pool[i].size >= qtd->length &&
				priv->memory_pool[i].free) {
			priv->memory_pool[i].free = 0;
			qtd->payload_addr = priv->memory_pool[i].start;
			return;
		}
	}
}

static void free_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	const struct isp1760_memory_layout *mem = priv->memory_layout;
	int i;

	if (!qtd->payload_addr)
		return;

	for (i = 0; i < mem->payload_blocks; i++) {
		if (priv->memory_pool[i].start == qtd->payload_addr) {
			WARN_ON(priv->memory_pool[i].free);
			priv->memory_pool[i].free = 1;
			qtd->payload_addr = 0;
			return;
		}
	}

	dev_err(hcd->self.controller, "%s: Invalid pointer: %08x\n",
						__func__, qtd->payload_addr);
	WARN_ON(1);
	qtd->payload_addr = 0;
}

/* reset a non-running (STS_HALT == 1) controller */
static int ehci_reset(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	hcd->state = HC_STATE_HALT;
	priv->next_statechange = jiffies;

	return isp1760_hcd_set_and_wait_swap(hcd, CMD_RESET, 250 * 1000);
}

static struct isp1760_qh *qh_alloc(gfp_t flags)
{
	struct isp1760_qh *qh;

	qh = kmem_cache_zalloc(qh_cachep, flags);
	if (!qh)
		return NULL;

	INIT_LIST_HEAD(&qh->qh_list);
	INIT_LIST_HEAD(&qh->qtd_list);
	qh->slot = -1;

	return qh;
}

static void qh_free(struct isp1760_qh *qh)
{
	WARN_ON(!list_empty(&qh->qtd_list));
	WARN_ON(qh->slot > -1);
	kmem_cache_free(qh_cachep, qh);
}

/* one-time init, only for memory state */
static int priv_init(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	u32 isoc_cache;
	u32 isoc_thres;
	int i;

	spin_lock_init(&priv->lock);

	for (i = 0; i < QH_END; i++)
		INIT_LIST_HEAD(&priv->qh_list[i]);

	/*
	 * hw default: 1K periodic list heads, one per frame.
	 * periodic_size can shrink by USBCMD update if hcc_params allows.
	 */
	priv->periodic_size = DEFAULT_I_TDPS;

	if (priv->is_isp1763) {
		priv->i_thresh = 2;
		return 0;
	}

	/* controllers may cache some of the periodic schedule ... */
	isoc_cache = isp1760_hcd_read(hcd, HCC_ISOC_CACHE);
	isoc_thres = isp1760_hcd_read(hcd, HCC_ISOC_THRES);

	/* full frame cache */
	if (isoc_cache)
		priv->i_thresh = 8;
	else /* N microframes cached */
		priv->i_thresh = 2 + isoc_thres;

	return 0;
}

static int isp1760_hc_setup(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	u32 atx_reset;
	int result;
	u32 scratch;
	u32 pattern;

	if (priv->is_isp1763)
		pattern = 0xcafe;
	else
		pattern = 0xdeadcafe;

	isp1760_hcd_write(hcd, HC_SCRATCH, pattern);

	/* Change bus pattern */
	scratch = isp1760_hcd_read(hcd, HC_CHIP_ID_HIGH);
	dev_err(hcd->self.controller, "Scratch test 0x%08x\n", scratch);
	scratch = isp1760_hcd_read(hcd, HC_SCRATCH);
	if (scratch != pattern) {
		dev_err(hcd->self.controller, "Scratch test failed. 0x%08x\n", scratch);
		return -ENODEV;
	}

	/*
	 * The RESET_HC bit in the SW_RESET register is supposed to reset the
	 * host controller without touching the CPU interface registers, but at
	 * least on the ISP1761 it seems to behave as the RESET_ALL bit and
	 * reset the whole device. We thus can't use it here, so let's reset
	 * the host controller through the EHCI USB Command register. The device
	 * has been reset in core code anyway, so this shouldn't matter.
	 */
	isp1760_hcd_clear(hcd, ISO_BUF_FILL);
	isp1760_hcd_clear(hcd, INT_BUF_FILL);
	isp1760_hcd_clear(hcd, ATL_BUF_FILL);

	isp1760_hcd_set(hcd, HC_ATL_PTD_SKIPMAP);
	isp1760_hcd_set(hcd, HC_INT_PTD_SKIPMAP);
	isp1760_hcd_set(hcd, HC_ISO_PTD_SKIPMAP);

	result = ehci_reset(hcd);
	if (result)
		return result;

	/* Step 11 passed */

	/* ATL reset */
	if (priv->is_isp1763)
		atx_reset = SW_RESET_RESET_ATX;
	else
		atx_reset = ALL_ATX_RESET;

	isp1760_hcd_set(hcd, atx_reset);
	mdelay(10);
	isp1760_hcd_clear(hcd, atx_reset);

	if (priv->is_isp1763) {
		isp1760_hcd_set(hcd, HW_OTG_DISABLE);
		isp1760_hcd_set(hcd, HW_SW_SEL_HC_DC_CLEAR);
		isp1760_hcd_set(hcd, HW_HC_2_DIS_CLEAR);
		mdelay(10);

		isp1760_hcd_set(hcd, HW_INTF_LOCK);
	}

	isp1760_hcd_set(hcd, HC_INT_IRQ_ENABLE);
	isp1760_hcd_set(hcd, HC_ATL_IRQ_ENABLE);

	return priv_init(hcd);
}

static u32 base_to_chip(u32 base)
{
	return ((base - 0x400) >> 3);
}

static int last_qtd_of_urb(struct isp1760_qtd *qtd, struct isp1760_qh *qh)
{
	struct urb *urb;

	if (list_is_last(&qtd->qtd_list, &qh->qtd_list))
		return 1;

	urb = qtd->urb;
	qtd = list_entry(qtd->qtd_list.next, typeof(*qtd), qtd_list);
	return (qtd->urb != urb);
}

/* magic numbers that can affect system performance */
#define	EHCI_TUNE_CERR		3	/* 0-3 qtd retries; 0 == don't stop */
#define	EHCI_TUNE_RL_HS		4	/* nak throttle; see 4.9 */
#define	EHCI_TUNE_RL_TT		0
#define	EHCI_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */
#define	EHCI_TUNE_MULT_TT	1
#define	EHCI_TUNE_FLS		2	/* (small) 256 frame schedule */

static void create_ptd_atl(struct isp1760_qh *qh,
			struct isp1760_qtd *qtd, struct ptd *ptd)
{
	u32 maxpacket;
	u32 multi;
	u32 rl = RL_COUNTER;
	u32 nak = NAK_COUNTER;

	memset(ptd, 0, sizeof(*ptd));

	/* according to 3.6.2, max packet len can not be > 0x400 */
	maxpacket = usb_maxpacket(qtd->urb->dev, qtd->urb->pipe,
						usb_pipeout(qtd->urb->pipe));
	multi =  1 + ((maxpacket >> 11) & 0x3);
	maxpacket &= 0x7ff;

	/* DW0 */
	ptd->dw0 = DW0_VALID_BIT;
	ptd->dw0 |= TO_DW0_LENGTH(qtd->length);
	ptd->dw0 |= TO_DW0_MAXPACKET(maxpacket);
	ptd->dw0 |= TO_DW0_ENDPOINT(usb_pipeendpoint(qtd->urb->pipe));

	/* DW1 */
	ptd->dw1 = TO_DW((usb_pipeendpoint(qtd->urb->pipe) >> 1));
	ptd->dw1 |= TO_DW1_DEVICE_ADDR(usb_pipedevice(qtd->urb->pipe));
	ptd->dw1 |= TO_DW1_PID_TOKEN(qtd->packet_type);

	if (usb_pipebulk(qtd->urb->pipe))
		ptd->dw1 |= DW1_TRANS_BULK;
	else if  (usb_pipeint(qtd->urb->pipe))
		ptd->dw1 |= DW1_TRANS_INT;

	if (qtd->urb->dev->speed != USB_SPEED_HIGH) {
		/* split transaction */

		ptd->dw1 |= DW1_TRANS_SPLIT;
		if (qtd->urb->dev->speed == USB_SPEED_LOW)
			ptd->dw1 |= DW1_SE_USB_LOSPEED;

		ptd->dw1 |= TO_DW1_PORT_NUM(qtd->urb->dev->ttport);
		ptd->dw1 |= TO_DW1_HUB_NUM(qtd->urb->dev->tt->hub->devnum);

		/* SE bit for Split INT transfers */
		if (usb_pipeint(qtd->urb->pipe) &&
				(qtd->urb->dev->speed == USB_SPEED_LOW))
			ptd->dw1 |= DW1_SE_USB_LOSPEED;

		rl = 0;
		nak = 0;
	} else {
		ptd->dw0 |= TO_DW0_MULTI(multi);
		if (usb_pipecontrol(qtd->urb->pipe) ||
						usb_pipebulk(qtd->urb->pipe))
			ptd->dw3 |= TO_DW3_PING(qh->ping);
	}
	/* DW2 */
	ptd->dw2 = 0;
	ptd->dw2 |= TO_DW2_DATA_START_ADDR(base_to_chip(qtd->payload_addr));
	ptd->dw2 |= TO_DW2_RL(rl);

	/* DW3 */
	ptd->dw3 |= TO_DW3_NAKCOUNT(nak);
	ptd->dw3 |= TO_DW3_DATA_TOGGLE(qh->toggle);
	if (usb_pipecontrol(qtd->urb->pipe)) {
		if (qtd->data_buffer == qtd->urb->setup_packet)
			ptd->dw3 &= ~TO_DW3_DATA_TOGGLE(1);
		else if (last_qtd_of_urb(qtd, qh))
			ptd->dw3 |= TO_DW3_DATA_TOGGLE(1);
	}

	ptd->dw3 |= DW3_ACTIVE_BIT;
	/* Cerr */
	ptd->dw3 |= TO_DW3_CERR(ERR_COUNTER);
}

static void transform_add_int(struct isp1760_qh *qh,
			struct isp1760_qtd *qtd, struct ptd *ptd)
{
	u32 usof;
	u32 period;

	/*
	 * Most of this is guessing. ISP1761 datasheet is quite unclear, and
	 * the algorithm from the original Philips driver code, which was
	 * pretty much used in this driver before as well, is quite horrendous
	 * and, i believe, incorrect. The code below follows the datasheet and
	 * USB2.0 spec as far as I can tell, and plug/unplug seems to be much
	 * more reliable this way (fingers crossed...).
	 */

	if (qtd->urb->dev->speed == USB_SPEED_HIGH) {
		/* urb->interval is in units of microframes (1/8 ms) */
		period = qtd->urb->interval >> 3;

		if (qtd->urb->interval > 4)
			usof = 0x01; /* One bit set =>
						interval 1 ms * uFrame-match */
		else if (qtd->urb->interval > 2)
			usof = 0x22; /* Two bits set => interval 1/2 ms */
		else if (qtd->urb->interval > 1)
			usof = 0x55; /* Four bits set => interval 1/4 ms */
		else
			usof = 0xff; /* All bits set => interval 1/8 ms */
	} else {
		/* urb->interval is in units of frames (1 ms) */
		period = qtd->urb->interval;
		usof = 0x0f;		/* Execute Start Split on any of the
					   four first uFrames */

		/*
		 * First 8 bits in dw5 is uSCS and "specifies which uSOF the
		 * complete split needs to be sent. Valid only for IN." Also,
		 * "All bits can be set to one for every transfer." (p 82,
		 * ISP1761 data sheet.) 0x1c is from Philips driver. Where did
		 * that number come from? 0xff seems to work fine...
		 */
		/* ptd->dw5 = 0x1c; */
		ptd->dw5 = TO_DW(0xff); /* Execute Complete Split on any uFrame */
	}

	period = period >> 1;/* Ensure equal or shorter period than requested */
	period &= 0xf8; /* Mask off too large values and lowest unused 3 bits */

	ptd->dw2 |= TO_DW(period);
	ptd->dw4 = TO_DW(usof);
}

static void create_ptd_int(struct isp1760_qh *qh,
			struct isp1760_qtd *qtd, struct ptd *ptd)
{
	create_ptd_atl(qh, qtd, ptd);
	transform_add_int(qh, qtd, ptd);
}

static void isp1760_urb_done(struct usb_hcd *hcd, struct urb *urb)
__releases(priv->lock)
__acquires(priv->lock)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	if (!urb->unlinked) {
		if (urb->status == -EINPROGRESS)
			urb->status = 0;
	}

	if (usb_pipein(urb->pipe) && usb_pipetype(urb->pipe) != PIPE_CONTROL) {
		void *ptr;
		for (ptr = urb->transfer_buffer;
		     ptr < urb->transfer_buffer + urb->transfer_buffer_length;
		     ptr += PAGE_SIZE)
			flush_dcache_page(virt_to_page(ptr));
	}

	/* complete() can reenter this HCD */
	usb_hcd_unlink_urb_from_ep(hcd, urb);
	spin_unlock(&priv->lock);
	usb_hcd_giveback_urb(hcd, urb, urb->status);
	spin_lock(&priv->lock);
}

static struct isp1760_qtd *qtd_alloc(gfp_t flags, struct urb *urb,
								u8 packet_type)
{
	struct isp1760_qtd *qtd;

	qtd = kmem_cache_zalloc(qtd_cachep, flags);
	if (!qtd)
		return NULL;

	INIT_LIST_HEAD(&qtd->qtd_list);
	qtd->urb = urb;
	qtd->packet_type = packet_type;
	qtd->status = QTD_ENQUEUED;
	qtd->actual_length = 0;

	return qtd;
}

static void qtd_free(struct isp1760_qtd *qtd)
{
	WARN_ON(qtd->payload_addr);
	kmem_cache_free(qtd_cachep, qtd);
}

static void start_bus_transfer(struct usb_hcd *hcd, u32 ptd_offset, int slot,
				struct isp1760_slotinfo *slots,
				struct isp1760_qtd *qtd, struct isp1760_qh *qh,
				struct ptd *ptd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	const struct isp1760_memory_layout *mem = priv->memory_layout;
	int skip_map;

	WARN_ON((slot < 0) || (slot > mem->slot_num - 1));
	WARN_ON(qtd->length && !qtd->payload_addr);
	WARN_ON(slots[slot].qtd);
	WARN_ON(slots[slot].qh);
	WARN_ON(qtd->status != QTD_PAYLOAD_ALLOC);

	if (priv->is_isp1763)
		ndelay(100);

	/* Make sure done map has not triggered from some unlinked transfer */
	if (ptd_offset == ATL_PTD_OFFSET) {
		skip_map = isp1760_hcd_read(hcd, HC_ATL_PTD_SKIPMAP);
		isp1760_hcd_write(hcd, HC_ATL_PTD_SKIPMAP,
				  skip_map | (1 << slot));
		priv->atl_done_map |= isp1760_hcd_read(hcd, HC_ATL_PTD_DONEMAP);
		priv->atl_done_map &= ~(1 << slot);
	} else {
		skip_map = isp1760_hcd_read(hcd, HC_INT_PTD_SKIPMAP);
		isp1760_hcd_write(hcd, HC_INT_PTD_SKIPMAP,
				  skip_map | (1 << slot));
		priv->int_done_map |= isp1760_hcd_read(hcd, HC_INT_PTD_DONEMAP);
		priv->int_done_map &= ~(1 << slot);
	}

	skip_map &= ~(1 << slot);
	qh->slot = slot;
	qtd->status = QTD_XFER_STARTED;
	slots[slot].timestamp = jiffies;
	slots[slot].qtd = qtd;
	slots[slot].qh = qh;
	ptd_write(hcd, ptd_offset, slot, ptd);

	if (ptd_offset == ATL_PTD_OFFSET)
		isp1760_hcd_write(hcd, HC_ATL_PTD_SKIPMAP, skip_map);
	else
		isp1760_hcd_write(hcd, HC_INT_PTD_SKIPMAP, skip_map);
}

static int is_short_bulk(struct isp1760_qtd *qtd)
{
	return (usb_pipebulk(qtd->urb->pipe) &&
					(qtd->actual_length < qtd->length));
}

static void collect_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh,
						struct list_head *urb_list)
{
	struct isp1760_qtd *qtd, *qtd_next;
	struct urb_listitem *urb_listitem;
	int last_qtd;

	list_for_each_entry_safe(qtd, qtd_next, &qh->qtd_list, qtd_list) {
		if (qtd->status < QTD_XFER_COMPLETE)
			break;

		last_qtd = last_qtd_of_urb(qtd, qh);

		if ((!last_qtd) && (qtd->status == QTD_RETIRE))
			qtd_next->status = QTD_RETIRE;

		if (qtd->status == QTD_XFER_COMPLETE) {
			if (qtd->actual_length) {
				switch (qtd->packet_type) {
				case IN_PID:
					mem_read(hcd, qtd->payload_addr,
						 qtd->data_buffer,
						 qtd->actual_length);
					fallthrough;
				case OUT_PID:
					qtd->urb->actual_length +=
							qtd->actual_length;
					fallthrough;
				case SETUP_PID:
					break;
				}
			}

			if (is_short_bulk(qtd)) {
				if (qtd->urb->transfer_flags & URB_SHORT_NOT_OK)
					qtd->urb->status = -EREMOTEIO;
				if (!last_qtd)
					qtd_next->status = QTD_RETIRE;
			}
		}

		if (qtd->payload_addr)
			free_mem(hcd, qtd);

		if (last_qtd) {
			if ((qtd->status == QTD_RETIRE) &&
					(qtd->urb->status == -EINPROGRESS))
				qtd->urb->status = -EPIPE;
			/* Defer calling of urb_done() since it releases lock */
			urb_listitem = kmem_cache_zalloc(urb_listitem_cachep,
								GFP_ATOMIC);
			if (unlikely(!urb_listitem))
				break; /* Try again on next call */
			urb_listitem->urb = qtd->urb;
			list_add_tail(&urb_listitem->urb_list, urb_list);
		}

		list_del(&qtd->qtd_list);
		qtd_free(qtd);
	}
}

#define ENQUEUE_DEPTH	2
static void enqueue_qtds(struct usb_hcd *hcd, struct isp1760_qh *qh)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	const struct isp1760_memory_layout *mem = priv->memory_layout;
	int slot_num = mem->slot_num;
	int ptd_offset;
	struct isp1760_slotinfo *slots;
	int curr_slot, free_slot;
	int n;
	struct ptd ptd;
	struct isp1760_qtd *qtd;

	if (unlikely(list_empty(&qh->qtd_list))) {
		WARN_ON(1);
		return;
	}

	/* Make sure this endpoint's TT buffer is clean before queueing ptds */
	if (qh->tt_buffer_dirty)
		return;

	if (usb_pipeint(list_entry(qh->qtd_list.next, struct isp1760_qtd,
							qtd_list)->urb->pipe)) {
		ptd_offset = INT_PTD_OFFSET;
		slots = priv->int_slots;
	} else {
		ptd_offset = ATL_PTD_OFFSET;
		slots = priv->atl_slots;
	}

	free_slot = -1;
	for (curr_slot = 0; curr_slot < slot_num; curr_slot++) {
		if ((free_slot == -1) && (slots[curr_slot].qtd == NULL))
			free_slot = curr_slot;
		if (slots[curr_slot].qh == qh)
			break;
	}

	n = 0;
	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
		if (qtd->status == QTD_ENQUEUED) {
			WARN_ON(qtd->payload_addr);
			alloc_mem(hcd, qtd);
			if ((qtd->length) && (!qtd->payload_addr))
				break;

			if (qtd->length && (qtd->packet_type == SETUP_PID ||
					    qtd->packet_type == OUT_PID)) {
				mem_write(hcd, qtd->payload_addr,
					  qtd->data_buffer, qtd->length);
			}

			qtd->status = QTD_PAYLOAD_ALLOC;
		}

		if (qtd->status == QTD_PAYLOAD_ALLOC) {
/*
			if ((curr_slot > 31) && (free_slot == -1))
				dev_dbg(hcd->self.controller, "%s: No slot "
					"available for transfer\n", __func__);
*/
			/* Start xfer for this endpoint if not already done */
			if ((curr_slot > slot_num - 1) && (free_slot > -1)) {
				if (usb_pipeint(qtd->urb->pipe))
					create_ptd_int(qh, qtd, &ptd);
				else
					create_ptd_atl(qh, qtd, &ptd);

				start_bus_transfer(hcd, ptd_offset, free_slot,
							slots, qtd, qh, &ptd);
				curr_slot = free_slot;
			}

			n++;
			if (n >= ENQUEUE_DEPTH)
				break;
		}
	}
}

static void schedule_ptds(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv;
	struct isp1760_qh *qh, *qh_next;
	struct list_head *ep_queue;
	LIST_HEAD(urb_list);
	struct urb_listitem *urb_listitem, *urb_listitem_next;
	int i;

	if (!hcd) {
		WARN_ON(1);
		return;
	}

	priv = hcd_to_priv(hcd);

	/*
	 * check finished/retired xfers, transfer payloads, call urb_done()
	 */
	for (i = 0; i < QH_END; i++) {
		ep_queue = &priv->qh_list[i];
		list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) {
			collect_qtds(hcd, qh, &urb_list);
			if (list_empty(&qh->qtd_list))
				list_del(&qh->qh_list);
		}
	}

	list_for_each_entry_safe(urb_listitem, urb_listitem_next, &urb_list,
								urb_list) {
		isp1760_urb_done(hcd, urb_listitem->urb);
		kmem_cache_free(urb_listitem_cachep, urb_listitem);
	}

	/*
	 * Schedule packets for transfer.
	 *
	 * According to USB2.0 specification:
	 *
	 * 1st prio: interrupt xfers, up to 80 % of bandwidth
	 * 2nd prio: control xfers
	 * 3rd prio: bulk xfers
	 *
	 * ... but let's use a simpler scheme here (mostly because ISP1761 doc
	 * is very unclear on how to prioritize traffic):
	 *
	 * 1) Enqueue any queued control transfers, as long as payload chip mem
	 *    and PTD ATL slots are available.
	 * 2) Enqueue any queued INT transfers, as long as payload chip mem
	 *    and PTD INT slots are available.
	 * 3) Enqueue any queued bulk transfers, as long as payload chip mem
	 *    and PTD ATL slots are available.
	 *
	 * Use double buffering (ENQUEUE_DEPTH==2) as a compromise between
	 * conservation of chip mem and performance.
	 *
	 * I'm sure this scheme could be improved upon!
	 */
	for (i = 0; i < QH_END; i++) {
		ep_queue = &priv->qh_list[i];
		list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list)
			enqueue_qtds(hcd, qh);
	}
}

#define PTD_STATE_QTD_DONE	1
#define PTD_STATE_QTD_RELOAD	2
#define PTD_STATE_URB_RETIRE	3

static int check_int_transfer(struct usb_hcd *hcd, struct ptd *ptd,
								struct urb *urb)
{
	u32 dw4;
	int i;

	dw4 = TO_U32(ptd->dw4);
	dw4 >>= 8;

	/* FIXME: ISP1761 datasheet does not say what to do with these. Do we
	   need to handle these errors? Is it done in hardware? */

	if (ptd->dw3 & DW3_HALT_BIT) {

		urb->status = -EPROTO; /* Default unknown error */

		for (i = 0; i < 8; i++) {
			switch (dw4 & 0x7) {
			case INT_UNDERRUN:
				dev_dbg(hcd->self.controller, "%s: underrun "
						"during uFrame %d\n",
						__func__, i);
				urb->status = -ECOMM; /* Could not write data */
				break;
			case INT_EXACT:
				dev_dbg(hcd->self.controller, "%s: transaction "
						"error during uFrame %d\n",
						__func__, i);
				urb->status = -EPROTO; /* timeout, bad CRC, PID
							  error etc. */
				break;
			case INT_BABBLE:
				dev_dbg(hcd->self.controller, "%s: babble "
						"error during uFrame %d\n",
						__func__, i);
				urb->status = -EOVERFLOW;
				break;
			}
			dw4 >>= 3;
		}

		return PTD_STATE_URB_RETIRE;
	}

	return PTD_STATE_QTD_DONE;
}

static int check_atl_transfer(struct usb_hcd *hcd, struct ptd *ptd,
								struct urb *urb)
{
	WARN_ON(!ptd);
	if (ptd->dw3 & DW3_HALT_BIT) {
		if (ptd->dw3 & DW3_BABBLE_BIT)
			urb->status = -EOVERFLOW;
		else if (FROM_DW3_CERR(ptd->dw3))
			urb->status = -EPIPE;  /* Stall */
		else
			urb->status = -EPROTO; /* Unknown */
/*
		dev_dbg(hcd->self.controller, "%s: ptd error:\n"
			"        dw0: %08x dw1: %08x dw2: %08x dw3: %08x\n"
			"        dw4: %08x dw5: %08x dw6: %08x dw7: %08x\n",
			__func__,
			ptd->dw0, ptd->dw1, ptd->dw2, ptd->dw3,
			ptd->dw4, ptd->dw5, ptd->dw6, ptd->dw7);
*/
		return PTD_STATE_URB_RETIRE;
	}

	if ((ptd->dw3 & DW3_ERROR_BIT) && (ptd->dw3 & DW3_ACTIVE_BIT)) {
		/* Transfer Error, *but* active and no HALT -> reload */
		dev_dbg(hcd->self.controller, "PID error; reloading ptd\n");
		return PTD_STATE_QTD_RELOAD;
	}

	if (!FROM_DW3_NAKCOUNT(ptd->dw3) && (ptd->dw3 & DW3_ACTIVE_BIT)) {
		/*
		 * NAKs are handled in HW by the chip. Usually if the
		 * device is not able to send data fast enough.
		 * This happens mostly on slower hardware.
		 */
		return PTD_STATE_QTD_RELOAD;
	}

	return PTD_STATE_QTD_DONE;
}

static void handle_done_ptds(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	struct ptd ptd;
	struct isp1760_qh *qh;
	int slot;
	int state;
	struct isp1760_slotinfo *slots;
	u32 ptd_offset;
	struct isp1760_qtd *qtd;
	int modified;
	int skip_map;

	skip_map = isp1760_hcd_read(hcd, HC_INT_PTD_SKIPMAP);
	priv->int_done_map &= ~skip_map;
	skip_map = isp1760_hcd_read(hcd, HC_ATL_PTD_SKIPMAP);
	priv->atl_done_map &= ~skip_map;

	modified = priv->int_done_map || priv->atl_done_map;

	while (priv->int_done_map || priv->atl_done_map) {
		if (priv->int_done_map) {
			/* INT ptd */
			slot = __ffs(priv->int_done_map);
			priv->int_done_map &= ~(1 << slot);
			slots = priv->int_slots;
			/* This should not trigger, and could be removed if
			   noone have any problems with it triggering: */
			if (!slots[slot].qh) {
				WARN_ON(1);
				continue;
			}
			ptd_offset = INT_PTD_OFFSET;
			ptd_read(hcd, INT_PTD_OFFSET, slot, &ptd);
			state = check_int_transfer(hcd, &ptd,
							slots[slot].qtd->urb);
		} else {
			/* ATL ptd */
			slot = __ffs(priv->atl_done_map);
			priv->atl_done_map &= ~(1 << slot);
			slots = priv->atl_slots;
			/* This should not trigger, and could be removed if
			   noone have any problems with it triggering: */
			if (!slots[slot].qh) {
				WARN_ON(1);
				continue;
			}
			ptd_offset = ATL_PTD_OFFSET;
			ptd_read(hcd, ATL_PTD_OFFSET, slot, &ptd);
			state = check_atl_transfer(hcd, &ptd,
							slots[slot].qtd->urb);
		}

		qtd = slots[slot].qtd;
		slots[slot].qtd = NULL;
		qh = slots[slot].qh;
		slots[slot].qh = NULL;
		qh->slot = -1;

		WARN_ON(qtd->status != QTD_XFER_STARTED);

		switch (state) {
		case PTD_STATE_QTD_DONE:
			if ((usb_pipeint(qtd->urb->pipe)) &&
				       (qtd->urb->dev->speed != USB_SPEED_HIGH))
				qtd->actual_length =
				       FROM_DW3_SCS_NRBYTESTRANSFERRED(ptd.dw3);
			else
				qtd->actual_length =
					FROM_DW3_NRBYTESTRANSFERRED(ptd.dw3);

			qtd->status = QTD_XFER_COMPLETE;
			if (list_is_last(&qtd->qtd_list, &qh->qtd_list) ||
			    is_short_bulk(qtd))
				qtd = NULL;
			else
				qtd = list_entry(qtd->qtd_list.next,
							typeof(*qtd), qtd_list);

			qh->toggle = FROM_DW3_DATA_TOGGLE(ptd.dw3);
			qh->ping = FROM_DW3_PING(ptd.dw3);
			break;

		case PTD_STATE_QTD_RELOAD: /* QTD_RETRY, for atls only */
			qtd->status = QTD_PAYLOAD_ALLOC;
			ptd.dw0 |= DW0_VALID_BIT;
			/* RL counter = ERR counter */
			ptd.dw3 &= ~TO_DW3_NAKCOUNT(0xf);
			ptd.dw3 |= TO_DW3_NAKCOUNT(FROM_DW2_RL(ptd.dw2));
			ptd.dw3 &= ~TO_DW3_CERR(3);
			ptd.dw3 |= TO_DW3_CERR(ERR_COUNTER);
			qh->toggle = FROM_DW3_DATA_TOGGLE(ptd.dw3);
			qh->ping = FROM_DW3_PING(ptd.dw3);
			break;

		case PTD_STATE_URB_RETIRE:
			qtd->status = QTD_RETIRE;
			if ((qtd->urb->dev->speed != USB_SPEED_HIGH) &&
					(qtd->urb->status != -EPIPE) &&
					(qtd->urb->status != -EREMOTEIO)) {
				qh->tt_buffer_dirty = 1;
				if (usb_hub_clear_tt_buffer(qtd->urb))
					/* Clear failed; let's hope things work
					   anyway */
					qh->tt_buffer_dirty = 0;
			}
			qtd = NULL;
			qh->toggle = 0;
			qh->ping = 0;
			break;

		default:
			WARN_ON(1);
			continue;
		}

		if (qtd && (qtd->status == QTD_PAYLOAD_ALLOC)) {
			if (slots == priv->int_slots) {
				if (state == PTD_STATE_QTD_RELOAD)
					dev_err(hcd->self.controller,
						"%s: PTD_STATE_QTD_RELOAD on "
						"interrupt packet\n", __func__);
				if (state != PTD_STATE_QTD_RELOAD)
					create_ptd_int(qh, qtd, &ptd);
			} else {
				if (state != PTD_STATE_QTD_RELOAD)
					create_ptd_atl(qh, qtd, &ptd);
			}

			start_bus_transfer(hcd, ptd_offset, slot, slots, qtd,
				qh, &ptd);
		}
	}

	if (modified)
		schedule_ptds(hcd);
}

static irqreturn_t isp1760_irq(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	irqreturn_t irqret = IRQ_NONE;
	u32 int_reg;
	u32 imask;

	spin_lock(&priv->lock);

	if (!(hcd->state & HC_STATE_RUNNING))
		goto leave;

	imask = isp1760_hcd_read(hcd, HC_INTERRUPT);
	if (unlikely(!imask))
		goto leave;

	int_reg = priv->is_isp1763 ? ISP1763_HC_INTERRUPT :
		ISP176x_HC_INTERRUPT;
	isp1760_reg_write(priv->regs, int_reg, imask);

	priv->int_done_map |= isp1760_hcd_read(hcd, HC_INT_PTD_DONEMAP);
	priv->atl_done_map |= isp1760_hcd_read(hcd, HC_ATL_PTD_DONEMAP);

	handle_done_ptds(hcd);

	irqret = IRQ_HANDLED;

leave:
	spin_unlock(&priv->lock);

	return irqret;
}

/*
 * Workaround for problem described in chip errata 2:
 *
 * Sometimes interrupts are not generated when ATL (not INT?) completion occurs.
 * One solution suggested in the errata is to use SOF interrupts _instead_of_
 * ATL done interrupts (the "instead of" might be important since it seems
 * enabling ATL interrupts also causes the chip to sometimes - rarely - "forget"
 * to set the PTD's done bit in addition to not generating an interrupt!).
 *
 * So if we use SOF + ATL interrupts, we sometimes get stale PTDs since their
 * done bit is not being set. This is bad - it blocks the endpoint until reboot.
 *
 * If we use SOF interrupts only, we get latency between ptd completion and the
 * actual handling. This is very noticeable in testusb runs which takes several
 * minutes longer without ATL interrupts.
 *
 * A better solution is to run the code below every SLOT_CHECK_PERIOD ms. If it
 * finds active ATL slots which are older than SLOT_TIMEOUT ms, it checks the
 * slot's ACTIVE and VALID bits. If these are not set, the ptd is considered
 * completed and its done map bit is set.
 *
 * The values of SLOT_TIMEOUT and SLOT_CHECK_PERIOD have been arbitrarily chosen
 * not to cause too much lag when this HW bug occurs, while still hopefully
 * ensuring that the check does not falsely trigger.
 */
#define SLOT_TIMEOUT 300
#define SLOT_CHECK_PERIOD 200
static struct timer_list errata2_timer;
static struct usb_hcd *errata2_timer_hcd;

static void errata2_function(struct timer_list *unused)
{
	struct usb_hcd *hcd = errata2_timer_hcd;
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	const struct isp1760_memory_layout *mem = priv->memory_layout;
	int slot;
	struct ptd ptd;
	unsigned long spinflags;

	spin_lock_irqsave(&priv->lock, spinflags);

	for (slot = 0; slot < mem->slot_num; slot++)
		if (priv->atl_slots[slot].qh && time_after(jiffies,
					priv->atl_slots[slot].timestamp +
					msecs_to_jiffies(SLOT_TIMEOUT))) {
			ptd_read(hcd, ATL_PTD_OFFSET, slot, &ptd);
			if (!FROM_DW0_VALID(ptd.dw0) &&
					!FROM_DW3_ACTIVE(ptd.dw3))
				priv->atl_done_map |= 1 << slot;
		}

	if (priv->atl_done_map)
		handle_done_ptds(hcd);

	spin_unlock_irqrestore(&priv->lock, spinflags);

	errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD);
	add_timer(&errata2_timer);
}

static int isp1763_run(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	int retval;
	u32 chipid_h;
	u32 chipid_l;
	u32 chip_rev;
	u32 ptd_atl_int;
	u32 ptd_iso;

	hcd->uses_new_polling = 1;
	hcd->state = HC_STATE_RUNNING;

	chipid_h = isp1760_hcd_read(hcd, HC_CHIP_ID_HIGH);
	chipid_l = isp1760_hcd_read(hcd, HC_CHIP_ID_LOW);
	chip_rev = isp1760_hcd_read(hcd, HC_CHIP_REV);
	dev_info(hcd->self.controller, "USB ISP %02x%02x HW rev. %d started\n",
		 chipid_h, chipid_l, chip_rev);

	isp1760_hcd_clear(hcd, ISO_BUF_FILL);
	isp1760_hcd_clear(hcd, INT_BUF_FILL);
	isp1760_hcd_clear(hcd, ATL_BUF_FILL);

	isp1760_hcd_set(hcd, HC_ATL_PTD_SKIPMAP);
	isp1760_hcd_set(hcd, HC_INT_PTD_SKIPMAP);
	isp1760_hcd_set(hcd, HC_ISO_PTD_SKIPMAP);
	ndelay(100);
	isp1760_hcd_clear(hcd, HC_ATL_PTD_DONEMAP);
	isp1760_hcd_clear(hcd, HC_INT_PTD_DONEMAP);
	isp1760_hcd_clear(hcd, HC_ISO_PTD_DONEMAP);

	isp1760_hcd_set(hcd, HW_OTG_DISABLE);
	isp1760_reg_write(priv->regs, ISP1763_HC_OTG_CTRL_CLEAR, BIT(7));
	isp1760_reg_write(priv->regs, ISP1763_HC_OTG_CTRL_CLEAR, BIT(15));
	mdelay(10);

	isp1760_hcd_set(hcd, HC_INT_IRQ_ENABLE);
	isp1760_hcd_set(hcd, HC_ATL_IRQ_ENABLE);

	isp1760_hcd_set(hcd, HW_GLOBAL_INTR_EN);

	isp1760_hcd_clear(hcd, HC_ATL_IRQ_MASK_AND);
	isp1760_hcd_clear(hcd, HC_INT_IRQ_MASK_AND);
	isp1760_hcd_clear(hcd, HC_ISO_IRQ_MASK_AND);

	isp1760_hcd_set(hcd, HC_ATL_IRQ_MASK_OR);
	isp1760_hcd_set(hcd, HC_INT_IRQ_MASK_OR);
	isp1760_hcd_set(hcd, HC_ISO_IRQ_MASK_OR);

	ptd_atl_int = 0x8000;
	ptd_iso = 0x0001;

	isp1760_hcd_write(hcd, HC_ATL_PTD_LASTPTD, ptd_atl_int);
	isp1760_hcd_write(hcd, HC_INT_PTD_LASTPTD, ptd_atl_int);
	isp1760_hcd_write(hcd, HC_ISO_PTD_LASTPTD, ptd_iso);

	isp1760_hcd_set(hcd, ATL_BUF_FILL);
	isp1760_hcd_set(hcd, INT_BUF_FILL);

	isp1760_hcd_clear(hcd, CMD_LRESET);
	isp1760_hcd_clear(hcd, CMD_RESET);

	retval = isp1760_hcd_set_and_wait(hcd, CMD_RUN, 250 * 1000);
	if (retval)
		return retval;

	down_write(&ehci_cf_port_reset_rwsem);
	retval = isp1760_hcd_set_and_wait(hcd, FLAG_CF, 250 * 1000);
	up_write(&ehci_cf_port_reset_rwsem);
	if (retval)
		return retval;

	return 0;
}

static int isp1760_run(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	int retval;
	u32 chipid_h;
	u32 chipid_l;
	u32 chip_rev;
	u32 ptd_atl_int;
	u32 ptd_iso;

	/*
	 * ISP1763 have some differences in the setup and order to enable
	 * the ports, disable otg, setup buffers, and ATL, INT, ISO status.
	 * So, just handle it a separate sequence.
	 */
	if (priv->is_isp1763)
		return isp1763_run(hcd);

	hcd->uses_new_polling = 1;

	hcd->state = HC_STATE_RUNNING;

	/* Set PTD interrupt AND & OR maps */
	isp1760_hcd_clear(hcd, HC_ATL_IRQ_MASK_AND);
	isp1760_hcd_clear(hcd, HC_INT_IRQ_MASK_AND);
	isp1760_hcd_clear(hcd, HC_ISO_IRQ_MASK_AND);

	isp1760_hcd_set(hcd, HC_ATL_IRQ_MASK_OR);
	isp1760_hcd_set(hcd, HC_INT_IRQ_MASK_OR);
	isp1760_hcd_set(hcd, HC_ISO_IRQ_MASK_OR);

	/* step 23 passed */

	isp1760_hcd_set(hcd, HW_GLOBAL_INTR_EN);

	isp1760_hcd_clear(hcd, CMD_LRESET);
	isp1760_hcd_clear(hcd, CMD_RESET);

	retval = isp1760_hcd_set_and_wait(hcd, CMD_RUN, 250 * 1000);
	if (retval)
		return retval;

	/*
	 * XXX
	 * Spec says to write FLAG_CF as last config action, priv code grabs
	 * the semaphore while doing so.
	 */
	down_write(&ehci_cf_port_reset_rwsem);

	retval = isp1760_hcd_set_and_wait(hcd, FLAG_CF, 250 * 1000);
	up_write(&ehci_cf_port_reset_rwsem);
	if (retval)
		return retval;

	errata2_timer_hcd = hcd;
	timer_setup(&errata2_timer, errata2_function, 0);
	errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD);
	add_timer(&errata2_timer);

	chipid_h = isp1760_hcd_read(hcd, HC_CHIP_ID_HIGH);
	chipid_l = isp1760_hcd_read(hcd, HC_CHIP_ID_LOW);
	chip_rev = isp1760_hcd_read(hcd, HC_CHIP_REV);
	dev_info(hcd->self.controller, "USB ISP %02x%02x HW rev. %d started\n",
		 chipid_h, chipid_l, chip_rev);

	/* PTD Register Init Part 2, Step 28 */

	/* Setup registers controlling PTD checking */
	ptd_atl_int = 0x80000000;
	ptd_iso = 0x00000001;

	isp1760_hcd_write(hcd, HC_ATL_PTD_LASTPTD, ptd_atl_int);
	isp1760_hcd_write(hcd, HC_INT_PTD_LASTPTD, ptd_atl_int);
	isp1760_hcd_write(hcd, HC_ISO_PTD_LASTPTD, ptd_iso);

	isp1760_hcd_set(hcd, HC_ATL_PTD_SKIPMAP);
	isp1760_hcd_set(hcd, HC_INT_PTD_SKIPMAP);
	isp1760_hcd_set(hcd, HC_ISO_PTD_SKIPMAP);

	isp1760_hcd_set(hcd, ATL_BUF_FILL);
	isp1760_hcd_set(hcd, INT_BUF_FILL);

	/* GRR this is run-once init(), being done every time the HC starts.
	 * So long as they're part of class devices, we can't do it init()
	 * since the class device isn't created that early.
	 */
	return 0;
}

static int qtd_fill(struct isp1760_qtd *qtd, void *databuffer, size_t len)
{
	qtd->data_buffer = databuffer;

	qtd->length = len;

	return qtd->length;
}

static void qtd_list_free(struct list_head *qtd_list)
{
	struct isp1760_qtd *qtd, *qtd_next;

	list_for_each_entry_safe(qtd, qtd_next, qtd_list, qtd_list) {
		list_del(&qtd->qtd_list);
		qtd_free(qtd);
	}
}

/*
 * Packetize urb->transfer_buffer into list of packets of size wMaxPacketSize.
 * Also calculate the PID type (SETUP/IN/OUT) for each packet.
 */
#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
static void packetize_urb(struct usb_hcd *hcd,
		struct urb *urb, struct list_head *head, gfp_t flags)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	const struct isp1760_memory_layout *mem = priv->memory_layout;
	struct isp1760_qtd *qtd;
	void *buf;
	int len, maxpacketsize;
	u8 packet_type;

	/*
	 * URBs map to sequences of QTDs:  one logical transaction
	 */

	if (!urb->transfer_buffer && urb->transfer_buffer_length) {
		/* XXX This looks like usb storage / SCSI bug */
		dev_err(hcd->self.controller,
				"buf is null, dma is %08lx len is %d\n",
				(long unsigned)urb->transfer_dma,
				urb->transfer_buffer_length);
		WARN_ON(1);
	}

	if (usb_pipein(urb->pipe))
		packet_type = IN_PID;
	else
		packet_type = OUT_PID;

	if (usb_pipecontrol(urb->pipe)) {
		qtd = qtd_alloc(flags, urb, SETUP_PID);
		if (!qtd)
			goto cleanup;
		qtd_fill(qtd, urb->setup_packet, sizeof(struct usb_ctrlrequest));
		list_add_tail(&qtd->qtd_list, head);

		/* for zero length DATA stages, STATUS is always IN */
		if (urb->transfer_buffer_length == 0)
			packet_type = IN_PID;
	}

	maxpacketsize = max_packet(usb_maxpacket(urb->dev, urb->pipe,
						usb_pipeout(urb->pipe)));

	/*
	 * buffer gets wrapped in one or more qtds;
	 * last one may be "short" (including zero len)
	 * and may serve as a control status ack
	 */
	buf = urb->transfer_buffer;
	len = urb->transfer_buffer_length;

	for (;;) {
		int this_qtd_len;

		qtd = qtd_alloc(flags, urb, packet_type);
		if (!qtd)
			goto cleanup;

		if (len > mem->blocks_size[ISP176x_BLOCK_NUM - 1])
			len = mem->blocks_size[ISP176x_BLOCK_NUM - 1];

		this_qtd_len = qtd_fill(qtd, buf, len);
		list_add_tail(&qtd->qtd_list, head);

		len -= this_qtd_len;
		buf += this_qtd_len;

		if (len <= 0)
			break;
	}

	/*
	 * control requests may need a terminating data "status" ack;
	 * bulk ones may need a terminating short packet (zero length).
	 */
	if (urb->transfer_buffer_length != 0) {
		int one_more = 0;

		if (usb_pipecontrol(urb->pipe)) {
			one_more = 1;
			if (packet_type == IN_PID)
				packet_type = OUT_PID;
			else
				packet_type = IN_PID;
		} else if (usb_pipebulk(urb->pipe)
				&& (urb->transfer_flags & URB_ZERO_PACKET)
				&& !(urb->transfer_buffer_length %
							maxpacketsize)) {
			one_more = 1;
		}
		if (one_more) {
			qtd = qtd_alloc(flags, urb, packet_type);
			if (!qtd)
				goto cleanup;

			/* never any data in such packets */
			qtd_fill(qtd, NULL, 0);
			list_add_tail(&qtd->qtd_list, head);
		}
	}

	return;

cleanup:
	qtd_list_free(head);
}

static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
		gfp_t mem_flags)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	struct list_head *ep_queue;
	struct isp1760_qh *qh, *qhit;
	unsigned long spinflags;
	LIST_HEAD(new_qtds);
	int retval;
	int qh_in_queue;

	switch (usb_pipetype(urb->pipe)) {
	case PIPE_CONTROL:
		ep_queue = &priv->qh_list[QH_CONTROL];
		break;
	case PIPE_BULK:
		ep_queue = &priv->qh_list[QH_BULK];
		break;
	case PIPE_INTERRUPT:
		if (urb->interval < 0)
			return -EINVAL;
		/* FIXME: Check bandwidth  */
		ep_queue = &priv->qh_list[QH_INTERRUPT];
		break;
	case PIPE_ISOCHRONOUS:
		dev_err(hcd->self.controller, "%s: isochronous USB packets "
							"not yet supported\n",
							__func__);
		return -EPIPE;
	default:
		dev_err(hcd->self.controller, "%s: unknown pipe type\n",
							__func__);
		return -EPIPE;
	}

	if (usb_pipein(urb->pipe))
		urb->actual_length = 0;

	packetize_urb(hcd, urb, &new_qtds, mem_flags);
	if (list_empty(&new_qtds))
		return -ENOMEM;

	retval = 0;
	spin_lock_irqsave(&priv->lock, spinflags);

	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
		retval = -ESHUTDOWN;
		qtd_list_free(&new_qtds);
		goto out;
	}
	retval = usb_hcd_link_urb_to_ep(hcd, urb);
	if (retval) {
		qtd_list_free(&new_qtds);
		goto out;
	}

	qh = urb->ep->hcpriv;
	if (qh) {
		qh_in_queue = 0;
		list_for_each_entry(qhit, ep_queue, qh_list) {
			if (qhit == qh) {
				qh_in_queue = 1;
				break;
			}
		}
		if (!qh_in_queue)
			list_add_tail(&qh->qh_list, ep_queue);
	} else {
		qh = qh_alloc(GFP_ATOMIC);
		if (!qh) {
			retval = -ENOMEM;
			usb_hcd_unlink_urb_from_ep(hcd, urb);
			qtd_list_free(&new_qtds);
			goto out;
		}
		list_add_tail(&qh->qh_list, ep_queue);
		urb->ep->hcpriv = qh;
	}

	list_splice_tail(&new_qtds, &qh->qtd_list);
	schedule_ptds(hcd);

out:
	spin_unlock_irqrestore(&priv->lock, spinflags);
	return retval;
}

static void kill_transfer(struct usb_hcd *hcd, struct urb *urb,
		struct isp1760_qh *qh)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	int skip_map;

	WARN_ON(qh->slot == -1);

	/* We need to forcefully reclaim the slot since some transfers never
	   return, e.g. interrupt transfers and NAKed bulk transfers. */
	if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) {
		skip_map = isp1760_hcd_read(hcd, HC_ATL_PTD_SKIPMAP);
		skip_map |= (1 << qh->slot);
		isp1760_hcd_write(hcd, HC_ATL_PTD_SKIPMAP, skip_map);
		ndelay(100);
		priv->atl_slots[qh->slot].qh = NULL;
		priv->atl_slots[qh->slot].qtd = NULL;
	} else {
		skip_map = isp1760_hcd_read(hcd, HC_INT_PTD_SKIPMAP);
		skip_map |= (1 << qh->slot);
		isp1760_hcd_write(hcd, HC_INT_PTD_SKIPMAP, skip_map);
		priv->int_slots[qh->slot].qh = NULL;
		priv->int_slots[qh->slot].qtd = NULL;
	}

	qh->slot = -1;
}

/*
 * Retire the qtds beginning at 'qtd' and belonging all to the same urb, killing
 * any active transfer belonging to the urb in the process.
 */
static void dequeue_urb_from_qtd(struct usb_hcd *hcd, struct isp1760_qh *qh,
						struct isp1760_qtd *qtd)
{
	struct urb *urb;
	int urb_was_running;

	urb = qtd->urb;
	urb_was_running = 0;
	list_for_each_entry_from(qtd, &qh->qtd_list, qtd_list) {
		if (qtd->urb != urb)
			break;

		if (qtd->status >= QTD_XFER_STARTED)
			urb_was_running = 1;
		if (last_qtd_of_urb(qtd, qh) &&
					(qtd->status >= QTD_XFER_COMPLETE))
			urb_was_running = 0;

		if (qtd->status == QTD_XFER_STARTED)
			kill_transfer(hcd, urb, qh);
		qtd->status = QTD_RETIRE;
	}

	if ((urb->dev->speed != USB_SPEED_HIGH) && urb_was_running) {
		qh->tt_buffer_dirty = 1;
		if (usb_hub_clear_tt_buffer(urb))
			/* Clear failed; let's hope things work anyway */
			qh->tt_buffer_dirty = 0;
	}
}

static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
		int status)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	unsigned long spinflags;
	struct isp1760_qh *qh;
	struct isp1760_qtd *qtd;
	int retval = 0;

	spin_lock_irqsave(&priv->lock, spinflags);
	retval = usb_hcd_check_unlink_urb(hcd, urb, status);
	if (retval)
		goto out;

	qh = urb->ep->hcpriv;
	if (!qh) {
		retval = -EINVAL;
		goto out;
	}

	list_for_each_entry(qtd, &qh->qtd_list, qtd_list)
		if (qtd->urb == urb) {
			dequeue_urb_from_qtd(hcd, qh, qtd);
			list_move(&qtd->qtd_list, &qh->qtd_list);
			break;
		}

	urb->status = status;
	schedule_ptds(hcd);

out:
	spin_unlock_irqrestore(&priv->lock, spinflags);
	return retval;
}

static void isp1760_endpoint_disable(struct usb_hcd *hcd,
		struct usb_host_endpoint *ep)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	unsigned long spinflags;
	struct isp1760_qh *qh, *qh_iter;
	int i;

	spin_lock_irqsave(&priv->lock, spinflags);

	qh = ep->hcpriv;
	if (!qh)
		goto out;

	WARN_ON(!list_empty(&qh->qtd_list));

	for (i = 0; i < QH_END; i++)
		list_for_each_entry(qh_iter, &priv->qh_list[i], qh_list)
			if (qh_iter == qh) {
				list_del(&qh_iter->qh_list);
				i = QH_END;
				break;
			}
	qh_free(qh);
	ep->hcpriv = NULL;

	schedule_ptds(hcd);

out:
	spin_unlock_irqrestore(&priv->lock, spinflags);
}

static int isp1760_hub_status_data(struct usb_hcd *hcd, char *buf)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	u32 status = 0;
	int retval = 1;
	unsigned long flags;

	/* if !PM, root hub timers won't get shut down ... */
	if (!HC_IS_RUNNING(hcd->state))
		return 0;

	/* init status to no-changes */
	buf[0] = 0;

	spin_lock_irqsave(&priv->lock, flags);

	if (isp1760_hcd_is_set(hcd, PORT_OWNER) &&
	    isp1760_hcd_is_set(hcd, PORT_CSC)) {
		isp1760_hcd_clear(hcd, PORT_CSC);
		goto done;
	}

	/*
	 * Return status information even for ports with OWNER set.
	 * Otherwise hub_wq wouldn't see the disconnect event when a
	 * high-speed device is switched over to the companion
	 * controller by the user.
	 */
	if (isp1760_hcd_is_set(hcd, PORT_CSC) ||
	    (isp1760_hcd_is_set(hcd, PORT_RESUME) &&
	     time_after_eq(jiffies, priv->reset_done))) {
		buf [0] |= 1 << (0 + 1);
		status = STS_PCD;
	}
	/* FIXME autosuspend idle root hubs */
done:
	spin_unlock_irqrestore(&priv->lock, flags);
	return status ? retval : 0;
}

static void isp1760_hub_descriptor(struct isp1760_hcd *priv,
		struct usb_hub_descriptor *desc)
{
	int ports;
	u16 temp;

	ports = isp1760_hcd_n_ports(priv->hcd);

	desc->bDescriptorType = USB_DT_HUB;
	/* priv 1.0, 2.3.9 says 20ms max */
	desc->bPwrOn2PwrGood = 10;
	desc->bHubContrCurrent = 0;

	desc->bNbrPorts = ports;
	temp = 1 + (ports / 8);
	desc->bDescLength = 7 + 2 * temp;

	/* ports removable, and usb 1.0 legacy PortPwrCtrlMask */
	memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
	memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);

	/* per-port overcurrent reporting */
	temp = HUB_CHAR_INDV_PORT_OCPM;
	if (isp1760_hcd_ppc_is_set(priv->hcd))
		/* per-port power control */
		temp |= HUB_CHAR_INDV_PORT_LPSM;
	else
		/* no power switching */
		temp |= HUB_CHAR_NO_LPSM;
	desc->wHubCharacteristics = cpu_to_le16(temp);
}

#define	PORT_WAKE_BITS	(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)

static void check_reset_complete(struct usb_hcd *hcd, int index)
{
	if (!(isp1760_hcd_is_set(hcd, PORT_CONNECT)))
		return;

	/* if reset finished and it's still not enabled -- handoff */
	if (!isp1760_hcd_is_set(hcd, PORT_PE)) {
		dev_info(hcd->self.controller,
			 "port %d full speed --> companion\n", index + 1);

		isp1760_hcd_set(hcd, PORT_OWNER);

		isp1760_hcd_clear(hcd, PORT_CSC);
	} else {
		dev_info(hcd->self.controller, "port %d high speed\n",
			 index + 1);
	}

	return;
}

static int isp1760_hub_control(struct usb_hcd *hcd, u16 typeReq,
		u16 wValue, u16 wIndex, char *buf, u16 wLength)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	u32 status;
	unsigned long flags;
	int retval = 0;
	int ports;

	ports = isp1760_hcd_n_ports(hcd);

	/*
	 * FIXME:  support SetPortFeatures USB_PORT_FEAT_INDICATOR.
	 * HCS_INDICATOR may say we can change LEDs to off/amber/green.
	 * (track current state ourselves) ... blink for diagnostics,
	 * power, "this is the one", etc.  EHCI spec supports this.
	 */

	spin_lock_irqsave(&priv->lock, flags);
	switch (typeReq) {
	case ClearHubFeature:
		switch (wValue) {
		case C_HUB_LOCAL_POWER:
		case C_HUB_OVER_CURRENT:
			/* no hub-wide feature/status flags */
			break;
		default:
			goto error;
		}
		break;
	case ClearPortFeature:
		if (!wIndex || wIndex > ports)
			goto error;
		wIndex--;

		/*
		 * Even if OWNER is set, so the port is owned by the
		 * companion controller, hub_wq needs to be able to clear
		 * the port-change status bits (especially
		 * USB_PORT_STAT_C_CONNECTION).
		 */

		switch (wValue) {
		case USB_PORT_FEAT_ENABLE:
			isp1760_hcd_clear(hcd, PORT_PE);
			break;
		case USB_PORT_FEAT_C_ENABLE:
			/* XXX error? */
			break;
		case USB_PORT_FEAT_SUSPEND:
			if (isp1760_hcd_is_set(hcd, PORT_RESET))
				goto error;

			if (isp1760_hcd_is_set(hcd, PORT_SUSPEND)) {
				if (!isp1760_hcd_is_set(hcd, PORT_PE))
					goto error;
				/* resume signaling for 20 msec */
				isp1760_hcd_clear(hcd, PORT_CSC);
				isp1760_hcd_set(hcd, PORT_RESUME);

				priv->reset_done = jiffies +
					msecs_to_jiffies(USB_RESUME_TIMEOUT);
			}
			break;
		case USB_PORT_FEAT_C_SUSPEND:
			/* we auto-clear this feature */
			break;
		case USB_PORT_FEAT_POWER:
			if (isp1760_hcd_ppc_is_set(hcd))
				isp1760_hcd_clear(hcd, PORT_POWER);
			break;
		case USB_PORT_FEAT_C_CONNECTION:
			isp1760_hcd_set(hcd, PORT_CSC);
			break;
		case USB_PORT_FEAT_C_OVER_CURRENT:
			/* XXX error ?*/
			break;
		case USB_PORT_FEAT_C_RESET:
			/* GetPortStatus clears reset */
			break;
		default:
			goto error;
		}
		isp1760_hcd_read(hcd, CMD_RUN);
		break;
	case GetHubDescriptor:
		isp1760_hub_descriptor(priv, (struct usb_hub_descriptor *)
			buf);
		break;
	case GetHubStatus:
		/* no hub-wide feature/status flags */
		memset(buf, 0, 4);
		break;
	case GetPortStatus:
		if (!wIndex || wIndex > ports)
			goto error;
		wIndex--;
		status = 0;

		/* wPortChange bits */
		if (isp1760_hcd_is_set(hcd, PORT_CSC))
			status |= USB_PORT_STAT_C_CONNECTION << 16;

		/* whoever resumes must GetPortStatus to complete it!! */
		if (isp1760_hcd_is_set(hcd, PORT_RESUME)) {
			dev_err(hcd->self.controller, "Port resume should be skipped.\n");

			/* Remote Wakeup received? */
			if (!priv->reset_done) {
				/* resume signaling for 20 msec */
				priv->reset_done = jiffies
						+ msecs_to_jiffies(20);
				/* check the port again */
				mod_timer(&hcd->rh_timer, priv->reset_done);
			}

			/* resume completed? */
			else if (time_after_eq(jiffies,
					priv->reset_done)) {
				status |= USB_PORT_STAT_C_SUSPEND << 16;
				priv->reset_done = 0;

				/* stop resume signaling */
				isp1760_hcd_clear(hcd, PORT_CSC);

				retval = isp1760_hcd_clear_and_wait(hcd,
							  PORT_RESUME, 2000);
				if (retval != 0) {
					dev_err(hcd->self.controller,
						"port %d resume error %d\n",
						wIndex + 1, retval);
					goto error;
				}
			}
		}

		/* whoever resets must GetPortStatus to complete it!! */
		if (isp1760_hcd_is_set(hcd, PORT_RESET) &&
		    time_after_eq(jiffies, priv->reset_done)) {
			status |= USB_PORT_STAT_C_RESET << 16;
			priv->reset_done = 0;

			/* force reset to complete */
			/* REVISIT:  some hardware needs 550+ usec to clear
			 * this bit; seems too long to spin routinely...
			 */
			retval = isp1760_hcd_clear_and_wait(hcd, PORT_RESET,
							    750);
			if (retval != 0) {
				dev_err(hcd->self.controller, "port %d reset error %d\n",
					wIndex + 1, retval);
				goto error;
			}

			/* see what we found out */
			check_reset_complete(hcd, wIndex);
		}
		/*
		 * Even if OWNER is set, there's no harm letting hub_wq
		 * see the wPortStatus values (they should all be 0 except
		 * for PORT_POWER anyway).
		 */

		if (isp1760_hcd_is_set(hcd, PORT_OWNER))
			dev_err(hcd->self.controller, "PORT_OWNER is set\n");

		if (isp1760_hcd_is_set(hcd, PORT_CONNECT)) {
			status |= USB_PORT_STAT_CONNECTION;
			/* status may be from integrated TT */
			status |= USB_PORT_STAT_HIGH_SPEED;
		}
		if (isp1760_hcd_is_set(hcd, PORT_PE))
			status |= USB_PORT_STAT_ENABLE;
		if (isp1760_hcd_is_set(hcd, PORT_SUSPEND) &&
		    isp1760_hcd_is_set(hcd, PORT_RESUME))
			status |= USB_PORT_STAT_SUSPEND;
		if (isp1760_hcd_is_set(hcd, PORT_RESET))
			status |= USB_PORT_STAT_RESET;
		if (isp1760_hcd_is_set(hcd, PORT_POWER))
			status |= USB_PORT_STAT_POWER;

		put_unaligned(cpu_to_le32(status), (__le32 *) buf);
		break;
	case SetHubFeature:
		switch (wValue) {
		case C_HUB_LOCAL_POWER:
		case C_HUB_OVER_CURRENT:
			/* no hub-wide feature/status flags */
			break;
		default:
			goto error;
		}
		break;
	case SetPortFeature:
		wIndex &= 0xff;
		if (!wIndex || wIndex > ports)
			goto error;
		wIndex--;

		if (isp1760_hcd_is_set(hcd, PORT_OWNER))
			break;

		switch (wValue) {
		case USB_PORT_FEAT_ENABLE:
			isp1760_hcd_set(hcd, PORT_PE);
			break;

		case USB_PORT_FEAT_SUSPEND:
			if (!isp1760_hcd_is_set(hcd, PORT_PE) ||
			    isp1760_hcd_is_set(hcd, PORT_RESET))
				goto error;

			isp1760_hcd_set(hcd, PORT_SUSPEND);
			break;
		case USB_PORT_FEAT_POWER:
			if (isp1760_hcd_ppc_is_set(hcd))
				isp1760_hcd_set(hcd, PORT_POWER);
			break;
		case USB_PORT_FEAT_RESET:
			if (isp1760_hcd_is_set(hcd, PORT_RESUME))
				goto error;
			/* line status bits may report this as low speed,
			 * which can be fine if this root hub has a
			 * transaction translator built in.
			 */
			if ((isp1760_hcd_is_set(hcd, PORT_CONNECT) &&
			     !isp1760_hcd_is_set(hcd, PORT_PE)) &&
			    (isp1760_hcd_read(hcd, PORT_LSTATUS) == 1)) {
				isp1760_hcd_set(hcd, PORT_OWNER);
			} else {
				isp1760_hcd_set(hcd, PORT_RESET);
				isp1760_hcd_clear(hcd, PORT_PE);

				/*
				 * caller must wait, then call GetPortStatus
				 * usb 2.0 spec says 50 ms resets on root
				 */
				priv->reset_done = jiffies +
					msecs_to_jiffies(50);
			}
			break;
		default:
			goto error;
		}
		break;

	default:
error:
		/* "stall" on error */
		retval = -EPIPE;
	}
	spin_unlock_irqrestore(&priv->lock, flags);
	return retval;
}

static int isp1760_get_frame(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	u32 fr;

	fr = isp1760_hcd_read(hcd, HC_FRINDEX);
	return (fr >> 3) % priv->periodic_size;
}

static void isp1760_stop(struct usb_hcd *hcd)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);

	del_timer(&errata2_timer);

	isp1760_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER,	1,
			NULL, 0);
	msleep(20);

	spin_lock_irq(&priv->lock);
	ehci_reset(hcd);
	/* Disable IRQ */
	isp1760_hcd_clear(hcd, HW_GLOBAL_INTR_EN);
	spin_unlock_irq(&priv->lock);

	isp1760_hcd_clear(hcd, FLAG_CF);
}

static void isp1760_shutdown(struct usb_hcd *hcd)
{
	isp1760_stop(hcd);

	isp1760_hcd_clear(hcd, HW_GLOBAL_INTR_EN);

	isp1760_hcd_clear(hcd, CMD_RUN);
}

static void isp1760_clear_tt_buffer_complete(struct usb_hcd *hcd,
						struct usb_host_endpoint *ep)
{
	struct isp1760_hcd *priv = hcd_to_priv(hcd);
	struct isp1760_qh *qh = ep->hcpriv;
	unsigned long spinflags;

	if (!qh)
		return;

	spin_lock_irqsave(&priv->lock, spinflags);
	qh->tt_buffer_dirty = 0;
	schedule_ptds(hcd);
	spin_unlock_irqrestore(&priv->lock, spinflags);
}


static const struct hc_driver isp1760_hc_driver = {
	.description		= "isp1760-hcd",
	.product_desc		= "NXP ISP1760 USB Host Controller",
	.hcd_priv_size		= sizeof(struct isp1760_hcd *),
	.irq			= isp1760_irq,
	.flags			= HCD_MEMORY | HCD_USB2,
	.reset			= isp1760_hc_setup,
	.start			= isp1760_run,
	.stop			= isp1760_stop,
	.shutdown		= isp1760_shutdown,
	.urb_enqueue		= isp1760_urb_enqueue,
	.urb_dequeue		= isp1760_urb_dequeue,
	.endpoint_disable	= isp1760_endpoint_disable,
	.get_frame_number	= isp1760_get_frame,
	.hub_status_data	= isp1760_hub_status_data,
	.hub_control		= isp1760_hub_control,
	.clear_tt_buffer_complete	= isp1760_clear_tt_buffer_complete,
};

int __init isp1760_init_kmem_once(void)
{
	urb_listitem_cachep = kmem_cache_create("isp1760_urb_listitem",
			sizeof(struct urb_listitem), 0, SLAB_TEMPORARY |
			SLAB_MEM_SPREAD, NULL);

	if (!urb_listitem_cachep)
		return -ENOMEM;

	qtd_cachep = kmem_cache_create("isp1760_qtd",
			sizeof(struct isp1760_qtd), 0, SLAB_TEMPORARY |
			SLAB_MEM_SPREAD, NULL);

	if (!qtd_cachep)
		return -ENOMEM;

	qh_cachep = kmem_cache_create("isp1760_qh", sizeof(struct isp1760_qh),
			0, SLAB_TEMPORARY | SLAB_MEM_SPREAD, NULL);

	if (!qh_cachep) {
		kmem_cache_destroy(qtd_cachep);
		return -ENOMEM;
	}

	return 0;
}

void isp1760_deinit_kmem_cache(void)
{
	kmem_cache_destroy(qtd_cachep);
	kmem_cache_destroy(qh_cachep);
	kmem_cache_destroy(urb_listitem_cachep);
}

int isp1760_hcd_register(struct isp1760_hcd *priv, struct resource *mem,
			 int irq, unsigned long irqflags,
			 struct device *dev)
{
	const struct isp1760_memory_layout *mem_layout = priv->memory_layout;
	struct usb_hcd *hcd;
	int ret;

	hcd = usb_create_hcd(&isp1760_hc_driver, dev, dev_name(dev));
	if (!hcd)
		return -ENOMEM;

	*(struct isp1760_hcd **)hcd->hcd_priv = priv;

	priv->hcd = hcd;

	priv->atl_slots = kcalloc(mem_layout->slot_num,
				  sizeof(struct isp1760_slotinfo), GFP_KERNEL);
	if (!priv->atl_slots) {
		ret = -ENOMEM;
		goto put_hcd;
	}

	priv->int_slots = kcalloc(mem_layout->slot_num,
				  sizeof(struct isp1760_slotinfo), GFP_KERNEL);
	if (!priv->int_slots) {
		ret = -ENOMEM;
		goto free_atl_slots;
	}

	init_memory(priv);

	hcd->irq = irq;
	hcd->rsrc_start = mem->start;
	hcd->rsrc_len = resource_size(mem);

	/* This driver doesn't support wakeup requests */
	hcd->cant_recv_wakeups = 1;

	ret = usb_add_hcd(hcd, irq, irqflags);
	if (ret)
		goto free_int_slots;

	device_wakeup_enable(hcd->self.controller);

	return 0;

free_int_slots:
	kfree(priv->int_slots);
free_atl_slots:
	kfree(priv->atl_slots);
put_hcd:
	usb_put_hcd(hcd);
	return ret;
}

void isp1760_hcd_unregister(struct isp1760_hcd *priv)
{
	if (!priv->hcd)
		return;

	usb_remove_hcd(priv->hcd);
	usb_put_hcd(priv->hcd);
	kfree(priv->atl_slots);
	kfree(priv->int_slots);
}
