diff options
Diffstat (limited to 'drivers/usb/host')
31 files changed, 1411 insertions, 1132 deletions
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 350d14fc1cc9..58321d3f314c 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -1,8 +1,9 @@ | |||
1 | # | 1 | # |
2 | # Makefile for USB Host Controller Driver | 2 | # Makefile for USB Host Controller Drivers |
3 | # framework and drivers | ||
4 | # | 3 | # |
5 | 4 | ||
5 | obj-$(CONFIG_PCI) += pci-quirks.o | ||
6 | |||
6 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o | 7 | obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o |
7 | obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o | 8 | obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o |
8 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o | 9 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b948ffd94f45..29f52a44b928 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -182,6 +182,9 @@ static int ehci_halt (struct ehci_hcd *ehci) | |||
182 | { | 182 | { |
183 | u32 temp = readl (&ehci->regs->status); | 183 | u32 temp = readl (&ehci->regs->status); |
184 | 184 | ||
185 | /* disable any irqs left enabled by previous code */ | ||
186 | writel (0, &ehci->regs->intr_enable); | ||
187 | |||
185 | if ((temp & STS_HALT) != 0) | 188 | if ((temp & STS_HALT) != 0) |
186 | return 0; | 189 | return 0; |
187 | 190 | ||
@@ -297,50 +300,17 @@ static void ehci_watchdog (unsigned long param) | |||
297 | spin_unlock_irqrestore (&ehci->lock, flags); | 300 | spin_unlock_irqrestore (&ehci->lock, flags); |
298 | } | 301 | } |
299 | 302 | ||
300 | #ifdef CONFIG_PCI | 303 | /* Reboot notifiers kick in for silicon on any bus (not just pci, etc). |
301 | 304 | * This forcibly disables dma and IRQs, helping kexec and other cases | |
302 | /* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... | 305 | * where the next system software may expect clean state. |
303 | * off the controller (maybe it can boot from highspeed USB disks). | ||
304 | */ | 306 | */ |
305 | static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) | ||
306 | { | ||
307 | struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); | ||
308 | |||
309 | /* always say Linux will own the hardware */ | ||
310 | pci_write_config_byte(pdev, where + 3, 1); | ||
311 | |||
312 | /* maybe wait a while for BIOS to respond */ | ||
313 | if (cap & (1 << 16)) { | ||
314 | int msec = 5000; | ||
315 | |||
316 | do { | ||
317 | msleep(10); | ||
318 | msec -= 10; | ||
319 | pci_read_config_dword(pdev, where, &cap); | ||
320 | } while ((cap & (1 << 16)) && msec); | ||
321 | if (cap & (1 << 16)) { | ||
322 | ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", | ||
323 | where, cap); | ||
324 | // some BIOS versions seem buggy... | ||
325 | // return 1; | ||
326 | ehci_warn (ehci, "continuing after BIOS bug...\n"); | ||
327 | /* disable all SMIs, and clear "BIOS owns" flag */ | ||
328 | pci_write_config_dword(pdev, where + 4, 0); | ||
329 | pci_write_config_byte(pdev, where + 2, 0); | ||
330 | } else | ||
331 | ehci_dbg(ehci, "BIOS handoff succeeded\n"); | ||
332 | } | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | #endif | ||
337 | |||
338 | static int | 307 | static int |
339 | ehci_reboot (struct notifier_block *self, unsigned long code, void *null) | 308 | ehci_reboot (struct notifier_block *self, unsigned long code, void *null) |
340 | { | 309 | { |
341 | struct ehci_hcd *ehci; | 310 | struct ehci_hcd *ehci; |
342 | 311 | ||
343 | ehci = container_of (self, struct ehci_hcd, reboot_notifier); | 312 | ehci = container_of (self, struct ehci_hcd, reboot_notifier); |
313 | (void) ehci_halt (ehci); | ||
344 | 314 | ||
345 | /* make BIOS/etc use companion controller during reboot */ | 315 | /* make BIOS/etc use companion controller during reboot */ |
346 | writel (0, &ehci->regs->configured_flag); | 316 | writel (0, &ehci->regs->configured_flag); |
@@ -363,215 +333,117 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | |||
363 | msleep(20); | 333 | msleep(20); |
364 | } | 334 | } |
365 | 335 | ||
336 | /*-------------------------------------------------------------------------*/ | ||
337 | |||
338 | /* | ||
339 | * ehci_work is called from some interrupts, timers, and so on. | ||
340 | * it calls driver completion functions, after dropping ehci->lock. | ||
341 | */ | ||
342 | static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) | ||
343 | { | ||
344 | timer_action_done (ehci, TIMER_IO_WATCHDOG); | ||
345 | if (ehci->reclaim_ready) | ||
346 | end_unlink_async (ehci, regs); | ||
347 | |||
348 | /* another CPU may drop ehci->lock during a schedule scan while | ||
349 | * it reports urb completions. this flag guards against bogus | ||
350 | * attempts at re-entrant schedule scanning. | ||
351 | */ | ||
352 | if (ehci->scanning) | ||
353 | return; | ||
354 | ehci->scanning = 1; | ||
355 | scan_async (ehci, regs); | ||
356 | if (ehci->next_uframe != -1) | ||
357 | scan_periodic (ehci, regs); | ||
358 | ehci->scanning = 0; | ||
366 | 359 | ||
367 | /* called by khubd or root hub init threads */ | 360 | /* the IO watchdog guards against hardware or driver bugs that |
361 | * misplace IRQs, and should let us run completely without IRQs. | ||
362 | * such lossage has been observed on both VT6202 and VT8235. | ||
363 | */ | ||
364 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && | ||
365 | (ehci->async->qh_next.ptr != NULL || | ||
366 | ehci->periodic_sched != 0)) | ||
367 | timer_action (ehci, TIMER_IO_WATCHDOG); | ||
368 | } | ||
368 | 369 | ||
369 | static int ehci_hc_reset (struct usb_hcd *hcd) | 370 | static void ehci_stop (struct usb_hcd *hcd) |
370 | { | 371 | { |
371 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 372 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
372 | u32 temp; | ||
373 | unsigned count = 256/4; | ||
374 | 373 | ||
375 | spin_lock_init (&ehci->lock); | 374 | ehci_dbg (ehci, "stop\n"); |
376 | 375 | ||
377 | ehci->caps = hcd->regs; | 376 | /* Turn off port power on all root hub ports. */ |
378 | ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase)); | 377 | ehci_port_power (ehci, 0); |
379 | dbg_hcs_params (ehci, "reset"); | ||
380 | dbg_hcc_params (ehci, "reset"); | ||
381 | 378 | ||
382 | /* cache this readonly data; minimize chip reads */ | 379 | /* no more interrupts ... */ |
383 | ehci->hcs_params = readl (&ehci->caps->hcs_params); | 380 | del_timer_sync (&ehci->watchdog); |
384 | 381 | ||
385 | #ifdef CONFIG_PCI | 382 | spin_lock_irq(&ehci->lock); |
386 | if (hcd->self.controller->bus == &pci_bus_type) { | 383 | if (HC_IS_RUNNING (hcd->state)) |
387 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 384 | ehci_quiesce (ehci); |
388 | 385 | ||
389 | switch (pdev->vendor) { | 386 | ehci_reset (ehci); |
390 | case PCI_VENDOR_ID_TDI: | 387 | writel (0, &ehci->regs->intr_enable); |
391 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { | 388 | spin_unlock_irq(&ehci->lock); |
392 | ehci->is_tdi_rh_tt = 1; | ||
393 | tdi_reset (ehci); | ||
394 | } | ||
395 | break; | ||
396 | case PCI_VENDOR_ID_AMD: | ||
397 | /* AMD8111 EHCI doesn't work, according to AMD errata */ | ||
398 | if (pdev->device == 0x7463) { | ||
399 | ehci_info (ehci, "ignoring AMD8111 (errata)\n"); | ||
400 | return -EIO; | ||
401 | } | ||
402 | break; | ||
403 | case PCI_VENDOR_ID_NVIDIA: | ||
404 | /* NVidia reports that certain chips don't handle | ||
405 | * QH, ITD, or SITD addresses above 2GB. (But TD, | ||
406 | * data buffer, and periodic schedule are normal.) | ||
407 | */ | ||
408 | switch (pdev->device) { | ||
409 | case 0x003c: /* MCP04 */ | ||
410 | case 0x005b: /* CK804 */ | ||
411 | case 0x00d8: /* CK8 */ | ||
412 | case 0x00e8: /* CK8S */ | ||
413 | if (pci_set_consistent_dma_mask(pdev, | ||
414 | DMA_31BIT_MASK) < 0) | ||
415 | ehci_warn (ehci, "can't enable NVidia " | ||
416 | "workaround for >2GB RAM\n"); | ||
417 | break; | ||
418 | } | ||
419 | break; | ||
420 | } | ||
421 | 389 | ||
422 | /* optional debug port, normally in the first BAR */ | 390 | /* let companion controllers work when we aren't */ |
423 | temp = pci_find_capability (pdev, 0x0a); | 391 | writel (0, &ehci->regs->configured_flag); |
424 | if (temp) { | 392 | unregister_reboot_notifier (&ehci->reboot_notifier); |
425 | pci_read_config_dword(pdev, temp, &temp); | ||
426 | temp >>= 16; | ||
427 | if ((temp & (3 << 13)) == (1 << 13)) { | ||
428 | temp &= 0x1fff; | ||
429 | ehci->debug = hcd->regs + temp; | ||
430 | temp = readl (&ehci->debug->control); | ||
431 | ehci_info (ehci, "debug port %d%s\n", | ||
432 | HCS_DEBUG_PORT(ehci->hcs_params), | ||
433 | (temp & DBGP_ENABLED) | ||
434 | ? " IN USE" | ||
435 | : ""); | ||
436 | if (!(temp & DBGP_ENABLED)) | ||
437 | ehci->debug = NULL; | ||
438 | } | ||
439 | } | ||
440 | 393 | ||
441 | temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); | 394 | remove_debug_files (ehci); |
442 | } else | ||
443 | temp = 0; | ||
444 | |||
445 | /* EHCI 0.96 and later may have "extended capabilities" */ | ||
446 | while (temp && count--) { | ||
447 | u32 cap; | ||
448 | |||
449 | pci_read_config_dword (to_pci_dev(hcd->self.controller), | ||
450 | temp, &cap); | ||
451 | ehci_dbg (ehci, "capability %04x at %02x\n", cap, temp); | ||
452 | switch (cap & 0xff) { | ||
453 | case 1: /* BIOS/SMM/... handoff */ | ||
454 | if (bios_handoff (ehci, temp, cap) != 0) | ||
455 | return -EOPNOTSUPP; | ||
456 | break; | ||
457 | case 0: /* illegal reserved capability */ | ||
458 | ehci_warn (ehci, "illegal capability!\n"); | ||
459 | cap = 0; | ||
460 | /* FALLTHROUGH */ | ||
461 | default: /* unknown */ | ||
462 | break; | ||
463 | } | ||
464 | temp = (cap >> 8) & 0xff; | ||
465 | } | ||
466 | if (!count) { | ||
467 | ehci_err (ehci, "bogus capabilities ... PCI problems!\n"); | ||
468 | return -EIO; | ||
469 | } | ||
470 | if (ehci_is_TDI(ehci)) | ||
471 | ehci_reset (ehci); | ||
472 | #endif | ||
473 | 395 | ||
474 | ehci_port_power (ehci, 0); | 396 | /* root hub is shut down separately (first, when possible) */ |
397 | spin_lock_irq (&ehci->lock); | ||
398 | if (ehci->async) | ||
399 | ehci_work (ehci, NULL); | ||
400 | spin_unlock_irq (&ehci->lock); | ||
401 | ehci_mem_cleanup (ehci); | ||
475 | 402 | ||
476 | /* at least the Genesys GL880S needs fixup here */ | 403 | #ifdef EHCI_STATS |
477 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); | 404 | ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", |
478 | temp &= 0x0f; | 405 | ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, |
479 | if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { | 406 | ehci->stats.lost_iaa); |
480 | ehci_dbg (ehci, "bogus port configuration: " | 407 | ehci_dbg (ehci, "complete %ld unlink %ld\n", |
481 | "cc=%d x pcc=%d < ports=%d\n", | 408 | ehci->stats.complete, ehci->stats.unlink); |
482 | HCS_N_CC(ehci->hcs_params), | ||
483 | HCS_N_PCC(ehci->hcs_params), | ||
484 | HCS_N_PORTS(ehci->hcs_params)); | ||
485 | |||
486 | #ifdef CONFIG_PCI | ||
487 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
488 | struct pci_dev *pdev; | ||
489 | |||
490 | pdev = to_pci_dev(hcd->self.controller); | ||
491 | switch (pdev->vendor) { | ||
492 | case 0x17a0: /* GENESYS */ | ||
493 | /* GL880S: should be PORTS=2 */ | ||
494 | temp |= (ehci->hcs_params & ~0xf); | ||
495 | ehci->hcs_params = temp; | ||
496 | break; | ||
497 | case PCI_VENDOR_ID_NVIDIA: | ||
498 | /* NF4: should be PCC=10 */ | ||
499 | break; | ||
500 | } | ||
501 | } | ||
502 | #endif | 409 | #endif |
503 | } | ||
504 | 410 | ||
505 | /* force HC to halt state */ | 411 | dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); |
506 | return ehci_halt (ehci); | ||
507 | } | 412 | } |
508 | 413 | ||
509 | static int ehci_start (struct usb_hcd *hcd) | 414 | /* one-time init, only for memory state */ |
415 | static int ehci_init(struct usb_hcd *hcd) | ||
510 | { | 416 | { |
511 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 417 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
512 | u32 temp; | 418 | u32 temp; |
513 | int retval; | 419 | int retval; |
514 | u32 hcc_params; | 420 | u32 hcc_params; |
515 | u8 sbrn = 0; | 421 | |
516 | int first; | 422 | spin_lock_init(&ehci->lock); |
517 | 423 | ||
518 | /* skip some things on restart paths */ | 424 | init_timer(&ehci->watchdog); |
519 | first = (ehci->watchdog.data == 0); | 425 | ehci->watchdog.function = ehci_watchdog; |
520 | if (first) { | 426 | ehci->watchdog.data = (unsigned long) ehci; |
521 | init_timer (&ehci->watchdog); | ||
522 | ehci->watchdog.function = ehci_watchdog; | ||
523 | ehci->watchdog.data = (unsigned long) ehci; | ||
524 | } | ||
525 | 427 | ||
526 | /* | 428 | /* |
527 | * hw default: 1K periodic list heads, one per frame. | 429 | * hw default: 1K periodic list heads, one per frame. |
528 | * periodic_size can shrink by USBCMD update if hcc_params allows. | 430 | * periodic_size can shrink by USBCMD update if hcc_params allows. |
529 | */ | 431 | */ |
530 | ehci->periodic_size = DEFAULT_I_TDPS; | 432 | ehci->periodic_size = DEFAULT_I_TDPS; |
531 | if (first && (retval = ehci_mem_init (ehci, GFP_KERNEL)) < 0) | 433 | if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) |
532 | return retval; | 434 | return retval; |
533 | 435 | ||
534 | /* controllers may cache some of the periodic schedule ... */ | 436 | /* controllers may cache some of the periodic schedule ... */ |
535 | hcc_params = readl (&ehci->caps->hcc_params); | 437 | hcc_params = readl(&ehci->caps->hcc_params); |
536 | if (HCC_ISOC_CACHE (hcc_params)) // full frame cache | 438 | if (HCC_ISOC_CACHE(hcc_params)) // full frame cache |
537 | ehci->i_thresh = 8; | 439 | ehci->i_thresh = 8; |
538 | else // N microframes cached | 440 | else // N microframes cached |
539 | ehci->i_thresh = 2 + HCC_ISOC_THRES (hcc_params); | 441 | ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); |
540 | 442 | ||
541 | ehci->reclaim = NULL; | 443 | ehci->reclaim = NULL; |
542 | ehci->reclaim_ready = 0; | 444 | ehci->reclaim_ready = 0; |
543 | ehci->next_uframe = -1; | 445 | ehci->next_uframe = -1; |
544 | 446 | ||
545 | /* controller state: unknown --> reset */ | ||
546 | |||
547 | /* EHCI spec section 4.1 */ | ||
548 | if ((retval = ehci_reset (ehci)) != 0) { | ||
549 | ehci_mem_cleanup (ehci); | ||
550 | return retval; | ||
551 | } | ||
552 | writel (ehci->periodic_dma, &ehci->regs->frame_list); | ||
553 | |||
554 | #ifdef CONFIG_PCI | ||
555 | if (hcd->self.controller->bus == &pci_bus_type) { | ||
556 | struct pci_dev *pdev; | ||
557 | u16 port_wake; | ||
558 | |||
559 | pdev = to_pci_dev(hcd->self.controller); | ||
560 | |||
561 | /* Serial Bus Release Number is at PCI 0x60 offset */ | ||
562 | pci_read_config_byte(pdev, 0x60, &sbrn); | ||
563 | |||
564 | /* port wake capability, reported by boot firmware */ | ||
565 | pci_read_config_word(pdev, 0x62, &port_wake); | ||
566 | hcd->can_wakeup = (port_wake & 1) != 0; | ||
567 | |||
568 | /* help hc dma work well with cachelines */ | ||
569 | retval = pci_set_mwi(pdev); | ||
570 | if (retval) | ||
571 | ehci_dbg(ehci, "unable to enable MWI - not fatal.\n"); | ||
572 | } | ||
573 | #endif | ||
574 | |||
575 | /* | 447 | /* |
576 | * dedicate a qh for the async ring head, since we couldn't unlink | 448 | * dedicate a qh for the async ring head, since we couldn't unlink |
577 | * a 'real' qh without stopping the async schedule [4.8]. use it | 449 | * a 'real' qh without stopping the async schedule [4.8]. use it |
@@ -579,37 +451,13 @@ static int ehci_start (struct usb_hcd *hcd) | |||
579 | * its dummy is used in hw_alt_next of many tds, to prevent the qh | 451 | * its dummy is used in hw_alt_next of many tds, to prevent the qh |
580 | * from automatically advancing to the next td after short reads. | 452 | * from automatically advancing to the next td after short reads. |
581 | */ | 453 | */ |
582 | if (first) { | 454 | ehci->async->qh_next.qh = NULL; |
583 | ehci->async->qh_next.qh = NULL; | 455 | ehci->async->hw_next = QH_NEXT(ehci->async->qh_dma); |
584 | ehci->async->hw_next = QH_NEXT (ehci->async->qh_dma); | 456 | ehci->async->hw_info1 = cpu_to_le32(QH_HEAD); |
585 | ehci->async->hw_info1 = cpu_to_le32 (QH_HEAD); | 457 | ehci->async->hw_token = cpu_to_le32(QTD_STS_HALT); |
586 | ehci->async->hw_token = cpu_to_le32 (QTD_STS_HALT); | 458 | ehci->async->hw_qtd_next = EHCI_LIST_END; |
587 | ehci->async->hw_qtd_next = EHCI_LIST_END; | 459 | ehci->async->qh_state = QH_STATE_LINKED; |
588 | ehci->async->qh_state = QH_STATE_LINKED; | 460 | ehci->async->hw_alt_next = QTD_NEXT(ehci->async->dummy->qtd_dma); |
589 | ehci->async->hw_alt_next = QTD_NEXT (ehci->async->dummy->qtd_dma); | ||
590 | } | ||
591 | writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next); | ||
592 | |||
593 | /* | ||
594 | * hcc_params controls whether ehci->regs->segment must (!!!) | ||
595 | * be used; it constrains QH/ITD/SITD and QTD locations. | ||
596 | * pci_pool consistent memory always uses segment zero. | ||
597 | * streaming mappings for I/O buffers, like pci_map_single(), | ||
598 | * can return segments above 4GB, if the device allows. | ||
599 | * | ||
600 | * NOTE: the dma mask is visible through dma_supported(), so | ||
601 | * drivers can pass this info along ... like NETIF_F_HIGHDMA, | ||
602 | * Scsi_Host.highmem_io, and so forth. It's readonly to all | ||
603 | * host side drivers though. | ||
604 | */ | ||
605 | if (HCC_64BIT_ADDR (hcc_params)) { | ||
606 | writel (0, &ehci->regs->segment); | ||
607 | #if 0 | ||
608 | // this is deeply broken on almost all architectures | ||
609 | if (!dma_set_mask (hcd->self.controller, DMA_64BIT_MASK)) | ||
610 | ehci_info (ehci, "enabled 64bit DMA\n"); | ||
611 | #endif | ||
612 | } | ||
613 | 461 | ||
614 | /* clear interrupt enables, set irq latency */ | 462 | /* clear interrupt enables, set irq latency */ |
615 | if (log2_irq_thresh < 0 || log2_irq_thresh > 6) | 463 | if (log2_irq_thresh < 0 || log2_irq_thresh > 6) |
@@ -624,13 +472,13 @@ static int ehci_start (struct usb_hcd *hcd) | |||
624 | * make problems: throughput reduction (!), data errors... | 472 | * make problems: throughput reduction (!), data errors... |
625 | */ | 473 | */ |
626 | if (park) { | 474 | if (park) { |
627 | park = min (park, (unsigned) 3); | 475 | park = min(park, (unsigned) 3); |
628 | temp |= CMD_PARK; | 476 | temp |= CMD_PARK; |
629 | temp |= park << 8; | 477 | temp |= park << 8; |
630 | } | 478 | } |
631 | ehci_info (ehci, "park %d\n", park); | 479 | ehci_dbg(ehci, "park %d\n", park); |
632 | } | 480 | } |
633 | if (HCC_PGM_FRAMELISTLEN (hcc_params)) { | 481 | if (HCC_PGM_FRAMELISTLEN(hcc_params)) { |
634 | /* periodic schedule size can be smaller than default */ | 482 | /* periodic schedule size can be smaller than default */ |
635 | temp &= ~(3 << 2); | 483 | temp &= ~(3 << 2); |
636 | temp |= (EHCI_TUNE_FLS << 2); | 484 | temp |= (EHCI_TUNE_FLS << 2); |
@@ -638,16 +486,63 @@ static int ehci_start (struct usb_hcd *hcd) | |||
638 | case 0: ehci->periodic_size = 1024; break; | 486 | case 0: ehci->periodic_size = 1024; break; |
639 | case 1: ehci->periodic_size = 512; break; | 487 | case 1: ehci->periodic_size = 512; break; |
640 | case 2: ehci->periodic_size = 256; break; | 488 | case 2: ehci->periodic_size = 256; break; |
641 | default: BUG (); | 489 | default: BUG(); |
642 | } | 490 | } |
643 | } | 491 | } |
492 | ehci->command = temp; | ||
493 | |||
494 | ehci->reboot_notifier.notifier_call = ehci_reboot; | ||
495 | register_reboot_notifier(&ehci->reboot_notifier); | ||
496 | |||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | /* start HC running; it's halted, ehci_init() has been run (once) */ | ||
501 | static int ehci_run (struct usb_hcd *hcd) | ||
502 | { | ||
503 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
504 | int retval; | ||
505 | u32 temp; | ||
506 | u32 hcc_params; | ||
507 | |||
508 | /* EHCI spec section 4.1 */ | ||
509 | if ((retval = ehci_reset(ehci)) != 0) { | ||
510 | unregister_reboot_notifier(&ehci->reboot_notifier); | ||
511 | ehci_mem_cleanup(ehci); | ||
512 | return retval; | ||
513 | } | ||
514 | writel(ehci->periodic_dma, &ehci->regs->frame_list); | ||
515 | writel((u32)ehci->async->qh_dma, &ehci->regs->async_next); | ||
516 | |||
517 | /* | ||
518 | * hcc_params controls whether ehci->regs->segment must (!!!) | ||
519 | * be used; it constrains QH/ITD/SITD and QTD locations. | ||
520 | * pci_pool consistent memory always uses segment zero. | ||
521 | * streaming mappings for I/O buffers, like pci_map_single(), | ||
522 | * can return segments above 4GB, if the device allows. | ||
523 | * | ||
524 | * NOTE: the dma mask is visible through dma_supported(), so | ||
525 | * drivers can pass this info along ... like NETIF_F_HIGHDMA, | ||
526 | * Scsi_Host.highmem_io, and so forth. It's readonly to all | ||
527 | * host side drivers though. | ||
528 | */ | ||
529 | hcc_params = readl(&ehci->caps->hcc_params); | ||
530 | if (HCC_64BIT_ADDR(hcc_params)) { | ||
531 | writel(0, &ehci->regs->segment); | ||
532 | #if 0 | ||
533 | // this is deeply broken on almost all architectures | ||
534 | if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK)) | ||
535 | ehci_info(ehci, "enabled 64bit DMA\n"); | ||
536 | #endif | ||
537 | } | ||
538 | |||
539 | |||
644 | // Philips, Intel, and maybe others need CMD_RUN before the | 540 | // Philips, Intel, and maybe others need CMD_RUN before the |
645 | // root hub will detect new devices (why?); NEC doesn't | 541 | // root hub will detect new devices (why?); NEC doesn't |
646 | temp |= CMD_RUN; | 542 | ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); |
647 | writel (temp, &ehci->regs->command); | 543 | ehci->command |= CMD_RUN; |
648 | dbg_cmd (ehci, "init", temp); | 544 | writel (ehci->command, &ehci->regs->command); |
649 | 545 | dbg_cmd (ehci, "init", ehci->command); | |
650 | /* set async sleep time = 10 us ... ? */ | ||
651 | 546 | ||
652 | /* | 547 | /* |
653 | * Start, enabling full USB 2.0 functionality ... usb 1.1 devices | 548 | * Start, enabling full USB 2.0 functionality ... usb 1.1 devices |
@@ -655,210 +550,25 @@ static int ehci_start (struct usb_hcd *hcd) | |||
655 | * involved with the root hub. (Except where one is integrated, | 550 | * involved with the root hub. (Except where one is integrated, |
656 | * and there's no companion controller unless maybe for USB OTG.) | 551 | * and there's no companion controller unless maybe for USB OTG.) |
657 | */ | 552 | */ |
658 | if (first) { | ||
659 | ehci->reboot_notifier.notifier_call = ehci_reboot; | ||
660 | register_reboot_notifier (&ehci->reboot_notifier); | ||
661 | } | ||
662 | |||
663 | hcd->state = HC_STATE_RUNNING; | 553 | hcd->state = HC_STATE_RUNNING; |
664 | writel (FLAG_CF, &ehci->regs->configured_flag); | 554 | writel (FLAG_CF, &ehci->regs->configured_flag); |
665 | readl (&ehci->regs->command); /* unblock posted write */ | 555 | readl (&ehci->regs->command); /* unblock posted writes */ |
666 | 556 | ||
667 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); | 557 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); |
668 | ehci_info (ehci, | 558 | ehci_info (ehci, |
669 | "USB %x.%x %s, EHCI %x.%02x, driver %s\n", | 559 | "USB %x.%x started, EHCI %x.%02x, driver %s\n", |
670 | ((sbrn & 0xf0)>>4), (sbrn & 0x0f), | 560 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), |
671 | first ? "initialized" : "restarted", | ||
672 | temp >> 8, temp & 0xff, DRIVER_VERSION); | 561 | temp >> 8, temp & 0xff, DRIVER_VERSION); |
673 | 562 | ||
674 | writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ | 563 | writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ |
675 | 564 | ||
676 | if (first) | 565 | /* GRR this is run-once init(), being done every time the HC starts. |
677 | create_debug_files (ehci); | 566 | * So long as they're part of class devices, we can't do it init() |
678 | 567 | * since the class device isn't created that early. | |
679 | return 0; | ||
680 | } | ||
681 | |||
682 | /* always called by thread; normally rmmod */ | ||
683 | |||
684 | static void ehci_stop (struct usb_hcd *hcd) | ||
685 | { | ||
686 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
687 | |||
688 | ehci_dbg (ehci, "stop\n"); | ||
689 | |||
690 | /* Turn off port power on all root hub ports. */ | ||
691 | ehci_port_power (ehci, 0); | ||
692 | |||
693 | /* no more interrupts ... */ | ||
694 | del_timer_sync (&ehci->watchdog); | ||
695 | |||
696 | spin_lock_irq(&ehci->lock); | ||
697 | if (HC_IS_RUNNING (hcd->state)) | ||
698 | ehci_quiesce (ehci); | ||
699 | |||
700 | ehci_reset (ehci); | ||
701 | writel (0, &ehci->regs->intr_enable); | ||
702 | spin_unlock_irq(&ehci->lock); | ||
703 | |||
704 | /* let companion controllers work when we aren't */ | ||
705 | writel (0, &ehci->regs->configured_flag); | ||
706 | unregister_reboot_notifier (&ehci->reboot_notifier); | ||
707 | |||
708 | remove_debug_files (ehci); | ||
709 | |||
710 | /* root hub is shut down separately (first, when possible) */ | ||
711 | spin_lock_irq (&ehci->lock); | ||
712 | if (ehci->async) | ||
713 | ehci_work (ehci, NULL); | ||
714 | spin_unlock_irq (&ehci->lock); | ||
715 | ehci_mem_cleanup (ehci); | ||
716 | |||
717 | #ifdef EHCI_STATS | ||
718 | ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", | ||
719 | ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, | ||
720 | ehci->stats.lost_iaa); | ||
721 | ehci_dbg (ehci, "complete %ld unlink %ld\n", | ||
722 | ehci->stats.complete, ehci->stats.unlink); | ||
723 | #endif | ||
724 | |||
725 | dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); | ||
726 | } | ||
727 | |||
728 | static int ehci_get_frame (struct usb_hcd *hcd) | ||
729 | { | ||
730 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
731 | return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; | ||
732 | } | ||
733 | |||
734 | /*-------------------------------------------------------------------------*/ | ||
735 | |||
736 | #ifdef CONFIG_PM | ||
737 | |||
738 | /* suspend/resume, section 4.3 */ | ||
739 | |||
740 | /* These routines rely on the bus (pci, platform, etc) | ||
741 | * to handle powerdown and wakeup, and currently also on | ||
742 | * transceivers that don't need any software attention to set up | ||
743 | * the right sort of wakeup. | ||
744 | */ | ||
745 | |||
746 | static int ehci_suspend (struct usb_hcd *hcd, pm_message_t message) | ||
747 | { | ||
748 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
749 | |||
750 | if (time_before (jiffies, ehci->next_statechange)) | ||
751 | msleep (100); | ||
752 | |||
753 | #ifdef CONFIG_USB_SUSPEND | ||
754 | (void) usb_suspend_device (hcd->self.root_hub, message); | ||
755 | #else | ||
756 | usb_lock_device (hcd->self.root_hub); | ||
757 | (void) ehci_hub_suspend (hcd); | ||
758 | usb_unlock_device (hcd->self.root_hub); | ||
759 | #endif | ||
760 | |||
761 | // save (PCI) FLADJ in case of Vaux power loss | ||
762 | // ... we'd only use it to handle clock skew | ||
763 | |||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | static int ehci_resume (struct usb_hcd *hcd) | ||
768 | { | ||
769 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | ||
770 | unsigned port; | ||
771 | struct usb_device *root = hcd->self.root_hub; | ||
772 | int retval = -EINVAL; | ||
773 | |||
774 | // maybe restore (PCI) FLADJ | ||
775 | |||
776 | if (time_before (jiffies, ehci->next_statechange)) | ||
777 | msleep (100); | ||
778 | |||
779 | /* If any port is suspended (or owned by the companion), | ||
780 | * we know we can/must resume the HC (and mustn't reset it). | ||
781 | */ | 568 | */ |
782 | for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) { | 569 | create_debug_files(ehci); |
783 | u32 status; | ||
784 | port--; | ||
785 | status = readl (&ehci->regs->port_status [port]); | ||
786 | if (!(status & PORT_POWER)) | ||
787 | continue; | ||
788 | if (status & (PORT_SUSPEND | PORT_OWNER)) { | ||
789 | down (&hcd->self.root_hub->serialize); | ||
790 | retval = ehci_hub_resume (hcd); | ||
791 | up (&hcd->self.root_hub->serialize); | ||
792 | break; | ||
793 | } | ||
794 | if (!root->children [port]) | ||
795 | continue; | ||
796 | dbg_port (ehci, __FUNCTION__, port + 1, status); | ||
797 | usb_set_device_state (root->children[port], | ||
798 | USB_STATE_NOTATTACHED); | ||
799 | } | ||
800 | 570 | ||
801 | /* Else reset, to cope with power loss or flush-to-storage | 571 | return 0; |
802 | * style "resume" having activated BIOS during reboot. | ||
803 | */ | ||
804 | if (port == 0) { | ||
805 | (void) ehci_halt (ehci); | ||
806 | (void) ehci_reset (ehci); | ||
807 | (void) ehci_hc_reset (hcd); | ||
808 | |||
809 | /* emptying the schedule aborts any urbs */ | ||
810 | spin_lock_irq (&ehci->lock); | ||
811 | if (ehci->reclaim) | ||
812 | ehci->reclaim_ready = 1; | ||
813 | ehci_work (ehci, NULL); | ||
814 | spin_unlock_irq (&ehci->lock); | ||
815 | |||
816 | /* restart; khubd will disconnect devices */ | ||
817 | retval = ehci_start (hcd); | ||
818 | |||
819 | /* here we "know" root ports should always stay powered; | ||
820 | * but some controllers may lose all power. | ||
821 | */ | ||
822 | ehci_port_power (ehci, 1); | ||
823 | } | ||
824 | |||
825 | return retval; | ||
826 | } | ||
827 | |||
828 | #endif | ||
829 | |||
830 | /*-------------------------------------------------------------------------*/ | ||
831 | |||
832 | /* | ||
833 | * ehci_work is called from some interrupts, timers, and so on. | ||
834 | * it calls driver completion functions, after dropping ehci->lock. | ||
835 | */ | ||
836 | static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) | ||
837 | { | ||
838 | timer_action_done (ehci, TIMER_IO_WATCHDOG); | ||
839 | if (ehci->reclaim_ready) | ||
840 | end_unlink_async (ehci, regs); | ||
841 | |||
842 | /* another CPU may drop ehci->lock during a schedule scan while | ||
843 | * it reports urb completions. this flag guards against bogus | ||
844 | * attempts at re-entrant schedule scanning. | ||
845 | */ | ||
846 | if (ehci->scanning) | ||
847 | return; | ||
848 | ehci->scanning = 1; | ||
849 | scan_async (ehci, regs); | ||
850 | if (ehci->next_uframe != -1) | ||
851 | scan_periodic (ehci, regs); | ||
852 | ehci->scanning = 0; | ||
853 | |||
854 | /* the IO watchdog guards against hardware or driver bugs that | ||
855 | * misplace IRQs, and should let us run completely without IRQs. | ||
856 | * such lossage has been observed on both VT6202 and VT8235. | ||
857 | */ | ||
858 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && | ||
859 | (ehci->async->qh_next.ptr != NULL || | ||
860 | ehci->periodic_sched != 0)) | ||
861 | timer_action (ehci, TIMER_IO_WATCHDOG); | ||
862 | } | 572 | } |
863 | 573 | ||
864 | /*-------------------------------------------------------------------------*/ | 574 | /*-------------------------------------------------------------------------*/ |
@@ -935,9 +645,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) | |||
935 | * stop that signaling. | 645 | * stop that signaling. |
936 | */ | 646 | */ |
937 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); | 647 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); |
938 | mod_timer (&hcd->rh_timer, | ||
939 | ehci->reset_done [i] + 1); | ||
940 | ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); | 648 | ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); |
649 | usb_hcd_resume_root_hub(hcd); | ||
941 | } | 650 | } |
942 | } | 651 | } |
943 | 652 | ||
@@ -983,7 +692,7 @@ static int ehci_urb_enqueue ( | |||
983 | struct usb_hcd *hcd, | 692 | struct usb_hcd *hcd, |
984 | struct usb_host_endpoint *ep, | 693 | struct usb_host_endpoint *ep, |
985 | struct urb *urb, | 694 | struct urb *urb, |
986 | unsigned mem_flags | 695 | gfp_t mem_flags |
987 | ) { | 696 | ) { |
988 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 697 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
989 | struct list_head qtd_list; | 698 | struct list_head qtd_list; |
@@ -1171,106 +880,24 @@ done: | |||
1171 | return; | 880 | return; |
1172 | } | 881 | } |
1173 | 882 | ||
1174 | /*-------------------------------------------------------------------------*/ | 883 | static int ehci_get_frame (struct usb_hcd *hcd) |
1175 | 884 | { | |
1176 | static const struct hc_driver ehci_driver = { | 885 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
1177 | .description = hcd_name, | 886 | return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; |
1178 | .product_desc = "EHCI Host Controller", | 887 | } |
1179 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
1180 | |||
1181 | /* | ||
1182 | * generic hardware linkage | ||
1183 | */ | ||
1184 | .irq = ehci_irq, | ||
1185 | .flags = HCD_MEMORY | HCD_USB2, | ||
1186 | |||
1187 | /* | ||
1188 | * basic lifecycle operations | ||
1189 | */ | ||
1190 | .reset = ehci_hc_reset, | ||
1191 | .start = ehci_start, | ||
1192 | #ifdef CONFIG_PM | ||
1193 | .suspend = ehci_suspend, | ||
1194 | .resume = ehci_resume, | ||
1195 | #endif | ||
1196 | .stop = ehci_stop, | ||
1197 | |||
1198 | /* | ||
1199 | * managing i/o requests and associated device resources | ||
1200 | */ | ||
1201 | .urb_enqueue = ehci_urb_enqueue, | ||
1202 | .urb_dequeue = ehci_urb_dequeue, | ||
1203 | .endpoint_disable = ehci_endpoint_disable, | ||
1204 | |||
1205 | /* | ||
1206 | * scheduling support | ||
1207 | */ | ||
1208 | .get_frame_number = ehci_get_frame, | ||
1209 | |||
1210 | /* | ||
1211 | * root hub support | ||
1212 | */ | ||
1213 | .hub_status_data = ehci_hub_status_data, | ||
1214 | .hub_control = ehci_hub_control, | ||
1215 | .hub_suspend = ehci_hub_suspend, | ||
1216 | .hub_resume = ehci_hub_resume, | ||
1217 | }; | ||
1218 | 888 | ||
1219 | /*-------------------------------------------------------------------------*/ | 889 | /*-------------------------------------------------------------------------*/ |
1220 | 890 | ||
1221 | /* EHCI 1.0 doesn't require PCI */ | ||
1222 | |||
1223 | #ifdef CONFIG_PCI | ||
1224 | |||
1225 | /* PCI driver selection metadata; PCI hotplugging uses this */ | ||
1226 | static const struct pci_device_id pci_ids [] = { { | ||
1227 | /* handle any USB 2.0 EHCI controller */ | ||
1228 | PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), | ||
1229 | .driver_data = (unsigned long) &ehci_driver, | ||
1230 | }, | ||
1231 | { /* end: all zeroes */ } | ||
1232 | }; | ||
1233 | MODULE_DEVICE_TABLE (pci, pci_ids); | ||
1234 | |||
1235 | /* pci driver glue; this is a "new style" PCI driver module */ | ||
1236 | static struct pci_driver ehci_pci_driver = { | ||
1237 | .name = (char *) hcd_name, | ||
1238 | .id_table = pci_ids, | ||
1239 | |||
1240 | .probe = usb_hcd_pci_probe, | ||
1241 | .remove = usb_hcd_pci_remove, | ||
1242 | |||
1243 | #ifdef CONFIG_PM | ||
1244 | .suspend = usb_hcd_pci_suspend, | ||
1245 | .resume = usb_hcd_pci_resume, | ||
1246 | #endif | ||
1247 | }; | ||
1248 | |||
1249 | #endif /* PCI */ | ||
1250 | |||
1251 | |||
1252 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC | 891 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC |
1253 | 892 | ||
1254 | MODULE_DESCRIPTION (DRIVER_INFO); | 893 | MODULE_DESCRIPTION (DRIVER_INFO); |
1255 | MODULE_AUTHOR (DRIVER_AUTHOR); | 894 | MODULE_AUTHOR (DRIVER_AUTHOR); |
1256 | MODULE_LICENSE ("GPL"); | 895 | MODULE_LICENSE ("GPL"); |
1257 | 896 | ||
1258 | static int __init init (void) | 897 | #ifdef CONFIG_PCI |
1259 | { | 898 | #include "ehci-pci.c" |
1260 | if (usb_disabled()) | 899 | #endif |
1261 | return -ENODEV; | ||
1262 | |||
1263 | pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", | ||
1264 | hcd_name, | ||
1265 | sizeof (struct ehci_qh), sizeof (struct ehci_qtd), | ||
1266 | sizeof (struct ehci_itd), sizeof (struct ehci_sitd)); | ||
1267 | |||
1268 | return pci_register_driver (&ehci_pci_driver); | ||
1269 | } | ||
1270 | module_init (init); | ||
1271 | 900 | ||
1272 | static void __exit cleanup (void) | 901 | #if !defined(CONFIG_PCI) |
1273 | { | 902 | #error "missing bus glue for ehci-hcd" |
1274 | pci_unregister_driver (&ehci_pci_driver); | 903 | #endif |
1275 | } | ||
1276 | module_exit (cleanup); | ||
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 18d3f2270316..82caf336e9b6 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #ifdef CONFIG_PM | 31 | #ifdef CONFIG_PM |
32 | 32 | ||
33 | static int ehci_hub_suspend (struct usb_hcd *hcd) | 33 | static int ehci_bus_suspend (struct usb_hcd *hcd) |
34 | { | 34 | { |
35 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 35 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
36 | int port; | 36 | int port; |
@@ -83,7 +83,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd) | |||
83 | 83 | ||
84 | 84 | ||
85 | /* caller has locked the root hub, and should reset/reinit on error */ | 85 | /* caller has locked the root hub, and should reset/reinit on error */ |
86 | static int ehci_hub_resume (struct usb_hcd *hcd) | 86 | static int ehci_bus_resume (struct usb_hcd *hcd) |
87 | { | 87 | { |
88 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 88 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
89 | u32 temp; | 89 | u32 temp; |
@@ -94,6 +94,13 @@ static int ehci_hub_resume (struct usb_hcd *hcd) | |||
94 | msleep(5); | 94 | msleep(5); |
95 | spin_lock_irq (&ehci->lock); | 95 | spin_lock_irq (&ehci->lock); |
96 | 96 | ||
97 | /* Ideally and we've got a real resume here, and no port's power | ||
98 | * was lost. (For PCI, that means Vaux was maintained.) But we | ||
99 | * could instead be restoring a swsusp snapshot -- so that BIOS was | ||
100 | * the last user of the controller, not reset/pm hardware keeping | ||
101 | * state we gave to it. | ||
102 | */ | ||
103 | |||
97 | /* re-init operational registers in case we lost power */ | 104 | /* re-init operational registers in case we lost power */ |
98 | if (readl (&ehci->regs->intr_enable) == 0) { | 105 | if (readl (&ehci->regs->intr_enable) == 0) { |
99 | /* at least some APM implementations will try to deliver | 106 | /* at least some APM implementations will try to deliver |
@@ -159,8 +166,8 @@ static int ehci_hub_resume (struct usb_hcd *hcd) | |||
159 | 166 | ||
160 | #else | 167 | #else |
161 | 168 | ||
162 | #define ehci_hub_suspend NULL | 169 | #define ehci_bus_suspend NULL |
163 | #define ehci_hub_resume NULL | 170 | #define ehci_bus_resume NULL |
164 | 171 | ||
165 | #endif /* CONFIG_PM */ | 172 | #endif /* CONFIG_PM */ |
166 | 173 | ||
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 5c38ad869485..91c2ab43cbcc 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c | |||
@@ -45,7 +45,7 @@ static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma) | |||
45 | INIT_LIST_HEAD (&qtd->qtd_list); | 45 | INIT_LIST_HEAD (&qtd->qtd_list); |
46 | } | 46 | } |
47 | 47 | ||
48 | static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags) | 48 | static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, gfp_t flags) |
49 | { | 49 | { |
50 | struct ehci_qtd *qtd; | 50 | struct ehci_qtd *qtd; |
51 | dma_addr_t dma; | 51 | dma_addr_t dma; |
@@ -79,7 +79,7 @@ static void qh_destroy (struct kref *kref) | |||
79 | dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); | 79 | dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); |
80 | } | 80 | } |
81 | 81 | ||
82 | static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags) | 82 | static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) |
83 | { | 83 | { |
84 | struct ehci_qh *qh; | 84 | struct ehci_qh *qh; |
85 | dma_addr_t dma; | 85 | dma_addr_t dma; |
@@ -161,7 +161,7 @@ static void ehci_mem_cleanup (struct ehci_hcd *ehci) | |||
161 | } | 161 | } |
162 | 162 | ||
163 | /* remember to add cleanup code (above) if you add anything here */ | 163 | /* remember to add cleanup code (above) if you add anything here */ |
164 | static int ehci_mem_init (struct ehci_hcd *ehci, int flags) | 164 | static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags) |
165 | { | 165 | { |
166 | int i; | 166 | int i; |
167 | 167 | ||
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c new file mode 100644 index 000000000000..13f73a836e45 --- /dev/null +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -0,0 +1,425 @@ | |||
1 | /* | ||
2 | * EHCI HCD (Host Controller Driver) PCI Bus Glue. | ||
3 | * | ||
4 | * Copyright (c) 2000-2004 by David Brownell | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
13 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software Foundation, | ||
18 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef CONFIG_PCI | ||
22 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." | ||
23 | #endif | ||
24 | |||
25 | /*-------------------------------------------------------------------------*/ | ||
26 | |||
27 | /* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... | ||
28 | * off the controller (maybe it can boot from highspeed USB disks). | ||
29 | */ | ||
30 | static int bios_handoff(struct ehci_hcd *ehci, int where, u32 cap) | ||
31 | { | ||
32 | struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); | ||
33 | |||
34 | /* always say Linux will own the hardware */ | ||
35 | pci_write_config_byte(pdev, where + 3, 1); | ||
36 | |||
37 | /* maybe wait a while for BIOS to respond */ | ||
38 | if (cap & (1 << 16)) { | ||
39 | int msec = 5000; | ||
40 | |||
41 | do { | ||
42 | msleep(10); | ||
43 | msec -= 10; | ||
44 | pci_read_config_dword(pdev, where, &cap); | ||
45 | } while ((cap & (1 << 16)) && msec); | ||
46 | if (cap & (1 << 16)) { | ||
47 | ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", | ||
48 | where, cap); | ||
49 | // some BIOS versions seem buggy... | ||
50 | // return 1; | ||
51 | ehci_warn(ehci, "continuing after BIOS bug...\n"); | ||
52 | /* disable all SMIs, and clear "BIOS owns" flag */ | ||
53 | pci_write_config_dword(pdev, where + 4, 0); | ||
54 | pci_write_config_byte(pdev, where + 2, 0); | ||
55 | } else | ||
56 | ehci_dbg(ehci, "BIOS handoff succeeded\n"); | ||
57 | } | ||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | /* called after powerup, by probe or system-pm "wakeup" */ | ||
62 | static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) | ||
63 | { | ||
64 | u32 temp; | ||
65 | int retval; | ||
66 | unsigned count = 256/4; | ||
67 | |||
68 | /* optional debug port, normally in the first BAR */ | ||
69 | temp = pci_find_capability(pdev, 0x0a); | ||
70 | if (temp) { | ||
71 | pci_read_config_dword(pdev, temp, &temp); | ||
72 | temp >>= 16; | ||
73 | if ((temp & (3 << 13)) == (1 << 13)) { | ||
74 | temp &= 0x1fff; | ||
75 | ehci->debug = ehci_to_hcd(ehci)->regs + temp; | ||
76 | temp = readl(&ehci->debug->control); | ||
77 | ehci_info(ehci, "debug port %d%s\n", | ||
78 | HCS_DEBUG_PORT(ehci->hcs_params), | ||
79 | (temp & DBGP_ENABLED) | ||
80 | ? " IN USE" | ||
81 | : ""); | ||
82 | if (!(temp & DBGP_ENABLED)) | ||
83 | ehci->debug = NULL; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | temp = HCC_EXT_CAPS(readl(&ehci->caps->hcc_params)); | ||
88 | |||
89 | /* EHCI 0.96 and later may have "extended capabilities" */ | ||
90 | while (temp && count--) { | ||
91 | u32 cap; | ||
92 | |||
93 | pci_read_config_dword(pdev, temp, &cap); | ||
94 | ehci_dbg(ehci, "capability %04x at %02x\n", cap, temp); | ||
95 | switch (cap & 0xff) { | ||
96 | case 1: /* BIOS/SMM/... handoff */ | ||
97 | if (bios_handoff(ehci, temp, cap) != 0) | ||
98 | return -EOPNOTSUPP; | ||
99 | break; | ||
100 | case 0: /* illegal reserved capability */ | ||
101 | ehci_dbg(ehci, "illegal capability!\n"); | ||
102 | cap = 0; | ||
103 | /* FALLTHROUGH */ | ||
104 | default: /* unknown */ | ||
105 | break; | ||
106 | } | ||
107 | temp = (cap >> 8) & 0xff; | ||
108 | } | ||
109 | if (!count) { | ||
110 | ehci_err(ehci, "bogus capabilities ... PCI problems!\n"); | ||
111 | return -EIO; | ||
112 | } | ||
113 | |||
114 | /* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */ | ||
115 | retval = pci_set_mwi(pdev); | ||
116 | if (!retval) | ||
117 | ehci_dbg(ehci, "MWI active\n"); | ||
118 | |||
119 | ehci_port_power(ehci, 0); | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | /* called during probe() after chip reset completes */ | ||
125 | static int ehci_pci_setup(struct usb_hcd *hcd) | ||
126 | { | ||
127 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
128 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
129 | u32 temp; | ||
130 | int retval; | ||
131 | |||
132 | ehci->caps = hcd->regs; | ||
133 | ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); | ||
134 | dbg_hcs_params(ehci, "reset"); | ||
135 | dbg_hcc_params(ehci, "reset"); | ||
136 | |||
137 | /* cache this readonly data; minimize chip reads */ | ||
138 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | ||
139 | |||
140 | retval = ehci_halt(ehci); | ||
141 | if (retval) | ||
142 | return retval; | ||
143 | |||
144 | /* data structure init */ | ||
145 | retval = ehci_init(hcd); | ||
146 | if (retval) | ||
147 | return retval; | ||
148 | |||
149 | /* NOTE: only the parts below this line are PCI-specific */ | ||
150 | |||
151 | switch (pdev->vendor) { | ||
152 | case PCI_VENDOR_ID_TDI: | ||
153 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { | ||
154 | ehci->is_tdi_rh_tt = 1; | ||
155 | tdi_reset(ehci); | ||
156 | } | ||
157 | break; | ||
158 | case PCI_VENDOR_ID_AMD: | ||
159 | /* AMD8111 EHCI doesn't work, according to AMD errata */ | ||
160 | if (pdev->device == 0x7463) { | ||
161 | ehci_info(ehci, "ignoring AMD8111 (errata)\n"); | ||
162 | retval = -EIO; | ||
163 | goto done; | ||
164 | } | ||
165 | break; | ||
166 | case PCI_VENDOR_ID_NVIDIA: | ||
167 | /* NVidia reports that certain chips don't handle | ||
168 | * QH, ITD, or SITD addresses above 2GB. (But TD, | ||
169 | * data buffer, and periodic schedule are normal.) | ||
170 | */ | ||
171 | switch (pdev->device) { | ||
172 | case 0x003c: /* MCP04 */ | ||
173 | case 0x005b: /* CK804 */ | ||
174 | case 0x00d8: /* CK8 */ | ||
175 | case 0x00e8: /* CK8S */ | ||
176 | if (pci_set_consistent_dma_mask(pdev, | ||
177 | DMA_31BIT_MASK) < 0) | ||
178 | ehci_warn(ehci, "can't enable NVidia " | ||
179 | "workaround for >2GB RAM\n"); | ||
180 | break; | ||
181 | } | ||
182 | break; | ||
183 | } | ||
184 | |||
185 | if (ehci_is_TDI(ehci)) | ||
186 | ehci_reset(ehci); | ||
187 | |||
188 | /* at least the Genesys GL880S needs fixup here */ | ||
189 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); | ||
190 | temp &= 0x0f; | ||
191 | if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { | ||
192 | ehci_dbg(ehci, "bogus port configuration: " | ||
193 | "cc=%d x pcc=%d < ports=%d\n", | ||
194 | HCS_N_CC(ehci->hcs_params), | ||
195 | HCS_N_PCC(ehci->hcs_params), | ||
196 | HCS_N_PORTS(ehci->hcs_params)); | ||
197 | |||
198 | switch (pdev->vendor) { | ||
199 | case 0x17a0: /* GENESYS */ | ||
200 | /* GL880S: should be PORTS=2 */ | ||
201 | temp |= (ehci->hcs_params & ~0xf); | ||
202 | ehci->hcs_params = temp; | ||
203 | break; | ||
204 | case PCI_VENDOR_ID_NVIDIA: | ||
205 | /* NF4: should be PCC=10 */ | ||
206 | break; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /* Serial Bus Release Number is at PCI 0x60 offset */ | ||
211 | pci_read_config_byte(pdev, 0x60, &ehci->sbrn); | ||
212 | |||
213 | /* REVISIT: per-port wake capability (PCI 0x62) currently unused */ | ||
214 | |||
215 | retval = ehci_pci_reinit(ehci, pdev); | ||
216 | done: | ||
217 | return retval; | ||
218 | } | ||
219 | |||
220 | /*-------------------------------------------------------------------------*/ | ||
221 | |||
222 | #ifdef CONFIG_PM | ||
223 | |||
224 | /* suspend/resume, section 4.3 */ | ||
225 | |||
226 | /* These routines rely on the PCI bus glue | ||
227 | * to handle powerdown and wakeup, and currently also on | ||
228 | * transceivers that don't need any software attention to set up | ||
229 | * the right sort of wakeup. | ||
230 | * Also they depend on separate root hub suspend/resume. | ||
231 | */ | ||
232 | |||
233 | static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) | ||
234 | { | ||
235 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
236 | unsigned long flags; | ||
237 | int rc = 0; | ||
238 | |||
239 | if (time_before(jiffies, ehci->next_statechange)) | ||
240 | msleep(10); | ||
241 | |||
242 | /* Root hub was already suspended. Disable irq emission and | ||
243 | * mark HW unaccessible, bail out if RH has been resumed. Use | ||
244 | * the spinlock to properly synchronize with possible pending | ||
245 | * RH suspend or resume activity. | ||
246 | * | ||
247 | * This is still racy as hcd->state is manipulated outside of | ||
248 | * any locks =P But that will be a different fix. | ||
249 | */ | ||
250 | spin_lock_irqsave (&ehci->lock, flags); | ||
251 | if (hcd->state != HC_STATE_SUSPENDED) { | ||
252 | rc = -EINVAL; | ||
253 | goto bail; | ||
254 | } | ||
255 | writel (0, &ehci->regs->intr_enable); | ||
256 | (void)readl(&ehci->regs->intr_enable); | ||
257 | |||
258 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
259 | bail: | ||
260 | spin_unlock_irqrestore (&ehci->lock, flags); | ||
261 | |||
262 | // could save FLADJ in case of Vaux power loss | ||
263 | // ... we'd only use it to handle clock skew | ||
264 | |||
265 | return rc; | ||
266 | } | ||
267 | |||
268 | static int ehci_pci_resume(struct usb_hcd *hcd) | ||
269 | { | ||
270 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
271 | unsigned port; | ||
272 | struct usb_device *root = hcd->self.root_hub; | ||
273 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
274 | int retval = -EINVAL; | ||
275 | |||
276 | // maybe restore FLADJ | ||
277 | |||
278 | if (time_before(jiffies, ehci->next_statechange)) | ||
279 | msleep(100); | ||
280 | |||
281 | /* Mark hardware accessible again as we are out of D3 state by now */ | ||
282 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
283 | |||
284 | /* If CF is clear, we lost PCI Vaux power and need to restart. */ | ||
285 | if (readl(&ehci->regs->configured_flag) != FLAG_CF) | ||
286 | goto restart; | ||
287 | |||
288 | /* If any port is suspended (or owned by the companion), | ||
289 | * we know we can/must resume the HC (and mustn't reset it). | ||
290 | * We just defer that to the root hub code. | ||
291 | */ | ||
292 | for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) { | ||
293 | u32 status; | ||
294 | port--; | ||
295 | status = readl(&ehci->regs->port_status [port]); | ||
296 | if (!(status & PORT_POWER)) | ||
297 | continue; | ||
298 | if (status & (PORT_SUSPEND | PORT_RESUME | PORT_OWNER)) { | ||
299 | usb_hcd_resume_root_hub(hcd); | ||
300 | return 0; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | restart: | ||
305 | ehci_dbg(ehci, "lost power, restarting\n"); | ||
306 | for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) { | ||
307 | port--; | ||
308 | if (!root->children [port]) | ||
309 | continue; | ||
310 | usb_set_device_state(root->children[port], | ||
311 | USB_STATE_NOTATTACHED); | ||
312 | } | ||
313 | |||
314 | /* Else reset, to cope with power loss or flush-to-storage | ||
315 | * style "resume" having let BIOS kick in during reboot. | ||
316 | */ | ||
317 | (void) ehci_halt(ehci); | ||
318 | (void) ehci_reset(ehci); | ||
319 | (void) ehci_pci_reinit(ehci, pdev); | ||
320 | |||
321 | /* emptying the schedule aborts any urbs */ | ||
322 | spin_lock_irq(&ehci->lock); | ||
323 | if (ehci->reclaim) | ||
324 | ehci->reclaim_ready = 1; | ||
325 | ehci_work(ehci, NULL); | ||
326 | spin_unlock_irq(&ehci->lock); | ||
327 | |||
328 | /* restart; khubd will disconnect devices */ | ||
329 | retval = ehci_run(hcd); | ||
330 | |||
331 | /* here we "know" root ports should always stay powered */ | ||
332 | ehci_port_power(ehci, 1); | ||
333 | |||
334 | return retval; | ||
335 | } | ||
336 | #endif | ||
337 | |||
338 | static const struct hc_driver ehci_pci_hc_driver = { | ||
339 | .description = hcd_name, | ||
340 | .product_desc = "EHCI Host Controller", | ||
341 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
342 | |||
343 | /* | ||
344 | * generic hardware linkage | ||
345 | */ | ||
346 | .irq = ehci_irq, | ||
347 | .flags = HCD_MEMORY | HCD_USB2, | ||
348 | |||
349 | /* | ||
350 | * basic lifecycle operations | ||
351 | */ | ||
352 | .reset = ehci_pci_setup, | ||
353 | .start = ehci_run, | ||
354 | #ifdef CONFIG_PM | ||
355 | .suspend = ehci_pci_suspend, | ||
356 | .resume = ehci_pci_resume, | ||
357 | #endif | ||
358 | .stop = ehci_stop, | ||
359 | |||
360 | /* | ||
361 | * managing i/o requests and associated device resources | ||
362 | */ | ||
363 | .urb_enqueue = ehci_urb_enqueue, | ||
364 | .urb_dequeue = ehci_urb_dequeue, | ||
365 | .endpoint_disable = ehci_endpoint_disable, | ||
366 | |||
367 | /* | ||
368 | * scheduling support | ||
369 | */ | ||
370 | .get_frame_number = ehci_get_frame, | ||
371 | |||
372 | /* | ||
373 | * root hub support | ||
374 | */ | ||
375 | .hub_status_data = ehci_hub_status_data, | ||
376 | .hub_control = ehci_hub_control, | ||
377 | .bus_suspend = ehci_bus_suspend, | ||
378 | .bus_resume = ehci_bus_resume, | ||
379 | }; | ||
380 | |||
381 | /*-------------------------------------------------------------------------*/ | ||
382 | |||
383 | /* PCI driver selection metadata; PCI hotplugging uses this */ | ||
384 | static const struct pci_device_id pci_ids [] = { { | ||
385 | /* handle any USB 2.0 EHCI controller */ | ||
386 | PCI_DEVICE_CLASS(((PCI_CLASS_SERIAL_USB << 8) | 0x20), ~0), | ||
387 | .driver_data = (unsigned long) &ehci_pci_hc_driver, | ||
388 | }, | ||
389 | { /* end: all zeroes */ } | ||
390 | }; | ||
391 | MODULE_DEVICE_TABLE(pci, pci_ids); | ||
392 | |||
393 | /* pci driver glue; this is a "new style" PCI driver module */ | ||
394 | static struct pci_driver ehci_pci_driver = { | ||
395 | .name = (char *) hcd_name, | ||
396 | .id_table = pci_ids, | ||
397 | |||
398 | .probe = usb_hcd_pci_probe, | ||
399 | .remove = usb_hcd_pci_remove, | ||
400 | |||
401 | #ifdef CONFIG_PM | ||
402 | .suspend = usb_hcd_pci_suspend, | ||
403 | .resume = usb_hcd_pci_resume, | ||
404 | #endif | ||
405 | }; | ||
406 | |||
407 | static int __init ehci_hcd_pci_init(void) | ||
408 | { | ||
409 | if (usb_disabled()) | ||
410 | return -ENODEV; | ||
411 | |||
412 | pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", | ||
413 | hcd_name, | ||
414 | sizeof(struct ehci_qh), sizeof(struct ehci_qtd), | ||
415 | sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); | ||
416 | |||
417 | return pci_register_driver(&ehci_pci_driver); | ||
418 | } | ||
419 | module_init(ehci_hcd_pci_init); | ||
420 | |||
421 | static void __exit ehci_hcd_pci_cleanup(void) | ||
422 | { | ||
423 | pci_unregister_driver(&ehci_pci_driver); | ||
424 | } | ||
425 | module_exit(ehci_hcd_pci_cleanup); | ||
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 940d38ca7d91..bf03ec0d8ee2 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -477,7 +477,7 @@ qh_urb_transaction ( | |||
477 | struct ehci_hcd *ehci, | 477 | struct ehci_hcd *ehci, |
478 | struct urb *urb, | 478 | struct urb *urb, |
479 | struct list_head *head, | 479 | struct list_head *head, |
480 | int flags | 480 | gfp_t flags |
481 | ) { | 481 | ) { |
482 | struct ehci_qtd *qtd, *qtd_prev; | 482 | struct ehci_qtd *qtd, *qtd_prev; |
483 | dma_addr_t buf; | 483 | dma_addr_t buf; |
@@ -629,7 +629,7 @@ static struct ehci_qh * | |||
629 | qh_make ( | 629 | qh_make ( |
630 | struct ehci_hcd *ehci, | 630 | struct ehci_hcd *ehci, |
631 | struct urb *urb, | 631 | struct urb *urb, |
632 | int flags | 632 | gfp_t flags |
633 | ) { | 633 | ) { |
634 | struct ehci_qh *qh = ehci_qh_alloc (ehci, flags); | 634 | struct ehci_qh *qh = ehci_qh_alloc (ehci, flags); |
635 | u32 info1 = 0, info2 = 0; | 635 | u32 info1 = 0, info2 = 0; |
@@ -906,12 +906,13 @@ submit_async ( | |||
906 | struct usb_host_endpoint *ep, | 906 | struct usb_host_endpoint *ep, |
907 | struct urb *urb, | 907 | struct urb *urb, |
908 | struct list_head *qtd_list, | 908 | struct list_head *qtd_list, |
909 | unsigned mem_flags | 909 | gfp_t mem_flags |
910 | ) { | 910 | ) { |
911 | struct ehci_qtd *qtd; | 911 | struct ehci_qtd *qtd; |
912 | int epnum; | 912 | int epnum; |
913 | unsigned long flags; | 913 | unsigned long flags; |
914 | struct ehci_qh *qh = NULL; | 914 | struct ehci_qh *qh = NULL; |
915 | int rc = 0; | ||
915 | 916 | ||
916 | qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list); | 917 | qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list); |
917 | epnum = ep->desc.bEndpointAddress; | 918 | epnum = ep->desc.bEndpointAddress; |
@@ -926,21 +927,28 @@ submit_async ( | |||
926 | #endif | 927 | #endif |
927 | 928 | ||
928 | spin_lock_irqsave (&ehci->lock, flags); | 929 | spin_lock_irqsave (&ehci->lock, flags); |
930 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, | ||
931 | &ehci_to_hcd(ehci)->flags))) { | ||
932 | rc = -ESHUTDOWN; | ||
933 | goto done; | ||
934 | } | ||
935 | |||
929 | qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv); | 936 | qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv); |
937 | if (unlikely(qh == NULL)) { | ||
938 | rc = -ENOMEM; | ||
939 | goto done; | ||
940 | } | ||
930 | 941 | ||
931 | /* Control/bulk operations through TTs don't need scheduling, | 942 | /* Control/bulk operations through TTs don't need scheduling, |
932 | * the HC and TT handle it when the TT has a buffer ready. | 943 | * the HC and TT handle it when the TT has a buffer ready. |
933 | */ | 944 | */ |
934 | if (likely (qh != NULL)) { | 945 | if (likely (qh->qh_state == QH_STATE_IDLE)) |
935 | if (likely (qh->qh_state == QH_STATE_IDLE)) | 946 | qh_link_async (ehci, qh_get (qh)); |
936 | qh_link_async (ehci, qh_get (qh)); | 947 | done: |
937 | } | ||
938 | spin_unlock_irqrestore (&ehci->lock, flags); | 948 | spin_unlock_irqrestore (&ehci->lock, flags); |
939 | if (unlikely (qh == NULL)) { | 949 | if (unlikely (qh == NULL)) |
940 | qtd_list_free (ehci, urb, qtd_list); | 950 | qtd_list_free (ehci, urb, qtd_list); |
941 | return -ENOMEM; | 951 | return rc; |
942 | } | ||
943 | return 0; | ||
944 | } | 952 | } |
945 | 953 | ||
946 | /*-------------------------------------------------------------------------*/ | 954 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index ccc7300baa6d..57e77374d228 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -589,7 +589,7 @@ static int intr_submit ( | |||
589 | struct usb_host_endpoint *ep, | 589 | struct usb_host_endpoint *ep, |
590 | struct urb *urb, | 590 | struct urb *urb, |
591 | struct list_head *qtd_list, | 591 | struct list_head *qtd_list, |
592 | unsigned mem_flags | 592 | gfp_t mem_flags |
593 | ) { | 593 | ) { |
594 | unsigned epnum; | 594 | unsigned epnum; |
595 | unsigned long flags; | 595 | unsigned long flags; |
@@ -602,6 +602,12 @@ static int intr_submit ( | |||
602 | 602 | ||
603 | spin_lock_irqsave (&ehci->lock, flags); | 603 | spin_lock_irqsave (&ehci->lock, flags); |
604 | 604 | ||
605 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, | ||
606 | &ehci_to_hcd(ehci)->flags))) { | ||
607 | status = -ESHUTDOWN; | ||
608 | goto done; | ||
609 | } | ||
610 | |||
605 | /* get qh and force any scheduling errors */ | 611 | /* get qh and force any scheduling errors */ |
606 | INIT_LIST_HEAD (&empty); | 612 | INIT_LIST_HEAD (&empty); |
607 | qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv); | 613 | qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv); |
@@ -634,7 +640,7 @@ done: | |||
634 | /* ehci_iso_stream ops work with both ITD and SITD */ | 640 | /* ehci_iso_stream ops work with both ITD and SITD */ |
635 | 641 | ||
636 | static struct ehci_iso_stream * | 642 | static struct ehci_iso_stream * |
637 | iso_stream_alloc (unsigned mem_flags) | 643 | iso_stream_alloc (gfp_t mem_flags) |
638 | { | 644 | { |
639 | struct ehci_iso_stream *stream; | 645 | struct ehci_iso_stream *stream; |
640 | 646 | ||
@@ -851,7 +857,7 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) | |||
851 | /* ehci_iso_sched ops can be ITD-only or SITD-only */ | 857 | /* ehci_iso_sched ops can be ITD-only or SITD-only */ |
852 | 858 | ||
853 | static struct ehci_iso_sched * | 859 | static struct ehci_iso_sched * |
854 | iso_sched_alloc (unsigned packets, unsigned mem_flags) | 860 | iso_sched_alloc (unsigned packets, gfp_t mem_flags) |
855 | { | 861 | { |
856 | struct ehci_iso_sched *iso_sched; | 862 | struct ehci_iso_sched *iso_sched; |
857 | int size = sizeof *iso_sched; | 863 | int size = sizeof *iso_sched; |
@@ -924,7 +930,7 @@ itd_urb_transaction ( | |||
924 | struct ehci_iso_stream *stream, | 930 | struct ehci_iso_stream *stream, |
925 | struct ehci_hcd *ehci, | 931 | struct ehci_hcd *ehci, |
926 | struct urb *urb, | 932 | struct urb *urb, |
927 | unsigned mem_flags | 933 | gfp_t mem_flags |
928 | ) | 934 | ) |
929 | { | 935 | { |
930 | struct ehci_itd *itd; | 936 | struct ehci_itd *itd; |
@@ -1418,7 +1424,7 @@ itd_complete ( | |||
1418 | /*-------------------------------------------------------------------------*/ | 1424 | /*-------------------------------------------------------------------------*/ |
1419 | 1425 | ||
1420 | static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, | 1426 | static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, |
1421 | unsigned mem_flags) | 1427 | gfp_t mem_flags) |
1422 | { | 1428 | { |
1423 | int status = -EINVAL; | 1429 | int status = -EINVAL; |
1424 | unsigned long flags; | 1430 | unsigned long flags; |
@@ -1456,7 +1462,11 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, | |||
1456 | 1462 | ||
1457 | /* schedule ... need to lock */ | 1463 | /* schedule ... need to lock */ |
1458 | spin_lock_irqsave (&ehci->lock, flags); | 1464 | spin_lock_irqsave (&ehci->lock, flags); |
1459 | status = iso_stream_schedule (ehci, urb, stream); | 1465 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, |
1466 | &ehci_to_hcd(ehci)->flags))) | ||
1467 | status = -ESHUTDOWN; | ||
1468 | else | ||
1469 | status = iso_stream_schedule (ehci, urb, stream); | ||
1460 | if (likely (status == 0)) | 1470 | if (likely (status == 0)) |
1461 | itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); | 1471 | itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); |
1462 | spin_unlock_irqrestore (&ehci->lock, flags); | 1472 | spin_unlock_irqrestore (&ehci->lock, flags); |
@@ -1529,7 +1539,7 @@ sitd_urb_transaction ( | |||
1529 | struct ehci_iso_stream *stream, | 1539 | struct ehci_iso_stream *stream, |
1530 | struct ehci_hcd *ehci, | 1540 | struct ehci_hcd *ehci, |
1531 | struct urb *urb, | 1541 | struct urb *urb, |
1532 | unsigned mem_flags | 1542 | gfp_t mem_flags |
1533 | ) | 1543 | ) |
1534 | { | 1544 | { |
1535 | struct ehci_sitd *sitd; | 1545 | struct ehci_sitd *sitd; |
@@ -1779,7 +1789,7 @@ sitd_complete ( | |||
1779 | 1789 | ||
1780 | 1790 | ||
1781 | static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, | 1791 | static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, |
1782 | unsigned mem_flags) | 1792 | gfp_t mem_flags) |
1783 | { | 1793 | { |
1784 | int status = -EINVAL; | 1794 | int status = -EINVAL; |
1785 | unsigned long flags; | 1795 | unsigned long flags; |
@@ -1815,7 +1825,11 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, | |||
1815 | 1825 | ||
1816 | /* schedule ... need to lock */ | 1826 | /* schedule ... need to lock */ |
1817 | spin_lock_irqsave (&ehci->lock, flags); | 1827 | spin_lock_irqsave (&ehci->lock, flags); |
1818 | status = iso_stream_schedule (ehci, urb, stream); | 1828 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, |
1829 | &ehci_to_hcd(ehci)->flags))) | ||
1830 | status = -ESHUTDOWN; | ||
1831 | else | ||
1832 | status = iso_stream_schedule (ehci, urb, stream); | ||
1819 | if (status == 0) | 1833 | if (status == 0) |
1820 | sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); | 1834 | sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); |
1821 | spin_unlock_irqrestore (&ehci->lock, flags); | 1835 | spin_unlock_irqrestore (&ehci->lock, flags); |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index f34a0516d35f..18e257c2bdb5 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -97,6 +97,7 @@ struct ehci_hcd { /* one per controller */ | |||
97 | #else | 97 | #else |
98 | # define COUNT(x) do {} while (0) | 98 | # define COUNT(x) do {} while (0) |
99 | #endif | 99 | #endif |
100 | u8 sbrn; /* packed release number */ | ||
100 | }; | 101 | }; |
101 | 102 | ||
102 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ | 103 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c index a8267cf17db4..0eaabeb37ac3 100644 --- a/drivers/usb/host/hc_crisv10.c +++ b/drivers/usb/host/hc_crisv10.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/unistd.h> | 14 | #include <linux/unistd.h> |
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/version.h> | ||
18 | #include <linux/list.h> | 17 | #include <linux/list.h> |
19 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
20 | 19 | ||
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 41bbae83fc71..82f64986bc22 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #include <linux/interrupt.h> | 70 | #include <linux/interrupt.h> |
71 | #include <linux/usb.h> | 71 | #include <linux/usb.h> |
72 | #include <linux/usb_isp116x.h> | 72 | #include <linux/usb_isp116x.h> |
73 | #include <linux/platform_device.h> | ||
73 | 74 | ||
74 | #include <asm/io.h> | 75 | #include <asm/io.h> |
75 | #include <asm/irq.h> | 76 | #include <asm/irq.h> |
@@ -326,7 +327,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
326 | usb_settoggle(udev, ep->epnum, | 327 | usb_settoggle(udev, ep->epnum, |
327 | ep->nextpid == | 328 | ep->nextpid == |
328 | USB_PID_OUT, | 329 | USB_PID_OUT, |
329 | PTD_GET_TOGGLE(ptd) ^ 1); | 330 | PTD_GET_TOGGLE(ptd)); |
331 | urb->actual_length += PTD_GET_COUNT(ptd); | ||
330 | urb->status = cc_to_error[TD_DATAUNDERRUN]; | 332 | urb->status = cc_to_error[TD_DATAUNDERRUN]; |
331 | spin_unlock(&urb->lock); | 333 | spin_unlock(&urb->lock); |
332 | continue; | 334 | continue; |
@@ -637,7 +639,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) | |||
637 | + msecs_to_jiffies(20) + 1); | 639 | + msecs_to_jiffies(20) + 1); |
638 | if (intstat & HCINT_RD) { | 640 | if (intstat & HCINT_RD) { |
639 | DBG("---- remote wakeup\n"); | 641 | DBG("---- remote wakeup\n"); |
640 | schedule_work(&isp116x->rh_resume); | 642 | usb_hcd_resume_root_hub(hcd); |
641 | ret = IRQ_HANDLED; | 643 | ret = IRQ_HANDLED; |
642 | } | 644 | } |
643 | irqstat &= ~HCuPINT_OPR; | 645 | irqstat &= ~HCuPINT_OPR; |
@@ -693,7 +695,7 @@ static int balance(struct isp116x *isp116x, u16 period, u16 load) | |||
693 | 695 | ||
694 | static int isp116x_urb_enqueue(struct usb_hcd *hcd, | 696 | static int isp116x_urb_enqueue(struct usb_hcd *hcd, |
695 | struct usb_host_endpoint *hep, struct urb *urb, | 697 | struct usb_host_endpoint *hep, struct urb *urb, |
696 | unsigned mem_flags) | 698 | gfp_t mem_flags) |
697 | { | 699 | { |
698 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 700 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
699 | struct usb_device *udev = urb->dev; | 701 | struct usb_device *udev = urb->dev; |
@@ -1159,7 +1161,7 @@ static int isp116x_hub_control(struct usb_hcd *hcd, | |||
1159 | 1161 | ||
1160 | #ifdef CONFIG_PM | 1162 | #ifdef CONFIG_PM |
1161 | 1163 | ||
1162 | static int isp116x_hub_suspend(struct usb_hcd *hcd) | 1164 | static int isp116x_bus_suspend(struct usb_hcd *hcd) |
1163 | { | 1165 | { |
1164 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 1166 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
1165 | unsigned long flags; | 1167 | unsigned long flags; |
@@ -1199,7 +1201,7 @@ static int isp116x_hub_suspend(struct usb_hcd *hcd) | |||
1199 | return ret; | 1201 | return ret; |
1200 | } | 1202 | } |
1201 | 1203 | ||
1202 | static int isp116x_hub_resume(struct usb_hcd *hcd) | 1204 | static int isp116x_bus_resume(struct usb_hcd *hcd) |
1203 | { | 1205 | { |
1204 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 1206 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
1205 | u32 val; | 1207 | u32 val; |
@@ -1262,21 +1264,11 @@ static int isp116x_hub_resume(struct usb_hcd *hcd) | |||
1262 | return 0; | 1264 | return 0; |
1263 | } | 1265 | } |
1264 | 1266 | ||
1265 | static void isp116x_rh_resume(void *_hcd) | ||
1266 | { | ||
1267 | struct usb_hcd *hcd = _hcd; | ||
1268 | |||
1269 | usb_resume_device(hcd->self.root_hub); | ||
1270 | } | ||
1271 | 1267 | ||
1272 | #else | 1268 | #else |
1273 | 1269 | ||
1274 | #define isp116x_hub_suspend NULL | 1270 | #define isp116x_bus_suspend NULL |
1275 | #define isp116x_hub_resume NULL | 1271 | #define isp116x_bus_resume NULL |
1276 | |||
1277 | static void isp116x_rh_resume(void *_hcd) | ||
1278 | { | ||
1279 | } | ||
1280 | 1272 | ||
1281 | #endif | 1273 | #endif |
1282 | 1274 | ||
@@ -1635,23 +1627,21 @@ static struct hc_driver isp116x_hc_driver = { | |||
1635 | 1627 | ||
1636 | .hub_status_data = isp116x_hub_status_data, | 1628 | .hub_status_data = isp116x_hub_status_data, |
1637 | .hub_control = isp116x_hub_control, | 1629 | .hub_control = isp116x_hub_control, |
1638 | .hub_suspend = isp116x_hub_suspend, | 1630 | .bus_suspend = isp116x_bus_suspend, |
1639 | .hub_resume = isp116x_hub_resume, | 1631 | .bus_resume = isp116x_bus_resume, |
1640 | }; | 1632 | }; |
1641 | 1633 | ||
1642 | /*----------------------------------------------------------------*/ | 1634 | /*----------------------------------------------------------------*/ |
1643 | 1635 | ||
1644 | static int __init_or_module isp116x_remove(struct device *dev) | 1636 | static int __init_or_module isp116x_remove(struct platform_device *pdev) |
1645 | { | 1637 | { |
1646 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 1638 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
1647 | struct isp116x *isp116x; | 1639 | struct isp116x *isp116x; |
1648 | struct platform_device *pdev; | ||
1649 | struct resource *res; | 1640 | struct resource *res; |
1650 | 1641 | ||
1651 | if (!hcd) | 1642 | if (!hcd) |
1652 | return 0; | 1643 | return 0; |
1653 | isp116x = hcd_to_isp116x(hcd); | 1644 | isp116x = hcd_to_isp116x(hcd); |
1654 | pdev = container_of(dev, struct platform_device, dev); | ||
1655 | remove_debug_file(isp116x); | 1645 | remove_debug_file(isp116x); |
1656 | usb_remove_hcd(hcd); | 1646 | usb_remove_hcd(hcd); |
1657 | 1647 | ||
@@ -1668,18 +1658,16 @@ static int __init_or_module isp116x_remove(struct device *dev) | |||
1668 | 1658 | ||
1669 | #define resource_len(r) (((r)->end - (r)->start) + 1) | 1659 | #define resource_len(r) (((r)->end - (r)->start) + 1) |
1670 | 1660 | ||
1671 | static int __init isp116x_probe(struct device *dev) | 1661 | static int __init isp116x_probe(struct platform_device *pdev) |
1672 | { | 1662 | { |
1673 | struct usb_hcd *hcd; | 1663 | struct usb_hcd *hcd; |
1674 | struct isp116x *isp116x; | 1664 | struct isp116x *isp116x; |
1675 | struct platform_device *pdev; | ||
1676 | struct resource *addr, *data; | 1665 | struct resource *addr, *data; |
1677 | void __iomem *addr_reg; | 1666 | void __iomem *addr_reg; |
1678 | void __iomem *data_reg; | 1667 | void __iomem *data_reg; |
1679 | int irq; | 1668 | int irq; |
1680 | int ret = 0; | 1669 | int ret = 0; |
1681 | 1670 | ||
1682 | pdev = container_of(dev, struct platform_device, dev); | ||
1683 | if (pdev->num_resources < 3) { | 1671 | if (pdev->num_resources < 3) { |
1684 | ret = -ENODEV; | 1672 | ret = -ENODEV; |
1685 | goto err1; | 1673 | goto err1; |
@@ -1693,7 +1681,7 @@ static int __init isp116x_probe(struct device *dev) | |||
1693 | goto err1; | 1681 | goto err1; |
1694 | } | 1682 | } |
1695 | 1683 | ||
1696 | if (dev->dma_mask) { | 1684 | if (pdev->dev.dma_mask) { |
1697 | DBG("DMA not supported\n"); | 1685 | DBG("DMA not supported\n"); |
1698 | ret = -EINVAL; | 1686 | ret = -EINVAL; |
1699 | goto err1; | 1687 | goto err1; |
@@ -1719,7 +1707,7 @@ static int __init isp116x_probe(struct device *dev) | |||
1719 | } | 1707 | } |
1720 | 1708 | ||
1721 | /* allocate and initialize hcd */ | 1709 | /* allocate and initialize hcd */ |
1722 | hcd = usb_create_hcd(&isp116x_hc_driver, dev, dev->bus_id); | 1710 | hcd = usb_create_hcd(&isp116x_hc_driver, &pdev->dev, pdev->dev.bus_id); |
1723 | if (!hcd) { | 1711 | if (!hcd) { |
1724 | ret = -ENOMEM; | 1712 | ret = -ENOMEM; |
1725 | goto err5; | 1713 | goto err5; |
@@ -1731,8 +1719,7 @@ static int __init isp116x_probe(struct device *dev) | |||
1731 | isp116x->addr_reg = addr_reg; | 1719 | isp116x->addr_reg = addr_reg; |
1732 | spin_lock_init(&isp116x->lock); | 1720 | spin_lock_init(&isp116x->lock); |
1733 | INIT_LIST_HEAD(&isp116x->async); | 1721 | INIT_LIST_HEAD(&isp116x->async); |
1734 | INIT_WORK(&isp116x->rh_resume, isp116x_rh_resume, hcd); | 1722 | isp116x->board = pdev->dev.platform_data; |
1735 | isp116x->board = dev->platform_data; | ||
1736 | 1723 | ||
1737 | if (!isp116x->board) { | 1724 | if (!isp116x->board) { |
1738 | ERR("Platform data structure not initialized\n"); | 1725 | ERR("Platform data structure not initialized\n"); |
@@ -1773,22 +1760,13 @@ static int __init isp116x_probe(struct device *dev) | |||
1773 | /* | 1760 | /* |
1774 | Suspend of platform device | 1761 | Suspend of platform device |
1775 | */ | 1762 | */ |
1776 | static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase) | 1763 | static int isp116x_suspend(struct platform_device *dev, pm_message_t state) |
1777 | { | 1764 | { |
1778 | int ret = 0; | 1765 | int ret = 0; |
1779 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
1780 | 1766 | ||
1781 | VDBG("%s: state %x, phase %x\n", __func__, state, phase); | 1767 | VDBG("%s: state %x\n", __func__, state); |
1782 | 1768 | ||
1783 | if (phase != SUSPEND_DISABLE && phase != SUSPEND_POWER_DOWN) | 1769 | dev->dev.power.power_state = state; |
1784 | return 0; | ||
1785 | |||
1786 | ret = usb_suspend_device(hcd->self.root_hub, state); | ||
1787 | if (!ret) { | ||
1788 | dev->power.power_state = state; | ||
1789 | INFO("%s suspended\n", hcd_name); | ||
1790 | } else | ||
1791 | ERR("%s suspend failed\n", hcd_name); | ||
1792 | 1770 | ||
1793 | return ret; | 1771 | return ret; |
1794 | } | 1772 | } |
@@ -1796,21 +1774,14 @@ static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase) | |||
1796 | /* | 1774 | /* |
1797 | Resume platform device | 1775 | Resume platform device |
1798 | */ | 1776 | */ |
1799 | static int isp116x_resume(struct device *dev, u32 phase) | 1777 | static int isp116x_resume(struct platform_device *dev) |
1800 | { | 1778 | { |
1801 | int ret = 0; | 1779 | int ret = 0; |
1802 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
1803 | 1780 | ||
1804 | VDBG("%s: state %x, phase %x\n", __func__, dev->power.power_state, | 1781 | VDBG("%s: state %x\n", __func__, dev->dev.power.power_state); |
1805 | phase); | 1782 | |
1806 | if (phase != RESUME_POWER_ON) | 1783 | dev->dev.power.power_state = PMSG_ON; |
1807 | return 0; | ||
1808 | 1784 | ||
1809 | ret = usb_resume_device(hcd->self.root_hub); | ||
1810 | if (!ret) { | ||
1811 | dev->power.power_state = PMSG_ON; | ||
1812 | VDBG("%s resumed\n", (char *)hcd_name); | ||
1813 | } | ||
1814 | return ret; | 1785 | return ret; |
1815 | } | 1786 | } |
1816 | 1787 | ||
@@ -1821,13 +1792,14 @@ static int isp116x_resume(struct device *dev, u32 phase) | |||
1821 | 1792 | ||
1822 | #endif | 1793 | #endif |
1823 | 1794 | ||
1824 | static struct device_driver isp116x_driver = { | 1795 | static struct platform_driver isp116x_driver = { |
1825 | .name = (char *)hcd_name, | ||
1826 | .bus = &platform_bus_type, | ||
1827 | .probe = isp116x_probe, | 1796 | .probe = isp116x_probe, |
1828 | .remove = isp116x_remove, | 1797 | .remove = isp116x_remove, |
1829 | .suspend = isp116x_suspend, | 1798 | .suspend = isp116x_suspend, |
1830 | .resume = isp116x_resume, | 1799 | .resume = isp116x_resume, |
1800 | .driver = { | ||
1801 | .name = (char *)hcd_name, | ||
1802 | }, | ||
1831 | }; | 1803 | }; |
1832 | 1804 | ||
1833 | /*-----------------------------------------------------------------*/ | 1805 | /*-----------------------------------------------------------------*/ |
@@ -1838,14 +1810,14 @@ static int __init isp116x_init(void) | |||
1838 | return -ENODEV; | 1810 | return -ENODEV; |
1839 | 1811 | ||
1840 | INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION); | 1812 | INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION); |
1841 | return driver_register(&isp116x_driver); | 1813 | return platform_driver_register(&isp116x_driver); |
1842 | } | 1814 | } |
1843 | 1815 | ||
1844 | module_init(isp116x_init); | 1816 | module_init(isp116x_init); |
1845 | 1817 | ||
1846 | static void __exit isp116x_cleanup(void) | 1818 | static void __exit isp116x_cleanup(void) |
1847 | { | 1819 | { |
1848 | driver_unregister(&isp116x_driver); | 1820 | platform_driver_unregister(&isp116x_driver); |
1849 | } | 1821 | } |
1850 | 1822 | ||
1851 | module_exit(isp116x_cleanup); | 1823 | module_exit(isp116x_cleanup); |
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index 58873470dcf5..c6fec96785fe 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h | |||
@@ -253,7 +253,6 @@ static const int cc_to_error[16] = { | |||
253 | 253 | ||
254 | struct isp116x { | 254 | struct isp116x { |
255 | spinlock_t lock; | 255 | spinlock_t lock; |
256 | struct work_struct rh_resume; | ||
257 | 256 | ||
258 | void __iomem *addr_reg; | 257 | void __iomem *addr_reg; |
259 | void __iomem *data_reg; | 258 | void __iomem *data_reg; |
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 3981bf15c8c7..d9cf3b327d96 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -18,6 +18,8 @@ | |||
18 | * This file is licenced under the GPL. | 18 | * This file is licenced under the GPL. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/platform_device.h> | ||
22 | |||
21 | #include <asm/mach-au1x00/au1000.h> | 23 | #include <asm/mach-au1x00/au1000.h> |
22 | 24 | ||
23 | #define USBH_ENABLE_BE (1<<0) | 25 | #define USBH_ENABLE_BE (1<<0) |
@@ -214,13 +216,17 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { | |||
214 | */ | 216 | */ |
215 | .hub_status_data = ohci_hub_status_data, | 217 | .hub_status_data = ohci_hub_status_data, |
216 | .hub_control = ohci_hub_control, | 218 | .hub_control = ohci_hub_control, |
219 | #ifdef CONFIG_PM | ||
220 | .bus_suspend = ohci_bus_suspend, | ||
221 | .bus_resume = ohci_bus_resume, | ||
222 | #endif | ||
223 | .start_port_reset = ohci_start_port_reset, | ||
217 | }; | 224 | }; |
218 | 225 | ||
219 | /*-------------------------------------------------------------------------*/ | 226 | /*-------------------------------------------------------------------------*/ |
220 | 227 | ||
221 | static int ohci_hcd_au1xxx_drv_probe(struct device *dev) | 228 | static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) |
222 | { | 229 | { |
223 | struct platform_device *pdev = to_platform_device(dev); | ||
224 | int ret; | 230 | int ret; |
225 | 231 | ||
226 | pr_debug ("In ohci_hcd_au1xxx_drv_probe"); | 232 | pr_debug ("In ohci_hcd_au1xxx_drv_probe"); |
@@ -232,38 +238,37 @@ static int ohci_hcd_au1xxx_drv_probe(struct device *dev) | |||
232 | return ret; | 238 | return ret; |
233 | } | 239 | } |
234 | 240 | ||
235 | static int ohci_hcd_au1xxx_drv_remove(struct device *dev) | 241 | static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev) |
236 | { | 242 | { |
237 | struct platform_device *pdev = to_platform_device(dev); | 243 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
238 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
239 | 244 | ||
240 | usb_hcd_au1xxx_remove(hcd, pdev); | 245 | usb_hcd_au1xxx_remove(hcd, pdev); |
241 | return 0; | 246 | return 0; |
242 | } | 247 | } |
243 | /*TBD*/ | 248 | /*TBD*/ |
244 | /*static int ohci_hcd_au1xxx_drv_suspend(struct device *dev) | 249 | /*static int ohci_hcd_au1xxx_drv_suspend(struct platform_device *dev) |
245 | { | 250 | { |
246 | struct platform_device *pdev = to_platform_device(dev); | 251 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
247 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
248 | 252 | ||
249 | return 0; | 253 | return 0; |
250 | } | 254 | } |
251 | static int ohci_hcd_au1xxx_drv_resume(struct device *dev) | 255 | static int ohci_hcd_au1xxx_drv_resume(struct platform_device *dev) |
252 | { | 256 | { |
253 | struct platform_device *pdev = to_platform_device(dev); | 257 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
254 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
255 | 258 | ||
256 | return 0; | 259 | return 0; |
257 | } | 260 | } |
258 | */ | 261 | */ |
259 | 262 | ||
260 | static struct device_driver ohci_hcd_au1xxx_driver = { | 263 | static struct platform_driver ohci_hcd_au1xxx_driver = { |
261 | .name = "au1xxx-ohci", | ||
262 | .bus = &platform_bus_type, | ||
263 | .probe = ohci_hcd_au1xxx_drv_probe, | 264 | .probe = ohci_hcd_au1xxx_drv_probe, |
264 | .remove = ohci_hcd_au1xxx_drv_remove, | 265 | .remove = ohci_hcd_au1xxx_drv_remove, |
265 | /*.suspend = ohci_hcd_au1xxx_drv_suspend, */ | 266 | /*.suspend = ohci_hcd_au1xxx_drv_suspend, */ |
266 | /*.resume = ohci_hcd_au1xxx_drv_resume, */ | 267 | /*.resume = ohci_hcd_au1xxx_drv_resume, */ |
268 | .driver = { | ||
269 | .name = "au1xxx-ohci", | ||
270 | .owner = THIS_MODULE, | ||
271 | }, | ||
267 | }; | 272 | }; |
268 | 273 | ||
269 | static int __init ohci_hcd_au1xxx_init (void) | 274 | static int __init ohci_hcd_au1xxx_init (void) |
@@ -272,12 +277,12 @@ static int __init ohci_hcd_au1xxx_init (void) | |||
272 | pr_debug ("block sizes: ed %d td %d\n", | 277 | pr_debug ("block sizes: ed %d td %d\n", |
273 | sizeof (struct ed), sizeof (struct td)); | 278 | sizeof (struct ed), sizeof (struct td)); |
274 | 279 | ||
275 | return driver_register(&ohci_hcd_au1xxx_driver); | 280 | return platform_driver_register(&ohci_hcd_au1xxx_driver); |
276 | } | 281 | } |
277 | 282 | ||
278 | static void __exit ohci_hcd_au1xxx_cleanup (void) | 283 | static void __exit ohci_hcd_au1xxx_cleanup (void) |
279 | { | 284 | { |
280 | driver_unregister(&ohci_hcd_au1xxx_driver); | 285 | platform_driver_unregister(&ohci_hcd_au1xxx_driver); |
281 | } | 286 | } |
282 | 287 | ||
283 | module_init (ohci_hcd_au1xxx_init); | 288 | module_init (ohci_hcd_au1xxx_init); |
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 7924c74f958e..7bfffcbbd226 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -193,10 +193,6 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) | |||
193 | 193 | ||
194 | maybe_print_eds (controller, "donehead", | 194 | maybe_print_eds (controller, "donehead", |
195 | ohci_readl (controller, ®s->donehead), next, size); | 195 | ohci_readl (controller, ®s->donehead), next, size); |
196 | |||
197 | /* broken fminterval means traffic won't flow! */ | ||
198 | ohci_dbg (controller, "fminterval %08x\n", | ||
199 | ohci_readl (controller, ®s->fminterval)); | ||
200 | } | 196 | } |
201 | 197 | ||
202 | #define dbg_port_sw(hc,num,value,next,size) \ | 198 | #define dbg_port_sw(hc,num,value,next,size) \ |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 67c1aa5eb1c1..bf1d9abc07ac 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -115,7 +115,7 @@ | |||
115 | 115 | ||
116 | /*-------------------------------------------------------------------------*/ | 116 | /*-------------------------------------------------------------------------*/ |
117 | 117 | ||
118 | // #define OHCI_VERBOSE_DEBUG /* not always helpful */ | 118 | #undef OHCI_VERBOSE_DEBUG /* not always helpful */ |
119 | 119 | ||
120 | /* For initializing controller (mask in an HCFS mode too) */ | 120 | /* For initializing controller (mask in an HCFS mode too) */ |
121 | #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR | 121 | #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR |
@@ -180,7 +180,7 @@ static int ohci_urb_enqueue ( | |||
180 | struct usb_hcd *hcd, | 180 | struct usb_hcd *hcd, |
181 | struct usb_host_endpoint *ep, | 181 | struct usb_host_endpoint *ep, |
182 | struct urb *urb, | 182 | struct urb *urb, |
183 | unsigned mem_flags | 183 | gfp_t mem_flags |
184 | ) { | 184 | ) { |
185 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 185 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
186 | struct ed *ed; | 186 | struct ed *ed; |
@@ -253,6 +253,10 @@ static int ohci_urb_enqueue ( | |||
253 | spin_lock_irqsave (&ohci->lock, flags); | 253 | spin_lock_irqsave (&ohci->lock, flags); |
254 | 254 | ||
255 | /* don't submit to a dead HC */ | 255 | /* don't submit to a dead HC */ |
256 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { | ||
257 | retval = -ENODEV; | ||
258 | goto fail; | ||
259 | } | ||
256 | if (!HC_IS_RUNNING(hcd->state)) { | 260 | if (!HC_IS_RUNNING(hcd->state)) { |
257 | retval = -ENODEV; | 261 | retval = -ENODEV; |
258 | goto fail; | 262 | goto fail; |
@@ -723,7 +727,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) | |||
723 | ohci_vdbg (ohci, "resume detect\n"); | 727 | ohci_vdbg (ohci, "resume detect\n"); |
724 | ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); | 728 | ohci_writel (ohci, OHCI_INTR_RD, ®s->intrstatus); |
725 | if (hcd->state != HC_STATE_QUIESCING) | 729 | if (hcd->state != HC_STATE_QUIESCING) |
726 | schedule_work(&ohci->rh_resume); | 730 | usb_hcd_resume_root_hub(hcd); |
727 | } | 731 | } |
728 | 732 | ||
729 | if (ints & OHCI_INTR_WDH) { | 733 | if (ints & OHCI_INTR_WDH) { |
@@ -791,7 +795,7 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
791 | 795 | ||
792 | /* must not be called from interrupt context */ | 796 | /* must not be called from interrupt context */ |
793 | 797 | ||
794 | #if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) | 798 | #ifdef CONFIG_PM |
795 | 799 | ||
796 | static int ohci_restart (struct ohci_hcd *ohci) | 800 | static int ohci_restart (struct ohci_hcd *ohci) |
797 | { | 801 | { |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index ce7b28da7a15..72e3b12a1926 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | /*-------------------------------------------------------------------------*/ | 37 | /*-------------------------------------------------------------------------*/ |
38 | 38 | ||
39 | #if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) | 39 | #ifdef CONFIG_PM |
40 | 40 | ||
41 | #define OHCI_SCHED_ENABLES \ | 41 | #define OHCI_SCHED_ENABLES \ |
42 | (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) | 42 | (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) |
@@ -45,7 +45,7 @@ static void dl_done_list (struct ohci_hcd *, struct pt_regs *); | |||
45 | static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *); | 45 | static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *); |
46 | static int ohci_restart (struct ohci_hcd *ohci); | 46 | static int ohci_restart (struct ohci_hcd *ohci); |
47 | 47 | ||
48 | static int ohci_hub_suspend (struct usb_hcd *hcd) | 48 | static int ohci_bus_suspend (struct usb_hcd *hcd) |
49 | { | 49 | { |
50 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 50 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
51 | int status = 0; | 51 | int status = 0; |
@@ -53,6 +53,11 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) | |||
53 | 53 | ||
54 | spin_lock_irqsave (&ohci->lock, flags); | 54 | spin_lock_irqsave (&ohci->lock, flags); |
55 | 55 | ||
56 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) { | ||
57 | spin_unlock_irqrestore (&ohci->lock, flags); | ||
58 | return -ESHUTDOWN; | ||
59 | } | ||
60 | |||
56 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); | 61 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); |
57 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { | 62 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { |
58 | case OHCI_USB_RESUME: | 63 | case OHCI_USB_RESUME: |
@@ -73,7 +78,6 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) | |||
73 | ohci_dbg (ohci, "suspend root hub\n"); | 78 | ohci_dbg (ohci, "suspend root hub\n"); |
74 | 79 | ||
75 | /* First stop any processing */ | 80 | /* First stop any processing */ |
76 | hcd->state = HC_STATE_QUIESCING; | ||
77 | if (ohci->hc_control & OHCI_SCHED_ENABLES) { | 81 | if (ohci->hc_control & OHCI_SCHED_ENABLES) { |
78 | int limit; | 82 | int limit; |
79 | 83 | ||
@@ -108,7 +112,9 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) | |||
108 | else | 112 | else |
109 | ohci->hc_control &= ~OHCI_CTRL_RWE; | 113 | ohci->hc_control &= ~OHCI_CTRL_RWE; |
110 | 114 | ||
111 | /* Suspend hub */ | 115 | /* Suspend hub ... this is the "global (to this bus) suspend" mode, |
116 | * which doesn't imply ports will first be individually suspended. | ||
117 | */ | ||
112 | ohci->hc_control &= ~OHCI_CTRL_HCFS; | 118 | ohci->hc_control &= ~OHCI_CTRL_HCFS; |
113 | ohci->hc_control |= OHCI_USB_SUSPEND; | 119 | ohci->hc_control |= OHCI_USB_SUSPEND; |
114 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); | 120 | ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); |
@@ -118,8 +124,9 @@ static int ohci_hub_suspend (struct usb_hcd *hcd) | |||
118 | ohci->next_statechange = jiffies + msecs_to_jiffies (5); | 124 | ohci->next_statechange = jiffies + msecs_to_jiffies (5); |
119 | 125 | ||
120 | done: | 126 | done: |
127 | /* external suspend vs self autosuspend ... same effect */ | ||
121 | if (status == 0) | 128 | if (status == 0) |
122 | hcd->state = HC_STATE_SUSPENDED; | 129 | usb_hcd_suspend_root_hub(hcd); |
123 | spin_unlock_irqrestore (&ohci->lock, flags); | 130 | spin_unlock_irqrestore (&ohci->lock, flags); |
124 | return status; | 131 | return status; |
125 | } | 132 | } |
@@ -133,20 +140,28 @@ static inline struct ed *find_head (struct ed *ed) | |||
133 | } | 140 | } |
134 | 141 | ||
135 | /* caller has locked the root hub */ | 142 | /* caller has locked the root hub */ |
136 | static int ohci_hub_resume (struct usb_hcd *hcd) | 143 | static int ohci_bus_resume (struct usb_hcd *hcd) |
137 | { | 144 | { |
138 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 145 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
139 | u32 temp, enables; | 146 | u32 temp, enables; |
140 | int status = -EINPROGRESS; | 147 | int status = -EINPROGRESS; |
148 | unsigned long flags; | ||
141 | 149 | ||
142 | if (time_before (jiffies, ohci->next_statechange)) | 150 | if (time_before (jiffies, ohci->next_statechange)) |
143 | msleep(5); | 151 | msleep(5); |
144 | 152 | ||
145 | spin_lock_irq (&ohci->lock); | 153 | spin_lock_irqsave (&ohci->lock, flags); |
154 | |||
155 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) { | ||
156 | spin_unlock_irqrestore (&ohci->lock, flags); | ||
157 | return -ESHUTDOWN; | ||
158 | } | ||
159 | |||
160 | |||
146 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); | 161 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); |
147 | 162 | ||
148 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { | 163 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { |
149 | /* this can happen after suspend-to-disk */ | 164 | /* this can happen after resuming a swsusp snapshot */ |
150 | if (hcd->state == HC_STATE_RESUMING) { | 165 | if (hcd->state == HC_STATE_RESUMING) { |
151 | ohci_dbg (ohci, "BIOS/SMM active, control %03x\n", | 166 | ohci_dbg (ohci, "BIOS/SMM active, control %03x\n", |
152 | ohci->hc_control); | 167 | ohci->hc_control); |
@@ -169,14 +184,15 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
169 | ohci_info (ohci, "wakeup\n"); | 184 | ohci_info (ohci, "wakeup\n"); |
170 | break; | 185 | break; |
171 | case OHCI_USB_OPER: | 186 | case OHCI_USB_OPER: |
172 | ohci_dbg (ohci, "already resumed\n"); | 187 | /* this can happen after resuming a swsusp snapshot */ |
173 | status = 0; | 188 | ohci_dbg (ohci, "snapshot resume? reinit\n"); |
189 | status = -EBUSY; | ||
174 | break; | 190 | break; |
175 | default: /* RESET, we lost power */ | 191 | default: /* RESET, we lost power */ |
176 | ohci_dbg (ohci, "root hub hardware reset\n"); | 192 | ohci_dbg (ohci, "lost power\n"); |
177 | status = -EBUSY; | 193 | status = -EBUSY; |
178 | } | 194 | } |
179 | spin_unlock_irq (&ohci->lock); | 195 | spin_unlock_irqrestore (&ohci->lock, flags); |
180 | if (status == -EBUSY) { | 196 | if (status == -EBUSY) { |
181 | (void) ohci_init (ohci); | 197 | (void) ohci_init (ohci); |
182 | return ohci_restart (ohci); | 198 | return ohci_restart (ohci); |
@@ -198,8 +214,7 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
198 | } | 214 | } |
199 | 215 | ||
200 | /* Some controllers (lucent erratum) need extra-long delays */ | 216 | /* Some controllers (lucent erratum) need extra-long delays */ |
201 | hcd->state = HC_STATE_RESUMING; | 217 | msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1); |
202 | mdelay (20 /* usb 11.5.1.10 */ + 15); | ||
203 | 218 | ||
204 | temp = ohci_readl (ohci, &ohci->regs->control); | 219 | temp = ohci_readl (ohci, &ohci->regs->control); |
205 | temp &= OHCI_CTRL_HCFS; | 220 | temp &= OHCI_CTRL_HCFS; |
@@ -273,28 +288,10 @@ static int ohci_hub_resume (struct usb_hcd *hcd) | |||
273 | (void) ohci_readl (ohci, &ohci->regs->control); | 288 | (void) ohci_readl (ohci, &ohci->regs->control); |
274 | } | 289 | } |
275 | 290 | ||
276 | hcd->state = HC_STATE_RUNNING; | ||
277 | return 0; | 291 | return 0; |
278 | } | 292 | } |
279 | 293 | ||
280 | static void ohci_rh_resume (void *_hcd) | 294 | #endif /* CONFIG_PM */ |
281 | { | ||
282 | struct usb_hcd *hcd = _hcd; | ||
283 | |||
284 | usb_lock_device (hcd->self.root_hub); | ||
285 | (void) ohci_hub_resume (hcd); | ||
286 | usb_unlock_device (hcd->self.root_hub); | ||
287 | } | ||
288 | |||
289 | #else | ||
290 | |||
291 | static void ohci_rh_resume (void *_hcd) | ||
292 | { | ||
293 | struct ohci_hcd *ohci = hcd_to_ohci (_hcd); | ||
294 | ohci_dbg(ohci, "rh_resume ??\n"); | ||
295 | } | ||
296 | |||
297 | #endif /* CONFIG_USB_SUSPEND || CONFIG_PM */ | ||
298 | 295 | ||
299 | /*-------------------------------------------------------------------------*/ | 296 | /*-------------------------------------------------------------------------*/ |
300 | 297 | ||
@@ -313,8 +310,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
313 | /* handle autosuspended root: finish resuming before | 310 | /* handle autosuspended root: finish resuming before |
314 | * letting khubd or root hub timer see state changes. | 311 | * letting khubd or root hub timer see state changes. |
315 | */ | 312 | */ |
316 | if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER | 313 | if (unlikely((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER |
317 | || !HC_IS_RUNNING(hcd->state)) { | 314 | || !HC_IS_RUNNING(hcd->state))) { |
318 | can_suspend = 0; | 315 | can_suspend = 0; |
319 | goto done; | 316 | goto done; |
320 | } | 317 | } |
@@ -367,7 +364,6 @@ done: | |||
367 | #ifdef CONFIG_PM | 364 | #ifdef CONFIG_PM |
368 | /* save power by suspending idle root hubs; | 365 | /* save power by suspending idle root hubs; |
369 | * INTR_RD wakes us when there's work | 366 | * INTR_RD wakes us when there's work |
370 | * NOTE: if we can do this, we don't need a root hub timer! | ||
371 | */ | 367 | */ |
372 | if (can_suspend | 368 | if (can_suspend |
373 | && !changed | 369 | && !changed |
@@ -379,8 +375,7 @@ done: | |||
379 | && usb_trylock_device (hcd->self.root_hub) | 375 | && usb_trylock_device (hcd->self.root_hub) |
380 | ) { | 376 | ) { |
381 | ohci_vdbg (ohci, "autosuspend\n"); | 377 | ohci_vdbg (ohci, "autosuspend\n"); |
382 | (void) ohci_hub_suspend (hcd); | 378 | (void) ohci_bus_suspend (hcd); |
383 | hcd->state = HC_STATE_RUNNING; | ||
384 | usb_unlock_device (hcd->self.root_hub); | 379 | usb_unlock_device (hcd->self.root_hub); |
385 | } | 380 | } |
386 | #endif | 381 | #endif |
@@ -526,6 +521,9 @@ static int ohci_hub_control ( | |||
526 | u32 temp; | 521 | u32 temp; |
527 | int retval = 0; | 522 | int retval = 0; |
528 | 523 | ||
524 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) | ||
525 | return -ESHUTDOWN; | ||
526 | |||
529 | switch (typeReq) { | 527 | switch (typeReq) { |
530 | case ClearHubFeature: | 528 | case ClearHubFeature: |
531 | switch (wValue) { | 529 | switch (wValue) { |
@@ -554,7 +552,7 @@ static int ohci_hub_control ( | |||
554 | temp = RH_PS_POCI; | 552 | temp = RH_PS_POCI; |
555 | if ((ohci->hc_control & OHCI_CTRL_HCFS) | 553 | if ((ohci->hc_control & OHCI_CTRL_HCFS) |
556 | != OHCI_USB_OPER) | 554 | != OHCI_USB_OPER) |
557 | schedule_work (&ohci->rh_resume); | 555 | usb_hcd_resume_root_hub(hcd); |
558 | break; | 556 | break; |
559 | case USB_PORT_FEAT_C_SUSPEND: | 557 | case USB_PORT_FEAT_C_SUSPEND: |
560 | temp = RH_PS_PSSC; | 558 | temp = RH_PS_PSSC; |
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index 817620d73841..3959ccc88332 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c | |||
@@ -16,9 +16,9 @@ | |||
16 | * This file is licenced under the GPL. | 16 | * This file is licenced under the GPL. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/platform_device.h> | ||
20 | |||
19 | #include <asm/hardware.h> | 21 | #include <asm/hardware.h> |
20 | #include <asm/mach-types.h> | ||
21 | #include <asm/arch/hardware.h> | ||
22 | 22 | ||
23 | 23 | ||
24 | extern int usb_disabled(void); | 24 | extern int usb_disabled(void); |
@@ -195,13 +195,17 @@ static const struct hc_driver ohci_lh7a404_hc_driver = { | |||
195 | */ | 195 | */ |
196 | .hub_status_data = ohci_hub_status_data, | 196 | .hub_status_data = ohci_hub_status_data, |
197 | .hub_control = ohci_hub_control, | 197 | .hub_control = ohci_hub_control, |
198 | #ifdef CONFIG_PM | ||
199 | .bus_suspend = ohci_bus_suspend, | ||
200 | .bus_resume = ohci_bus_resume, | ||
201 | #endif | ||
202 | .start_port_reset = ohci_start_port_reset, | ||
198 | }; | 203 | }; |
199 | 204 | ||
200 | /*-------------------------------------------------------------------------*/ | 205 | /*-------------------------------------------------------------------------*/ |
201 | 206 | ||
202 | static int ohci_hcd_lh7a404_drv_probe(struct device *dev) | 207 | static int ohci_hcd_lh7a404_drv_probe(struct platform_device *pdev) |
203 | { | 208 | { |
204 | struct platform_device *pdev = to_platform_device(dev); | ||
205 | int ret; | 209 | int ret; |
206 | 210 | ||
207 | pr_debug ("In ohci_hcd_lh7a404_drv_probe"); | 211 | pr_debug ("In ohci_hcd_lh7a404_drv_probe"); |
@@ -213,39 +217,38 @@ static int ohci_hcd_lh7a404_drv_probe(struct device *dev) | |||
213 | return ret; | 217 | return ret; |
214 | } | 218 | } |
215 | 219 | ||
216 | static int ohci_hcd_lh7a404_drv_remove(struct device *dev) | 220 | static int ohci_hcd_lh7a404_drv_remove(struct platform_device *pdev) |
217 | { | 221 | { |
218 | struct platform_device *pdev = to_platform_device(dev); | 222 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
219 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
220 | 223 | ||
221 | usb_hcd_lh7a404_remove(hcd, pdev); | 224 | usb_hcd_lh7a404_remove(hcd, pdev); |
222 | return 0; | 225 | return 0; |
223 | } | 226 | } |
224 | /*TBD*/ | 227 | /*TBD*/ |
225 | /*static int ohci_hcd_lh7a404_drv_suspend(struct device *dev) | 228 | /*static int ohci_hcd_lh7a404_drv_suspend(struct platform_device *dev) |
226 | { | 229 | { |
227 | struct platform_device *pdev = to_platform_device(dev); | 230 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
228 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
229 | 231 | ||
230 | return 0; | 232 | return 0; |
231 | } | 233 | } |
232 | static int ohci_hcd_lh7a404_drv_resume(struct device *dev) | 234 | static int ohci_hcd_lh7a404_drv_resume(struct platform_device *dev) |
233 | { | 235 | { |
234 | struct platform_device *pdev = to_platform_device(dev); | 236 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
235 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
236 | 237 | ||
237 | 238 | ||
238 | return 0; | 239 | return 0; |
239 | } | 240 | } |
240 | */ | 241 | */ |
241 | 242 | ||
242 | static struct device_driver ohci_hcd_lh7a404_driver = { | 243 | static struct platform_driver ohci_hcd_lh7a404_driver = { |
243 | .name = "lh7a404-ohci", | ||
244 | .bus = &platform_bus_type, | ||
245 | .probe = ohci_hcd_lh7a404_drv_probe, | 244 | .probe = ohci_hcd_lh7a404_drv_probe, |
246 | .remove = ohci_hcd_lh7a404_drv_remove, | 245 | .remove = ohci_hcd_lh7a404_drv_remove, |
247 | /*.suspend = ohci_hcd_lh7a404_drv_suspend, */ | 246 | /*.suspend = ohci_hcd_lh7a404_drv_suspend, */ |
248 | /*.resume = ohci_hcd_lh7a404_drv_resume, */ | 247 | /*.resume = ohci_hcd_lh7a404_drv_resume, */ |
248 | .driver = { | ||
249 | .name = "lh7a404-ohci", | ||
250 | .owner = THIS_MODULE, | ||
251 | }, | ||
249 | }; | 252 | }; |
250 | 253 | ||
251 | static int __init ohci_hcd_lh7a404_init (void) | 254 | static int __init ohci_hcd_lh7a404_init (void) |
@@ -254,12 +257,12 @@ static int __init ohci_hcd_lh7a404_init (void) | |||
254 | pr_debug ("block sizes: ed %d td %d\n", | 257 | pr_debug ("block sizes: ed %d td %d\n", |
255 | sizeof (struct ed), sizeof (struct td)); | 258 | sizeof (struct ed), sizeof (struct td)); |
256 | 259 | ||
257 | return driver_register(&ohci_hcd_lh7a404_driver); | 260 | return platform_driver_register(&ohci_hcd_lh7a404_driver); |
258 | } | 261 | } |
259 | 262 | ||
260 | static void __exit ohci_hcd_lh7a404_cleanup (void) | 263 | static void __exit ohci_hcd_lh7a404_cleanup (void) |
261 | { | 264 | { |
262 | driver_unregister(&ohci_hcd_lh7a404_driver); | 265 | platform_driver_unregister(&ohci_hcd_lh7a404_driver); |
263 | } | 266 | } |
264 | 267 | ||
265 | module_init (ohci_hcd_lh7a404_init); | 268 | module_init (ohci_hcd_lh7a404_init); |
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index fd3c4d3714bd..bfbe328a4788 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -28,7 +28,6 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) | |||
28 | ohci->next_statechange = jiffies; | 28 | ohci->next_statechange = jiffies; |
29 | spin_lock_init (&ohci->lock); | 29 | spin_lock_init (&ohci->lock); |
30 | INIT_LIST_HEAD (&ohci->pending); | 30 | INIT_LIST_HEAD (&ohci->pending); |
31 | INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci)); | ||
32 | ohci->reboot_notifier.notifier_call = ohci_reboot; | 31 | ohci->reboot_notifier.notifier_call = ohci_reboot; |
33 | } | 32 | } |
34 | 33 | ||
@@ -84,7 +83,7 @@ dma_to_td (struct ohci_hcd *hc, dma_addr_t td_dma) | |||
84 | 83 | ||
85 | /* TDs ... */ | 84 | /* TDs ... */ |
86 | static struct td * | 85 | static struct td * |
87 | td_alloc (struct ohci_hcd *hc, unsigned mem_flags) | 86 | td_alloc (struct ohci_hcd *hc, gfp_t mem_flags) |
88 | { | 87 | { |
89 | dma_addr_t dma; | 88 | dma_addr_t dma; |
90 | struct td *td; | 89 | struct td *td; |
@@ -118,7 +117,7 @@ td_free (struct ohci_hcd *hc, struct td *td) | |||
118 | 117 | ||
119 | /* EDs ... */ | 118 | /* EDs ... */ |
120 | static struct ed * | 119 | static struct ed * |
121 | ed_alloc (struct ohci_hcd *hc, unsigned mem_flags) | 120 | ed_alloc (struct ohci_hcd *hc, gfp_t mem_flags) |
122 | { | 121 | { |
123 | dma_addr_t dma; | 122 | dma_addr_t dma; |
124 | struct ed *ed; | 123 | struct ed *ed; |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 5cde76faab93..c9e29d808711 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -14,11 +14,14 @@ | |||
14 | * This file is licenced under the GPL. | 14 | * This file is licenced under the GPL. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/signal.h> /* SA_INTERRUPT */ | ||
18 | #include <linux/jiffies.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | |||
17 | #include <asm/hardware.h> | 21 | #include <asm/hardware.h> |
18 | #include <asm/io.h> | 22 | #include <asm/io.h> |
19 | #include <asm/mach-types.h> | 23 | #include <asm/mach-types.h> |
20 | 24 | ||
21 | #include <asm/arch/hardware.h> | ||
22 | #include <asm/arch/mux.h> | 25 | #include <asm/arch/mux.h> |
23 | #include <asm/arch/irqs.h> | 26 | #include <asm/arch/irqs.h> |
24 | #include <asm/arch/gpio.h> | 27 | #include <asm/arch/gpio.h> |
@@ -421,33 +424,31 @@ static const struct hc_driver ohci_omap_hc_driver = { | |||
421 | */ | 424 | */ |
422 | .hub_status_data = ohci_hub_status_data, | 425 | .hub_status_data = ohci_hub_status_data, |
423 | .hub_control = ohci_hub_control, | 426 | .hub_control = ohci_hub_control, |
424 | #ifdef CONFIG_USB_SUSPEND | 427 | #ifdef CONFIG_PM |
425 | .hub_suspend = ohci_hub_suspend, | 428 | .bus_suspend = ohci_bus_suspend, |
426 | .hub_resume = ohci_hub_resume, | 429 | .bus_resume = ohci_bus_resume, |
427 | #endif | 430 | #endif |
428 | .start_port_reset = ohci_start_port_reset, | 431 | .start_port_reset = ohci_start_port_reset, |
429 | }; | 432 | }; |
430 | 433 | ||
431 | /*-------------------------------------------------------------------------*/ | 434 | /*-------------------------------------------------------------------------*/ |
432 | 435 | ||
433 | static int ohci_hcd_omap_drv_probe(struct device *dev) | 436 | static int ohci_hcd_omap_drv_probe(struct platform_device *dev) |
434 | { | 437 | { |
435 | return usb_hcd_omap_probe(&ohci_omap_hc_driver, | 438 | return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev); |
436 | to_platform_device(dev)); | ||
437 | } | 439 | } |
438 | 440 | ||
439 | static int ohci_hcd_omap_drv_remove(struct device *dev) | 441 | static int ohci_hcd_omap_drv_remove(struct platform_device *dev) |
440 | { | 442 | { |
441 | struct platform_device *pdev = to_platform_device(dev); | 443 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
442 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
443 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 444 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
444 | 445 | ||
445 | usb_hcd_omap_remove(hcd, pdev); | 446 | usb_hcd_omap_remove(hcd, dev); |
446 | if (ohci->transceiver) { | 447 | if (ohci->transceiver) { |
447 | (void) otg_set_host(ohci->transceiver, 0); | 448 | (void) otg_set_host(ohci->transceiver, 0); |
448 | put_device(ohci->transceiver->dev); | 449 | put_device(ohci->transceiver->dev); |
449 | } | 450 | } |
450 | dev_set_drvdata(dev, NULL); | 451 | platform_set_drvdata(dev, NULL); |
451 | 452 | ||
452 | return 0; | 453 | return 0; |
453 | } | 454 | } |
@@ -456,50 +457,32 @@ static int ohci_hcd_omap_drv_remove(struct device *dev) | |||
456 | 457 | ||
457 | #ifdef CONFIG_PM | 458 | #ifdef CONFIG_PM |
458 | 459 | ||
459 | static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level) | 460 | static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message) |
460 | { | 461 | { |
461 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); | 462 | struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev)); |
462 | int status = -EINVAL; | 463 | |
463 | 464 | if (time_before(jiffies, ohci->next_statechange)) | |
464 | if (level != SUSPEND_POWER_DOWN) | 465 | msleep(5); |
465 | return 0; | 466 | ohci->next_statechange = jiffies; |
466 | 467 | ||
467 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 468 | omap_ohci_clock_power(0); |
468 | status = ohci_hub_suspend(ohci_to_hcd(ohci)); | 469 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; |
469 | if (status == 0) { | 470 | dev->power.power_state = PMSG_SUSPEND; |
470 | omap_ohci_clock_power(0); | 471 | return 0; |
471 | ohci_to_hcd(ohci)->self.root_hub->state = | ||
472 | USB_STATE_SUSPENDED; | ||
473 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; | ||
474 | dev->power.power_state = PMSG_SUSPEND; | ||
475 | } | ||
476 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); | ||
477 | return status; | ||
478 | } | 472 | } |
479 | 473 | ||
480 | static int ohci_omap_resume(struct device *dev, u32 level) | 474 | static int ohci_omap_resume(struct platform_device *dev) |
481 | { | 475 | { |
482 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); | 476 | struct ohci_hcd *ohci = hcd_to_ohci(platform_get_drvdata(dev)); |
483 | int status = 0; | ||
484 | |||
485 | if (level != RESUME_POWER_ON) | ||
486 | return 0; | ||
487 | 477 | ||
488 | if (time_before(jiffies, ohci->next_statechange)) | 478 | if (time_before(jiffies, ohci->next_statechange)) |
489 | msleep(5); | 479 | msleep(5); |
490 | ohci->next_statechange = jiffies; | 480 | ohci->next_statechange = jiffies; |
481 | |||
491 | omap_ohci_clock_power(1); | 482 | omap_ohci_clock_power(1); |
492 | #ifdef CONFIG_USB_SUSPEND | 483 | dev->power.power_state = PMSG_ON; |
493 | /* get extra cleanup even if remote wakeup isn't in use */ | 484 | usb_hcd_resume_root_hub(dev_get_drvdata(dev)); |
494 | status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); | 485 | return 0; |
495 | #else | ||
496 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); | ||
497 | status = ohci_hub_resume(ohci_to_hcd(ohci)); | ||
498 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); | ||
499 | #endif | ||
500 | if (status == 0) | ||
501 | dev->power.power_state = PMSG_ON; | ||
502 | return status; | ||
503 | } | 486 | } |
504 | 487 | ||
505 | #endif | 488 | #endif |
@@ -509,15 +492,17 @@ static int ohci_omap_resume(struct device *dev, u32 level) | |||
509 | /* | 492 | /* |
510 | * Driver definition to register with the OMAP bus | 493 | * Driver definition to register with the OMAP bus |
511 | */ | 494 | */ |
512 | static struct device_driver ohci_hcd_omap_driver = { | 495 | static struct platform_driver ohci_hcd_omap_driver = { |
513 | .name = "ohci", | ||
514 | .bus = &platform_bus_type, | ||
515 | .probe = ohci_hcd_omap_drv_probe, | 496 | .probe = ohci_hcd_omap_drv_probe, |
516 | .remove = ohci_hcd_omap_drv_remove, | 497 | .remove = ohci_hcd_omap_drv_remove, |
517 | #ifdef CONFIG_PM | 498 | #ifdef CONFIG_PM |
518 | .suspend = ohci_omap_suspend, | 499 | .suspend = ohci_omap_suspend, |
519 | .resume = ohci_omap_resume, | 500 | .resume = ohci_omap_resume, |
520 | #endif | 501 | #endif |
502 | .driver = { | ||
503 | .owner = THIS_MODULE, | ||
504 | .name = "ohci", | ||
505 | }, | ||
521 | }; | 506 | }; |
522 | 507 | ||
523 | static int __init ohci_hcd_omap_init (void) | 508 | static int __init ohci_hcd_omap_init (void) |
@@ -529,12 +514,12 @@ static int __init ohci_hcd_omap_init (void) | |||
529 | pr_debug("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | 514 | pr_debug("%s: block sizes: ed %Zd td %Zd\n", hcd_name, |
530 | sizeof (struct ed), sizeof (struct td)); | 515 | sizeof (struct ed), sizeof (struct td)); |
531 | 516 | ||
532 | return driver_register(&ohci_hcd_omap_driver); | 517 | return platform_driver_register(&ohci_hcd_omap_driver); |
533 | } | 518 | } |
534 | 519 | ||
535 | static void __exit ohci_hcd_omap_cleanup (void) | 520 | static void __exit ohci_hcd_omap_cleanup (void) |
536 | { | 521 | { |
537 | driver_unregister(&ohci_hcd_omap_driver); | 522 | platform_driver_unregister(&ohci_hcd_omap_driver); |
538 | } | 523 | } |
539 | 524 | ||
540 | module_init (ohci_hcd_omap_init); | 525 | module_init (ohci_hcd_omap_init); |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index eede6be098d2..1b09dde068e1 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -14,13 +14,6 @@ | |||
14 | * This file is licenced under the GPL. | 14 | * This file is licenced under the GPL. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #ifdef CONFIG_PPC_PMAC | ||
18 | #include <asm/machdep.h> | ||
19 | #include <asm/pmac_feature.h> | ||
20 | #include <asm/pci-bridge.h> | ||
21 | #include <asm/prom.h> | ||
22 | #endif | ||
23 | |||
24 | #ifndef CONFIG_PCI | 17 | #ifndef CONFIG_PCI |
25 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." | 18 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." |
26 | #endif | 19 | #endif |
@@ -112,66 +105,38 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
112 | 105 | ||
113 | static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) | 106 | static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) |
114 | { | 107 | { |
115 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 108 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
116 | 109 | unsigned long flags; | |
117 | /* suspend root hub, hoping it keeps power during suspend */ | 110 | int rc = 0; |
118 | if (time_before (jiffies, ohci->next_statechange)) | 111 | |
119 | msleep (100); | 112 | /* Root hub was already suspended. Disable irq emission and |
120 | 113 | * mark HW unaccessible, bail out if RH has been resumed. Use | |
121 | #ifdef CONFIG_USB_SUSPEND | 114 | * the spinlock to properly synchronize with possible pending |
122 | (void) usb_suspend_device (hcd->self.root_hub, message); | 115 | * RH suspend or resume activity. |
123 | #else | 116 | * |
124 | usb_lock_device (hcd->self.root_hub); | 117 | * This is still racy as hcd->state is manipulated outside of |
125 | (void) ohci_hub_suspend (hcd); | 118 | * any locks =P But that will be a different fix. |
126 | usb_unlock_device (hcd->self.root_hub); | 119 | */ |
127 | #endif | 120 | spin_lock_irqsave (&ohci->lock, flags); |
128 | 121 | if (hcd->state != HC_STATE_SUSPENDED) { | |
129 | /* let things settle down a bit */ | 122 | rc = -EINVAL; |
130 | msleep (100); | 123 | goto bail; |
131 | |||
132 | #ifdef CONFIG_PPC_PMAC | ||
133 | if (_machine == _MACH_Pmac) { | ||
134 | struct device_node *of_node; | ||
135 | |||
136 | /* Disable USB PAD & cell clock */ | ||
137 | of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); | ||
138 | if (of_node) | ||
139 | pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0); | ||
140 | } | 124 | } |
141 | #endif /* CONFIG_PPC_PMAC */ | 125 | ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
142 | return 0; | 126 | (void)ohci_readl(ohci, &ohci->regs->intrdisable); |
127 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
128 | bail: | ||
129 | spin_unlock_irqrestore (&ohci->lock, flags); | ||
130 | |||
131 | return rc; | ||
143 | } | 132 | } |
144 | 133 | ||
145 | 134 | ||
146 | static int ohci_pci_resume (struct usb_hcd *hcd) | 135 | static int ohci_pci_resume (struct usb_hcd *hcd) |
147 | { | 136 | { |
148 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 137 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
149 | int retval = 0; | 138 | usb_hcd_resume_root_hub(hcd); |
150 | 139 | return 0; | |
151 | #ifdef CONFIG_PPC_PMAC | ||
152 | if (_machine == _MACH_Pmac) { | ||
153 | struct device_node *of_node; | ||
154 | |||
155 | /* Re-enable USB PAD & cell clock */ | ||
156 | of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller)); | ||
157 | if (of_node) | ||
158 | pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1); | ||
159 | } | ||
160 | #endif /* CONFIG_PPC_PMAC */ | ||
161 | |||
162 | /* resume root hub */ | ||
163 | if (time_before (jiffies, ohci->next_statechange)) | ||
164 | msleep (100); | ||
165 | #ifdef CONFIG_USB_SUSPEND | ||
166 | /* get extra cleanup even if remote wakeup isn't in use */ | ||
167 | retval = usb_resume_device (hcd->self.root_hub); | ||
168 | #else | ||
169 | usb_lock_device (hcd->self.root_hub); | ||
170 | retval = ohci_hub_resume (hcd); | ||
171 | usb_unlock_device (hcd->self.root_hub); | ||
172 | #endif | ||
173 | |||
174 | return retval; | ||
175 | } | 140 | } |
176 | 141 | ||
177 | #endif /* CONFIG_PM */ | 142 | #endif /* CONFIG_PM */ |
@@ -218,9 +183,9 @@ static const struct hc_driver ohci_pci_hc_driver = { | |||
218 | */ | 183 | */ |
219 | .hub_status_data = ohci_hub_status_data, | 184 | .hub_status_data = ohci_hub_status_data, |
220 | .hub_control = ohci_hub_control, | 185 | .hub_control = ohci_hub_control, |
221 | #ifdef CONFIG_USB_SUSPEND | 186 | #ifdef CONFIG_PM |
222 | .hub_suspend = ohci_hub_suspend, | 187 | .bus_suspend = ohci_bus_suspend, |
223 | .hub_resume = ohci_hub_resume, | 188 | .bus_resume = ohci_bus_resume, |
224 | #endif | 189 | #endif |
225 | .start_port_reset = ohci_start_port_reset, | 190 | .start_port_reset = ohci_start_port_reset, |
226 | }; | 191 | }; |
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 251533363028..2ec6a78bd65e 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -14,6 +14,8 @@ | |||
14 | * This file is licenced under the GPL. | 14 | * This file is licenced under the GPL. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/platform_device.h> | ||
18 | |||
17 | /* configure so an HC device and id are always provided */ | 19 | /* configure so an HC device and id are always provided */ |
18 | /* always called with process context; sleeping is OK */ | 20 | /* always called with process context; sleeping is OK */ |
19 | 21 | ||
@@ -163,16 +165,15 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = { | |||
163 | */ | 165 | */ |
164 | .hub_status_data = ohci_hub_status_data, | 166 | .hub_status_data = ohci_hub_status_data, |
165 | .hub_control = ohci_hub_control, | 167 | .hub_control = ohci_hub_control, |
166 | #ifdef CONFIG_USB_SUSPEND | 168 | #ifdef CONFIG_PM |
167 | .hub_suspend = ohci_hub_suspend, | 169 | .bus_suspend = ohci_bus_suspend, |
168 | .hub_resume = ohci_hub_resume, | 170 | .bus_resume = ohci_bus_resume, |
169 | #endif | 171 | #endif |
170 | .start_port_reset = ohci_start_port_reset, | 172 | .start_port_reset = ohci_start_port_reset, |
171 | }; | 173 | }; |
172 | 174 | ||
173 | static int ohci_hcd_ppc_soc_drv_probe(struct device *dev) | 175 | static int ohci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) |
174 | { | 176 | { |
175 | struct platform_device *pdev = to_platform_device(dev); | ||
176 | int ret; | 177 | int ret; |
177 | 178 | ||
178 | if (usb_disabled()) | 179 | if (usb_disabled()) |
@@ -182,24 +183,25 @@ static int ohci_hcd_ppc_soc_drv_probe(struct device *dev) | |||
182 | return ret; | 183 | return ret; |
183 | } | 184 | } |
184 | 185 | ||
185 | static int ohci_hcd_ppc_soc_drv_remove(struct device *dev) | 186 | static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev) |
186 | { | 187 | { |
187 | struct platform_device *pdev = to_platform_device(dev); | 188 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
188 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
189 | 189 | ||
190 | usb_hcd_ppc_soc_remove(hcd, pdev); | 190 | usb_hcd_ppc_soc_remove(hcd, pdev); |
191 | return 0; | 191 | return 0; |
192 | } | 192 | } |
193 | 193 | ||
194 | static struct device_driver ohci_hcd_ppc_soc_driver = { | 194 | static struct platform_driver ohci_hcd_ppc_soc_driver = { |
195 | .name = "ppc-soc-ohci", | ||
196 | .bus = &platform_bus_type, | ||
197 | .probe = ohci_hcd_ppc_soc_drv_probe, | 195 | .probe = ohci_hcd_ppc_soc_drv_probe, |
198 | .remove = ohci_hcd_ppc_soc_drv_remove, | 196 | .remove = ohci_hcd_ppc_soc_drv_remove, |
199 | #if defined(CONFIG_USB_SUSPEND) || defined(CONFIG_PM) | 197 | #ifdef CONFIG_PM |
200 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ | 198 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ |
201 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ | 199 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ |
202 | #endif | 200 | #endif |
201 | .driver = { | ||
202 | .name = "ppc-soc-ohci", | ||
203 | .owner = THIS_MODULE, | ||
204 | }, | ||
203 | }; | 205 | }; |
204 | 206 | ||
205 | static int __init ohci_hcd_ppc_soc_init(void) | 207 | static int __init ohci_hcd_ppc_soc_init(void) |
@@ -208,12 +210,12 @@ static int __init ohci_hcd_ppc_soc_init(void) | |||
208 | pr_debug("block sizes: ed %d td %d\n", sizeof(struct ed), | 210 | pr_debug("block sizes: ed %d td %d\n", sizeof(struct ed), |
209 | sizeof(struct td)); | 211 | sizeof(struct td)); |
210 | 212 | ||
211 | return driver_register(&ohci_hcd_ppc_soc_driver); | 213 | return platform_driver_register(&ohci_hcd_ppc_soc_driver); |
212 | } | 214 | } |
213 | 215 | ||
214 | static void __exit ohci_hcd_ppc_soc_cleanup(void) | 216 | static void __exit ohci_hcd_ppc_soc_cleanup(void) |
215 | { | 217 | { |
216 | driver_unregister(&ohci_hcd_ppc_soc_driver); | 218 | platform_driver_unregister(&ohci_hcd_ppc_soc_driver); |
217 | } | 219 | } |
218 | 220 | ||
219 | module_init(ohci_hcd_ppc_soc_init); | 221 | module_init(ohci_hcd_ppc_soc_init); |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 2fdb262d4726..9d65ec307990 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -20,6 +20,9 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/signal.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | |||
23 | #include <asm/mach-types.h> | 26 | #include <asm/mach-types.h> |
24 | #include <asm/hardware.h> | 27 | #include <asm/hardware.h> |
25 | #include <asm/arch/pxa-regs.h> | 28 | #include <asm/arch/pxa-regs.h> |
@@ -278,17 +281,17 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { | |||
278 | */ | 281 | */ |
279 | .hub_status_data = ohci_hub_status_data, | 282 | .hub_status_data = ohci_hub_status_data, |
280 | .hub_control = ohci_hub_control, | 283 | .hub_control = ohci_hub_control, |
281 | #ifdef CONFIG_USB_SUSPEND | 284 | #ifdef CONFIG_PM |
282 | .hub_suspend = ohci_hub_suspend, | 285 | .bus_suspend = ohci_bus_suspend, |
283 | .hub_resume = ohci_hub_resume, | 286 | .bus_resume = ohci_bus_resume, |
284 | #endif | 287 | #endif |
288 | .start_port_reset = ohci_start_port_reset, | ||
285 | }; | 289 | }; |
286 | 290 | ||
287 | /*-------------------------------------------------------------------------*/ | 291 | /*-------------------------------------------------------------------------*/ |
288 | 292 | ||
289 | static int ohci_hcd_pxa27x_drv_probe(struct device *dev) | 293 | static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev) |
290 | { | 294 | { |
291 | struct platform_device *pdev = to_platform_device(dev); | ||
292 | int ret; | 295 | int ret; |
293 | 296 | ||
294 | pr_debug ("In ohci_hcd_pxa27x_drv_probe"); | 297 | pr_debug ("In ohci_hcd_pxa27x_drv_probe"); |
@@ -300,41 +303,39 @@ static int ohci_hcd_pxa27x_drv_probe(struct device *dev) | |||
300 | return ret; | 303 | return ret; |
301 | } | 304 | } |
302 | 305 | ||
303 | static int ohci_hcd_pxa27x_drv_remove(struct device *dev) | 306 | static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev) |
304 | { | 307 | { |
305 | struct platform_device *pdev = to_platform_device(dev); | 308 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
306 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
307 | 309 | ||
308 | usb_hcd_pxa27x_remove(hcd, pdev); | 310 | usb_hcd_pxa27x_remove(hcd, pdev); |
309 | return 0; | 311 | return 0; |
310 | } | 312 | } |
311 | 313 | ||
312 | static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state, u32 level) | 314 | static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *dev, pm_message_t state) |
313 | { | 315 | { |
314 | // struct platform_device *pdev = to_platform_device(dev); | 316 | // struct usb_hcd *hcd = platform_get_drvdata(dev); |
315 | // struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
316 | printk("%s: not implemented yet\n", __FUNCTION__); | 317 | printk("%s: not implemented yet\n", __FUNCTION__); |
317 | 318 | ||
318 | return 0; | 319 | return 0; |
319 | } | 320 | } |
320 | 321 | ||
321 | static int ohci_hcd_pxa27x_drv_resume(struct device *dev, u32 level) | 322 | static int ohci_hcd_pxa27x_drv_resume(struct platform_device *dev) |
322 | { | 323 | { |
323 | // struct platform_device *pdev = to_platform_device(dev); | 324 | // struct usb_hcd *hcd = platform_get_drvdata(dev); |
324 | // struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
325 | printk("%s: not implemented yet\n", __FUNCTION__); | 325 | printk("%s: not implemented yet\n", __FUNCTION__); |
326 | 326 | ||
327 | return 0; | 327 | return 0; |
328 | } | 328 | } |
329 | 329 | ||
330 | 330 | ||
331 | static struct device_driver ohci_hcd_pxa27x_driver = { | 331 | static struct platform_driver ohci_hcd_pxa27x_driver = { |
332 | .name = "pxa27x-ohci", | ||
333 | .bus = &platform_bus_type, | ||
334 | .probe = ohci_hcd_pxa27x_drv_probe, | 332 | .probe = ohci_hcd_pxa27x_drv_probe, |
335 | .remove = ohci_hcd_pxa27x_drv_remove, | 333 | .remove = ohci_hcd_pxa27x_drv_remove, |
336 | .suspend = ohci_hcd_pxa27x_drv_suspend, | 334 | .suspend = ohci_hcd_pxa27x_drv_suspend, |
337 | .resume = ohci_hcd_pxa27x_drv_resume, | 335 | .resume = ohci_hcd_pxa27x_drv_resume, |
336 | .driver = { | ||
337 | .name = "pxa27x-ohci", | ||
338 | }, | ||
338 | }; | 339 | }; |
339 | 340 | ||
340 | static int __init ohci_hcd_pxa27x_init (void) | 341 | static int __init ohci_hcd_pxa27x_init (void) |
@@ -343,12 +344,12 @@ static int __init ohci_hcd_pxa27x_init (void) | |||
343 | pr_debug ("block sizes: ed %d td %d\n", | 344 | pr_debug ("block sizes: ed %d td %d\n", |
344 | sizeof (struct ed), sizeof (struct td)); | 345 | sizeof (struct ed), sizeof (struct td)); |
345 | 346 | ||
346 | return driver_register(&ohci_hcd_pxa27x_driver); | 347 | return platform_driver_register(&ohci_hcd_pxa27x_driver); |
347 | } | 348 | } |
348 | 349 | ||
349 | static void __exit ohci_hcd_pxa27x_cleanup (void) | 350 | static void __exit ohci_hcd_pxa27x_cleanup (void) |
350 | { | 351 | { |
351 | driver_unregister(&ohci_hcd_pxa27x_driver); | 352 | platform_driver_unregister(&ohci_hcd_pxa27x_driver); |
352 | } | 353 | } |
353 | 354 | ||
354 | module_init (ohci_hcd_pxa27x_init); | 355 | module_init (ohci_hcd_pxa27x_init); |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 3d9bcf78a9a4..35cc9402adc0 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -19,8 +19,9 @@ | |||
19 | * This file is licenced under the GPL. | 19 | * This file is licenced under the GPL. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/platform_device.h> | ||
23 | |||
22 | #include <asm/hardware.h> | 24 | #include <asm/hardware.h> |
23 | #include <asm/mach-types.h> | ||
24 | #include <asm/hardware/clock.h> | 25 | #include <asm/hardware/clock.h> |
25 | #include <asm/arch/usb-control.h> | 26 | #include <asm/arch/usb-control.h> |
26 | 27 | ||
@@ -449,47 +450,47 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { | |||
449 | */ | 450 | */ |
450 | .hub_status_data = ohci_s3c2410_hub_status_data, | 451 | .hub_status_data = ohci_s3c2410_hub_status_data, |
451 | .hub_control = ohci_s3c2410_hub_control, | 452 | .hub_control = ohci_s3c2410_hub_control, |
452 | 453 | #ifdef CONFIG_PM | |
453 | #if defined(CONFIG_USB_SUSPEND) && 0 | 454 | .bus_suspend = ohci_bus_suspend, |
454 | .hub_suspend = ohci_hub_suspend, | 455 | .bus_resume = ohci_bus_resume, |
455 | .hub_resume = ohci_hub_resume, | ||
456 | #endif | 456 | #endif |
457 | .start_port_reset = ohci_start_port_reset, | ||
457 | }; | 458 | }; |
458 | 459 | ||
459 | /* device driver */ | 460 | /* device driver */ |
460 | 461 | ||
461 | static int ohci_hcd_s3c2410_drv_probe(struct device *dev) | 462 | static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev) |
462 | { | 463 | { |
463 | struct platform_device *pdev = to_platform_device(dev); | ||
464 | return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev); | 464 | return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev); |
465 | } | 465 | } |
466 | 466 | ||
467 | static int ohci_hcd_s3c2410_drv_remove(struct device *dev) | 467 | static int ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev) |
468 | { | 468 | { |
469 | struct platform_device *pdev = to_platform_device(dev); | 469 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
470 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
471 | 470 | ||
472 | usb_hcd_s3c2410_remove(hcd, pdev); | 471 | usb_hcd_s3c2410_remove(hcd, pdev); |
473 | return 0; | 472 | return 0; |
474 | } | 473 | } |
475 | 474 | ||
476 | static struct device_driver ohci_hcd_s3c2410_driver = { | 475 | static struct platform_driver ohci_hcd_s3c2410_driver = { |
477 | .name = "s3c2410-ohci", | ||
478 | .bus = &platform_bus_type, | ||
479 | .probe = ohci_hcd_s3c2410_drv_probe, | 476 | .probe = ohci_hcd_s3c2410_drv_probe, |
480 | .remove = ohci_hcd_s3c2410_drv_remove, | 477 | .remove = ohci_hcd_s3c2410_drv_remove, |
481 | /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ | 478 | /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ |
482 | /*.resume = ohci_hcd_s3c2410_drv_resume, */ | 479 | /*.resume = ohci_hcd_s3c2410_drv_resume, */ |
480 | .driver = { | ||
481 | .owner = THIS_MODULE, | ||
482 | .name = "s3c2410-ohci", | ||
483 | }, | ||
483 | }; | 484 | }; |
484 | 485 | ||
485 | static int __init ohci_hcd_s3c2410_init (void) | 486 | static int __init ohci_hcd_s3c2410_init (void) |
486 | { | 487 | { |
487 | return driver_register(&ohci_hcd_s3c2410_driver); | 488 | return platform_driver_register(&ohci_hcd_s3c2410_driver); |
488 | } | 489 | } |
489 | 490 | ||
490 | static void __exit ohci_hcd_s3c2410_cleanup (void) | 491 | static void __exit ohci_hcd_s3c2410_cleanup (void) |
491 | { | 492 | { |
492 | driver_unregister(&ohci_hcd_s3c2410_driver); | 493 | platform_driver_unregister(&ohci_hcd_s3c2410_driver); |
493 | } | 494 | } |
494 | 495 | ||
495 | module_init (ohci_hcd_s3c2410_init); | 496 | module_init (ohci_hcd_s3c2410_init); |
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 814d2be4ee7b..fb3221ebbb29 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -235,10 +235,11 @@ static const struct hc_driver ohci_sa1111_hc_driver = { | |||
235 | */ | 235 | */ |
236 | .hub_status_data = ohci_hub_status_data, | 236 | .hub_status_data = ohci_hub_status_data, |
237 | .hub_control = ohci_hub_control, | 237 | .hub_control = ohci_hub_control, |
238 | #ifdef CONFIG_USB_SUSPEND | 238 | #ifdef CONFIG_PM |
239 | .hub_suspend = ohci_hub_suspend, | 239 | .bus_suspend = ohci_bus_suspend, |
240 | .hub_resume = ohci_hub_resume, | 240 | .bus_resume = ohci_bus_resume, |
241 | #endif | 241 | #endif |
242 | .start_port_reset = ohci_start_port_reset, | ||
242 | }; | 243 | }; |
243 | 244 | ||
244 | /*-------------------------------------------------------------------------*/ | 245 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 8a9b9d9209e9..caacf14371f5 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -389,7 +389,6 @@ struct ohci_hcd { | |||
389 | unsigned long next_statechange; /* suspend/resume */ | 389 | unsigned long next_statechange; /* suspend/resume */ |
390 | u32 fminterval; /* saved register */ | 390 | u32 fminterval; /* saved register */ |
391 | 391 | ||
392 | struct work_struct rh_resume; | ||
393 | struct notifier_block reboot_notifier; | 392 | struct notifier_block reboot_notifier; |
394 | 393 | ||
395 | unsigned long flags; /* for HC bugs */ | 394 | unsigned long flags; /* for HC bugs */ |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c new file mode 100644 index 000000000000..e46528c825bf --- /dev/null +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -0,0 +1,319 @@ | |||
1 | /* | ||
2 | * This file contains code to reset and initialize USB host controllers. | ||
3 | * Some of it includes work-arounds for PCI hardware and BIOS quirks. | ||
4 | * It may need to run early during booting -- before USB would normally | ||
5 | * initialize -- to ensure that Linux doesn't use any legacy modes. | ||
6 | * | ||
7 | * Copyright (c) 1999 Martin Mares <mj@ucw.cz> | ||
8 | * (and others) | ||
9 | */ | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | #ifdef CONFIG_USB_DEBUG | ||
13 | #define DEBUG | ||
14 | #else | ||
15 | #undef DEBUG | ||
16 | #endif | ||
17 | |||
18 | #include <linux/types.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/acpi.h> | ||
24 | |||
25 | |||
26 | #define UHCI_USBLEGSUP 0xc0 /* legacy support */ | ||
27 | #define UHCI_USBCMD 0 /* command register */ | ||
28 | #define UHCI_USBINTR 4 /* interrupt register */ | ||
29 | #define UHCI_USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ | ||
30 | #define UHCI_USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ | ||
31 | #define UHCI_USBCMD_RUN 0x0001 /* RUN/STOP bit */ | ||
32 | #define UHCI_USBCMD_HCRESET 0x0002 /* Host Controller reset */ | ||
33 | #define UHCI_USBCMD_EGSM 0x0008 /* Global Suspend Mode */ | ||
34 | #define UHCI_USBCMD_CONFIGURE 0x0040 /* Config Flag */ | ||
35 | #define UHCI_USBINTR_RESUME 0x0002 /* Resume interrupt enable */ | ||
36 | |||
37 | #define OHCI_CONTROL 0x04 | ||
38 | #define OHCI_CMDSTATUS 0x08 | ||
39 | #define OHCI_INTRSTATUS 0x0c | ||
40 | #define OHCI_INTRENABLE 0x10 | ||
41 | #define OHCI_INTRDISABLE 0x14 | ||
42 | #define OHCI_OCR (1 << 3) /* ownership change request */ | ||
43 | #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ | ||
44 | #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ | ||
45 | #define OHCI_INTR_OC (1 << 30) /* ownership change */ | ||
46 | |||
47 | #define EHCI_HCC_PARAMS 0x08 /* extended capabilities */ | ||
48 | #define EHCI_USBCMD 0 /* command register */ | ||
49 | #define EHCI_USBCMD_RUN (1 << 0) /* RUN/STOP bit */ | ||
50 | #define EHCI_USBSTS 4 /* status register */ | ||
51 | #define EHCI_USBSTS_HALTED (1 << 12) /* HCHalted bit */ | ||
52 | #define EHCI_USBINTR 8 /* interrupt register */ | ||
53 | #define EHCI_USBLEGSUP 0 /* legacy support register */ | ||
54 | #define EHCI_USBLEGSUP_BIOS (1 << 16) /* BIOS semaphore */ | ||
55 | #define EHCI_USBLEGSUP_OS (1 << 24) /* OS semaphore */ | ||
56 | #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ | ||
57 | #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ | ||
58 | |||
59 | |||
60 | /* | ||
61 | * Make sure the controller is completely inactive, unable to | ||
62 | * generate interrupts or do DMA. | ||
63 | */ | ||
64 | void uhci_reset_hc(struct pci_dev *pdev, unsigned long base) | ||
65 | { | ||
66 | /* Turn off PIRQ enable and SMI enable. (This also turns off the | ||
67 | * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. | ||
68 | */ | ||
69 | pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_RWC); | ||
70 | |||
71 | /* Reset the HC - this will force us to get a | ||
72 | * new notification of any already connected | ||
73 | * ports due to the virtual disconnect that it | ||
74 | * implies. | ||
75 | */ | ||
76 | outw(UHCI_USBCMD_HCRESET, base + UHCI_USBCMD); | ||
77 | mb(); | ||
78 | udelay(5); | ||
79 | if (inw(base + UHCI_USBCMD) & UHCI_USBCMD_HCRESET) | ||
80 | dev_warn(&pdev->dev, "HCRESET not completed yet!\n"); | ||
81 | |||
82 | /* Just to be safe, disable interrupt requests and | ||
83 | * make sure the controller is stopped. | ||
84 | */ | ||
85 | outw(0, base + UHCI_USBINTR); | ||
86 | outw(0, base + UHCI_USBCMD); | ||
87 | } | ||
88 | EXPORT_SYMBOL_GPL(uhci_reset_hc); | ||
89 | |||
90 | /* | ||
91 | * Initialize a controller that was newly discovered or has just been | ||
92 | * resumed. In either case we can't be sure of its previous state. | ||
93 | * | ||
94 | * Returns: 1 if the controller was reset, 0 otherwise. | ||
95 | */ | ||
96 | int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) | ||
97 | { | ||
98 | u16 legsup; | ||
99 | unsigned int cmd, intr; | ||
100 | |||
101 | /* | ||
102 | * When restarting a suspended controller, we expect all the | ||
103 | * settings to be the same as we left them: | ||
104 | * | ||
105 | * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; | ||
106 | * Controller is stopped and configured with EGSM set; | ||
107 | * No interrupts enabled except possibly Resume Detect. | ||
108 | * | ||
109 | * If any of these conditions are violated we do a complete reset. | ||
110 | */ | ||
111 | pci_read_config_word(pdev, UHCI_USBLEGSUP, &legsup); | ||
112 | if (legsup & ~(UHCI_USBLEGSUP_RO | UHCI_USBLEGSUP_RWC)) { | ||
113 | dev_dbg(&pdev->dev, "%s: legsup = 0x%04x\n", | ||
114 | __FUNCTION__, legsup); | ||
115 | goto reset_needed; | ||
116 | } | ||
117 | |||
118 | cmd = inw(base + UHCI_USBCMD); | ||
119 | if ((cmd & UHCI_USBCMD_RUN) || !(cmd & UHCI_USBCMD_CONFIGURE) || | ||
120 | !(cmd & UHCI_USBCMD_EGSM)) { | ||
121 | dev_dbg(&pdev->dev, "%s: cmd = 0x%04x\n", | ||
122 | __FUNCTION__, cmd); | ||
123 | goto reset_needed; | ||
124 | } | ||
125 | |||
126 | intr = inw(base + UHCI_USBINTR); | ||
127 | if (intr & (~UHCI_USBINTR_RESUME)) { | ||
128 | dev_dbg(&pdev->dev, "%s: intr = 0x%04x\n", | ||
129 | __FUNCTION__, intr); | ||
130 | goto reset_needed; | ||
131 | } | ||
132 | return 0; | ||
133 | |||
134 | reset_needed: | ||
135 | dev_dbg(&pdev->dev, "Performing full reset\n"); | ||
136 | uhci_reset_hc(pdev, base); | ||
137 | return 1; | ||
138 | } | ||
139 | EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); | ||
140 | |||
141 | static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) | ||
142 | { | ||
143 | u16 cmd; | ||
144 | return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask); | ||
145 | } | ||
146 | |||
147 | #define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO) | ||
148 | #define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY) | ||
149 | |||
150 | static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) | ||
151 | { | ||
152 | unsigned long base = 0; | ||
153 | int i; | ||
154 | |||
155 | if (!pio_enabled(pdev)) | ||
156 | return; | ||
157 | |||
158 | for (i = 0; i < PCI_ROM_RESOURCE; i++) | ||
159 | if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { | ||
160 | base = pci_resource_start(pdev, i); | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | if (base) | ||
165 | uhci_check_and_reset_hc(pdev, base); | ||
166 | } | ||
167 | |||
168 | static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx) | ||
169 | { | ||
170 | return pci_resource_start(pdev, idx) && mmio_enabled(pdev); | ||
171 | } | ||
172 | |||
173 | static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | ||
174 | { | ||
175 | void __iomem *base; | ||
176 | int wait_time; | ||
177 | u32 control; | ||
178 | |||
179 | if (!mmio_resource_enabled(pdev, 0)) | ||
180 | return; | ||
181 | |||
182 | base = ioremap_nocache(pci_resource_start(pdev, 0), | ||
183 | pci_resource_len(pdev, 0)); | ||
184 | if (base == NULL) return; | ||
185 | |||
186 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ | ||
187 | #ifndef __hppa__ | ||
188 | control = readl(base + OHCI_CONTROL); | ||
189 | if (control & OHCI_CTRL_IR) { | ||
190 | wait_time = 500; /* arbitrary; 5 seconds */ | ||
191 | writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); | ||
192 | writel(OHCI_OCR, base + OHCI_CMDSTATUS); | ||
193 | while (wait_time > 0 && | ||
194 | readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { | ||
195 | wait_time -= 10; | ||
196 | msleep(10); | ||
197 | } | ||
198 | if (wait_time <= 0) | ||
199 | printk(KERN_WARNING "%s %s: early BIOS handoff " | ||
200 | "failed (BIOS bug ?)\n", | ||
201 | pdev->dev.bus_id, "OHCI"); | ||
202 | |||
203 | /* reset controller, preserving RWC */ | ||
204 | writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL); | ||
205 | } | ||
206 | #endif | ||
207 | |||
208 | /* | ||
209 | * disable interrupts | ||
210 | */ | ||
211 | writel(~(u32)0, base + OHCI_INTRDISABLE); | ||
212 | writel(~(u32)0, base + OHCI_INTRSTATUS); | ||
213 | |||
214 | iounmap(base); | ||
215 | } | ||
216 | |||
217 | static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | ||
218 | { | ||
219 | int wait_time, delta; | ||
220 | void __iomem *base, *op_reg_base; | ||
221 | u32 hcc_params, val, temp; | ||
222 | u8 cap_length; | ||
223 | |||
224 | if (!mmio_resource_enabled(pdev, 0)) | ||
225 | return; | ||
226 | |||
227 | base = ioremap_nocache(pci_resource_start(pdev, 0), | ||
228 | pci_resource_len(pdev, 0)); | ||
229 | if (base == NULL) return; | ||
230 | |||
231 | cap_length = readb(base); | ||
232 | op_reg_base = base + cap_length; | ||
233 | hcc_params = readl(base + EHCI_HCC_PARAMS); | ||
234 | hcc_params = (hcc_params >> 8) & 0xff; | ||
235 | if (hcc_params) { | ||
236 | pci_read_config_dword(pdev, | ||
237 | hcc_params + EHCI_USBLEGSUP, | ||
238 | &val); | ||
239 | if (((val & 0xff) == 1) && (val & EHCI_USBLEGSUP_BIOS)) { | ||
240 | /* | ||
241 | * Ok, BIOS is in smm mode, try to hand off... | ||
242 | */ | ||
243 | pci_read_config_dword(pdev, | ||
244 | hcc_params + EHCI_USBLEGCTLSTS, | ||
245 | &temp); | ||
246 | pci_write_config_dword(pdev, | ||
247 | hcc_params + EHCI_USBLEGCTLSTS, | ||
248 | temp | EHCI_USBLEGCTLSTS_SOOE); | ||
249 | val |= EHCI_USBLEGSUP_OS; | ||
250 | pci_write_config_dword(pdev, | ||
251 | hcc_params + EHCI_USBLEGSUP, | ||
252 | val); | ||
253 | |||
254 | wait_time = 500; | ||
255 | do { | ||
256 | msleep(10); | ||
257 | wait_time -= 10; | ||
258 | pci_read_config_dword(pdev, | ||
259 | hcc_params + EHCI_USBLEGSUP, | ||
260 | &val); | ||
261 | } while (wait_time && (val & EHCI_USBLEGSUP_BIOS)); | ||
262 | if (!wait_time) { | ||
263 | /* | ||
264 | * well, possibly buggy BIOS... | ||
265 | */ | ||
266 | printk(KERN_WARNING "%s %s: early BIOS handoff " | ||
267 | "failed (BIOS bug ?)\n", | ||
268 | pdev->dev.bus_id, "EHCI"); | ||
269 | pci_write_config_dword(pdev, | ||
270 | hcc_params + EHCI_USBLEGSUP, | ||
271 | EHCI_USBLEGSUP_OS); | ||
272 | pci_write_config_dword(pdev, | ||
273 | hcc_params + EHCI_USBLEGCTLSTS, | ||
274 | 0); | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * halt EHCI & disable its interrupts in any case | ||
281 | */ | ||
282 | val = readl(op_reg_base + EHCI_USBSTS); | ||
283 | if ((val & EHCI_USBSTS_HALTED) == 0) { | ||
284 | val = readl(op_reg_base + EHCI_USBCMD); | ||
285 | val &= ~EHCI_USBCMD_RUN; | ||
286 | writel(val, op_reg_base + EHCI_USBCMD); | ||
287 | |||
288 | wait_time = 2000; | ||
289 | delta = 100; | ||
290 | do { | ||
291 | writel(0x3f, op_reg_base + EHCI_USBSTS); | ||
292 | udelay(delta); | ||
293 | wait_time -= delta; | ||
294 | val = readl(op_reg_base + EHCI_USBSTS); | ||
295 | if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { | ||
296 | break; | ||
297 | } | ||
298 | } while (wait_time > 0); | ||
299 | } | ||
300 | writel(0, op_reg_base + EHCI_USBINTR); | ||
301 | writel(0x3f, op_reg_base + EHCI_USBSTS); | ||
302 | |||
303 | iounmap(base); | ||
304 | |||
305 | return; | ||
306 | } | ||
307 | |||
308 | |||
309 | |||
310 | static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) | ||
311 | { | ||
312 | if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) | ||
313 | quirk_usb_handoff_uhci(pdev); | ||
314 | else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI) | ||
315 | quirk_usb_handoff_ohci(pdev); | ||
316 | else if (pdev->class == PCI_CLASS_SERIAL_USB_EHCI) | ||
317 | quirk_usb_disable_ehci(pdev); | ||
318 | } | ||
319 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); | ||
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index d2a1fd40dfcb..a7722a6a5a5b 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/interrupt.h> | 54 | #include <linux/interrupt.h> |
55 | #include <linux/usb.h> | 55 | #include <linux/usb.h> |
56 | #include <linux/usb_sl811.h> | 56 | #include <linux/usb_sl811.h> |
57 | #include <linux/platform_device.h> | ||
57 | 58 | ||
58 | #include <asm/io.h> | 59 | #include <asm/io.h> |
59 | #include <asm/irq.h> | 60 | #include <asm/irq.h> |
@@ -782,6 +783,9 @@ retry: | |||
782 | /* usb 1.1 says max 90% of a frame is available for periodic transfers. | 783 | /* usb 1.1 says max 90% of a frame is available for periodic transfers. |
783 | * this driver doesn't promise that much since it's got to handle an | 784 | * this driver doesn't promise that much since it's got to handle an |
784 | * IRQ per packet; irq handling latencies also use up that time. | 785 | * IRQ per packet; irq handling latencies also use up that time. |
786 | * | ||
787 | * NOTE: the periodic schedule is a sparse tree, with the load for | ||
788 | * each branch minimized. see fig 3.5 in the OHCI spec for example. | ||
785 | */ | 789 | */ |
786 | #define MAX_PERIODIC_LOAD 500 /* out of 1000 usec */ | 790 | #define MAX_PERIODIC_LOAD 500 /* out of 1000 usec */ |
787 | 791 | ||
@@ -815,7 +819,7 @@ static int sl811h_urb_enqueue( | |||
815 | struct usb_hcd *hcd, | 819 | struct usb_hcd *hcd, |
816 | struct usb_host_endpoint *hep, | 820 | struct usb_host_endpoint *hep, |
817 | struct urb *urb, | 821 | struct urb *urb, |
818 | unsigned mem_flags | 822 | gfp_t mem_flags |
819 | ) { | 823 | ) { |
820 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 824 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
821 | struct usb_device *udev = urb->dev; | 825 | struct usb_device *udev = urb->dev; |
@@ -843,6 +847,7 @@ static int sl811h_urb_enqueue( | |||
843 | if (!(sl811->port1 & (1 << USB_PORT_FEAT_ENABLE)) | 847 | if (!(sl811->port1 & (1 << USB_PORT_FEAT_ENABLE)) |
844 | || !HC_IS_RUNNING(hcd->state)) { | 848 | || !HC_IS_RUNNING(hcd->state)) { |
845 | retval = -ENODEV; | 849 | retval = -ENODEV; |
850 | kfree(ep); | ||
846 | goto fail; | 851 | goto fail; |
847 | } | 852 | } |
848 | 853 | ||
@@ -911,8 +916,16 @@ static int sl811h_urb_enqueue( | |||
911 | case PIPE_ISOCHRONOUS: | 916 | case PIPE_ISOCHRONOUS: |
912 | case PIPE_INTERRUPT: | 917 | case PIPE_INTERRUPT: |
913 | urb->interval = ep->period; | 918 | urb->interval = ep->period; |
914 | if (ep->branch < PERIODIC_SIZE) | 919 | if (ep->branch < PERIODIC_SIZE) { |
920 | /* NOTE: the phase is correct here, but the value | ||
921 | * needs offsetting by the transfer queue depth. | ||
922 | * All current drivers ignore start_frame, so this | ||
923 | * is unlikely to ever matter... | ||
924 | */ | ||
925 | urb->start_frame = (sl811->frame & (PERIODIC_SIZE - 1)) | ||
926 | + ep->branch; | ||
915 | break; | 927 | break; |
928 | } | ||
916 | 929 | ||
917 | retval = balance(sl811, ep->period, ep->load); | 930 | retval = balance(sl811, ep->period, ep->load); |
918 | if (retval < 0) | 931 | if (retval < 0) |
@@ -1122,7 +1135,7 @@ sl811h_hub_descriptor ( | |||
1122 | desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp); | 1135 | desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp); |
1123 | 1136 | ||
1124 | /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ | 1137 | /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ |
1125 | desc->bitmap[0] = 1 << 1; | 1138 | desc->bitmap[0] = 0 << 1; |
1126 | desc->bitmap[1] = ~0; | 1139 | desc->bitmap[1] = ~0; |
1127 | } | 1140 | } |
1128 | 1141 | ||
@@ -1351,7 +1364,7 @@ error: | |||
1351 | #ifdef CONFIG_PM | 1364 | #ifdef CONFIG_PM |
1352 | 1365 | ||
1353 | static int | 1366 | static int |
1354 | sl811h_hub_suspend(struct usb_hcd *hcd) | 1367 | sl811h_bus_suspend(struct usb_hcd *hcd) |
1355 | { | 1368 | { |
1356 | // SOFs off | 1369 | // SOFs off |
1357 | DBG("%s\n", __FUNCTION__); | 1370 | DBG("%s\n", __FUNCTION__); |
@@ -1359,7 +1372,7 @@ sl811h_hub_suspend(struct usb_hcd *hcd) | |||
1359 | } | 1372 | } |
1360 | 1373 | ||
1361 | static int | 1374 | static int |
1362 | sl811h_hub_resume(struct usb_hcd *hcd) | 1375 | sl811h_bus_resume(struct usb_hcd *hcd) |
1363 | { | 1376 | { |
1364 | // SOFs on | 1377 | // SOFs on |
1365 | DBG("%s\n", __FUNCTION__); | 1378 | DBG("%s\n", __FUNCTION__); |
@@ -1368,8 +1381,8 @@ sl811h_hub_resume(struct usb_hcd *hcd) | |||
1368 | 1381 | ||
1369 | #else | 1382 | #else |
1370 | 1383 | ||
1371 | #define sl811h_hub_suspend NULL | 1384 | #define sl811h_bus_suspend NULL |
1372 | #define sl811h_hub_resume NULL | 1385 | #define sl811h_bus_resume NULL |
1373 | 1386 | ||
1374 | #endif | 1387 | #endif |
1375 | 1388 | ||
@@ -1611,31 +1624,28 @@ static struct hc_driver sl811h_hc_driver = { | |||
1611 | */ | 1624 | */ |
1612 | .hub_status_data = sl811h_hub_status_data, | 1625 | .hub_status_data = sl811h_hub_status_data, |
1613 | .hub_control = sl811h_hub_control, | 1626 | .hub_control = sl811h_hub_control, |
1614 | .hub_suspend = sl811h_hub_suspend, | 1627 | .bus_suspend = sl811h_bus_suspend, |
1615 | .hub_resume = sl811h_hub_resume, | 1628 | .bus_resume = sl811h_bus_resume, |
1616 | }; | 1629 | }; |
1617 | 1630 | ||
1618 | /*-------------------------------------------------------------------------*/ | 1631 | /*-------------------------------------------------------------------------*/ |
1619 | 1632 | ||
1620 | static int __devexit | 1633 | static int __devexit |
1621 | sl811h_remove(struct device *dev) | 1634 | sl811h_remove(struct platform_device *dev) |
1622 | { | 1635 | { |
1623 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 1636 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
1624 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 1637 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
1625 | struct platform_device *pdev; | ||
1626 | struct resource *res; | 1638 | struct resource *res; |
1627 | 1639 | ||
1628 | pdev = container_of(dev, struct platform_device, dev); | ||
1629 | |||
1630 | remove_debug_file(sl811); | 1640 | remove_debug_file(sl811); |
1631 | usb_remove_hcd(hcd); | 1641 | usb_remove_hcd(hcd); |
1632 | 1642 | ||
1633 | /* some platforms may use IORESOURCE_IO */ | 1643 | /* some platforms may use IORESOURCE_IO */ |
1634 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1644 | res = platform_get_resource(dev, IORESOURCE_MEM, 1); |
1635 | if (res) | 1645 | if (res) |
1636 | iounmap(sl811->data_reg); | 1646 | iounmap(sl811->data_reg); |
1637 | 1647 | ||
1638 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1648 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
1639 | if (res) | 1649 | if (res) |
1640 | iounmap(sl811->addr_reg); | 1650 | iounmap(sl811->addr_reg); |
1641 | 1651 | ||
@@ -1644,11 +1654,10 @@ sl811h_remove(struct device *dev) | |||
1644 | } | 1654 | } |
1645 | 1655 | ||
1646 | static int __devinit | 1656 | static int __devinit |
1647 | sl811h_probe(struct device *dev) | 1657 | sl811h_probe(struct platform_device *dev) |
1648 | { | 1658 | { |
1649 | struct usb_hcd *hcd; | 1659 | struct usb_hcd *hcd; |
1650 | struct sl811 *sl811; | 1660 | struct sl811 *sl811; |
1651 | struct platform_device *pdev; | ||
1652 | struct resource *addr, *data; | 1661 | struct resource *addr, *data; |
1653 | int irq; | 1662 | int irq; |
1654 | void __iomem *addr_reg; | 1663 | void __iomem *addr_reg; |
@@ -1661,24 +1670,23 @@ sl811h_probe(struct device *dev) | |||
1661 | * specific platform_data. we don't probe for IRQs, and do only | 1670 | * specific platform_data. we don't probe for IRQs, and do only |
1662 | * minimal sanity checking. | 1671 | * minimal sanity checking. |
1663 | */ | 1672 | */ |
1664 | pdev = container_of(dev, struct platform_device, dev); | 1673 | irq = platform_get_irq(dev, 0); |
1665 | irq = platform_get_irq(pdev, 0); | 1674 | if (dev->num_resources < 3 || irq < 0) |
1666 | if (pdev->num_resources < 3 || irq < 0) | ||
1667 | return -ENODEV; | 1675 | return -ENODEV; |
1668 | 1676 | ||
1669 | /* refuse to confuse usbcore */ | 1677 | /* refuse to confuse usbcore */ |
1670 | if (dev->dma_mask) { | 1678 | if (dev->dev.dma_mask) { |
1671 | DBG("no we won't dma\n"); | 1679 | DBG("no we won't dma\n"); |
1672 | return -EINVAL; | 1680 | return -EINVAL; |
1673 | } | 1681 | } |
1674 | 1682 | ||
1675 | /* the chip may be wired for either kind of addressing */ | 1683 | /* the chip may be wired for either kind of addressing */ |
1676 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1684 | addr = platform_get_resource(dev, IORESOURCE_MEM, 0); |
1677 | data = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1685 | data = platform_get_resource(dev, IORESOURCE_MEM, 1); |
1678 | retval = -EBUSY; | 1686 | retval = -EBUSY; |
1679 | if (!addr || !data) { | 1687 | if (!addr || !data) { |
1680 | addr = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1688 | addr = platform_get_resource(dev, IORESOURCE_IO, 0); |
1681 | data = platform_get_resource(pdev, IORESOURCE_IO, 1); | 1689 | data = platform_get_resource(dev, IORESOURCE_IO, 1); |
1682 | if (!addr || !data) | 1690 | if (!addr || !data) |
1683 | return -ENODEV; | 1691 | return -ENODEV; |
1684 | ioaddr = 1; | 1692 | ioaddr = 1; |
@@ -1700,7 +1708,7 @@ sl811h_probe(struct device *dev) | |||
1700 | } | 1708 | } |
1701 | 1709 | ||
1702 | /* allocate and initialize hcd */ | 1710 | /* allocate and initialize hcd */ |
1703 | hcd = usb_create_hcd(&sl811h_hc_driver, dev, dev->bus_id); | 1711 | hcd = usb_create_hcd(&sl811h_hc_driver, &dev->dev, dev->dev.bus_id); |
1704 | if (!hcd) { | 1712 | if (!hcd) { |
1705 | retval = -ENOMEM; | 1713 | retval = -ENOMEM; |
1706 | goto err5; | 1714 | goto err5; |
@@ -1710,7 +1718,7 @@ sl811h_probe(struct device *dev) | |||
1710 | 1718 | ||
1711 | spin_lock_init(&sl811->lock); | 1719 | spin_lock_init(&sl811->lock); |
1712 | INIT_LIST_HEAD(&sl811->async); | 1720 | INIT_LIST_HEAD(&sl811->async); |
1713 | sl811->board = dev->platform_data; | 1721 | sl811->board = dev->dev.platform_data; |
1714 | init_timer(&sl811->timer); | 1722 | init_timer(&sl811->timer); |
1715 | sl811->timer.function = sl811h_timer; | 1723 | sl811->timer.function = sl811h_timer; |
1716 | sl811->timer.data = (unsigned long) sl811; | 1724 | sl811->timer.data = (unsigned long) sl811; |
@@ -1772,45 +1780,39 @@ sl811h_probe(struct device *dev) | |||
1772 | */ | 1780 | */ |
1773 | 1781 | ||
1774 | static int | 1782 | static int |
1775 | sl811h_suspend(struct device *dev, pm_message_t state, u32 phase) | 1783 | sl811h_suspend(struct platform_device *dev, pm_message_t state) |
1776 | { | 1784 | { |
1777 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 1785 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
1778 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 1786 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
1779 | int retval = 0; | 1787 | int retval = 0; |
1780 | 1788 | ||
1781 | if (phase != SUSPEND_POWER_DOWN) | ||
1782 | return retval; | ||
1783 | |||
1784 | if (state.event == PM_EVENT_FREEZE) | 1789 | if (state.event == PM_EVENT_FREEZE) |
1785 | retval = sl811h_hub_suspend(hcd); | 1790 | retval = sl811h_bus_suspend(hcd); |
1786 | else if (state.event == PM_EVENT_SUSPEND) | 1791 | else if (state.event == PM_EVENT_SUSPEND) |
1787 | port_power(sl811, 0); | 1792 | port_power(sl811, 0); |
1788 | if (retval == 0) | 1793 | if (retval == 0) |
1789 | dev->power.power_state = state; | 1794 | dev->dev.power.power_state = state; |
1790 | return retval; | 1795 | return retval; |
1791 | } | 1796 | } |
1792 | 1797 | ||
1793 | static int | 1798 | static int |
1794 | sl811h_resume(struct device *dev, u32 phase) | 1799 | sl811h_resume(struct platform_device *dev) |
1795 | { | 1800 | { |
1796 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 1801 | struct usb_hcd *hcd = platform_get_drvdata(dev); |
1797 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 1802 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
1798 | 1803 | ||
1799 | if (phase != RESUME_POWER_ON) | ||
1800 | return 0; | ||
1801 | |||
1802 | /* with no "check to see if VBUS is still powered" board hook, | 1804 | /* with no "check to see if VBUS is still powered" board hook, |
1803 | * let's assume it'd only be powered to enable remote wakeup. | 1805 | * let's assume it'd only be powered to enable remote wakeup. |
1804 | */ | 1806 | */ |
1805 | if (dev->power.power_state.event == PM_EVENT_SUSPEND | 1807 | if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND |
1806 | || !hcd->can_wakeup) { | 1808 | || !hcd->can_wakeup) { |
1807 | sl811->port1 = 0; | 1809 | sl811->port1 = 0; |
1808 | port_power(sl811, 1); | 1810 | port_power(sl811, 1); |
1809 | return 0; | 1811 | return 0; |
1810 | } | 1812 | } |
1811 | 1813 | ||
1812 | dev->power.power_state = PMSG_ON; | 1814 | dev->dev.power.power_state = PMSG_ON; |
1813 | return sl811h_hub_resume(hcd); | 1815 | return sl811h_bus_resume(hcd); |
1814 | } | 1816 | } |
1815 | 1817 | ||
1816 | #else | 1818 | #else |
@@ -1822,15 +1824,16 @@ sl811h_resume(struct device *dev, u32 phase) | |||
1822 | 1824 | ||
1823 | 1825 | ||
1824 | /* this driver is exported so sl811_cs can depend on it */ | 1826 | /* this driver is exported so sl811_cs can depend on it */ |
1825 | struct device_driver sl811h_driver = { | 1827 | struct platform_driver sl811h_driver = { |
1826 | .name = (char *) hcd_name, | ||
1827 | .bus = &platform_bus_type, | ||
1828 | |||
1829 | .probe = sl811h_probe, | 1828 | .probe = sl811h_probe, |
1830 | .remove = __devexit_p(sl811h_remove), | 1829 | .remove = __devexit_p(sl811h_remove), |
1831 | 1830 | ||
1832 | .suspend = sl811h_suspend, | 1831 | .suspend = sl811h_suspend, |
1833 | .resume = sl811h_resume, | 1832 | .resume = sl811h_resume, |
1833 | .driver = { | ||
1834 | .name = (char *) hcd_name, | ||
1835 | .owner = THIS_MODULE, | ||
1836 | }, | ||
1834 | }; | 1837 | }; |
1835 | EXPORT_SYMBOL(sl811h_driver); | 1838 | EXPORT_SYMBOL(sl811h_driver); |
1836 | 1839 | ||
@@ -1842,12 +1845,12 @@ static int __init sl811h_init(void) | |||
1842 | return -ENODEV; | 1845 | return -ENODEV; |
1843 | 1846 | ||
1844 | INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION); | 1847 | INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION); |
1845 | return driver_register(&sl811h_driver); | 1848 | return platform_driver_register(&sl811h_driver); |
1846 | } | 1849 | } |
1847 | module_init(sl811h_init); | 1850 | module_init(sl811h_init); |
1848 | 1851 | ||
1849 | static void __exit sl811h_cleanup(void) | 1852 | static void __exit sl811h_cleanup(void) |
1850 | { | 1853 | { |
1851 | driver_unregister(&sl811h_driver); | 1854 | platform_driver_unregister(&sl811h_driver); |
1852 | } | 1855 | } |
1853 | module_exit(sl811h_cleanup); | 1856 | module_exit(sl811h_cleanup); |
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 38aebe361ca1..e73faf831b24 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
20 | #include <linux/timer.h> | 20 | #include <linux/timer.h> |
21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
22 | #include <linux/platform_device.h> | ||
22 | 23 | ||
23 | #include <pcmcia/cs_types.h> | 24 | #include <pcmcia/cs_types.h> |
24 | #include <pcmcia/cs.h> | 25 | #include <pcmcia/cs.h> |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 4538a98b6f9d..151154df37fa 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -348,7 +348,6 @@ static int uhci_show_urbp(struct uhci_hcd *uhci, struct urb_priv *urbp, char *bu | |||
348 | 348 | ||
349 | if (urbp->urb->status != -EINPROGRESS) | 349 | if (urbp->urb->status != -EINPROGRESS) |
350 | out += sprintf(out, "Status=%d ", urbp->urb->status); | 350 | out += sprintf(out, "Status=%d ", urbp->urb->status); |
351 | //out += sprintf(out, "Inserttime=%lx ",urbp->inserttime); | ||
352 | //out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime); | 351 | //out += sprintf(out, "FSBRtime=%lx ",urbp->fsbrtime); |
353 | 352 | ||
354 | count = 0; | 353 | count = 0; |
@@ -446,11 +445,11 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
446 | out += sprintf(out, "Frame List\n"); | 445 | out += sprintf(out, "Frame List\n"); |
447 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { | 446 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { |
448 | int shown = 0; | 447 | int shown = 0; |
449 | td = uhci->fl->frame_cpu[i]; | 448 | td = uhci->frame_cpu[i]; |
450 | if (!td) | 449 | if (!td) |
451 | continue; | 450 | continue; |
452 | 451 | ||
453 | if (td->dma_handle != (dma_addr_t)uhci->fl->frame[i]) { | 452 | if (td->dma_handle != (dma_addr_t)uhci->frame[i]) { |
454 | show_frame_num(); | 453 | show_frame_num(); |
455 | out += sprintf(out, " frame list does not match td->dma_handle!\n"); | 454 | out += sprintf(out, " frame list does not match td->dma_handle!\n"); |
456 | } | 455 | } |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 0c024898cbea..ed550132db0b 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -101,37 +101,16 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | |||
101 | #include "uhci-q.c" | 101 | #include "uhci-q.c" |
102 | #include "uhci-hub.c" | 102 | #include "uhci-hub.c" |
103 | 103 | ||
104 | extern void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); | ||
105 | extern int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); | ||
106 | |||
104 | /* | 107 | /* |
105 | * Make sure the controller is completely inactive, unable to | 108 | * Finish up a host controller reset and update the recorded state. |
106 | * generate interrupts or do DMA. | ||
107 | */ | 109 | */ |
108 | static void reset_hc(struct uhci_hcd *uhci) | 110 | static void finish_reset(struct uhci_hcd *uhci) |
109 | { | 111 | { |
110 | int port; | 112 | int port; |
111 | 113 | ||
112 | /* Turn off PIRQ enable and SMI enable. (This also turns off the | ||
113 | * BIOS's USB Legacy Support.) Turn off all the R/WC bits too. | ||
114 | */ | ||
115 | pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, | ||
116 | USBLEGSUP_RWC); | ||
117 | |||
118 | /* Reset the HC - this will force us to get a | ||
119 | * new notification of any already connected | ||
120 | * ports due to the virtual disconnect that it | ||
121 | * implies. | ||
122 | */ | ||
123 | outw(USBCMD_HCRESET, uhci->io_addr + USBCMD); | ||
124 | mb(); | ||
125 | udelay(5); | ||
126 | if (inw(uhci->io_addr + USBCMD) & USBCMD_HCRESET) | ||
127 | dev_warn(uhci_dev(uhci), "HCRESET not completed yet!\n"); | ||
128 | |||
129 | /* Just to be safe, disable interrupt requests and | ||
130 | * make sure the controller is stopped. | ||
131 | */ | ||
132 | outw(0, uhci->io_addr + USBINTR); | ||
133 | outw(0, uhci->io_addr + USBCMD); | ||
134 | |||
135 | /* HCRESET doesn't affect the Suspend, Reset, and Resume Detect | 114 | /* HCRESET doesn't affect the Suspend, Reset, and Resume Detect |
136 | * bits in the port status and control registers. | 115 | * bits in the port status and control registers. |
137 | * We have to clear them by hand. | 116 | * We have to clear them by hand. |
@@ -153,7 +132,8 @@ static void reset_hc(struct uhci_hcd *uhci) | |||
153 | */ | 132 | */ |
154 | static void hc_died(struct uhci_hcd *uhci) | 133 | static void hc_died(struct uhci_hcd *uhci) |
155 | { | 134 | { |
156 | reset_hc(uhci); | 135 | uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr); |
136 | finish_reset(uhci); | ||
157 | uhci->hc_inaccessible = 1; | 137 | uhci->hc_inaccessible = 1; |
158 | } | 138 | } |
159 | 139 | ||
@@ -163,44 +143,8 @@ static void hc_died(struct uhci_hcd *uhci) | |||
163 | */ | 143 | */ |
164 | static void check_and_reset_hc(struct uhci_hcd *uhci) | 144 | static void check_and_reset_hc(struct uhci_hcd *uhci) |
165 | { | 145 | { |
166 | u16 legsup; | 146 | if (uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr)) |
167 | unsigned int cmd, intr; | 147 | finish_reset(uhci); |
168 | |||
169 | /* | ||
170 | * When restarting a suspended controller, we expect all the | ||
171 | * settings to be the same as we left them: | ||
172 | * | ||
173 | * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; | ||
174 | * Controller is stopped and configured with EGSM set; | ||
175 | * No interrupts enabled except possibly Resume Detect. | ||
176 | * | ||
177 | * If any of these conditions are violated we do a complete reset. | ||
178 | */ | ||
179 | pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup); | ||
180 | if (legsup & ~(USBLEGSUP_RO | USBLEGSUP_RWC)) { | ||
181 | dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n", | ||
182 | __FUNCTION__, legsup); | ||
183 | goto reset_needed; | ||
184 | } | ||
185 | |||
186 | cmd = inw(uhci->io_addr + USBCMD); | ||
187 | if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) { | ||
188 | dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n", | ||
189 | __FUNCTION__, cmd); | ||
190 | goto reset_needed; | ||
191 | } | ||
192 | |||
193 | intr = inw(uhci->io_addr + USBINTR); | ||
194 | if (intr & (~USBINTR_RESUME)) { | ||
195 | dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n", | ||
196 | __FUNCTION__, intr); | ||
197 | goto reset_needed; | ||
198 | } | ||
199 | return; | ||
200 | |||
201 | reset_needed: | ||
202 | dev_dbg(uhci_dev(uhci), "Performing full reset\n"); | ||
203 | reset_hc(uhci); | ||
204 | } | 148 | } |
205 | 149 | ||
206 | /* | 150 | /* |
@@ -212,13 +156,13 @@ static void configure_hc(struct uhci_hcd *uhci) | |||
212 | outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF); | 156 | outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF); |
213 | 157 | ||
214 | /* Store the frame list base address */ | 158 | /* Store the frame list base address */ |
215 | outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD); | 159 | outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD); |
216 | 160 | ||
217 | /* Set the current frame number */ | 161 | /* Set the current frame number */ |
218 | outw(uhci->frame_number, uhci->io_addr + USBFRNUM); | 162 | outw(uhci->frame_number, uhci->io_addr + USBFRNUM); |
219 | 163 | ||
220 | /* Mark controller as running before we enable interrupts */ | 164 | /* Mark controller as not halted before we enable interrupts */ |
221 | uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; | 165 | uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED; |
222 | mb(); | 166 | mb(); |
223 | 167 | ||
224 | /* Enable PIRQ */ | 168 | /* Enable PIRQ */ |
@@ -319,6 +263,7 @@ __acquires(uhci->lock) | |||
319 | 263 | ||
320 | static void start_rh(struct uhci_hcd *uhci) | 264 | static void start_rh(struct uhci_hcd *uhci) |
321 | { | 265 | { |
266 | uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; | ||
322 | uhci->is_stopped = 0; | 267 | uhci->is_stopped = 0; |
323 | smp_wmb(); | 268 | smp_wmb(); |
324 | 269 | ||
@@ -437,36 +382,21 @@ static void release_uhci(struct uhci_hcd *uhci) | |||
437 | int i; | 382 | int i; |
438 | 383 | ||
439 | for (i = 0; i < UHCI_NUM_SKELQH; i++) | 384 | for (i = 0; i < UHCI_NUM_SKELQH; i++) |
440 | if (uhci->skelqh[i]) { | 385 | uhci_free_qh(uhci, uhci->skelqh[i]); |
441 | uhci_free_qh(uhci, uhci->skelqh[i]); | ||
442 | uhci->skelqh[i] = NULL; | ||
443 | } | ||
444 | 386 | ||
445 | if (uhci->term_td) { | 387 | uhci_free_td(uhci, uhci->term_td); |
446 | uhci_free_td(uhci, uhci->term_td); | ||
447 | uhci->term_td = NULL; | ||
448 | } | ||
449 | 388 | ||
450 | if (uhci->qh_pool) { | 389 | dma_pool_destroy(uhci->qh_pool); |
451 | dma_pool_destroy(uhci->qh_pool); | ||
452 | uhci->qh_pool = NULL; | ||
453 | } | ||
454 | 390 | ||
455 | if (uhci->td_pool) { | 391 | dma_pool_destroy(uhci->td_pool); |
456 | dma_pool_destroy(uhci->td_pool); | ||
457 | uhci->td_pool = NULL; | ||
458 | } | ||
459 | 392 | ||
460 | if (uhci->fl) { | 393 | kfree(uhci->frame_cpu); |
461 | dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), | ||
462 | uhci->fl, uhci->fl->dma_handle); | ||
463 | uhci->fl = NULL; | ||
464 | } | ||
465 | 394 | ||
466 | if (uhci->dentry) { | 395 | dma_free_coherent(uhci_dev(uhci), |
467 | debugfs_remove(uhci->dentry); | 396 | UHCI_NUMFRAMES * sizeof(*uhci->frame), |
468 | uhci->dentry = NULL; | 397 | uhci->frame, uhci->frame_dma_handle); |
469 | } | 398 | |
399 | debugfs_remove(uhci->dentry); | ||
470 | } | 400 | } |
471 | 401 | ||
472 | static int uhci_reset(struct usb_hcd *hcd) | 402 | static int uhci_reset(struct usb_hcd *hcd) |
@@ -545,7 +475,6 @@ static int uhci_start(struct usb_hcd *hcd) | |||
545 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); | 475 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
546 | int retval = -EBUSY; | 476 | int retval = -EBUSY; |
547 | int i; | 477 | int i; |
548 | dma_addr_t dma_handle; | ||
549 | struct dentry *dentry; | 478 | struct dentry *dentry; |
550 | 479 | ||
551 | hcd->uses_new_polling = 1; | 480 | hcd->uses_new_polling = 1; |
@@ -579,17 +508,23 @@ static int uhci_start(struct usb_hcd *hcd) | |||
579 | 508 | ||
580 | init_waitqueue_head(&uhci->waitqh); | 509 | init_waitqueue_head(&uhci->waitqh); |
581 | 510 | ||
582 | uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl), | 511 | uhci->frame = dma_alloc_coherent(uhci_dev(uhci), |
583 | &dma_handle, 0); | 512 | UHCI_NUMFRAMES * sizeof(*uhci->frame), |
584 | if (!uhci->fl) { | 513 | &uhci->frame_dma_handle, 0); |
514 | if (!uhci->frame) { | ||
585 | dev_err(uhci_dev(uhci), "unable to allocate " | 515 | dev_err(uhci_dev(uhci), "unable to allocate " |
586 | "consistent memory for frame list\n"); | 516 | "consistent memory for frame list\n"); |
587 | goto err_alloc_fl; | 517 | goto err_alloc_frame; |
588 | } | 518 | } |
519 | memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame)); | ||
589 | 520 | ||
590 | memset((void *)uhci->fl, 0, sizeof(*uhci->fl)); | 521 | uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu), |
591 | 522 | GFP_KERNEL); | |
592 | uhci->fl->dma_handle = dma_handle; | 523 | if (!uhci->frame_cpu) { |
524 | dev_err(uhci_dev(uhci), "unable to allocate " | ||
525 | "memory for frame pointers\n"); | ||
526 | goto err_alloc_frame_cpu; | ||
527 | } | ||
593 | 528 | ||
594 | uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), | 529 | uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), |
595 | sizeof(struct uhci_td), 16, 0); | 530 | sizeof(struct uhci_td), 16, 0); |
@@ -672,7 +607,7 @@ static int uhci_start(struct usb_hcd *hcd) | |||
672 | irq = 7; | 607 | irq = 7; |
673 | 608 | ||
674 | /* Only place we don't use the frame list routines */ | 609 | /* Only place we don't use the frame list routines */ |
675 | uhci->fl->frame[i] = UHCI_PTR_QH | | 610 | uhci->frame[i] = UHCI_PTR_QH | |
676 | cpu_to_le32(uhci->skelqh[irq]->dma_handle); | 611 | cpu_to_le32(uhci->skelqh[irq]->dma_handle); |
677 | } | 612 | } |
678 | 613 | ||
@@ -690,31 +625,29 @@ static int uhci_start(struct usb_hcd *hcd) | |||
690 | * error exits: | 625 | * error exits: |
691 | */ | 626 | */ |
692 | err_alloc_skelqh: | 627 | err_alloc_skelqh: |
693 | for (i = 0; i < UHCI_NUM_SKELQH; i++) | 628 | for (i = 0; i < UHCI_NUM_SKELQH; i++) { |
694 | if (uhci->skelqh[i]) { | 629 | if (uhci->skelqh[i]) |
695 | uhci_free_qh(uhci, uhci->skelqh[i]); | 630 | uhci_free_qh(uhci, uhci->skelqh[i]); |
696 | uhci->skelqh[i] = NULL; | 631 | } |
697 | } | ||
698 | 632 | ||
699 | uhci_free_td(uhci, uhci->term_td); | 633 | uhci_free_td(uhci, uhci->term_td); |
700 | uhci->term_td = NULL; | ||
701 | 634 | ||
702 | err_alloc_term_td: | 635 | err_alloc_term_td: |
703 | dma_pool_destroy(uhci->qh_pool); | 636 | dma_pool_destroy(uhci->qh_pool); |
704 | uhci->qh_pool = NULL; | ||
705 | 637 | ||
706 | err_create_qh_pool: | 638 | err_create_qh_pool: |
707 | dma_pool_destroy(uhci->td_pool); | 639 | dma_pool_destroy(uhci->td_pool); |
708 | uhci->td_pool = NULL; | ||
709 | 640 | ||
710 | err_create_td_pool: | 641 | err_create_td_pool: |
711 | dma_free_coherent(uhci_dev(uhci), sizeof(*uhci->fl), | 642 | kfree(uhci->frame_cpu); |
712 | uhci->fl, uhci->fl->dma_handle); | ||
713 | uhci->fl = NULL; | ||
714 | 643 | ||
715 | err_alloc_fl: | 644 | err_alloc_frame_cpu: |
645 | dma_free_coherent(uhci_dev(uhci), | ||
646 | UHCI_NUMFRAMES * sizeof(*uhci->frame), | ||
647 | uhci->frame, uhci->frame_dma_handle); | ||
648 | |||
649 | err_alloc_frame: | ||
716 | debugfs_remove(uhci->dentry); | 650 | debugfs_remove(uhci->dentry); |
717 | uhci->dentry = NULL; | ||
718 | 651 | ||
719 | err_create_debug_entry: | 652 | err_create_debug_entry: |
720 | return retval; | 653 | return retval; |
@@ -726,7 +659,7 @@ static void uhci_stop(struct usb_hcd *hcd) | |||
726 | 659 | ||
727 | spin_lock_irq(&uhci->lock); | 660 | spin_lock_irq(&uhci->lock); |
728 | if (!uhci->hc_inaccessible) | 661 | if (!uhci->hc_inaccessible) |
729 | reset_hc(uhci); | 662 | hc_died(uhci); |
730 | uhci_scan_schedule(uhci, NULL); | 663 | uhci_scan_schedule(uhci, NULL); |
731 | spin_unlock_irq(&uhci->lock); | 664 | spin_unlock_irq(&uhci->lock); |
732 | 665 | ||
@@ -774,14 +707,8 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) | |||
774 | if (uhci->hc_inaccessible) /* Dead or already suspended */ | 707 | if (uhci->hc_inaccessible) /* Dead or already suspended */ |
775 | goto done; | 708 | goto done; |
776 | 709 | ||
777 | #ifndef CONFIG_USB_SUSPEND | ||
778 | /* Otherwise this would never happen */ | ||
779 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | ||
780 | #endif | ||
781 | |||
782 | if (uhci->rh_state > UHCI_RH_SUSPENDED) { | 710 | if (uhci->rh_state > UHCI_RH_SUSPENDED) { |
783 | dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); | 711 | dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); |
784 | hcd->state = HC_STATE_RUNNING; | ||
785 | rc = -EBUSY; | 712 | rc = -EBUSY; |
786 | goto done; | 713 | goto done; |
787 | }; | 714 | }; |
@@ -790,6 +717,7 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) | |||
790 | * at the source, so we must turn off PIRQ. | 717 | * at the source, so we must turn off PIRQ. |
791 | */ | 718 | */ |
792 | pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); | 719 | pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); |
720 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
793 | uhci->hc_inaccessible = 1; | 721 | uhci->hc_inaccessible = 1; |
794 | hcd->poll_rh = 0; | 722 | hcd->poll_rh = 0; |
795 | 723 | ||
@@ -806,6 +734,11 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
806 | 734 | ||
807 | dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); | 735 | dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__); |
808 | 736 | ||
737 | /* We aren't in D3 state anymore, we do that even if dead as I | ||
738 | * really don't want to keep a stale HCD_FLAG_HW_ACCESSIBLE=0 | ||
739 | */ | ||
740 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
741 | |||
809 | if (uhci->rh_state == UHCI_RH_RESET) /* Dead */ | 742 | if (uhci->rh_state == UHCI_RH_RESET) /* Dead */ |
810 | return 0; | 743 | return 0; |
811 | spin_lock_irq(&uhci->lock); | 744 | spin_lock_irq(&uhci->lock); |
@@ -820,10 +753,6 @@ static int uhci_resume(struct usb_hcd *hcd) | |||
820 | check_and_reset_hc(uhci); | 753 | check_and_reset_hc(uhci); |
821 | configure_hc(uhci); | 754 | configure_hc(uhci); |
822 | 755 | ||
823 | #ifndef CONFIG_USB_SUSPEND | ||
824 | /* Otherwise this would never happen */ | ||
825 | wakeup_rh(uhci); | ||
826 | #endif | ||
827 | if (uhci->rh_state == UHCI_RH_RESET) | 756 | if (uhci->rh_state == UHCI_RH_RESET) |
828 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | 757 | suspend_rh(uhci, UHCI_RH_SUSPENDED); |
829 | 758 | ||
@@ -881,8 +810,8 @@ static const struct hc_driver uhci_driver = { | |||
881 | #ifdef CONFIG_PM | 810 | #ifdef CONFIG_PM |
882 | .suspend = uhci_suspend, | 811 | .suspend = uhci_suspend, |
883 | .resume = uhci_resume, | 812 | .resume = uhci_resume, |
884 | .hub_suspend = uhci_rh_suspend, | 813 | .bus_suspend = uhci_rh_suspend, |
885 | .hub_resume = uhci_rh_resume, | 814 | .bus_resume = uhci_rh_resume, |
886 | #endif | 815 | #endif |
887 | .stop = uhci_stop, | 816 | .stop = uhci_stop, |
888 | 817 | ||
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 282f40b75881..e576db57a926 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT) | 7 | #define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT) |
8 | #define PIPE_DEVEP_MASK 0x0007ff00 | 8 | #define PIPE_DEVEP_MASK 0x0007ff00 |
9 | 9 | ||
10 | |||
10 | /* | 11 | /* |
11 | * Universal Host Controller Interface data structures and defines | 12 | * Universal Host Controller Interface data structures and defines |
12 | */ | 13 | */ |
@@ -82,15 +83,10 @@ | |||
82 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ | 83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ |
83 | #define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ | 84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far future frames can be scheduled */ |
84 | 85 | ||
85 | struct uhci_frame_list { | ||
86 | __le32 frame[UHCI_NUMFRAMES]; | ||
87 | |||
88 | void *frame_cpu[UHCI_NUMFRAMES]; | ||
89 | |||
90 | dma_addr_t dma_handle; | ||
91 | }; | ||
92 | 86 | ||
93 | struct urb_priv; | 87 | /* |
88 | * Queue Headers | ||
89 | */ | ||
94 | 90 | ||
95 | /* | 91 | /* |
96 | * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is | 92 | * One role of a QH is to hold a queue of TDs for some endpoint. Each QH is |
@@ -116,13 +112,13 @@ struct uhci_qh { | |||
116 | 112 | ||
117 | struct urb_priv *urbp; | 113 | struct urb_priv *urbp; |
118 | 114 | ||
119 | struct list_head list; /* P: uhci->frame_list_lock */ | 115 | struct list_head list; |
120 | struct list_head remove_list; /* P: uhci->remove_list_lock */ | 116 | struct list_head remove_list; |
121 | } __attribute__((aligned(16))); | 117 | } __attribute__((aligned(16))); |
122 | 118 | ||
123 | /* | 119 | /* |
124 | * We need a special accessor for the element pointer because it is | 120 | * We need a special accessor for the element pointer because it is |
125 | * subject to asynchronous updates by the controller | 121 | * subject to asynchronous updates by the controller. |
126 | */ | 122 | */ |
127 | static __le32 inline qh_element(struct uhci_qh *qh) { | 123 | static __le32 inline qh_element(struct uhci_qh *qh) { |
128 | __le32 element = qh->element; | 124 | __le32 element = qh->element; |
@@ -131,6 +127,11 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
131 | return element; | 127 | return element; |
132 | } | 128 | } |
133 | 129 | ||
130 | |||
131 | /* | ||
132 | * Transfer Descriptors | ||
133 | */ | ||
134 | |||
134 | /* | 135 | /* |
135 | * for TD <status>: | 136 | * for TD <status>: |
136 | */ | 137 | */ |
@@ -183,17 +184,10 @@ static __le32 inline qh_element(struct uhci_qh *qh) { | |||
183 | * | 184 | * |
184 | * That's silly, the hardware doesn't care. The hardware only cares that | 185 | * That's silly, the hardware doesn't care. The hardware only cares that |
185 | * the hardware words are 16-byte aligned, and we can have any amount of | 186 | * the hardware words are 16-byte aligned, and we can have any amount of |
186 | * sw space after the TD entry as far as I can tell. | 187 | * sw space after the TD entry. |
187 | * | ||
188 | * But let's just go with the documentation, at least for 32-bit machines. | ||
189 | * On 64-bit machines we probably want to take advantage of the fact that | ||
190 | * hw doesn't really care about the size of the sw-only area. | ||
191 | * | ||
192 | * Alas, not anymore, we have more than 4 words for software, woops. | ||
193 | * Everything still works tho, surprise! -jerdfelt | ||
194 | * | 188 | * |
195 | * td->link points to either another TD (not necessarily for the same urb or | 189 | * td->link points to either another TD (not necessarily for the same urb or |
196 | * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs) | 190 | * even the same endpoint), or nothing (PTR_TERM), or a QH (for queued urbs). |
197 | */ | 191 | */ |
198 | struct uhci_td { | 192 | struct uhci_td { |
199 | /* Hardware fields */ | 193 | /* Hardware fields */ |
@@ -205,18 +199,16 @@ struct uhci_td { | |||
205 | /* Software fields */ | 199 | /* Software fields */ |
206 | dma_addr_t dma_handle; | 200 | dma_addr_t dma_handle; |
207 | 201 | ||
208 | struct urb *urb; | 202 | struct list_head list; |
209 | 203 | struct list_head remove_list; | |
210 | struct list_head list; /* P: urb->lock */ | ||
211 | struct list_head remove_list; /* P: uhci->td_remove_list_lock */ | ||
212 | 204 | ||
213 | int frame; /* for iso: what frame? */ | 205 | int frame; /* for iso: what frame? */ |
214 | struct list_head fl_list; /* P: uhci->frame_list_lock */ | 206 | struct list_head fl_list; |
215 | } __attribute__((aligned(16))); | 207 | } __attribute__((aligned(16))); |
216 | 208 | ||
217 | /* | 209 | /* |
218 | * We need a special accessor for the control/status word because it is | 210 | * We need a special accessor for the control/status word because it is |
219 | * subject to asynchronous updates by the controller | 211 | * subject to asynchronous updates by the controller. |
220 | */ | 212 | */ |
221 | static u32 inline td_status(struct uhci_td *td) { | 213 | static u32 inline td_status(struct uhci_td *td) { |
222 | __le32 status = td->status; | 214 | __le32 status = td->status; |
@@ -227,6 +219,10 @@ static u32 inline td_status(struct uhci_td *td) { | |||
227 | 219 | ||
228 | 220 | ||
229 | /* | 221 | /* |
222 | * Skeleton Queue Headers | ||
223 | */ | ||
224 | |||
225 | /* | ||
230 | * The UHCI driver places Interrupt, Control and Bulk into QH's both | 226 | * The UHCI driver places Interrupt, Control and Bulk into QH's both |
231 | * to group together TD's for one transfer, and also to faciliate queuing | 227 | * to group together TD's for one transfer, and also to faciliate queuing |
232 | * of URB's. To make it easy to insert entries into the schedule, we have | 228 | * of URB's. To make it easy to insert entries into the schedule, we have |
@@ -256,15 +252,15 @@ static u32 inline td_status(struct uhci_td *td) { | |||
256 | * | 252 | * |
257 | * The terminating QH is used for 2 reasons: | 253 | * The terminating QH is used for 2 reasons: |
258 | * - To place a terminating TD which is used to workaround a PIIX bug | 254 | * - To place a terminating TD which is used to workaround a PIIX bug |
259 | * (see Intel errata for explanation) | 255 | * (see Intel errata for explanation), and |
260 | * - To loop back to the full-speed control queue for full-speed bandwidth | 256 | * - To loop back to the full-speed control queue for full-speed bandwidth |
261 | * reclamation | 257 | * reclamation. |
262 | * | 258 | * |
263 | * Isochronous transfers are stored before the start of the skeleton | 259 | * Isochronous transfers are stored before the start of the skeleton |
264 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the | 260 | * schedule and don't use QH's. While the UHCI spec doesn't forbid the |
265 | * use of QH's for Isochronous, it doesn't use them either. Since we don't | 261 | * use of QH's for Isochronous, it doesn't use them either. And the spec |
266 | * need to use them either, we follow the spec diagrams in hope that it'll | 262 | * says that queues never advance on an error completion status, which |
267 | * be more compatible with future UHCI implementations. | 263 | * makes them totally unsuitable for Isochronous transfers. |
268 | */ | 264 | */ |
269 | 265 | ||
270 | #define UHCI_NUM_SKELQH 12 | 266 | #define UHCI_NUM_SKELQH 12 |
@@ -314,8 +310,13 @@ static inline int __interval_to_skel(int interval) | |||
314 | return 0; /* int128 for 128-255 ms (Max.) */ | 310 | return 0; /* int128 for 128-255 ms (Max.) */ |
315 | } | 311 | } |
316 | 312 | ||
313 | |||
314 | /* | ||
315 | * The UHCI controller and root hub | ||
316 | */ | ||
317 | |||
317 | /* | 318 | /* |
318 | * States for the root hub. | 319 | * States for the root hub: |
319 | * | 320 | * |
320 | * To prevent "bouncing" in the presence of electrical noise, | 321 | * To prevent "bouncing" in the presence of electrical noise, |
321 | * when there are no devices attached we delay for 1 second in the | 322 | * when there are no devices attached we delay for 1 second in the |
@@ -326,7 +327,7 @@ static inline int __interval_to_skel(int interval) | |||
326 | */ | 327 | */ |
327 | enum uhci_rh_state { | 328 | enum uhci_rh_state { |
328 | /* In the following states the HC must be halted. | 329 | /* In the following states the HC must be halted. |
329 | * These two must come first */ | 330 | * These two must come first. */ |
330 | UHCI_RH_RESET, | 331 | UHCI_RH_RESET, |
331 | UHCI_RH_SUSPENDED, | 332 | UHCI_RH_SUSPENDED, |
332 | 333 | ||
@@ -338,13 +339,13 @@ enum uhci_rh_state { | |||
338 | UHCI_RH_SUSPENDING, | 339 | UHCI_RH_SUSPENDING, |
339 | 340 | ||
340 | /* In the following states it's an error if the HC is halted. | 341 | /* In the following states it's an error if the HC is halted. |
341 | * These two must come last */ | 342 | * These two must come last. */ |
342 | UHCI_RH_RUNNING, /* The normal state */ | 343 | UHCI_RH_RUNNING, /* The normal state */ |
343 | UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ | 344 | UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ |
344 | }; | 345 | }; |
345 | 346 | ||
346 | /* | 347 | /* |
347 | * This describes the full uhci information. | 348 | * The full UHCI controller information: |
348 | */ | 349 | */ |
349 | struct uhci_hcd { | 350 | struct uhci_hcd { |
350 | 351 | ||
@@ -361,7 +362,11 @@ struct uhci_hcd { | |||
361 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ | 362 | struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ |
362 | 363 | ||
363 | spinlock_t lock; | 364 | spinlock_t lock; |
364 | struct uhci_frame_list *fl; /* P: uhci->lock */ | 365 | |
366 | dma_addr_t frame_dma_handle; /* Hardware frame list */ | ||
367 | __le32 *frame; | ||
368 | void **frame_cpu; /* CPU's frame list */ | ||
369 | |||
365 | int fsbr; /* Full-speed bandwidth reclamation */ | 370 | int fsbr; /* Full-speed bandwidth reclamation */ |
366 | unsigned long fsbrtimeout; /* FSBR delay */ | 371 | unsigned long fsbrtimeout; /* FSBR delay */ |
367 | 372 | ||
@@ -385,22 +390,22 @@ struct uhci_hcd { | |||
385 | unsigned long ports_timeout; /* Time to stop signalling */ | 390 | unsigned long ports_timeout; /* Time to stop signalling */ |
386 | 391 | ||
387 | /* Main list of URB's currently controlled by this HC */ | 392 | /* Main list of URB's currently controlled by this HC */ |
388 | struct list_head urb_list; /* P: uhci->lock */ | 393 | struct list_head urb_list; |
389 | 394 | ||
390 | /* List of QH's that are done, but waiting to be unlinked (race) */ | 395 | /* List of QH's that are done, but waiting to be unlinked (race) */ |
391 | struct list_head qh_remove_list; /* P: uhci->lock */ | 396 | struct list_head qh_remove_list; |
392 | unsigned int qh_remove_age; /* Age in frames */ | 397 | unsigned int qh_remove_age; /* Age in frames */ |
393 | 398 | ||
394 | /* List of TD's that are done, but waiting to be freed (race) */ | 399 | /* List of TD's that are done, but waiting to be freed (race) */ |
395 | struct list_head td_remove_list; /* P: uhci->lock */ | 400 | struct list_head td_remove_list; |
396 | unsigned int td_remove_age; /* Age in frames */ | 401 | unsigned int td_remove_age; /* Age in frames */ |
397 | 402 | ||
398 | /* List of asynchronously unlinked URB's */ | 403 | /* List of asynchronously unlinked URB's */ |
399 | struct list_head urb_remove_list; /* P: uhci->lock */ | 404 | struct list_head urb_remove_list; |
400 | unsigned int urb_remove_age; /* Age in frames */ | 405 | unsigned int urb_remove_age; /* Age in frames */ |
401 | 406 | ||
402 | /* List of URB's awaiting completion callback */ | 407 | /* List of URB's awaiting completion callback */ |
403 | struct list_head complete_list; /* P: uhci->lock */ | 408 | struct list_head complete_list; |
404 | 409 | ||
405 | int rh_numports; /* Number of root-hub ports */ | 410 | int rh_numports; /* Number of root-hub ports */ |
406 | 411 | ||
@@ -419,13 +424,17 @@ static inline struct usb_hcd *uhci_to_hcd(struct uhci_hcd *uhci) | |||
419 | 424 | ||
420 | #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) | 425 | #define uhci_dev(u) (uhci_to_hcd(u)->self.controller) |
421 | 426 | ||
427 | |||
428 | /* | ||
429 | * Private per-URB data | ||
430 | */ | ||
422 | struct urb_priv { | 431 | struct urb_priv { |
423 | struct list_head urb_list; | 432 | struct list_head urb_list; |
424 | 433 | ||
425 | struct urb *urb; | 434 | struct urb *urb; |
426 | 435 | ||
427 | struct uhci_qh *qh; /* QH for this URB */ | 436 | struct uhci_qh *qh; /* QH for this URB */ |
428 | struct list_head td_list; /* P: urb->lock */ | 437 | struct list_head td_list; |
429 | 438 | ||
430 | unsigned fsbr : 1; /* URB turned on FSBR */ | 439 | unsigned fsbr : 1; /* URB turned on FSBR */ |
431 | unsigned fsbr_timeout : 1; /* URB timed out on FSBR */ | 440 | unsigned fsbr_timeout : 1; /* URB timed out on FSBR */ |
@@ -434,12 +443,12 @@ struct urb_priv { | |||
434 | /* a control transfer, retrigger */ | 443 | /* a control transfer, retrigger */ |
435 | /* the status phase */ | 444 | /* the status phase */ |
436 | 445 | ||
437 | unsigned long inserttime; /* In jiffies */ | ||
438 | unsigned long fsbrtime; /* In jiffies */ | 446 | unsigned long fsbrtime; /* In jiffies */ |
439 | 447 | ||
440 | struct list_head queue_list; /* P: uhci->frame_list_lock */ | 448 | struct list_head queue_list; |
441 | }; | 449 | }; |
442 | 450 | ||
451 | |||
443 | /* | 452 | /* |
444 | * Locking in uhci.c | 453 | * Locking in uhci.c |
445 | * | 454 | * |
@@ -459,6 +468,5 @@ struct urb_priv { | |||
459 | 468 | ||
460 | #define PCI_VENDOR_ID_GENESYS 0x17a0 | 469 | #define PCI_VENDOR_ID_GENESYS 0x17a0 |
461 | #define PCI_DEVICE_ID_GL880S_UHCI 0x8083 | 470 | #define PCI_DEVICE_ID_GL880S_UHCI 0x8083 |
462 | #define PCI_DEVICE_ID_GL880S_EHCI 0x8084 | ||
463 | 471 | ||
464 | #endif | 472 | #endif |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index ea0d168a8c67..7e46887d9e12 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -89,10 +89,10 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, | |||
89 | td->frame = framenum; | 89 | td->frame = framenum; |
90 | 90 | ||
91 | /* Is there a TD already mapped there? */ | 91 | /* Is there a TD already mapped there? */ |
92 | if (uhci->fl->frame_cpu[framenum]) { | 92 | if (uhci->frame_cpu[framenum]) { |
93 | struct uhci_td *ftd, *ltd; | 93 | struct uhci_td *ftd, *ltd; |
94 | 94 | ||
95 | ftd = uhci->fl->frame_cpu[framenum]; | 95 | ftd = uhci->frame_cpu[framenum]; |
96 | ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); | 96 | ltd = list_entry(ftd->fl_list.prev, struct uhci_td, fl_list); |
97 | 97 | ||
98 | list_add_tail(&td->fl_list, &ftd->fl_list); | 98 | list_add_tail(&td->fl_list, &ftd->fl_list); |
@@ -101,29 +101,32 @@ static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, | |||
101 | wmb(); | 101 | wmb(); |
102 | ltd->link = cpu_to_le32(td->dma_handle); | 102 | ltd->link = cpu_to_le32(td->dma_handle); |
103 | } else { | 103 | } else { |
104 | td->link = uhci->fl->frame[framenum]; | 104 | td->link = uhci->frame[framenum]; |
105 | wmb(); | 105 | wmb(); |
106 | uhci->fl->frame[framenum] = cpu_to_le32(td->dma_handle); | 106 | uhci->frame[framenum] = cpu_to_le32(td->dma_handle); |
107 | uhci->fl->frame_cpu[framenum] = td; | 107 | uhci->frame_cpu[framenum] = td; |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td) | 111 | static inline void uhci_remove_td_frame_list(struct uhci_hcd *uhci, |
112 | struct uhci_td *td) | ||
112 | { | 113 | { |
113 | /* If it's not inserted, don't remove it */ | 114 | /* If it's not inserted, don't remove it */ |
114 | if (td->frame == -1 && list_empty(&td->fl_list)) | 115 | if (td->frame == -1) { |
116 | WARN_ON(!list_empty(&td->fl_list)); | ||
115 | return; | 117 | return; |
118 | } | ||
116 | 119 | ||
117 | if (td->frame != -1 && uhci->fl->frame_cpu[td->frame] == td) { | 120 | if (uhci->frame_cpu[td->frame] == td) { |
118 | if (list_empty(&td->fl_list)) { | 121 | if (list_empty(&td->fl_list)) { |
119 | uhci->fl->frame[td->frame] = td->link; | 122 | uhci->frame[td->frame] = td->link; |
120 | uhci->fl->frame_cpu[td->frame] = NULL; | 123 | uhci->frame_cpu[td->frame] = NULL; |
121 | } else { | 124 | } else { |
122 | struct uhci_td *ntd; | 125 | struct uhci_td *ntd; |
123 | 126 | ||
124 | ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); | 127 | ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); |
125 | uhci->fl->frame[td->frame] = cpu_to_le32(ntd->dma_handle); | 128 | uhci->frame[td->frame] = cpu_to_le32(ntd->dma_handle); |
126 | uhci->fl->frame_cpu[td->frame] = ntd; | 129 | uhci->frame_cpu[td->frame] = ntd; |
127 | } | 130 | } |
128 | } else { | 131 | } else { |
129 | struct uhci_td *ptd; | 132 | struct uhci_td *ptd; |
@@ -132,13 +135,20 @@ static void uhci_remove_td(struct uhci_hcd *uhci, struct uhci_td *td) | |||
132 | ptd->link = td->link; | 135 | ptd->link = td->link; |
133 | } | 136 | } |
134 | 137 | ||
135 | wmb(); | ||
136 | td->link = UHCI_PTR_TERM; | ||
137 | |||
138 | list_del_init(&td->fl_list); | 138 | list_del_init(&td->fl_list); |
139 | td->frame = -1; | 139 | td->frame = -1; |
140 | } | 140 | } |
141 | 141 | ||
142 | static void unlink_isochronous_tds(struct uhci_hcd *uhci, struct urb *urb) | ||
143 | { | ||
144 | struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; | ||
145 | struct uhci_td *td; | ||
146 | |||
147 | list_for_each_entry(td, &urbp->td_list, list) | ||
148 | uhci_remove_td_frame_list(uhci, td); | ||
149 | wmb(); | ||
150 | } | ||
151 | |||
142 | /* | 152 | /* |
143 | * Inserts a td list into qh. | 153 | * Inserts a td list into qh. |
144 | */ | 154 | */ |
@@ -443,7 +453,6 @@ static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *u | |||
443 | 453 | ||
444 | memset((void *)urbp, 0, sizeof(*urbp)); | 454 | memset((void *)urbp, 0, sizeof(*urbp)); |
445 | 455 | ||
446 | urbp->inserttime = jiffies; | ||
447 | urbp->fsbrtime = jiffies; | 456 | urbp->fsbrtime = jiffies; |
448 | urbp->urb = urb; | 457 | urbp->urb = urb; |
449 | 458 | ||
@@ -462,8 +471,6 @@ static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td) | |||
462 | { | 471 | { |
463 | struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; | 472 | struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; |
464 | 473 | ||
465 | td->urb = urb; | ||
466 | |||
467 | list_add_tail(&td->list, &urbp->td_list); | 474 | list_add_tail(&td->list, &urbp->td_list); |
468 | } | 475 | } |
469 | 476 | ||
@@ -473,8 +480,6 @@ static void uhci_remove_td_from_urb(struct uhci_td *td) | |||
473 | return; | 480 | return; |
474 | 481 | ||
475 | list_del_init(&td->list); | 482 | list_del_init(&td->list); |
476 | |||
477 | td->urb = NULL; | ||
478 | } | 483 | } |
479 | 484 | ||
480 | static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) | 485 | static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) |
@@ -503,7 +508,6 @@ static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb) | |||
503 | 508 | ||
504 | list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { | 509 | list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { |
505 | uhci_remove_td_from_urb(td); | 510 | uhci_remove_td_from_urb(td); |
506 | uhci_remove_td(uhci, td); | ||
507 | list_add(&td->remove_list, &uhci->td_remove_list); | 511 | list_add(&td->remove_list, &uhci->td_remove_list); |
508 | } | 512 | } |
509 | 513 | ||
@@ -1073,6 +1077,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1073 | struct uhci_td *td; | 1077 | struct uhci_td *td; |
1074 | int i, ret, frame; | 1078 | int i, ret, frame; |
1075 | int status, destination; | 1079 | int status, destination; |
1080 | struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; | ||
1076 | 1081 | ||
1077 | status = TD_CTRL_ACTIVE | TD_CTRL_IOS; | 1082 | status = TD_CTRL_ACTIVE | TD_CTRL_IOS; |
1078 | destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); | 1083 | destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); |
@@ -1081,11 +1086,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1081 | if (ret) | 1086 | if (ret) |
1082 | return ret; | 1087 | return ret; |
1083 | 1088 | ||
1084 | frame = urb->start_frame; | 1089 | for (i = 0; i < urb->number_of_packets; i++) { |
1085 | for (i = 0; i < urb->number_of_packets; i++, frame += urb->interval) { | ||
1086 | if (!urb->iso_frame_desc[i].length) | ||
1087 | continue; | ||
1088 | |||
1089 | td = uhci_alloc_td(uhci); | 1090 | td = uhci_alloc_td(uhci); |
1090 | if (!td) | 1091 | if (!td) |
1091 | return -ENOMEM; | 1092 | return -ENOMEM; |
@@ -1096,8 +1097,12 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1096 | 1097 | ||
1097 | if (i + 1 >= urb->number_of_packets) | 1098 | if (i + 1 >= urb->number_of_packets) |
1098 | td->status |= cpu_to_le32(TD_CTRL_IOC); | 1099 | td->status |= cpu_to_le32(TD_CTRL_IOC); |
1100 | } | ||
1099 | 1101 | ||
1102 | frame = urb->start_frame; | ||
1103 | list_for_each_entry(td, &urbp->td_list, list) { | ||
1100 | uhci_insert_td_frame_list(uhci, td, frame); | 1104 | uhci_insert_td_frame_list(uhci, td, frame); |
1105 | frame += urb->interval; | ||
1101 | } | 1106 | } |
1102 | 1107 | ||
1103 | return -EINPROGRESS; | 1108 | return -EINPROGRESS; |
@@ -1110,7 +1115,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1110 | int status; | 1115 | int status; |
1111 | int i, ret = 0; | 1116 | int i, ret = 0; |
1112 | 1117 | ||
1113 | urb->actual_length = 0; | 1118 | urb->actual_length = urb->error_count = 0; |
1114 | 1119 | ||
1115 | i = 0; | 1120 | i = 0; |
1116 | list_for_each_entry(td, &urbp->td_list, list) { | 1121 | list_for_each_entry(td, &urbp->td_list, list) { |
@@ -1134,6 +1139,7 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1134 | 1139 | ||
1135 | i++; | 1140 | i++; |
1136 | } | 1141 | } |
1142 | unlink_isochronous_tds(uhci, urb); | ||
1137 | 1143 | ||
1138 | return ret; | 1144 | return ret; |
1139 | } | 1145 | } |
@@ -1164,7 +1170,7 @@ static struct urb *uhci_find_urb_ep(struct uhci_hcd *uhci, struct urb *urb) | |||
1164 | 1170 | ||
1165 | static int uhci_urb_enqueue(struct usb_hcd *hcd, | 1171 | static int uhci_urb_enqueue(struct usb_hcd *hcd, |
1166 | struct usb_host_endpoint *ep, | 1172 | struct usb_host_endpoint *ep, |
1167 | struct urb *urb, unsigned mem_flags) | 1173 | struct urb *urb, gfp_t mem_flags) |
1168 | { | 1174 | { |
1169 | int ret; | 1175 | int ret; |
1170 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); | 1176 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
@@ -1366,6 +1372,8 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
1366 | goto done; | 1372 | goto done; |
1367 | list_del_init(&urbp->urb_list); | 1373 | list_del_init(&urbp->urb_list); |
1368 | 1374 | ||
1375 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) | ||
1376 | unlink_isochronous_tds(uhci, urb); | ||
1369 | uhci_unlink_generic(uhci, urb); | 1377 | uhci_unlink_generic(uhci, urb); |
1370 | 1378 | ||
1371 | uhci_get_current_frame_number(uhci); | 1379 | uhci_get_current_frame_number(uhci); |