diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 606e4a083337913e45f2f584706de2c7864e84c7..986bb53b60c9df660592fedff103534245c0c3de 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -525,11 +525,7 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev) } pci_restore_state(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); + pci_pme_restore(pci_dev); return 0; } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 586e2735d6e0b5944510be92a5941fd7860c3e80..c11a89cd5a352a0d37568b185ab38ba51ce6b2f2 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1109,6 +1109,26 @@ static void ehci_remove_device(struct usb_hcd *hcd, struct usb_device *udev) #ifdef CONFIG_PM +/* Clear wakeup signal locked in zhaoxin platform when device plug in. */ +static void ehci_zx_wakeup_clear(struct ehci_hcd *ehci) +{ + 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); + msleep(1); + t1 &= (u32)~0xf0000; + ehci_writel(ehci, t1, reg); + ehci_readl(ehci, reg); + msleep(1); + t1 = ehci_readl(ehci, reg); + ehci_writel(ehci, t1 | PORT_CSC, reg); + ehci_readl(ehci, reg); +} + /* suspend/resume, section 4.3 */ /* These routines handle the generic parts of controller suspend/resume */ @@ -1142,27 +1162,6 @@ 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); @@ -1181,6 +1180,9 @@ int ehci_resume(struct usb_hcd *hcd, bool force_reset) if (ehci->shutdown) return 0; /* Controller is dead */ + if (ehci->zx_wakeup_clear_needed) + ehci_zx_wakeup_clear(ehci); + /* * If CF is still set and reset isn't forced * then we maintained suspend power. diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index d0d07d30e9128a476003eca5002ba0e1c0706cd0..9937c5a7efc2d139cf759355fa0530f0dfc0b180 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -225,16 +225,16 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ehci->has_synopsys_hc_bug = 1; } break; - case PCI_VENDOR_ID_ZHAOXIN: - if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x90) - ehci->zx_wakeup_clear = 1; - break; case PCI_VENDOR_ID_ASPEED: if (pdev->device == PCI_DEVICE_ID_ASPEED_EHCI) { ehci_info(ehci, "applying Aspeed HC workaround\n"); ehci->is_aspeed = 1; } break; + case PCI_VENDOR_ID_ZHAOXIN: + if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x90) + ehci->zx_wakeup_clear_needed = 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 8da080a54668730ee954e16a00737499ece697e0..480833c942e71d25fe251c97e1eb08aea5f0e3bb 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -219,7 +219,7 @@ struct ehci_hcd { /* one per controller */ unsigned need_oc_pp_cycle:1; /* MPC834X port power */ unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ unsigned is_aspeed:1; - unsigned zx_wakeup_clear:1; + unsigned zx_wakeup_clear_needed:1; /* required for usb32 quirk */ #define OHCI_CTRL_HCFS (3 << 6)