diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 45c3a78d6004eaf6228ddcea89366daddf0bd776..9329f4881d428a7932c910fa7908900a33242bcd 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -513,7 +513,11 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev) } pci_restore_state(pci_dev); - pci_pme_restore(pci_dev); + if (!(pci_dev->vendor == PCI_VENDOR_ID_ZHAOXIN && + pci_dev->device == 0x3104 && + (pci_dev->revision & 0xf0) == 0x90 && + pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI)) + pci_pme_restore(pci_dev); return 0; } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 8608ac513fb764e4c8069cf870ecd1e12e068d1d..0daa6d98f9b91567a66d5811b828b5fedf9b8bc4 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1110,6 +1110,27 @@ int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup) return -EBUSY; } + /* Clear wakeup signal locked in S0 state when device plug in */ + if (ehci->zx_wakeup_clear == 1) { + u32 __iomem *reg = &ehci->regs->port_status[4]; + u32 t1 = ehci_readl(ehci, reg); + + t1 &= (u32)~0xf0000; + t1 |= PORT_TEST_FORCE; + ehci_writel(ehci, t1, reg); + t1 = ehci_readl(ehci, reg); + usleep_range(1000, 2000); + t1 &= (u32)~0xf0000; + ehci_writel(ehci, t1, reg); + usleep_range(1000, 2000); + t1 = ehci_readl(ehci, reg); + ehci_writel(ehci, t1 | PORT_CSC, reg); + udelay(500); + t1 = ehci_readl(ehci, &ehci->regs->status); + ehci_writel(ehci, t1 & STS_PCD, &ehci->regs->status); + ehci_readl(ehci, &ehci->regs->status); + } + return 0; } EXPORT_SYMBOL_GPL(ehci_suspend); diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index baae879dbddd3986767494be03ff8a20d7113756..357dc140e91402d93bdb000f802442bc048e5f99 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -216,6 +216,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ehci_info(ehci, "applying MosChip frame-index workaround\n"); ehci->frame_index_bug = 1; break; + case PCI_VENDOR_ID_ZHAOXIN: + if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x90) + ehci->zx_wakeup_clear = 1; + break; } /* optional debug port, normally in the first BAR */ diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index c8e9a48e1d517db699120899368355d84441cecf..9625b6030757858cb029eb191c8f19f72a823080 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -218,6 +218,7 @@ struct ehci_hcd { /* one per controller */ unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ unsigned need_oc_pp_cycle:1; /* MPC834X port power */ unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ + unsigned zx_wakeup_clear:1; /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6)