aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2005-04-23 15:49:16 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-27 17:43:46 -0400
commitf4df0e334a9fc731689e8ba4f42a0d72a7491348 (patch)
tree7bce31f214c0fe1feb221726f6f19b78cae3aa1c
parentff7c79e4f37821235b51fb8e19088c08938cc8fc (diff)
[PATCH] USB: add reboot notifier to ohci
Adds a reboot notifier to OHCI, mostly to benefit kexec; plus minor #include tweaks. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/host/ohci-hcd.c28
-rw-r--r--drivers/usb/host/ohci-mem.c1
-rw-r--r--drivers/usb/host/ohci.h1
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";
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 *-------------------------------------------------------------------------*/
@@ -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 */