Blame view

drivers/usb/host/isp116x-hcd.c 43.6 KB
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  /*
   * ISP116x HCD (Host Controller Driver) for USB.
   *
   * Derived from the SL811 HCD, rewritten for ISP116x.
   * Copyright (C) 2005 Olav Kongas <ok@artecdesign.ee>
   *
   * Portions:
   * Copyright (C) 2004 Psion Teklogix (for NetBook PRO)
   * Copyright (C) 2004 David Brownell
   *
   * Periodic scheduling is based on Roman's OHCI code
   * Copyright (C) 1999 Roman Weissgaerber
   *
   */
  
  /*
   * The driver basically works. A number of people have used it with a range
   * of devices.
   *
17f8bb731   Olav Kongas   [PATCH] USB: isp1...
20
   * The driver passes all usbtests 1-14.
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
   *
   * Suspending/resuming of root hub via sysfs works. Remote wakeup works too.
   * And suspending/resuming of platform device works too. Suspend/resume
   * via HCD operations vector is not implemented.
   *
   * Iso transfer support is not implemented. Adding this would include
   * implementing recovery from the failure to service the processed ITL
   * fifo ram in time, which will involve chip reset.
   *
   * TODO:
   + More testing of suspend/resume.
  */
  
  /*
    ISP116x chips require certain delays between accesses to its
    registers. The following timing options exist.
  
    1. Configure your memory controller (the best)
    2. Implement platform-specific delay function possibly
    combined with configuring the memory controller; see
    include/linux/usb-isp116x.h for more info. Some broken
    memory controllers line LH7A400 SMC need this. Also,
    uncomment for that to work the following
    USE_PLATFORM_DELAY macro.
    3. Use ndelay (easiest, poorest). For that, uncomment
    the following USE_NDELAY macro.
  */
  #define USE_PLATFORM_DELAY
  //#define USE_NDELAY
  
  //#define DEBUG
  //#define VERBOSE
  /* Transfer descriptors. See dump_ptd() for printout format  */
  //#define PTD_TRACE
  /* enqueuing/finishing log of urbs */
  //#define URB_TRACE
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
57
  #include <linux/module.h>
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
58
  #include <linux/delay.h>
959eea219   Olav Kongas   [PATCH] USB: isp1...
59
60
  #include <linux/debugfs.h>
  #include <linux/seq_file.h>
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
61
62
63
  #include <linux/errno.h>
  #include <linux/init.h>
  #include <linux/list.h>
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
64
  #include <linux/usb.h>
325a4af60   David Brownell   [PATCH] USB: move...
65
  #include <linux/usb/isp116x.h>
d052d1bef   Russell King   Create platform_d...
66
  #include <linux/platform_device.h>
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
67
68
69
70
71
  
  #include <asm/io.h>
  #include <asm/irq.h>
  #include <asm/system.h>
  #include <asm/byteorder.h>
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
72
73
  #include "../core/hcd.h"
  #include "isp116x.h"
959eea219   Olav Kongas   [PATCH] USB: isp1...
74
  #define DRIVER_VERSION	"03 Nov 2005"
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  #define DRIVER_DESC	"ISP116x USB Host Controller Driver"
  
  MODULE_DESCRIPTION(DRIVER_DESC);
  MODULE_LICENSE("GPL");
  
  static const char hcd_name[] = "isp116x-hcd";
  
  /*-----------------------------------------------------------------*/
  
  /*
    Write len bytes to fifo, pad till 32-bit boundary
   */
  static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
  {
  	u8 *dp = (u8 *) buf;
  	u16 *dp2 = (u16 *) buf;
  	u16 w;
  	int quot = len % 4;
28874b7ec   Julien May   USB: Fix bug with...
93
94
95
  	/* buffer is already in 'usb data order', which is LE. */
  	/* When reading buffer as u16, we have to take care byte order */
  	/* doesn't get mixed up */
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
96
97
98
99
100
101
102
103
104
105
106
  	if ((unsigned long)dp2 & 1) {
  		/* not aligned */
  		for (; len > 1; len -= 2) {
  			w = *dp++;
  			w |= *dp++ << 8;
  			isp116x_raw_write_data16(isp116x, w);
  		}
  		if (len)
  			isp116x_write_data16(isp116x, (u16) * dp);
  	} else {
  		/* aligned */
28874b7ec   Julien May   USB: Fix bug with...
107
108
109
110
  		for (; len > 1; len -= 2) {
  			/* Keep byte order ! */
  			isp116x_raw_write_data16(isp116x, cpu_to_le16(*dp2++));
  		}
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
  		if (len)
  			isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
  	}
  	if (quot == 1 || quot == 2)
  		isp116x_raw_write_data16(isp116x, 0);
  }
  
  /*
    Read len bytes from fifo and then read till 32-bit boundary.
   */
  static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
  {
  	u8 *dp = (u8 *) buf;
  	u16 *dp2 = (u16 *) buf;
  	u16 w;
  	int quot = len % 4;
28874b7ec   Julien May   USB: Fix bug with...
127
128
129
  	/* buffer is already in 'usb data order', which is LE. */
  	/* When reading buffer as u16, we have to take care byte order */
  	/* doesn't get mixed up */
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
130
131
132
133
134
135
136
  	if ((unsigned long)dp2 & 1) {
  		/* not aligned */
  		for (; len > 1; len -= 2) {
  			w = isp116x_raw_read_data16(isp116x);
  			*dp++ = w & 0xff;
  			*dp++ = (w >> 8) & 0xff;
  		}
28874b7ec   Julien May   USB: Fix bug with...
137

4808a1c02   Olav Kongas   [PATCH] USB: Add ...
138
139
140
141
  		if (len)
  			*dp = 0xff & isp116x_read_data16(isp116x);
  	} else {
  		/* aligned */
28874b7ec   Julien May   USB: Fix bug with...
142
143
144
145
  		for (; len > 1; len -= 2) {
  			/* Keep byte order! */
  			*dp2++ = le16_to_cpu(isp116x_raw_read_data16(isp116x));
  		}
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  		if (len)
  			*(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
  	}
  	if (quot == 1 || quot == 2)
  		isp116x_raw_read_data16(isp116x);
  }
  
  /*
    Write ptd's and data for scheduled transfers into
    the fifo ram. Fifo must be empty and ready.
  */
  static void pack_fifo(struct isp116x *isp116x)
  {
  	struct isp116x_ep *ep;
  	struct ptd *ptd;
  	int buflen = isp116x->atl_last_dir == PTD_DIR_IN
  	    ? isp116x->atl_bufshrt : isp116x->atl_buflen;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
163
164
165
166
167
  
  	isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
  	isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
  	isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
  	for (ep = isp116x->atl_active; ep; ep = ep->active) {
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  		ptd = &ep->ptd;
  		dump_ptd(ptd);
  		dump_ptd_out_data(ptd, ep->data);
  		isp116x_write_data16(isp116x, ptd->count);
  		isp116x_write_data16(isp116x, ptd->mps);
  		isp116x_write_data16(isp116x, ptd->len);
  		isp116x_write_data16(isp116x, ptd->faddr);
  		buflen -= sizeof(struct ptd);
  		/* Skip writing data for last IN PTD */
  		if (ep->active || (isp116x->atl_last_dir != PTD_DIR_IN)) {
  			write_ptddata_to_fifo(isp116x, ep->data, ep->length);
  			buflen -= ALIGN(ep->length, 4);
  		}
  	}
  	BUG_ON(buflen);
  }
  
  /*
    Read the processed ptd's and data from fifo ram back to
    URBs' buffers. Fifo must be full and done
  */
  static void unpack_fifo(struct isp116x *isp116x)
  {
  	struct isp116x_ep *ep;
  	struct ptd *ptd;
  	int buflen = isp116x->atl_last_dir == PTD_DIR_IN
  	    ? isp116x->atl_buflen : isp116x->atl_bufshrt;
  
  	isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
  	isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
  	isp116x_write_addr(isp116x, HCATLPORT);
  	for (ep = isp116x->atl_active; ep; ep = ep->active) {
  		ptd = &ep->ptd;
  		ptd->count = isp116x_read_data16(isp116x);
  		ptd->mps = isp116x_read_data16(isp116x);
  		ptd->len = isp116x_read_data16(isp116x);
  		ptd->faddr = isp116x_read_data16(isp116x);
  		buflen -= sizeof(struct ptd);
  		/* Skip reading data for last Setup or Out PTD */
  		if (ep->active || (isp116x->atl_last_dir == PTD_DIR_IN)) {
  			read_ptddata_from_fifo(isp116x, ep->data, ep->length);
  			buflen -= ALIGN(ep->length, 4);
  		}
  		dump_ptd(ptd);
  		dump_ptd_in_data(ptd, ep->data);
  	}
  	BUG_ON(buflen);
  }
  
  /*---------------------------------------------------------------*/
  
  /*
    Set up PTD's.
  */
  static void preproc_atl_queue(struct isp116x *isp116x)
  {
  	struct isp116x_ep *ep;
  	struct urb *urb;
  	struct ptd *ptd;
f10eff268   Olav Kongas   [PATCH] USB: Fix ...
227
  	u16 len;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
228
229
  
  	for (ep = isp116x->atl_active; ep; ep = ep->active) {
f10eff268   Olav Kongas   [PATCH] USB: Fix ...
230
  		u16 toggle = 0, dir = PTD_DIR_SETUP;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
231
232
233
234
235
  		BUG_ON(list_empty(&ep->hep->urb_list));
  		urb = container_of(ep->hep->urb_list.next,
  				   struct urb, urb_list);
  		ptd = &ep->ptd;
  		len = ep->length;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
236
237
238
239
240
241
242
243
244
245
246
247
248
  		ep->data = (unsigned char *)urb->transfer_buffer
  		    + urb->actual_length;
  
  		switch (ep->nextpid) {
  		case USB_PID_IN:
  			toggle = usb_gettoggle(urb->dev, ep->epnum, 0);
  			dir = PTD_DIR_IN;
  			break;
  		case USB_PID_OUT:
  			toggle = usb_gettoggle(urb->dev, ep->epnum, 1);
  			dir = PTD_DIR_OUT;
  			break;
  		case USB_PID_SETUP:
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
249
250
251
252
253
254
255
256
257
258
259
  			len = sizeof(struct usb_ctrlrequest);
  			ep->data = urb->setup_packet;
  			break;
  		case USB_PID_ACK:
  			toggle = 1;
  			len = 0;
  			dir = (urb->transfer_buffer_length
  			       && usb_pipein(urb->pipe))
  			    ? PTD_DIR_OUT : PTD_DIR_IN;
  			break;
  		default:
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
260
261
262
  			ERR("%s %d: ep->nextpid %d
  ", __func__, __LINE__,
  			    ep->nextpid);
17f8bb731   Olav Kongas   [PATCH] USB: isp1...
263
  			BUG();
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
264
265
266
267
268
269
270
271
  		}
  
  		ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK | PTD_TOGGLE(toggle);
  		ptd->mps = PTD_MPS(ep->maxpacket)
  		    | PTD_SPD(urb->dev->speed == USB_SPEED_LOW)
  		    | PTD_EP(ep->epnum);
  		ptd->len = PTD_LEN(len) | PTD_DIR(dir);
  		ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe));
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
272
273
274
275
276
277
278
279
280
281
  		if (!ep->active) {
  			ptd->mps |= PTD_LAST_MSK;
  			isp116x->atl_last_dir = dir;
  		}
  		isp116x->atl_bufshrt = sizeof(struct ptd) + isp116x->atl_buflen;
  		isp116x->atl_buflen = isp116x->atl_bufshrt + ALIGN(len, 4);
  	}
  }
  
  /*
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
282
283
284
285
    Take done or failed requests out of schedule. Give back
    processed urbs.
  */
  static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep,
4a00027dc   Alan Stern   USB: Eliminate ur...
286
  			   struct urb *urb, int status)
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
287
288
289
  __releases(isp116x->lock) __acquires(isp116x->lock)
  {
  	unsigned i;
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
290
291
292
293
294
295
  	ep->error_count = 0;
  
  	if (usb_pipecontrol(urb->pipe))
  		ep->nextpid = USB_PID_SETUP;
  
  	urb_dbg(urb, "Finish");
e9df41c5c   Alan Stern   USB: make HCDs re...
296
  	usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb);
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
297
  	spin_unlock(&isp116x->lock);
4a00027dc   Alan Stern   USB: Eliminate ur...
298
  	usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, status);
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
  	spin_lock(&isp116x->lock);
  
  	/* take idle endpoints out of the schedule */
  	if (!list_empty(&ep->hep->urb_list))
  		return;
  
  	/* async deschedule */
  	if (!list_empty(&ep->schedule)) {
  		list_del_init(&ep->schedule);
  		return;
  	}
  
  	/* periodic deschedule */
  	DBG("deschedule qh%d/%p branch %d
  ", ep->period, ep, ep->branch);
  	for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) {
  		struct isp116x_ep *temp;
  		struct isp116x_ep **prev = &isp116x->periodic[i];
  
  		while (*prev && ((temp = *prev) != ep))
  			prev = &temp->next;
  		if (*prev)
  			*prev = ep->next;
  		isp116x->load[i] -= ep->load;
  	}
  	ep->branch = PERIODIC_SIZE;
  	isp116x_to_hcd(isp116x)->self.bandwidth_allocated -=
  	    ep->load / ep->period;
  
  	/* switch irq type? */
  	if (!--isp116x->periodic_count) {
  		isp116x->irqenb &= ~HCuPINT_SOF;
  		isp116x->irqenb |= HCuPINT_ATL;
  	}
  }
  
  /*
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
336
337
338
339
340
341
342
343
344
    Analyze transfer results, handle partial transfers and errors
  */
  static void postproc_atl_queue(struct isp116x *isp116x)
  {
  	struct isp116x_ep *ep;
  	struct urb *urb;
  	struct usb_device *udev;
  	struct ptd *ptd;
  	int short_not_ok;
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
345
  	int status;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
346
347
348
349
350
351
352
353
354
  	u8 cc;
  
  	for (ep = isp116x->atl_active; ep; ep = ep->active) {
  		BUG_ON(list_empty(&ep->hep->urb_list));
  		urb =
  		    container_of(ep->hep->urb_list.next, struct urb, urb_list);
  		udev = urb->dev;
  		ptd = &ep->ptd;
  		cc = PTD_GET_CC(ptd);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
355
  		short_not_ok = 1;
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
356
  		status = -EINPROGRESS;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
357
358
359
360
361
362
363
  
  		/* Data underrun is special. For allowed underrun
  		   we clear the error and continue as normal. For
  		   forbidden underrun we finish the DATA stage
  		   immediately while for control transfer,
  		   we do a STATUS stage. */
  		if (cc == TD_DATAUNDERRUN) {
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
364
365
366
367
  			if (!(urb->transfer_flags & URB_SHORT_NOT_OK) ||
  					usb_pipecontrol(urb->pipe)) {
  				DBG("Allowed or control data underrun
  ");
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
368
369
370
371
  				cc = TD_CC_NOERROR;
  				short_not_ok = 0;
  			} else {
  				ep->error_count = 1;
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
372
373
374
  				usb_settoggle(udev, ep->epnum,
  					      ep->nextpid == USB_PID_OUT,
  					      PTD_GET_TOGGLE(ptd));
e9b765dec   Olav Kongas   [PATCH] isp116x-h...
375
  				urb->actual_length += PTD_GET_COUNT(ptd);
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
376
377
  				status = cc_to_error[TD_DATAUNDERRUN];
  				goto done;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
378
379
  			}
  		}
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
380
381
382
383
  
  		if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED
  		    && (++ep->error_count >= 3 || cc == TD_CC_STALL
  			|| cc == TD_DATAOVERRUN)) {
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
384
  			status = cc_to_error[cc];
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
385
386
  			if (ep->nextpid == USB_PID_ACK)
  				ep->nextpid = 0;
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
387
  			goto done;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
388
389
390
391
392
  		}
  		/* According to usb spec, zero-length Int transfer signals
  		   finishing of the urb. Hey, does this apply only
  		   for IN endpoints? */
  		if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) {
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
393
394
  			status = 0;
  			goto done;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
  		}
  
  		/* Relax after previously failed, but later succeeded
  		   or correctly NAK'ed retransmission attempt */
  		if (ep->error_count
  		    && (cc == TD_CC_NOERROR || cc == TD_NOTACCESSED))
  			ep->error_count = 0;
  
  		/* Take into account idiosyncracies of the isp116x chip
  		   regarding toggle bit for failed transfers */
  		if (ep->nextpid == USB_PID_OUT)
  			usb_settoggle(udev, ep->epnum, 1, PTD_GET_TOGGLE(ptd)
  				      ^ (ep->error_count > 0));
  		else if (ep->nextpid == USB_PID_IN)
  			usb_settoggle(udev, ep->epnum, 0, PTD_GET_TOGGLE(ptd)
  				      ^ (ep->error_count > 0));
  
  		switch (ep->nextpid) {
  		case USB_PID_IN:
  		case USB_PID_OUT:
  			urb->actual_length += PTD_GET_COUNT(ptd);
  			if (PTD_GET_ACTIVE(ptd)
  			    || (cc != TD_CC_NOERROR && cc < 0x0E))
  				break;
  			if (urb->transfer_buffer_length != urb->actual_length) {
  				if (short_not_ok)
  					break;
  			} else {
  				if (urb->transfer_flags & URB_ZERO_PACKET
  				    && ep->nextpid == USB_PID_OUT
  				    && !(PTD_GET_COUNT(ptd) % ep->maxpacket)) {
  					DBG("Zero packet requested
  ");
  					break;
  				}
  			}
  			/* All data for this URB is transferred, let's finish */
  			if (usb_pipecontrol(urb->pipe))
  				ep->nextpid = USB_PID_ACK;
1b4cd43bd   Alan Stern   isp116x-hcd: prep...
434
435
  			else
  				status = 0;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  			break;
  		case USB_PID_SETUP:
  			if (PTD_GET_ACTIVE(ptd)
  			    || (cc != TD_CC_NOERROR && cc < 0x0E))
  				break;
  			if (urb->transfer_buffer_length == urb->actual_length)
  				ep->nextpid = USB_PID_ACK;
  			else if (usb_pipeout(urb->pipe)) {
  				usb_settoggle(udev, 0, 1, 1);
  				ep->nextpid = USB_PID_OUT;
  			} else {
  				usb_settoggle(udev, 0, 0, 1);
  				ep->nextpid = USB_PID_IN;
  			}
  			break;
  		case USB_PID_ACK:
  			if (PTD_GET_ACTIVE(ptd)
  			    || (cc != TD_CC_NOERROR && cc < 0x0E))
  				break;
b0d9efba3   Alan Stern   USB: centralize -...
455
  			status = 0;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
456
457
458
  			ep->nextpid = 0;
  			break;
  		default:
959eea219   Olav Kongas   [PATCH] USB: isp1...
459
  			BUG();
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
460
  		}
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
461

1b4cd43bd   Alan Stern   isp116x-hcd: prep...
462
   done:
4a00027dc   Alan Stern   USB: Eliminate ur...
463
464
  		if (status != -EINPROGRESS || urb->unlinked)
  			finish_request(isp116x, ep, urb, status);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
  	}
  }
  
  /*
    Scan transfer lists, schedule transfers, send data off
    to chip.
   */
  static void start_atl_transfers(struct isp116x *isp116x)
  {
  	struct isp116x_ep *last_ep = NULL, *ep;
  	struct urb *urb;
  	u16 load = 0;
  	int len, index, speed, byte_time;
  
  	if (atomic_read(&isp116x->atl_finishing))
  		return;
  
  	if (!HC_IS_RUNNING(isp116x_to_hcd(isp116x)->state))
  		return;
  
  	/* FIFO not empty? */
  	if (isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_FULL)
  		return;
  
  	isp116x->atl_active = NULL;
  	isp116x->atl_buflen = isp116x->atl_bufshrt = 0;
  
  	/* Schedule int transfers */
  	if (isp116x->periodic_count) {
  		isp116x->fmindex = index =
  		    (isp116x->fmindex + 1) & (PERIODIC_SIZE - 1);
  		if ((load = isp116x->load[index])) {
  			/* Bring all int transfers for this frame
  			   into the active queue */
  			isp116x->atl_active = last_ep =
  			    isp116x->periodic[index];
  			while (last_ep->next)
  				last_ep = (last_ep->active = last_ep->next);
  			last_ep->active = NULL;
  		}
  	}
  
  	/* Schedule control/bulk transfers */
  	list_for_each_entry(ep, &isp116x->async, schedule) {
  		urb = container_of(ep->hep->urb_list.next,
  				   struct urb, urb_list);
  		speed = urb->dev->speed;
  		byte_time = speed == USB_SPEED_LOW
  		    ? BYTE_TIME_LOWSPEED : BYTE_TIME_FULLSPEED;
  
  		if (ep->nextpid == USB_PID_SETUP) {
  			len = sizeof(struct usb_ctrlrequest);
  		} else if (ep->nextpid == USB_PID_ACK) {
  			len = 0;
  		} else {
  			/* Find current free length ... */
  			len = (MAX_LOAD_LIMIT - load) / byte_time;
  
  			/* ... then limit it to configured max size ... */
  			len = min(len, speed == USB_SPEED_LOW ?
  				  MAX_TRANSFER_SIZE_LOWSPEED :
  				  MAX_TRANSFER_SIZE_FULLSPEED);
  
  			/* ... and finally cut to the multiple of MaxPacketSize,
  			   or to the real length if there's enough room. */
  			if (len <
  			    (urb->transfer_buffer_length -
  			     urb->actual_length)) {
  				len -= len % ep->maxpacket;
  				if (!len)
  					continue;
  			} else
  				len = urb->transfer_buffer_length -
  				    urb->actual_length;
  			BUG_ON(len < 0);
  		}
  
  		load += len * byte_time;
  		if (load > MAX_LOAD_LIMIT)
  			break;
  
  		ep->active = NULL;
  		ep->length = len;
  		if (last_ep)
  			last_ep->active = ep;
  		else
  			isp116x->atl_active = ep;
  		last_ep = ep;
  	}
  
  	/* Avoid starving of endpoints */
  	if ((&isp116x->async)->next != (&isp116x->async)->prev)
  		list_move(&isp116x->async, (&isp116x->async)->next);
  
  	if (isp116x->atl_active) {
  		preproc_atl_queue(isp116x);
  		pack_fifo(isp116x);
  	}
  }
  
  /*
    Finish the processed transfers
  */
7d12e780e   David Howells   IRQ: Maintain reg...
568
  static void finish_atl_transfers(struct isp116x *isp116x)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
569
  {
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
570
571
572
573
574
575
576
577
578
  	if (!isp116x->atl_active)
  		return;
  	/* Fifo not ready? */
  	if (!(isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_DONE))
  		return;
  
  	atomic_inc(&isp116x->atl_finishing);
  	unpack_fifo(isp116x);
  	postproc_atl_queue(isp116x);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
579
580
  	atomic_dec(&isp116x->atl_finishing);
  }
7d12e780e   David Howells   IRQ: Maintain reg...
581
  static irqreturn_t isp116x_irq(struct usb_hcd *hcd)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
582
583
584
585
586
587
588
589
590
591
592
593
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	u16 irqstat;
  	irqreturn_t ret = IRQ_NONE;
  
  	spin_lock(&isp116x->lock);
  	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
  	irqstat = isp116x_read_reg16(isp116x, HCuPINT);
  	isp116x_write_reg16(isp116x, HCuPINT, irqstat);
  
  	if (irqstat & (HCuPINT_ATL | HCuPINT_SOF)) {
  		ret = IRQ_HANDLED;
7d12e780e   David Howells   IRQ: Maintain reg...
594
  		finish_atl_transfers(isp116x);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
595
596
597
598
599
600
  	}
  
  	if (irqstat & HCuPINT_OPR) {
  		u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
  		isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
  		if (intstat & HCINT_UE) {
959eea219   Olav Kongas   [PATCH] USB: isp1...
601
602
603
604
605
606
607
  			ERR("Unrecoverable error, HC is dead!
  ");
  			/* IRQ's are off, we do no DMA,
  			   perfectly ready to die ... */
  			hcd->state = HC_STATE_HALT;
  			ret = IRQ_HANDLED;
  			goto done;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
608
  		}
9a57116bc   Olav Kongas   [PATCH] USB: Swit...
609
610
611
612
613
614
  		if (intstat & HCINT_RHSC)
  			/* When root hub or any of its ports is going
  			   to come out of suspend, it may take more
  			   than 10ms for status bits to stabilize. */
  			mod_timer(&hcd->rh_timer, jiffies
  				  + msecs_to_jiffies(20) + 1);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
615
616
617
  		if (intstat & HCINT_RD) {
  			DBG("---- remote wakeup
  ");
ccdcf77ae   David Brownell   [PATCH] ISP116x P...
618
  			usb_hcd_resume_root_hub(hcd);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
619
620
621
622
623
624
625
626
627
628
  		}
  		irqstat &= ~HCuPINT_OPR;
  		ret = IRQ_HANDLED;
  	}
  
  	if (irqstat & (HCuPINT_ATL | HCuPINT_SOF)) {
  		start_atl_transfers(isp116x);
  	}
  
  	isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb);
959eea219   Olav Kongas   [PATCH] USB: isp1...
629
        done:
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
  	spin_unlock(&isp116x->lock);
  	return ret;
  }
  
  /*-----------------------------------------------------------------*/
  
  /* usb 1.1 says max 90% of a frame is available for periodic transfers.
   * this driver doesn't promise that much since it's got to handle an
   * IRQ per packet; irq handling latencies also use up that time.
   */
  
  /* out of 1000 us */
  #define	MAX_PERIODIC_LOAD	600
  static int balance(struct isp116x *isp116x, u16 period, u16 load)
  {
  	int i, branch = -ENOSPC;
  
  	/* search for the least loaded schedule branch of that period
  	   which has enough bandwidth left unreserved. */
  	for (i = 0; i < period; i++) {
  		if (branch < 0 || isp116x->load[branch] > isp116x->load[i]) {
  			int j;
  
  			for (j = i; j < PERIODIC_SIZE; j += period) {
  				if ((isp116x->load[j] + load)
  				    > MAX_PERIODIC_LOAD)
  					break;
  			}
  			if (j < PERIODIC_SIZE)
  				continue;
  			branch = i;
  		}
  	}
  	return branch;
  }
  
  /* NB! ALL the code above this point runs with isp116x->lock
     held, irqs off
  */
  
  /*-----------------------------------------------------------------*/
  
  static int isp116x_urb_enqueue(struct usb_hcd *hcd,
e9df41c5c   Alan Stern   USB: make HCDs re...
673
  			       struct urb *urb,
55016f10e   Al Viro   [PATCH] gfp_t: dr...
674
  			       gfp_t mem_flags)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
675
676
677
678
679
680
681
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	struct usb_device *udev = urb->dev;
  	unsigned int pipe = urb->pipe;
  	int is_out = !usb_pipein(pipe);
  	int type = usb_pipetype(pipe);
  	int epnum = usb_pipeendpoint(pipe);
e9df41c5c   Alan Stern   USB: make HCDs re...
682
  	struct usb_host_endpoint *hep = urb->ep;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
  	struct isp116x_ep *ep = NULL;
  	unsigned long flags;
  	int i;
  	int ret = 0;
  
  	urb_dbg(urb, "Enqueue");
  
  	if (type == PIPE_ISOCHRONOUS) {
  		ERR("Isochronous transfers not supported
  ");
  		urb_dbg(urb, "Refused to enqueue");
  		return -ENXIO;
  	}
  	/* avoid all allocations within spinlocks: request or endpoint */
  	if (!hep->hcpriv) {
7b842b6e3   Pekka Enberg   [PATCH] USB: conv...
698
  		ep = kzalloc(sizeof *ep, mem_flags);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
699
700
701
702
703
704
  		if (!ep)
  			return -ENOMEM;
  	}
  
  	spin_lock_irqsave(&isp116x->lock, flags);
  	if (!HC_IS_RUNNING(hcd->state)) {
959eea219   Olav Kongas   [PATCH] USB: isp1...
705
  		kfree(ep);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
706
  		ret = -ENODEV;
e9df41c5c   Alan Stern   USB: make HCDs re...
707
708
709
710
711
712
  		goto fail_not_linked;
  	}
  	ret = usb_hcd_link_urb_to_ep(hcd, urb);
  	if (ret) {
  		kfree(ep);
  		goto fail_not_linked;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
713
714
715
716
717
718
  	}
  
  	if (hep->hcpriv)
  		ep = hep->hcpriv;
  	else {
  		INIT_LIST_HEAD(&ep->schedule);
6a8e87b23   Alan Stern   [PATCH] USB core ...
719
  		ep->udev = udev;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
  		ep->epnum = epnum;
  		ep->maxpacket = usb_maxpacket(udev, urb->pipe, is_out);
  		usb_settoggle(udev, epnum, is_out, 0);
  
  		if (type == PIPE_CONTROL) {
  			ep->nextpid = USB_PID_SETUP;
  		} else if (is_out) {
  			ep->nextpid = USB_PID_OUT;
  		} else {
  			ep->nextpid = USB_PID_IN;
  		}
  
  		if (urb->interval) {
  			/*
  			   With INT URBs submitted, the driver works with SOF
  			   interrupt enabled and ATL interrupt disabled. After
  			   the PTDs are written to fifo ram, the chip starts
  			   fifo processing and usb transfers after the next
  			   SOF and continues until the transfers are finished
  			   (succeeded or failed) or the frame ends. Therefore,
  			   the transfers occur only in every second frame,
  			   while fifo reading/writing and data processing
  			   occur in every other second frame. */
  			if (urb->interval < 2)
  				urb->interval = 2;
  			if (urb->interval > 2 * PERIODIC_SIZE)
  				urb->interval = 2 * PERIODIC_SIZE;
  			ep->period = urb->interval >> 1;
  			ep->branch = PERIODIC_SIZE;
  			ep->load = usb_calc_bus_time(udev->speed,
  						     !is_out,
  						     (type == PIPE_ISOCHRONOUS),
  						     usb_maxpacket(udev, pipe,
  								   is_out)) /
  			    1000;
  		}
  		hep->hcpriv = ep;
  		ep->hep = hep;
  	}
  
  	/* maybe put endpoint into schedule */
  	switch (type) {
  	case PIPE_CONTROL:
  	case PIPE_BULK:
  		if (list_empty(&ep->schedule))
  			list_add_tail(&ep->schedule, &isp116x->async);
  		break;
  	case PIPE_INTERRUPT:
  		urb->interval = ep->period;
16e2e5f63   Greg Kroah-Hartman   USB: make transfe...
769
  		ep->length = min_t(u32, ep->maxpacket,
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
770
771
772
773
774
  				 urb->transfer_buffer_length);
  
  		/* urb submitted for already existing endpoint */
  		if (ep->branch < PERIODIC_SIZE)
  			break;
d5ce1379b   Eric Sesterhenn   [PATCH] USB: nega...
775
  		ep->branch = ret = balance(isp116x, ep->period, ep->load);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
  		if (ret < 0)
  			goto fail;
  		ret = 0;
  
  		urb->start_frame = (isp116x->fmindex & (PERIODIC_SIZE - 1))
  		    + ep->branch;
  
  		/* sort each schedule branch by period (slow before fast)
  		   to share the faster parts of the tree without needing
  		   dummy/placeholder nodes */
  		DBG("schedule qh%d/%p branch %d
  ", ep->period, ep, ep->branch);
  		for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) {
  			struct isp116x_ep **prev = &isp116x->periodic[i];
  			struct isp116x_ep *here = *prev;
  
  			while (here && ep != here) {
  				if (ep->period > here->period)
  					break;
  				prev = &here->next;
  				here = *prev;
  			}
  			if (ep != here) {
  				ep->next = here;
  				*prev = ep;
  			}
  			isp116x->load[i] += ep->load;
  		}
  		hcd->self.bandwidth_allocated += ep->load / ep->period;
  
  		/* switch over to SOFint */
  		if (!isp116x->periodic_count++) {
  			isp116x->irqenb &= ~HCuPINT_ATL;
  			isp116x->irqenb |= HCuPINT_SOF;
  			isp116x_write_reg16(isp116x, HCuPINTENB,
  					    isp116x->irqenb);
  		}
  	}
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
814
  	urb->hcpriv = hep;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
815
816
817
  	start_atl_transfers(isp116x);
  
        fail:
e9df41c5c   Alan Stern   USB: make HCDs re...
818
819
820
  	if (ret)
  		usb_hcd_unlink_urb_from_ep(hcd, urb);
        fail_not_linked:
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
821
822
823
824
825
826
827
  	spin_unlock_irqrestore(&isp116x->lock, flags);
  	return ret;
  }
  
  /*
     Dequeue URBs.
  */
e9df41c5c   Alan Stern   USB: make HCDs re...
828
829
  static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
  		int status)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
830
831
832
833
834
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	struct usb_host_endpoint *hep;
  	struct isp116x_ep *ep, *ep_act;
  	unsigned long flags;
e9df41c5c   Alan Stern   USB: make HCDs re...
835
  	int rc;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
836
837
  
  	spin_lock_irqsave(&isp116x->lock, flags);
e9df41c5c   Alan Stern   USB: make HCDs re...
838
839
840
  	rc = usb_hcd_check_unlink_urb(hcd, urb, status);
  	if (rc)
  		goto done;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
841
  	hep = urb->hcpriv;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
  	ep = hep->hcpriv;
  	WARN_ON(hep != ep->hep);
  
  	/* In front of queue? */
  	if (ep->hep->urb_list.next == &urb->urb_list)
  		/* active? */
  		for (ep_act = isp116x->atl_active; ep_act;
  		     ep_act = ep_act->active)
  			if (ep_act == ep) {
  				VDBG("dequeue, urb %p active; wait for irq
  ",
  				     urb);
  				urb = NULL;
  				break;
  			}
  
  	if (urb)
4a00027dc   Alan Stern   USB: Eliminate ur...
859
  		finish_request(isp116x, ep, urb, status);
e9df41c5c   Alan Stern   USB: make HCDs re...
860
   done:
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
861
  	spin_unlock_irqrestore(&isp116x->lock, flags);
e9df41c5c   Alan Stern   USB: make HCDs re...
862
  	return rc;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
863
864
865
866
867
868
  }
  
  static void isp116x_endpoint_disable(struct usb_hcd *hcd,
  				     struct usb_host_endpoint *hep)
  {
  	int i;
959eea219   Olav Kongas   [PATCH] USB: isp1...
869
  	struct isp116x_ep *ep = hep->hcpriv;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
870
871
872
873
874
875
876
877
  
  	if (!ep)
  		return;
  
  	/* assume we'd just wait for the irq */
  	for (i = 0; i < 100 && !list_empty(&hep->urb_list); i++)
  		msleep(3);
  	if (!list_empty(&hep->urb_list))
b6c639370   Arjan van de Ven   Rename WARN() to ...
878
879
  		WARNING("ep %p not empty?
  ", ep);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
880

4808a1c02   Olav Kongas   [PATCH] USB: Add ...
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
  	kfree(ep);
  	hep->hcpriv = NULL;
  }
  
  static int isp116x_get_frame(struct usb_hcd *hcd)
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	u32 fmnum;
  	unsigned long flags;
  
  	spin_lock_irqsave(&isp116x->lock, flags);
  	fmnum = isp116x_read_reg32(isp116x, HCFMNUM);
  	spin_unlock_irqrestore(&isp116x->lock, flags);
  	return (int)fmnum;
  }
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
896
897
898
899
900
901
902
  /*
    Adapted from ohci-hub.c. Currently we don't support autosuspend.
  */
  static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	int ports, i, changed = 0;
