mirror of
https://github.com/adulau/aha.git
synced 2025-01-01 13:46:24 +00:00
[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>
This commit is contained in:
parent
ff7c79e4f3
commit
f4df0e334a
3 changed files with 26 additions and 4 deletions
|
@ -95,12 +95,11 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/interrupt.h> /* for in_interrupt () */
|
|
||||||
#include <linux/usb.h>
|
#include <linux/usb.h>
|
||||||
#include <linux/usb_otg.h>
|
#include <linux/usb_otg.h>
|
||||||
#include "../core/hcd.h"
|
|
||||||
#include <linux/dma-mapping.h>
|
#include <linux/dma-mapping.h>
|
||||||
#include <linux/dmapool.h> /* needed by ohci-mem.c when no PCI */
|
#include <linux/dmapool.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
|
@ -108,8 +107,9 @@
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
|
#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_AUTHOR "Roman Weissgaerber, David Brownell"
|
||||||
#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
|
#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 void ohci_dump (struct ohci_hcd *ohci, int verbose);
|
||||||
static int ohci_init (struct ohci_hcd *ohci);
|
static int ohci_init (struct ohci_hcd *ohci);
|
||||||
static void ohci_stop (struct usb_hcd *hcd);
|
static void ohci_stop (struct usb_hcd *hcd);
|
||||||
|
static int ohci_reboot (struct notifier_block *, unsigned long , void *);
|
||||||
|
|
||||||
#include "ohci-hub.c"
|
#include "ohci-hub.c"
|
||||||
#include "ohci-dbg.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);
|
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
|
* HC functions
|
||||||
*-------------------------------------------------------------------------*/
|
*-------------------------------------------------------------------------*/
|
||||||
|
@ -684,6 +702,7 @@ retry:
|
||||||
if (ohci->power_budget)
|
if (ohci->power_budget)
|
||||||
hub_set_power_budget(udev, ohci->power_budget);
|
hub_set_power_budget(udev, ohci->power_budget);
|
||||||
|
|
||||||
|
register_reboot_notifier (&ohci->reboot_notifier);
|
||||||
create_debug_files (ohci);
|
create_debug_files (ohci);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -781,6 +800,7 @@ static void ohci_stop (struct usb_hcd *hcd)
|
||||||
ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
|
ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
|
||||||
|
|
||||||
remove_debug_files (ohci);
|
remove_debug_files (ohci);
|
||||||
|
unregister_reboot_notifier (&ohci->reboot_notifier);
|
||||||
ohci_mem_cleanup (ohci);
|
ohci_mem_cleanup (ohci);
|
||||||
if (ohci->hcca) {
|
if (ohci->hcca) {
|
||||||
dma_free_coherent (hcd->self.controller,
|
dma_free_coherent (hcd->self.controller,
|
||||||
|
|
|
@ -29,6 +29,7 @@ static void ohci_hcd_init (struct ohci_hcd *ohci)
|
||||||
spin_lock_init (&ohci->lock);
|
spin_lock_init (&ohci->lock);
|
||||||
INIT_LIST_HEAD (&ohci->pending);
|
INIT_LIST_HEAD (&ohci->pending);
|
||||||
INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci));
|
INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci));
|
||||||
|
ohci->reboot_notifier.notifier_call = ohci_reboot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -390,6 +390,7 @@ struct ohci_hcd {
|
||||||
u32 fminterval; /* saved register */
|
u32 fminterval; /* saved register */
|
||||||
|
|
||||||
struct work_struct rh_resume;
|
struct work_struct rh_resume;
|
||||||
|
struct notifier_block reboot_notifier;
|
||||||
|
|
||||||
unsigned long flags; /* for HC bugs */
|
unsigned long flags; /* for HC bugs */
|
||||||
#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */
|
#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */
|
||||||
|
|
Loading…
Reference in a new issue