aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-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/ehci-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/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d63177a8eaea..1c54b303e5fc 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -292,21 +292,20 @@ static void ehci_watchdog (unsigned long param)
292 spin_unlock_irqrestore (&ehci->lock, flags); 292 spin_unlock_irqrestore (&ehci->lock, flags);
293} 293}
294 294
295/* Reboot notifiers kick in for silicon on any bus (not just pci, etc). 295/* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
296 * This forcibly disables dma and IRQs, helping kexec and other cases 296 * This forcibly disables dma and IRQs, helping kexec and other cases
297 * where the next system software may expect clean state. 297 * where the next system software may expect clean state.
298 */ 298 */
299static int 299static void
300ehci_reboot (struct notifier_block *self, unsigned long code, void *null) 300ehci_shutdown (struct usb_hcd *hcd)
301{ 301{
302 struct ehci_hcd *ehci; 302 struct ehci_hcd *ehci;
303 303
304 ehci = container_of (self, struct ehci_hcd, reboot_notifier); 304 ehci = hcd_to_ehci (hcd);
305 (void) ehci_halt (ehci); 305 (void) ehci_halt (ehci);
306 306
307 /* make BIOS/etc use companion controller during reboot */ 307 /* make BIOS/etc use companion controller during reboot */
308 writel (0, &ehci->regs->configured_flag); 308 writel (0, &ehci->regs->configured_flag);
309 return 0;
310} 309}
311 310
312static void ehci_port_power (struct ehci_hcd *ehci, int is_on) 311static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
@@ -381,7 +380,6 @@ static void ehci_stop (struct usb_hcd *hcd)
381 380
382 /* let companion controllers work when we aren't */ 381 /* let companion controllers work when we aren't */
383 writel (0, &ehci->regs->configured_flag); 382 writel (0, &ehci->regs->configured_flag);
384 unregister_reboot_notifier (&ehci->reboot_notifier);
385 383
386 remove_debug_files (ehci); 384 remove_debug_files (ehci);
387 385
@@ -483,9 +481,6 @@ static int ehci_init(struct usb_hcd *hcd)
483 } 481 }
484 ehci->command = temp; 482 ehci->command = temp;
485 483
486 ehci->reboot_notifier.notifier_call = ehci_reboot;
487 register_reboot_notifier(&ehci->reboot_notifier);
488
489 return 0; 484 return 0;
490} 485}
491 486
@@ -499,7 +494,6 @@ static int ehci_run (struct usb_hcd *hcd)
499 494
500 /* EHCI spec section 4.1 */ 495 /* EHCI spec section 4.1 */
501 if ((retval = ehci_reset(ehci)) != 0) { 496 if ((retval = ehci_reset(ehci)) != 0) {
502 unregister_reboot_notifier(&ehci->reboot_notifier);
503 ehci_mem_cleanup(ehci); 497 ehci_mem_cleanup(ehci);
504 return retval; 498 return retval;
505 } 499 }