9a57116bc   Olav Kongas   [PATCH] USB: Swit...
903
  	unsigned long flags;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
904
905
906
  
  	if (!HC_IS_RUNNING(hcd->state))
  		return -ESHUTDOWN;
9a57116bc   Olav Kongas   [PATCH] USB: Swit...
907
908
909
910
  	/* Report no status change now, if we are scheduled to be
  	   called later */
  	if (timer_pending(&hcd->rh_timer))
  		return 0;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
911

9a57116bc   Olav Kongas   [PATCH] USB: Swit...
912
913
914
  	ports = isp116x->rhdesca & RH_A_NDP;
  	spin_lock_irqsave(&isp116x->lock, flags);
  	isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
915
916
917
918
919
920
  	if (isp116x->rhstatus & (RH_HS_LPSC | RH_HS_OCIC))
  		buf[0] = changed = 1;
  	else
  		buf[0] = 0;
  
  	for (i = 0; i < ports; i++) {
0ed930bff   Anti Sullin   USB: isp116x: fix...
921
  		u32 status = isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
922
923
924
925
926
  
  		if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
  			      | RH_PS_OCIC | RH_PS_PRSC)) {
  			changed = 1;
  			buf[0] |= 1 << (i + 1);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
927
928
  		}
  	}
9a57116bc   Olav Kongas   [PATCH] USB: Swit...
929
  	spin_unlock_irqrestore(&isp116x->lock, flags);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
930
931
932
933
934
935
936
937
938
939
940
941
942
  	return changed;
  }
  
  static void isp116x_hub_descriptor(struct isp116x *isp116x,
  				   struct usb_hub_descriptor *desc)
  {
  	u32 reg = isp116x->rhdesca;
  
  	desc->bDescriptorType = 0x29;
  	desc->bDescLength = 9;
  	desc->bHubContrCurrent = 0;
  	desc->bNbrPorts = (u8) (reg & 0x3);
  	/* Power switching, device type, overcurrent. */
959eea219   Olav Kongas   [PATCH] USB: isp1...
943
  	desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f));
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
944
945
  	desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff);
  	/* two bitmaps:  ports removable, and legacy PortPwrCtrlMask */
