#endif /* CONFIG_PM */
 
+/**
+ * usb_hcd_pci_shutdown - shutdown host controller
+ * @dev: USB Host Controller being shutdown
+ */
+void usb_hcd_pci_shutdown (struct pci_dev *dev)
+{
+       struct usb_hcd          *hcd;
+
+       hcd = pci_get_drvdata(dev);
+       if (!hcd)
+               return;
+
+       if (hcd->driver->shutdown)
+               hcd->driver->shutdown(hcd);
+}
+EXPORT_SYMBOL (usb_hcd_pci_shutdown);
 
 
 #include <linux/mutex.h>
 #include <asm/irq.h>
 #include <asm/byteorder.h>
+#include <linux/platform_device.h>
 
 #include <linux/usb.h>
 
 }
 EXPORT_SYMBOL (usb_remove_hcd);
 
+void
+usb_hcd_platform_shutdown(struct platform_device* dev)
+{
+       struct usb_hcd *hcd = platform_get_drvdata(dev);
+
+       if (hcd->driver->shutdown)
+               hcd->driver->shutdown(hcd);
+}
+EXPORT_SYMBOL (usb_hcd_platform_shutdown);
+
 /*-------------------------------------------------------------------------*/
 
 #if defined(CONFIG_USB_MON)
 
        /* cleanly make HCD stop writing memory and doing I/O */
        void    (*stop) (struct usb_hcd *hcd);
 
+       /* shutdown HCD */
+       void    (*shutdown) (struct usb_hcd *hcd);
+
        /* return current frame number */
        int     (*get_frame_number) (struct usb_hcd *hcd);
 
                unsigned int irqnum, unsigned long irqflags);
 extern void usb_remove_hcd(struct usb_hcd *hcd);
 
+struct platform_device;
+extern void usb_hcd_platform_shutdown(struct platform_device* dev);
+
 #ifdef CONFIG_PCI
 struct pci_dev;
 struct pci_device_id;
 extern int usb_hcd_pci_resume (struct pci_dev *dev);
 #endif /* CONFIG_PM */
 
+extern void usb_hcd_pci_shutdown (struct pci_dev *dev);
+
 #endif /* CONFIG_PCI */
 
 /* pci-ish (pdev null is ok) buffer alloc/mapping support */
 
        .reset = ehci_init,
        .start = ehci_run,
        .stop = ehci_stop,
+       .shutdown = ehci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
 static struct platform_driver ehci_hcd_au1xxx_driver = {
        .probe = ehci_hcd_au1xxx_drv_probe,
        .remove = ehci_hcd_au1xxx_drv_remove,
+       .shutdown = usb_hcd_platform_shutdown,
        /*.suspend      = ehci_hcd_au1xxx_drv_suspend, */
        /*.resume       = ehci_hcd_au1xxx_drv_resume, */
        .driver = {
 
        .resume = ehci_bus_resume,
 #endif
        .stop = ehci_stop,
+       .shutdown = ehci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
 static struct platform_driver ehci_fsl_driver = {
        .probe = ehci_fsl_drv_probe,
        .remove = ehci_fsl_drv_remove,
+       .shutdown = usb_hcd_platform_shutdown,
        .driver = {
                   .name = "fsl-ehci",
                   },
 
        spin_unlock_irqrestore (&ehci->lock, flags);
 }
 
-/* Reboot notifiers kick in for silicon on any bus (not just pci, etc).
+/* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
  * This forcibly disables dma and IRQs, helping kexec and other cases
  * where the next system software may expect clean state.
  */
-static int
-ehci_reboot (struct notifier_block *self, unsigned long code, void *null)
+static void
+ehci_shutdown (struct usb_hcd *hcd)
 {
-       struct ehci_hcd         *ehci;
+       struct ehci_hcd *ehci;
 
-       ehci = container_of (self, struct ehci_hcd, reboot_notifier);
+       ehci = hcd_to_ehci (hcd);
        (void) ehci_halt (ehci);
 
        /* make BIOS/etc use companion controller during reboot */
        writel (0, &ehci->regs->configured_flag);
-       return 0;
 }
 
 static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
 
        /* let companion controllers work when we aren't */
        writel (0, &ehci->regs->configured_flag);
-       unregister_reboot_notifier (&ehci->reboot_notifier);
 
        remove_debug_files (ehci);
 
        }
        ehci->command = temp;
 
-       ehci->reboot_notifier.notifier_call = ehci_reboot;
-       register_reboot_notifier(&ehci->reboot_notifier);
-
        return 0;
 }
 
 
        /* EHCI spec section 4.1 */
        if ((retval = ehci_reset(ehci)) != 0) {
-               unregister_reboot_notifier(&ehci->reboot_notifier);
                ehci_mem_cleanup(ehci);
                return retval;
        }
 
        .resume =               ehci_pci_resume,
 #endif
        .stop =                 ehci_stop,
