From e1001f0d9a0eb978513595da20f96f1475208c07 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sat, 23 Apr 2005 12:49:16 -0700 Subject: [PATCH] --- yaml --- r: 3667 b: refs/heads/master c: f4df0e334a9fc731689e8ba4f42a0d72a7491348 h: refs/heads/master i: 3665: d526a4ed4a2f53a4d145ca5d468b7677d927b0ce 3663: 808012837292a2dda0f61fb9781e4902317491e1 v: v3 --- [refs] | 2 +- trunk/drivers/usb/host/ohci-hcd.c | 28 ++++++++++++++++++++++++---- trunk/drivers/usb/host/ohci-mem.c | 1 + trunk/drivers/usb/host/ohci.h | 1 + 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 736db544e2bf..00e978c14fe7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ff7c79e4f37821235b51fb8e19088c08938cc8fc +refs/heads/master: f4df0e334a9fc731689e8ba4f42a0d72a7491348 diff --git a/trunk/drivers/usb/host/ohci-hcd.c b/trunk/drivers/usb/host/ohci-hcd.c index 1e27f10c1592..32120042ab65 100644 --- a/trunk/drivers/usb/host/ohci-hcd.c +++ b/trunk/drivers/usb/host/ohci-hcd.c @@ -95,12 +95,11 @@ #include #include #include -#include /* for in_interrupt () */ #include #include -#include "../core/hcd.h" #include -#include /* needed by ohci-mem.c when no PCI */ +#include +#include #include #include @@ -108,8 +107,9 @@ #include #include +#include "../core/hcd.h" -#define DRIVER_VERSION "2004 Nov 08" +#define DRIVER_VERSION "2005 April 22" #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell" #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver" @@ -141,6 +141,7 @@ static const char hcd_name [] = "ohci_hcd"; static void ohci_dump (struct ohci_hcd *ohci, int verbose); static int ohci_init (struct ohci_hcd *ohci); static void ohci_stop (struct usb_hcd *hcd); +static int ohci_reboot (struct notifier_block *, unsigned long , void *); #include "ohci-hub.c" #include "ohci-dbg.c" @@ -420,6 +421,23 @@ static void ohci_usb_reset (struct ohci_hcd *ohci) ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); } +/* reboot notifier forcibly disables IRQs and DMA, helping kexec and + * other cases where the next software may expect clean state from the + * "firmware". this is bus-neutral, unlike shutdown() methods. + */ +static int +ohci_reboot (struct notifier_block *block, unsigned long code, void *null) +{ + struct ohci_hcd *ohci; + + ohci = container_of (block, struct ohci_hcd, reboot_notifier); + ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); + ohci_usb_reset (ohci); + /* flush the writes */ + (void) ohci_readl (ohci, &ohci->regs->control); + return 0; +} + /*-------------------------------------------------------------------------* * HC functions *-------------------------------------------------------------------------*/ @@ -684,6 +702,7 @@ static int ohci_run (struct ohci_hcd *ohci) if (ohci->power_budget) hub_set_power_budget(udev, ohci->power_budget); + register_reboot_notifier (&ohci->reboot_notifier); create_debug_files (ohci); return 0; } @@ -781,6 +800,7 @@ static void ohci_stop (struct usb_hcd *hcd) ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); remove_debug_files (ohci); + unregister_reboot_notifier (&ohci->reboot_notifier); ohci_mem_cleanup (ohci); if (ohci->hcca) { dma_free_coherent (hcd->self.controller, diff --git a/trunk/drivers/usb/host/ohci-mem.c b/trunk/drivers/usb/host/ohci-mem.c index e55682b4919d..23735a36af00 100644 --- a/trunk/drivers/usb/host/ohci-mem.c +++ b/trunk/drivers/usb/host/ohci-mem.c @@ -29,6 +29,7 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) spin_lock_init (&ohci->lock); INIT_LIST_HEAD (&ohci->pending); INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci)); + ohci->reboot_notifier.notifier_call = ohci_reboot; } /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/host/ohci.h b/trunk/drivers/usb/host/ohci.h index 22e1ac138ac0..3dbc7c0eed43 100644 --- a/trunk/drivers/usb/host/ohci.h +++ b/trunk/drivers/usb/host/ohci.h @@ -390,6 +390,7 @@ struct ohci_hcd { u32 fminterval; /* saved register */ struct work_struct rh_resume; + struct notifier_block reboot_notifier; unsigned long flags; /* for HC bugs */ #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */