11da177e4SLinus Torvalds /* 2578333abSAlan Stern * Open Host Controller Interface (OHCI) driver for USB. 3578333abSAlan Stern * 4578333abSAlan Stern * Maintainer: Alan Stern <stern@rowland.harvard.edu> 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> 71da177e4SLinus Torvalds * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> 81da177e4SLinus Torvalds * 91da177e4SLinus Torvalds * [ Initialisation is based on Linus' ] 101da177e4SLinus Torvalds * [ uhci code and gregs ohci fragments ] 111da177e4SLinus Torvalds * [ (C) Copyright 1999 Linus Torvalds ] 121da177e4SLinus Torvalds * [ (C) Copyright 1999 Gregory P. Smith] 131da177e4SLinus Torvalds * 141da177e4SLinus Torvalds * 151da177e4SLinus Torvalds * OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller 161da177e4SLinus Torvalds * interfaces (though some non-x86 Intel chips use it). It supports 171da177e4SLinus Torvalds * smarter hardware than UHCI. A download link for the spec available 181da177e4SLinus Torvalds * through the http://www.usb.org website. 191da177e4SLinus Torvalds * 201da177e4SLinus Torvalds * This file is licenced under the GPL. 211da177e4SLinus Torvalds */ 221da177e4SLinus Torvalds 231da177e4SLinus Torvalds #include <linux/module.h> 241da177e4SLinus Torvalds #include <linux/moduleparam.h> 251da177e4SLinus Torvalds #include <linux/pci.h> 261da177e4SLinus Torvalds #include <linux/kernel.h> 271da177e4SLinus Torvalds #include <linux/delay.h> 281da177e4SLinus Torvalds #include <linux/ioport.h> 291da177e4SLinus Torvalds #include <linux/sched.h> 301da177e4SLinus Torvalds #include <linux/slab.h> 311da177e4SLinus Torvalds #include <linux/errno.h> 321da177e4SLinus Torvalds #include <linux/init.h> 331da177e4SLinus Torvalds #include <linux/timer.h> 341da177e4SLinus Torvalds #include <linux/list.h> 351da177e4SLinus Torvalds #include <linux/usb.h> 363a16f7b4SDavid Brownell #include <linux/usb/otg.h> 3727729aadSEric Lescouet #include <linux/usb/hcd.h> 381da177e4SLinus Torvalds #include <linux/dma-mapping.h> 39f4df0e33SDavid Brownell #include <linux/dmapool.h> 40d576bb9fSMichael Hanselmann #include <linux/workqueue.h> 41684c19e0STony Jones #include <linux/debugfs.h> 421da177e4SLinus Torvalds 431da177e4SLinus Torvalds #include <asm/io.h> 441da177e4SLinus Torvalds #include <asm/irq.h> 451da177e4SLinus Torvalds #include <asm/unaligned.h> 461da177e4SLinus Torvalds #include <asm/byteorder.h> 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell" 501da177e4SLinus Torvalds #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" 511da177e4SLinus Torvalds 521da177e4SLinus Torvalds /*-------------------------------------------------------------------------*/ 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds /* For initializing controller (mask in an HCFS mode too) */ 551da177e4SLinus Torvalds #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR 561da177e4SLinus Torvalds #define OHCI_INTR_INIT \ 57d413984aSDavid Brownell (OHCI_INTR_MIE | OHCI_INTR_RHSC | OHCI_INTR_UE \ 58d413984aSDavid Brownell | OHCI_INTR_RD | OHCI_INTR_WDH) 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds #ifdef __hppa__ 611da177e4SLinus Torvalds /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ 621da177e4SLinus Torvalds #define IR_DISABLE 631da177e4SLinus Torvalds #endif 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds #ifdef CONFIG_ARCH_OMAP 661da177e4SLinus Torvalds /* OMAP doesn't support IR (no SMM; not needed) */ 671da177e4SLinus Torvalds #define IR_DISABLE 681da177e4SLinus Torvalds #endif 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds /*-------------------------------------------------------------------------*/ 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds static const char hcd_name [] = "ohci_hcd"; 731da177e4SLinus Torvalds 74d413984aSDavid Brownell #define STATECHANGE_DELAY msecs_to_jiffies(300) 7581e38333SAlan Stern #define IO_WATCHDOG_DELAY msecs_to_jiffies(250) 76d413984aSDavid Brownell 771da177e4SLinus Torvalds #include "ohci.h" 78ad93562bSAndiry Xu #include "pci-quirks.h" 791da177e4SLinus Torvalds 80256dbcd8SAlan Stern static void ohci_dump(struct ohci_hcd *ohci); 811da177e4SLinus Torvalds static void ohci_stop(struct usb_hcd *hcd); 8281e38333SAlan Stern static void io_watchdog_func(unsigned long _ohci); 83ab1666c1SLibin Yang 841da177e4SLinus Torvalds #include "ohci-hub.c" 851da177e4SLinus Torvalds #include "ohci-dbg.c" 861da177e4SLinus Torvalds #include "ohci-mem.c" 871da177e4SLinus Torvalds #include "ohci-q.c" 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds 901da177e4SLinus Torvalds /* 911da177e4SLinus Torvalds * On architectures with edge-triggered interrupts we must never return 921da177e4SLinus Torvalds * IRQ_NONE. 931da177e4SLinus Torvalds */ 941da177e4SLinus Torvalds #if defined(CONFIG_SA1111) /* ... or other edge-triggered systems */ 951da177e4SLinus Torvalds #define IRQ_NOTMINE IRQ_HANDLED 961da177e4SLinus Torvalds #else 971da177e4SLinus Torvalds #define IRQ_NOTMINE IRQ_NONE 981da177e4SLinus Torvalds #endif 991da177e4SLinus Torvalds 1001da177e4SLinus Torvalds 1011da177e4SLinus Torvalds /* Some boards misreport power switching/overcurrent */ 10290ab5ee9SRusty Russell static bool distrust_firmware = 1; 1031da177e4SLinus Torvalds module_param (distrust_firmware, bool, 0); 1041da177e4SLinus Torvalds MODULE_PARM_DESC (distrust_firmware, 1051da177e4SLinus Torvalds "true to distrust firmware power/overcurrent setup"); 1061da177e4SLinus Torvalds 1071da177e4SLinus Torvalds /* Some boards leave IR set wrongly, since they fail BIOS/SMM handshakes */ 10890ab5ee9SRusty Russell static bool no_handshake = 0; 1091da177e4SLinus Torvalds module_param (no_handshake, bool, 0); 1101da177e4SLinus Torvalds MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake"); 1111da177e4SLinus Torvalds 1121da177e4SLinus Torvalds /*-------------------------------------------------------------------------*/ 1131da177e4SLinus Torvalds 1146f65126cSAlan Stern static int number_of_tds(struct urb *urb) 1156f65126cSAlan Stern { 1166f65126cSAlan Stern int len, i, num, this_sg_len; 1176f65126cSAlan Stern struct scatterlist *sg; 1186f65126cSAlan Stern 1196f65126cSAlan Stern len = urb->transfer_buffer_length; 1206f65126cSAlan Stern i = urb->num_mapped_sgs; 1216f65126cSAlan Stern 1226f65126cSAlan Stern if (len > 0 && i > 0) { /* Scatter-gather transfer */ 1236f65126cSAlan Stern num = 0; 1246f65126cSAlan Stern sg = urb->sg; 1256f65126cSAlan Stern for (;;) { 1266f65126cSAlan Stern this_sg_len = min_t(int, sg_dma_len(sg), len); 1276f65126cSAlan Stern num += DIV_ROUND_UP(this_sg_len, 4096); 1286f65126cSAlan Stern len -= this_sg_len; 1296f65126cSAlan Stern if (--i <= 0 || len <= 0) 1306f65126cSAlan Stern break; 1316f65126cSAlan Stern sg = sg_next(sg); 1326f65126cSAlan Stern } 1336f65126cSAlan Stern 1346f65126cSAlan Stern } else { /* Non-SG transfer */ 1356f65126cSAlan Stern /* one TD for every 4096 Bytes (could be up to 8K) */ 1366f65126cSAlan Stern num = DIV_ROUND_UP(len, 4096); 1376f65126cSAlan Stern } 1386f65126cSAlan Stern return num; 1396f65126cSAlan Stern } 1406f65126cSAlan Stern 1411da177e4SLinus Torvalds /* 1421da177e4SLinus Torvalds * queue up an urb for anything except the root hub 1431da177e4SLinus Torvalds */ 1441da177e4SLinus Torvalds static int ohci_urb_enqueue ( 1451da177e4SLinus Torvalds struct usb_hcd *hcd, 1461da177e4SLinus Torvalds struct urb *urb, 14755016f10SAl Viro gfp_t mem_flags 1481da177e4SLinus Torvalds ) { 1491da177e4SLinus Torvalds struct ohci_hcd *ohci = hcd_to_ohci (hcd); 1501da177e4SLinus Torvalds struct ed *ed; 1511da177e4SLinus Torvalds urb_priv_t *urb_priv; 1521da177e4SLinus Torvalds unsigned int pipe = urb->pipe; 1531da177e4SLinus Torvalds int i, size = 0; 1541da177e4SLinus Torvalds unsigned long flags; 1551da177e4SLinus Torvalds int retval = 0; 1561da177e4SLinus Torvalds 1571da177e4SLinus Torvalds /* every endpoint has a ed, locate and maybe (re)initialize it */ 158e9df41c5SAlan Stern if (! (ed = ed_get (ohci, urb->ep, urb->dev, pipe, urb->interval))) 1591da177e4SLinus Torvalds return -ENOMEM; 1601da177e4SLinus Torvalds 1611da177e4SLinus Torvalds /* for the private part of the URB we need the number of TDs (size) */ 1621da177e4SLinus Torvalds switch (ed->type) { 1631da177e4SLinus Torvalds case PIPE_CONTROL: 1641da177e4SLinus Torvalds /* td_submit_urb() doesn't yet handle these */ 1651da177e4SLinus Torvalds if (urb->transfer_buffer_length > 4096) 1661da177e4SLinus Torvalds return -EMSGSIZE; 1671da177e4SLinus Torvalds 1681da177e4SLinus Torvalds /* 1 TD for setup, 1 for ACK, plus ... */ 1691da177e4SLinus Torvalds size = 2; 1701da177e4SLinus Torvalds /* FALLTHROUGH */ 1711da177e4SLinus Torvalds // case PIPE_INTERRUPT: 1721da177e4SLinus Torvalds // case PIPE_BULK: 1731da177e4SLinus Torvalds default: 1746f65126cSAlan Stern size += number_of_tds(urb); 1756f65126cSAlan Stern /* maybe a zero-length packet to wrap it up */ 1761da177e4SLinus Torvalds if (size == 0) 1771da177e4SLinus Torvalds size++; 1781da177e4SLinus Torvalds else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0 1791da177e4SLinus Torvalds && (urb->transfer_buffer_length 1801da177e4SLinus Torvalds % usb_maxpacket (urb->dev, pipe, 1811da177e4SLinus Torvalds usb_pipeout (pipe))) == 0) 1821da177e4SLinus Torvalds size++; 1831da177e4SLinus Torvalds break; 1841da177e4SLinus Torvalds case PIPE_ISOCHRONOUS: /* number of packets from URB */ 1851da177e4SLinus Torvalds size = urb->number_of_packets; 1861da177e4SLinus Torvalds break; 1871da177e4SLinus Torvalds } 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds /* allocate the private part of the URB */ 190dd00cc48SYoann Padioleau urb_priv = kzalloc (sizeof (urb_priv_t) + size * sizeof (struct td *), 1911da177e4SLinus Torvalds mem_flags); 1921da177e4SLinus Torvalds if (!urb_priv) 1931da177e4SLinus Torvalds return -ENOMEM; 1941da177e4SLinus Torvalds INIT_LIST_HEAD (&urb_priv->pending); 1951da177e4SLinus Torvalds urb_priv->length = size; 1961da177e4SLinus Torvalds urb_priv->ed = ed; 1971da177e4SLinus Torvalds 1981da177e4SLinus Torvalds /* allocate the TDs (deferring hash chain updates) */ 1991da177e4SLinus Torvalds for (i = 0; i < size; i++) { 2001da177e4SLinus Torvalds urb_priv->td [i] = td_alloc (ohci, mem_flags); 2011da177e4SLinus Torvalds if (!urb_priv->td [i]) { 2021da177e4SLinus Torvalds urb_priv->length = i; 2031da177e4SLinus Torvalds urb_free_priv (ohci, urb_priv); 2041da177e4SLinus Torvalds return -ENOMEM; 2051da177e4SLinus Torvalds } 2061da177e4SLinus Torvalds } 2071da177e4SLinus Torvalds 2081da177e4SLinus Torvalds spin_lock_irqsave (&ohci->lock, flags); 2091da177e4SLinus Torvalds 2101da177e4SLinus Torvalds /* don't submit to a dead HC */ 211541c7d43SAlan Stern if (!HCD_HW_ACCESSIBLE(hcd)) { 2128de98402SBenjamin Herrenschmidt retval = -ENODEV; 2138de98402SBenjamin Herrenschmidt goto fail; 2148de98402SBenjamin Herrenschmidt } 215b7463c71SAlan Stern if (ohci->rh_state != OHCI_RH_RUNNING) { 2161da177e4SLinus Torvalds retval = -ENODEV; 2171da177e4SLinus Torvalds goto fail; 2181da177e4SLinus Torvalds } 219e9df41c5SAlan Stern retval = usb_hcd_link_urb_to_ep(hcd, urb); 220e9df41c5SAlan Stern if (retval) 2211da177e4SLinus Torvalds goto fail; 2221da177e4SLinus Torvalds 2231da177e4SLinus Torvalds /* schedule the ed if needed */ 2241da177e4SLinus Torvalds if (ed->state == ED_IDLE) { 2251da177e4SLinus Torvalds retval = ed_schedule (ohci, ed); 226e9df41c5SAlan Stern if (retval < 0) { 227e9df41c5SAlan Stern usb_hcd_unlink_urb_from_ep(hcd, urb); 228e9df41c5SAlan Stern goto fail; 229e9df41c5SAlan Stern } 23081e38333SAlan Stern 23181e38333SAlan Stern /* Start up the I/O watchdog timer, if it's not running */ 23281e38333SAlan Stern if (!timer_pending(&ohci->io_watchdog) && 233*499b3803SAlan Stern list_empty(&ohci->eds_in_use)) { 234*499b3803SAlan Stern ohci->prev_frame_no = ohci_frame_no(ohci); 23581e38333SAlan Stern mod_timer(&ohci->io_watchdog, 23681e38333SAlan Stern jiffies + IO_WATCHDOG_DELAY); 237*499b3803SAlan Stern } 23881e38333SAlan Stern list_add(&ed->in_use_list, &ohci->eds_in_use); 23981e38333SAlan Stern 2401da177e4SLinus Torvalds if (ed->type == PIPE_ISOCHRONOUS) { 2411da177e4SLinus Torvalds u16 frame = ohci_frame_no(ohci); 2421da177e4SLinus Torvalds 2431da177e4SLinus Torvalds /* delay a few frames before the first TD */ 2441da177e4SLinus Torvalds frame += max_t (u16, 8, ed->interval); 2451da177e4SLinus Torvalds frame &= ~(ed->interval - 1); 2461da177e4SLinus Torvalds frame |= ed->branch; 2471da177e4SLinus Torvalds urb->start_frame = frame; 248a8693424SAlan Stern ed->last_iso = frame + ed->interval * (size - 1); 2491da177e4SLinus Torvalds } 2506a41b4d3SAlan Stern } else if (ed->type == PIPE_ISOCHRONOUS) { 251e1944017SAlan Stern u16 next = ohci_frame_no(ohci) + 1; 2526a41b4d3SAlan Stern u16 frame = ed->last_iso + ed->interval; 253a8693424SAlan Stern u16 length = ed->interval * (size - 1); 2546a41b4d3SAlan Stern 2556a41b4d3SAlan Stern /* Behind the scheduling threshold? */ 2566a41b4d3SAlan Stern if (unlikely(tick_before(frame, next))) { 2576a41b4d3SAlan Stern 258a8693424SAlan Stern /* URB_ISO_ASAP: Round up to the first available slot */ 259815fa7b9SAlan Stern if (urb->transfer_flags & URB_ISO_ASAP) { 2606a41b4d3SAlan Stern frame += (next - frame + ed->interval - 1) & 2616a41b4d3SAlan Stern -ed->interval; 2626a41b4d3SAlan Stern 2636a41b4d3SAlan Stern /* 264a8693424SAlan Stern * Not ASAP: Use the next slot in the stream, 265a8693424SAlan Stern * no matter what. 2666a41b4d3SAlan Stern */ 267815fa7b9SAlan Stern } else { 2686a41b4d3SAlan Stern /* 2696a41b4d3SAlan Stern * Some OHCI hardware doesn't handle late TDs 270815fa7b9SAlan Stern * correctly. After retiring them it proceeds 271815fa7b9SAlan Stern * to the next ED instead of the next TD. 272815fa7b9SAlan Stern * Therefore we have to omit the late TDs 273815fa7b9SAlan Stern * entirely. 2746a41b4d3SAlan Stern */ 275815fa7b9SAlan Stern urb_priv->td_cnt = DIV_ROUND_UP( 276815fa7b9SAlan Stern (u16) (next - frame), 2776a41b4d3SAlan Stern ed->interval); 278a8693424SAlan Stern if (urb_priv->td_cnt >= urb_priv->length) { 279a8693424SAlan Stern ++urb_priv->td_cnt; /* Mark it */ 280a8693424SAlan Stern ohci_dbg(ohci, "iso underrun %p (%u+%u < %u)\n", 281a8693424SAlan Stern urb, frame, length, 282a8693424SAlan Stern next); 283a8693424SAlan Stern } 2846a41b4d3SAlan Stern } 285815fa7b9SAlan Stern } 2866a41b4d3SAlan Stern urb->start_frame = frame; 287a8693424SAlan Stern ed->last_iso = frame + length; 2886a41b4d3SAlan Stern } 2891da177e4SLinus Torvalds 2901da177e4SLinus Torvalds /* fill the TDs and link them to the ed; and 2911da177e4SLinus Torvalds * enable that part of the schedule, if needed 2921da177e4SLinus Torvalds * and update count of queued periodic urbs 2931da177e4SLinus Torvalds */ 2941da177e4SLinus Torvalds urb->hcpriv = urb_priv; 2951da177e4SLinus Torvalds td_submit_urb (ohci, urb); 2961da177e4SLinus Torvalds 2971da177e4SLinus Torvalds fail: 2981da177e4SLinus Torvalds if (retval) 2991da177e4SLinus Torvalds urb_free_priv (ohci, urb_priv); 3001da177e4SLinus Torvalds spin_unlock_irqrestore (&ohci->lock, flags); 3011da177e4SLinus Torvalds return retval; 3021da177e4SLinus Torvalds } 3031da177e4SLinus Torvalds 3041da177e4SLinus Torvalds /* 30555d84968SAlan Stern * decouple the URB from the HC queues (TDs, urb_priv). 30655d84968SAlan Stern * reporting is always done 3071da177e4SLinus Torvalds * asynchronously, and we might be dealing with an urb that's 3081da177e4SLinus Torvalds * partially transferred, or an ED with other urbs being unlinked. 3091da177e4SLinus Torvalds */ 310e9df41c5SAlan Stern static int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) 3111da177e4SLinus Torvalds { 3121da177e4SLinus Torvalds struct ohci_hcd *ohci = hcd_to_ohci (hcd); 3131da177e4SLinus Torvalds unsigned long flags; 314e9df41c5SAlan Stern int rc; 3158b3ab0edSAlan Stern urb_priv_t *urb_priv; 3161da177e4SLinus Torvalds 3171da177e4SLinus Torvalds spin_lock_irqsave (&ohci->lock, flags); 318e9df41c5SAlan Stern rc = usb_hcd_check_unlink_urb(hcd, urb, status); 3198b3ab0edSAlan Stern if (rc == 0) { 3201da177e4SLinus Torvalds 3211da177e4SLinus Torvalds /* Unless an IRQ completed the unlink while it was being 3221da177e4SLinus Torvalds * handed to us, flag it for unlink and giveback, and force 3231da177e4SLinus Torvalds * some upcoming INTR_SF to call finish_unlinks() 3241da177e4SLinus Torvalds */ 3251da177e4SLinus Torvalds urb_priv = urb->hcpriv; 3261da177e4SLinus Torvalds if (urb_priv->ed->state == ED_OPER) 3271da177e4SLinus Torvalds start_ed_unlink(ohci, urb_priv->ed); 3288b3ab0edSAlan Stern 3298b3ab0edSAlan Stern if (ohci->rh_state != OHCI_RH_RUNNING) { 3308b3ab0edSAlan Stern /* With HC dead, we can clean up right away */ 331cdb4dd15SAlan Stern ohci_work(ohci); 3321da177e4SLinus Torvalds } 3331da177e4SLinus Torvalds } 3341da177e4SLinus Torvalds spin_unlock_irqrestore (&ohci->lock, flags); 335e9df41c5SAlan Stern return rc; 3361da177e4SLinus Torvalds } 3371da177e4SLinus Torvalds 3381da177e4SLinus Torvalds /*-------------------------------------------------------------------------*/ 3391da177e4SLinus Torvalds 3401da177e4SLinus Torvalds /* frees config/altsetting state for endpoints, 3411da177e4SLinus Torvalds * including ED memory, dummy TD, and bulk/intr data toggle 3421da177e4SLinus Torvalds */ 3431da177e4SLinus Torvalds 3441da177e4SLinus Torvalds static void 3451da177e4SLinus Torvalds ohci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) 3461da177e4SLinus Torvalds { 3471da177e4SLinus Torvalds struct ohci_hcd *ohci = hcd_to_ohci (hcd); 3481da177e4SLinus Torvalds unsigned long flags; 3491da177e4SLinus Torvalds struct ed *ed = ep->hcpriv; 3501da177e4SLinus Torvalds unsigned limit = 1000; 3511da177e4SLinus Torvalds 3521da177e4SLinus Torvalds /* ASSERT: any requests/urbs are being unlinked */ 3531da177e4SLinus Torvalds /* ASSERT: nobody can be submitting urbs for this any more */ 3541da177e4SLinus Torvalds 3551da177e4SLinus Torvalds if (!ed) 3561da177e4SLinus Torvalds return; 3571da177e4SLinus Torvalds 3581da177e4SLinus Torvalds rescan: 3591da177e4SLinus Torvalds spin_lock_irqsave (&ohci->lock, flags); 3601da177e4SLinus Torvalds 361b7463c71SAlan Stern if (ohci->rh_state != OHCI_RH_RUNNING) { 3621da177e4SLinus Torvalds sanitize: 3631da177e4SLinus Torvalds ed->state = ED_IDLE; 364cdb4dd15SAlan Stern ohci_work(ohci); 3651da177e4SLinus Torvalds } 3661da177e4SLinus Torvalds 3671da177e4SLinus Torvalds switch (ed->state) { 3681da177e4SLinus Torvalds case ED_UNLINK: /* wait for hw to finish? */ 3691da177e4SLinus Torvalds /* major IRQ delivery trouble loses INTR_SF too... */ 3701da177e4SLinus Torvalds if (limit-- == 0) { 37189a0fd18SMike Nuss ohci_warn(ohci, "ED unlink timeout\n"); 3721da177e4SLinus Torvalds goto sanitize; 3731da177e4SLinus Torvalds } 3741da177e4SLinus Torvalds spin_unlock_irqrestore (&ohci->lock, flags); 37522c43863SNishanth Aravamudan schedule_timeout_uninterruptible(1); 3761da177e4SLinus Torvalds goto rescan; 3771da177e4SLinus Torvalds case ED_IDLE: /* fully unlinked */ 3781da177e4SLinus Torvalds if (list_empty (&ed->td_list)) { 3791da177e4SLinus Torvalds td_free (ohci, ed->dummy); 3801da177e4SLinus Torvalds ed_free (ohci, ed); 3811da177e4SLinus Torvalds break; 3821da177e4SLinus Torvalds } 3831da177e4SLinus Torvalds /* else FALL THROUGH */ 3841da177e4SLinus Torvalds default: 3851da177e4SLinus Torvalds /* caller was supposed to have unlinked any requests; 3861da177e4SLinus Torvalds * that's not our job. can't recover; must leak ed. 3871da177e4SLinus Torvalds */ 3881da177e4SLinus Torvalds ohci_err (ohci, "leak ed %p (#%02x) state %d%s\n", 3891da177e4SLinus Torvalds ed, ep->desc.bEndpointAddress, ed->state, 3901da177e4SLinus Torvalds list_empty (&ed->td_list) ? "" : " (has tds)"); 3911da177e4SLinus Torvalds td_free (ohci, ed->dummy); 3921da177e4SLinus Torvalds break; 3931da177e4SLinus Torvalds } 3941da177e4SLinus Torvalds ep->hcpriv = NULL; 3951da177e4SLinus Torvalds spin_unlock_irqrestore (&ohci->lock, flags); 3961da177e4SLinus Torvalds } 3971da177e4SLinus Torvalds 3981da177e4SLinus Torvalds static int ohci_get_frame (struct usb_hcd *hcd) 3991da177e4SLinus Torvalds { 4001da177e4SLinus Torvalds struct ohci_hcd *ohci = hcd_to_ohci (hcd); 4011da177e4SLinus Torvalds 4021da177e4SLinus Torvalds return ohci_frame_no(ohci); 4031da177e4SLinus Torvalds } 4041da177e4SLinus Torvalds 4051da177e4SLinus Torvalds static void ohci_usb_reset (struct ohci_hcd *ohci) 4061da177e4SLinus Torvalds { 4071da177e4SLinus Torvalds ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); 4081da177e4SLinus Torvalds ohci->hc_control &= OHCI_CTRL_RWC; 4091da177e4SLinus Torvalds ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); 410b7463c71SAlan Stern ohci->rh_state = OHCI_RH_HALTED; 4111da177e4SLinus Torvalds } 4121da177e4SLinus Torvalds 41364a21d02SAleksey Gorelov /* ohci_shutdown forcibly disables IRQs and DMA, helping kexec and 414f4df0e33SDavid Brownell * other cases where the next software may expect clean state from the 415f4df0e33SDavid Brownell * "firmware". this is bus-neutral, unlike shutdown() methods. 416f4df0e33SDavid Brownell */ 41764a21d02SAleksey Gorelov static void 41864a21d02SAleksey Gorelov ohci_shutdown (struct usb_hcd *hcd) 419f4df0e33SDavid Brownell { 420f4df0e33SDavid Brownell struct ohci_hcd *ohci; 421f4df0e33SDavid Brownell 42264a21d02SAleksey Gorelov ohci = hcd_to_ohci (hcd); 423c6187597SAlan Stern ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable); 4243df7169eSAlan Stern 425c6187597SAlan Stern /* Software reset, after which the controller goes into SUSPEND */ 426c6187597SAlan Stern ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus); 427c6187597SAlan Stern ohci_readl(ohci, &ohci->regs->cmdstatus); /* flush the writes */ 428c6187597SAlan Stern udelay(10); 4293df7169eSAlan Stern 430c6187597SAlan Stern ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval); 43181e38333SAlan Stern ohci->rh_state = OHCI_RH_HALTED; 432f4df0e33SDavid Brownell } 433f4df0e33SDavid Brownell 4341da177e4SLinus Torvalds /*-------------------------------------------------------------------------* 4351da177e4SLinus Torvalds * HC functions 4361da177e4SLinus Torvalds *-------------------------------------------------------------------------*/ 4371da177e4SLinus Torvalds 4381da177e4SLinus Torvalds /* init memory, and kick BIOS/SMM off */ 4391da177e4SLinus Torvalds 4401da177e4SLinus Torvalds static int ohci_init (struct ohci_hcd *ohci) 4411da177e4SLinus Torvalds { 4421da177e4SLinus Torvalds int ret; 4436a9062f3SDavid Brownell struct usb_hcd *hcd = ohci_to_hcd(ohci); 4441da177e4SLinus Torvalds 4456f65126cSAlan Stern /* Accept arbitrarily long scatter-gather lists */ 4466f65126cSAlan Stern hcd->self.sg_tablesize = ~0; 4476f65126cSAlan Stern 4481133cd8aSDmitry Baryshkov if (distrust_firmware) 4491133cd8aSDmitry Baryshkov ohci->flags |= OHCI_QUIRK_HUB_POWER; 4501133cd8aSDmitry Baryshkov 451b7463c71SAlan Stern ohci->rh_state = OHCI_RH_HALTED; 4526a9062f3SDavid Brownell ohci->regs = hcd->regs; 4531da177e4SLinus Torvalds 4546a9062f3SDavid Brownell /* REVISIT this BIOS handshake is now moved into PCI "quirks", and 4556a9062f3SDavid Brownell * was never needed for most non-PCI systems ... remove the code? 4566a9062f3SDavid Brownell */ 4576a9062f3SDavid Brownell 4581da177e4SLinus Torvalds #ifndef IR_DISABLE 4591da177e4SLinus Torvalds /* SMM owns the HC? not for long! */ 4601da177e4SLinus Torvalds if (!no_handshake && ohci_readl (ohci, 4611da177e4SLinus Torvalds &ohci->regs->control) & OHCI_CTRL_IR) { 4621da177e4SLinus Torvalds u32 temp; 4631da177e4SLinus Torvalds 4641da177e4SLinus Torvalds ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n"); 4651da177e4SLinus Torvalds 4661da177e4SLinus Torvalds /* this timeout is arbitrary. we make it long, so systems 4671da177e4SLinus Torvalds * depending on usb keyboards may be usable even if the 4681da177e4SLinus Torvalds * BIOS/SMM code seems pretty broken. 4691da177e4SLinus Torvalds */ 4701da177e4SLinus Torvalds temp = 500; /* arbitrary: five seconds */ 4711da177e4SLinus Torvalds 4721da177e4SLinus Torvalds ohci_writel (ohci, OHCI_INTR_OC, &ohci->regs->intrenable); 4731da177e4SLinus Torvalds ohci_writel (ohci, OHCI_OCR, &ohci->regs->cmdstatus); 4741da177e4SLinus Torvalds while (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_IR) { 4751da177e4SLinus Torvalds msleep (10); 4761da177e4SLinus Torvalds if (--temp == 0) { 4771da177e4SLinus Torvalds ohci_err (ohci, "USB HC takeover failed!" 4781da177e4SLinus Torvalds " (BIOS/SMM bug)\n"); 4791da177e4SLinus Torvalds return -EBUSY; 4801da177e4SLinus Torvalds } 4811da177e4SLinus Torvalds } 4821da177e4SLinus Torvalds ohci_usb_reset (ohci); 4831da177e4SLinus Torvalds } 4841da177e4SLinus Torvalds #endif 4851da177e4SLinus Torvalds 4861da177e4SLinus Torvalds /* Disable HC interrupts */ 4871da177e4SLinus Torvalds ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); 4886a9062f3SDavid Brownell 4896a9062f3SDavid Brownell /* flush the writes, and save key bits like RWC */ 4906a9062f3SDavid Brownell if (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_RWC) 4916a9062f3SDavid Brownell ohci->hc_control |= OHCI_CTRL_RWC; 4921da177e4SLinus Torvalds 493fdd13b36SDavid Brownell /* Read the number of ports unless overridden */ 494fdd13b36SDavid Brownell if (ohci->num_ports == 0) 495fdd13b36SDavid Brownell ohci->num_ports = roothub_a(ohci) & RH_A_NDP; 496fdd13b36SDavid Brownell 4971da177e4SLinus Torvalds if (ohci->hcca) 4981da177e4SLinus Torvalds return 0; 4991da177e4SLinus Torvalds 50081e38333SAlan Stern setup_timer(&ohci->io_watchdog, io_watchdog_func, 50181e38333SAlan Stern (unsigned long) ohci); 50281e38333SAlan Stern set_timer_slack(&ohci->io_watchdog, msecs_to_jiffies(20)); 50381e38333SAlan Stern 5046a9062f3SDavid Brownell ohci->hcca = dma_alloc_coherent (hcd->self.controller, 5054428524dSVladimir Zapolskiy sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL); 5061da177e4SLinus Torvalds if (!ohci->hcca) 5071da177e4SLinus Torvalds return -ENOMEM; 5081da177e4SLinus Torvalds 5091da177e4SLinus Torvalds if ((ret = ohci_mem_init (ohci)) < 0) 5106a9062f3SDavid Brownell ohci_stop (hcd); 5116a9062f3SDavid Brownell else { 5126a9062f3SDavid Brownell create_debug_files (ohci); 5136a9062f3SDavid Brownell } 5141da177e4SLinus Torvalds 5151da177e4SLinus Torvalds return ret; 5161da177e4SLinus Torvalds } 5171da177e4SLinus Torvalds 5181da177e4SLinus Torvalds /*-------------------------------------------------------------------------*/ 5191da177e4SLinus Torvalds 5201da177e4SLinus Torvalds /* Start an OHCI controller, set the BUS operational 5211da177e4SLinus Torvalds * resets USB and controller 5221da177e4SLinus Torvalds * enable interrupts 5231da177e4SLinus Torvalds */ 5241da177e4SLinus Torvalds static int ohci_run (struct ohci_hcd *ohci) 5251da177e4SLinus Torvalds { 52696f90a8bSH Hartley Sweeten u32 mask, val; 5271da177e4SLinus Torvalds int first = ohci->fminterval == 0; 5286a9062f3SDavid Brownell struct usb_hcd *hcd = ohci_to_hcd(ohci); 5291da177e4SLinus Torvalds 530b7463c71SAlan Stern ohci->rh_state = OHCI_RH_HALTED; 5311da177e4SLinus Torvalds 5321da177e4SLinus Torvalds /* boot firmware should have set this up (5.1.1.3.1) */ 5331da177e4SLinus Torvalds if (first) { 5341da177e4SLinus Torvalds 53596f90a8bSH Hartley Sweeten val = ohci_readl (ohci, &ohci->regs->fminterval); 53696f90a8bSH Hartley Sweeten ohci->fminterval = val & 0x3fff; 5371da177e4SLinus Torvalds if (ohci->fminterval != FI) 5381da177e4SLinus Torvalds ohci_dbg (ohci, "fminterval delta %d\n", 5391da177e4SLinus Torvalds ohci->fminterval - FI); 5401da177e4SLinus Torvalds ohci->fminterval |= FSMP (ohci->fminterval) << 16; 5411da177e4SLinus Torvalds /* also: power/overcurrent flags in roothub.a */ 5421da177e4SLinus Torvalds } 5431da177e4SLinus Torvalds 5446fd9086aSAlan Stern /* Reset USB nearly "by the book". RemoteWakeupConnected has 5456fd9086aSAlan Stern * to be checked in case boot firmware (BIOS/SMM/...) has set up 5466fd9086aSAlan Stern * wakeup in a way the bus isn't aware of (e.g., legacy PCI PM). 5476fd9086aSAlan Stern * If the bus glue detected wakeup capability then it should 548bcca06efSAlan Stern * already be enabled; if so we'll just enable it again. 5491da177e4SLinus Torvalds */ 550bcca06efSAlan Stern if ((ohci->hc_control & OHCI_CTRL_RWC) != 0) 551bcca06efSAlan Stern device_set_wakeup_capable(hcd->self.controller, 1); 5521da177e4SLinus Torvalds 5531da177e4SLinus Torvalds switch (ohci->hc_control & OHCI_CTRL_HCFS) { 5541da177e4SLinus Torvalds case OHCI_USB_OPER: 55596f90a8bSH Hartley Sweeten val = 0; 5561da177e4SLinus Torvalds break; 5571da177e4SLinus Torvalds case OHCI_USB_SUSPEND: 5581da177e4SLinus Torvalds case OHCI_USB_RESUME: 5591da177e4SLinus Torvalds ohci->hc_control &= OHCI_CTRL_RWC; 5601da177e4SLinus Torvalds ohci->hc_control |= OHCI_USB_RESUME; 56196f90a8bSH Hartley Sweeten val = 10 /* msec wait */; 5621da177e4SLinus Torvalds break; 5631da177e4SLinus Torvalds // case OHCI_USB_RESET: 5641da177e4SLinus Torvalds default: 5651da177e4SLinus Torvalds ohci->hc_control &= OHCI_CTRL_RWC; 5661da177e4SLinus Torvalds ohci->hc_control |= OHCI_USB_RESET; 56796f90a8bSH Hartley Sweeten val = 50 /* msec wait */; 5681da177e4SLinus Torvalds break; 5691da177e4SLinus Torvalds } 5701da177e4SLinus Torvalds ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); 5711da177e4SLinus Torvalds // flush the writes 5721da177e4SLinus Torvalds (void) ohci_readl (ohci, &ohci->regs->control); 57396f90a8bSH Hartley Sweeten msleep(val); 574383975d7SAlan Stern 5751da177e4SLinus Torvalds memset (ohci->hcca, 0, sizeof (struct ohci_hcca)); 5761da177e4SLinus Torvalds 5771da177e4SLinus Torvalds /* 2msec timelimit here means no irqs/preempt */ 5781da177e4SLinus Torvalds spin_lock_irq (&ohci->lock); 5791da177e4SLinus Torvalds 5801da177e4SLinus Torvalds retry: 5811da177e4SLinus Torvalds /* HC Reset requires max 10 us delay */ 5821da177e4SLinus Torvalds ohci_writel (ohci, OHCI_HCR, &ohci->regs->cmdstatus); 58396f90a8bSH Hartley Sweeten val = 30; /* ... allow extra time */ 5841da177e4SLinus Torvalds while ((ohci_readl (ohci, &ohci->regs->cmdstatus) & OHCI_HCR) != 0) { 58596f90a8bSH Hartley Sweeten if (--val == 0) { 5861da177e4SLinus Torvalds spin_unlock_irq (&ohci->lock); 5871da177e4SLinus Torvalds ohci_err (ohci, "USB HC reset timed out!\n"); 5881da177e4SLinus Torvalds return -1; 5891da177e4SLinus Torvalds } 5901da177e4SLinus Torvalds udelay (1); 5911da177e4SLinus Torvalds } 5921da177e4SLinus Torvalds 5931da177e4SLinus Torvalds /* now we're in the SUSPEND state ... must go OPERATIONAL 5941da177e4SLinus Torvalds * within 2msec else HC enters RESUME 5951da177e4SLinus Torvalds * 5961da177e4SLinus Torvalds * ... but some hardware won't init fmInterval "by the book" 5971da177e4SLinus Torvalds * (SiS, OPTi ...), so reset again instead. SiS doesn't need 5981da177e4SLinus Torvalds * this if we write fmInterval after we're OPERATIONAL. 5991da177e4SLinus Torvalds * Unclear about ALi, ServerWorks, and others ... this could 6001da177e4SLinus Torvalds * easily be a longstanding bug in chip init on Linux. 6011da177e4SLinus Torvalds */ 6021da177e4SLinus Torvalds if (ohci->flags & OHCI_QUIRK_INITRESET) { 6031da177e4SLinus Torvalds ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); 6041da177e4SLinus Torvalds // flush those writes 6051da177e4SLinus Torvalds (void) ohci_readl (ohci, &ohci->regs->control); 6061da177e4SLinus Torvalds } 6071da177e4SLinus Torvalds 6081da177e4SLinus Torvalds /* Tell the controller where the control and bulk lists are 6091da177e4SLinus Torvalds * The lists are empty now. */ 6101da177e4SLinus Torvalds ohci_writel (ohci, 0, &ohci->regs->ed_controlhead); 6111da177e4SLinus Torvalds ohci_writel (ohci, 0, &ohci->regs->ed_bulkhead); 6121da177e4SLinus Torvalds 6131da177e4SLinus Torvalds /* a reset clears this */ 6141da177e4SLinus Torvalds ohci_writel (ohci, (u32) ohci->hcca_dma, &ohci->regs->hcca); 6151da177e4SLinus Torvalds 6161da177e4SLinus Torvalds periodic_reinit (ohci); 6171da177e4SLinus Torvalds 6181da177e4SLinus Torvalds /* some OHCI implementations are finicky about how they init. 6191da177e4SLinus Torvalds * bogus values here mean not even enumeration could work. 6201da177e4SLinus Torvalds */ 6211da177e4SLinus Torvalds if ((ohci_readl (ohci, &ohci->regs->fminterval) & 0x3fff0000) == 0 6221da177e4SLinus Torvalds || !ohci_readl (ohci, &ohci->regs->periodicstart)) { 6231da177e4SLinus Torvalds if (!(ohci->flags & OHCI_QUIRK_INITRESET)) { 6241da177e4SLinus Torvalds ohci->flags |= OHCI_QUIRK_INITRESET; 6251da177e4SLinus Torvalds ohci_dbg (ohci, "enabling initreset quirk\n"); 6261da177e4SLinus Torvalds goto retry; 6271da177e4SLinus Torvalds } 6281da177e4SLinus Torvalds spin_unlock_irq (&ohci->lock); 6291da177e4SLinus Torvalds ohci_err (ohci, "init err (%08x %04x)\n", 6301da177e4SLinus Torvalds ohci_readl (ohci, &ohci->regs->fminterval), 6311da177e4SLinus Torvalds ohci_readl (ohci, &ohci->regs->periodicstart)); 6321da177e4SLinus Torvalds return -EOVERFLOW; 6331da177e4SLinus Torvalds } 6341da177e4SLinus Torvalds 635d413984aSDavid Brownell /* use rhsc irqs after khubd is fully initialized */ 636541c7d43SAlan Stern set_bit(HCD_FLAG_POLL_RH, &hcd->flags); 637d413984aSDavid Brownell hcd->uses_new_polling = 1; 638d413984aSDavid Brownell 6391da177e4SLinus Torvalds /* start controller operations */ 6401da177e4SLinus Torvalds ohci->hc_control &= OHCI_CTRL_RWC; 6411da177e4SLinus Torvalds ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER; 6421da177e4SLinus Torvalds ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); 643b7463c71SAlan Stern ohci->rh_state = OHCI_RH_RUNNING; 6441da177e4SLinus Torvalds 6451da177e4SLinus Torvalds /* wake on ConnectStatusChange, matching external hubs */ 6461da177e4SLinus Torvalds ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status); 6471da177e4SLinus Torvalds 6481da177e4SLinus Torvalds /* Choose the interrupts we care about now, others later on demand */ 6491da177e4SLinus Torvalds mask = OHCI_INTR_INIT; 650d413984aSDavid Brownell ohci_writel (ohci, ~0, &ohci->regs->intrstatus); 6511da177e4SLinus Torvalds ohci_writel (ohci, mask, &ohci->regs->intrenable); 6521da177e4SLinus Torvalds 6531da177e4SLinus Torvalds /* handle root hub init quirks ... */ 65496f90a8bSH Hartley Sweeten val = roothub_a (ohci); 65596f90a8bSH Hartley Sweeten val &= ~(RH_A_PSM | RH_A_OCPM); 6561da177e4SLinus Torvalds if (ohci->flags & OHCI_QUIRK_SUPERIO) { 6571da177e4SLinus Torvalds /* NSC 87560 and maybe others */ 65896f90a8bSH Hartley Sweeten val |= RH_A_NOCP; 65996f90a8bSH Hartley Sweeten val &= ~(RH_A_POTPGT | RH_A_NPS); 66096f90a8bSH Hartley Sweeten ohci_writel (ohci, val, &ohci->regs->roothub.a); 6611133cd8aSDmitry Baryshkov } else if ((ohci->flags & OHCI_QUIRK_AMD756) || 6621133cd8aSDmitry Baryshkov (ohci->flags & OHCI_QUIRK_HUB_POWER)) { 6631da177e4SLinus Torvalds /* hub power always on; required for AMD-756 and some 6641da177e4SLinus Torvalds * Mac platforms. ganged overcurrent reporting, if any. 6651da177e4SLinus Torvalds */ 66696f90a8bSH Hartley Sweeten val |= RH_A_NPS; 66796f90a8bSH Hartley Sweeten ohci_writel (ohci, val, &ohci->regs->roothub.a); 6681da177e4SLinus Torvalds } 6691da177e4SLinus Torvalds ohci_writel (ohci, RH_HS_LPSC, &ohci->regs->roothub.status); 67096f90a8bSH Hartley Sweeten ohci_writel (ohci, (val & RH_A_NPS) ? 0 : RH_B_PPCM, 6711da177e4SLinus Torvalds &ohci->regs->roothub.b); 6721da177e4SLinus Torvalds // flush those writes 6731da177e4SLinus Torvalds (void) ohci_readl (ohci, &ohci->regs->control); 6741da177e4SLinus Torvalds 675d413984aSDavid Brownell ohci->next_statechange = jiffies + STATECHANGE_DELAY; 6761da177e4SLinus Torvalds spin_unlock_irq (&ohci->lock); 6771da177e4SLinus Torvalds 6781da177e4SLinus Torvalds // POTPGT delay is bits 24-31, in 2 ms units. 67996f90a8bSH Hartley Sweeten mdelay ((val >> 23) & 0x1fe); 6801da177e4SLinus Torvalds 681256dbcd8SAlan Stern ohci_dump(ohci); 6821da177e4SLinus Torvalds 6831da177e4SLinus Torvalds return 0; 6841da177e4SLinus Torvalds } 6851da177e4SLinus Torvalds 68695e44d44SManjunath Goudar /* ohci_setup routine for generic controller initialization */ 68795e44d44SManjunath Goudar 68895e44d44SManjunath Goudar int ohci_setup(struct usb_hcd *hcd) 68995e44d44SManjunath Goudar { 69095e44d44SManjunath Goudar struct ohci_hcd *ohci = hcd_to_ohci(hcd); 69195e44d44SManjunath Goudar 69295e44d44SManjunath Goudar ohci_hcd_init(ohci); 69395e44d44SManjunath Goudar 69495e44d44SManjunath Goudar return ohci_init(ohci); 69595e44d44SManjunath Goudar } 69695e44d44SManjunath Goudar EXPORT_SYMBOL_GPL(ohci_setup); 69795e44d44SManjunath Goudar 69895e44d44SManjunath Goudar /* ohci_start routine for generic controller start of all OHCI bus glue */ 69995e44d44SManjunath Goudar static int ohci_start(struct usb_hcd *hcd) 70095e44d44SManjunath Goudar { 70195e44d44SManjunath Goudar struct ohci_hcd *ohci = hcd_to_ohci(hcd); 70295e44d44SManjunath Goudar int ret; 70395e44d44SManjunath Goudar 70495e44d44SManjunath Goudar ret = ohci_run(ohci); 70595e44d44SManjunath Goudar if (ret < 0) { 70695e44d44SManjunath Goudar ohci_err(ohci, "can't start\n"); 70795e44d44SManjunath Goudar ohci_stop(hcd); 70895e44d44SManjunath Goudar } 70995e44d44SManjunath Goudar return ret; 71095e44d44SManjunath Goudar } 71195e44d44SManjunath Goudar 7121da177e4SLinus Torvalds /*-------------------------------------------------------------------------*/ 7131da177e4SLinus Torvalds 71481e38333SAlan Stern /* 71581e38333SAlan Stern * Some OHCI controllers are known to lose track of completed TDs. They 71681e38333SAlan Stern * don't add the TDs to the hardware done queue, which means we never see 71781e38333SAlan Stern * them as being completed. 71881e38333SAlan Stern * 71981e38333SAlan Stern * This watchdog routine checks for such problems. Without some way to 72081e38333SAlan Stern * tell when those TDs have completed, we would never take their EDs off 72181e38333SAlan Stern * the unlink list. As a result, URBs could never be dequeued and 72281e38333SAlan Stern * endpoints could never be released. 72381e38333SAlan Stern */ 72481e38333SAlan Stern static void io_watchdog_func(unsigned long _ohci) 72581e38333SAlan Stern { 72681e38333SAlan Stern struct ohci_hcd *ohci = (struct ohci_hcd *) _ohci; 72781e38333SAlan Stern bool takeback_all_pending = false; 72881e38333SAlan Stern u32 status; 72981e38333SAlan Stern u32 head; 73081e38333SAlan Stern struct ed *ed; 73181e38333SAlan Stern struct td *td, *td_start, *td_next; 732*499b3803SAlan Stern unsigned frame_no; 73381e38333SAlan Stern unsigned long flags; 73481e38333SAlan Stern 73581e38333SAlan Stern spin_lock_irqsave(&ohci->lock, flags); 73681e38333SAlan Stern 73781e38333SAlan Stern /* 73881e38333SAlan Stern * One way to lose track of completed TDs is if the controller 73981e38333SAlan Stern * never writes back the done queue head. If it hasn't been 74081e38333SAlan Stern * written back since the last time this function ran and if it 74181e38333SAlan Stern * was non-empty at that time, something is badly wrong with the 74281e38333SAlan Stern * hardware. 74381e38333SAlan Stern */ 74481e38333SAlan Stern status = ohci_readl(ohci, &ohci->regs->intrstatus); 74581e38333SAlan Stern if (!(status & OHCI_INTR_WDH) && ohci->wdh_cnt == ohci->prev_wdh_cnt) { 74681e38333SAlan Stern if (ohci->prev_donehead) { 74781e38333SAlan Stern ohci_err(ohci, "HcDoneHead not written back; disabled\n"); 748*499b3803SAlan Stern died: 74981e38333SAlan Stern usb_hc_died(ohci_to_hcd(ohci)); 75081e38333SAlan Stern ohci_dump(ohci); 75181e38333SAlan Stern ohci_shutdown(ohci_to_hcd(ohci)); 75281e38333SAlan Stern goto done; 75381e38333SAlan Stern } else { 75481e38333SAlan Stern /* No write back because the done queue was empty */ 75581e38333SAlan Stern takeback_all_pending = true; 75681e38333SAlan Stern } 75781e38333SAlan Stern } 75881e38333SAlan Stern 75981e38333SAlan Stern /* Check every ED which might have pending TDs */ 76081e38333SAlan Stern list_for_each_entry(ed, &ohci->eds_in_use, in_use_list) { 76181e38333SAlan Stern if (ed->pending_td) { 76281e38333SAlan Stern if (takeback_all_pending || 76381e38333SAlan Stern OKAY_TO_TAKEBACK(ohci, ed)) { 76481e38333SAlan Stern unsigned tmp = hc32_to_cpu(ohci, ed->hwINFO); 76581e38333SAlan Stern 76681e38333SAlan Stern ohci_dbg(ohci, "takeback pending TD for dev %d ep 0x%x\n", 76781e38333SAlan Stern 0x007f & tmp, 76881e38333SAlan Stern (0x000f & (tmp >> 7)) + 76981e38333SAlan Stern ((tmp & ED_IN) >> 5)); 77081e38333SAlan Stern add_to_done_list(ohci, ed->pending_td); 77181e38333SAlan Stern } 77281e38333SAlan Stern } 77381e38333SAlan Stern 77481e38333SAlan Stern /* Starting from the latest pending TD, */ 77581e38333SAlan Stern td = ed->pending_td; 77681e38333SAlan Stern 77781e38333SAlan Stern /* or the last TD on the done list, */ 77881e38333SAlan Stern if (!td) { 77981e38333SAlan Stern list_for_each_entry(td_next, &ed->td_list, td_list) { 78081e38333SAlan Stern if (!td_next->next_dl_td) 78181e38333SAlan Stern break; 78281e38333SAlan Stern td = td_next; 78381e38333SAlan Stern } 78481e38333SAlan Stern } 78581e38333SAlan Stern 78681e38333SAlan Stern /* find the last TD processed by the controller. */ 78781e38333SAlan Stern head = hc32_to_cpu(ohci, ACCESS_ONCE(ed->hwHeadP)) & TD_MASK; 78881e38333SAlan Stern td_start = td; 78981e38333SAlan Stern td_next = list_prepare_entry(td, &ed->td_list, td_list); 79081e38333SAlan Stern list_for_each_entry_continue(td_next, &ed->td_list, td_list) { 79181e38333SAlan Stern if (head == (u32) td_next->td_dma) 79281e38333SAlan Stern break; 79381e38333SAlan Stern td = td_next; /* head pointer has passed this TD */ 79481e38333SAlan Stern } 79581e38333SAlan Stern if (td != td_start) { 79681e38333SAlan Stern /* 79781e38333SAlan Stern * In case a WDH cycle is in progress, we will wait 79881e38333SAlan Stern * for the next two cycles to complete before assuming 79981e38333SAlan Stern * this TD will never get on the done queue. 80081e38333SAlan Stern */ 80181e38333SAlan Stern ed->takeback_wdh_cnt = ohci->wdh_cnt + 2; 80281e38333SAlan Stern ed->pending_td = td; 80381e38333SAlan Stern } 80481e38333SAlan Stern } 80581e38333SAlan Stern 80681e38333SAlan Stern ohci_work(ohci); 80781e38333SAlan Stern 80881e38333SAlan Stern if (ohci->rh_state == OHCI_RH_RUNNING) { 809*499b3803SAlan Stern 810*499b3803SAlan Stern /* 811*499b3803SAlan Stern * Sometimes a controller just stops working. We can tell 812*499b3803SAlan Stern * by checking that the frame counter has advanced since 813*499b3803SAlan Stern * the last time we ran. 814*499b3803SAlan Stern * 815*499b3803SAlan Stern * But be careful: Some controllers violate the spec by 816*499b3803SAlan Stern * stopping their frame counter when no ports are active. 817*499b3803SAlan Stern */ 818*499b3803SAlan Stern frame_no = ohci_frame_no(ohci); 819*499b3803SAlan Stern if (frame_no == ohci->prev_frame_no) { 820*499b3803SAlan Stern int active_cnt = 0; 821*499b3803SAlan Stern int i; 822*499b3803SAlan Stern unsigned tmp; 823*499b3803SAlan Stern 824*499b3803SAlan Stern for (i = 0; i < ohci->num_ports; ++i) { 825*499b3803SAlan Stern tmp = roothub_portstatus(ohci, i); 826*499b3803SAlan Stern /* Enabled and not suspended? */ 827*499b3803SAlan Stern if ((tmp & RH_PS_PES) && !(tmp & RH_PS_PSS)) 828*499b3803SAlan Stern ++active_cnt; 829*499b3803SAlan Stern } 830*499b3803SAlan Stern 831*499b3803SAlan Stern if (active_cnt > 0) { 832*499b3803SAlan Stern ohci_err(ohci, "frame counter not updating; disabled\n"); 833*499b3803SAlan Stern goto died; 834*499b3803SAlan Stern } 835*499b3803SAlan Stern } 83681e38333SAlan Stern if (!list_empty(&ohci->eds_in_use)) { 837*499b3803SAlan Stern ohci->prev_frame_no = frame_no; 83881e38333SAlan Stern ohci->prev_wdh_cnt = ohci->wdh_cnt; 83981e38333SAlan Stern ohci->prev_donehead = ohci_readl(ohci, 84081e38333SAlan Stern &ohci->regs->donehead); 84181e38333SAlan Stern mod_timer(&ohci->io_watchdog, 84281e38333SAlan Stern jiffies + IO_WATCHDOG_DELAY); 84381e38333SAlan Stern } 84481e38333SAlan Stern } 84581e38333SAlan Stern 84681e38333SAlan Stern done: 84781e38333SAlan Stern spin_unlock_irqrestore(&ohci->lock, flags); 84881e38333SAlan Stern } 84981e38333SAlan Stern 8501da177e4SLinus Torvalds /* an interrupt happens */ 8511da177e4SLinus Torvalds 8527d12e780SDavid Howells static irqreturn_t ohci_irq (struct usb_hcd *hcd) 8531da177e4SLinus Torvalds { 8541da177e4SLinus Torvalds struct ohci_hcd *ohci = hcd_to_ohci (hcd); 8551da177e4SLinus Torvalds struct ohci_regs __iomem *regs = ohci->regs; 8561da177e4SLinus Torvalds int ints; 8571da177e4SLinus Torvalds 858565227c0SBenjamin Herrenschmidt /* Read interrupt status (and flush pending writes). We ignore the 859565227c0SBenjamin Herrenschmidt * optimization of checking the LSB of hcca->done_head; it doesn't 860565227c0SBenjamin Herrenschmidt * work on all systems (edge triggering for OHCI can be a factor). 86189a0fd18SMike Nuss */ 862565227c0SBenjamin Herrenschmidt ints = ohci_readl(ohci, ®s->intrstatus); 8631da177e4SLinus Torvalds 864565227c0SBenjamin Herrenschmidt /* Check for an all 1's result which is a typical consequence 865565227c0SBenjamin Herrenschmidt * of dead, unclocked, or unplugged (CardBus...) devices 866565227c0SBenjamin Herrenschmidt */ 867565227c0SBenjamin Herrenschmidt if (ints == ~(u32)0) { 868b7463c71SAlan Stern ohci->rh_state = OHCI_RH_HALTED; 8691da177e4SLinus Torvalds ohci_dbg (ohci, "device removed!\n"); 87069fff59dSAlan Stern usb_hc_died(hcd); 8711da177e4SLinus Torvalds return IRQ_HANDLED; 872565227c0SBenjamin Herrenschmidt } 873565227c0SBenjamin Herrenschmidt 874565227c0SBenjamin Herrenschmidt /* We only care about interrupts that are enabled */ 875565227c0SBenjamin Herrenschmidt ints &= ohci_readl(ohci, ®s->intrenable); 8761da177e4SLinus Torvalds 8771da177e4SLinus Torvalds /* interrupt for some other device? */ 878b7463c71SAlan Stern if (ints == 0 || unlikely(ohci->rh_state == OHCI_RH_HALTED)) 8791da177e4SLinus Torvalds return IRQ_NOTMINE; 8801da177e4SLinus Torvalds 8811da177e4SLinus Torvalds if (ints & OHCI_INTR_UE) { 882d576bb9fSMichael Hanselmann // e.g. due to PCI Master/Target Abort 88389a0fd18SMike Nuss if (quirk_nec(ohci)) { 884d576bb9fSMichael Hanselmann /* Workaround for a silicon bug in some NEC chips used 885d576bb9fSMichael Hanselmann * in Apple's PowerBooks. Adapted from Darwin code. 886d576bb9fSMichael Hanselmann */ 887d576bb9fSMichael Hanselmann ohci_err (ohci, "OHCI Unrecoverable Error, scheduling NEC chip restart\n"); 888d576bb9fSMichael Hanselmann 889d576bb9fSMichael Hanselmann ohci_writel (ohci, OHCI_INTR_UE, ®s->intrdisable); 890d576bb9fSMichael Hanselmann 891d576bb9fSMichael Hanselmann schedule_work (&ohci->nec_work); 892d576bb9fSMichael Hanselmann } else { 8931da177e4SLinus Torvalds ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n"); 894b7463c71SAlan Stern ohci->rh_state = OHCI_RH_HALTED; 89569fff59dSAlan Stern usb_hc_died(hcd); 896d576bb9fSMichael Hanselmann } 8971da177e4SLinus Torvalds 898256dbcd8SAlan Stern ohci_dump(ohci); 8991da177e4SLinus Torvalds ohci_usb_reset (ohci); 9001da177e4SLinus Torvalds } 9011da177e4SLinus Torvalds 902583ceadaSAlan Stern if (ints & OHCI_INTR_RHSC) { 903d2c4254fSOliver Neukum ohci_dbg(ohci, "rhsc\n"); 904583ceadaSAlan Stern ohci->next_statechange = jiffies + STATECHANGE_DELAY; 905583ceadaSAlan Stern ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC, 906583ceadaSAlan Stern ®s->intrstatus); 907052ac01aSAlan Stern 908052ac01aSAlan Stern /* NOTE: Vendors didn't always make the same implementation 909052ac01aSAlan Stern * choices for RHSC. Many followed the spec; RHSC triggers 910052ac01aSAlan Stern * on an edge, like setting and maybe clearing a port status 911052ac01aSAlan Stern * change bit. With others it's level-triggered, active 912052ac01aSAlan Stern * until khubd clears all the port status change bits. We'll 913052ac01aSAlan Stern * always disable it here and rely on polling until khubd 914052ac01aSAlan Stern * re-enables it. 915052ac01aSAlan Stern */ 916052ac01aSAlan Stern ohci_writel(ohci, OHCI_INTR_RHSC, ®s->intrdisable); 917583ceadaSAlan Stern usb_hcd_poll_rh_status(hcd); 918583ceadaSAlan Stern } 919583ceadaSAlan Stern 920583ceadaSAlan Stern /* For connect and disconnect events, we expect the controller 921583ceadaSAlan Stern * to turn on RHSC along with RD. But for remote wakeup events 922583ceadaSAlan Stern * this might not happen. 923583ceadaSAlan Stern */ 924583ceadaSAlan Stern else if (ints & OHCI_INTR_RD) { 925d2c4254fSOliver Neukum ohci_dbg(ohci, "resume detect\n"); 926e0fd3cbcSDavid Brownell ohci_writel(ohci, OHCI_INTR_RD, ®s->intrstatus); 927541c7d43SAlan Stern set_bit(HCD_FLAG_POLL_RH, &hcd->flags); 9288d1a243bSAlan Stern if (ohci->autostop) { 9298d1a243bSAlan Stern spin_lock (&ohci->lock); 9308d1a243bSAlan Stern ohci_rh_resume (ohci); 9318d1a243bSAlan Stern spin_unlock (&ohci->lock); 9328d1a243bSAlan Stern } else 933f197b2c5SDavid Brownell usb_hcd_resume_root_hub(hcd); 9341da177e4SLinus Torvalds } 9351da177e4SLinus Torvalds 9361da177e4SLinus Torvalds spin_lock(&ohci->lock); 937c6fcb85eSAlan Stern if (ints & OHCI_INTR_WDH) 938c6fcb85eSAlan Stern update_done_list(ohci); 9391da177e4SLinus Torvalds 9401da177e4SLinus Torvalds /* could track INTR_SO to reduce available PCI/... bandwidth */ 9411da177e4SLinus Torvalds 9421da177e4SLinus Torvalds /* handle any pending URB/ED unlinks, leaving INTR_SF enabled 9431da177e4SLinus Torvalds * when there's still unlinking to be done (next frame). 9441da177e4SLinus Torvalds */ 945cdb4dd15SAlan Stern ohci_work(ohci); 94695d9a01dSAlan Stern if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list 947b7463c71SAlan Stern && ohci->rh_state == OHCI_RH_RUNNING) 9481da177e4SLinus Torvalds ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); 9491da177e4SLinus Torvalds 950b7463c71SAlan Stern if (ohci->rh_state == OHCI_RH_RUNNING) { 9511da177e4SLinus Torvalds ohci_writel (ohci, ints, ®s->intrstatus); 95281e38333SAlan Stern if (ints & OHCI_INTR_WDH) 95381e38333SAlan Stern ++ohci->wdh_cnt; 95481e38333SAlan Stern 9551da177e4SLinus Torvalds ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable); 9561da177e4SLinus Torvalds // flush those writes 9571da177e4SLinus Torvalds (void) ohci_readl (ohci, &ohci->regs->control); 9581da177e4SLinus Torvalds } 959c6fcb85eSAlan Stern spin_unlock(&ohci->lock); 9601da177e4SLinus Torvalds 9611da177e4SLinus Torvalds return IRQ_HANDLED; 9621da177e4SLinus Torvalds } 9631da177e4SLinus Torvalds 9641da177e4SLinus Torvalds /*-------------------------------------------------------------------------*/ 9651da177e4SLinus Torvalds 9661da177e4SLinus Torvalds static void ohci_stop (struct usb_hcd *hcd) 9671da177e4SLinus Torvalds { 9681da177e4SLinus Torvalds struct ohci_hcd *ohci = hcd_to_ohci (hcd); 9691da177e4SLinus Torvalds 970256dbcd8SAlan Stern ohci_dump(ohci); 9711da177e4SLinus Torvalds 972569ff2deSTejun Heo if (quirk_nec(ohci)) 97343829731STejun Heo flush_work(&ohci->nec_work); 97481e38333SAlan Stern del_timer_sync(&ohci->io_watchdog); 9751da177e4SLinus Torvalds 9761da177e4SLinus Torvalds ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); 977435932f2Scaizhiyong ohci_usb_reset(ohci); 97871795c1dSPete Zaitcev free_irq(hcd->irq, hcd); 979cd70469dSFelipe Balbi hcd->irq = 0; 9801da177e4SLinus Torvalds 981ab1666c1SLibin Yang if (quirk_amdiso(ohci)) 982ad93562bSAndiry Xu usb_amd_dev_put(); 98389a0fd18SMike Nuss 9841da177e4SLinus Torvalds remove_debug_files (ohci); 9851da177e4SLinus Torvalds ohci_mem_cleanup (ohci); 9861da177e4SLinus Torvalds if (ohci->hcca) { 9871da177e4SLinus Torvalds dma_free_coherent (hcd->self.controller, 9881da177e4SLinus Torvalds sizeof *ohci->hcca, 9891da177e4SLinus Torvalds ohci->hcca, ohci->hcca_dma); 9901da177e4SLinus Torvalds ohci->hcca = NULL; 9911da177e4SLinus Torvalds ohci->hcca_dma = 0; 9921da177e4SLinus Torvalds } 9931da177e4SLinus Torvalds } 9941da177e4SLinus Torvalds 9951da177e4SLinus Torvalds /*-------------------------------------------------------------------------*/ 9961da177e4SLinus Torvalds 997da6fb570SDavid Brownell #if defined(CONFIG_PM) || defined(CONFIG_PCI) 998da6fb570SDavid Brownell 9991da177e4SLinus Torvalds /* must not be called from interrupt context */ 100095e44d44SManjunath Goudar int ohci_restart(struct ohci_hcd *ohci) 10011da177e4SLinus Torvalds { 10021da177e4SLinus Torvalds int temp; 10031da177e4SLinus Torvalds int i; 10041da177e4SLinus Torvalds struct urb_priv *priv; 10051da177e4SLinus Torvalds 100695e44d44SManjunath Goudar ohci_init(ohci); 10071da177e4SLinus Torvalds spin_lock_irq(&ohci->lock); 1008b7463c71SAlan Stern ohci->rh_state = OHCI_RH_HALTED; 1009d576bb9fSMichael Hanselmann 1010d576bb9fSMichael Hanselmann /* Recycle any "live" eds/tds (and urbs). */ 10111da177e4SLinus Torvalds if (!list_empty (&ohci->pending)) 10121da177e4SLinus Torvalds ohci_dbg(ohci, "abort schedule...\n"); 10131da177e4SLinus Torvalds list_for_each_entry (priv, &ohci->pending, pending) { 10141da177e4SLinus Torvalds struct urb *urb = priv->td[0]->urb; 10151da177e4SLinus Torvalds struct ed *ed = priv->ed; 10161da177e4SLinus Torvalds 10171da177e4SLinus Torvalds switch (ed->state) { 10181da177e4SLinus Torvalds case ED_OPER: 10191da177e4SLinus Torvalds ed->state = ED_UNLINK; 10201da177e4SLinus Torvalds ed->hwINFO |= cpu_to_hc32(ohci, ED_DEQUEUE); 10211da177e4SLinus Torvalds ed_deschedule (ohci, ed); 10221da177e4SLinus Torvalds 10231da177e4SLinus Torvalds ed->ed_next = ohci->ed_rm_list; 10241da177e4SLinus Torvalds ed->ed_prev = NULL; 10251da177e4SLinus Torvalds ohci->ed_rm_list = ed; 10261da177e4SLinus Torvalds /* FALLTHROUGH */ 10271da177e4SLinus Torvalds case ED_UNLINK: 10281da177e4SLinus Torvalds break; 10291da177e4SLinus Torvalds default: 10301da177e4SLinus Torvalds ohci_dbg(ohci, "bogus ed %p state %d\n", 10311da177e4SLinus Torvalds ed, ed->state); 10321da177e4SLinus Torvalds } 10331da177e4SLinus Torvalds 103455d84968SAlan Stern if (!urb->unlinked) 103555d84968SAlan Stern urb->unlinked = -ESHUTDOWN; 10361da177e4SLinus Torvalds } 1037cdb4dd15SAlan Stern ohci_work(ohci); 10381da177e4SLinus Torvalds spin_unlock_irq(&ohci->lock); 10391da177e4SLinus Torvalds 10401da177e4SLinus Torvalds /* paranoia, in case that didn't work: */ 10411da177e4SLinus Torvalds 10421da177e4SLinus Torvalds /* empty the interrupt branches */ 10431da177e4SLinus Torvalds for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0; 10441da177e4SLinus Torvalds for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table [i] = 0; 10451da177e4SLinus Torvalds 10461da177e4SLinus Torvalds /* no EDs to remove */ 10471da177e4SLinus Torvalds ohci->ed_rm_list = NULL; 10481da177e4SLinus Torvalds 10491da177e4SLinus Torvalds /* empty control and bulk lists */ 10501da177e4SLinus Torvalds ohci->ed_controltail = NULL; 10511da177e4SLinus Torvalds ohci->ed_bulktail = NULL; 10521da177e4SLinus Torvalds 10531da177e4SLinus Torvalds if ((temp = ohci_run (ohci)) < 0) { 10541da177e4SLinus Torvalds ohci_err (ohci, "can't restart, %d\n", temp); 10551da177e4SLinus Torvalds return temp; 10561da177e4SLinus Torvalds } 1057383975d7SAlan Stern ohci_dbg(ohci, "restart complete\n"); 10581da177e4SLinus Torvalds return 0; 10591da177e4SLinus Torvalds } 106095e44d44SManjunath Goudar EXPORT_SYMBOL_GPL(ohci_restart); 1061d576bb9fSMichael Hanselmann 1062da6fb570SDavid Brownell #endif 1063da6fb570SDavid Brownell 1064cd1965dbSFlorian Fainelli #ifdef CONFIG_PM 1065cd1965dbSFlorian Fainelli 106695e44d44SManjunath Goudar int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) 1067cd1965dbSFlorian Fainelli { 1068cd1965dbSFlorian Fainelli struct ohci_hcd *ohci = hcd_to_ohci (hcd); 1069cd1965dbSFlorian Fainelli unsigned long flags; 1070e1bffbf6SMajunath Goudar int rc = 0; 1071cd1965dbSFlorian Fainelli 1072d4ae47dcSFlorian Fainelli /* Disable irq emission and mark HW unaccessible. Use 1073cd1965dbSFlorian Fainelli * the spinlock to properly synchronize with possible pending 1074cd1965dbSFlorian Fainelli * RH suspend or resume activity. 1075cd1965dbSFlorian Fainelli */ 1076cd1965dbSFlorian Fainelli spin_lock_irqsave (&ohci->lock, flags); 1077cd1965dbSFlorian Fainelli ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); 1078cd1965dbSFlorian Fainelli (void)ohci_readl(ohci, &ohci->regs->intrdisable); 1079cd1965dbSFlorian Fainelli 1080cd1965dbSFlorian Fainelli clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 1081cd1965dbSFlorian Fainelli spin_unlock_irqrestore (&ohci->lock, flags); 1082cd1965dbSFlorian Fainelli 1083e1bffbf6SMajunath Goudar synchronize_irq(hcd->irq); 1084e1bffbf6SMajunath Goudar 1085e1bffbf6SMajunath Goudar if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) { 1086e1bffbf6SMajunath Goudar ohci_resume(hcd, false); 1087e1bffbf6SMajunath Goudar rc = -EBUSY; 1088e1bffbf6SMajunath Goudar } 1089e1bffbf6SMajunath Goudar return rc; 1090cd1965dbSFlorian Fainelli } 109195e44d44SManjunath Goudar EXPORT_SYMBOL_GPL(ohci_suspend); 1092cd1965dbSFlorian Fainelli 1093cd1965dbSFlorian Fainelli 109495e44d44SManjunath Goudar int ohci_resume(struct usb_hcd *hcd, bool hibernated) 1095cd1965dbSFlorian Fainelli { 1096cfa49b4bSFlorian Fainelli struct ohci_hcd *ohci = hcd_to_ohci(hcd); 1097cfa49b4bSFlorian Fainelli int port; 1098cfa49b4bSFlorian Fainelli bool need_reinit = false; 1099cfa49b4bSFlorian Fainelli 1100cd1965dbSFlorian Fainelli set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 1101cd1965dbSFlorian Fainelli 1102cd1965dbSFlorian Fainelli /* Make sure resume from hibernation re-enumerates everything */ 1103cd1965dbSFlorian Fainelli if (hibernated) 1104cfa49b4bSFlorian Fainelli ohci_usb_reset(ohci); 1105cd1965dbSFlorian Fainelli 1106cfa49b4bSFlorian Fainelli /* See if the controller is already running or has been reset */ 1107cfa49b4bSFlorian Fainelli ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); 1108cfa49b4bSFlorian Fainelli if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { 1109cfa49b4bSFlorian Fainelli need_reinit = true; 1110cfa49b4bSFlorian Fainelli } else { 1111cfa49b4bSFlorian Fainelli switch (ohci->hc_control & OHCI_CTRL_HCFS) { 1112cfa49b4bSFlorian Fainelli case OHCI_USB_OPER: 1113cfa49b4bSFlorian Fainelli case OHCI_USB_RESET: 1114cfa49b4bSFlorian Fainelli need_reinit = true; 1115cfa49b4bSFlorian Fainelli } 1116cfa49b4bSFlorian Fainelli } 1117cfa49b4bSFlorian Fainelli 1118cfa49b4bSFlorian Fainelli /* If needed, reinitialize and suspend the root hub */ 1119cfa49b4bSFlorian Fainelli if (need_reinit) { 1120cfa49b4bSFlorian Fainelli spin_lock_irq(&ohci->lock); 1121cfa49b4bSFlorian Fainelli ohci_rh_resume(ohci); 1122cfa49b4bSFlorian Fainelli ohci_rh_suspend(ohci, 0); 1123cfa49b4bSFlorian Fainelli spin_unlock_irq(&ohci->lock); 1124cfa49b4bSFlorian Fainelli } 1125cfa49b4bSFlorian Fainelli 1126cfa49b4bSFlorian Fainelli /* Normally just turn on port power and enable interrupts */ 1127cfa49b4bSFlorian Fainelli else { 1128cfa49b4bSFlorian Fainelli ohci_dbg(ohci, "powerup ports\n"); 1129cfa49b4bSFlorian Fainelli for (port = 0; port < ohci->num_ports; port++) 1130cfa49b4bSFlorian Fainelli ohci_writel(ohci, RH_PS_PPS, 1131cfa49b4bSFlorian Fainelli &ohci->regs->roothub.portstatus[port]); 1132cfa49b4bSFlorian Fainelli 1133cfa49b4bSFlorian Fainelli ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); 1134cfa49b4bSFlorian Fainelli ohci_readl(ohci, &ohci->regs->intrenable); 1135cfa49b4bSFlorian Fainelli msleep(20); 1136cfa49b4bSFlorian Fainelli } 1137cfa49b4bSFlorian Fainelli 1138cfa49b4bSFlorian Fainelli usb_hcd_resume_root_hub(hcd); 1139cfa49b4bSFlorian Fainelli 1140cd1965dbSFlorian Fainelli return 0; 1141cd1965dbSFlorian Fainelli } 114295e44d44SManjunath Goudar EXPORT_SYMBOL_GPL(ohci_resume); 1143cd1965dbSFlorian Fainelli 1144cd1965dbSFlorian Fainelli #endif 1145cd1965dbSFlorian Fainelli 1146d576bb9fSMichael Hanselmann /*-------------------------------------------------------------------------*/ 1147d576bb9fSMichael Hanselmann 114895e44d44SManjunath Goudar /* 114995e44d44SManjunath Goudar * Generic structure: This gets copied for platform drivers so that 115095e44d44SManjunath Goudar * individual entries can be overridden as needed. 115195e44d44SManjunath Goudar */ 115295e44d44SManjunath Goudar 115395e44d44SManjunath Goudar static const struct hc_driver ohci_hc_driver = { 115495e44d44SManjunath Goudar .description = hcd_name, 115595e44d44SManjunath Goudar .product_desc = "OHCI Host Controller", 115695e44d44SManjunath Goudar .hcd_priv_size = sizeof(struct ohci_hcd), 115795e44d44SManjunath Goudar 115895e44d44SManjunath Goudar /* 115995e44d44SManjunath Goudar * generic hardware linkage 116095e44d44SManjunath Goudar */ 116195e44d44SManjunath Goudar .irq = ohci_irq, 116295e44d44SManjunath Goudar .flags = HCD_MEMORY | HCD_USB11, 116395e44d44SManjunath Goudar 116495e44d44SManjunath Goudar /* 116595e44d44SManjunath Goudar * basic lifecycle operations 116695e44d44SManjunath Goudar */ 116795e44d44SManjunath Goudar .reset = ohci_setup, 116895e44d44SManjunath Goudar .start = ohci_start, 116995e44d44SManjunath Goudar .stop = ohci_stop, 117095e44d44SManjunath Goudar .shutdown = ohci_shutdown, 117195e44d44SManjunath Goudar 117295e44d44SManjunath Goudar /* 117395e44d44SManjunath Goudar * managing i/o requests and associated device resources 117495e44d44SManjunath Goudar */ 117595e44d44SManjunath Goudar .urb_enqueue = ohci_urb_enqueue, 117695e44d44SManjunath Goudar .urb_dequeue = ohci_urb_dequeue, 117795e44d44SManjunath Goudar .endpoint_disable = ohci_endpoint_disable, 117895e44d44SManjunath Goudar 117995e44d44SManjunath Goudar /* 118095e44d44SManjunath Goudar * scheduling support 118195e44d44SManjunath Goudar */ 118295e44d44SManjunath Goudar .get_frame_number = ohci_get_frame, 118395e44d44SManjunath Goudar 118495e44d44SManjunath Goudar /* 118595e44d44SManjunath Goudar * root hub support 118695e44d44SManjunath Goudar */ 118795e44d44SManjunath Goudar .hub_status_data = ohci_hub_status_data, 118895e44d44SManjunath Goudar .hub_control = ohci_hub_control, 118995e44d44SManjunath Goudar #ifdef CONFIG_PM 119095e44d44SManjunath Goudar .bus_suspend = ohci_bus_suspend, 119195e44d44SManjunath Goudar .bus_resume = ohci_bus_resume, 119295e44d44SManjunath Goudar #endif 119395e44d44SManjunath Goudar .start_port_reset = ohci_start_port_reset, 119495e44d44SManjunath Goudar }; 119595e44d44SManjunath Goudar 119695e44d44SManjunath Goudar void ohci_init_driver(struct hc_driver *drv, 119795e44d44SManjunath Goudar const struct ohci_driver_overrides *over) 119895e44d44SManjunath Goudar { 119995e44d44SManjunath Goudar /* Copy the generic table to drv and then apply the overrides */ 120095e44d44SManjunath Goudar *drv = ohci_hc_driver; 120195e44d44SManjunath Goudar 1202c80ad6d1SKevin Hilman if (over) { 120395e44d44SManjunath Goudar drv->product_desc = over->product_desc; 120495e44d44SManjunath Goudar drv->hcd_priv_size += over->extra_priv_size; 120595e44d44SManjunath Goudar if (over->reset) 120695e44d44SManjunath Goudar drv->reset = over->reset; 120795e44d44SManjunath Goudar } 1208c80ad6d1SKevin Hilman } 120995e44d44SManjunath Goudar EXPORT_SYMBOL_GPL(ohci_init_driver); 121095e44d44SManjunath Goudar 121195e44d44SManjunath Goudar /*-------------------------------------------------------------------------*/ 121295e44d44SManjunath Goudar 12131da177e4SLinus Torvalds MODULE_AUTHOR (DRIVER_AUTHOR); 12142b70f073SAlan Stern MODULE_DESCRIPTION(DRIVER_DESC); 12151da177e4SLinus Torvalds MODULE_LICENSE ("GPL"); 12161da177e4SLinus Torvalds 12176381fad7SEric Miao #if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_SA1111) 12181da177e4SLinus Torvalds #include "ohci-sa1111.c" 12195e16fabeSSylvain Munaut #define SA1111_DRIVER ohci_hcd_sa1111_driver 12201da177e4SLinus Torvalds #endif 12211da177e4SLinus Torvalds 1222068413e9SArnd Bergmann #ifdef CONFIG_USB_OHCI_HCD_DAVINCI 1223efe7daf2SSergei Shtylyov #include "ohci-da8xx.c" 12248097804eSArnd Bergmann #define DAVINCI_PLATFORM_DRIVER ohci_hcd_da8xx_driver 1225efe7daf2SSergei Shtylyov #endif 1226efe7daf2SSergei Shtylyov 1227495a678fSSylvain Munaut #ifdef CONFIG_USB_OHCI_HCD_PPC_OF 1228495a678fSSylvain Munaut #include "ohci-ppc-of.c" 1229495a678fSSylvain Munaut #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver 1230495a678fSSylvain Munaut #endif 1231495a678fSSylvain Munaut 12326a6c957eSGeoff Levand #ifdef CONFIG_PPC_PS3 12336a6c957eSGeoff Levand #include "ohci-ps3.c" 12347a4eb7fdSGeoff Levand #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver 12356a6c957eSGeoff Levand #endif 12366a6c957eSGeoff Levand 1237f54aab6eSMagnus Damm #ifdef CONFIG_MFD_SM501 1238f54aab6eSMagnus Damm #include "ohci-sm501.c" 12393ee38d8bSBen Dooks #define SM501_OHCI_DRIVER ohci_hcd_sm501_driver 1240f54aab6eSMagnus Damm #endif 1241f54aab6eSMagnus Damm 124278c73414SDmitry Baryshkov #ifdef CONFIG_MFD_TC6393XB 124378c73414SDmitry Baryshkov #include "ohci-tmio.c" 124478c73414SDmitry Baryshkov #define TMIO_OHCI_DRIVER ohci_hcd_tmio_driver 124578c73414SDmitry Baryshkov #endif 124678c73414SDmitry Baryshkov 12472249071bSLars-Peter Clausen #ifdef CONFIG_MACH_JZ4740 12482249071bSLars-Peter Clausen #include "ohci-jz4740.c" 12492249071bSLars-Peter Clausen #define PLATFORM_DRIVER ohci_hcd_jz4740_driver 12502249071bSLars-Peter Clausen #endif 12512249071bSLars-Peter Clausen 12521643accdSDavid Daney #ifdef CONFIG_USB_OCTEON_OHCI 12531643accdSDavid Daney #include "ohci-octeon.c" 12541643accdSDavid Daney #define PLATFORM_DRIVER ohci_octeon_driver 12551643accdSDavid Daney #endif 12561643accdSDavid Daney 125747fc28bfSChris Metcalf #ifdef CONFIG_TILE_USB 125847fc28bfSChris Metcalf #include "ohci-tilegx.c" 125947fc28bfSChris Metcalf #define PLATFORM_DRIVER ohci_hcd_tilegx_driver 126047fc28bfSChris Metcalf #endif 126147fc28bfSChris Metcalf 12625e16fabeSSylvain Munaut static int __init ohci_hcd_mod_init(void) 12635e16fabeSSylvain Munaut { 12645e16fabeSSylvain Munaut int retval = 0; 12655e16fabeSSylvain Munaut 12665e16fabeSSylvain Munaut if (usb_disabled()) 12675e16fabeSSylvain Munaut return -ENODEV; 12685e16fabeSSylvain Munaut 12692b70f073SAlan Stern printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name); 12705e16fabeSSylvain Munaut pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, 12715e16fabeSSylvain Munaut sizeof (struct ed), sizeof (struct td)); 12729beeee65SAlan Stern set_bit(USB_OHCI_LOADED, &usb_hcds_loaded); 12735e16fabeSSylvain Munaut 1274485f4f39SGreg Kroah-Hartman ohci_debug_root = debugfs_create_dir("ohci", usb_debug_root); 1275684c19e0STony Jones if (!ohci_debug_root) { 1276684c19e0STony Jones retval = -ENOENT; 1277684c19e0STony Jones goto error_debug; 1278684c19e0STony Jones } 1279684c19e0STony Jones 12806a6c957eSGeoff Levand #ifdef PS3_SYSTEM_BUS_DRIVER 12817a4eb7fdSGeoff Levand retval = ps3_ohci_driver_register(&PS3_SYSTEM_BUS_DRIVER); 12826a6c957eSGeoff Levand if (retval < 0) 12836a6c957eSGeoff Levand goto error_ps3; 12846a6c957eSGeoff Levand #endif 12856a6c957eSGeoff Levand 12865e16fabeSSylvain Munaut #ifdef PLATFORM_DRIVER 12875e16fabeSSylvain Munaut retval = platform_driver_register(&PLATFORM_DRIVER); 12885e16fabeSSylvain Munaut if (retval < 0) 1289de44743bSBenjamin Herrenschmidt goto error_platform; 12905e16fabeSSylvain Munaut #endif 12915e16fabeSSylvain Munaut 1292495a678fSSylvain Munaut #ifdef OF_PLATFORM_DRIVER 1293d35fb641SGrant Likely retval = platform_driver_register(&OF_PLATFORM_DRIVER); 1294495a678fSSylvain Munaut if (retval < 0) 1295de44743bSBenjamin Herrenschmidt goto error_of_platform; 1296495a678fSSylvain Munaut #endif 1297495a678fSSylvain Munaut 12985e16fabeSSylvain Munaut #ifdef SA1111_DRIVER 12995e16fabeSSylvain Munaut retval = sa1111_driver_register(&SA1111_DRIVER); 13005e16fabeSSylvain Munaut if (retval < 0) 1301de44743bSBenjamin Herrenschmidt goto error_sa1111; 13025e16fabeSSylvain Munaut #endif 13035e16fabeSSylvain Munaut 13043ee38d8bSBen Dooks #ifdef SM501_OHCI_DRIVER 13053ee38d8bSBen Dooks retval = platform_driver_register(&SM501_OHCI_DRIVER); 13063ee38d8bSBen Dooks if (retval < 0) 13073ee38d8bSBen Dooks goto error_sm501; 13083ee38d8bSBen Dooks #endif 13093ee38d8bSBen Dooks 131078c73414SDmitry Baryshkov #ifdef TMIO_OHCI_DRIVER 131178c73414SDmitry Baryshkov retval = platform_driver_register(&TMIO_OHCI_DRIVER); 131278c73414SDmitry Baryshkov if (retval < 0) 131378c73414SDmitry Baryshkov goto error_tmio; 131478c73414SDmitry Baryshkov #endif 131578c73414SDmitry Baryshkov 13168097804eSArnd Bergmann #ifdef DAVINCI_PLATFORM_DRIVER 13178097804eSArnd Bergmann retval = platform_driver_register(&DAVINCI_PLATFORM_DRIVER); 13188097804eSArnd Bergmann if (retval < 0) 13198097804eSArnd Bergmann goto error_davinci; 13208097804eSArnd Bergmann #endif 13218097804eSArnd Bergmann 13225e16fabeSSylvain Munaut return retval; 13235e16fabeSSylvain Munaut 13245e16fabeSSylvain Munaut /* Error path */ 13258097804eSArnd Bergmann #ifdef DAVINCI_PLATFORM_DRIVER 13268097804eSArnd Bergmann platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER); 13278097804eSArnd Bergmann error_davinci: 13288097804eSArnd Bergmann #endif 132978c73414SDmitry Baryshkov #ifdef TMIO_OHCI_DRIVER 133078c73414SDmitry Baryshkov platform_driver_unregister(&TMIO_OHCI_DRIVER); 133178c73414SDmitry Baryshkov error_tmio: 133278c73414SDmitry Baryshkov #endif 13333ee38d8bSBen Dooks #ifdef SM501_OHCI_DRIVER 133478c73414SDmitry Baryshkov platform_driver_unregister(&SM501_OHCI_DRIVER); 13353ee38d8bSBen Dooks error_sm501: 13363ee38d8bSBen Dooks #endif 13375e16fabeSSylvain Munaut #ifdef SA1111_DRIVER 13385e16fabeSSylvain Munaut sa1111_driver_unregister(&SA1111_DRIVER); 1339de44743bSBenjamin Herrenschmidt error_sa1111: 1340de44743bSBenjamin Herrenschmidt #endif 1341de44743bSBenjamin Herrenschmidt #ifdef OF_PLATFORM_DRIVER 1342d35fb641SGrant Likely platform_driver_unregister(&OF_PLATFORM_DRIVER); 1343de44743bSBenjamin Herrenschmidt error_of_platform: 1344de44743bSBenjamin Herrenschmidt #endif 13458097804eSArnd Bergmann #ifdef PLATFORM_DRIVER 13468097804eSArnd Bergmann platform_driver_unregister(&PLATFORM_DRIVER); 13478097804eSArnd Bergmann error_platform: 1348968b448bSAnand Gadiyar #endif 13496a6c957eSGeoff Levand #ifdef PS3_SYSTEM_BUS_DRIVER 13507a4eb7fdSGeoff Levand ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); 13516a6c957eSGeoff Levand error_ps3: 13526a6c957eSGeoff Levand #endif 1353684c19e0STony Jones debugfs_remove(ohci_debug_root); 1354684c19e0STony Jones ohci_debug_root = NULL; 1355684c19e0STony Jones error_debug: 1356684c19e0STony Jones 13579beeee65SAlan Stern clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded); 13585e16fabeSSylvain Munaut return retval; 13595e16fabeSSylvain Munaut } 13605e16fabeSSylvain Munaut module_init(ohci_hcd_mod_init); 13615e16fabeSSylvain Munaut 13625e16fabeSSylvain Munaut static void __exit ohci_hcd_mod_exit(void) 13635e16fabeSSylvain Munaut { 13648097804eSArnd Bergmann #ifdef DAVINCI_PLATFORM_DRIVER 13658097804eSArnd Bergmann platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER); 13668097804eSArnd Bergmann #endif 136778c73414SDmitry Baryshkov #ifdef TMIO_OHCI_DRIVER 136878c73414SDmitry Baryshkov platform_driver_unregister(&TMIO_OHCI_DRIVER); 136978c73414SDmitry Baryshkov #endif 13703ee38d8bSBen Dooks #ifdef SM501_OHCI_DRIVER 13713ee38d8bSBen Dooks platform_driver_unregister(&SM501_OHCI_DRIVER); 13723ee38d8bSBen Dooks #endif 13735e16fabeSSylvain Munaut #ifdef SA1111_DRIVER 13745e16fabeSSylvain Munaut sa1111_driver_unregister(&SA1111_DRIVER); 13755e16fabeSSylvain Munaut #endif 1376495a678fSSylvain Munaut #ifdef OF_PLATFORM_DRIVER 1377d35fb641SGrant Likely platform_driver_unregister(&OF_PLATFORM_DRIVER); 1378495a678fSSylvain Munaut #endif 13798097804eSArnd Bergmann #ifdef PLATFORM_DRIVER 13808097804eSArnd Bergmann platform_driver_unregister(&PLATFORM_DRIVER); 13818097804eSArnd Bergmann #endif 13826a6c957eSGeoff Levand #ifdef PS3_SYSTEM_BUS_DRIVER 13837a4eb7fdSGeoff Levand ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); 13846a6c957eSGeoff Levand #endif 1385684c19e0STony Jones debugfs_remove(ohci_debug_root); 13869beeee65SAlan Stern clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded); 13875e16fabeSSylvain Munaut } 13885e16fabeSSylvain Munaut module_exit(ohci_hcd_mod_exit); 13895e16fabeSSylvain Munaut 1390