aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c6
-rw-r--r--drivers/pci/msi.c10
-rw-r--r--drivers/pci/pci.c12
-rw-r--r--drivers/pci/pcie/aspm.c19
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
129err_exit: 126err_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;