959eea219   Olav Kongas   [PATCH] USB: isp1...
946
  	desc->bitmap[0] = 0;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
  	desc->bitmap[1] = ~0;
  }
  
  /* Perform reset of a given port.
     It would be great to just start the reset and let the
     USB core to clear the reset in due time. However,
     root hub ports should be reset for at least 50 ms, while
     our chip stays in reset for about 10 ms. I.e., we must
     repeatedly reset it ourself here.
  */
  static inline void root_port_reset(struct isp116x *isp116x, unsigned port)
  {
  	u32 tmp;
  	unsigned long flags, t;
  
  	/* Root hub reset should be 50 ms, but some devices
  	   want it even longer. */
  	t = jiffies + msecs_to_jiffies(100);
  
  	while (time_before(jiffies, t)) {
  		spin_lock_irqsave(&isp116x->lock, flags);
  		/* spin until any current reset finishes */
  		for (;;) {
  			tmp = isp116x_read_reg32(isp116x, port ?
  						 HCRHPORT2 : HCRHPORT1);
  			if (!(tmp & RH_PS_PRS))
  				break;
  			udelay(500);
  		}
  		/* Don't reset a disconnected port */
  		if (!(tmp & RH_PS_CCS)) {
  			spin_unlock_irqrestore(&isp116x->lock, flags);
  			break;
  		}
  		/* Reset lasts 10ms (claims datasheet) */
  		isp116x_write_reg32(isp116x, port ? HCRHPORT2 :
  				    HCRHPORT1, (RH_PS_PRS));
  		spin_unlock_irqrestore(&isp116x->lock, flags);
  		msleep(10);
  	}
  }
  
  /* Adapted from ohci-hub.c */
  static int isp116x_hub_control(struct usb_hcd *hcd,
  			       u16 typeReq,
  			       u16 wValue, u16 wIndex, char *buf, u16 wLength)
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	int ret = 0;
  	unsigned long flags;
  	int ports = isp116x->rhdesca & RH_A_NDP;
  	u32 tmp = 0;
  
  	switch (typeReq) {
  	case ClearHubFeature:
  		DBG("ClearHubFeature: ");
  		switch (wValue) {
  		case C_HUB_OVER_CURRENT:
  			DBG("C_HUB_OVER_CURRENT
  ");
  			spin_lock_irqsave(&isp116x->lock, flags);
  			isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_OCIC);
  			spin_unlock_irqrestore(&isp116x->lock, flags);
  		case C_HUB_LOCAL_POWER:
  			DBG("C_HUB_LOCAL_POWER
  ");
  			break;
  		default:
  			goto error;
  		}
  		break;
  	case SetHubFeature:
  		DBG("SetHubFeature: ");
  		switch (wValue) {
  		case C_HUB_OVER_CURRENT:
  		case C_HUB_LOCAL_POWER:
  			DBG("C_HUB_OVER_CURRENT or C_HUB_LOCAL_POWER
  ");
  			break;
  		default:
  			goto error;
  		}
  		break;
  	case GetHubDescriptor:
  		DBG("GetHubDescriptor
  ");
  		isp116x_hub_descriptor(isp116x,
  				       (struct usb_hub_descriptor *)buf);
  		break;
  	case GetHubStatus:
  		DBG("GetHubStatus
  ");
17f8bb731   Olav Kongas   [PATCH] USB: isp1...
1039
  		*(__le32 *) buf = 0;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1040
1041
1042
1043
1044
1045
  		break;
  	case GetPortStatus:
  		DBG("GetPortStatus
  ");
  		if (!wIndex || wIndex > ports)
  			goto error;
0ed930bff   Anti Sullin   USB: isp116x: fix...
1046
1047
1048
  		spin_lock_irqsave(&isp116x->lock, flags);
  		tmp = isp116x_read_reg32(isp116x, (--wIndex) ? HCRHPORT2 : HCRHPORT1);
  		spin_unlock_irqrestore(&isp116x->lock, flags);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
  		*(__le32 *) buf = cpu_to_le32(tmp);
  		DBG("GetPortStatus: port[%d]  %08x
  ", wIndex + 1, tmp);
  		break;
  	case ClearPortFeature:
  		DBG("ClearPortFeature: ");
  		if (!wIndex || wIndex > ports)
  			goto error;
  		wIndex--;
  
  		switch (wValue) {
  		case USB_PORT_FEAT_ENABLE:
  			DBG("USB_PORT_FEAT_ENABLE
  ");
  			tmp = RH_PS_CCS;
  			break;
  		case USB_PORT_FEAT_C_ENABLE:
  			DBG("USB_PORT_FEAT_C_ENABLE
  ");
  			tmp = RH_PS_PESC;
  			break;
  		case USB_PORT_FEAT_SUSPEND:
  			DBG("USB_PORT_FEAT_SUSPEND
  ");
  			tmp = RH_PS_POCI;
  			break;
  		case USB_PORT_FEAT_C_SUSPEND:
  			DBG("USB_PORT_FEAT_C_SUSPEND
  ");
  			tmp = RH_PS_PSSC;
  			break;
  		case USB_PORT_FEAT_POWER:
  			DBG("USB_PORT_FEAT_POWER
  ");
  			tmp = RH_PS_LSDA;
  			break;
  		case USB_PORT_FEAT_C_CONNECTION:
  			DBG("USB_PORT_FEAT_C_CONNECTION
  ");
  			tmp = RH_PS_CSC;
  			break;
  		case USB_PORT_FEAT_C_OVER_CURRENT:
  			DBG("USB_PORT_FEAT_C_OVER_CURRENT
  ");
  			tmp = RH_PS_OCIC;
  			break;
  		case USB_PORT_FEAT_C_RESET:
  			DBG("USB_PORT_FEAT_C_RESET
  ");
  			tmp = RH_PS_PRSC;
  			break;
  		default:
  			goto error;
  		}
  		spin_lock_irqsave(&isp116x->lock, flags);
  		isp116x_write_reg32(isp116x, wIndex
  				    ? HCRHPORT2 : HCRHPORT1, tmp);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
  		spin_unlock_irqrestore(&isp116x->lock, flags);
  		break;
  	case SetPortFeature:
  		DBG("SetPortFeature: ");
  		if (!wIndex || wIndex > ports)
  			goto error;
  		wIndex--;
  		switch (wValue) {
  		case USB_PORT_FEAT_SUSPEND:
  			DBG("USB_PORT_FEAT_SUSPEND
  ");
  			spin_lock_irqsave(&isp116x->lock, flags);
  			isp116x_write_reg32(isp116x, wIndex
  					    ? HCRHPORT2 : HCRHPORT1, RH_PS_PSS);
0ed930bff   Anti Sullin   USB: isp116x: fix...
1120
  			spin_unlock_irqrestore(&isp116x->lock, flags);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1121
1122
1123
1124
1125
1126
1127
  			break;
  		case USB_PORT_FEAT_POWER:
  			DBG("USB_PORT_FEAT_POWER
  ");
  			spin_lock_irqsave(&isp116x->lock, flags);
  			isp116x_write_reg32(isp116x, wIndex
  					    ? HCRHPORT2 : HCRHPORT1, RH_PS_PPS);
0ed930bff   Anti Sullin   USB: isp116x: fix...
1128
  			spin_unlock_irqrestore(&isp116x->lock, flags);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1129
1130
1131
1132
1133
  			break;
  		case USB_PORT_FEAT_RESET:
  			DBG("USB_PORT_FEAT_RESET
  ");
  			root_port_reset(isp116x, wIndex);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1134
1135
1136
1137
  			break;
  		default:
  			goto error;
  		}
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
  		break;
  
  	default:
  	      error:
  		/* "protocol stall" on error */
  		DBG("PROTOCOL STALL
  ");
  		ret = -EPIPE;
  	}
  	return ret;
  }
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1149
  /*-----------------------------------------------------------------*/
959eea219   Olav Kongas   [PATCH] USB: isp1...
1150
  #ifdef CONFIG_DEBUG_FS
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
  
  static void dump_irq(struct seq_file *s, char *label, u16 mask)
  {
  	seq_printf(s, "%s %04x%s%s%s%s%s%s
  ", label, mask,
  		   mask & HCuPINT_CLKRDY ? " clkrdy" : "",
  		   mask & HCuPINT_SUSP ? " susp" : "",
  		   mask & HCuPINT_OPR ? " opr" : "",
  		   mask & HCuPINT_AIIEOT ? " eot" : "",
  		   mask & HCuPINT_ATL ? " atl" : "",
  		   mask & HCuPINT_SOF ? " sof" : "");
  }
  
  static void dump_int(struct seq_file *s, char *label, u32 mask)
  {
  	seq_printf(s, "%s %08x%s%s%s%s%s%s%s
  ", label, mask,
  		   mask & HCINT_MIE ? " MIE" : "",
  		   mask & HCINT_RHSC ? " rhsc" : "",
  		   mask & HCINT_FNO ? " fno" : "",
  		   mask & HCINT_UE ? " ue" : "",
  		   mask & HCINT_RD ? " rd" : "",
  		   mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : "");
  }
959eea219   Olav Kongas   [PATCH] USB: isp1...
1175
  static int isp116x_show_dbg(struct seq_file *s, void *unused)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1176
1177
  {
  	struct isp116x *isp116x = s->private;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
  
  	seq_printf(s, "%s
  %s version %s
  ",
  		   isp116x_to_hcd(isp116x)->product_desc, hcd_name,
  		   DRIVER_VERSION);
  
  	if (HC_IS_SUSPENDED(isp116x_to_hcd(isp116x)->state)) {
  		seq_printf(s, "HCD is suspended
  ");
  		return 0;
  	}
  	if (!HC_IS_RUNNING(isp116x_to_hcd(isp116x)->state)) {
  		seq_printf(s, "HCD not running
  ");
  		return 0;
  	}
  
  	spin_lock_irq(&isp116x->lock);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1197
1198
1199
1200
  	dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB));
  	dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT));
  	dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB));
  	dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT));
959eea219   Olav Kongas   [PATCH] USB: isp1...
1201
  	isp116x_show_regs_seq(isp116x, s);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1202
1203
1204
1205
1206
1207
  	spin_unlock_irq(&isp116x->lock);
  	seq_printf(s, "
  ");
  
  	return 0;
  }
959eea219   Olav Kongas   [PATCH] USB: isp1...
1208
  static int isp116x_open_seq(struct inode *inode, struct file *file)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1209
  {
8e18e2941   Theodore Ts'o   [PATCH] inode_die...
1210
  	return single_open(file, isp116x_show_dbg, inode->i_private);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1211
  }
066202dd4   Luiz Fernando N. Capitulino   USB: Make file op...
1212
  static const struct file_operations isp116x_debug_fops = {
959eea219   Olav Kongas   [PATCH] USB: isp1...
1213
  	.open = isp116x_open_seq,
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1214
1215
1216
1217
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = single_release,
  };
959eea219   Olav Kongas   [PATCH] USB: isp1...
1218
  static int create_debug_file(struct isp116x *isp116x)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1219
  {
959eea219   Olav Kongas   [PATCH] USB: isp1...
1220
1221
1222
1223
1224
1225
  	isp116x->dentry = debugfs_create_file(hcd_name,
  					      S_IRUGO, NULL, isp116x,
  					      &isp116x_debug_fops);
  	if (!isp116x->dentry)
  		return -ENOMEM;
  	return 0;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1226
1227
1228
1229
  }
  
  static void remove_debug_file(struct isp116x *isp116x)
  {
959eea219   Olav Kongas   [PATCH] USB: isp1...
1230
  	debugfs_remove(isp116x->dentry);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1231
  }
959eea219   Olav Kongas   [PATCH] USB: isp1...
1232
1233
1234
1235
1236
1237
  #else
  
  #define	create_debug_file(d)	0
  #define	remove_debug_file(d)	do{}while(0)
  
  #endif				/* CONFIG_DEBUG_FS */
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
  
  /*-----------------------------------------------------------------*/
  
  /*
    Software reset - can be called from any contect.
  */
  static int isp116x_sw_reset(struct isp116x *isp116x)
  {
  	int retries = 15;
  	unsigned long flags;
  	int ret = 0;
  
  	spin_lock_irqsave(&isp116x->lock, flags);
  	isp116x_write_reg16(isp116x, HCSWRES, HCSWRES_MAGIC);
  	isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR);
  	while (--retries) {
  		/* It usually resets within 1 ms */
  		mdelay(1);
  		if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR))
  			break;
  	}
  	if (!retries) {
  		ERR("Software reset timeout
  ");
  		ret = -ETIME;
  	}
  	spin_unlock_irqrestore(&isp116x->lock, flags);
  	return ret;
  }
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1267
1268
1269
1270
1271
  static int isp116x_reset(struct usb_hcd *hcd)
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	unsigned long t;
  	u16 clkrdy = 0;
959eea219   Olav Kongas   [PATCH] USB: isp1...
1272
  	int ret, timeout = 15 /* ms */ ;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1273

f8d23d309   Olav Kongas   [PATCH] USB: isp1...
1274
  	ret = isp116x_sw_reset(isp116x);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
  	if (ret)
  		return ret;
  
  	t = jiffies + msecs_to_jiffies(timeout);
  	while (time_before_eq(jiffies, t)) {
  		msleep(4);
  		spin_lock_irq(&isp116x->lock);
  		clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY;
  		spin_unlock_irq(&isp116x->lock);
  		if (clkrdy)
  			break;
  	}
  	if (!clkrdy) {
959eea219   Olav Kongas   [PATCH] USB: isp1...
1288
1289
  		ERR("Clock not ready after %dms
  ", timeout);
589a0083a   Olav Kongas   [PATCH] USB: Fix ...
1290
1291
  		/* After sw_reset the clock won't report to be ready, if
  		   H_WAKEUP pin is high. */
f8d23d309   Olav Kongas   [PATCH] USB: isp1...
1292
1293
  		ERR("Please make sure that the H_WAKEUP pin is pulled low!
  ");
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
  		ret = -ENODEV;
  	}
  	return ret;
  }
  
  static void isp116x_stop(struct usb_hcd *hcd)
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	unsigned long flags;
  	u32 val;
  
  	spin_lock_irqsave(&isp116x->lock, flags);
  	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
  
  	/* Switch off ports' power, some devices don't come up
  	   after next 'insmod' without this */
  	val = isp116x_read_reg32(isp116x, HCRHDESCA);
  	val &= ~(RH_A_NPS | RH_A_PSM);
  	isp116x_write_reg32(isp116x, HCRHDESCA, val);
  	isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
  	spin_unlock_irqrestore(&isp116x->lock, flags);
f8d23d309   Olav Kongas   [PATCH] USB: isp1...
1315
  	isp116x_sw_reset(isp116x);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1316
1317
1318
1319
1320
1321
1322
1323
1324
  }
  
  /*
    Configure the chip. The chip must be successfully reset by now.
  */
  static int isp116x_start(struct usb_hcd *hcd)
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	struct isp116x_platform_data *board = isp116x->board;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
  	u32 val;
  	unsigned long flags;
  
  	spin_lock_irqsave(&isp116x->lock, flags);
  
  	/* clear interrupt status and disable all interrupt sources */
  	isp116x_write_reg16(isp116x, HCuPINT, 0xff);
  	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
  
  	val = isp116x_read_reg16(isp116x, HCCHIPID);
  	if ((val & HCCHIPID_MASK) != HCCHIPID_MAGIC) {
  		ERR("Invalid chip ID %04x
  ", val);
  		spin_unlock_irqrestore(&isp116x->lock, flags);
  		return -ENODEV;
  	}
9a57116bc   Olav Kongas   [PATCH] USB: Swit...
1341
1342
  	/* To be removed in future */
  	hcd->uses_new_polling = 1;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1343
1344
1345
1346
1347
1348
1349
1350
  	isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
  	isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
  
  	/* ----- HW conf */
  	val = HCHWCFG_INT_ENABLE | HCHWCFG_DBWIDTH(1);
  	if (board->sel15Kres)
  		val |= HCHWCFG_15KRSEL;
  	/* Remote wakeup won't work without working clock */
d4d62861b   Olav Kongas   [PATCH] USB: isp1...
1351
  	if (board->remote_wakeup_enable)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
  		val |= HCHWCFG_CLKNOTSTOP;
  	if (board->oc_enable)
  		val |= HCHWCFG_ANALOG_OC;
  	if (board->int_act_high)
  		val |= HCHWCFG_INT_POL;
  	if (board->int_edge_triggered)
  		val |= HCHWCFG_INT_TRIGGER;
  	isp116x_write_reg16(isp116x, HCHWCFG, val);
  
  	/* ----- Root hub conf */
dc5bed091   Olav Kongas   [PATCH] USB: isp1...
1362
  	val = (25 << 24) & RH_A_POTPGT;
165c0f393   Olav Kongas   [PATCH] USB: isp1...
1363
1364
1365
1366
  	/* AN10003_1.pdf recommends RH_A_NPS (no power switching) to
  	   be always set. Yet, instead, we request individual port
  	   power switching. */
  	val |= RH_A_PSM;
9d233d9fa   Olav Kongas   [PATCH] USB: isp1...
1367
1368
  	/* Report overcurrent per port */
  	val |= RH_A_OCPM;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1369
1370
1371
1372
1373
1374
1375
1376
1377
  	isp116x_write_reg32(isp116x, HCRHDESCA, val);
  	isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
  
  	val = RH_B_PPCM;
  	isp116x_write_reg32(isp116x, HCRHDESCB, val);
  	isp116x->rhdescb = isp116x_read_reg32(isp116x, HCRHDESCB);
  
  	val = 0;
  	if (board->remote_wakeup_enable) {
704aa0b7a   David Brownell   [PATCH] USB: wake...
1378
1379
  		if (!device_can_wakeup(hcd->self.controller))
  			device_init_wakeup(hcd->self.controller, 1);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1380
1381
1382
1383
1384
1385
  		val |= RH_HS_DRWE;
  	}
  	isp116x_write_reg32(isp116x, HCRHSTATUS, val);
  	isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
  
  	isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1386

4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1387
  	hcd->state = HC_STATE_RUNNING;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
  	/* Set up interrupts */
  	isp116x->intenb = HCINT_MIE | HCINT_RHSC | HCINT_UE;
  	if (board->remote_wakeup_enable)
  		isp116x->intenb |= HCINT_RD;
  	isp116x->irqenb = HCuPINT_ATL | HCuPINT_OPR;	/* | HCuPINT_SUSP; */
  	isp116x_write_reg32(isp116x, HCINTENB, isp116x->intenb);
  	isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb);
  
  	/* Go operational */
  	val = HCCONTROL_USB_OPER;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1398
1399
1400
1401
1402
1403
1404
  	if (board->remote_wakeup_enable)
  		val |= HCCONTROL_RWE;
  	isp116x_write_reg32(isp116x, HCCONTROL, val);
  
  	/* Disable ports to avoid race in device enumeration */
  	isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
  	isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1405
  	isp116x_show_regs_log(isp116x);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1406
1407
1408
  	spin_unlock_irqrestore(&isp116x->lock, flags);
  	return 0;
  }
959eea219   Olav Kongas   [PATCH] USB: isp1...
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
  #ifdef	CONFIG_PM
  
  static int isp116x_bus_suspend(struct usb_hcd *hcd)
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	unsigned long flags;
  	u32 val;
  	int ret = 0;
  
  	spin_lock_irqsave(&isp116x->lock, flags);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1419
  	val = isp116x_read_reg32(isp116x, HCCONTROL);
0be930c54   Olav Kongas   [PATCH] USB: isp1...
1420

959eea219   Olav Kongas   [PATCH] USB: isp1...
1421
1422
  	switch (val & HCCONTROL_HCFS) {
  	case HCCONTROL_USB_OPER:
0be930c54   Olav Kongas   [PATCH] USB: isp1...
1423
  		spin_unlock_irqrestore(&isp116x->lock, flags);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1424
1425
  		val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
  		val |= HCCONTROL_USB_SUSPEND;
58a97ffeb   Alan Stern   USB: HCDs use the...
1426
  		if (hcd->self.root_hub->do_remote_wakeup)
959eea219   Olav Kongas   [PATCH] USB: isp1...
1427
1428
  			val |= HCCONTROL_RWE;
  		/* Wait for usb transfers to finish */
0be930c54   Olav Kongas   [PATCH] USB: isp1...
1429
1430
  		msleep(2);
  		spin_lock_irqsave(&isp116x->lock, flags);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1431
  		isp116x_write_reg32(isp116x, HCCONTROL, val);
0be930c54   Olav Kongas   [PATCH] USB: isp1...
1432
  		spin_unlock_irqrestore(&isp116x->lock, flags);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1433
  		/* Wait for devices to suspend */
0be930c54   Olav Kongas   [PATCH] USB: isp1...
1434
  		msleep(5);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1435
1436
1437
1438
1439
1440
1441
  		break;
  	case HCCONTROL_USB_RESUME:
  		isp116x_write_reg32(isp116x, HCCONTROL,
  				    (val & ~HCCONTROL_HCFS) |
  				    HCCONTROL_USB_RESET);
  	case HCCONTROL_USB_RESET:
  		ret = -EBUSY;
0be930c54   Olav Kongas   [PATCH] USB: isp1...
1442
1443
  	default:		/* HCCONTROL_USB_SUSPEND */
  		spin_unlock_irqrestore(&isp116x->lock, flags);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1444
  		break;
959eea219   Olav Kongas   [PATCH] USB: isp1...
1445
  	}
959eea219   Olav Kongas   [PATCH] USB: isp1...
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
  	return ret;
  }
  
  static int isp116x_bus_resume(struct usb_hcd *hcd)
  {
  	struct isp116x *isp116x = hcd_to_isp116x(hcd);
  	u32 val;
  
  	msleep(5);
  	spin_lock_irq(&isp116x->lock);
  
  	val = isp116x_read_reg32(isp116x, HCCONTROL);
  	switch (val & HCCONTROL_HCFS) {
  	case HCCONTROL_USB_SUSPEND:
  		val &= ~HCCONTROL_HCFS;
  		val |= HCCONTROL_USB_RESUME;
  		isp116x_write_reg32(isp116x, HCCONTROL, val);
  	case HCCONTROL_USB_RESUME:
  		break;
  	case HCCONTROL_USB_OPER:
  		spin_unlock_irq(&isp116x->lock);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
  		return 0;
  	default:
  		/* HCCONTROL_USB_RESET: this may happen, when during
  		   suspension the HC lost power. Reinitialize completely */
  		spin_unlock_irq(&isp116x->lock);
  		DBG("Chip has been reset while suspended. Reinit from scratch.
  ");
  		isp116x_reset(hcd);
  		isp116x_start(hcd);
  		isp116x_hub_control(hcd, SetPortFeature,
  				    USB_PORT_FEAT_POWER, 1, NULL, 0);
  		if ((isp116x->rhdesca & RH_A_NDP) == 2)
  			isp116x_hub_control(hcd, SetPortFeature,
  					    USB_PORT_FEAT_POWER, 2, NULL, 0);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
  		return 0;
  	}
  
  	val = isp116x->rhdesca & RH_A_NDP;
  	while (val--) {
  		u32 stat =
  		    isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1);
  		/* force global, not selective, resume */
  		if (!(stat & RH_PS_PSS))
  			continue;
  		DBG("%s: Resuming port %d
  ", __func__, val);
  		isp116x_write_reg32(isp116x, RH_PS_POCI, val
  				    ? HCRHPORT2 : HCRHPORT1);
  	}
  	spin_unlock_irq(&isp116x->lock);
  
  	hcd->state = HC_STATE_RESUMING;
  	msleep(20);
  
  	/* Go operational */
  	spin_lock_irq(&isp116x->lock);
  	val = isp116x_read_reg32(isp116x, HCCONTROL);
  	isp116x_write_reg32(isp116x, HCCONTROL,
  			    (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
  	spin_unlock_irq(&isp116x->lock);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
  	hcd->state = HC_STATE_RUNNING;
  
  	return 0;
  }
  
  #else
  
  #define	isp116x_bus_suspend	NULL
  #define	isp116x_bus_resume	NULL
  
  #endif
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
  
  static struct hc_driver isp116x_hc_driver = {
  	.description = hcd_name,
  	.product_desc = "ISP116x Host Controller",
  	.hcd_priv_size = sizeof(struct isp116x),
  
  	.irq = isp116x_irq,
  	.flags = HCD_USB11,
  
  	.reset = isp116x_reset,
  	.start = isp116x_start,
  	.stop = isp116x_stop,
  
  	.urb_enqueue = isp116x_urb_enqueue,
  	.urb_dequeue = isp116x_urb_dequeue,
  	.endpoint_disable = isp116x_endpoint_disable,
  
  	.get_frame_number = isp116x_get_frame,
  
  	.hub_status_data = isp116x_hub_status_data,
  	.hub_control = isp116x_hub_control,
0c0382e32   Alan Stern   [PATCH] USB: Rena...
1539
1540
  	.bus_suspend = isp116x_bus_suspend,
  	.bus_resume = isp116x_bus_resume,
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1541
1542
1543
  };
  
  /*----------------------------------------------------------------*/
b712548c5   Greg Kroah-Hartman   [PATCH] USB: fix ...
1544
  static int isp116x_remove(struct platform_device *pdev)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1545
  {
3ae5eaec1   Russell King   [DRIVER MODEL] Co...
1546
  	struct usb_hcd *hcd = platform_get_drvdata(pdev);
589a0083a   Olav Kongas   [PATCH] USB: Fix ...
1547
  	struct isp116x *isp116x;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1548
  	struct resource *res;
9a57116bc   Olav Kongas   [PATCH] USB: Swit...
1549
  	if (!hcd)
589a0083a   Olav Kongas   [PATCH] USB: Fix ...
1550
1551
  		return 0;
  	isp116x = hcd_to_isp116x(hcd);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
  	remove_debug_file(isp116x);
  	usb_remove_hcd(hcd);
  
  	iounmap(isp116x->data_reg);
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  	release_mem_region(res->start, 2);
  	iounmap(isp116x->addr_reg);
  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  	release_mem_region(res->start, 2);
  
  	usb_put_hcd(hcd);
  	return 0;
  }
  
  #define resource_len(r) (((r)->end - (r)->start) + 1)
5bcd70eba   Prarit Bhargava   USB: change __ini...
1567
  static int __devinit isp116x_probe(struct platform_device *pdev)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1568
1569
1570
  {
  	struct usb_hcd *hcd;
  	struct isp116x *isp116x;
271402193   Marc Zyngier   USB: Let some USB...
1571
  	struct resource *addr, *data, *ires;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1572
1573
1574
1575
  	void __iomem *addr_reg;
  	void __iomem *data_reg;
  	int irq;
  	int ret = 0;
271402193   Marc Zyngier   USB: Let some USB...
1576
  	unsigned long irqflags;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1577

4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1578
1579
1580
1581
1582
1583
1584
  	if (pdev->num_resources < 3) {
  		ret = -ENODEV;
  		goto err1;
  	}
  
  	data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  	addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
271402193   Marc Zyngier   USB: Let some USB...
1585
1586
1587
  	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  
  	if (!addr || !data || !ires) {
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1588
1589
1590
  		ret = -ENODEV;
  		goto err1;
  	}
271402193   Marc Zyngier   USB: Let some USB...
1591
1592
  	irq = ires->start;
  	irqflags = ires->flags & IRQF_TRIGGER_MASK;
3ae5eaec1   Russell King   [DRIVER MODEL] Co...
1593
  	if (pdev->dev.dma_mask) {
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
  		DBG("DMA not supported
  ");
  		ret = -EINVAL;
  		goto err1;
  	}
  
  	if (!request_mem_region(addr->start, 2, hcd_name)) {
  		ret = -EBUSY;
  		goto err1;
  	}
  	addr_reg = ioremap(addr->start, resource_len(addr));
  	if (addr_reg == NULL) {
  		ret = -ENOMEM;
  		goto err2;
  	}
  	if (!request_mem_region(data->start, 2, hcd_name)) {
  		ret = -EBUSY;
  		goto err3;
  	}
  	data_reg = ioremap(data->start, resource_len(data));
  	if (data_reg == NULL) {
  		ret = -ENOMEM;
  		goto err4;
  	}
  
  	/* allocate and initialize hcd */
7071a3ce0   Kay Sievers   USB: usb dev_name...
1620
  	hcd = usb_create_hcd(&isp116x_hc_driver, &pdev->dev, dev_name(&pdev->dev));
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
  	if (!hcd) {
  		ret = -ENOMEM;
  		goto err5;
  	}
  	/* this rsrc_start is bogus */
  	hcd->rsrc_start = addr->start;
  	isp116x = hcd_to_isp116x(hcd);
  	isp116x->data_reg = data_reg;
  	isp116x->addr_reg = addr_reg;
  	spin_lock_init(&isp116x->lock);
  	INIT_LIST_HEAD(&isp116x->async);
3ae5eaec1   Russell King   [DRIVER MODEL] Co...
1632
  	isp116x->board = pdev->dev.platform_data;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
  
  	if (!isp116x->board) {
  		ERR("Platform data structure not initialized
  ");
  		ret = -ENODEV;
  		goto err6;
  	}
  	if (isp116x_check_platform_delay(isp116x)) {
  		ERR("USE_PLATFORM_DELAY defined, but delay function not "
  		    "implemented.
  ");
  		ERR("See comments in drivers/usb/host/isp116x-hcd.c
  ");
  		ret = -ENODEV;
  		goto err6;
  	}
271402193   Marc Zyngier   USB: Let some USB...
1649
  	ret = usb_add_hcd(hcd, irq, irqflags | IRQF_DISABLED);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1650
  	if (ret)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1651
  		goto err6;
959eea219   Olav Kongas   [PATCH] USB: isp1...
1652
1653
1654
1655
1656
1657
  	ret = create_debug_file(isp116x);
  	if (ret) {
  		ERR("Couldn't create debugfs entry
  ");
  		goto err7;
  	}
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1658
  	return 0;
959eea219   Olav Kongas   [PATCH] USB: isp1...
1659
1660
        err7:
  	usb_remove_hcd(hcd);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
        err6:
  	usb_put_hcd(hcd);
        err5:
  	iounmap(data_reg);
        err4:
  	release_mem_region(data->start, 2);
        err3:
  	iounmap(addr_reg);
        err2:
  	release_mem_region(addr->start, 2);
        err1:
  	ERR("init error, %d
  ", ret);
  	return ret;
  }
  
  #ifdef	CONFIG_PM
  /*
    Suspend of platform device
  */
3ae5eaec1   Russell King   [DRIVER MODEL] Co...
1681
  static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1682
  {
959eea219   Olav Kongas   [PATCH] USB: isp1...
1683
1684
  	VDBG("%s: state %x
  ", __func__, state.event);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1685
  	return 0;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1686
1687
1688
1689
1690
  }
  
  /*
    Resume platform device
  */
3ae5eaec1   Russell King   [DRIVER MODEL] Co...
1691
  static int isp116x_resume(struct platform_device *dev)
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1692
  {
70a1c9e08   Alan Stern   USB: remove dev->...
1693
1694
  	VDBG("%s
  ", __func__);
959eea219   Olav Kongas   [PATCH] USB: isp1...
1695
  	return 0;
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1696
1697
1698
1699
1700
1701
1702
1703
  }
  
  #else
  
  #define	isp116x_suspend    NULL
  #define	isp116x_resume     NULL
  
  #endif
f4fce61d4   Kay Sievers   usb host: fix pla...
1704
1705
  /* work with hotplug and coldplug */
  MODULE_ALIAS("platform:isp116x-hcd");
3ae5eaec1   Russell King   [DRIVER MODEL] Co...
1706
  static struct platform_driver isp116x_driver = {
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1707
1708
1709
1710
  	.probe = isp116x_probe,
  	.remove = isp116x_remove,
  	.suspend = isp116x_suspend,
  	.resume = isp116x_resume,
0be930c54   Olav Kongas   [PATCH] USB: isp1...
1711
  	.driver = {
f4fce61d4   Kay Sievers   usb host: fix pla...
1712
1713
1714
  		.name = (char *)hcd_name,
  		.owner	= THIS_MODULE,
  	},
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
  };
  
  /*-----------------------------------------------------------------*/
  
  static int __init isp116x_init(void)
  {
  	if (usb_disabled())
  		return -ENODEV;
  
  	INFO("driver %s, %s
  ", hcd_name, DRIVER_VERSION);
3ae5eaec1   Russell King   [DRIVER MODEL] Co...
1726
  	return platform_driver_register(&isp116x_driver);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1727
1728
1729
1730
1731
1732
  }
  
  module_init(isp116x_init);
  
  static void __exit isp116x_cleanup(void)
  {
3ae5eaec1   Russell King   [DRIVER MODEL] Co...
1733
  	platform_driver_unregister(&isp116x_driver);
4808a1c02   Olav Kongas   [PATCH] USB: Add ...
1734
1735
1736
  }
  
  module_exit(isp116x_cleanup);