162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * ISP1362 HCD (Host Controller Driver) for USB.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * COPYRIGHT (C) by L. Wassmann <LW@KARO-electronics.de>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/* ------------------------------------------------------------------------- */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#define MAX_ROOT_PORTS		2
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define USE_32BIT		0
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/* These options are mutually exclusive */
1562306a36Sopenharmony_ci#define USE_PLATFORM_DELAY	0
1662306a36Sopenharmony_ci#define USE_NDELAY		0
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define DUMMY_DELAY_ACCESS do {} while (0)
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/* ------------------------------------------------------------------------- */
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define USB_RESET_WIDTH			50
2362306a36Sopenharmony_ci#define MAX_XFER_SIZE			1023
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/* Buffer sizes */
2662306a36Sopenharmony_ci#define ISP1362_BUF_SIZE		4096
2762306a36Sopenharmony_ci#define ISP1362_ISTL_BUFSIZE		512
2862306a36Sopenharmony_ci#define ISP1362_INTL_BLKSIZE		64
2962306a36Sopenharmony_ci#define ISP1362_INTL_BUFFERS		16
3062306a36Sopenharmony_ci#define ISP1362_ATL_BLKSIZE		64
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci#define ISP1362_REG_WRITE_OFFSET	0x80
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define REG_WIDTH_16			0x000
3562306a36Sopenharmony_ci#define REG_WIDTH_32			0x100
3662306a36Sopenharmony_ci#define REG_WIDTH_MASK			0x100
3762306a36Sopenharmony_ci#define REG_NO_MASK			0x0ff
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#ifdef ISP1362_DEBUG
4062306a36Sopenharmony_citypedef const unsigned int isp1362_reg_t;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#define REG_ACCESS_R			0x200
4362306a36Sopenharmony_ci#define REG_ACCESS_W			0x400
4462306a36Sopenharmony_ci#define REG_ACCESS_RW			0x600
4562306a36Sopenharmony_ci#define REG_ACCESS_MASK			0x600
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#define ISP1362_REG_NO(r)		((r) & REG_NO_MASK)
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci#define ISP1362_REG(name, addr, width, rw) \
5062306a36Sopenharmony_cistatic isp1362_reg_t ISP1362_REG_##name = ((addr) | (width) | (rw))
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci#define REG_ACCESS_TEST(r)   BUG_ON(((r) & ISP1362_REG_WRITE_OFFSET) && !((r) & REG_ACCESS_W))
5362306a36Sopenharmony_ci#define REG_WIDTH_TEST(r, w) BUG_ON(((r) & REG_WIDTH_MASK) != (w))
5462306a36Sopenharmony_ci#else
5562306a36Sopenharmony_citypedef const unsigned char isp1362_reg_t;
5662306a36Sopenharmony_ci#define ISP1362_REG_NO(r)		(r)
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci#define ISP1362_REG(name, addr, width, rw) \
5962306a36Sopenharmony_cistatic isp1362_reg_t __maybe_unused ISP1362_REG_##name = addr
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci#define REG_ACCESS_TEST(r)		do {} while (0)
6262306a36Sopenharmony_ci#define REG_WIDTH_TEST(r, w)		do {} while (0)
6362306a36Sopenharmony_ci#endif
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci/* OHCI compatible registers */
6662306a36Sopenharmony_ci/*
6762306a36Sopenharmony_ci * Note: Some of the ISP1362 'OHCI' registers implement only
6862306a36Sopenharmony_ci * a subset of the bits defined in the OHCI spec.
6962306a36Sopenharmony_ci *
7062306a36Sopenharmony_ci * Bitmasks for the individual bits of these registers are defined in "ohci.h"
7162306a36Sopenharmony_ci */
7262306a36Sopenharmony_ciISP1362_REG(HCREVISION,	0x00,	REG_WIDTH_32,	REG_ACCESS_R);
7362306a36Sopenharmony_ciISP1362_REG(HCCONTROL,	0x01,	REG_WIDTH_32,	REG_ACCESS_RW);
7462306a36Sopenharmony_ciISP1362_REG(HCCMDSTAT,	0x02,	REG_WIDTH_32,	REG_ACCESS_RW);
7562306a36Sopenharmony_ciISP1362_REG(HCINTSTAT,	0x03,	REG_WIDTH_32,	REG_ACCESS_RW);
7662306a36Sopenharmony_ciISP1362_REG(HCINTENB,	0x04,	REG_WIDTH_32,	REG_ACCESS_RW);
7762306a36Sopenharmony_ciISP1362_REG(HCINTDIS,	0x05,	REG_WIDTH_32,	REG_ACCESS_RW);
7862306a36Sopenharmony_ciISP1362_REG(HCFMINTVL,	0x0d,	REG_WIDTH_32,	REG_ACCESS_RW);
7962306a36Sopenharmony_ciISP1362_REG(HCFMREM,	0x0e,	REG_WIDTH_32,	REG_ACCESS_RW);
8062306a36Sopenharmony_ciISP1362_REG(HCFMNUM,	0x0f,	REG_WIDTH_32,	REG_ACCESS_RW);
8162306a36Sopenharmony_ciISP1362_REG(HCLSTHRESH,	0x11,	REG_WIDTH_32,	REG_ACCESS_RW);
8262306a36Sopenharmony_ciISP1362_REG(HCRHDESCA,	0x12,	REG_WIDTH_32,	REG_ACCESS_RW);
8362306a36Sopenharmony_ciISP1362_REG(HCRHDESCB,	0x13,	REG_WIDTH_32,	REG_ACCESS_RW);
8462306a36Sopenharmony_ciISP1362_REG(HCRHSTATUS,	0x14,	REG_WIDTH_32,	REG_ACCESS_RW);
8562306a36Sopenharmony_ciISP1362_REG(HCRHPORT1,	0x15,	REG_WIDTH_32,	REG_ACCESS_RW);
8662306a36Sopenharmony_ciISP1362_REG(HCRHPORT2,	0x16,	REG_WIDTH_32,	REG_ACCESS_RW);
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/* Philips ISP1362 specific registers */
8962306a36Sopenharmony_ciISP1362_REG(HCHWCFG,	0x20,	REG_WIDTH_16,	REG_ACCESS_RW);
9062306a36Sopenharmony_ci#define HCHWCFG_DISABLE_SUSPEND	(1 << 15)
9162306a36Sopenharmony_ci#define HCHWCFG_GLOBAL_PWRDOWN	(1 << 14)
9262306a36Sopenharmony_ci#define HCHWCFG_PULLDOWN_DS2	(1 << 13)
9362306a36Sopenharmony_ci#define HCHWCFG_PULLDOWN_DS1	(1 << 12)
9462306a36Sopenharmony_ci#define HCHWCFG_CLKNOTSTOP	(1 << 11)
9562306a36Sopenharmony_ci#define HCHWCFG_ANALOG_OC	(1 << 10)
9662306a36Sopenharmony_ci#define HCHWCFG_ONEINT		(1 << 9)
9762306a36Sopenharmony_ci#define HCHWCFG_DACK_MODE	(1 << 8)
9862306a36Sopenharmony_ci#define HCHWCFG_ONEDMA		(1 << 7)
9962306a36Sopenharmony_ci#define HCHWCFG_DACK_POL	(1 << 6)
10062306a36Sopenharmony_ci#define HCHWCFG_DREQ_POL	(1 << 5)
10162306a36Sopenharmony_ci#define HCHWCFG_DBWIDTH_MASK	(0x03 << 3)
10262306a36Sopenharmony_ci#define HCHWCFG_DBWIDTH(n)	(((n) << 3) & HCHWCFG_DBWIDTH_MASK)
10362306a36Sopenharmony_ci#define HCHWCFG_INT_POL		(1 << 2)
10462306a36Sopenharmony_ci#define HCHWCFG_INT_TRIGGER	(1 << 1)
10562306a36Sopenharmony_ci#define HCHWCFG_INT_ENABLE	(1 << 0)
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciISP1362_REG(HCDMACFG,	0x21,	REG_WIDTH_16,	REG_ACCESS_RW);
10862306a36Sopenharmony_ci#define HCDMACFG_CTR_ENABLE	(1 << 7)
10962306a36Sopenharmony_ci#define HCDMACFG_BURST_LEN_MASK	(0x03 << 5)
11062306a36Sopenharmony_ci#define HCDMACFG_BURST_LEN(n)	(((n) << 5) & HCDMACFG_BURST_LEN_MASK)
11162306a36Sopenharmony_ci#define HCDMACFG_BURST_LEN_1	HCDMACFG_BURST_LEN(0)
11262306a36Sopenharmony_ci#define HCDMACFG_BURST_LEN_4	HCDMACFG_BURST_LEN(1)
11362306a36Sopenharmony_ci#define HCDMACFG_BURST_LEN_8	HCDMACFG_BURST_LEN(2)
11462306a36Sopenharmony_ci#define HCDMACFG_DMA_ENABLE	(1 << 4)
11562306a36Sopenharmony_ci#define HCDMACFG_BUF_TYPE_MASK	(0x07 << 1)
11662306a36Sopenharmony_ci#define HCDMACFG_BUF_TYPE(n)	(((n) << 1) & HCDMACFG_BUF_TYPE_MASK)
11762306a36Sopenharmony_ci#define HCDMACFG_BUF_ISTL0	HCDMACFG_BUF_TYPE(0)
11862306a36Sopenharmony_ci#define HCDMACFG_BUF_ISTL1	HCDMACFG_BUF_TYPE(1)
11962306a36Sopenharmony_ci#define HCDMACFG_BUF_INTL	HCDMACFG_BUF_TYPE(2)
12062306a36Sopenharmony_ci#define HCDMACFG_BUF_ATL	HCDMACFG_BUF_TYPE(3)
12162306a36Sopenharmony_ci#define HCDMACFG_BUF_DIRECT	HCDMACFG_BUF_TYPE(4)
12262306a36Sopenharmony_ci#define HCDMACFG_DMA_RW_SELECT	(1 << 0)
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ciISP1362_REG(HCXFERCTR,	0x22,	REG_WIDTH_16,	REG_ACCESS_RW);
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ciISP1362_REG(HCuPINT,	0x24,	REG_WIDTH_16,	REG_ACCESS_RW);
12762306a36Sopenharmony_ci#define HCuPINT_SOF		(1 << 0)
12862306a36Sopenharmony_ci#define HCuPINT_ISTL0		(1 << 1)
12962306a36Sopenharmony_ci#define HCuPINT_ISTL1		(1 << 2)
13062306a36Sopenharmony_ci#define HCuPINT_EOT		(1 << 3)
13162306a36Sopenharmony_ci#define HCuPINT_OPR		(1 << 4)
13262306a36Sopenharmony_ci#define HCuPINT_SUSP		(1 << 5)
13362306a36Sopenharmony_ci#define HCuPINT_CLKRDY		(1 << 6)
13462306a36Sopenharmony_ci#define HCuPINT_INTL		(1 << 7)
13562306a36Sopenharmony_ci#define HCuPINT_ATL		(1 << 8)
13662306a36Sopenharmony_ci#define HCuPINT_OTG		(1 << 9)
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ciISP1362_REG(HCuPINTENB,	0x25,	REG_WIDTH_16,	REG_ACCESS_RW);
13962306a36Sopenharmony_ci/* same bit definitions apply as for HCuPINT */
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ciISP1362_REG(HCCHIPID,	0x27,	REG_WIDTH_16,	REG_ACCESS_R);
14262306a36Sopenharmony_ci#define HCCHIPID_MASK		0xff00
14362306a36Sopenharmony_ci#define HCCHIPID_MAGIC		0x3600
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ciISP1362_REG(HCSCRATCH,	0x28,	REG_WIDTH_16,	REG_ACCESS_RW);
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ciISP1362_REG(HCSWRES,	0x29,	REG_WIDTH_16,	REG_ACCESS_W);
14862306a36Sopenharmony_ci#define HCSWRES_MAGIC		0x00f6
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ciISP1362_REG(HCBUFSTAT,	0x2c,	REG_WIDTH_16,	REG_ACCESS_RW);
15162306a36Sopenharmony_ci#define HCBUFSTAT_ISTL0_FULL	(1 << 0)
15262306a36Sopenharmony_ci#define HCBUFSTAT_ISTL1_FULL	(1 << 1)
15362306a36Sopenharmony_ci#define HCBUFSTAT_INTL_ACTIVE	(1 << 2)
15462306a36Sopenharmony_ci#define HCBUFSTAT_ATL_ACTIVE	(1 << 3)
15562306a36Sopenharmony_ci#define HCBUFSTAT_RESET_HWPP	(1 << 4)
15662306a36Sopenharmony_ci#define HCBUFSTAT_ISTL0_ACTIVE	(1 << 5)
15762306a36Sopenharmony_ci#define HCBUFSTAT_ISTL1_ACTIVE	(1 << 6)
15862306a36Sopenharmony_ci#define HCBUFSTAT_ISTL0_DONE	(1 << 8)
15962306a36Sopenharmony_ci#define HCBUFSTAT_ISTL1_DONE	(1 << 9)
16062306a36Sopenharmony_ci#define HCBUFSTAT_PAIRED_PTDPP	(1 << 10)
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ciISP1362_REG(HCDIRADDR,	0x32,	REG_WIDTH_32,	REG_ACCESS_RW);
16362306a36Sopenharmony_ci#define HCDIRADDR_ADDR_MASK	0x0000ffff
16462306a36Sopenharmony_ci#define HCDIRADDR_ADDR(n)	(((n) << 0) & HCDIRADDR_ADDR_MASK)
16562306a36Sopenharmony_ci#define HCDIRADDR_COUNT_MASK	0xffff0000
16662306a36Sopenharmony_ci#define HCDIRADDR_COUNT(n)	(((n) << 16) & HCDIRADDR_COUNT_MASK)
16762306a36Sopenharmony_ciISP1362_REG(HCDIRDATA,	0x45,	REG_WIDTH_16,	REG_ACCESS_RW);
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ciISP1362_REG(HCISTLBUFSZ, 0x30,	REG_WIDTH_16,	REG_ACCESS_RW);
17062306a36Sopenharmony_ciISP1362_REG(HCISTL0PORT, 0x40,	REG_WIDTH_16,	REG_ACCESS_RW);
17162306a36Sopenharmony_ciISP1362_REG(HCISTL1PORT, 0x42,	REG_WIDTH_16,	REG_ACCESS_RW);
17262306a36Sopenharmony_ciISP1362_REG(HCISTLRATE,	0x47,	REG_WIDTH_16,	REG_ACCESS_RW);
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ciISP1362_REG(HCINTLBUFSZ, 0x33,	REG_WIDTH_16,	REG_ACCESS_RW);
17562306a36Sopenharmony_ciISP1362_REG(HCINTLPORT,	0x43,	REG_WIDTH_16,	REG_ACCESS_RW);
17662306a36Sopenharmony_ciISP1362_REG(HCINTLBLKSZ, 0x53,	REG_WIDTH_16,	REG_ACCESS_RW);
17762306a36Sopenharmony_ciISP1362_REG(HCINTLDONE,	0x17,	REG_WIDTH_32,	REG_ACCESS_R);
17862306a36Sopenharmony_ciISP1362_REG(HCINTLSKIP,	0x18,	REG_WIDTH_32,	REG_ACCESS_RW);
17962306a36Sopenharmony_ciISP1362_REG(HCINTLLAST,	0x19,	REG_WIDTH_32,	REG_ACCESS_RW);
18062306a36Sopenharmony_ciISP1362_REG(HCINTLCURR,	0x1a,	REG_WIDTH_16,	REG_ACCESS_R);
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ciISP1362_REG(HCATLBUFSZ, 0x34,	REG_WIDTH_16,	REG_ACCESS_RW);
18362306a36Sopenharmony_ciISP1362_REG(HCATLPORT,	0x44,	REG_WIDTH_16,	REG_ACCESS_RW);
18462306a36Sopenharmony_ciISP1362_REG(HCATLBLKSZ, 0x54,	REG_WIDTH_16,	REG_ACCESS_RW);
18562306a36Sopenharmony_ciISP1362_REG(HCATLDONE,	0x1b,	REG_WIDTH_32,	REG_ACCESS_R);
18662306a36Sopenharmony_ciISP1362_REG(HCATLSKIP,	0x1c,	REG_WIDTH_32,	REG_ACCESS_RW);
18762306a36Sopenharmony_ciISP1362_REG(HCATLLAST,	0x1d,	REG_WIDTH_32,	REG_ACCESS_RW);
18862306a36Sopenharmony_ciISP1362_REG(HCATLCURR,	0x1e,	REG_WIDTH_16,	REG_ACCESS_R);
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ciISP1362_REG(HCATLDTC,	0x51,	REG_WIDTH_16,	REG_ACCESS_RW);
19162306a36Sopenharmony_ciISP1362_REG(HCATLDTCTO,	0x52,	REG_WIDTH_16,	REG_ACCESS_RW);
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ciISP1362_REG(OTGCONTROL,	0x62,	REG_WIDTH_16,	REG_ACCESS_RW);
19562306a36Sopenharmony_ciISP1362_REG(OTGSTATUS,	0x67,	REG_WIDTH_16,	REG_ACCESS_R);
19662306a36Sopenharmony_ciISP1362_REG(OTGINT,	0x68,	REG_WIDTH_16,	REG_ACCESS_RW);
19762306a36Sopenharmony_ciISP1362_REG(OTGINTENB,	0x69,	REG_WIDTH_16,	REG_ACCESS_RW);
19862306a36Sopenharmony_ciISP1362_REG(OTGTIMER,	0x6A,	REG_WIDTH_16,	REG_ACCESS_RW);
19962306a36Sopenharmony_ciISP1362_REG(OTGALTTMR,	0x6C,	REG_WIDTH_16,	REG_ACCESS_RW);
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci/* Philips transfer descriptor, cpu-endian */
20262306a36Sopenharmony_cistruct ptd {
20362306a36Sopenharmony_ci	u16 count;
20462306a36Sopenharmony_ci#define	PTD_COUNT_MSK	(0x3ff << 0)
20562306a36Sopenharmony_ci#define	PTD_TOGGLE_MSK	(1 << 10)
20662306a36Sopenharmony_ci#define	PTD_ACTIVE_MSK	(1 << 11)
20762306a36Sopenharmony_ci#define	PTD_CC_MSK	(0xf << 12)
20862306a36Sopenharmony_ci	u16 mps;
20962306a36Sopenharmony_ci#define	PTD_MPS_MSK	(0x3ff << 0)
21062306a36Sopenharmony_ci#define	PTD_SPD_MSK	(1 << 10)
21162306a36Sopenharmony_ci#define	PTD_LAST_MSK	(1 << 11)
21262306a36Sopenharmony_ci#define	PTD_EP_MSK	(0xf << 12)
21362306a36Sopenharmony_ci	u16 len;
21462306a36Sopenharmony_ci#define	PTD_LEN_MSK	(0x3ff << 0)
21562306a36Sopenharmony_ci#define	PTD_DIR_MSK	(3 << 10)
21662306a36Sopenharmony_ci#define	PTD_DIR_SETUP	(0)
21762306a36Sopenharmony_ci#define	PTD_DIR_OUT	(1)
21862306a36Sopenharmony_ci#define	PTD_DIR_IN	(2)
21962306a36Sopenharmony_ci	u16 faddr;
22062306a36Sopenharmony_ci#define	PTD_FA_MSK	(0x7f << 0)
22162306a36Sopenharmony_ci/* PTD Byte 7: [StartingFrame (if ISO PTD) | StartingFrame[0..4], PollingRate[0..2] (if INT PTD)] */
22262306a36Sopenharmony_ci#define PTD_SF_ISO_MSK	(0xff << 8)
22362306a36Sopenharmony_ci#define PTD_SF_INT_MSK	(0x1f << 8)
22462306a36Sopenharmony_ci#define PTD_PR_MSK	(0x07 << 13)
22562306a36Sopenharmony_ci} __attribute__ ((packed, aligned(2)));
22662306a36Sopenharmony_ci#define PTD_HEADER_SIZE sizeof(struct ptd)
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci/* ------------------------------------------------------------------------- */
22962306a36Sopenharmony_ci/* Copied from ohci.h: */
23062306a36Sopenharmony_ci/*
23162306a36Sopenharmony_ci * Hardware transfer status codes -- CC from PTD
23262306a36Sopenharmony_ci */
23362306a36Sopenharmony_ci#define PTD_CC_NOERROR      0x00
23462306a36Sopenharmony_ci#define PTD_CC_CRC          0x01
23562306a36Sopenharmony_ci#define PTD_CC_BITSTUFFING  0x02
23662306a36Sopenharmony_ci#define PTD_CC_DATATOGGLEM  0x03
23762306a36Sopenharmony_ci#define PTD_CC_STALL        0x04
23862306a36Sopenharmony_ci#define PTD_DEVNOTRESP      0x05
23962306a36Sopenharmony_ci#define PTD_PIDCHECKFAIL    0x06
24062306a36Sopenharmony_ci#define PTD_UNEXPECTEDPID   0x07
24162306a36Sopenharmony_ci#define PTD_DATAOVERRUN     0x08
24262306a36Sopenharmony_ci#define PTD_DATAUNDERRUN    0x09
24362306a36Sopenharmony_ci    /* 0x0A, 0x0B reserved for hardware */
24462306a36Sopenharmony_ci#define PTD_BUFFEROVERRUN   0x0C
24562306a36Sopenharmony_ci#define PTD_BUFFERUNDERRUN  0x0D
24662306a36Sopenharmony_ci    /* 0x0E, 0x0F reserved for HCD */
24762306a36Sopenharmony_ci#define PTD_NOTACCESSED     0x0F
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci/* map OHCI TD status codes (CC) to errno values */
25162306a36Sopenharmony_cistatic const int cc_to_error[16] = {
25262306a36Sopenharmony_ci	/* No  Error  */               0,
25362306a36Sopenharmony_ci	/* CRC Error  */               -EILSEQ,
25462306a36Sopenharmony_ci	/* Bit Stuff  */               -EPROTO,
25562306a36Sopenharmony_ci	/* Data Togg  */               -EILSEQ,
25662306a36Sopenharmony_ci	/* Stall      */               -EPIPE,
25762306a36Sopenharmony_ci	/* DevNotResp */               -ETIMEDOUT,
25862306a36Sopenharmony_ci	/* PIDCheck   */               -EPROTO,
25962306a36Sopenharmony_ci	/* UnExpPID   */               -EPROTO,
26062306a36Sopenharmony_ci	/* DataOver   */               -EOVERFLOW,
26162306a36Sopenharmony_ci	/* DataUnder  */               -EREMOTEIO,
26262306a36Sopenharmony_ci	/* (for hw)   */               -EIO,
26362306a36Sopenharmony_ci	/* (for hw)   */               -EIO,
26462306a36Sopenharmony_ci	/* BufferOver */               -ECOMM,
26562306a36Sopenharmony_ci	/* BuffUnder  */               -ENOSR,
26662306a36Sopenharmony_ci	/* (for HCD)  */               -EALREADY,
26762306a36Sopenharmony_ci	/* (for HCD)  */               -EALREADY
26862306a36Sopenharmony_ci};
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci/*
27262306a36Sopenharmony_ci * HcControl (control) register masks
27362306a36Sopenharmony_ci */
27462306a36Sopenharmony_ci#define OHCI_CTRL_HCFS	(3 << 6)	/* host controller functional state */
27562306a36Sopenharmony_ci#define OHCI_CTRL_RWC	(1 << 9)	/* remote wakeup connected */
27662306a36Sopenharmony_ci#define OHCI_CTRL_RWE	(1 << 10)	/* remote wakeup enable */
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci/* pre-shifted values for HCFS */
27962306a36Sopenharmony_ci#	define OHCI_USB_RESET	(0 << 6)
28062306a36Sopenharmony_ci#	define OHCI_USB_RESUME	(1 << 6)
28162306a36Sopenharmony_ci#	define OHCI_USB_OPER	(2 << 6)
28262306a36Sopenharmony_ci#	define OHCI_USB_SUSPEND	(3 << 6)
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci/*
28562306a36Sopenharmony_ci * HcCommandStatus (cmdstatus) register masks
28662306a36Sopenharmony_ci */
28762306a36Sopenharmony_ci#define OHCI_HCR	(1 << 0)	/* host controller reset */
28862306a36Sopenharmony_ci#define OHCI_SOC  	(3 << 16)	/* scheduling overrun count */
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci/*
29162306a36Sopenharmony_ci * masks used with interrupt registers:
29262306a36Sopenharmony_ci * HcInterruptStatus (intrstatus)
29362306a36Sopenharmony_ci * HcInterruptEnable (intrenable)
29462306a36Sopenharmony_ci * HcInterruptDisable (intrdisable)
29562306a36Sopenharmony_ci */
29662306a36Sopenharmony_ci#define OHCI_INTR_SO	(1 << 0)	/* scheduling overrun */
29762306a36Sopenharmony_ci#define OHCI_INTR_WDH	(1 << 1)	/* writeback of done_head */
29862306a36Sopenharmony_ci#define OHCI_INTR_SF	(1 << 2)	/* start frame */
29962306a36Sopenharmony_ci#define OHCI_INTR_RD	(1 << 3)	/* resume detect */
30062306a36Sopenharmony_ci#define OHCI_INTR_UE	(1 << 4)	/* unrecoverable error */
30162306a36Sopenharmony_ci#define OHCI_INTR_FNO	(1 << 5)	/* frame number overflow */
30262306a36Sopenharmony_ci#define OHCI_INTR_RHSC	(1 << 6)	/* root hub status change */
30362306a36Sopenharmony_ci#define OHCI_INTR_OC	(1 << 30)	/* ownership change */
30462306a36Sopenharmony_ci#define OHCI_INTR_MIE	(1 << 31)	/* master interrupt enable */
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci/* roothub.portstatus [i] bits */
30762306a36Sopenharmony_ci#define RH_PS_CCS            0x00000001   	/* current connect status */
30862306a36Sopenharmony_ci#define RH_PS_PES            0x00000002   	/* port enable status*/
30962306a36Sopenharmony_ci#define RH_PS_PSS            0x00000004   	/* port suspend status */
31062306a36Sopenharmony_ci#define RH_PS_POCI           0x00000008   	/* port over current indicator */
31162306a36Sopenharmony_ci#define RH_PS_PRS            0x00000010  	/* port reset status */
31262306a36Sopenharmony_ci#define RH_PS_PPS            0x00000100   	/* port power status */
31362306a36Sopenharmony_ci#define RH_PS_LSDA           0x00000200    	/* low speed device attached */
31462306a36Sopenharmony_ci#define RH_PS_CSC            0x00010000 	/* connect status change */
31562306a36Sopenharmony_ci#define RH_PS_PESC           0x00020000   	/* port enable status change */
31662306a36Sopenharmony_ci#define RH_PS_PSSC           0x00040000    	/* port suspend status change */
31762306a36Sopenharmony_ci#define RH_PS_OCIC           0x00080000    	/* over current indicator change */
31862306a36Sopenharmony_ci#define RH_PS_PRSC           0x00100000   	/* port reset status change */
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci/* roothub.status bits */
32162306a36Sopenharmony_ci#define RH_HS_LPS	     0x00000001		/* local power status */
32262306a36Sopenharmony_ci#define RH_HS_OCI	     0x00000002		/* over current indicator */
32362306a36Sopenharmony_ci#define RH_HS_DRWE	     0x00008000		/* device remote wakeup enable */
32462306a36Sopenharmony_ci#define RH_HS_LPSC	     0x00010000		/* local power status change */
32562306a36Sopenharmony_ci#define RH_HS_OCIC	     0x00020000		/* over current indicator change */
32662306a36Sopenharmony_ci#define RH_HS_CRWE	     0x80000000		/* clear remote wakeup enable */
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci/* roothub.b masks */
32962306a36Sopenharmony_ci#define RH_B_DR		0x0000ffff		/* device removable flags */
33062306a36Sopenharmony_ci#define RH_B_PPCM	0xffff0000		/* port power control mask */
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci/* roothub.a masks */
33362306a36Sopenharmony_ci#define	RH_A_NDP	(0xff << 0)		/* number of downstream ports */
33462306a36Sopenharmony_ci#define	RH_A_PSM	(1 << 8)		/* power switching mode */
33562306a36Sopenharmony_ci#define	RH_A_NPS	(1 << 9)		/* no power switching */
33662306a36Sopenharmony_ci#define	RH_A_DT		(1 << 10)		/* device type (mbz) */
33762306a36Sopenharmony_ci#define	RH_A_OCPM	(1 << 11)		/* over current protection mode */
33862306a36Sopenharmony_ci#define	RH_A_NOCP	(1 << 12)		/* no over current protection */
33962306a36Sopenharmony_ci#define	RH_A_POTPGT	(0xff << 24)		/* power on to power good time */
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci#define	FI			0x2edf		/* 12000 bits per frame (-1) */
34262306a36Sopenharmony_ci#define	FSMP(fi) 		(0x7fff & ((6 * ((fi) - 210)) / 7))
34362306a36Sopenharmony_ci#define LSTHRESH		0x628		/* lowspeed bit threshold */
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci/* ------------------------------------------------------------------------- */
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci/* PTD accessor macros. */
34862306a36Sopenharmony_ci#define PTD_GET_COUNT(p)	(((p)->count & PTD_COUNT_MSK) >> 0)
34962306a36Sopenharmony_ci#define PTD_COUNT(v)		(((v) << 0) & PTD_COUNT_MSK)
35062306a36Sopenharmony_ci#define PTD_GET_TOGGLE(p)	(((p)->count & PTD_TOGGLE_MSK) >> 10)
35162306a36Sopenharmony_ci#define PTD_TOGGLE(v)		(((v) << 10) & PTD_TOGGLE_MSK)
35262306a36Sopenharmony_ci#define PTD_GET_ACTIVE(p)	(((p)->count & PTD_ACTIVE_MSK) >> 11)
35362306a36Sopenharmony_ci#define PTD_ACTIVE(v)		(((v) << 11) & PTD_ACTIVE_MSK)
35462306a36Sopenharmony_ci#define PTD_GET_CC(p)		(((p)->count & PTD_CC_MSK) >> 12)
35562306a36Sopenharmony_ci#define PTD_CC(v)		(((v) << 12) & PTD_CC_MSK)
35662306a36Sopenharmony_ci#define PTD_GET_MPS(p)		(((p)->mps & PTD_MPS_MSK) >> 0)
35762306a36Sopenharmony_ci#define PTD_MPS(v)		(((v) << 0) & PTD_MPS_MSK)
35862306a36Sopenharmony_ci#define PTD_GET_SPD(p)		(((p)->mps & PTD_SPD_MSK) >> 10)
35962306a36Sopenharmony_ci#define PTD_SPD(v)		(((v) << 10) & PTD_SPD_MSK)
36062306a36Sopenharmony_ci#define PTD_GET_LAST(p)		(((p)->mps & PTD_LAST_MSK) >> 11)
36162306a36Sopenharmony_ci#define PTD_LAST(v)		(((v) << 11) & PTD_LAST_MSK)
36262306a36Sopenharmony_ci#define PTD_GET_EP(p)		(((p)->mps & PTD_EP_MSK) >> 12)
36362306a36Sopenharmony_ci#define PTD_EP(v)		(((v) << 12) & PTD_EP_MSK)
36462306a36Sopenharmony_ci#define PTD_GET_LEN(p)		(((p)->len & PTD_LEN_MSK) >> 0)
36562306a36Sopenharmony_ci#define PTD_LEN(v)		(((v) << 0) & PTD_LEN_MSK)
36662306a36Sopenharmony_ci#define PTD_GET_DIR(p)		(((p)->len & PTD_DIR_MSK) >> 10)
36762306a36Sopenharmony_ci#define PTD_DIR(v)		(((v) << 10) & PTD_DIR_MSK)
36862306a36Sopenharmony_ci#define PTD_GET_FA(p)		(((p)->faddr & PTD_FA_MSK) >> 0)
36962306a36Sopenharmony_ci#define PTD_FA(v)		(((v) << 0) & PTD_FA_MSK)
37062306a36Sopenharmony_ci#define PTD_GET_SF_INT(p)	(((p)->faddr & PTD_SF_INT_MSK) >> 8)
37162306a36Sopenharmony_ci#define PTD_SF_INT(v)		(((v) << 8) & PTD_SF_INT_MSK)
37262306a36Sopenharmony_ci#define PTD_GET_SF_ISO(p)	(((p)->faddr & PTD_SF_ISO_MSK) >> 8)
37362306a36Sopenharmony_ci#define PTD_SF_ISO(v)		(((v) << 8) & PTD_SF_ISO_MSK)
37462306a36Sopenharmony_ci#define PTD_GET_PR(p)		(((p)->faddr & PTD_PR_MSK) >> 13)
37562306a36Sopenharmony_ci#define PTD_PR(v)		(((v) << 13) & PTD_PR_MSK)
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci#define	LOG2_PERIODIC_SIZE	5	/* arbitrary; this matches OHCI */
37862306a36Sopenharmony_ci#define	PERIODIC_SIZE		(1 << LOG2_PERIODIC_SIZE)
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_cistruct isp1362_ep {
38162306a36Sopenharmony_ci	struct usb_host_endpoint *hep;
38262306a36Sopenharmony_ci	struct usb_device	*udev;
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	/* philips transfer descriptor */
38562306a36Sopenharmony_ci	struct ptd		ptd;
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	u8			maxpacket;
38862306a36Sopenharmony_ci	u8			epnum;
38962306a36Sopenharmony_ci	u8			nextpid;
39062306a36Sopenharmony_ci	u16			error_count;
39162306a36Sopenharmony_ci	u16			length;		/* of current packet */
39262306a36Sopenharmony_ci	s16			ptd_offset;	/* buffer offset in ISP1362 where
39362306a36Sopenharmony_ci						   PTD has been stored
39462306a36Sopenharmony_ci						   (for access thru HCDIRDATA) */
39562306a36Sopenharmony_ci	int			ptd_index;
39662306a36Sopenharmony_ci	int num_ptds;
39762306a36Sopenharmony_ci	void 			*data;		/* to databuf */
39862306a36Sopenharmony_ci	/* queue of active EPs (the ones transmitted to the chip) */
39962306a36Sopenharmony_ci	struct list_head	active;
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	/* periodic schedule */
40262306a36Sopenharmony_ci	u8			branch;
40362306a36Sopenharmony_ci	u16			interval;
40462306a36Sopenharmony_ci	u16			load;
40562306a36Sopenharmony_ci	u16			last_iso;
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci	/* async schedule */
40862306a36Sopenharmony_ci	struct list_head	schedule;	/* list of all EPs that need processing */
40962306a36Sopenharmony_ci	struct list_head	remove_list;
41062306a36Sopenharmony_ci	int			num_req;
41162306a36Sopenharmony_ci};
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_cistruct isp1362_ep_queue {
41462306a36Sopenharmony_ci	struct list_head	active;		/* list of PTDs currently processed by HC */
41562306a36Sopenharmony_ci	atomic_t		finishing;
41662306a36Sopenharmony_ci	unsigned long		buf_map;
41762306a36Sopenharmony_ci	unsigned long		skip_map;
41862306a36Sopenharmony_ci	int			free_ptd;
41962306a36Sopenharmony_ci	u16			buf_start;
42062306a36Sopenharmony_ci	u16			buf_size;
42162306a36Sopenharmony_ci	u16			blk_size;	/* PTD buffer block size for ATL and INTL */
42262306a36Sopenharmony_ci	u8			buf_count;
42362306a36Sopenharmony_ci	u8			buf_avail;
42462306a36Sopenharmony_ci	char			name[16];
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	/* for statistical tracking */
42762306a36Sopenharmony_ci	u8			stat_maxptds;	/* Max # of ptds seen simultaneously in fifo */
42862306a36Sopenharmony_ci	u8			ptd_count;	/* number of ptds submitted to this queue */
42962306a36Sopenharmony_ci};
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_cistruct isp1362_hcd {
43262306a36Sopenharmony_ci	spinlock_t		lock;
43362306a36Sopenharmony_ci	void __iomem		*addr_reg;
43462306a36Sopenharmony_ci	void __iomem		*data_reg;
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	struct isp1362_platform_data *board;
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	unsigned long		stat1, stat2, stat4, stat8, stat16;
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	/* HC registers */
44162306a36Sopenharmony_ci	u32			intenb;		/* "OHCI" interrupts */
44262306a36Sopenharmony_ci	u16			irqenb;		/* uP interrupts */
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci	/* Root hub registers */
44562306a36Sopenharmony_ci	u32			rhdesca;
44662306a36Sopenharmony_ci	u32			rhdescb;
44762306a36Sopenharmony_ci	u32			rhstatus;
44862306a36Sopenharmony_ci	u32			rhport[MAX_ROOT_PORTS];
44962306a36Sopenharmony_ci	unsigned long		next_statechange;
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci	/* HC control reg shadow copy */
45262306a36Sopenharmony_ci	u32			hc_control;
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci	/* async schedule: control, bulk */
45562306a36Sopenharmony_ci	struct list_head	async;
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	/* periodic schedule: int */
45862306a36Sopenharmony_ci	u16			load[PERIODIC_SIZE];
45962306a36Sopenharmony_ci	struct list_head	periodic;
46062306a36Sopenharmony_ci	u16			fmindex;
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci	/* periodic schedule: isochronous */
46362306a36Sopenharmony_ci	struct list_head	isoc;
46462306a36Sopenharmony_ci	unsigned int		istl_flip:1;
46562306a36Sopenharmony_ci	unsigned int		irq_active:1;
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	/* Schedules for the current frame */
46862306a36Sopenharmony_ci	struct isp1362_ep_queue atl_queue;
46962306a36Sopenharmony_ci	struct isp1362_ep_queue intl_queue;
47062306a36Sopenharmony_ci	struct isp1362_ep_queue istl_queue[2];
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci	/* list of PTDs retrieved from HC */
47362306a36Sopenharmony_ci	struct list_head	remove_list;
47462306a36Sopenharmony_ci	enum {
47562306a36Sopenharmony_ci		ISP1362_INT_SOF,
47662306a36Sopenharmony_ci		ISP1362_INT_ISTL0,
47762306a36Sopenharmony_ci		ISP1362_INT_ISTL1,
47862306a36Sopenharmony_ci		ISP1362_INT_EOT,
47962306a36Sopenharmony_ci		ISP1362_INT_OPR,
48062306a36Sopenharmony_ci		ISP1362_INT_SUSP,
48162306a36Sopenharmony_ci		ISP1362_INT_CLKRDY,
48262306a36Sopenharmony_ci		ISP1362_INT_INTL,
48362306a36Sopenharmony_ci		ISP1362_INT_ATL,
48462306a36Sopenharmony_ci		ISP1362_INT_OTG,
48562306a36Sopenharmony_ci		NUM_ISP1362_IRQS
48662306a36Sopenharmony_ci	} IRQ_NAMES;
48762306a36Sopenharmony_ci	unsigned int		irq_stat[NUM_ISP1362_IRQS];
48862306a36Sopenharmony_ci	int			req_serial;
48962306a36Sopenharmony_ci};
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_cistatic inline const char *ISP1362_INT_NAME(int n)
49262306a36Sopenharmony_ci{
49362306a36Sopenharmony_ci	switch (n) {
49462306a36Sopenharmony_ci	case ISP1362_INT_SOF:    return "SOF";
49562306a36Sopenharmony_ci	case ISP1362_INT_ISTL0:  return "ISTL0";
49662306a36Sopenharmony_ci	case ISP1362_INT_ISTL1:  return "ISTL1";
49762306a36Sopenharmony_ci	case ISP1362_INT_EOT:    return "EOT";
49862306a36Sopenharmony_ci	case ISP1362_INT_OPR:    return "OPR";
49962306a36Sopenharmony_ci	case ISP1362_INT_SUSP:   return "SUSP";
50062306a36Sopenharmony_ci	case ISP1362_INT_CLKRDY: return "CLKRDY";
50162306a36Sopenharmony_ci	case ISP1362_INT_INTL:   return "INTL";
50262306a36Sopenharmony_ci	case ISP1362_INT_ATL:    return "ATL";
50362306a36Sopenharmony_ci	case ISP1362_INT_OTG:    return "OTG";
50462306a36Sopenharmony_ci	default:                 return "unknown";
50562306a36Sopenharmony_ci	}
50662306a36Sopenharmony_ci}
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_cistatic inline void ALIGNSTAT(struct isp1362_hcd *isp1362_hcd, void *ptr)
50962306a36Sopenharmony_ci{
51062306a36Sopenharmony_ci	unsigned long p = (unsigned long)ptr;
51162306a36Sopenharmony_ci	if (!(p & 0xf))
51262306a36Sopenharmony_ci		isp1362_hcd->stat16++;
51362306a36Sopenharmony_ci	else if (!(p & 0x7))
51462306a36Sopenharmony_ci		isp1362_hcd->stat8++;
51562306a36Sopenharmony_ci	else if (!(p & 0x3))
51662306a36Sopenharmony_ci		isp1362_hcd->stat4++;
51762306a36Sopenharmony_ci	else if (!(p & 0x1))
51862306a36Sopenharmony_ci		isp1362_hcd->stat2++;
51962306a36Sopenharmony_ci	else
52062306a36Sopenharmony_ci		isp1362_hcd->stat1++;
52162306a36Sopenharmony_ci}
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_cistatic inline struct isp1362_hcd *hcd_to_isp1362_hcd(struct usb_hcd *hcd)
52462306a36Sopenharmony_ci{
52562306a36Sopenharmony_ci	return (struct isp1362_hcd *) (hcd->hcd_priv);
52662306a36Sopenharmony_ci}
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_cistatic inline struct usb_hcd *isp1362_hcd_to_hcd(struct isp1362_hcd *isp1362_hcd)
52962306a36Sopenharmony_ci{
53062306a36Sopenharmony_ci	return container_of((void *)isp1362_hcd, struct usb_hcd, hcd_priv);
53162306a36Sopenharmony_ci}
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci#define frame_before(f1, f2)	((s16)((u16)f1 - (u16)f2) < 0)
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci/*
53662306a36Sopenharmony_ci * ISP1362 HW Interface
53762306a36Sopenharmony_ci */
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci#define DBG(level, fmt...) \
54062306a36Sopenharmony_ci	do { \
54162306a36Sopenharmony_ci		if (dbg_level > level) \
54262306a36Sopenharmony_ci			pr_debug(fmt); \
54362306a36Sopenharmony_ci	} while (0)
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci#ifdef VERBOSE
54662306a36Sopenharmony_ci#    define VDBG(fmt...)	DBG(3, fmt)
54762306a36Sopenharmony_ci#else
54862306a36Sopenharmony_ci#    define VDBG(fmt...)	do {} while (0)
54962306a36Sopenharmony_ci#endif
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci#ifdef REGISTERS
55262306a36Sopenharmony_ci#    define RDBG(fmt...)	DBG(1, fmt)
55362306a36Sopenharmony_ci#else
55462306a36Sopenharmony_ci#    define RDBG(fmt...)	do {} while (0)
55562306a36Sopenharmony_ci#endif
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci#ifdef URB_TRACE
55862306a36Sopenharmony_ci#define URB_DBG(fmt...)		DBG(0, fmt)
55962306a36Sopenharmony_ci#else
56062306a36Sopenharmony_ci#define URB_DBG(fmt...)		do {} while (0)
56162306a36Sopenharmony_ci#endif
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci#if USE_PLATFORM_DELAY
56562306a36Sopenharmony_ci#if USE_NDELAY
56662306a36Sopenharmony_ci#error USE_PLATFORM_DELAY and USE_NDELAY defined simultaneously.
56762306a36Sopenharmony_ci#endif
56862306a36Sopenharmony_ci#define	isp1362_delay(h, d)	(h)->board->delay(isp1362_hcd_to_hcd(h)->self.controller, d)
56962306a36Sopenharmony_ci#elif USE_NDELAY
57062306a36Sopenharmony_ci#define	isp1362_delay(h, d)	ndelay(d)
57162306a36Sopenharmony_ci#else
57262306a36Sopenharmony_ci#define	isp1362_delay(h, d)	do {} while (0)
57362306a36Sopenharmony_ci#endif
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci#define get_urb(ep) ({							\
57662306a36Sopenharmony_ci	BUG_ON(list_empty(&ep->hep->urb_list));				\
57762306a36Sopenharmony_ci	container_of(ep->hep->urb_list.next, struct urb, urb_list);	\
57862306a36Sopenharmony_ci})
57962306a36Sopenharmony_ci
58062306a36Sopenharmony_ci/* basic access functions for ISP1362 chip registers */
58162306a36Sopenharmony_ci/* NOTE: The contents of the address pointer register cannot be read back! The driver must ensure,
58262306a36Sopenharmony_ci * that all register accesses are performed with interrupts disabled, since the interrupt
58362306a36Sopenharmony_ci * handler has no way of restoring the previous state.
58462306a36Sopenharmony_ci */
58562306a36Sopenharmony_cistatic void isp1362_write_addr(struct isp1362_hcd *isp1362_hcd, isp1362_reg_t reg)
58662306a36Sopenharmony_ci{
58762306a36Sopenharmony_ci	REG_ACCESS_TEST(reg);
58862306a36Sopenharmony_ci	DUMMY_DELAY_ACCESS;
58962306a36Sopenharmony_ci	writew(ISP1362_REG_NO(reg), isp1362_hcd->addr_reg);
59062306a36Sopenharmony_ci	DUMMY_DELAY_ACCESS;
59162306a36Sopenharmony_ci	isp1362_delay(isp1362_hcd, 1);
59262306a36Sopenharmony_ci}
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_cistatic void isp1362_write_data16(struct isp1362_hcd *isp1362_hcd, u16 val)
59562306a36Sopenharmony_ci{
59662306a36Sopenharmony_ci	DUMMY_DELAY_ACCESS;
59762306a36Sopenharmony_ci	writew(val, isp1362_hcd->data_reg);
59862306a36Sopenharmony_ci}
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_cistatic u16 isp1362_read_data16(struct isp1362_hcd *isp1362_hcd)
60162306a36Sopenharmony_ci{
60262306a36Sopenharmony_ci	u16 val;
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	DUMMY_DELAY_ACCESS;
60562306a36Sopenharmony_ci	val = readw(isp1362_hcd->data_reg);
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	return val;
60862306a36Sopenharmony_ci}
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_cistatic void isp1362_write_data32(struct isp1362_hcd *isp1362_hcd, u32 val)
61162306a36Sopenharmony_ci{
61262306a36Sopenharmony_ci#if USE_32BIT
61362306a36Sopenharmony_ci	DUMMY_DELAY_ACCESS;
61462306a36Sopenharmony_ci	writel(val, isp1362_hcd->data_reg);
61562306a36Sopenharmony_ci#else
61662306a36Sopenharmony_ci	DUMMY_DELAY_ACCESS;
61762306a36Sopenharmony_ci	writew((u16)val, isp1362_hcd->data_reg);
61862306a36Sopenharmony_ci	DUMMY_DELAY_ACCESS;
61962306a36Sopenharmony_ci	writew(val >> 16, isp1362_hcd->data_reg);
62062306a36Sopenharmony_ci#endif
62162306a36Sopenharmony_ci}
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_cistatic u32 isp1362_read_data32(struct isp1362_hcd *isp1362_hcd)
62462306a36Sopenharmony_ci{
62562306a36Sopenharmony_ci	u32 val;
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci#if USE_32BIT
62862306a36Sopenharmony_ci	DUMMY_DELAY_ACCESS;
62962306a36Sopenharmony_ci	val = readl(isp1362_hcd->data_reg);
63062306a36Sopenharmony_ci#else
63162306a36Sopenharmony_ci	DUMMY_DELAY_ACCESS;
63262306a36Sopenharmony_ci	val = (u32)readw(isp1362_hcd->data_reg);
63362306a36Sopenharmony_ci	DUMMY_DELAY_ACCESS;
63462306a36Sopenharmony_ci	val |= (u32)readw(isp1362_hcd->data_reg) << 16;
63562306a36Sopenharmony_ci#endif
63662306a36Sopenharmony_ci	return val;
63762306a36Sopenharmony_ci}
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci/* use readsw/writesw to access the fifo whenever possible */
64062306a36Sopenharmony_ci/* assume HCDIRDATA or XFERCTR & addr_reg have been set up */
64162306a36Sopenharmony_cistatic void isp1362_read_fifo(struct isp1362_hcd *isp1362_hcd, void *buf, u16 len)
64262306a36Sopenharmony_ci{
64362306a36Sopenharmony_ci	u8 *dp = buf;
64462306a36Sopenharmony_ci	u16 data;
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci	if (!len)
64762306a36Sopenharmony_ci		return;
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci	RDBG("%s: Reading %d byte from fifo to mem @ %p\n", __func__, len, buf);
65062306a36Sopenharmony_ci#if USE_32BIT
65162306a36Sopenharmony_ci	if (len >= 4) {
65262306a36Sopenharmony_ci		RDBG("%s: Using readsl for %d dwords\n", __func__, len >> 2);
65362306a36Sopenharmony_ci		readsl(isp1362_hcd->data_reg, dp, len >> 2);
65462306a36Sopenharmony_ci		dp += len & ~3;
65562306a36Sopenharmony_ci		len &= 3;
65662306a36Sopenharmony_ci	}
65762306a36Sopenharmony_ci#endif
65862306a36Sopenharmony_ci	if (len >= 2) {
65962306a36Sopenharmony_ci		RDBG("%s: Using readsw for %d words\n", __func__, len >> 1);
66062306a36Sopenharmony_ci		insw((unsigned long)isp1362_hcd->data_reg, dp, len >> 1);
66162306a36Sopenharmony_ci		dp += len & ~1;
66262306a36Sopenharmony_ci		len &= 1;
66362306a36Sopenharmony_ci	}
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	BUG_ON(len & ~1);
66662306a36Sopenharmony_ci	if (len > 0) {
66762306a36Sopenharmony_ci		data = isp1362_read_data16(isp1362_hcd);
66862306a36Sopenharmony_ci		RDBG("%s: Reading trailing byte %02x to mem @ %08x\n", __func__,
66962306a36Sopenharmony_ci		     (u8)data, (u32)dp);
67062306a36Sopenharmony_ci		*dp = (u8)data;
67162306a36Sopenharmony_ci	}
67262306a36Sopenharmony_ci}
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_cistatic void isp1362_write_fifo(struct isp1362_hcd *isp1362_hcd, void *buf, u16 len)
67562306a36Sopenharmony_ci{
67662306a36Sopenharmony_ci	u8 *dp = buf;
67762306a36Sopenharmony_ci	u16 data;
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	if (!len)
68062306a36Sopenharmony_ci		return;
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci	if ((unsigned long)dp & 0x1) {
68362306a36Sopenharmony_ci		/* not aligned */
68462306a36Sopenharmony_ci		for (; len > 1; len -= 2) {
68562306a36Sopenharmony_ci			data = *dp++;
68662306a36Sopenharmony_ci			data |= *dp++ << 8;
68762306a36Sopenharmony_ci			isp1362_write_data16(isp1362_hcd, data);
68862306a36Sopenharmony_ci		}
68962306a36Sopenharmony_ci		if (len)
69062306a36Sopenharmony_ci			isp1362_write_data16(isp1362_hcd, *dp);
69162306a36Sopenharmony_ci		return;
69262306a36Sopenharmony_ci	}
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	RDBG("%s: Writing %d byte to fifo from memory @%p\n", __func__, len, buf);
69562306a36Sopenharmony_ci#if USE_32BIT
69662306a36Sopenharmony_ci	if (len >= 4) {
69762306a36Sopenharmony_ci		RDBG("%s: Using writesl for %d dwords\n", __func__, len >> 2);
69862306a36Sopenharmony_ci		writesl(isp1362_hcd->data_reg, dp, len >> 2);
69962306a36Sopenharmony_ci		dp += len & ~3;
70062306a36Sopenharmony_ci		len &= 3;
70162306a36Sopenharmony_ci	}
70262306a36Sopenharmony_ci#endif
70362306a36Sopenharmony_ci	if (len >= 2) {
70462306a36Sopenharmony_ci		RDBG("%s: Using writesw for %d words\n", __func__, len >> 1);
70562306a36Sopenharmony_ci		outsw((unsigned long)isp1362_hcd->data_reg, dp, len >> 1);
70662306a36Sopenharmony_ci		dp += len & ~1;
70762306a36Sopenharmony_ci		len &= 1;
70862306a36Sopenharmony_ci	}
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	BUG_ON(len & ~1);
71162306a36Sopenharmony_ci	if (len > 0) {
71262306a36Sopenharmony_ci		/* finally write any trailing byte; we don't need to care
71362306a36Sopenharmony_ci		 * about the high byte of the last word written
71462306a36Sopenharmony_ci		 */
71562306a36Sopenharmony_ci		data = (u16)*dp;
71662306a36Sopenharmony_ci		RDBG("%s: Sending trailing byte %02x from mem @ %08x\n", __func__,
71762306a36Sopenharmony_ci			data, (u32)dp);
71862306a36Sopenharmony_ci		isp1362_write_data16(isp1362_hcd, data);
71962306a36Sopenharmony_ci	}
72062306a36Sopenharmony_ci}
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci#define isp1362_read_reg16(d, r)		({			\
72362306a36Sopenharmony_ci	u16 __v;							\
72462306a36Sopenharmony_ci	REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_16);			\
72562306a36Sopenharmony_ci	isp1362_write_addr(d, ISP1362_REG_##r);				\
72662306a36Sopenharmony_ci	__v = isp1362_read_data16(d);					\
72762306a36Sopenharmony_ci	RDBG("%s: Read %04x from %s[%02x]\n", __func__, __v, #r,	\
72862306a36Sopenharmony_ci	     ISP1362_REG_NO(ISP1362_REG_##r));				\
72962306a36Sopenharmony_ci	__v;								\
73062306a36Sopenharmony_ci})
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_ci#define isp1362_read_reg32(d, r)		({			\
73362306a36Sopenharmony_ci	u32 __v;							\
73462306a36Sopenharmony_ci	REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_32);			\
73562306a36Sopenharmony_ci	isp1362_write_addr(d, ISP1362_REG_##r);				\
73662306a36Sopenharmony_ci	__v = isp1362_read_data32(d);					\
73762306a36Sopenharmony_ci	RDBG("%s: Read %08x from %s[%02x]\n", __func__, __v, #r,	\
73862306a36Sopenharmony_ci	     ISP1362_REG_NO(ISP1362_REG_##r));				\
73962306a36Sopenharmony_ci	__v;								\
74062306a36Sopenharmony_ci})
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci#define isp1362_write_reg16(d, r, v)	{					\
74362306a36Sopenharmony_ci	REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_16);				\
74462306a36Sopenharmony_ci	isp1362_write_addr(d, (ISP1362_REG_##r) | ISP1362_REG_WRITE_OFFSET);	\
74562306a36Sopenharmony_ci	isp1362_write_data16(d, (u16)(v));					\
74662306a36Sopenharmony_ci	RDBG("%s: Wrote %04x to %s[%02x]\n", __func__, (u16)(v), #r,	\
74762306a36Sopenharmony_ci	     ISP1362_REG_NO(ISP1362_REG_##r));					\
74862306a36Sopenharmony_ci}
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci#define isp1362_write_reg32(d, r, v)	{					\
75162306a36Sopenharmony_ci	REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_32);				\
75262306a36Sopenharmony_ci	isp1362_write_addr(d, (ISP1362_REG_##r) | ISP1362_REG_WRITE_OFFSET);	\
75362306a36Sopenharmony_ci	isp1362_write_data32(d, (u32)(v));					\
75462306a36Sopenharmony_ci	RDBG("%s: Wrote %08x to %s[%02x]\n", __func__, (u32)(v), #r,	\
75562306a36Sopenharmony_ci	     ISP1362_REG_NO(ISP1362_REG_##r));					\
75662306a36Sopenharmony_ci}
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci#define isp1362_set_mask16(d, r, m) {			\
75962306a36Sopenharmony_ci	u16 __v;					\
76062306a36Sopenharmony_ci	__v = isp1362_read_reg16(d, r);			\
76162306a36Sopenharmony_ci	if ((__v | m) != __v)				\
76262306a36Sopenharmony_ci		isp1362_write_reg16(d, r, __v | m);	\
76362306a36Sopenharmony_ci}
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci#define isp1362_clr_mask16(d, r, m) {			\
76662306a36Sopenharmony_ci	u16 __v;					\
76762306a36Sopenharmony_ci	__v = isp1362_read_reg16(d, r);			\
76862306a36Sopenharmony_ci	if ((__v & ~m) != __v)			\
76962306a36Sopenharmony_ci		isp1362_write_reg16(d, r, __v & ~m);	\
77062306a36Sopenharmony_ci}
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci#define isp1362_set_mask32(d, r, m) {			\
77362306a36Sopenharmony_ci	u32 __v;					\
77462306a36Sopenharmony_ci	__v = isp1362_read_reg32(d, r);			\
77562306a36Sopenharmony_ci	if ((__v | m) != __v)				\
77662306a36Sopenharmony_ci		isp1362_write_reg32(d, r, __v | m);	\
77762306a36Sopenharmony_ci}
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_ci#define isp1362_clr_mask32(d, r, m) {			\
78062306a36Sopenharmony_ci	u32 __v;					\
78162306a36Sopenharmony_ci	__v = isp1362_read_reg32(d, r);			\
78262306a36Sopenharmony_ci	if ((__v & ~m) != __v)			\
78362306a36Sopenharmony_ci		isp1362_write_reg32(d, r, __v & ~m);	\
78462306a36Sopenharmony_ci}
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci#define isp1362_show_reg(d, r) {								\
78762306a36Sopenharmony_ci	if ((ISP1362_REG_##r & REG_WIDTH_MASK) == REG_WIDTH_32)			\
78862306a36Sopenharmony_ci		DBG(0, "%-12s[%02x]: %08x\n", #r,					\
78962306a36Sopenharmony_ci			ISP1362_REG_NO(ISP1362_REG_##r), isp1362_read_reg32(d, r));	\
79062306a36Sopenharmony_ci	else									\
79162306a36Sopenharmony_ci		DBG(0, "%-12s[%02x]:     %04x\n", #r,					\
79262306a36Sopenharmony_ci			ISP1362_REG_NO(ISP1362_REG_##r), isp1362_read_reg16(d, r));	\
79362306a36Sopenharmony_ci}
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_cistatic void isp1362_write_diraddr(struct isp1362_hcd *isp1362_hcd, u16 offset, u16 len)
79662306a36Sopenharmony_ci{
79762306a36Sopenharmony_ci	len = (len + 1) & ~1;
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci	isp1362_clr_mask16(isp1362_hcd, HCDMACFG, HCDMACFG_CTR_ENABLE);
80062306a36Sopenharmony_ci	isp1362_write_reg32(isp1362_hcd, HCDIRADDR,
80162306a36Sopenharmony_ci			    HCDIRADDR_ADDR(offset) | HCDIRADDR_COUNT(len));
80262306a36Sopenharmony_ci}
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_cistatic void isp1362_read_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16 offset, int len)
80562306a36Sopenharmony_ci{
80662306a36Sopenharmony_ci	isp1362_write_diraddr(isp1362_hcd, offset, len);
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_ci	DBG(3, "%s: Reading %d byte from buffer @%04x to memory @ %p\n",
80962306a36Sopenharmony_ci	    __func__, len, offset, buf);
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_ci	isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT);
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_ci	isp1362_write_addr(isp1362_hcd, ISP1362_REG_HCDIRDATA);
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci	isp1362_read_fifo(isp1362_hcd, buf, len);
81662306a36Sopenharmony_ci	isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT);
81762306a36Sopenharmony_ci}
81862306a36Sopenharmony_ci
81962306a36Sopenharmony_cistatic void isp1362_write_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16 offset, int len)
82062306a36Sopenharmony_ci{
82162306a36Sopenharmony_ci	isp1362_write_diraddr(isp1362_hcd, offset, len);
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci	DBG(3, "%s: Writing %d byte to buffer @%04x from memory @ %p\n",
82462306a36Sopenharmony_ci	    __func__, len, offset, buf);
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ci	isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT);
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci	isp1362_write_addr(isp1362_hcd, ISP1362_REG_HCDIRDATA | ISP1362_REG_WRITE_OFFSET);
82962306a36Sopenharmony_ci	isp1362_write_fifo(isp1362_hcd, buf, len);
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci	isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT);
83262306a36Sopenharmony_ci}
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_cistatic void __attribute__((unused)) dump_data(char *buf, int len)
83562306a36Sopenharmony_ci{
83662306a36Sopenharmony_ci	if (dbg_level > 0) {
83762306a36Sopenharmony_ci		int k;
83862306a36Sopenharmony_ci		int lf = 0;
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_ci		for (k = 0; k < len; ++k) {
84162306a36Sopenharmony_ci			if (!lf)
84262306a36Sopenharmony_ci				DBG(0, "%04x:", k);
84362306a36Sopenharmony_ci			printk(" %02x", ((u8 *) buf)[k]);
84462306a36Sopenharmony_ci			lf = 1;
84562306a36Sopenharmony_ci			if (!k)
84662306a36Sopenharmony_ci				continue;
84762306a36Sopenharmony_ci			if (k % 16 == 15) {
84862306a36Sopenharmony_ci				printk("\n");
84962306a36Sopenharmony_ci				lf = 0;
85062306a36Sopenharmony_ci				continue;
85162306a36Sopenharmony_ci			}
85262306a36Sopenharmony_ci			if (k % 8 == 7)
85362306a36Sopenharmony_ci				printk(" ");
85462306a36Sopenharmony_ci			if (k % 4 == 3)
85562306a36Sopenharmony_ci				printk(" ");
85662306a36Sopenharmony_ci		}
85762306a36Sopenharmony_ci		if (lf)
85862306a36Sopenharmony_ci			printk("\n");
85962306a36Sopenharmony_ci	}
86062306a36Sopenharmony_ci}
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci#if defined(PTD_TRACE)
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_cistatic void dump_ptd(struct ptd *ptd)
86562306a36Sopenharmony_ci{
86662306a36Sopenharmony_ci	DBG(0, "EP %p: CC=%x EP=%d DIR=%x CNT=%d LEN=%d MPS=%d TGL=%x ACT=%x FA=%d SPD=%x SF=%x PR=%x LST=%x\n",
86762306a36Sopenharmony_ci	    container_of(ptd, struct isp1362_ep, ptd),
86862306a36Sopenharmony_ci	    PTD_GET_CC(ptd), PTD_GET_EP(ptd), PTD_GET_DIR(ptd),
86962306a36Sopenharmony_ci	    PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
87062306a36Sopenharmony_ci	    PTD_GET_TOGGLE(ptd), PTD_GET_ACTIVE(ptd), PTD_GET_FA(ptd),
87162306a36Sopenharmony_ci	    PTD_GET_SPD(ptd), PTD_GET_SF_INT(ptd), PTD_GET_PR(ptd), PTD_GET_LAST(ptd));
87262306a36Sopenharmony_ci	DBG(0, "  %04x %04x %04x %04x\n", ptd->count, ptd->mps, ptd->len, ptd->faddr);
87362306a36Sopenharmony_ci}
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_cistatic void dump_ptd_out_data(struct ptd *ptd, u8 *buf)
87662306a36Sopenharmony_ci{
87762306a36Sopenharmony_ci	if (dbg_level > 0) {
87862306a36Sopenharmony_ci		if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) {
87962306a36Sopenharmony_ci			DBG(0, "--out->\n");
88062306a36Sopenharmony_ci			dump_data(buf, PTD_GET_LEN(ptd));
88162306a36Sopenharmony_ci		}
88262306a36Sopenharmony_ci	}
88362306a36Sopenharmony_ci}
88462306a36Sopenharmony_ci
88562306a36Sopenharmony_cistatic void dump_ptd_in_data(struct ptd *ptd, u8 *buf)
88662306a36Sopenharmony_ci{
88762306a36Sopenharmony_ci	if (dbg_level > 0) {
88862306a36Sopenharmony_ci		if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) {
88962306a36Sopenharmony_ci			DBG(0, "<--in--\n");
89062306a36Sopenharmony_ci			dump_data(buf, PTD_GET_COUNT(ptd));
89162306a36Sopenharmony_ci		}
89262306a36Sopenharmony_ci		DBG(0, "-----\n");
89362306a36Sopenharmony_ci	}
89462306a36Sopenharmony_ci}
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_cistatic void dump_ptd_queue(struct isp1362_ep_queue *epq)
89762306a36Sopenharmony_ci{
89862306a36Sopenharmony_ci	struct isp1362_ep *ep;
89962306a36Sopenharmony_ci	int dbg = dbg_level;
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci	dbg_level = 1;
90262306a36Sopenharmony_ci	list_for_each_entry(ep, &epq->active, active) {
90362306a36Sopenharmony_ci		dump_ptd(&ep->ptd);
90462306a36Sopenharmony_ci		dump_data(ep->data, ep->length);
90562306a36Sopenharmony_ci	}
90662306a36Sopenharmony_ci	dbg_level = dbg;
90762306a36Sopenharmony_ci}
90862306a36Sopenharmony_ci#else
90962306a36Sopenharmony_ci#define dump_ptd(ptd)			do {} while (0)
91062306a36Sopenharmony_ci#define dump_ptd_in_data(ptd, buf)	do {} while (0)
91162306a36Sopenharmony_ci#define dump_ptd_out_data(ptd, buf)	do {} while (0)
91262306a36Sopenharmony_ci#define dump_ptd_data(ptd, buf)		do {} while (0)
91362306a36Sopenharmony_ci#define dump_ptd_queue(epq)		do {} while (0)
91462306a36Sopenharmony_ci#endif
915