diff options
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 28 | ||||
-rw-r--r-- | drivers/usb/host/ohci-mem.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/ohci.h | 1 |
3 files changed, 26 insertions, 4 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 1e27f10c1592..32120042ab65 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"; | |||
141 | static void ohci_dump (struct ohci_hcd *ohci, int verbose); | 141 | static void ohci_dump (struct ohci_hcd *ohci, int verbose); |
142 | static int ohci_init (struct ohci_hcd *ohci); | 142 | static int ohci_init (struct ohci_hcd *ohci); |
143 | static void ohci_stop (struct usb_hcd *hcd); | 143 | static void ohci_stop (struct usb_hcd *hcd); |
144 | static 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 | */ | ||
428 | static int | ||
429 | ohci_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 | *-------------------------------------------------------------------------*/ |
@@ -684,6 +702,7 @@ retry: | |||
684 | if (ohci->power_budget) | 702 | if (ohci->power_budget) |
685 | hub_set_power_budget(udev, ohci->power_budget); | 703 | hub_set_power_budget(udev, ohci->power_budget); |
686 | 704 | ||
705 | register_reboot_notifier (&ohci->reboot_notifier); | ||
687 | create_debug_files (ohci); | 706 | create_debug_files (ohci); |
688 | return 0; | 707 | return 0; |
689 | } | 708 | } |
@@ -781,6 +800,7 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
781 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | 800 | ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); |
782 | 801 | ||
783 | remove_debug_files (ohci); | 802 | remove_debug_files (ohci); |
803 | unregister_reboot_notifier (&ohci->reboot_notifier); | ||
784 | ohci_mem_cleanup (ohci); | 804 | ohci_mem_cleanup (ohci); |
785 | if (ohci->hcca) { | 805 | if (ohci->hcca) { |
786 | dma_free_coherent (hcd->self.controller, | 806 | dma_free_coherent (hcd->self.controller, |
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index e55682b4919d..23735a36af00 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -29,6 +29,7 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) | |||
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)); | 31 | INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci)); |
32 | ohci->reboot_notifier.notifier_call = ohci_reboot; | ||
32 | } | 33 | } |
33 | 34 | ||
34 | /*-------------------------------------------------------------------------*/ | 35 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 22e1ac138ac0..3dbc7c0eed43 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -390,6 +390,7 @@ struct ohci_hcd { | |||
390 | u32 fminterval; /* saved register */ | 390 | u32 fminterval; /* saved register */ |
391 | 391 | ||
392 | struct work_struct rh_resume; | 392 | struct work_struct rh_resume; |
393 | struct notifier_block reboot_notifier; | ||
393 | 394 | ||
394 | unsigned long flags; /* for HC bugs */ | 395 | unsigned long flags; /* for HC bugs */ |
395 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ | 396 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ |