+ /* NOTE: chip docs cover clean "real suspend" cases (what Linux
+ * calls "standby", "suspend to RAM", and so on). There are also
+ * dirty cases when swsusp fakes a suspend in "shutdown" mode.
+ */
+ if (dev->current_state != PCI_D0) {
+#ifdef DEBUG
+ int pci_pm;
+ u16 pmcr;
+
+ pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM);
+ pci_read_config_word(dev, pci_pm + PCI_PM_CTRL, &pmcr);
+ pmcr &= PCI_PM_CTRL_STATE_MASK;
+ if (pmcr) {
+ /* Clean case: power to USB and to HC registers was
+ * maintained; remote wakeup is easy.
+ */
+ dev_dbg(hcd->self.controller, "resume from PCI D%d\n",
+ pmcr);
+ } else {
+ /* Clean: HC lost Vcc power, D0 uninitialized
+ * + Vaux may have preserved port and transceiver
+ * state ... for remote wakeup from D3cold
+ * + or not; HCD must reinit + re-enumerate
+ *
+ * Dirty: D0 semi-initialized cases with swsusp
+ * + after BIOS init
+ * + after Linux init (HCD statically linked)
+ */
+ dev_dbg(hcd->self.controller,
+ "PCI D0, from previous PCI D%d\n",
+ dev->current_state);
+ }
+#endif
+ /* yes, ignore these results too... */
+ (void) pci_enable_wake (dev, dev->current_state, 0);
+ (void) pci_enable_wake (dev, PCI_D3cold, 0);
+ } else {
+ /* Same basic cases: clean (powered/not), dirty */
+ dev_dbg(hcd->self.controller, "PCI legacy resume\n");
+ }
+
+ /* NOTE: the PCI API itself is asymmetric here. We don't need to
+ * pci_set_power_state(PCI_D0) since that's part of re-enabling;
+ * but that won't re-enable bus mastering. Yet pci_disable_device()
+ * explicitly disables bus mastering...
+ */
+ retval = pci_enable_device (dev);
+ if (retval < 0) {
+ dev_err (hcd->self.controller,
+ "can't re-enable after resume, %d!\n", retval);
+ return retval;
+ }
+ pci_set_master (dev);
+ pci_restore_state (dev);
+
+ dev->dev.power.power_state = PMSG_ON;
+
+ clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
+
+ if (hcd->driver->resume) {
+ retval = hcd->driver->resume(hcd);
+ if (retval) {
+ dev_err (hcd->self.controller,
+ "PCI post-resume error %d!\n", retval);
+ usb_hc_died (hcd);
+ }