]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/host/ohci-pci.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg...
[linux-2.6-omap-h63xx.git] / drivers / usb / host / ohci-pci.c
index b331ac4d0d62e619865d21bc102aa7767ad33970..3bf175d95a2303b17d80a3561fc38a727ce13c84 100644 (file)
 
 /*-------------------------------------------------------------------------*/
 
+static int broken_suspend(struct usb_hcd *hcd)
+{
+       device_init_wakeup(&hcd->self.root_hub->dev, 0);
+       return 0;
+}
+
 /* AMD 756, for most chips (early revs), corrupts register
  * values on read ... so enable the vendor workaround.
  */
-static int __devinit ohci_quirk_amd756(struct usb_hcd *hcd)
+static int ohci_quirk_amd756(struct usb_hcd *hcd)
 {
        struct ohci_hcd *ohci = hcd_to_ohci (hcd);
 
@@ -31,16 +37,14 @@ static int __devinit ohci_quirk_amd756(struct usb_hcd *hcd)
        ohci_dbg (ohci, "AMD756 erratum 4 workaround\n");
 
        /* also erratum 10 (suspend/resume issues) */
-       device_init_wakeup(&hcd->self.root_hub->dev, 0);
-
-       return 0;
+       return broken_suspend(hcd);
 }
 
 /* Apple's OHCI driver has a lot of bizarre workarounds
  * for this chip.  Evidently control and bulk lists
  * can get confused.  (B&W G3 models, and ...)
  */
-static int __devinit ohci_quirk_opti(struct usb_hcd *hcd)
+static int ohci_quirk_opti(struct usb_hcd *hcd)
 {
        struct ohci_hcd *ohci = hcd_to_ohci (hcd);
 
@@ -53,7 +57,7 @@ static int __devinit ohci_quirk_opti(struct usb_hcd *hcd)
  * identify the USB (fn2). This quirk might apply to more or
  * even all NSC stuff.
  */
-static int __devinit ohci_quirk_ns(struct usb_hcd *hcd)
+static int ohci_quirk_ns(struct usb_hcd *hcd)
 {
        struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
        struct pci_dev  *b;
@@ -75,12 +79,12 @@ static int __devinit ohci_quirk_ns(struct usb_hcd *hcd)
  * delays before control or bulk queues get re-activated
  * in finish_unlinks()
  */
-static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd)
+static int ohci_quirk_zfmicro(struct usb_hcd *hcd)
 {
        struct ohci_hcd *ohci = hcd_to_ohci (hcd);
 
        ohci->flags |= OHCI_QUIRK_ZFMICRO;
-       ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n");
+       ohci_dbg(ohci, "enabled Compaq ZFMicro chipset quirks\n");
 
        return 0;
 }
@@ -88,7 +92,7 @@ static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd)
 /* Check for Toshiba SCC OHCI which has big endian registers
  * and little endian in memory data structures
  */
-static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd)
+static int ohci_quirk_toshiba_scc(struct usb_hcd *hcd)
 {
        struct ohci_hcd *ohci = hcd_to_ohci (hcd);
 
@@ -107,6 +111,38 @@ static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd)
 #endif
 }
 
+/* Check for NEC chip and apply quirk for allegedly lost interrupts.
+ */
+
+static void ohci_quirk_nec_worker(struct work_struct *work)
+{
+       struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work);
+       int status;
+
+       status = ohci_init(ohci);
+       if (status != 0) {
+               ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n",
+                        "ohci_init", status);
+               return;
+       }
+
+       status = ohci_restart(ohci);
+       if (status != 0)
+               ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n",
+                        "ohci_restart", status);
+}
+
+static int ohci_quirk_nec(struct usb_hcd *hcd)
+{
+       struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+
+       ohci->flags |= OHCI_QUIRK_NEC;
+       INIT_WORK(&ohci->nec_work, ohci_quirk_nec_worker);
+       ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n");
+
+       return 0;
+}
+
 /* List of quirks for OHCI */
 static const struct pci_device_id ohci_pci_quirks[] = {
        {
@@ -129,6 +165,22 @@ static const struct pci_device_id ohci_pci_quirks[] = {
                PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6),
                .driver_data = (unsigned long)ohci_quirk_toshiba_scc,
        },
+       {
+               PCI_DEVICE(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB),
+               .driver_data = (unsigned long)ohci_quirk_nec,
+       },
+       {
+               /* Toshiba portege 4000 */
+               .vendor         = PCI_VENDOR_ID_AL,
+               .device         = 0x5237,
+               .subvendor      = PCI_VENDOR_ID_TOSHIBA,
+               .subdevice      = 0x0004,
+               .driver_data    = (unsigned long) broken_suspend,
+       },
+       {
+               PCI_DEVICE(PCI_VENDOR_ID_ITE, 0x8152),
+               .driver_data = (unsigned long) broken_suspend,
+       },
        /* FIXME for some of the early AMD 760 southbridges, OHCI
         * won't work at all.  blacklist them.
         */
@@ -225,7 +277,7 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
 static int ohci_pci_resume (struct usb_hcd *hcd)
 {
        set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
-       usb_hcd_resume_root_hub(hcd);
+       ohci_finish_controller_resume(hcd);
        return 0;
 }
 
@@ -254,9 +306,8 @@ static const struct hc_driver ohci_pci_hc_driver = {
        .shutdown =             ohci_shutdown,
 
 #ifdef CONFIG_PM
-       /* these suspend/resume entries are for upstream PCI glue ONLY */
-       .suspend =              ohci_pci_suspend,
-       .resume =               ohci_pci_resume,
+       .pci_suspend =          ohci_pci_suspend,
+       .pci_resume =           ohci_pci_resume,
 #endif
 
        /*
@@ -276,7 +327,6 @@ static const struct hc_driver ohci_pci_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,