aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
-rw-r--r--drivers/usb/host/ohci-hcd.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 1e27f10c1592..13cd2177b557 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -95,12 +95,11 @@
95#include <linux/init.h> 95#include <linux/init.h>
96#include <linux/timer.h> 96#include <linux/timer.h>
97#include <linux/list.h> 97#include <linux/list.h>
98#include <linux/interrupt.h> /* for in_interrupt () */
99#include <linux/usb.h> 98#include <linux/usb.h>
100#include <linux/usb_otg.h> 99#include <linux/usb_otg.h>
101#include "../core/hcd.h"
102#include <linux/dma-mapping.h> 100#include <linux/dma-mapping.h>
103#include <linux/dmapool.h> /* needed by ohci-mem.c when no PCI */ 101#include <linux/dmapool.h>
102#include <linux/reboot.h>
104 103
105#include <asm/io.h> 104#include <asm/io.h>
106#include <asm/irq.h> 105#include <asm/irq.h>
@@ -108,8 +107,9 @@
108#include <asm/unaligned.h> 107#include <asm/unaligned.h>
109#include <asm/byteorder.h> 108#include <asm/byteorder.h>
110 109
110#include "../core/hcd.h"
111 111
112#define DRIVER_VERSION "2004 Nov 08" 112#define DRIVER_VERSION "2005 April 22"
113#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell" 113#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
114#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" 114#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
115 115
@@ -141,6 +141,7 @@ static const char hcd_name [] = "ohci_hcd";
141static void ohci_dump (struct ohci_hcd *ohci, int verbose); 141static void ohci_dump (struct ohci_hcd *ohci, int verbose);
142static int ohci_init (struct ohci_hcd *ohci); 142static int ohci_init (struct ohci_hcd *ohci);
143static void ohci_stop (struct usb_hcd *hcd); 143static void ohci_stop (struct usb_hcd *hcd);
144static int ohci_reboot (struct notifier_block *, unsigned long , void *);
144 145
145#include "ohci-hub.c" 146#include "ohci-hub.c"
146#include "ohci-dbg.c" 147#include "ohci-dbg.c"
@@ -420,6 +421,23 @@ static void ohci_usb_reset (struct ohci_hcd *ohci)
420 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); 421 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
421} 422}
422 423
424/* reboot notifier forcibly disables IRQs and DMA, helping kexec and
425 * other cases where the next software may expect clean state from the
426 * "firmware". this is bus-neutral, unlike shutdown() methods.
427 */
428static int
429ohci_reboot (struct notifier_block *block, unsigned long code, void *null)
430{
431 struct ohci_hcd *ohci;
432
433 ohci = container_of (block, struct ohci_hcd, reboot_notifier);
434 ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
435 ohci_usb_reset (ohci);
436 /* flush the writes */
437 (void) ohci_readl (ohci, &ohci->regs->control);
438 return 0;
439}
440
423/*-------------------------------------------------------------------------* 441/*-------------------------------------------------------------------------*
424 * HC functions 442 * HC functions
425 *-------------------------------------------------------------------------*/ 443 *-------------------------------------------------------------------------*/
@@ -487,13 +505,10 @@ static int ohci_init (struct ohci_hcd *ohci)
487/* Start an OHCI controller, set the BUS operational 505/* Start an OHCI controller, set the BUS operational
488 * resets USB and controller 506 * resets USB and controller
489 * enable interrupts 507 * enable interrupts
490 * connect the virtual root hub
491 */ 508 */
492static int ohci_run (struct ohci_hcd *ohci) 509static int ohci_run (struct ohci_hcd *ohci)
493{ 510{
494 u32 mask, temp; 511 u32 mask, temp;
495 struct usb_device *udev;
496 struct usb_bus *bus;
497 int first = ohci->fminterval == 0; 512 int first = ohci->fminterval == 0;
498 513
499 disable (ohci); 514 disable (ohci);
@@ -654,37 +669,13 @@ retry:
654 669
655 // POTPGT delay is bits 24-31, in 2 ms units. 670 // POTPGT delay is bits 24-31, in 2 ms units.
656 mdelay ((temp >> 23) & 0x1fe); 671 mdelay ((temp >> 23) & 0x1fe);
657 bus = &ohci_to_hcd(ohci)->self;
658 ohci_to_hcd(ohci)->state = HC_STATE_RUNNING; 672 ohci_to_hcd(ohci)->state = HC_STATE_RUNNING;
659 673
660 ohci_dump (ohci, 1); 674 ohci_dump (ohci, 1);
661 675
662 udev = bus->root_hub; 676 if (ohci_to_hcd(ohci)->self.root_hub == NULL)
663 if (udev) { 677 create_debug_files (ohci);
664 return 0;
665 }
666
667 /* connect the virtual root hub */
668 udev = usb_alloc_dev (NULL, bus, 0);
669 if (!udev) {
670 disable (ohci);
671 ohci->hc_control &= ~OHCI_CTRL_HCFS;
672 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
673 return -ENOMEM;
674 }
675
676 udev->speed = USB_SPEED_FULL;
677 if (usb_hcd_register_root_hub (udev, ohci_to_hcd(ohci)) != 0) {
678 usb_put_dev (udev);
679 disable (ohci);
680 ohci->hc_control &= ~OHCI_CTRL_HCFS;
681 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
682 return -ENODEV;
683 }
684 if (ohci->power_budget)
685 hub_set_power_budget(udev, ohci->power_budget);
686 678
687 create_debug_files (ohci);
688 return 0; 679 return 0;
689} 680}
690 681
@@ -781,6 +772,7 @@ static void ohci_stop (struct usb_hcd *hcd)
781 ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); 772 ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
782 773
783 remove_debug_files (ohci); 774 remove_debug_files (ohci);
775 unregister_reboot_notifier (&ohci->reboot_notifier);
784 ohci_mem_cleanup (ohci); 776 ohci_mem_cleanup (ohci);
785 if (ohci->hcca) { 777 if (ohci->hcca) {
786 dma_free_coherent (hcd->self.controller, 778 dma_free_coherent (hcd->self.controller,