USB: serial: ch341: fix modem-control and B0 handling
[pandora-kernel.git] / drivers / pci / pci.c
index 6d4a531..6b72e4a 100644 (file)
@@ -664,15 +664,11 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
                error = platform_pci_set_power_state(dev, state);
                if (!error)
                        pci_update_current_state(dev, state);
-               /* Fall back to PCI_D0 if native PM is not supported */
-               if (!dev->pm_cap)
-                       dev->current_state = PCI_D0;
-       } else {
+       } else
                error = -ENODEV;
-               /* Fall back to PCI_D0 if native PM is not supported */
-               if (!dev->pm_cap)
-                       dev->current_state = PCI_D0;
-       }
+
+       if (error && !dev->pm_cap) /* Fall back to PCI_D0 */
+               dev->current_state = PCI_D0;
 
        return error;
 }
@@ -1082,6 +1078,8 @@ EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state);
 static int do_pci_enable_device(struct pci_dev *dev, int bars)
 {
        int err;
+       u16 cmd;
+       u8 pin;
 
        err = pci_set_power_state(dev, PCI_D0);
        if (err < 0 && err != -EIO)
@@ -1091,6 +1089,17 @@ static int do_pci_enable_device(struct pci_dev *dev, int bars)
                return err;
        pci_fixup_device(pci_fixup_enable, dev);
 
+       if (dev->msi_enabled || dev->msix_enabled)
+               return 0;
+
+       pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+       if (pin) {
+               pci_read_config_word(dev, PCI_COMMAND, &cmd);
+               if (cmd & PCI_COMMAND_INTX_DISABLE)
+                       pci_write_config_word(dev, PCI_COMMAND,
+                                             cmd & ~PCI_COMMAND_INTX_DISABLE);
+       }
+
        return 0;
 }
 
@@ -1754,6 +1763,10 @@ bool pci_dev_run_wake(struct pci_dev *dev)
        if (!dev->pme_support)
                return false;
 
+       /* PME-capable in principle, but not from the intended sleep state */
+       if (!pci_pme_capable(dev, pci_target_state(dev)))
+               return false;
+
        while (bus->parent) {
                struct pci_dev *bridge = bus->self;
 
@@ -1919,10 +1932,6 @@ void pci_enable_ari(struct pci_dev *dev)
        if (!pci_is_pcie(dev) || dev->devfn)
                return;
 
-       pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI);
-       if (!pos)
-               return;
-
        bridge = dev->bus->self;
        if (!bridge || !pci_is_pcie(bridge))
                return;
@@ -1941,10 +1950,14 @@ void pci_enable_ari(struct pci_dev *dev)
                return;
 
        pci_read_config_word(bridge, pos + PCI_EXP_DEVCTL2, &ctrl);
-       ctrl |= PCI_EXP_DEVCTL2_ARI;
+       if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) {
+               ctrl |= PCI_EXP_DEVCTL2_ARI;
+               bridge->ari_enabled = 1;
+       } else {
+               ctrl &= ~PCI_EXP_DEVCTL2_ARI;
+               bridge->ari_enabled = 0;
+       }
        pci_write_config_word(bridge, pos + PCI_EXP_DEVCTL2, ctrl);
-
-       bridge->ari_enabled = 1;
 }
 
 /**