aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-hcd.c
diff options
context:
space:
mode:
authorAleksey Gorelov <dared1st@yahoo.com>2006-08-08 20:24:08 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-27 14:58:54 -0400
commit64a21d025d3a979a8715f2ec7acabca7b5406c8a (patch)
treee3cbcef560d848e177cddde6d093aa2411cddd53 /drivers/usb/host/ohci-hcd.c
parenta94da8971e836f32315f8832b0bf3e88bee9efae (diff)
USB: Properly unregister reboot notifier in case of failure in ehci hcd
If some problem occurs during ehci startup, for instance, request_irq fails, echi hcd driver tries it best to cleanup, but fails to unregister reboot notifier, which in turn leads to crash on reboot/poweroff. The following patch resolves this problem by not using reboot notifiers anymore, but instead making ehci/ohci driver get its own shutdown method. For PCI, it is done through pci glue, for everything else through platform driver glue. One downside: sa1111 does not use platform driver stuff, and does not have its own shutdown hook, so no 'shutdown' is called for it now. I'm not sure if it is really necessary on that platform, though. Signed-off-by: Aleks Gorelov <dared1st@yahoo.com> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ohci-hcd.c')
-rw-r--r--drivers/usb/host/ohci-hcd.c12
1 files changed, 4 insertions, 8 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 7c3d8c60a60f..2c614af8f733 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -136,7 +136,6 @@ static const char hcd_name [] = "ohci_hcd";
136static void ohci_dump (struct ohci_hcd *ohci, int verbose); 136static void ohci_dump (struct ohci_hcd *ohci, int verbose);
137static int ohci_init (struct ohci_hcd *ohci); 137static int ohci_init (struct ohci_hcd *ohci);
138static void ohci_stop (struct usb_hcd *hcd); 138static void ohci_stop (struct usb_hcd *hcd);
139static int ohci_reboot (struct notifier_block *, unsigned long , void *);
140 139
141#include "ohci-hub.c" 140#include "ohci-hub.c"
142#include "ohci-dbg.c" 141#include "ohci-dbg.c"
@@ -419,21 +418,20 @@ static void ohci_usb_reset (struct ohci_hcd *ohci)
419 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); 418 ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
420} 419}
421 420
422/* reboot notifier forcibly disables IRQs and DMA, helping kexec and 421/* ohci_shutdown forcibly disables IRQs and DMA, helping kexec and
423 * other cases where the next software may expect clean state from the 422 * other cases where the next software may expect clean state from the
424 * "firmware". this is bus-neutral, unlike shutdown() methods. 423 * "firmware". this is bus-neutral, unlike shutdown() methods.
425 */ 424 */
426static int 425static void
427ohci_reboot (struct notifier_block *block, unsigned long code, void *null) 426ohci_shutdown (struct usb_hcd *hcd)
428{ 427{
429 struct ohci_hcd *ohci; 428 struct ohci_hcd *ohci;
430 429
431 ohci = container_of (block, struct ohci_hcd, reboot_notifier); 430 ohci = hcd_to_ohci (hcd);
432 ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); 431 ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
433 ohci_usb_reset (ohci); 432 ohci_usb_reset (ohci);
434 /* flush the writes */ 433 /* flush the writes */
435 (void) ohci_readl (ohci, &ohci->regs->control); 434 (void) ohci_readl (ohci, &ohci->regs->control);
436 return 0;
437} 435}
438 436
439/*-------------------------------------------------------------------------* 437/*-------------------------------------------------------------------------*
@@ -504,7 +502,6 @@ static int ohci_init (struct ohci_hcd *ohci)
504 if ((ret = ohci_mem_init (ohci)) < 0) 502 if ((ret = ohci_mem_init (ohci)) < 0)
505 ohci_stop (hcd); 503 ohci_stop (hcd);
506 else { 504 else {
507 register_reboot_notifier (&ohci->reboot_notifier);
508 create_debug_files (ohci); 505 create_debug_files (ohci);
509 } 506 }
510 507
@@ -800,7 +797,6 @@ static void ohci_stop (struct usb_hcd *hcd)
800 ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); 797 ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
801 798
802 remove_debug_files (ohci); 799 remove_debug_files (ohci);
803 unregister_reboot_notifier (&ohci->reboot_notifier);
804 ohci_mem_cleanup (ohci); 800 ohci_mem_cleanup (ohci);
805 if (ohci->hcca) { 801 if (ohci->hcca) {
806 dma_free_coherent (hcd->self.controller, 802 dma_free_coherent (hcd->self.controller,