+       .shutdown =             ehci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
        .suspend =      usb_hcd_pci_suspend,
        .resume =       usb_hcd_pci_resume,
 #endif
+       .shutdown =     usb_hcd_pci_shutdown,
 };
 
        struct dma_pool         *sitd_pool;     /* sitd per split iso urb */
 
        struct timer_list       watchdog;
-       struct notifier_block   reboot_notifier;
        unsigned long           actions;
        unsigned                stamp;
        unsigned long           next_statechange;
 
         */
        .start =                ohci_at91_start,
        .stop =                 ohci_stop,
+       .shutdown =             ohci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
 static struct platform_driver ohci_hcd_at91_driver = {
        .probe          = ohci_hcd_at91_drv_probe,
        .remove         = ohci_hcd_at91_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
        .suspend        = ohci_hcd_at91_drv_suspend,
        .resume         = ohci_hcd_at91_drv_resume,
        .driver         = {
 
         */
        .start =                ohci_au1xxx_start,
        .stop =                 ohci_stop,
+       .shutdown =             ohci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
 static struct platform_driver ohci_hcd_au1xxx_driver = {
        .probe          = ohci_hcd_au1xxx_drv_probe,
        .remove         = ohci_hcd_au1xxx_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
        /*.suspend      = ohci_hcd_au1xxx_drv_suspend, */
        /*.resume       = ohci_hcd_au1xxx_drv_resume, */
        .driver         = {
 
        .flags                  = HCD_USB11 | HCD_MEMORY,
        .start                  = ohci_ep93xx_start,
        .stop                   = ohci_stop,
+       .shutdown               = ohci_shutdown,
        .urb_enqueue            = ohci_urb_enqueue,
        .urb_dequeue            = ohci_urb_dequeue,
        .endpoint_disable       = ohci_endpoint_disable,
 static struct platform_driver ohci_hcd_ep93xx_driver = {
        .probe          = ohci_hcd_ep93xx_drv_probe,
        .remove         = ohci_hcd_ep93xx_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
 #ifdef CONFIG_PM
        .suspend        = ohci_hcd_ep93xx_drv_suspend,
        .resume         = ohci_hcd_ep93xx_drv_resume,
 
 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"
        ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
 }
 
-/* reboot notifier forcibly disables IRQs and DMA, helping kexec and
+/* ohci_shutdown 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)
+static void
+ohci_shutdown (struct usb_hcd *hcd)
 {
        struct ohci_hcd *ohci;
 
-       ohci = container_of (block, struct ohci_hcd, reboot_notifier);
+       ohci = hcd_to_ohci (hcd);
        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;
 }
 
 /*-------------------------------------------------------------------------*
        if ((ret = ohci_mem_init (ohci)) < 0)
                ohci_stop (hcd);
        else {
-               register_reboot_notifier (&ohci->reboot_notifier);
                create_debug_files (ohci);
        }
 
        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, 
 
         */
        .start =                ohci_lh7a404_start,
        .stop =                 ohci_stop,
+       .shutdown =             ohci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
 static struct platform_driver ohci_hcd_lh7a404_driver = {
        .probe          = ohci_hcd_lh7a404_drv_probe,
        .remove         = ohci_hcd_lh7a404_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
        /*.suspend      = ohci_hcd_lh7a404_drv_suspend, */
        /*.resume       = ohci_hcd_lh7a404_drv_resume, */
        .driver         = {
 
        ohci->next_statechange = jiffies;
        spin_lock_init (&ohci->lock);
        INIT_LIST_HEAD (&ohci->pending);
-       ohci->reboot_notifier.notifier_call = ohci_reboot;
 }
 
 /*-------------------------------------------------------------------------*/
 
        .reset =                ohci_omap_init,
        .start =                ohci_omap_start,
        .stop =                 ohci_omap_stop,
+       .shutdown =             ohci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
 static struct platform_driver ohci_hcd_omap_driver = {
        .probe          = ohci_hcd_omap_drv_probe,
        .remove         = ohci_hcd_omap_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
 #ifdef CONFIG_PM
        .suspend        = ohci_omap_suspend,
        .resume         = ohci_omap_resume,
 
        .reset =                ohci_pci_reset,
        .start =                ohci_pci_start,
        .stop =                 ohci_stop,
+       .shutdown =             ohci_shutdown,
 
 #ifdef CONFIG_PM
        /* these suspend/resume entries are for upstream PCI glue ONLY */
        .suspend =      usb_hcd_pci_suspend,
        .resume =       usb_hcd_pci_resume,
 #endif
+
+       .shutdown =     usb_hcd_pci_shutdown,
 };
 
  
 
         */
        .start =                ohci_ppc_soc_start,
        .stop =                 ohci_stop,
+       .shutdown =             ohci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
 static struct platform_driver ohci_hcd_ppc_soc_driver = {
        .probe          = ohci_hcd_ppc_soc_drv_probe,
        .remove         = ohci_hcd_ppc_soc_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
 #ifdef CONFIG_PM
        /*.suspend      = ohci_hcd_ppc_soc_drv_suspend,*/
        /*.resume       = ohci_hcd_ppc_soc_drv_resume,*/
 
         */
        .start =                ohci_pxa27x_start,
        .stop =                 ohci_stop,
+       .shutdown =             ohci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
 static struct platform_driver ohci_hcd_pxa27x_driver = {
        .probe          = ohci_hcd_pxa27x_drv_probe,
        .remove         = ohci_hcd_pxa27x_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
 #ifdef CONFIG_PM
        .suspend        = ohci_hcd_pxa27x_drv_suspend, 
        .resume         = ohci_hcd_pxa27x_drv_resume,
 
         */
        .start =                ohci_s3c2410_start,
        .stop =                 ohci_stop,
+       .shutdown =             ohci_shutdown,
 
        /*
         * managing i/o requests and associated device resources
 static struct platform_driver ohci_hcd_s3c2410_driver = {
        .probe          = ohci_hcd_s3c2410_drv_probe,
        .remove         = ohci_hcd_s3c2410_drv_remove,
+       .shutdown       = usb_hcd_platform_shutdown,
        /*.suspend      = ohci_hcd_s3c2410_drv_suspend, */
        /*.resume       = ohci_hcd_s3c2410_drv_resume, */
        .driver         = {
 
        unsigned long           next_statechange;       /* suspend/resume */
        u32                     fminterval;             /* saved register */
 
-       struct notifier_block   reboot_notifier;
-
        unsigned long           flags;          /* for HC bugs */
 #define        OHCI_QUIRK_AMD756       0x01                    /* erratum #4 */
 #define        OHCI_QUIRK_SUPERIO      0x02                    /* natsemi */