| xj | b04a402 | 2021-11-25 15:01:52 +0800 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 
 | 2 | /* | 
 | 3 |  * ISP1362 HCD (Host Controller Driver) for USB. | 
 | 4 |  * | 
 | 5 |  * COPYRIGHT (C) by L. Wassmann <LW@KARO-electronics.de> | 
 | 6 |  */ | 
 | 7 |  | 
 | 8 | /* ------------------------------------------------------------------------- */ | 
 | 9 |  | 
 | 10 | #define MAX_ROOT_PORTS		2 | 
 | 11 |  | 
 | 12 | #define USE_32BIT		0 | 
 | 13 |  | 
 | 14 | /* These options are mutually eclusive */ | 
 | 15 | #define USE_PLATFORM_DELAY	0 | 
 | 16 | #define USE_NDELAY		0 | 
 | 17 |  | 
 | 18 | #define DUMMY_DELAY_ACCESS do {} while (0) | 
 | 19 |  | 
 | 20 | /* ------------------------------------------------------------------------- */ | 
 | 21 |  | 
 | 22 | #define USB_RESET_WIDTH			50 | 
 | 23 | #define MAX_XFER_SIZE			1023 | 
 | 24 |  | 
 | 25 | /* Buffer sizes */ | 
 | 26 | #define ISP1362_BUF_SIZE		4096 | 
 | 27 | #define ISP1362_ISTL_BUFSIZE		512 | 
 | 28 | #define ISP1362_INTL_BLKSIZE		64 | 
 | 29 | #define ISP1362_INTL_BUFFERS		16 | 
 | 30 | #define ISP1362_ATL_BLKSIZE		64 | 
 | 31 |  | 
 | 32 | #define ISP1362_REG_WRITE_OFFSET	0x80 | 
 | 33 |  | 
 | 34 | #define REG_WIDTH_16			0x000 | 
 | 35 | #define REG_WIDTH_32			0x100 | 
 | 36 | #define REG_WIDTH_MASK			0x100 | 
 | 37 | #define REG_NO_MASK			0x0ff | 
 | 38 |  | 
 | 39 | #ifdef ISP1362_DEBUG | 
 | 40 | typedef const unsigned int isp1362_reg_t; | 
 | 41 |  | 
 | 42 | #define REG_ACCESS_R			0x200 | 
 | 43 | #define REG_ACCESS_W			0x400 | 
 | 44 | #define REG_ACCESS_RW			0x600 | 
 | 45 | #define REG_ACCESS_MASK			0x600 | 
 | 46 |  | 
 | 47 | #define ISP1362_REG_NO(r)		((r) & REG_NO_MASK) | 
 | 48 |  | 
 | 49 | #define ISP1362_REG(name, addr, width, rw) \ | 
 | 50 | static isp1362_reg_t ISP1362_REG_##name = ((addr) | (width) | (rw)) | 
 | 51 |  | 
 | 52 | #define REG_ACCESS_TEST(r)   BUG_ON(((r) & ISP1362_REG_WRITE_OFFSET) && !((r) & REG_ACCESS_W)) | 
 | 53 | #define REG_WIDTH_TEST(r, w) BUG_ON(((r) & REG_WIDTH_MASK) != (w)) | 
 | 54 | #else | 
 | 55 | typedef const unsigned char isp1362_reg_t; | 
 | 56 | #define ISP1362_REG_NO(r)		(r) | 
 | 57 |  | 
 | 58 | #define ISP1362_REG(name, addr, width, rw) \ | 
 | 59 | static isp1362_reg_t ISP1362_REG_##name = addr | 
 | 60 |  | 
 | 61 | #define REG_ACCESS_TEST(r)		do {} while (0) | 
 | 62 | #define REG_WIDTH_TEST(r, w)		do {} while (0) | 
 | 63 | #endif | 
 | 64 |  | 
 | 65 | /* OHCI compatible registers */ | 
 | 66 | /* | 
 | 67 |  * Note: Some of the ISP1362 'OHCI' registers implement only | 
 | 68 |  * a subset of the bits defined in the OHCI spec. | 
 | 69 |  * | 
 | 70 |  * Bitmasks for the individual bits of these registers are defined in "ohci.h" | 
 | 71 |  */ | 
 | 72 | ISP1362_REG(HCREVISION,	0x00,	REG_WIDTH_32,	REG_ACCESS_R); | 
 | 73 | ISP1362_REG(HCCONTROL,	0x01,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 74 | ISP1362_REG(HCCMDSTAT,	0x02,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 75 | ISP1362_REG(HCINTSTAT,	0x03,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 76 | ISP1362_REG(HCINTENB,	0x04,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 77 | ISP1362_REG(HCINTDIS,	0x05,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 78 | ISP1362_REG(HCFMINTVL,	0x0d,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 79 | ISP1362_REG(HCFMREM,	0x0e,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 80 | ISP1362_REG(HCFMNUM,	0x0f,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 81 | ISP1362_REG(HCLSTHRESH,	0x11,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 82 | ISP1362_REG(HCRHDESCA,	0x12,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 83 | ISP1362_REG(HCRHDESCB,	0x13,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 84 | ISP1362_REG(HCRHSTATUS,	0x14,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 85 | ISP1362_REG(HCRHPORT1,	0x15,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 86 | ISP1362_REG(HCRHPORT2,	0x16,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 87 |  | 
 | 88 | /* Philips ISP1362 specific registers */ | 
 | 89 | ISP1362_REG(HCHWCFG,	0x20,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 90 | #define HCHWCFG_DISABLE_SUSPEND	(1 << 15) | 
 | 91 | #define HCHWCFG_GLOBAL_PWRDOWN	(1 << 14) | 
 | 92 | #define HCHWCFG_PULLDOWN_DS2	(1 << 13) | 
 | 93 | #define HCHWCFG_PULLDOWN_DS1	(1 << 12) | 
 | 94 | #define HCHWCFG_CLKNOTSTOP	(1 << 11) | 
 | 95 | #define HCHWCFG_ANALOG_OC	(1 << 10) | 
 | 96 | #define HCHWCFG_ONEINT		(1 << 9) | 
 | 97 | #define HCHWCFG_DACK_MODE	(1 << 8) | 
 | 98 | #define HCHWCFG_ONEDMA		(1 << 7) | 
 | 99 | #define HCHWCFG_DACK_POL	(1 << 6) | 
 | 100 | #define HCHWCFG_DREQ_POL	(1 << 5) | 
 | 101 | #define HCHWCFG_DBWIDTH_MASK	(0x03 << 3) | 
 | 102 | #define HCHWCFG_DBWIDTH(n)	(((n) << 3) & HCHWCFG_DBWIDTH_MASK) | 
 | 103 | #define HCHWCFG_INT_POL		(1 << 2) | 
 | 104 | #define HCHWCFG_INT_TRIGGER	(1 << 1) | 
 | 105 | #define HCHWCFG_INT_ENABLE	(1 << 0) | 
 | 106 |  | 
 | 107 | ISP1362_REG(HCDMACFG,	0x21,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 108 | #define HCDMACFG_CTR_ENABLE	(1 << 7) | 
 | 109 | #define HCDMACFG_BURST_LEN_MASK	(0x03 << 5) | 
 | 110 | #define HCDMACFG_BURST_LEN(n)	(((n) << 5) & HCDMACFG_BURST_LEN_MASK) | 
 | 111 | #define HCDMACFG_BURST_LEN_1	HCDMACFG_BURST_LEN(0) | 
 | 112 | #define HCDMACFG_BURST_LEN_4	HCDMACFG_BURST_LEN(1) | 
 | 113 | #define HCDMACFG_BURST_LEN_8	HCDMACFG_BURST_LEN(2) | 
 | 114 | #define HCDMACFG_DMA_ENABLE	(1 << 4) | 
 | 115 | #define HCDMACFG_BUF_TYPE_MASK	(0x07 << 1) | 
 | 116 | #define HCDMACFG_BUF_TYPE(n)	(((n) << 1) & HCDMACFG_BUF_TYPE_MASK) | 
 | 117 | #define HCDMACFG_BUF_ISTL0	HCDMACFG_BUF_TYPE(0) | 
 | 118 | #define HCDMACFG_BUF_ISTL1	HCDMACFG_BUF_TYPE(1) | 
 | 119 | #define HCDMACFG_BUF_INTL	HCDMACFG_BUF_TYPE(2) | 
 | 120 | #define HCDMACFG_BUF_ATL	HCDMACFG_BUF_TYPE(3) | 
 | 121 | #define HCDMACFG_BUF_DIRECT	HCDMACFG_BUF_TYPE(4) | 
 | 122 | #define HCDMACFG_DMA_RW_SELECT	(1 << 0) | 
 | 123 |  | 
 | 124 | ISP1362_REG(HCXFERCTR,	0x22,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 125 |  | 
 | 126 | ISP1362_REG(HCuPINT,	0x24,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 127 | #define HCuPINT_SOF		(1 << 0) | 
 | 128 | #define HCuPINT_ISTL0		(1 << 1) | 
 | 129 | #define HCuPINT_ISTL1		(1 << 2) | 
 | 130 | #define HCuPINT_EOT		(1 << 3) | 
 | 131 | #define HCuPINT_OPR		(1 << 4) | 
 | 132 | #define HCuPINT_SUSP		(1 << 5) | 
 | 133 | #define HCuPINT_CLKRDY		(1 << 6) | 
 | 134 | #define HCuPINT_INTL		(1 << 7) | 
 | 135 | #define HCuPINT_ATL		(1 << 8) | 
 | 136 | #define HCuPINT_OTG		(1 << 9) | 
 | 137 |  | 
 | 138 | ISP1362_REG(HCuPINTENB,	0x25,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 139 | /* same bit definitions apply as for HCuPINT */ | 
 | 140 |  | 
 | 141 | ISP1362_REG(HCCHIPID,	0x27,	REG_WIDTH_16,	REG_ACCESS_R); | 
 | 142 | #define HCCHIPID_MASK		0xff00 | 
 | 143 | #define HCCHIPID_MAGIC		0x3600 | 
 | 144 |  | 
 | 145 | ISP1362_REG(HCSCRATCH,	0x28,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 146 |  | 
 | 147 | ISP1362_REG(HCSWRES,	0x29,	REG_WIDTH_16,	REG_ACCESS_W); | 
 | 148 | #define HCSWRES_MAGIC		0x00f6 | 
 | 149 |  | 
 | 150 | ISP1362_REG(HCBUFSTAT,	0x2c,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 151 | #define HCBUFSTAT_ISTL0_FULL	(1 << 0) | 
 | 152 | #define HCBUFSTAT_ISTL1_FULL	(1 << 1) | 
 | 153 | #define HCBUFSTAT_INTL_ACTIVE	(1 << 2) | 
 | 154 | #define HCBUFSTAT_ATL_ACTIVE	(1 << 3) | 
 | 155 | #define HCBUFSTAT_RESET_HWPP	(1 << 4) | 
 | 156 | #define HCBUFSTAT_ISTL0_ACTIVE	(1 << 5) | 
 | 157 | #define HCBUFSTAT_ISTL1_ACTIVE	(1 << 6) | 
 | 158 | #define HCBUFSTAT_ISTL0_DONE	(1 << 8) | 
 | 159 | #define HCBUFSTAT_ISTL1_DONE	(1 << 9) | 
 | 160 | #define HCBUFSTAT_PAIRED_PTDPP	(1 << 10) | 
 | 161 |  | 
 | 162 | ISP1362_REG(HCDIRADDR,	0x32,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 163 | #define HCDIRADDR_ADDR_MASK	0x0000ffff | 
 | 164 | #define HCDIRADDR_ADDR(n)	(((n) << 0) & HCDIRADDR_ADDR_MASK) | 
 | 165 | #define HCDIRADDR_COUNT_MASK	0xffff0000 | 
 | 166 | #define HCDIRADDR_COUNT(n)	(((n) << 16) & HCDIRADDR_COUNT_MASK) | 
 | 167 | ISP1362_REG(HCDIRDATA,	0x45,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 168 |  | 
 | 169 | ISP1362_REG(HCISTLBUFSZ, 0x30,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 170 | ISP1362_REG(HCISTL0PORT, 0x40,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 171 | ISP1362_REG(HCISTL1PORT, 0x42,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 172 | ISP1362_REG(HCISTLRATE,	0x47,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 173 |  | 
 | 174 | ISP1362_REG(HCINTLBUFSZ, 0x33,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 175 | ISP1362_REG(HCINTLPORT,	0x43,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 176 | ISP1362_REG(HCINTLBLKSZ, 0x53,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 177 | ISP1362_REG(HCINTLDONE,	0x17,	REG_WIDTH_32,	REG_ACCESS_R); | 
 | 178 | ISP1362_REG(HCINTLSKIP,	0x18,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 179 | ISP1362_REG(HCINTLLAST,	0x19,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 180 | ISP1362_REG(HCINTLCURR,	0x1a,	REG_WIDTH_16,	REG_ACCESS_R); | 
 | 181 |  | 
 | 182 | ISP1362_REG(HCATLBUFSZ, 0x34,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 183 | ISP1362_REG(HCATLPORT,	0x44,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 184 | ISP1362_REG(HCATLBLKSZ, 0x54,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 185 | ISP1362_REG(HCATLDONE,	0x1b,	REG_WIDTH_32,	REG_ACCESS_R); | 
 | 186 | ISP1362_REG(HCATLSKIP,	0x1c,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 187 | ISP1362_REG(HCATLLAST,	0x1d,	REG_WIDTH_32,	REG_ACCESS_RW); | 
 | 188 | ISP1362_REG(HCATLCURR,	0x1e,	REG_WIDTH_16,	REG_ACCESS_R); | 
 | 189 |  | 
 | 190 | ISP1362_REG(HCATLDTC,	0x51,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 191 | ISP1362_REG(HCATLDTCTO,	0x52,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 192 |  | 
 | 193 |  | 
 | 194 | ISP1362_REG(OTGCONTROL,	0x62,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 195 | ISP1362_REG(OTGSTATUS,	0x67,	REG_WIDTH_16,	REG_ACCESS_R); | 
 | 196 | ISP1362_REG(OTGINT,	0x68,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 197 | ISP1362_REG(OTGINTENB,	0x69,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 198 | ISP1362_REG(OTGTIMER,	0x6A,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 199 | ISP1362_REG(OTGALTTMR,	0x6C,	REG_WIDTH_16,	REG_ACCESS_RW); | 
 | 200 |  | 
 | 201 | /* Philips transfer descriptor, cpu-endian */ | 
 | 202 | struct ptd { | 
 | 203 | 	u16 count; | 
 | 204 | #define	PTD_COUNT_MSK	(0x3ff << 0) | 
 | 205 | #define	PTD_TOGGLE_MSK	(1 << 10) | 
 | 206 | #define	PTD_ACTIVE_MSK	(1 << 11) | 
 | 207 | #define	PTD_CC_MSK	(0xf << 12) | 
 | 208 | 	u16 mps; | 
 | 209 | #define	PTD_MPS_MSK	(0x3ff << 0) | 
 | 210 | #define	PTD_SPD_MSK	(1 << 10) | 
 | 211 | #define	PTD_LAST_MSK	(1 << 11) | 
 | 212 | #define	PTD_EP_MSK	(0xf << 12) | 
 | 213 | 	u16 len; | 
 | 214 | #define	PTD_LEN_MSK	(0x3ff << 0) | 
 | 215 | #define	PTD_DIR_MSK	(3 << 10) | 
 | 216 | #define	PTD_DIR_SETUP	(0) | 
 | 217 | #define	PTD_DIR_OUT	(1) | 
 | 218 | #define	PTD_DIR_IN	(2) | 
 | 219 | 	u16 faddr; | 
 | 220 | #define	PTD_FA_MSK	(0x7f << 0) | 
 | 221 | /* PTD Byte 7: [StartingFrame (if ISO PTD) | StartingFrame[0..4], PollingRate[0..2] (if INT PTD)] */ | 
 | 222 | #define PTD_SF_ISO_MSK	(0xff << 8) | 
 | 223 | #define PTD_SF_INT_MSK	(0x1f << 8) | 
 | 224 | #define PTD_PR_MSK	(0x07 << 13) | 
 | 225 | } __attribute__ ((packed, aligned(2))); | 
 | 226 | #define PTD_HEADER_SIZE sizeof(struct ptd) | 
 | 227 |  | 
 | 228 | /* ------------------------------------------------------------------------- */ | 
 | 229 | /* Copied from ohci.h: */ | 
 | 230 | /* | 
 | 231 |  * Hardware transfer status codes -- CC from PTD | 
 | 232 |  */ | 
 | 233 | #define PTD_CC_NOERROR      0x00 | 
 | 234 | #define PTD_CC_CRC          0x01 | 
 | 235 | #define PTD_CC_BITSTUFFING  0x02 | 
 | 236 | #define PTD_CC_DATATOGGLEM  0x03 | 
 | 237 | #define PTD_CC_STALL        0x04 | 
 | 238 | #define PTD_DEVNOTRESP      0x05 | 
 | 239 | #define PTD_PIDCHECKFAIL    0x06 | 
 | 240 | #define PTD_UNEXPECTEDPID   0x07 | 
 | 241 | #define PTD_DATAOVERRUN     0x08 | 
 | 242 | #define PTD_DATAUNDERRUN    0x09 | 
 | 243 |     /* 0x0A, 0x0B reserved for hardware */ | 
 | 244 | #define PTD_BUFFEROVERRUN   0x0C | 
 | 245 | #define PTD_BUFFERUNDERRUN  0x0D | 
 | 246 |     /* 0x0E, 0x0F reserved for HCD */ | 
 | 247 | #define PTD_NOTACCESSED     0x0F | 
 | 248 |  | 
 | 249 |  | 
 | 250 | /* map OHCI TD status codes (CC) to errno values */ | 
 | 251 | static const int cc_to_error[16] = { | 
 | 252 | 	/* No  Error  */               0, | 
 | 253 | 	/* CRC Error  */               -EILSEQ, | 
 | 254 | 	/* Bit Stuff  */               -EPROTO, | 
 | 255 | 	/* Data Togg  */               -EILSEQ, | 
 | 256 | 	/* Stall      */               -EPIPE, | 
 | 257 | 	/* DevNotResp */               -ETIMEDOUT, | 
 | 258 | 	/* PIDCheck   */               -EPROTO, | 
 | 259 | 	/* UnExpPID   */               -EPROTO, | 
 | 260 | 	/* DataOver   */               -EOVERFLOW, | 
 | 261 | 	/* DataUnder  */               -EREMOTEIO, | 
 | 262 | 	/* (for hw)   */               -EIO, | 
 | 263 | 	/* (for hw)   */               -EIO, | 
 | 264 | 	/* BufferOver */               -ECOMM, | 
 | 265 | 	/* BuffUnder  */               -ENOSR, | 
 | 266 | 	/* (for HCD)  */               -EALREADY, | 
 | 267 | 	/* (for HCD)  */               -EALREADY | 
 | 268 | }; | 
 | 269 |  | 
 | 270 |  | 
 | 271 | /* | 
 | 272 |  * HcControl (control) register masks | 
 | 273 |  */ | 
 | 274 | #define OHCI_CTRL_HCFS	(3 << 6)	/* host controller functional state */ | 
 | 275 | #define OHCI_CTRL_RWC	(1 << 9)	/* remote wakeup connected */ | 
 | 276 | #define OHCI_CTRL_RWE	(1 << 10)	/* remote wakeup enable */ | 
 | 277 |  | 
 | 278 | /* pre-shifted values for HCFS */ | 
 | 279 | #	define OHCI_USB_RESET	(0 << 6) | 
 | 280 | #	define OHCI_USB_RESUME	(1 << 6) | 
 | 281 | #	define OHCI_USB_OPER	(2 << 6) | 
 | 282 | #	define OHCI_USB_SUSPEND	(3 << 6) | 
 | 283 |  | 
 | 284 | /* | 
 | 285 |  * HcCommandStatus (cmdstatus) register masks | 
 | 286 |  */ | 
 | 287 | #define OHCI_HCR	(1 << 0)	/* host controller reset */ | 
 | 288 | #define OHCI_SOC  	(3 << 16)	/* scheduling overrun count */ | 
 | 289 |  | 
 | 290 | /* | 
 | 291 |  * masks used with interrupt registers: | 
 | 292 |  * HcInterruptStatus (intrstatus) | 
 | 293 |  * HcInterruptEnable (intrenable) | 
 | 294 |  * HcInterruptDisable (intrdisable) | 
 | 295 |  */ | 
 | 296 | #define OHCI_INTR_SO	(1 << 0)	/* scheduling overrun */ | 
 | 297 | #define OHCI_INTR_WDH	(1 << 1)	/* writeback of done_head */ | 
 | 298 | #define OHCI_INTR_SF	(1 << 2)	/* start frame */ | 
 | 299 | #define OHCI_INTR_RD	(1 << 3)	/* resume detect */ | 
 | 300 | #define OHCI_INTR_UE	(1 << 4)	/* unrecoverable error */ | 
 | 301 | #define OHCI_INTR_FNO	(1 << 5)	/* frame number overflow */ | 
 | 302 | #define OHCI_INTR_RHSC	(1 << 6)	/* root hub status change */ | 
 | 303 | #define OHCI_INTR_OC	(1 << 30)	/* ownership change */ | 
 | 304 | #define OHCI_INTR_MIE	(1 << 31)	/* master interrupt enable */ | 
 | 305 |  | 
 | 306 | /* roothub.portstatus [i] bits */ | 
 | 307 | #define RH_PS_CCS            0x00000001   	/* current connect status */ | 
 | 308 | #define RH_PS_PES            0x00000002   	/* port enable status*/ | 
 | 309 | #define RH_PS_PSS            0x00000004   	/* port suspend status */ | 
 | 310 | #define RH_PS_POCI           0x00000008   	/* port over current indicator */ | 
 | 311 | #define RH_PS_PRS            0x00000010  	/* port reset status */ | 
 | 312 | #define RH_PS_PPS            0x00000100   	/* port power status */ | 
 | 313 | #define RH_PS_LSDA           0x00000200    	/* low speed device attached */ | 
 | 314 | #define RH_PS_CSC            0x00010000 	/* connect status change */ | 
 | 315 | #define RH_PS_PESC           0x00020000   	/* port enable status change */ | 
 | 316 | #define RH_PS_PSSC           0x00040000    	/* port suspend status change */ | 
 | 317 | #define RH_PS_OCIC           0x00080000    	/* over current indicator change */ | 
 | 318 | #define RH_PS_PRSC           0x00100000   	/* port reset status change */ | 
 | 319 |  | 
 | 320 | /* roothub.status bits */ | 
 | 321 | #define RH_HS_LPS	     0x00000001		/* local power status */ | 
 | 322 | #define RH_HS_OCI	     0x00000002		/* over current indicator */ | 
 | 323 | #define RH_HS_DRWE	     0x00008000		/* device remote wakeup enable */ | 
 | 324 | #define RH_HS_LPSC	     0x00010000		/* local power status change */ | 
 | 325 | #define RH_HS_OCIC	     0x00020000		/* over current indicator change */ | 
 | 326 | #define RH_HS_CRWE	     0x80000000		/* clear remote wakeup enable */ | 
 | 327 |  | 
 | 328 | /* roothub.b masks */ | 
 | 329 | #define RH_B_DR		0x0000ffff		/* device removable flags */ | 
 | 330 | #define RH_B_PPCM	0xffff0000		/* port power control mask */ | 
 | 331 |  | 
 | 332 | /* roothub.a masks */ | 
 | 333 | #define	RH_A_NDP	(0xff << 0)		/* number of downstream ports */ | 
 | 334 | #define	RH_A_PSM	(1 << 8)		/* power switching mode */ | 
 | 335 | #define	RH_A_NPS	(1 << 9)		/* no power switching */ | 
 | 336 | #define	RH_A_DT		(1 << 10)		/* device type (mbz) */ | 
 | 337 | #define	RH_A_OCPM	(1 << 11)		/* over current protection mode */ | 
 | 338 | #define	RH_A_NOCP	(1 << 12)		/* no over current protection */ | 
 | 339 | #define	RH_A_POTPGT	(0xff << 24)		/* power on to power good time */ | 
 | 340 |  | 
 | 341 | #define	FI			0x2edf		/* 12000 bits per frame (-1) */ | 
 | 342 | #define	FSMP(fi) 		(0x7fff & ((6 * ((fi) - 210)) / 7)) | 
 | 343 | #define LSTHRESH		0x628		/* lowspeed bit threshold */ | 
 | 344 |  | 
 | 345 | /* ------------------------------------------------------------------------- */ | 
 | 346 |  | 
 | 347 | /* PTD accessor macros. */ | 
 | 348 | #define PTD_GET_COUNT(p)	(((p)->count & PTD_COUNT_MSK) >> 0) | 
 | 349 | #define PTD_COUNT(v)		(((v) << 0) & PTD_COUNT_MSK) | 
 | 350 | #define PTD_GET_TOGGLE(p)	(((p)->count & PTD_TOGGLE_MSK) >> 10) | 
 | 351 | #define PTD_TOGGLE(v)		(((v) << 10) & PTD_TOGGLE_MSK) | 
 | 352 | #define PTD_GET_ACTIVE(p)	(((p)->count & PTD_ACTIVE_MSK) >> 11) | 
 | 353 | #define PTD_ACTIVE(v)		(((v) << 11) & PTD_ACTIVE_MSK) | 
 | 354 | #define PTD_GET_CC(p)		(((p)->count & PTD_CC_MSK) >> 12) | 
 | 355 | #define PTD_CC(v)		(((v) << 12) & PTD_CC_MSK) | 
 | 356 | #define PTD_GET_MPS(p)		(((p)->mps & PTD_MPS_MSK) >> 0) | 
 | 357 | #define PTD_MPS(v)		(((v) << 0) & PTD_MPS_MSK) | 
 | 358 | #define PTD_GET_SPD(p)		(((p)->mps & PTD_SPD_MSK) >> 10) | 
 | 359 | #define PTD_SPD(v)		(((v) << 10) & PTD_SPD_MSK) | 
 | 360 | #define PTD_GET_LAST(p)		(((p)->mps & PTD_LAST_MSK) >> 11) | 
 | 361 | #define PTD_LAST(v)		(((v) << 11) & PTD_LAST_MSK) | 
 | 362 | #define PTD_GET_EP(p)		(((p)->mps & PTD_EP_MSK) >> 12) | 
 | 363 | #define PTD_EP(v)		(((v) << 12) & PTD_EP_MSK) | 
 | 364 | #define PTD_GET_LEN(p)		(((p)->len & PTD_LEN_MSK) >> 0) | 
 | 365 | #define PTD_LEN(v)		(((v) << 0) & PTD_LEN_MSK) | 
 | 366 | #define PTD_GET_DIR(p)		(((p)->len & PTD_DIR_MSK) >> 10) | 
 | 367 | #define PTD_DIR(v)		(((v) << 10) & PTD_DIR_MSK) | 
 | 368 | #define PTD_GET_FA(p)		(((p)->faddr & PTD_FA_MSK) >> 0) | 
 | 369 | #define PTD_FA(v)		(((v) << 0) & PTD_FA_MSK) | 
 | 370 | #define PTD_GET_SF_INT(p)	(((p)->faddr & PTD_SF_INT_MSK) >> 8) | 
 | 371 | #define PTD_SF_INT(v)		(((v) << 8) & PTD_SF_INT_MSK) | 
 | 372 | #define PTD_GET_SF_ISO(p)	(((p)->faddr & PTD_SF_ISO_MSK) >> 8) | 
 | 373 | #define PTD_SF_ISO(v)		(((v) << 8) & PTD_SF_ISO_MSK) | 
 | 374 | #define PTD_GET_PR(p)		(((p)->faddr & PTD_PR_MSK) >> 13) | 
 | 375 | #define PTD_PR(v)		(((v) << 13) & PTD_PR_MSK) | 
 | 376 |  | 
 | 377 | #define	LOG2_PERIODIC_SIZE	5	/* arbitrary; this matches OHCI */ | 
 | 378 | #define	PERIODIC_SIZE		(1 << LOG2_PERIODIC_SIZE) | 
 | 379 |  | 
 | 380 | struct isp1362_ep { | 
 | 381 | 	struct usb_host_endpoint *hep; | 
 | 382 | 	struct usb_device	*udev; | 
 | 383 |  | 
 | 384 | 	/* philips transfer descriptor */ | 
 | 385 | 	struct ptd		ptd; | 
 | 386 |  | 
 | 387 | 	u8			maxpacket; | 
 | 388 | 	u8			epnum; | 
 | 389 | 	u8			nextpid; | 
 | 390 | 	u16			error_count; | 
 | 391 | 	u16			length;		/* of current packet */ | 
 | 392 | 	s16			ptd_offset;	/* buffer offset in ISP1362 where | 
 | 393 | 						   PTD has been stored | 
 | 394 | 						   (for access thru HCDIRDATA) */ | 
 | 395 | 	int			ptd_index; | 
 | 396 | 	int num_ptds; | 
 | 397 | 	void 			*data;		/* to databuf */ | 
 | 398 | 	/* queue of active EPs (the ones transmitted to the chip) */ | 
 | 399 | 	struct list_head	active; | 
 | 400 |  | 
 | 401 | 	/* periodic schedule */ | 
 | 402 | 	u8			branch; | 
 | 403 | 	u16			interval; | 
 | 404 | 	u16			load; | 
 | 405 | 	u16			last_iso; | 
 | 406 |  | 
 | 407 | 	/* async schedule */ | 
 | 408 | 	struct list_head	schedule;	/* list of all EPs that need processing */ | 
 | 409 | 	struct list_head	remove_list; | 
 | 410 | 	int			num_req; | 
 | 411 | }; | 
 | 412 |  | 
 | 413 | struct isp1362_ep_queue { | 
 | 414 | 	struct list_head	active;		/* list of PTDs currently processed by HC */ | 
 | 415 | 	atomic_t		finishing; | 
 | 416 | 	unsigned long		buf_map; | 
 | 417 | 	unsigned long		skip_map; | 
 | 418 | 	int			free_ptd; | 
 | 419 | 	u16			buf_start; | 
 | 420 | 	u16			buf_size; | 
 | 421 | 	u16			blk_size;	/* PTD buffer block size for ATL and INTL */ | 
 | 422 | 	u8			buf_count; | 
 | 423 | 	u8			buf_avail; | 
 | 424 | 	char			name[16]; | 
 | 425 |  | 
 | 426 | 	/* for statistical tracking */ | 
 | 427 | 	u8			stat_maxptds;	/* Max # of ptds seen simultaneously in fifo */ | 
 | 428 | 	u8			ptd_count;	/* number of ptds submitted to this queue */ | 
 | 429 | }; | 
 | 430 |  | 
 | 431 | struct isp1362_hcd { | 
 | 432 | 	spinlock_t		lock; | 
 | 433 | 	void __iomem		*addr_reg; | 
 | 434 | 	void __iomem		*data_reg; | 
 | 435 |  | 
 | 436 | 	struct isp1362_platform_data *board; | 
 | 437 |  | 
 | 438 | 	struct dentry		*debug_file; | 
 | 439 | 	unsigned long		stat1, stat2, stat4, stat8, stat16; | 
 | 440 |  | 
 | 441 | 	/* HC registers */ | 
 | 442 | 	u32			intenb;		/* "OHCI" interrupts */ | 
 | 443 | 	u16			irqenb;		/* uP interrupts */ | 
 | 444 |  | 
 | 445 | 	/* Root hub registers */ | 
 | 446 | 	u32			rhdesca; | 
 | 447 | 	u32			rhdescb; | 
 | 448 | 	u32			rhstatus; | 
 | 449 | 	u32			rhport[MAX_ROOT_PORTS]; | 
 | 450 | 	unsigned long		next_statechange; | 
 | 451 |  | 
 | 452 | 	/* HC control reg shadow copy */ | 
 | 453 | 	u32			hc_control; | 
 | 454 |  | 
 | 455 | 	/* async schedule: control, bulk */ | 
 | 456 | 	struct list_head	async; | 
 | 457 |  | 
 | 458 | 	/* periodic schedule: int */ | 
 | 459 | 	u16			load[PERIODIC_SIZE]; | 
 | 460 | 	struct list_head	periodic; | 
 | 461 | 	u16			fmindex; | 
 | 462 |  | 
 | 463 | 	/* periodic schedule: isochronous */ | 
 | 464 | 	struct list_head	isoc; | 
 | 465 | 	unsigned int		istl_flip:1; | 
 | 466 | 	unsigned int		irq_active:1; | 
 | 467 |  | 
 | 468 | 	/* Schedules for the current frame */ | 
 | 469 | 	struct isp1362_ep_queue atl_queue; | 
 | 470 | 	struct isp1362_ep_queue intl_queue; | 
 | 471 | 	struct isp1362_ep_queue istl_queue[2]; | 
 | 472 |  | 
 | 473 | 	/* list of PTDs retrieved from HC */ | 
 | 474 | 	struct list_head	remove_list; | 
 | 475 | 	enum { | 
 | 476 | 		ISP1362_INT_SOF, | 
 | 477 | 		ISP1362_INT_ISTL0, | 
 | 478 | 		ISP1362_INT_ISTL1, | 
 | 479 | 		ISP1362_INT_EOT, | 
 | 480 | 		ISP1362_INT_OPR, | 
 | 481 | 		ISP1362_INT_SUSP, | 
 | 482 | 		ISP1362_INT_CLKRDY, | 
 | 483 | 		ISP1362_INT_INTL, | 
 | 484 | 		ISP1362_INT_ATL, | 
 | 485 | 		ISP1362_INT_OTG, | 
 | 486 | 		NUM_ISP1362_IRQS | 
 | 487 | 	} IRQ_NAMES; | 
 | 488 | 	unsigned int		irq_stat[NUM_ISP1362_IRQS]; | 
 | 489 | 	int			req_serial; | 
 | 490 | }; | 
 | 491 |  | 
 | 492 | static inline const char *ISP1362_INT_NAME(int n) | 
 | 493 | { | 
 | 494 | 	switch (n) { | 
 | 495 | 	case ISP1362_INT_SOF:    return "SOF"; | 
 | 496 | 	case ISP1362_INT_ISTL0:  return "ISTL0"; | 
 | 497 | 	case ISP1362_INT_ISTL1:  return "ISTL1"; | 
 | 498 | 	case ISP1362_INT_EOT:    return "EOT"; | 
 | 499 | 	case ISP1362_INT_OPR:    return "OPR"; | 
 | 500 | 	case ISP1362_INT_SUSP:   return "SUSP"; | 
 | 501 | 	case ISP1362_INT_CLKRDY: return "CLKRDY"; | 
 | 502 | 	case ISP1362_INT_INTL:   return "INTL"; | 
 | 503 | 	case ISP1362_INT_ATL:    return "ATL"; | 
 | 504 | 	case ISP1362_INT_OTG:    return "OTG"; | 
 | 505 | 	default:                 return "unknown"; | 
 | 506 | 	} | 
 | 507 | } | 
 | 508 |  | 
 | 509 | static inline void ALIGNSTAT(struct isp1362_hcd *isp1362_hcd, void *ptr) | 
 | 510 | { | 
 | 511 | 	unsigned long p = (unsigned long)ptr; | 
 | 512 | 	if (!(p & 0xf)) | 
 | 513 | 		isp1362_hcd->stat16++; | 
 | 514 | 	else if (!(p & 0x7)) | 
 | 515 | 		isp1362_hcd->stat8++; | 
 | 516 | 	else if (!(p & 0x3)) | 
 | 517 | 		isp1362_hcd->stat4++; | 
 | 518 | 	else if (!(p & 0x1)) | 
 | 519 | 		isp1362_hcd->stat2++; | 
 | 520 | 	else | 
 | 521 | 		isp1362_hcd->stat1++; | 
 | 522 | } | 
 | 523 |  | 
 | 524 | static inline struct isp1362_hcd *hcd_to_isp1362_hcd(struct usb_hcd *hcd) | 
 | 525 | { | 
 | 526 | 	return (struct isp1362_hcd *) (hcd->hcd_priv); | 
 | 527 | } | 
 | 528 |  | 
 | 529 | static inline struct usb_hcd *isp1362_hcd_to_hcd(struct isp1362_hcd *isp1362_hcd) | 
 | 530 | { | 
 | 531 | 	return container_of((void *)isp1362_hcd, struct usb_hcd, hcd_priv); | 
 | 532 | } | 
 | 533 |  | 
 | 534 | #define frame_before(f1, f2)	((s16)((u16)f1 - (u16)f2) < 0) | 
 | 535 |  | 
 | 536 | /* | 
 | 537 |  * ISP1362 HW Interface | 
 | 538 |  */ | 
 | 539 |  | 
 | 540 | #define DBG(level, fmt...) \ | 
 | 541 | 	do { \ | 
 | 542 | 		if (dbg_level > level) \ | 
 | 543 | 			pr_debug(fmt); \ | 
 | 544 | 	} while (0) | 
 | 545 |  | 
 | 546 | #ifdef VERBOSE | 
 | 547 | #    define VDBG(fmt...)	DBG(3, fmt) | 
 | 548 | #else | 
 | 549 | #    define VDBG(fmt...)	do {} while (0) | 
 | 550 | #endif | 
 | 551 |  | 
 | 552 | #ifdef REGISTERS | 
 | 553 | #    define RDBG(fmt...)	DBG(1, fmt) | 
 | 554 | #else | 
 | 555 | #    define RDBG(fmt...)	do {} while (0) | 
 | 556 | #endif | 
 | 557 |  | 
 | 558 | #ifdef URB_TRACE | 
 | 559 | #define URB_DBG(fmt...)		DBG(0, fmt) | 
 | 560 | #else | 
 | 561 | #define URB_DBG(fmt...)		do {} while (0) | 
 | 562 | #endif | 
 | 563 |  | 
 | 564 |  | 
 | 565 | #if USE_PLATFORM_DELAY | 
 | 566 | #if USE_NDELAY | 
 | 567 | #error USE_PLATFORM_DELAY and USE_NDELAY defined simultaneously. | 
 | 568 | #endif | 
 | 569 | #define	isp1362_delay(h, d)	(h)->board->delay(isp1362_hcd_to_hcd(h)->self.controller, d) | 
 | 570 | #elif USE_NDELAY | 
 | 571 | #define	isp1362_delay(h, d)	ndelay(d) | 
 | 572 | #else | 
 | 573 | #define	isp1362_delay(h, d)	do {} while (0) | 
 | 574 | #endif | 
 | 575 |  | 
 | 576 | #define get_urb(ep) ({							\ | 
 | 577 | 	BUG_ON(list_empty(&ep->hep->urb_list));				\ | 
 | 578 | 	container_of(ep->hep->urb_list.next, struct urb, urb_list);	\ | 
 | 579 | }) | 
 | 580 |  | 
 | 581 | /* basic access functions for ISP1362 chip registers */ | 
 | 582 | /* NOTE: The contents of the address pointer register cannot be read back! The driver must ensure, | 
 | 583 |  * that all register accesses are performed with interrupts disabled, since the interrupt | 
 | 584 |  * handler has no way of restoring the previous state. | 
 | 585 |  */ | 
 | 586 | static void isp1362_write_addr(struct isp1362_hcd *isp1362_hcd, isp1362_reg_t reg) | 
 | 587 | { | 
 | 588 | 	REG_ACCESS_TEST(reg); | 
 | 589 | 	DUMMY_DELAY_ACCESS; | 
 | 590 | 	writew(ISP1362_REG_NO(reg), isp1362_hcd->addr_reg); | 
 | 591 | 	DUMMY_DELAY_ACCESS; | 
 | 592 | 	isp1362_delay(isp1362_hcd, 1); | 
 | 593 | } | 
 | 594 |  | 
 | 595 | static void isp1362_write_data16(struct isp1362_hcd *isp1362_hcd, u16 val) | 
 | 596 | { | 
 | 597 | 	DUMMY_DELAY_ACCESS; | 
 | 598 | 	writew(val, isp1362_hcd->data_reg); | 
 | 599 | } | 
 | 600 |  | 
 | 601 | static u16 isp1362_read_data16(struct isp1362_hcd *isp1362_hcd) | 
 | 602 | { | 
 | 603 | 	u16 val; | 
 | 604 |  | 
 | 605 | 	DUMMY_DELAY_ACCESS; | 
 | 606 | 	val = readw(isp1362_hcd->data_reg); | 
 | 607 |  | 
 | 608 | 	return val; | 
 | 609 | } | 
 | 610 |  | 
 | 611 | static void isp1362_write_data32(struct isp1362_hcd *isp1362_hcd, u32 val) | 
 | 612 | { | 
 | 613 | #if USE_32BIT | 
 | 614 | 	DUMMY_DELAY_ACCESS; | 
 | 615 | 	writel(val, isp1362_hcd->data_reg); | 
 | 616 | #else | 
 | 617 | 	DUMMY_DELAY_ACCESS; | 
 | 618 | 	writew((u16)val, isp1362_hcd->data_reg); | 
 | 619 | 	DUMMY_DELAY_ACCESS; | 
 | 620 | 	writew(val >> 16, isp1362_hcd->data_reg); | 
 | 621 | #endif | 
 | 622 | } | 
 | 623 |  | 
 | 624 | static u32 isp1362_read_data32(struct isp1362_hcd *isp1362_hcd) | 
 | 625 | { | 
 | 626 | 	u32 val; | 
 | 627 |  | 
 | 628 | #if USE_32BIT | 
 | 629 | 	DUMMY_DELAY_ACCESS; | 
 | 630 | 	val = readl(isp1362_hcd->data_reg); | 
 | 631 | #else | 
 | 632 | 	DUMMY_DELAY_ACCESS; | 
 | 633 | 	val = (u32)readw(isp1362_hcd->data_reg); | 
 | 634 | 	DUMMY_DELAY_ACCESS; | 
 | 635 | 	val |= (u32)readw(isp1362_hcd->data_reg) << 16; | 
 | 636 | #endif | 
 | 637 | 	return val; | 
 | 638 | } | 
 | 639 |  | 
 | 640 | /* use readsw/writesw to access the fifo whenever possible */ | 
 | 641 | /* assume HCDIRDATA or XFERCTR & addr_reg have been set up */ | 
 | 642 | static void isp1362_read_fifo(struct isp1362_hcd *isp1362_hcd, void *buf, u16 len) | 
 | 643 | { | 
 | 644 | 	u8 *dp = buf; | 
 | 645 | 	u16 data; | 
 | 646 |  | 
 | 647 | 	if (!len) | 
 | 648 | 		return; | 
 | 649 |  | 
 | 650 | 	RDBG("%s: Reading %d byte from fifo to mem @ %p\n", __func__, len, buf); | 
 | 651 | #if USE_32BIT | 
 | 652 | 	if (len >= 4) { | 
 | 653 | 		RDBG("%s: Using readsl for %d dwords\n", __func__, len >> 2); | 
 | 654 | 		readsl(isp1362_hcd->data_reg, dp, len >> 2); | 
 | 655 | 		dp += len & ~3; | 
 | 656 | 		len &= 3; | 
 | 657 | 	} | 
 | 658 | #endif | 
 | 659 | 	if (len >= 2) { | 
 | 660 | 		RDBG("%s: Using readsw for %d words\n", __func__, len >> 1); | 
 | 661 | 		insw((unsigned long)isp1362_hcd->data_reg, dp, len >> 1); | 
 | 662 | 		dp += len & ~1; | 
 | 663 | 		len &= 1; | 
 | 664 | 	} | 
 | 665 |  | 
 | 666 | 	BUG_ON(len & ~1); | 
 | 667 | 	if (len > 0) { | 
 | 668 | 		data = isp1362_read_data16(isp1362_hcd); | 
 | 669 | 		RDBG("%s: Reading trailing byte %02x to mem @ %08x\n", __func__, | 
 | 670 | 		     (u8)data, (u32)dp); | 
 | 671 | 		*dp = (u8)data; | 
 | 672 | 	} | 
 | 673 | } | 
 | 674 |  | 
 | 675 | static void isp1362_write_fifo(struct isp1362_hcd *isp1362_hcd, void *buf, u16 len) | 
 | 676 | { | 
 | 677 | 	u8 *dp = buf; | 
 | 678 | 	u16 data; | 
 | 679 |  | 
 | 680 | 	if (!len) | 
 | 681 | 		return; | 
 | 682 |  | 
 | 683 | 	if ((unsigned long)dp & 0x1) { | 
 | 684 | 		/* not aligned */ | 
 | 685 | 		for (; len > 1; len -= 2) { | 
 | 686 | 			data = *dp++; | 
 | 687 | 			data |= *dp++ << 8; | 
 | 688 | 			isp1362_write_data16(isp1362_hcd, data); | 
 | 689 | 		} | 
 | 690 | 		if (len) | 
 | 691 | 			isp1362_write_data16(isp1362_hcd, *dp); | 
 | 692 | 		return; | 
 | 693 | 	} | 
 | 694 |  | 
 | 695 | 	RDBG("%s: Writing %d byte to fifo from memory @%p\n", __func__, len, buf); | 
 | 696 | #if USE_32BIT | 
 | 697 | 	if (len >= 4) { | 
 | 698 | 		RDBG("%s: Using writesl for %d dwords\n", __func__, len >> 2); | 
 | 699 | 		writesl(isp1362_hcd->data_reg, dp, len >> 2); | 
 | 700 | 		dp += len & ~3; | 
 | 701 | 		len &= 3; | 
 | 702 | 	} | 
 | 703 | #endif | 
 | 704 | 	if (len >= 2) { | 
 | 705 | 		RDBG("%s: Using writesw for %d words\n", __func__, len >> 1); | 
 | 706 | 		outsw((unsigned long)isp1362_hcd->data_reg, dp, len >> 1); | 
 | 707 | 		dp += len & ~1; | 
 | 708 | 		len &= 1; | 
 | 709 | 	} | 
 | 710 |  | 
 | 711 | 	BUG_ON(len & ~1); | 
 | 712 | 	if (len > 0) { | 
 | 713 | 		/* finally write any trailing byte; we don't need to care | 
 | 714 | 		 * about the high byte of the last word written | 
 | 715 | 		 */ | 
 | 716 | 		data = (u16)*dp; | 
 | 717 | 		RDBG("%s: Sending trailing byte %02x from mem @ %08x\n", __func__, | 
 | 718 | 			data, (u32)dp); | 
 | 719 | 		isp1362_write_data16(isp1362_hcd, data); | 
 | 720 | 	} | 
 | 721 | } | 
 | 722 |  | 
 | 723 | #define isp1362_read_reg16(d, r)		({			\ | 
 | 724 | 	u16 __v;							\ | 
 | 725 | 	REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_16);			\ | 
 | 726 | 	isp1362_write_addr(d, ISP1362_REG_##r);				\ | 
 | 727 | 	__v = isp1362_read_data16(d);					\ | 
 | 728 | 	RDBG("%s: Read %04x from %s[%02x]\n", __func__, __v, #r,	\ | 
 | 729 | 	     ISP1362_REG_NO(ISP1362_REG_##r));				\ | 
 | 730 | 	__v;								\ | 
 | 731 | }) | 
 | 732 |  | 
 | 733 | #define isp1362_read_reg32(d, r)		({			\ | 
 | 734 | 	u32 __v;							\ | 
 | 735 | 	REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_32);			\ | 
 | 736 | 	isp1362_write_addr(d, ISP1362_REG_##r);				\ | 
 | 737 | 	__v = isp1362_read_data32(d);					\ | 
 | 738 | 	RDBG("%s: Read %08x from %s[%02x]\n", __func__, __v, #r,	\ | 
 | 739 | 	     ISP1362_REG_NO(ISP1362_REG_##r));				\ | 
 | 740 | 	__v;								\ | 
 | 741 | }) | 
 | 742 |  | 
 | 743 | #define isp1362_write_reg16(d, r, v)	{					\ | 
 | 744 | 	REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_16);				\ | 
 | 745 | 	isp1362_write_addr(d, (ISP1362_REG_##r) | ISP1362_REG_WRITE_OFFSET);	\ | 
 | 746 | 	isp1362_write_data16(d, (u16)(v));					\ | 
 | 747 | 	RDBG("%s: Wrote %04x to %s[%02x]\n", __func__, (u16)(v), #r,	\ | 
 | 748 | 	     ISP1362_REG_NO(ISP1362_REG_##r));					\ | 
 | 749 | } | 
 | 750 |  | 
 | 751 | #define isp1362_write_reg32(d, r, v)	{					\ | 
 | 752 | 	REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_32);				\ | 
 | 753 | 	isp1362_write_addr(d, (ISP1362_REG_##r) | ISP1362_REG_WRITE_OFFSET);	\ | 
 | 754 | 	isp1362_write_data32(d, (u32)(v));					\ | 
 | 755 | 	RDBG("%s: Wrote %08x to %s[%02x]\n", __func__, (u32)(v), #r,	\ | 
 | 756 | 	     ISP1362_REG_NO(ISP1362_REG_##r));					\ | 
 | 757 | } | 
 | 758 |  | 
 | 759 | #define isp1362_set_mask16(d, r, m) {			\ | 
 | 760 | 	u16 __v;					\ | 
 | 761 | 	__v = isp1362_read_reg16(d, r);			\ | 
 | 762 | 	if ((__v | m) != __v)				\ | 
 | 763 | 		isp1362_write_reg16(d, r, __v | m);	\ | 
 | 764 | } | 
 | 765 |  | 
 | 766 | #define isp1362_clr_mask16(d, r, m) {			\ | 
 | 767 | 	u16 __v;					\ | 
 | 768 | 	__v = isp1362_read_reg16(d, r);			\ | 
 | 769 | 	if ((__v & ~m) != __v)			\ | 
 | 770 | 		isp1362_write_reg16(d, r, __v & ~m);	\ | 
 | 771 | } | 
 | 772 |  | 
 | 773 | #define isp1362_set_mask32(d, r, m) {			\ | 
 | 774 | 	u32 __v;					\ | 
 | 775 | 	__v = isp1362_read_reg32(d, r);			\ | 
 | 776 | 	if ((__v | m) != __v)				\ | 
 | 777 | 		isp1362_write_reg32(d, r, __v | m);	\ | 
 | 778 | } | 
 | 779 |  | 
 | 780 | #define isp1362_clr_mask32(d, r, m) {			\ | 
 | 781 | 	u32 __v;					\ | 
 | 782 | 	__v = isp1362_read_reg32(d, r);			\ | 
 | 783 | 	if ((__v & ~m) != __v)			\ | 
 | 784 | 		isp1362_write_reg32(d, r, __v & ~m);	\ | 
 | 785 | } | 
 | 786 |  | 
 | 787 | #define isp1362_show_reg(d, r) {								\ | 
 | 788 | 	if ((ISP1362_REG_##r & REG_WIDTH_MASK) == REG_WIDTH_32)			\ | 
 | 789 | 		DBG(0, "%-12s[%02x]: %08x\n", #r,					\ | 
 | 790 | 			ISP1362_REG_NO(ISP1362_REG_##r), isp1362_read_reg32(d, r));	\ | 
 | 791 | 	else									\ | 
 | 792 | 		DBG(0, "%-12s[%02x]:     %04x\n", #r,					\ | 
 | 793 | 			ISP1362_REG_NO(ISP1362_REG_##r), isp1362_read_reg16(d, r));	\ | 
 | 794 | } | 
 | 795 |  | 
 | 796 | static void __attribute__((__unused__)) isp1362_show_regs(struct isp1362_hcd *isp1362_hcd) | 
 | 797 | { | 
 | 798 | 	isp1362_show_reg(isp1362_hcd, HCREVISION); | 
 | 799 | 	isp1362_show_reg(isp1362_hcd, HCCONTROL); | 
 | 800 | 	isp1362_show_reg(isp1362_hcd, HCCMDSTAT); | 
 | 801 | 	isp1362_show_reg(isp1362_hcd, HCINTSTAT); | 
 | 802 | 	isp1362_show_reg(isp1362_hcd, HCINTENB); | 
 | 803 | 	isp1362_show_reg(isp1362_hcd, HCFMINTVL); | 
 | 804 | 	isp1362_show_reg(isp1362_hcd, HCFMREM); | 
 | 805 | 	isp1362_show_reg(isp1362_hcd, HCFMNUM); | 
 | 806 | 	isp1362_show_reg(isp1362_hcd, HCLSTHRESH); | 
 | 807 | 	isp1362_show_reg(isp1362_hcd, HCRHDESCA); | 
 | 808 | 	isp1362_show_reg(isp1362_hcd, HCRHDESCB); | 
 | 809 | 	isp1362_show_reg(isp1362_hcd, HCRHSTATUS); | 
 | 810 | 	isp1362_show_reg(isp1362_hcd, HCRHPORT1); | 
 | 811 | 	isp1362_show_reg(isp1362_hcd, HCRHPORT2); | 
 | 812 |  | 
 | 813 | 	isp1362_show_reg(isp1362_hcd, HCHWCFG); | 
 | 814 | 	isp1362_show_reg(isp1362_hcd, HCDMACFG); | 
 | 815 | 	isp1362_show_reg(isp1362_hcd, HCXFERCTR); | 
 | 816 | 	isp1362_show_reg(isp1362_hcd, HCuPINT); | 
 | 817 |  | 
 | 818 | 	if (in_interrupt()) | 
 | 819 | 		DBG(0, "%-12s[%02x]:     %04x\n", "HCuPINTENB", | 
 | 820 | 			 ISP1362_REG_NO(ISP1362_REG_HCuPINTENB), isp1362_hcd->irqenb); | 
 | 821 | 	else | 
 | 822 | 		isp1362_show_reg(isp1362_hcd, HCuPINTENB); | 
 | 823 | 	isp1362_show_reg(isp1362_hcd, HCCHIPID); | 
 | 824 | 	isp1362_show_reg(isp1362_hcd, HCSCRATCH); | 
 | 825 | 	isp1362_show_reg(isp1362_hcd, HCBUFSTAT); | 
 | 826 | 	isp1362_show_reg(isp1362_hcd, HCDIRADDR); | 
 | 827 | 	/* Access would advance fifo | 
 | 828 | 	 * isp1362_show_reg(isp1362_hcd, HCDIRDATA); | 
 | 829 | 	 */ | 
 | 830 | 	isp1362_show_reg(isp1362_hcd, HCISTLBUFSZ); | 
 | 831 | 	isp1362_show_reg(isp1362_hcd, HCISTLRATE); | 
 | 832 | 	isp1362_show_reg(isp1362_hcd, HCINTLBUFSZ); | 
 | 833 | 	isp1362_show_reg(isp1362_hcd, HCINTLBLKSZ); | 
 | 834 | 	isp1362_show_reg(isp1362_hcd, HCINTLDONE); | 
 | 835 | 	isp1362_show_reg(isp1362_hcd, HCINTLSKIP); | 
 | 836 | 	isp1362_show_reg(isp1362_hcd, HCINTLLAST); | 
 | 837 | 	isp1362_show_reg(isp1362_hcd, HCINTLCURR); | 
 | 838 | 	isp1362_show_reg(isp1362_hcd, HCATLBUFSZ); | 
 | 839 | 	isp1362_show_reg(isp1362_hcd, HCATLBLKSZ); | 
 | 840 | 	/* only valid after ATL_DONE interrupt | 
 | 841 | 	 * isp1362_show_reg(isp1362_hcd, HCATLDONE); | 
 | 842 | 	 */ | 
 | 843 | 	isp1362_show_reg(isp1362_hcd, HCATLSKIP); | 
 | 844 | 	isp1362_show_reg(isp1362_hcd, HCATLLAST); | 
 | 845 | 	isp1362_show_reg(isp1362_hcd, HCATLCURR); | 
 | 846 | 	isp1362_show_reg(isp1362_hcd, HCATLDTC); | 
 | 847 | 	isp1362_show_reg(isp1362_hcd, HCATLDTCTO); | 
 | 848 | } | 
 | 849 |  | 
 | 850 | static void isp1362_write_diraddr(struct isp1362_hcd *isp1362_hcd, u16 offset, u16 len) | 
 | 851 | { | 
 | 852 | 	len = (len + 1) & ~1; | 
 | 853 |  | 
 | 854 | 	isp1362_clr_mask16(isp1362_hcd, HCDMACFG, HCDMACFG_CTR_ENABLE); | 
 | 855 | 	isp1362_write_reg32(isp1362_hcd, HCDIRADDR, | 
 | 856 | 			    HCDIRADDR_ADDR(offset) | HCDIRADDR_COUNT(len)); | 
 | 857 | } | 
 | 858 |  | 
 | 859 | static void isp1362_read_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16 offset, int len) | 
 | 860 | { | 
 | 861 | 	isp1362_write_diraddr(isp1362_hcd, offset, len); | 
 | 862 |  | 
 | 863 | 	DBG(3, "%s: Reading %d byte from buffer @%04x to memory @ %p\n", | 
 | 864 | 	    __func__, len, offset, buf); | 
 | 865 |  | 
 | 866 | 	isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); | 
 | 867 |  | 
 | 868 | 	isp1362_write_addr(isp1362_hcd, ISP1362_REG_HCDIRDATA); | 
 | 869 |  | 
 | 870 | 	isp1362_read_fifo(isp1362_hcd, buf, len); | 
 | 871 | 	isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); | 
 | 872 | } | 
 | 873 |  | 
 | 874 | static void isp1362_write_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16 offset, int len) | 
 | 875 | { | 
 | 876 | 	isp1362_write_diraddr(isp1362_hcd, offset, len); | 
 | 877 |  | 
 | 878 | 	DBG(3, "%s: Writing %d byte to buffer @%04x from memory @ %p\n", | 
 | 879 | 	    __func__, len, offset, buf); | 
 | 880 |  | 
 | 881 | 	isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); | 
 | 882 |  | 
 | 883 | 	isp1362_write_addr(isp1362_hcd, ISP1362_REG_HCDIRDATA | ISP1362_REG_WRITE_OFFSET); | 
 | 884 | 	isp1362_write_fifo(isp1362_hcd, buf, len); | 
 | 885 |  | 
 | 886 | 	isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); | 
 | 887 | } | 
 | 888 |  | 
 | 889 | static void __attribute__((unused)) dump_data(char *buf, int len) | 
 | 890 | { | 
 | 891 | 	if (dbg_level > 0) { | 
 | 892 | 		int k; | 
 | 893 | 		int lf = 0; | 
 | 894 |  | 
 | 895 | 		for (k = 0; k < len; ++k) { | 
 | 896 | 			if (!lf) | 
 | 897 | 				DBG(0, "%04x:", k); | 
 | 898 | 			printk(" %02x", ((u8 *) buf)[k]); | 
 | 899 | 			lf = 1; | 
 | 900 | 			if (!k) | 
 | 901 | 				continue; | 
 | 902 | 			if (k % 16 == 15) { | 
 | 903 | 				printk("\n"); | 
 | 904 | 				lf = 0; | 
 | 905 | 				continue; | 
 | 906 | 			} | 
 | 907 | 			if (k % 8 == 7) | 
 | 908 | 				printk(" "); | 
 | 909 | 			if (k % 4 == 3) | 
 | 910 | 				printk(" "); | 
 | 911 | 		} | 
 | 912 | 		if (lf) | 
 | 913 | 			printk("\n"); | 
 | 914 | 	} | 
 | 915 | } | 
 | 916 |  | 
 | 917 | #if defined(PTD_TRACE) | 
 | 918 |  | 
 | 919 | static void dump_ptd(struct ptd *ptd) | 
 | 920 | { | 
 | 921 | 	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", | 
 | 922 | 	    container_of(ptd, struct isp1362_ep, ptd), | 
 | 923 | 	    PTD_GET_CC(ptd), PTD_GET_EP(ptd), PTD_GET_DIR(ptd), | 
 | 924 | 	    PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd), | 
 | 925 | 	    PTD_GET_TOGGLE(ptd), PTD_GET_ACTIVE(ptd), PTD_GET_FA(ptd), | 
 | 926 | 	    PTD_GET_SPD(ptd), PTD_GET_SF_INT(ptd), PTD_GET_PR(ptd), PTD_GET_LAST(ptd)); | 
 | 927 | 	DBG(0, "  %04x %04x %04x %04x\n", ptd->count, ptd->mps, ptd->len, ptd->faddr); | 
 | 928 | } | 
 | 929 |  | 
 | 930 | static void dump_ptd_out_data(struct ptd *ptd, u8 *buf) | 
 | 931 | { | 
 | 932 | 	if (dbg_level > 0) { | 
 | 933 | 		if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) { | 
 | 934 | 			DBG(0, "--out->\n"); | 
 | 935 | 			dump_data(buf, PTD_GET_LEN(ptd)); | 
 | 936 | 		} | 
 | 937 | 	} | 
 | 938 | } | 
 | 939 |  | 
 | 940 | static void dump_ptd_in_data(struct ptd *ptd, u8 *buf) | 
 | 941 | { | 
 | 942 | 	if (dbg_level > 0) { | 
 | 943 | 		if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) { | 
 | 944 | 			DBG(0, "<--in--\n"); | 
 | 945 | 			dump_data(buf, PTD_GET_COUNT(ptd)); | 
 | 946 | 		} | 
 | 947 | 		DBG(0, "-----\n"); | 
 | 948 | 	} | 
 | 949 | } | 
 | 950 |  | 
 | 951 | static void dump_ptd_queue(struct isp1362_ep_queue *epq) | 
 | 952 | { | 
 | 953 | 	struct isp1362_ep *ep; | 
 | 954 | 	int dbg = dbg_level; | 
 | 955 |  | 
 | 956 | 	dbg_level = 1; | 
 | 957 | 	list_for_each_entry(ep, &epq->active, active) { | 
 | 958 | 		dump_ptd(&ep->ptd); | 
 | 959 | 		dump_data(ep->data, ep->length); | 
 | 960 | 	} | 
 | 961 | 	dbg_level = dbg; | 
 | 962 | } | 
 | 963 | #else | 
 | 964 | #define dump_ptd(ptd)			do {} while (0) | 
 | 965 | #define dump_ptd_in_data(ptd, buf)	do {} while (0) | 
 | 966 | #define dump_ptd_out_data(ptd, buf)	do {} while (0) | 
 | 967 | #define dump_ptd_data(ptd, buf)		do {} while (0) | 
 | 968 | #define dump_ptd_queue(epq)		do {} while (0) | 
 | 969 | #endif |