usb: quirks: add control message delay for 1b1c:1b20
[pandora-kernel.git] / drivers / pci / pci.c
index 6f45a73..ff27772 100644 (file)
@@ -664,12 +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);
-       } 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;
 }
@@ -1079,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)
@@ -1088,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;
 }
 
@@ -1126,7 +1138,11 @@ static int __pci_enable_device_flags(struct pci_dev *dev,
        if (atomic_add_return(1, &dev->enable_cnt) > 1)
                return 0;               /* already enabled */
 
-       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+       /* only skip sriov related */
+       for (i = 0; i <= PCI_ROM_RESOURCE; i++)
+               if (dev->resource[i].flags & flags)
+                       bars |= (1 << i);
+       for (i = PCI_BRIDGE_RESOURCES; i < DEVICE_COUNT_RESOURCE; i++)
                if (dev->resource[i].flags & flags)
                        bars |= (1 << i);
 
@@ -1462,8 +1478,8 @@ static void pci_pme_list_scan(struct work_struct *work)
                        }
                }
                if (!list_empty(&pci_pme_list))
-                       schedule_delayed_work(&pci_pme_work,
-                                             msecs_to_jiffies(PME_TIMEOUT));
+                       queue_delayed_work(system_freezable_wq, &pci_pme_work,
+                                          msecs_to_jiffies(PME_TIMEOUT));
        }
        mutex_unlock(&pci_pme_list_mutex);
 }
@@ -1512,8 +1528,9 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
                        mutex_lock(&pci_pme_list_mutex);
                        list_add(&pme_dev->list, &pci_pme_list);
                        if (list_is_singular(&pci_pme_list))
-                               schedule_delayed_work(&pci_pme_work,
-                                                     msecs_to_jiffies(PME_TIMEOUT));
+                               queue_delayed_work(system_freezable_wq,
+                                                  &pci_pme_work,
+                                                  msecs_to_jiffies(PME_TIMEOUT));
                        mutex_unlock(&pci_pme_list_mutex);
                } else {
                        mutex_lock(&pci_pme_list_mutex);
@@ -1747,6 +1764,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;
 
@@ -1912,10 +1933,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;
@@ -1934,10 +1951,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;
 }
 
 /**