/*-------------------------------------------------------------------------*/
+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);
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);
* 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;
* 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;
}
/* 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);
#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[] = {
{
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.
*/
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;
}
.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
/*
*/
.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,
.shutdown = usb_hcd_pci_shutdown,
};
-
-static int __init ohci_hcd_pci_init (void)
-{
- printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name);
- if (usb_disabled())
- return -ENODEV;
-
- pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
- sizeof (struct ed), sizeof (struct td));
- return pci_register_driver (&ohci_pci_driver);
-}
-module_init (ohci_hcd_pci_init);
-
-/*-------------------------------------------------------------------------*/
-
-static void __exit ohci_hcd_pci_cleanup (void)
-{
- pci_unregister_driver (&ohci_pci_driver);
-}
-module_exit (ohci_hcd_pci_cleanup);