diff options
Diffstat (limited to 'drivers/pci')
| -rw-r--r-- | drivers/pci/hotplug/pciehp_ctrl.c | 6 | ||||
| -rw-r--r-- | drivers/pci/msi.c | 10 | ||||
| -rw-r--r-- | drivers/pci/pci.c | 12 | ||||
| -rw-r--r-- | drivers/pci/pcie/aspm.c | 19 |
4 files changed, 29 insertions, 18 deletions
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 10c9c0ba8ff2..ec0b4c11ccd9 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
| 32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
| 33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
| 34 | #include <linux/pm_runtime.h> | ||
| 35 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
| 36 | #include "../pci.h" | 35 | #include "../pci.h" |
| 37 | #include "pciehp.h" | 36 | #include "pciehp.h" |
| @@ -99,7 +98,6 @@ static int board_added(struct slot *p_slot) | |||
| 99 | pciehp_green_led_blink(p_slot); | 98 | pciehp_green_led_blink(p_slot); |
| 100 | 99 | ||
| 101 | /* Check link training status */ | 100 | /* Check link training status */ |
| 102 | pm_runtime_get_sync(&ctrl->pcie->port->dev); | ||
| 103 | retval = pciehp_check_link_status(ctrl); | 101 | retval = pciehp_check_link_status(ctrl); |
| 104 | if (retval) { | 102 | if (retval) { |
| 105 | ctrl_err(ctrl, "Failed to check link status\n"); | 103 | ctrl_err(ctrl, "Failed to check link status\n"); |
| @@ -120,14 +118,12 @@ static int board_added(struct slot *p_slot) | |||
| 120 | if (retval != -EEXIST) | 118 | if (retval != -EEXIST) |
| 121 | goto err_exit; | 119 | goto err_exit; |
| 122 | } | 120 | } |
| 123 | pm_runtime_put(&ctrl->pcie->port->dev); | ||
| 124 | 121 | ||
| 125 | pciehp_green_led_on(p_slot); | 122 | pciehp_green_led_on(p_slot); |
| 126 | pciehp_set_attention_status(p_slot, 0); | 123 | pciehp_set_attention_status(p_slot, 0); |
| 127 | return 0; | 124 | return 0; |
| 128 | 125 | ||
| 129 | err_exit: | 126 | err_exit: |
| 130 | pm_runtime_put(&ctrl->pcie->port->dev); | ||
| 131 | set_slot_off(ctrl, p_slot); | 127 | set_slot_off(ctrl, p_slot); |
| 132 | return retval; | 128 | return retval; |
| 133 | } | 129 | } |
| @@ -141,9 +137,7 @@ static int remove_board(struct slot *p_slot) | |||
| 141 | int retval; | 137 | int retval; |
| 142 | struct controller *ctrl = p_slot->ctrl; | 138 | struct controller *ctrl = p_slot->ctrl; |
| 143 | 139 | ||
| 144 | pm_runtime_get_sync(&ctrl->pcie->port->dev); | ||
| 145 | retval = pciehp_unconfigure_device(p_slot); | 140 | retval = pciehp_unconfigure_device(p_slot); |
| 146 | pm_runtime_put(&ctrl->pcie->port->dev); | ||
| 147 | if (retval) | 141 | if (retval) |
| 148 | return retval; | 142 | return retval; |
| 149 | 143 | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 50c5003295ca..7f73bacf13ed 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
| @@ -1206,6 +1206,16 @@ int pci_alloc_irq_vectors_affinity(struct pci_dev *dev, unsigned int min_vecs, | |||
| 1206 | if (flags & PCI_IRQ_AFFINITY) { | 1206 | if (flags & PCI_IRQ_AFFINITY) { |
| 1207 | if (!affd) | 1207 | if (!affd) |
| 1208 | affd = &msi_default_affd; | 1208 | affd = &msi_default_affd; |
| 1209 | |||
| 1210 | if (affd->pre_vectors + affd->post_vectors > min_vecs) | ||
| 1211 | return -EINVAL; | ||
| 1212 | |||
| 1213 | /* | ||
| 1214 | * If there aren't any vectors left after applying the pre/post | ||
| 1215 | * vectors don't bother with assigning affinity. | ||
| 1216 | */ | ||
| 1217 | if (affd->pre_vectors + affd->post_vectors == min_vecs) | ||
| 1218 | affd = NULL; | ||
| 1209 | } else { | 1219 | } else { |
| 1210 | if (WARN_ON(affd)) | 1220 | if (WARN_ON(affd)) |
| 1211 | affd = NULL; | 1221 | affd = NULL; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a881c0d3d2e8..7904d02ffdb9 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -2241,10 +2241,13 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge) | |||
| 2241 | return false; | 2241 | return false; |
| 2242 | 2242 | ||
| 2243 | /* | 2243 | /* |
| 2244 | * Hotplug ports handled by firmware in System Management Mode | 2244 | * Hotplug interrupts cannot be delivered if the link is down, |
| 2245 | * so parents of a hotplug port must stay awake. In addition, | ||
| 2246 | * hotplug ports handled by firmware in System Management Mode | ||
| 2245 | * may not be put into D3 by the OS (Thunderbolt on non-Macs). | 2247 | * may not be put into D3 by the OS (Thunderbolt on non-Macs). |
| 2248 | * For simplicity, disallow in general for now. | ||
| 2246 | */ | 2249 | */ |
| 2247 | if (bridge->is_hotplug_bridge && !pciehp_is_native(bridge)) | 2250 | if (bridge->is_hotplug_bridge) |
| 2248 | return false; | 2251 | return false; |
| 2249 | 2252 | ||
| 2250 | if (pci_bridge_d3_force) | 2253 | if (pci_bridge_d3_force) |
| @@ -2276,10 +2279,7 @@ static int pci_dev_check_d3cold(struct pci_dev *dev, void *data) | |||
| 2276 | !pci_pme_capable(dev, PCI_D3cold)) || | 2279 | !pci_pme_capable(dev, PCI_D3cold)) || |
| 2277 | 2280 | ||
| 2278 | /* If it is a bridge it must be allowed to go to D3. */ | 2281 | /* If it is a bridge it must be allowed to go to D3. */ |
| 2279 | !pci_power_manageable(dev) || | 2282 | !pci_power_manageable(dev)) |
| 2280 | |||
| 2281 | /* Hotplug interrupts cannot be delivered if the link is down. */ | ||
| 2282 | dev->is_hotplug_bridge) | ||
| 2283 | 2283 | ||
| 2284 | *d3cold_ok = false; | 2284 | *d3cold_ok = false; |
| 2285 | 2285 | ||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 17ac1dce3286..3dd8bcbb3011 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
| @@ -532,25 +532,32 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev) | |||
| 532 | link = kzalloc(sizeof(*link), GFP_KERNEL); | 532 | link = kzalloc(sizeof(*link), GFP_KERNEL); |
| 533 | if (!link) | 533 | if (!link) |
| 534 | return NULL; | 534 | return NULL; |
| 535 | |||
| 535 | INIT_LIST_HEAD(&link->sibling); | 536 | INIT_LIST_HEAD(&link->sibling); |
| 536 | INIT_LIST_HEAD(&link->children); | 537 | INIT_LIST_HEAD(&link->children); |
| 537 | INIT_LIST_HEAD(&link->link); | 538 | INIT_LIST_HEAD(&link->link); |
| 538 | link->pdev = pdev; | 539 | link->pdev = pdev; |
| 539 | if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) { | 540 | |
| 541 | /* | ||
| 542 | * Root Ports and PCI/PCI-X to PCIe Bridges are roots of PCIe | ||
| 543 | * hierarchies. | ||
| 544 | */ | ||
| 545 | if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT || | ||
| 546 | pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE) { | ||
| 547 | link->root = link; | ||
| 548 | } else { | ||
| 540 | struct pcie_link_state *parent; | 549 | struct pcie_link_state *parent; |
| 550 | |||
| 541 | parent = pdev->bus->parent->self->link_state; | 551 | parent = pdev->bus->parent->self->link_state; |
| 542 | if (!parent) { | 552 | if (!parent) { |
| 543 | kfree(link); | 553 | kfree(link); |
| 544 | return NULL; | 554 | return NULL; |
| 545 | } | 555 | } |
| 556 | |||
| 546 | link->parent = parent; | 557 | link->parent = parent; |
| 558 | link->root = link->parent->root; | ||
| 547 | list_add(&link->link, &parent->children); | 559 | list_add(&link->link, &parent->children); |
| 548 | } | 560 | } |
| 549 | /* Setup a pointer to the root port link */ | ||
| 550 | if (!link->parent) | ||
| 551 | link->root = link; | ||
| 552 | else | ||
| 553 | link->root = link->parent->root; | ||
| 554 | 561 | ||
| 555 | list_add(&link->sibling, &link_list); | 562 | list_add(&link->sibling, &link_list); |
| 556 | pdev->link_state = link; | 563 | pdev->link_state = link; |
